Commit Graph

854 Commits

Author SHA1 Message Date
gavrielc
1888ecc1e9 Merge pull request #1838 from qwibitai/refactor/pr1-prep
refactor: PR #1 prep — v1 removal, module contract, sdk bump
2026-04-18 14:26:30 +03:00
gavrielc
a1b227269e chore(deps): bump @onecli-sh/sdk to 0.3.1
Lockfile was pinned to 0.2.0 while package.json already declared
^0.3.1. The code depends on types added in 0.3.x (ApprovalRequest,
ManualApprovalHandle, configureManualApproval), so the host build
was failing on v2. Refreshing the lockfile resolves it.

0.3.1 was published 2026-04-10, well clear of minimumReleaseAge.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 14:24:04 +03:00
gavrielc
53e8135102 docs: add module contract for refactor
Codifies the interface between core and modules: the four registries
(delivery actions, inbound gate, response dispatcher, MCP tool
self-registration), default modules (typing, mount-security),
guarded-inline fallbacks, MODULE-HOOK skill-edit markers, and module
migration naming.

Authoritative reference for downstream extraction PRs and install
skills. See REFACTOR_PLAN.md for broader context.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 14:23:56 +03:00
gavrielc
86becf8dea chore: delete v1 reference code
Removes src/v1/ (37 files) and container/agent-runner/src/v1/ (3 files)
along with the v1 reference note in CLAUDE.md and the now-obsolete
tsconfig exclude. v1 was already out of the runtime path; this just
removes the dead weight.

~8,800 LOC removed, zero runtime change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 14:23:47 +03:00
gavrielc
27c52205f9 fix(channels): bridge openDM delegates to adapter directly
chat.openDM dispatches via inferAdapterFromUserId, which only recognizes
Discord/Slack/Teams/gChat formats and throws for everything else —
breaking approval delivery on Telegram (numeric IDs) and the other
direct-addressable channels the bridge now wraps. Delegate straight to
adapter.openDM + channelIdFromThreadId, and only expose openDM when the
underlying adapter implements it. Preserves the adapter's native
platform_id encoding (e.g. "telegram:<chatId>") so user_dms caches align
with the messaging_groups rows onInbound wrote.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 18:30:38 +03:00
gavrielc
e93292de2a fix(agent-runner): spawn built-in MCP server with bun, not node
The Bun migration (c5d0ef8) dropped the in-image tsc build step, so
/app/src/mcp-tools/index.js never exists — only index.ts. The spawn
config in container/agent-runner/src/index.ts still pointed at
index.js and invoked it with `node`, which can't execute TypeScript
anyway. Net effect: every session failed to start the `nanoclaw`
MCP server, so scheduling, send_to_agent, interactive questions,
and self-mod tools were silently absent from the agent's toolset.

Matches entrypoint.sh and src/container-runner.ts, which already
use `exec bun run /app/src/index.ts` for the same reason.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 17:17:45 +03:00
gavrielc
bd659fd7d6 style(v2/delivery): prettier reflow of test import
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 15:17:07 +03:00
gavrielc
ac9535baa8 fix(v2/delivery): prevent double-send from overlapping delivery polls
The active poll (1s, running sessions) and sweep poll (60s, all active
sessions) both call deliverSessionMessages, and a running session is in
both result sets. Without locking they race on the same outbound row:
both read it as undelivered, both call the channel adapter, both
markDelivered. INSERT OR IGNORE hides the DB collision but the user has
already received the message twice.

Adds a per-session inflight guard; the second concurrent caller skips
and picks up any leftover work on the next poll tick.

Also makes outbox cleanup in deliverMessage best-effort: the message is
already on the user's screen, so a cleanup throw must not propagate to
the retry path (which would resend).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 15:17:06 +03:00
gavrielc
bfc626be82 docs: drop v2 framing across CLAUDE.md and 12 docs
Renamed 12 docs/v2-*.md → docs/*.md (already in index from earlier git mv).
Rewrote CLAUDE.md to describe the codebase as just "the codebase" rather
than "v2"; added a "Channels and Providers (skill-installed)" section
reflecting the new model and updated the docs index links.

Agent (general-purpose) cleaned the 12 doc bodies:
- Dropped "NanoClaw v2" / "v2 schema" / "(v2)" prose throughout
- Rewrote inter-doc cross-references docs/v2-X.md → docs/X.md
- Architecture, agent-runner-details: collapsed v1↔v2 comparison tables
  into present-tense facts; added notes that trunk only ships `claude`
  and that channel adapters are skill-installed from the `channels` branch
- Setup-wiring, checklist: dropped v1→v2 migration items that no longer
  apply
- Frozen runtime paths preserved: data/v2.db, data/v2-sessions/,
  container name nanoclaw-v2

git grep confirms remaining `\bv2\b` matches in docs/ are only those
runtime paths.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 14:53:21 +03:00
gavrielc
c37609ffc8 docs(skills): drop "v2" from skill content + src/index.ts log lines
Cleans up the prose-level v2 references that the rename commit didn't
touch. Skills now describe themselves and the codebase without "v2"
versioning language. /add-X-v2 cross-references in setup, init-first-agent,
and manage-channels updated to /add-X.

Runtime path identifiers (data/v2.db, data/v2-sessions/, container name
nanoclaw-v2) deliberately left as-is — renaming them breaks live installs
without commensurate benefit.

Verified: pnpm run build clean, 326 host tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 14:42:55 +03:00
gavrielc
00fb1bee4a chore(skills): rename add-*-v2 → add-* and drop dead v1 channel skills
Renamed 13 skill folders to drop the -v2 suffix (the v2/v1 distinction
isn't load-bearing anymore — there is no v1 runtime). Deleted the four
v1 channel skills that occupied the rename target paths (add-discord,
add-slack, add-telegram, add-whatsapp); they targeted src/v1 which is
reference-only per CLAUDE.md.

Skill content still says "v2" in places — that's a follow-up commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 14:38:19 +03:00
gavrielc
4857512267 refactor(v2): move setup/groups.ts off trunk + drop pino dep
setup/groups.ts is whatsapp-only — its inline syncScript imports baileys
and pino to fetch group metadata via Baileys.groupFetchAllParticipating.
On trunk it was a no-op for non-whatsapp users (returned early without
auth) and the only thing keeping pino alive.

Removed:
- setup/groups.ts (lives on `channels` branch; restored by /add-whatsapp-v2)
- `groups` STEPS entry from setup/index.ts
- pino from package.json (no longer used outside the moved file)

/add-whatsapp-v2 skill updated to copy setup/groups.ts and register both
groups + whatsapp-auth in setup/index.ts STEPS, install pino@9.6.0 along
with baileys + qrcode.

Verified: build clean, 326 host tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 14:34:16 +03:00
gavrielc
712720eef4 refactor(v2): drop @chat-adapter/shared dep — duck-type NetworkError
The only use was channel-registry.ts checking `err instanceof NetworkError`
to retry transient setup failures. Switched to a duck-type predicate
(`err.name === 'NetworkError'`) so the dep is no longer needed at trunk
level. Channel skills bring it in transitively when they install their
Chat SDK adapter package.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 14:33:22 +03:00
gavrielc
a3376c25df docs(channel-skills): rewrite all 13 /add-*-v2 skills for copy-from-channels-branch pattern
Each skill now:
- Pre-flight: checks for file present + import line + dep listed (idempotent)
- git fetch origin channels
- git show origin/channels:<paths> > <paths> to copy adapter (and helpers/tests/setup-step where applicable)
- Append `import './<chan>.js';` to src/channels/index.ts
- pnpm install <pkg>@<pinned-version>
- pnpm run build

Telegram additionally copies 4 helper/test files + setup/pair-telegram.ts
and registers `'pair-telegram':` in setup/index.ts STEPS.

WhatsApp (native) additionally copies setup/whatsapp-auth.ts and
registers `'whatsapp-auth':` in setup/index.ts STEPS, installs
@whiskeysockets/baileys + qrcode + @types/qrcode pinned.

All credential / next-steps / channel-info / troubleshooting sections
preserved verbatim.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 14:24:20 +03:00
gavrielc
437ba63a2f refactor(v2): move channel adapters off v2 trunk
v2 ships with no channels baked in. All channel adapters (discord, slack,
telegram + helpers, whatsapp, whatsapp-cloud, gchat, github, imessage,
linear, matrix, resend, teams, webex) and their channel-specific setup
steps (pair-telegram, whatsapp-auth) now live on the `channels` branch
and get copied in via /add-*-v2 skills.

Removed:
- src/channels/{discord,slack,telegram*,whatsapp*,gchat,github,imessage,linear,matrix,resend,teams,webex}.ts
- setup/{pair-telegram,whatsapp-auth}.ts
- 14 channel-specific deps from package.json (@chat-adapter/*, @beeper/*,
  @bitbasti/*, @resend/chat-sdk-adapter, @whiskeysockets/baileys,
  chat-adapter-imessage, qrcode, @chat-adapter/state-memory unused)
- Their corresponding STEPS entries from setup/index.ts
- Channel imports from src/channels/index.ts

Kept:
- Channel infra: adapter.ts, channel-registry.ts (+ test), chat-sdk-bridge.ts,
  ask-question.ts, an empty-imports index.ts
- Chat SDK runtime (`chat`) for channels that copy in via Chat SDK bridge
- @chat-adapter/shared promoted from transitive to direct dep
  (channel-registry.ts uses NetworkError from it)

Verified: pnpm run build clean, 326 host tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 14:20:28 +03:00
gavrielc
32a973f1cd docs(add-opencode): rewrite skill for copy-from-providers-branch pattern
v2 no longer ships opencode on trunk. The skill now:
- Fetches origin/providers
- Copies opencode source files to their target paths
- Appends self-registration imports to both provider barrels
- Adds @opencode-ai/sdk@1.4.3 as a pinned agent-runner dep
- Adds OPENCODE_VERSION ARG + opencode-ai pnpm global install to Dockerfile
- Rebuilds host + container

All steps idempotent. Credential/env/Zen docs unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 14:14:10 +03:00
gavrielc
03dd559786 style: trim trailing whitespace in providers barrel
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 14:12:35 +03:00
gavrielc
e0258e8c1b refactor(v2): move opencode provider off v2 trunk
v2 ships with only claude baked in. opencode now lives on the `providers`
branch and gets copied in via the /add-opencode skill.

Removed:
- src/providers/opencode.ts
- container/agent-runner/src/providers/{opencode,mcp-to-opencode}.ts + test
- @opencode-ai/sdk from agent-runner package.json + bun.lock
- opencode-ai global install + OPENCODE_VERSION ARG from Dockerfile
- opencode self-registration imports from both provider barrels
- opencode test case from factory.test.ts

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 14:10:56 +03:00
gavrielc
2529c3e387 Merge pull request #1776 from talmosko-code/feat/add-opencode-v2
feat(v2): OpenCode agent provider
2026-04-17 12:22:48 +03:00
gavrielc
f18d0561a6 Merge pull request #1814 from qwibitai/refactor/provider-barrel-v2
refactor(v2/providers): self-registration barrel + host container-config registry
2026-04-17 12:22:12 +03:00
Tal Moskovich
c9dd6e050e docs: update OpenCode Zen integration details in SKILL.md
- Clarified the use of `x-api-key` for Zen's HTTP API, addressing common issues with Bearer tokens.
- Added configuration examples for `.env` and OneCLI registration for Zen keys.
- Provided guidance on naming conventions for OpenCode agent and provider settings.
- Included a note on the difference in authentication methods between OpenCode and OpenRouter.
2026-04-17 12:20:22 +03:00
Tal Moskovich
22150261c5 feat(v2): OpenCode agent provider
- Add OpenCodeProvider (SSE, session resume, MCP via mcp-to-opencode)
- Register opencode in factory; AGENT_PROVIDER passthrough from DB
- Host: XDG mount, NO_PROXY merge, OPENCODE_* env for opencode sessions
- Dockerfile: opencode-ai CLI; docs checklist + architecture diagram
- Skill add-opencode for v2; AgentProviderName in src/types.ts

Made-with: Cursor
2026-04-17 12:20:22 +03:00
gavrielc
7639f7b1bb style(v2/providers): prettier reflow of provider-container-registry signatures
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 12:17:09 +03:00
gavrielc
1f3b023a5a refactor(v2/providers): self-registration barrel + host container-config registry
Providers now mirror the channels pattern: each module calls
registerProvider() at top level, and providers/index.ts is a barrel of
side-effect imports. createProvider() becomes a thin registry lookup;
the closed ProviderName union is gone (now a string alias, since the
env var is a runtime string anyway).

Also adds a host-side provider-container-registry so providers can
declare their own mounts and env passthrough in src/providers/<name>.ts
instead of the container-runner having to know about each one. The
resolver runs once per spawn and threads provider + contribution
through buildMounts and buildContainerArgs so side effects (mkdir,
etc.) fire exactly once.

Both barrels are append-only — adding a new provider is a new file
+ one import line per barrel, no edits to existing files. The built-in
providers (claude, mock) don't need host-side config, so src/providers/
ships with an empty barrel; the container-side barrel imports both.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 12:17:09 +03:00
gavrielc
a38c6a962f Merge pull request #1813 from qwibitai/feat/v2-bun-container
feat(v2): Bun container runtime + build-surface improvements
2026-04-17 12:14:48 +03:00
gavrielc
f04921deee docs(v2): runtime-split guide, CLAUDE.md gotchas, setup CJK autodetect
- docs/v2-build-and-runtime.md: new — runtime split rationale (Node host,
  Bun container), lockfile topology, supply-chain trade-offs, image build
  surface, two session-wake paths, CI shape, key invariants. Indexed from
  CLAUDE.md v2 Docs Index.
- CLAUDE.md: Container Runtime (Bun) section with trigger/action gotchas
  a contributor editing the container must know (named-param prefix rule,
  bun:test vs vitest, bun.lock regeneration, no minimumReleaseAge for the
  Bun tree, no tsc build step, DELETE pragma invariant). CJK font support
  section for Claude sessions outside of /setup to proactively offer when
  they detect CJK signals. Development section updated with Bun commands.
- .claude/skills/setup/SKILL.md: step 3b — auto-enable CJK fonts without
  asking if the user is already writing in CJK; otherwise ask only on clear
  signals (CJK timezone from step 2a). 3c renumbered from old 3b.
2026-04-17 11:38:20 +03:00
gavrielc
c5d0ef8b4f feat(v2): migrate container runtime to Bun, improve image build surface
Container side:
- agent-runner switches to Bun. Drops better-sqlite3 (native compile gone),
  drops tsc build step in-image AND the tsc-on-every-session-wake in the
  entrypoint — bun runs src/index.ts directly. bun:sqlite replaces
  better-sqlite3; cross-mount DB invariants (journal_mode=DELETE, busy_timeout)
  preserved. Named params converted from @name to $name because bun:sqlite
  does not auto-strip the prefix the way better-sqlite3 does.
- Tests ported from vitest to bun:test (only describe/it/expect/before/afterEach
  used, API-compatible). vitest.config.ts excludes container/agent-runner/.
- bun.lock replaces pnpm-lock.yaml + pnpm-workspace.yaml under
  container/agent-runner/. Host pnpm workspace does NOT include this tree.

Dockerfile improvements (independent of Bun but bundled while touching the file):
- tini as PID 1 for correct SIGTERM propagation (prevents half-written
  outbound.db on shutdown).
- Extracted entrypoint.sh — readable and diffable vs the old inline printf.
- BuildKit cache mounts for apt + bun install + pnpm install.
- --no-install-recommends on apt, pinned CLAUDE_CODE_VERSION, AGENT_BROWSER,
  VERCEL, BUN_VERSION.
- CJK fonts (~200MB) behind ARG INSTALL_CJK_FONTS=false; build.sh reads from
  .env; setup/container.ts reads the same .env so /setup and manual rebuild
  stay in sync.
- PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 in case any postinstall tries to pull a
  redundant Chromium.
- /home/node 755 (was 777).

Host side:
- src/container-runner.ts dynamic spawn command collapses from
  `pnpm exec tsc --outDir /tmp/dist … && node /tmp/dist/index.js` to
  `exec bun run /app/src/index.ts` — cold start ~200-500ms faster per wake.

CI:
- oven-sh/setup-bun@v2 alongside Node/pnpm. Adds explicit container
  typecheck (was documented in CLAUDE.md, not enforced) and `bun test` for
  agent-runner tests.
2026-04-17 11:38:01 +03:00
gavrielc
45c35a08f0 docs(v2/db): add database architecture reference
Split into three files linked from CLAUDE.md's v2 docs index:

- v2-db.md — overview: three-DB model, cross-mount rules, central-vs-session
  decision, design patterns, readers/writers map.
- v2-db-central.md — every table in data/v2.db plus migration history.
- v2-db-session.md — per-session inbound.db / outbound.db schemas, session
  folder layout, seq parity invariant, lazy schema evolution.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 10:37:26 +03:00
gavrielc
31063a1b4c docs(v2/checklist): reflect progress on package install, vercel, and scope adjustments
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 09:55:24 +03:00
gavrielc
f2f76ab4ff Merge pull request #1771 from meeech/feat/v2-pnpm-migration
chore: migrate v2 from npm to pnpm
2026-04-17 09:54:40 +03:00
gavrielc
22498ae69c fix: remaining npm→pnpm gaps + dockerignore for pnpm symlinks
- container/.dockerignore (new): exclude agent-runner/node_modules and
  agent-runner/dist so COPY agent-runner/ ./ doesn't clobber the
  pnpm-installed node_modules with host directories. Under npm's flat
  layout this was forgiving; under pnpm's symlink layout it's a hard
  conflict (overlay2 cannot copy onto a symlink target).
- setup/{groups,service}.ts: execSync('pnpm run build') not npm.
- setup/index.ts: usage string.
- scripts/*.ts: usage comments + seed-discord final log.
- .claude/settings.json: permission allowlist entries.
- .claude/skills/{add-whatsapp-v2,add-dashboard}/SKILL.md: docs.
- container/skills/{frontend-engineer,vercel-cli,self-customize}/SKILL.md:
  agent-facing docs still told the container agent to run npm.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 09:53:00 +03:00
gavrielc
504e5296c9 fix: pnpm-lock sync, per-group build-script allowlist, ppnpm typos
- Regenerate pnpm-lock.yaml to match v2 package.json (Baileys 6.17.16,
  @chat-adapter/linear 4.26.0)
- src/container-runner.ts: when install_packages rebuilds a per-group
  image, append each installed package to /root/.npmrc's
  only-built-dependencies before pnpm install -g, so packages with
  postinstall scripts (playwright, puppeteer, native addons) don't
  install silently broken
- Fix stray 'ppnpm uninstall' in 13 skill files (REMOVE.md + SKILL.md)
  left over from the npm→pnpm sed pass

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 09:25:59 +03:00
meeech
44e2361293 fix: migrate container agent-runner to pnpm with proper build scripts
- Remove package-lock.json, add pnpm-lock.yaml for frozen installs
- Add pnpm-workspace.yaml with onlyBuiltDependencies (better-sqlite3)
  and minimumReleaseAge matching root project policy
- Dockerfile: allow agent-browser build scripts via global .npmrc
  (global installs don't read project-level workspace config)
- Dockerfile: make lockfile and workspace COPY mandatory (drop glob)
2026-04-17 09:23:35 +03:00
meeech
994b323cfa docs: add supply chain security rules for pnpm
Add agent-facing rules to CLAUDE.md covering minimumReleaseAgeExclude,
onlyBuiltDependencies, and frozen lockfile requirements — all require
human sign-off. Add comprehensive human-facing section to
docs/SECURITY.md with rationale, exclusion procedure (exact version
pin, approval, expiry), and build script allowlist documentation.
2026-04-17 09:23:26 +03:00
meeech
163f5700a5 chore: add .pnpm-store to gitignore and commit formatting fix
Add .pnpm-store/ to .gitignore — pnpm creates this when running in
sandbox mode with restricted network/filesystem access. Also commit
whatsapp.ts formatting change from prettier pre-commit hook.
2026-04-17 09:23:12 +03:00
meeech
211d2b5877 docs: convert all skill instructions from npm to pnpm
Batch update 62 files across .claude/skills/ — SKILL.md, REMOVE.md,
and script files. Conversions: npm run -> pnpm run, npm install ->
pnpm install, npx -> pnpm exec/dlx, npm uninstall -> pnpm uninstall,
package-lock.json -> pnpm-lock.yaml, shebangs updated.
2026-04-17 09:22:45 +03:00
meeech
8fbf9861f1 docs: update documentation for pnpm migration
Convert npm run/install/ci -> pnpm equivalents, npx -> pnpm exec,
package-lock.json -> pnpm-lock.yaml across CLAUDE.md, groups/global/,
docs/SPEC.md, docs/DEBUG_CHECKLIST.md, docs/BRANCH-FORK-MAINTENANCE.md,
and docs/docker-sandboxes.md. Kept .npmrc and npm config references
where they document real files.
2026-04-17 09:18:58 +03:00
meeech
2b7fef628d chore: migrate setup.sh bootstrap to pnpm
Replace npm ci with corepack enable + pnpm install --frozen-lockfile.
Remove --unsafe-perm logic (not needed with pnpm).
2026-04-17 09:18:29 +03:00
meeech
0b06343323 chore: use pnpm in dynamic container commands
Replace npx tsc with pnpm exec tsc in container entrypoint command,
and npm install -g with pnpm install -g in dynamic Dockerfile
generation. Variable names (npm, npmPackages) intentionally kept as
they refer to npm-registry packages, not the CLI.
2026-04-17 09:18:29 +03:00
meeech
58420e16eb chore: migrate container Dockerfile to pnpm with corepack
Enable corepack and PNPM_HOME in container, switch all npm/npx
invocations to pnpm/pnpm exec. Use wildcard COPY for optional
pnpm-lock.yaml in agent-runner.
2026-04-17 09:18:29 +03:00
meeech
d1ddfa0657 chore: migrate CI workflows and git hooks to pnpm
- ci.yml: add pnpm/action-setup, cache pnpm, use pnpm exec
- bump-version.yml: add pnpm/action-setup, pnpm version, drop
  package-lock.json from git add
- husky pre-commit: npm run -> pnpm run
2026-04-17 09:18:07 +03:00
meeech
113caa97e4 chore: replace package-lock.json with pnpm-lock.yaml
Generated via pnpm install with pnpm@10.33.0. Verified:
- pnpm install --frozen-lockfile passes
- better-sqlite3 native module loads correctly
2026-04-17 09:18:07 +03:00
meeech
3e1f226281 chore: add pnpm packageManager field and workspace config
Add pnpm@10.33.0 as packageManager, create pnpm-workspace.yaml with
minimumReleaseAge (3 days) and onlyBuiltDependencies allowlist
(better-sqlite3, esbuild, protobufjs, sharp), update .npmrc as
safety-net fallback.
2026-04-17 09:17:45 +03:00
Gabi Simons
1aeb8fb4ca refactor(add-vercel): drop Frontend Engineer delegation, add pre-deploy checks
The specialist-subagent pattern forced every /add-vercel user through the
OneCLI credential-assignment plumbing (dynamically created Frontend Engineer
agents had no Vercel secret on first deploy). For a personal assistant the
isolation wasn't worth the complexity — the host agent can deploy to Vercel
directly using the same CLI.

- Remove the Phase 5 CLAUDE.md patch that forbade writing frontend code
- Drop the bundled frontend-engineer container skill
- Strip the HARD RULE + "Building Websites" delegation from vercel-cli
- Add a concise "Pre-Send Checks" section: local build, deployment READY,
  live URL returns 2xx, optional agent-browser visual check

Net: -194 lines. /add-vercel now installs the CLI, registers the secret,
assigns it to existing agents, and teaches the agent to verify before
sharing the URL. No subagent plumbing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-16 19:59:30 +00:00
gavrielc
cc784ff94b refactor(v2): remove trigger_credential_collection MCP tool
Drops the in-chat credential-collection flow introduced in e92b245. Agents
can no longer collect API keys via a secure modal — users must add secrets
through OneCLI directly. Keeps the OneCLI manual-approval handler and
threaded-routing work from the same commit intact.

Removed:
* container/agent-runner/src/mcp-tools/credentials.ts (MCP tool)
* src/credentials.ts (host-side modal/OneCLI pipeline)
* src/db/credentials.ts + migration 005 (pending_credentials table)
* src/onecli-secrets.ts (createSecret CLI facade, only caller was credentials.ts)
* findCredentialResponse from agent-runner DB layer
* PendingCredential types
* Four credential hooks from ChannelSetup (getCredentialForModal,
  onCredentialReject, onCredentialSubmit, onCredentialChannelUnsupported)
* Credential card/modal handling in chat-sdk-bridge (nccr/nccm prefixes,
  Modal/TextInput imports)
* credential_request text fallback in WhatsApp adapter
* request_credential system-action case in delivery.ts

Added:
* Migration 009 drops pending_credentials on existing installs.

Vercel skill now tells the agent to ask the user to register the token via
OneCLI instead of invoking the removed tool.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-16 21:41:41 +03:00
gavrielc
e55ed0f4e8 fix(whatsapp): upgrade Baileys 6.7→6.17, fix proto import and 515 restart
Baileys 6.7.21 silently failed the pairing handshake. Upgrade to 6.17.16
which fixes this. Three related issues:

1. proto is no longer a named ESM export in 6.17.x — use createRequire
   to import via CJS (matching the proven v1 pattern).
2. Setup auth script didn't handle the 515 stream restart that WhatsApp
   sends after successful pairing. Refactored to reconnect (matching v1's
   connectSocket(isReconnect) pattern) instead of hanging until timeout.
3. Added succeeded guard and process.exit(0) to prevent timeout race
   after successful auth.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 21:01:55 +03:00
exe.dev user
cdf18e608f feat(v2): add update_task MCP tool, dedup list_tasks by series
update_task lets the agent adjust prompt/recurrence/processAfter/script
on a live scheduled task without losing the series id the user already
knows. Empty string clears recurrence/script.

list_tasks now groups by series_id so recurring tasks show as one row
(the live pending/paused occurrence) instead of one per firing — the
id displayed is the stable series handle that update/cancel/pause/resume
all match against.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-16 16:31:29 +00:00
exe.dev user
8ef30ad289 fix(v2): cancel/pause/resume recurring tasks via series_id
Recurring tasks spawn a new messages_in row per occurrence. Cancel
only matched the completed row the agent remembered, leaving the
live next occurrence running. Tag every row in a recurrence chain
with the originating task's id (series_id) so cancel/pause/resume
can reach any live row in the series. Cancel also clears recurrence
to prevent the sweep from cloning a cancelled task. Kind-aware id
prefix on recurrences (task- instead of msg-) keeps list_tasks output
consistent across occurrences.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-16 16:31:29 +00:00
exe.dev user
419d04fee0 chore(agent-runner): sync package-lock for existing deps
better-sqlite3 and @types/better-sqlite3 were declared in package.json
but missing from the lockfile. Ran `npm install` (needed to get tsc
working locally) and it patched the entries in. No code or behaviour
changes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 16:31:29 +00:00
exe.dev user
4c46dd3b39 fix(v2): await handleRecurrence so the DB isn't closed mid-flight
sweepSession called handleRecurrence without await, then synchronously
closed inDb in its finally block. handleRecurrence is async because it
does a dynamic `import('cron-parser')` before the first DB write; that
import resolved after the finally had already run, so insertRecurrence
hit a closed handle and threw "The database connection is not open".

Net effect: every recurring task was correctly marked completed by
syncProcessingAcks, but its next occurrence never got scheduled.
Single-word fix — `await`.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 16:31:29 +00:00