38 Commits

Author SHA1 Message Date
glifocat 069928a445 fix(ci): update update-tokens repo guard 2026-05-10 23:24:56 +02:00
glifocat 45189abaf1 fix(ci): update bump-version repo guard 2026-05-10 23:24:46 +02:00
glifocat 2b51a4e707 fix(workflows): label PRs from forks that follow the contributing template
On a fork PR, GITHUB_TOKEN is demoted to read-only regardless of the
workflow's permissions: block, so issues.addLabels() returns 403. The
label workflow silently works for PRs that skip the template (no
checkboxes ticked → no API call) and fails for PRs that actually
follow it — a hostile incentive against contributors who do the right
thing.

pull_request_target runs in the context of the base branch with full
declared permissions, which is the documented fix for this case. Safe
here because the workflow is metadata-only: it reads
context.payload.pull_request.body and calls addLabels. No checkout,
no PR-supplied code executes. A SECURITY comment is added above the
trigger to keep it that way.

Refs:
- https://docs.github.com/en/actions/reference/events-that-trigger-workflows#pull_request_target
- https://securitylab.github.com/resources/github-actions-preventing-pwn-requests/

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 12:50:25 +02: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
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
gavrielc ab9613a2b0 Merge branch 'main' into fix/ci-fork-guards 2026-03-25 23:10:07 +02:00
gavrielc d4073a01c5 chore: remove auto-sync GitHub Actions
These workflows auto-resolved package.json conflicts with --theirs,
silently stripping fork-specific dependencies during upstream syncs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 14:08:59 +02:00
gavrielc 616c1ae10a fix: expand auto-resolve patterns and add missing forks to dispatch
- Auto-resolve .env.example (keep fork's channel-specific vars) and
  .github/workflows/* (always take upstream) during fork sync
- Add docker-sandbox and docker-sandbox-windows to dispatch list

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 00:44:30 +02:00
gavrielc bf9b7d0311 fix: auto-resolve package-lock/badge/version conflicts in fork sync
The fork-sync and merge-forward workflows were failing on every run
because package-lock.json, package.json (version), and badge.svg
always conflict between upstream and forks. These are always safe to
take from upstream/main. Now auto-resolves these trivial conflicts
and only fails on real code conflicts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 00:39:20 +02:00
gavrielc 57e520c7e1 Merge origin/main: catch up with upstream (OneCLI, diagnostics, credential proxy)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 00:34:29 +02:00
Shawn Yeager d40affbdef fix: skip bump-version and update-tokens on forks
These workflows use APP_ID/APP_PRIVATE_KEY secrets that only exist on
the upstream repo. Without a fork guard they fail on every push for
every fork. merge-forward-skills already has the correct guard.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 13:41:20 +00:00
gavrielc ec1b14504b docs: update contributing guidelines and skill type taxonomy
- Rewrite CONTRIBUTING.md with four skill types (feature, utility,
  operational, container), PR requirements, pre-submission checklist
- Update PR template with skill type checkboxes and docs option
- Add label-pr workflow to auto-label PRs from template checkboxes
- Add hidden template version marker (v1) for follows-guidelines label
- Update CLAUDE.md with skill types overview and contributing instruction
- Update skills-as-branches.md to reference full taxonomy
- Remove /clear from README RFS (already exists as /add-compact)
- Delete obsolete docs (nanorepo-architecture.md, nanoclaw-architecture-final.md)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:08:42 +02:00
gavrielc 696ae5e872 Merge remote-tracking branch 'telegram/main'
# Conflicts:
#	repo-tokens/badge.svg
2026-03-14 15:01:08 +02:00
gavrielc 7e9a698aa1 feat: add nanoclaw-docker-sandboxes to fork dispatch list
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 12:30:14 +02:00
gavrielc 7061480ac0 fix: add concurrency group to prevent parallel fork-sync races 2026-03-10 22:43:00 +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 2eb5871454 Merge remote-tracking branch 'telegram/main' into rebuild-fork 2026-03-10 01:11:48 +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
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
Gabi Simons 11c201088b refactor: CI optimization, logging improvements, and codebase formatting (#456)
* fix(db): remove unique constraint on folder to support multi-channel agents

* ci: implement automated skill drift detection and self-healing PRs

* fix: align registration logic with Gavriel's feedback and fix build/test issues from Daniel Mi

* style: conform to prettier standards for CI validation

* test: fix branch naming inconsistency in CI (master vs main)

* fix(ci): robust module resolution by removing file extensions in scripts

* refactor(ci): simplify skill validation by removing redundant combination tests

* style: conform skills-engine to prettier, unify logging in index.ts and cleanup unused imports

* refactor: extract multi-channel DB changes to separate branch

Move channel column, folder suffix logic, and related migrations
to feat/multi-channel-db-v2 for independent review. This PR now
contains only CI/CD optimizations, Prettier formatting, and
logging improvements.

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 23:13:36 +02:00
gavrielc ee1dab8f81 chore: add gabi-simons as codeowner for core paths
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 18:31:01 +02:00
gavrielc f59ca7cd6d docs: make /update skill discoverable, add auto version bumping
Add /update to skills tables in CLAUDE.md and REQUIREMENTS.md. Add
"Updating" section to README. Remove /add-telegram and /add-discord
from RFS (already exist). Add CI workflow to bump patch version on
source/container changes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 02:04:55 +02:00
gavrielc 7181c49ada feat: add /convert-to-apple-container skill, remove /convert-to-docker (#324)
Docker is now the default runtime. The /convert-to-apple-container skill
uses the new skills engine format (manifest.yaml, modify/, intent files,
tests/) to switch to Apple Container on macOS.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 14:57:05 +02:00
gavrielc 51788de3b9 Skills engine v0.1 + multi-channel infrastructure (#307)
* refactor: multi-channel infrastructure with explicit channel/is_group tracking

- Add channels[] array and findChannel() routing in index.ts, replacing
  hardcoded whatsapp.* calls with channel-agnostic callbacks
- Add channel TEXT and is_group INTEGER columns to chats table with
  COALESCE upsert to protect existing values from null overwrites
- is_group defaults to 0 (safe: unknown chats excluded from groups)
- WhatsApp passes explicit channel='whatsapp' and isGroup to onChatMetadata
- getAvailableGroups filters on is_group instead of JID pattern matching
- findChannel logs warnings instead of silently dropping unroutable JIDs
- Migration backfills channel/is_group from JID patterns for existing DBs

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

* feat: skills engine v0.1 — deterministic skill packages with rerere resolution

Three-way merge engine for applying skill packages on top of a core
codebase. Skills declare which files they add/modify, and the engine
uses git merge-file for conflict detection with git rerere for
automatic resolution of previously-seen conflicts.

Key components:
- apply: three-way merge with backup/rollback safety net
- replay: clean-slate replay for uninstall and rebase
- update: core version updates with deletion detection
- rebase: bake applied skills into base (one-way)
- manifest: validation with path traversal protection
- resolution-cache: pre-computed rerere resolutions
- structured: npm deps, env vars, docker-compose merging
- CI: per-skill test matrix with conflict detection

151 unit tests covering merge, rerere, backup, replay, uninstall,
update, rebase, structured ops, and edge cases.

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

* feat: add Discord and Telegram skill packages

Skill packages for adding Discord and Telegram channels to NanoClaw.
Each package includes:
- Channel implementation (add/src/channels/)
- Three-way merge targets for index.ts, config.ts, routing.test.ts
- Intent docs explaining merge invariants
- Standalone integration tests
- manifest.yaml with dependency/conflict declarations

Applied via: npx tsx scripts/apply-skill.ts .claude/skills/add-discord
These are inert until applied — no runtime impact.

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

* remove unused docs (skills-system-status, implementation-guide)

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 01:55:00 +02:00
gavrielc 5031d0f0d8 ci: add workflow_dispatch trigger to token count workflow (#254)
Allows manual triggering for testing and on-demand badge updates.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 17:33:45 +02:00
gavrielc c467941804 fix: add git pull --rebase before push in token count workflow (#253)
Prevents push failures when remote has newer commits since checkout.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 17:31:57 +02:00
gavrielc e4d77cdba0 fix: use GitHub App token for token count workflow
Switches from default GITHUB_TOKEN to a scoped GitHub App token
so the workflow can push to the protected main branch.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 17:11:48 +02:00
gavrielc c8ab3d95e1 feat: add repo-tokens GitHub Action with token count badge
Reusable composite action that counts codebase tokens using tiktoken
and generates a shields.io-style SVG badge. Color reflects context
window usage: green (<30%), yellow-green (30-50%), yellow (50-70%),
red (70%+). Badge includes hardcoded link back to repo-tokens.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 01:41:14 +02:00
gavrielc 464735347c chore: add /groups/ and /launchd/ to CODEOWNERS
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 10:18:15 +02:00
gavrielc 8eb80d4ed0 fix: prevent infinite message replay on container timeout (#164)
Container timeout and idle timeout both fire at 30min, racing the
graceful shutdown. The hard kill returns error status, rolling back
the message cursor even though output was already sent — causing
duplicate messages indefinitely.

- Grace period: hard timeout is now IDLE_TIMEOUT + 30s minimum
- Timeout after output resolves as success (idle cleanup, not failure)
- Don't roll back cursor if output was already sent to user
- Remove src/telegram.ts and config vars (added to PR #156 by mistake)
- Add typecheck step to CI workflow
- Add container-runner timeout behavior tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 17:25:42 +02:00
gavrielc 2b56fecfdc Refactor index (#156)
* feat: add Telegram channel with agent swarm support

Add Telegram as a messaging channel that can run alongside WhatsApp
or standalone (TELEGRAM_ONLY mode). Includes bot pool support for
agent swarms where each subagent appears as a different bot identity
in the group.

- Add grammy dependency for Telegram Bot API
- Route messages through tg: JID prefix convention
- Add storeMessageDirect for non-Baileys channels
- Add sender field to IPC send_message for swarm identity
- Support TELEGRAM_BOT_TOKEN, TELEGRAM_ONLY, TELEGRAM_BOT_POOL config

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

* docs: add index.ts refactor plan

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

* refactor: extract channel abstraction, IPC, and router from index.ts

Break the 1088-line monolith into focused modules:
- src/channels/whatsapp.ts: WhatsAppChannel class implementing Channel interface
- src/ipc.ts: IPC watcher and task processing with dependency injection
- src/router.ts: message formatting, outbound routing, channel lookup
- src/types.ts: Channel interface, OnInboundMessage, OnChatMetadata types

Also adds regression test suite (98 tests), updates all documentation
and skill files to reflect the new architecture.

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

* ci: add test workflow for PRs

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

* chore: remove accidentally committed pool-bot assets

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

* fix(ci): remove grammy from base dependencies

Grammy is installed by the /add-telegram skill, not a base dependency.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 00:36:37 +02:00
gavrielc 722351159e Add contribution guidelines and PR checks for skills-only model
- CONTRIBUTING.md: Explain accepted source changes vs skills
- PR template: Checkboxes for contribution type
- CI workflow: Block PRs that add skills while modifying source
- CODEOWNERS: Require maintainer review for source changes

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 13:50:25 +02:00