Commit Graph

3 Commits

Author SHA1 Message Date
gavrielc
8412b899fa feat(diagnostics): funnel events throughout setup with persisted install-id
Shared bash + node emitter in setup/lib/diagnostics.{sh,ts} reads/writes data/install-id so every event from a single install shares one distinct_id — bash-side setup_launched/setup_start, node-side auto_started, per-step started/completed, auth_method_chosen, channel_chosen, first_chat_ready/failed, setup_incomplete, setup_aborted, setup_completed. Opt-out via NANOCLAW_NO_DIAGNOSTICS=1.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 19:21:06 +03:00
gavrielc
4859d8fb2d feat(setup): Claude-assisted error recovery with resume-at-step retry
When a setup step fails — whether hard via fail() or soft via the
"What's left" / "Skipping the first chat" notes — offer to ask Claude
to diagnose. On consent, spawn `claude -p --output-format stream-json`
with a scrolling 3-line action window ("Reading x", "Running y") so
the 1–4 minute investigations feel active rather than hung. No hard
timeout: debugging can take time, Ctrl-C is the escape hatch.

The prompt is minimal: one-paragraph framing, failed step name + msg +
hint, and a list of file references (not contents). Claude's Read/Grep
tools fetch what they need. A per-step map in claude-assist.ts gives
the most relevant files per step; the rest is README + auto.ts +
logs/setup.log + the per-step raw log.

Claude responds with REASON + COMMAND lines. We show the reason in a
clack note, prefill the command via setup/run-suggested.sh (bash 4+
readline, 3.x fallback to Enter-to-run), and eval on the user's
confirm.

When the user runs a fix, fail() now offers to retry the failing step
rather than aborting. setup/logs.ts tracks successfully-completed step
names in-memory; fail() threads those as NANOCLAW_SKIP on a spawnSync
retry, so the child picks up exactly where the parent left off — no
rebuilding containers or reinstalling OneCLI.

Other polish in this change:
- fitToWidth + dimWrap in lib/theme.ts to prevent long spinner labels
  from soft-wrapping (each terminal row stacks a stale copy otherwise).
- Shorter container step label ("Preparing your assistant's sandbox…")
  so it fits on narrow terminals.
- Wordmark anchored in the clack intro line on every run.
- All 25 existing fail() call sites updated to await fail(...) since
  fail is now async.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 12:42:44 +03:00
gavrielc
9b7d4d50e4 refactor(setup): split auto.ts into runner + theme + telegram channel
auto.ts had grown to 923 lines with ~10 interleaved responsibilities.
Split into three focused modules, keeping auto.ts as a pure step
sequencer:

- setup/lib/runner.ts (325 lines) — spawn + stream-parse + spinner-wrap
  primitives. Exports: spawnStep, spawnQuiet, runQuietStep,
  runQuietChild, runUnderSpinner (internal), StatusStream, types
  (Fields, Block, StepResult, SpinnerLabels, QuietChildResult),
  writeStepEntry, summariseTerminalFields, dumpTranscriptOnFailure,
  fail(), ensureAnswer().

- setup/lib/theme.ts (39 lines) — brand palette (brand, brandBold,
  brandChip) with USE_ANSI / TRUECOLOR gating, so both auto.ts and
  channel flows can render the NanoClaw cyan without duplicating the
  detection.

- setup/channels/telegram.ts (277 lines) — runTelegramChannel(displayName)
  owns the full flow: BotFather instructions, token paste + validation
  (via getMe), install script, pair-telegram streaming UI (code card +
  attempt checkpoints), agent-name prompt, init-first-agent wiring.

auto.ts drops to 376 lines. main() reads as a clean sequence of
`if (!skip.has(X)) await Xstep(...)` blocks.

fail() now takes the step name explicitly — no module-level
failingStep state. Every call site is grep-friendly and self-contained
(fail('container', msg, hint)).

Typechecks clean. Smoke-tested end-to-end: intro, mounts step,
progression log, and outro all render the same as before the split.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 02:26:50 +03:00