Commit Graph

222 Commits

Author SHA1 Message Date
gavrielc ea06453bcb fix: correct Photon URL from photon.im to photon.codes
The chat-adapter-imessage docs use photon.codes — our setup flow
and skill had the wrong domain.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-22 22:41:28 +03:00
Paul Snyman 3a87953bc9 fix(signal-auth): read 'number' field from signal-cli 0.13+ listAccounts
signal-cli >= 0.13 emits the account identifier as `number` in JSON
output, not `account`. The skip-if-already-linked path in signal-auth
always returned an empty list, so re-runs of setup unconditionally
tried `signal-cli link`, which fails when the data directory already
exists.

Read `number` first, fall back to `account` for older signal-cli.
2026-05-21 13:28:48 -07:00
madevizslove183 4d81dc4e0e setup: add files:read and files:write to Slack scope checklist
Without files:read, @chat-adapter/slack cannot download attachments —
Slack returns an HTML login page in place of file bytes and the adapter
throws a NetworkError. Bundles files:write for symmetric outbound
(files.uploadV2).

Closes #2457

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 17:43:15 +02:00
gavrielc c9c5ffadc9 fix(setup): pin OneCLI gateway version to 1.23.0
The upstream install script supports ONECLI_VERSION; use it to avoid
pulling an untested gateway release during setup.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-13 01:16:33 +03:00
glifocat bda72a4bf4 chore: rename remaining qwibitai/nanoclaw references to nanocoai/nanoclaw
Sweep of outbound strings, doc URLs, comments, and clone instructions
that were missed in the original org rename. One both-match case in
setup/lib/channels-remote.sh (URL detection) accepts either name so
existing forks with a `qwibitai` remote continue to resolve cleanly;
everywhere else is a straight rename.

Historical mentions left intact:
- CHANGELOG.md (v2.0.0 entry, frozen history)
- .claude/skills/add-gmail-tool/SKILL.md (pre-v2 qwibitai skill — historical)
- repo-tokens/badge.svg (auto-regenerated by update-tokens.yml)
2026-05-11 08:40:09 +02:00
gavrielc 2d03c94252 Merge pull request #2350 from qwibitai/ncl
feat(cli): add ncl admin CLI
2026-05-08 21:05:29 +03:00
gavrielc 93ec82ce38 Merge pull request #2300 from alipgoldberg/setup/slack-member-id-card
setup: correct Slack member-ID card directions
2026-05-08 20:14:27 +03:00
gavrielc 0855369b79 refactor(cli): rename nc to ncl
Rename the CLI binary, socket path, container wrapper, error prefixes,
and all references from `nc` to `ncl`. Add ~/.local/bin symlink during
setup and pnpm script alias.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-08 15:56:09 +03:00
gavrielc 9a649fadc5 feat(setup): default to interactive Claude handoff on failure
Failures now launch an interactive Claude session instead of the
non-interactive assist (REASON/COMMAND parser). The user debugs
with full terminal access and types /exit to return to setup.

The original assist mode is available via --assist-mode flag or
NANOCLAW_SETUP_ASSIST_MODE=1 env var.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-08 15:34:47 +03:00
gavrielc 8a7311a7bb Merge pull request #2324 from alipgoldberg/setup/claude-auth-skip
setup: add "Skip — I'll connect later" option to Claude auth picker
2026-05-08 00:12:29 +03:00
gavrielc 708f98e156 Merge pull request #2316 from alipgoldberg/setup/other-channel-back
setup: add back-to-channels exit to "Other…" channel prompt
2026-05-07 23:46:14 +03:00
gavrielc 8d5d088108 Merge pull request #2315 from alipgoldberg/setup/imessage-handle-copy
setup: drop "E.164" jargon from iMessage handle card
2026-05-07 17:13:58 +03:00
Ali Goldberg 6d8d085f96 setup: add "Skip — I'll connect later" option to Claude auth picker
Today the Claude auth picker has only three real-auth options. A user
without a Pro/Max subscription, an OAuth token, or an API key has no
graceful escape — Ctrl-C kills setup entirely.

Add a fourth option that confirms the trade-off (no agent runtime + no
Claude debug help during setup) and, on Yes, marks auth skipped and
lets setup continue. On No, loop back to the picker. Existing
NANOCLAW_SKIP=auth env hatch is unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 11:33:07 +00:00
Ali Goldberg 7e0c256fa0 setup: drop "E.164" jargon from iMessage handle card
Replace "full E.164, e.g. +15551234567" with plain-language guidance
mirroring the WhatsApp setup card: "start with + and your country code,
no spaces or dashes" plus a worked example. "E.164" is the technical
name for the format and means nothing to non-telecom users; the
explanation it stands in for is one sentence.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 08:29:07 +00:00
Ali Goldberg 1eb55e85a0 setup: add back-to-channels exit to "Other…" channel-name prompt
After picking "Other…" from the channel picker, today's flow drops the
user straight into a free-text prompt with no way back. Replace it with
a brightSelect that offers either "Type the channel name" (existing
behavior) or "← Back to channel selection" — same back-affording pattern
the channel sub-flows already use.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 08:28:12 +00:00
Daniel M d8d6f6bd65 Merge pull request #2313 from alipgoldberg/setup/teams-step-gate-back
setup: add back-to-channels exit at every Teams step gate
2026-05-07 11:16:26 +03:00
exe.dev user 88ff54cf83 setup: add back-to-channels exit at every Teams step gate
Teams setup is 6+ Azure steps over 30+ minutes. Today, every
"Done / Stuck / Show again" gate forces continuation; the only escape
is Ctrl-C, which kills setup entirely. Add a fourth option at each gate
that returns to the channel picker so a stuck operator can pick a
different channel without losing the rest of setup.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 08:05:26 +00:00
exe.dev user 5213c98506 setup: correct Slack member-ID card directions
Slack's profile button is in the bottom-left of the desktop sidebar (not
the top-right), and the "More" overflow icon next to "Copy member ID" is
the vertical kebab `⋮`, not the horizontal `⋯`. Match what users actually
see in Slack.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 11:13:23 +00:00
exe.dev user a36acd3413 setup: tidy Slack app-creation card
- Move the "Get started: …" URL above the numbered instructions and
  render it in bright white so it pops against the brand-cyan body.
  (Headless-only — interactive runs still auto-open the URL in a
  browser, no card line.)
- Group the OAuth scope list vertically by family (im, channels,
  groups, chat, users, reactions) instead of one comma-run wall.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 09:27:09 +00:00
gavrielc 87f75eed79 Merge branch 'main' into setup-telegram-no-telegram-fallback 2026-05-05 23:40:48 +03:00
gavrielc fc09b900ef Merge pull request #2274 from alipgoldberg/setup-channel-back-nav-pr5-signal
setup: add ← Back option to Signal channel flow
2026-05-05 23:37:26 +03:00
gavrielc 1a2d004bad Merge pull request #2273 from alipgoldberg/setup-channel-back-nav-pr4-teams
setup: add ← Back option to Teams channel flow
2026-05-05 23:37:12 +03:00
gavrielc e25eae7e57 Merge pull request #2272 from alipgoldberg/setup-channel-back-nav-pr3-slack
setup: add ← Back option to Slack channel flow
2026-05-05 23:36:30 +03:00
gavrielc 4a10a455f9 Merge pull request #2271 from alipgoldberg/setup-channel-back-nav-pr2-telegram
setup: add ← Back option to Telegram channel flow
2026-05-05 23:36:14 +03:00
gavrielc eefbf4f61d Merge pull request #2269 from alipgoldberg/setup-channel-back-nav-pr1
setup: add ← Back option to Discord, WhatsApp, iMessage channel flows
2026-05-05 23:34:33 +03:00
gavrielc a9c8c841f6 Merge pull request #2275 from alipgoldberg/whatsapp-linked-devices-copy
setup: update WhatsApp link instructions to "You / Settings"
2026-05-05 23:33:32 +03:00
gavrielc 3d42ba6e3d Merge pull request #2281 from alipgoldberg/setup-signal-cli-auto-install
setup: auto-install signal-cli when missing
2026-05-05 23:32:49 +03:00
glifocat a8e0a7f011 fix(setup): pin Baileys to 7.0.0-rc.9 in install-whatsapp scripts
PR #2259 (Baileys v6→v7) was merged into the channels branch instead of
main. PR #2260 was merged into main 28s later assuming v7 was already
in place. The v6 pin survived in three sites while the WhatsApp adapter
copied from origin/channels at install time was already on the v7 LID
API, breaking every fresh migrate-v2.sh run at 2c-install-whatsapp with
TS errors on remoteJidAlt/participantAlt/lid-mapping.update.

Bumps the pin to 7.0.0-rc.9 (the version v1 has been running on for
months) in:

- setup/install-whatsapp.sh
- setup/add-whatsapp.sh
- .claude/skills/add-whatsapp/SKILL.md (install instruction)

package.json + pnpm-lock.yaml are not touched here — install-whatsapp.sh
mutates them at runtime via pnpm install with the corrected pin.

Closes #2283
2026-05-05 20:47:36 +02:00
exe.dev user 291a1fc8a4 update Signal intro copy to reflect auto-install
Today's copy says "Check that signal-cli is installed (we'll guide
you if not)" but the auto-install PR (#2281) makes that misleading —
we don't guide, we just install. Update the intro list to match what
will actually happen, and add a "no input needed for any of it" lead
so users know to expect a hands-off run.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 17:09:39 +00:00
exe.dev user 92a2347dc5 setup: auto-install signal-cli when missing
When a user picks Signal in setup and signal-cli isn't on PATH, today
NanoClaw bails with a GitHub releases link and tells them to re-run.
That's a hard wall for non-technical users — GitHub releases pages
are intimidating, and the Linux native build / Java decision isn't
obvious.

Replace the bail-out with a real install: a new install-signal-cli.sh
script that does `brew install signal-cli` on macOS or downloads the
native Linux release into ~/.local/bin (no Java, no sudo). Wired into
ensureSignalCli with a spinner; probe again after, fall back to the
original manual-install copy if anything fails.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 17:04:53 +00:00
gavrielc 34982eaf31 Merge branch 'main' into fix/drop-whatsapp-lid-migration 2026-05-05 16:16:02 +03:00
exe.dev user 7fdd7eaa1c setup: update WhatsApp link instructions to "You / Settings"
WhatsApp's mobile UI calls the menu "You" on iOS and "Settings" on
Android (depending on platform/version). Both QR-scan and pairing-code
captions only mentioned "Settings", so iOS users had to figure out the
iOS-specific path on their own.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 10:14:12 +00:00
exe.dev user decf18049f setup: add ← Back option to Signal channel flow
Stacked on #2269 (back-nav scaffolding) plus the Telegram, Slack, and
Teams PRs. They share the same scaffolding file from #2269 — they
don't compile without it, so they have to stack.

Signal had no user-facing prompt before the install kicked off, so
there was nothing to attach a Back option to. This adds a brief "Set
up Signal" info card (what's about to happen, no new phone number
needed) followed by a Continue/Back brightSelect. The card serves
double duty — context for the install plus the Back gate.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 09:51:21 +00:00
exe.dev user c44c7a6669 setup: add ← Back option to Teams channel flow
Stacked on #2269 (back-nav scaffolding) plus the Telegram and Slack
PRs. They share the same scaffolding file from #2269 — they don't
compile without it, so they have to stack.

Both Teams paths already had a brightSelect at the right place, so we
just extend each with a Back option — no new prompts:

- Existing-credentials path: Yes/No confirm becomes Yes/No/Back
- Fresh-setup path: the very first stepGate ("How did that go?") gets
  a 4th option. Subsequent stepGates keep the original 3 options so
  we never lose mid-flow state.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 09:47:17 +00:00
exe.dev user 6a54b69912 setup: add ← Back option to Slack channel flow
Stacked on the back-nav scaffolding from #2269 and the Telegram PR.

Slack's first prompt was already a single-purpose "Press Enter to open
Slack app settings" confirm. Replacing it with a 2-option brightSelect
(Open / ← Back) folds the Back gate into the existing screen — net
same number of prompts as before, just with a way out. The redundant
confirmThenOpen Press-Enter step is dropped; openUrl is called inline.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 09:32:34 +00:00
exe.dev user e1ecfb9c48 setup: add ← Back option to Telegram channel flow
Stacked on the back-nav scaffolding from the Discord/WhatsApp/iMessage
PR — depends on setup/lib/back-nav.ts and the auto.ts loop.

Telegram's "no existing token" path adds one extra prompt — a
brightSelect "Ready to paste your bot token?" between the BotFather
instructions and the token paste. Clack's p.password prompt doesn't
support menu options so we can't fold Back into the paste itself; the
cleanest fix is a separate gate immediately before. The "existing
token" path doesn't add noise — the Yes/No confirm becomes Yes/No/Back.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 09:29:23 +00:00
exe.dev user c795ecff6e setup: add ← Back option to Discord, WhatsApp, iMessage channel flows
Picking the wrong messaging channel during setup left users with no way
to bail out — they had to either complete the chosen flow or kill setup
and start over. This adds a Back option to the first prompt of three
channel sub-flows that share the same simple shape (one leading
brightSelect that's easy to extend).

Mechanics:
- New `setup/lib/back-nav.ts` exports a BACK_TO_CHANNEL_SELECTION
  sentinel and ChannelFlowResult type.
- `setup/auto.ts` wraps the channel dispatch in a while-loop; channels
  return BACK_TO_CHANNEL_SELECTION to bounce back to the chooser
  without restarting setup. Channels not yet wired return void and the
  loop exits after one pass, so the change is backwards compatible.
- Discord, WhatsApp, iMessage each add a `← Back to channel selection`
  option to their first prompt.

Telegram, Slack, Teams, and Signal will follow as separate PRs — they
each need a slightly different shape (extra prompt insertions, gating
inside multi-step flows, etc.) and are easier to review independently.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 09:20:17 +00:00
gavrielc 948a0dcada fix: use nodeenv lts instead of pinned node 22
nodeenv doesn't support major-only version specifiers. Use lts
which resolves to the latest LTS release.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-05 07:28:48 +00:00
gavrielc 3c5ae96cdd use node 22 with nvx 2026-05-05 07:23:37 +00:00
exe.dev user 3eec441b84 improve node install to use uvx 2026-05-05 07:11:26 +00:00
exe.dev user 30a898508a fix(migrate): drop WhatsApp LID dual-row migration step
Remove step 2d (whatsapp-resolve-lids.ts) which pre-created duplicate
messaging_groups rows keyed by @lid alongside the phone-keyed rows.
This caused split sessions — the same contact got separate sessions
depending on which JID format arrived.

With the Baileys v7 upgrade (PR #2259 on channels), the adapter
resolves every LID to a phone JID via extractAddressingContext before
the message reaches the router, making dual rows unnecessary.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-04 21:58:57 +00:00
exe.dev user 306fa6f014 feat(setup): clearer "Open Telegram" copy + mobile fallback hint
Two friction points in the Telegram channel's "Open Telegram" card,
both surfaced when running setup on a VM-via-SSH where the user's
local laptop has no Telegram client installed:

1. The opening sentence read "Opening @yourbot in Telegram so it's
   ready when the pairing code shows up." On a headless device that's
   misleading — nothing is auto-opened, the user has to click the
   link or use their phone. Rewrite as a direct, action-led
   instruction on the headless flow only:

     Open @yourbot in Telegram now — the pairing code is coming next,
     and that's where you'll send it.

   Plus a "Get started: <url>" line and a full-strength mobile
   fallback hint inside the card so headless users have all
   self-serve options visible.

   On non-headless the original status-style line stays accurate
   (`xdg-open` / `open` does fire for users with Telegram desktop
   installed), so the card stays a single line.

2. Clicking `https://t.me/yourbot` silently fails when the user's
   local device has no Telegram client. Non-headless gains:
     - a "(must be installed here)" qualifier on the confirm prompt
       so users without Telegram desktop know up-front;
     - a single combined dim fallback line below the prompt:
         "If browser does not appear, please visit: <url> — or
         search for @yourbot on your mobile."

   Direct `p.confirm` + `openUrl` instead of `confirmThenOpen` for
   the non-headless branch so we control the dim line fully (single
   combined line vs the helper's default URL-only line).

Headless layout drives the same self-serve content via the card body
itself; no confirm prompt fires there.
2026-05-04 17:45:43 +00:00
exe.dev user b33f6654fd fix(setup): use fmtDuration in the container-build spinner
setup/lib/windowed-runner.ts was the one place on main still printing
elapsed time as raw seconds (`(170s)`) instead of using the
minute-aware `fmtDuration` helper from #2108. Two spots — the live
spinner suffix that ticks during the build, and the
success/error completion suffix — both now go through `fmtDuration`,
so anything past 60 seconds renders as `Xm Ys` (e.g. `2m 50s`) like
the rest of the setup flow.

The miss happened because a separate PR (closed) was supposed to
remove the timer entirely from this file, so #2108 deliberately
skipped it. With that other PR closed, applying `fmtDuration` here
is the consistent fix.

Pure formatting change. The helper itself is unchanged from #2108;
behavior under 60s is identical (`Xs`); behavior past 60s now
matches everywhere else.
2026-05-04 09:23:43 +00:00
exe.dev user 34c3e90156 feat(setup): clarify @BotFather is Telegram's official bot
Step 1 of the Telegram channel's BotFather instructions used to read:

  1. Open Telegram and message @BotFather

Two small UX issues with that:
  - "BotFather" reads slightly sketchy without context — a first-time
    user has no way to know it's the official, sanctioned account
    rather than an impersonator.
  - Typing the username from memory leaves room for picking a typo'd
    impostor account (Telegram has many @BotF4ther / @BotFAther / etc.
    look-alikes).

Update the line so the official-bot framing is part of the instruction
itself:

  1. Open Telegram and message @BotFather — Telegram's official bot
     for creating and managing bots

One-line change in the existing note() body. No new dependencies, no
asset churn, no other behavior change.
2026-05-04 09:01:43 +00:00
gavrielc 5eda6c160e Merge branch 'main' into setup-headless-auth-message 2026-05-04 10:07:56 +03:00
Koshkoshinsk 37d6335ebc fix(setup): clean up legacy OneCLI containers before installer runs
The OneCLI installer (curl onecli.sh/install | sh) doesn't pass
--remove-orphans to docker compose up. After the upstream service rename
(app -> onecli), the legacy onecli-app-1 container keeps :10254 bound
and crashes the new bring-up. This breaks /migrate-v2.sh on any host
that has a pre-rename OneCLI installed.

Workaround: before invoking the installer, remove containers in the
"onecli" compose project whose service name isn't in the v2 set
({onecli, postgres}). Label-keyed and no-op on fresh installs.

Filed upstream; remove this once the installer adds --remove-orphans.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 21:18:10 +00:00
Koshkoshinsk 58e4df44e2 fix: add hint to channel multiselect in migration
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-03 20:45:52 +00:00
Sebastien Tardif 5dc54194ab Recognize ANTHROPIC_AUTH_TOKEN in setup verification
The credential proxy already reads ANTHROPIC_AUTH_TOKEN (credential-proxy.ts
line 33) and uses it for OAuth-mode authentication, but setup/verify.ts did
not include it in its credential-detection regex.  Users with
ANTHROPIC_AUTH_TOKEN in .env saw 'CREDENTIALS: missing' even though their
credentials were valid at runtime.

Add ANTHROPIC_AUTH_TOKEN to the regex and add a matching test case.

Closes gh-853
2026-05-03 09:20:22 -07:00
exe.dev user e34380656c feat(setup): headless-aware Claude sign-in pre-message
The pre-message printed by setup/register-claude-token.sh used to
say "A browser window will open for you to sign in with your
Claude account." Accurate on a laptop or desktop, but a lie on
headless devices (Pi, SSH'd-into Linux server, CI) where the
browser auto-open never lands and the user actually has to copy
the URL `claude setup-token` prints to another device.

Add a small bash isHeadless check (mirrors `isHeadless()` in
setup/platform.ts: Linux without DISPLAY / WAYLAND_DISPLAY) and
swap the heredoc accordingly:

  - Headless: "A sign-in link will appear for you to sign in with
    your Claude account. When you finish, we'll save the token
    to your OneCLI vault automatically."
  - GUI: existing "A browser window will open…" copy, unchanged.

The trailing "Press Enter to continue, or edit the command first."
line and the actual `claude setup-token` invocation are unchanged
— only the leading sentence flips.
2026-05-03 12:48:37 +00:00
javexed 58fc5728db feat(setup): add "Other…" option to channel picker
The first-time setup picker only listed seven channels with bash
installers. Users wanting to install one of the other channels (matrix,
github, linear, webex, etc.) had no entry point from the picker and had
to know to run /add-<name> from Claude Code afterwards.

Add an "Other…" option that prompts for a free-text name, normalizes it
(accepts "matrix", "add-matrix", or "/add-matrix"), and prints a hint
telling the user to run /add-<name> from Claude Code after setup
finishes. The verify step's "What's left" panel already covers the
empty-channels case, so the user is not left thinking the channel was
wired.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 01:06:24 -04:00