411 Commits

Author SHA1 Message Date
gavrielc
845da49fa3 fix: prettier formatting for telegram.ts
Pre-existing formatting issue that causes CI format check to fail.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 12:08:52 +02:00
gavrielc
272cbcf18f fix: update sendMessage test expectations for Markdown parse_mode
The sendTelegramMessage helper now passes { parse_mode: 'Markdown' }
to bot.api.sendMessage, but three tests still expected only two args.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 12:06:28 +02:00
github-actions[bot]
90d38388ad Merge branch 'main' into skill/apple-container 2026-03-10 20:59:38 +00:00
gavrielc
0cfdde46c6 fix: remove claude plugin marketplace commands (skills are local now)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 22:59:23 +02:00
github-actions[bot]
5d226ba56c Merge branch 'main' into skill/apple-container 2026-03-10 20:52:02 +00:00
gavrielc
04fb44e417 fix: setup registration — use initDatabase/setRegisteredGroup, .ts imports, correct CLI commands
- setup/register.ts: replace inline DB logic with initDatabase() + setRegisteredGroup()
  (fixes missing is_main column on existing DBs, .js MODULE_NOT_FOUND with tsx)
- SKILL.md (telegram, slack, discord): replace broken registerGroup() pseudo-code
  with actual `npx tsx setup/index.ts --step register` commands
- docs/SPEC.md: fix registerGroup → setRegisteredGroup in example

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 22:51:40 +02:00
gavrielc
7061480ac0 fix: add concurrency group to prevent parallel fork-sync races 2026-03-10 22:43:00 +02:00
github-actions[bot]
6c8216e255 Merge branch 'main' into skill/apple-container 2026-03-10 20:39:54 +00:00
gavrielc
d8a1ee8c3c fix: use npm ci in bootstrap to prevent dirty lockfile blocking merges
setup.sh ran npm install which modified package-lock.json, causing
git merge to refuse during channel skill installation. Switch to
npm ci (deterministic, doesn't modify lockfile) and clean up stale
peer flags in the lockfile.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 22:39:26 +02:00
gavrielc
51ad949979 fix: re-fetch before skill branch merges to avoid stale refs 2026-03-10 22:28:12 +02:00
gavrielc
018deca3ef fix: use GitHub App token for fork-sync (workflows permission needed) 2026-03-10 22:16:02 +02:00
gavrielc
15ed3cf2a6 fix: repair escaped newlines in fork-sync workflow 2026-03-10 22:10:37 +02:00
gavrielc
107f9742a9 fix: update sync condition to check repo name, not owner 2026-03-10 22:00:36 +02:00
gavrielc
5a0bda8d37 Merge pull request #8 from Jimbo1167/feat/markdown-formatting
feat: add Markdown formatting for outbound messages
2026-03-10 18:41:21 +02:00
James Schindler
9a4fb61f6e feat: add Markdown formatting for outbound messages
Wrap outbound sendMessage calls with parse_mode: 'Markdown' so that
Claude's natural formatting (*bold*, _italic_, `code`, etc.) renders
correctly in Telegram instead of showing raw asterisks and underscores.

Falls back to plain text if Telegram rejects the Markdown formatting.
2026-03-10 11:58:00 -04:00
Michael Bravo
5ca0633c27 fix: refresh tasks snapshot immediately after IPC task mutations
Previously, current_tasks.json was only written at container-start time,
so tasks created (or paused/cancelled/updated) during a session were
invisible to list_tasks until the next invocation.

Add an onTasksChanged callback to IpcDeps, called after every successful
mutation in processTaskIpc (schedule_task, pause_task, resume_task,
cancel_task, update_task). index.ts wires it up to write fresh snapshots
for all registered groups immediately, keeping no new coupling between
ipc.ts and the container layer.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 15:59:52 +02:00
github-actions[bot]
b66b123886 Merge branch 'main' into skill/apple-container 2026-03-10 00:25:36 +00:00
gavrielc
d572bab5c6 feat: add marketplace skills as local project skills
Move skill definitions from the nanoclaw-skills marketplace plugin
into .claude/skills/ so they're available as unprefixed slash commands
(e.g. /add-whatsapp instead of /nanoclaw-skills:add-whatsapp).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 02:25:17 +02:00
gavrielc
b0c2c835ff Merge commit '4cdd09c' into rebuild-fork 2026-03-10 01:15:20 +02:00
gavrielc
2eb5871454 Merge remote-tracking branch 'telegram/main' into rebuild-fork 2026-03-10 01:11:48 +02:00
gavrielc
621fde8c75 fix: update marketplace cache before installing skills plugin in setup 2026-03-10 01:05:41 +02:00
gavrielc
f41b399aa1 fix: register marketplace and install channel skills individually in setup 2026-03-10 01:03:26 +02:00
gavrielc
4dee68c230 fix: run npm install after channel merges in setup to catch new dependencies 2026-03-10 00:57:18 +02:00
gavrielc
b913a37c21 ci: remove old merge-forward-skills.yml (replaced by fork-sync-skills.yml) 2026-03-10 00:53:51 +02:00
gavrielc
d487faf55a ci: rename sync workflow to fork-sync-skills.yml to avoid merge conflicts with core 2026-03-10 00:53:40 +02:00
gavrielc
e6ea914ef1 ci: add repo guard to merge-forward workflow to prevent conflicts on forks 2026-03-10 00:53:33 +02:00
github-actions[bot]
8564937d93 docs: update token count to 38.8k tokens · 19% of context window 2026-03-09 22:19:01 +00:00
gavrielc
5118239cea feat: skills as branches, channels as forks
Replace the custom skills engine with standard git operations.
Feature skills are now git branches (on upstream or channel forks)
applied via `git merge`. Channels are separate fork repos.

- Remove skills-engine/ (6,300+ lines), apply/uninstall/rebase scripts
- Remove old skill format (add/, modify/, manifest.yaml) from all skills
- Remove old CI (skill-drift.yml, skill-pr.yml)
- Add merge-forward CI for upstream skill branches
- Add fork notification (repository_dispatch to channel forks)
- Add marketplace config (.claude/settings.json)
- Add /update-skills operational skill
- Update /setup and /customize for marketplace plugin install
- Add docs/skills-as-branches.md architecture doc

Channel forks created: nanoclaw-whatsapp (with 5 skill branches),
nanoclaw-telegram, nanoclaw-discord, nanoclaw-slack, nanoclaw-gmail.

Upstream retains: skill/ollama-tool, skill/apple-container, skill/compact.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 00:18:25 +02:00
gavrielc
5acab2c09d ci: add upstream sync and merge-forward workflow
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 23:43:19 +02:00
gavrielc
27e241c13e Merge remote-tracking branch 'origin/main' into skill/telegram 2026-03-09 23:21:10 +02:00
gavrielc
4cdd09c45c Merge remote-tracking branch 'origin/main' into skill/apple-container
# Conflicts:
#	src/container-runner.ts
2026-03-09 23:20:34 +02:00
github-actions[bot]
e7852a45a5 chore: bump version to 1.2.12 2026-03-08 22:27:26 +00:00
Gabi Simons
13ce4aaf67 feat: enhance container environment isolation via credential proxy (#798)
* feat: implement credential proxy for enhanced container environment isolation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address PR review — bind proxy to loopback, scope OAuth injection, add tests

- Bind credential proxy to 127.0.0.1 instead of 0.0.0.0 (security)
- OAuth mode: only inject Authorization on token exchange endpoint
- Add 5 integration tests for credential-proxy.ts
- Remove dangling comment
- Extract host gateway into container-runtime.ts abstraction
- Update Apple Container skill for credential proxy compatibility

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: scope OAuth token injection by header presence instead of path

Path-based matching missed auth probe requests the CLI sends before
the token exchange. Now the proxy replaces Authorization only when
the container actually sends one, leaving x-api-key-only requests
(post-exchange) untouched.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: bind credential proxy to docker0 bridge IP on Linux

On bare-metal Linux Docker, containers reach the host via the bridge IP
(e.g. 172.17.0.1), not loopback. Detect the docker0 interface address
via os.networkInterfaces() and bind there instead of 0.0.0.0, so the
proxy is reachable by containers but not exposed to the LAN.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: bind credential proxy to loopback on WSL

WSL uses Docker Desktop with the same VM routing as macOS, so
127.0.0.1 is correct and secure. Without this, the fallback to
0.0.0.0 was triggered because WSL has no docker0 interface.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: detect WSL via /proc instead of env var

WSL_DISTRO_NAME isn't set under systemd. Use
/proc/sys/fs/binfmt_misc/WSLInterop which is always present on WSL.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 00:27:13 +02:00
gavrielc
16559e9dbf Merge remote-tracking branch 'origin/main' into skill/telegram 2026-03-09 00:07:58 +02:00
gavrielc
2f1933775c Merge remote-tracking branch 'origin/main' into skill/apple-container 2026-03-09 00:07:58 +02:00
Akshan Krithick
8521e42f7b Add /compact skill for manual context compaction (#817)
* feat: add /compact skill for manual context compaction

added /compact session command to fight context rot in long-running sessions. Uses Claude Agent SDK's built-in /compact command with auth gating (main-group or is_from_me only).

* simplify: remove group-queue modification, streamline denied path confirmed against fresh-clone merge.

* refactor: extract handleSessionCommand from index.ts into session-commands.ts

Verified: 345/345 tests pass on fresh-clone merge.
2026-03-08 23:59:17 +02:00
gavrielc
7c04dafa3d Merge remote-tracking branch 'origin/main' into skill/apple-container 2026-03-08 23:24:40 +02:00
gavrielc
a6dc297722 Merge remote-tracking branch 'origin/main' into skill/telegram 2026-03-08 23:24:39 +02:00
gavrielc
0161ba508a skill/apple-container: switch runtime from Docker to Apple Container
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 23:18:06 +02:00
gavrielc
83b91b3bf1 skill/telegram: Telegram channel integration
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 22:43:37 +02:00
github-actions[bot]
4ccc5c57f2 chore: bump version to 1.2.11 2026-03-08 19:43:31 +00:00
glifocat
a689a18dfa fix: close task container promptly when agent uses IPC-only messaging (#840)
Scheduled tasks that send messages via send_message (IPC) instead of
returning text as result left the container idle for ~30 minutes until
the hard timeout killed it (exit 137). This blocked new messages for
the group during that window.

Root cause: scheduleClose() was only called inside the
`if (streamedOutput.result)` branch. Tasks that communicate solely
through IPC (e.g. heartbeat check-ins) complete with result=null,
so the 10s close timer was never set.

Fix: also call scheduleClose() on status==='success', covering both
result-based and IPC-only task completions.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 21:43:21 +02:00
Yonatan Azrielant
ab9abbb21a feat(skill): add WhatsApp reactions skill (emoji reactions + status tracker) (#509)
* feat(skill): add reactions skill (emoji reactions + status tracker)

* refactor(reactions): minimize overlays per upstream review

Address gavrielc's review on qwibitai/nanoclaw#509:
- SKILL.md: remove all inline code, follow add-telegram/add-whatsapp pattern (465→79 lines)
- Rebuild overlays as minimal deltas against upstream/main base
- ipc-mcp-stdio.ts: upstream base + only react_to_message tool (8% delta)
- ipc.ts: upstream base + only reactions delta (14% delta)
- group-queue.test.ts: upstream base + isActive tests only (5% delta)
- Remove group-queue.ts overlay (isActive provided by container-hardening)
- Remove group-queue.ts from manifest modifies list

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 20:02:20 +02:00
glifocat
5b2bafd7bb fix(whatsapp): use sender's JID for DM-with-bot registration, skip trigger (#751)
Two bugs in the DM with dedicated bot number setup:

1. The skill asked for the bot's own phone number to use as the JID.
   But from the bot's perspective, incoming DMs appear with the SENDER's
   JID (the user's personal number), not the bot's own number. The
   registration must use the user's personal number as the JID.

2. DM with bot (1:1 conversation) should use --no-trigger-required, same
   as self-chat. A trigger prefix is unnecessary in a private DM.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 19:58:48 +02:00
Thomas Lok
cfabdd816b fix broken step references in setup/SKILL.md (#794) 2026-03-07 20:58:52 +02:00
glifocat
af937d6453 feat(skills): add image vision skill for WhatsApp (#770)
* chore: prepare image-vision skill for template regeneration

- Delete stale modify/*.ts templates (built against 1.1.2)
- Update core_version to 1.2.6
- Strip fork-specific details from intent docs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(skills): regenerate image-vision modify/ templates against upstream

Templates regenerated against upstream 1.2.6:
- src/container-runner.ts: imageAttachments field in ContainerInput
- src/index.ts: parseImageReferences + threading to runAgent
- src/channels/whatsapp.ts: downloadMediaMessage + image handling block
- src/channels/whatsapp.test.ts: image mocks + 4 test cases
- container/agent-runner/src/index.ts: ContentBlock types, pushMultimodal, image loading

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* test: update image-vision tests for upstream templates

- Relax downloadMediaMessage import pattern check (multi-line import)
- Remove check for [Image - processing failed] (not in upstream template)
- Add vitest.skills.config.ts for skill package test runs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: update image-vision core_version to 1.2.8

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 18:52:59 +02:00
glifocat
be1991108b fix(whatsapp): write pairing code to file for immediate access (#745)
The pairing code was only emitted to stdout, which is buffered by the
calling process and not visible until the auth command exits (~120s).
By also writing to store/pairing-code.txt the moment the code is ready,
callers can poll that file and display the code to the user within seconds
instead of after the 60s expiry window.

Update the add-whatsapp skill instructions to use the background +
file-poll pattern instead of waiting on buffered stdout.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 18:51:00 +02:00
glifocat
0b260ece57 feat(skills): add pdf-reader skill (#772)
Thanks @glifocat! Clean skill package — good docs, solid tests, nice intent files. Pushed a small fix for path traversal on the PDF filename before merging.
2026-03-06 18:47:12 +02:00
github-actions[bot]
1e89d61928 docs: update token count to 37.5k tokens · 19% of context window 2026-03-06 16:35:15 +00:00
github-actions[bot]
cf99b833b0 chore: bump version to 1.2.10 2026-03-06 16:35:08 +00:00