@openparachute/agent 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/scheduled_tasks.lock +1 -0
- package/.claude/settings.json +5 -0
- package/.claude/skills/add-atomic-chat-tool/SKILL.md +243 -0
- package/.claude/skills/add-atomic-chat-tool/atomic-chat-mcp-stdio.ts +229 -0
- package/.claude/skills/add-codex/SKILL.md +161 -0
- package/.claude/skills/add-dashboard/SKILL.md +138 -0
- package/.claude/skills/add-dashboard/resources/dashboard-pusher.ts +495 -0
- package/.claude/skills/add-emacs/SKILL.md +296 -0
- package/.claude/skills/add-gcal-tool/SKILL.md +210 -0
- package/.claude/skills/add-gchat/REMOVE.md +6 -0
- package/.claude/skills/add-gchat/SKILL.md +92 -0
- package/.claude/skills/add-gchat/VERIFY.md +3 -0
- package/.claude/skills/add-github/REMOVE.md +6 -0
- package/.claude/skills/add-github/SKILL.md +148 -0
- package/.claude/skills/add-github/VERIFY.md +3 -0
- package/.claude/skills/add-gmail-tool/SKILL.md +229 -0
- package/.claude/skills/add-imessage/REMOVE.md +6 -0
- package/.claude/skills/add-imessage/SKILL.md +113 -0
- package/.claude/skills/add-imessage/VERIFY.md +3 -0
- package/.claude/skills/add-karpathy-llm-wiki/SKILL.md +110 -0
- package/.claude/skills/add-karpathy-llm-wiki/llm-wiki.md +75 -0
- package/.claude/skills/add-linear/REMOVE.md +6 -0
- package/.claude/skills/add-linear/SKILL.md +168 -0
- package/.claude/skills/add-linear/VERIFY.md +3 -0
- package/.claude/skills/add-macos-statusbar/SKILL.md +133 -0
- package/.claude/skills/add-macos-statusbar/add/src/statusbar.swift +147 -0
- package/.claude/skills/add-matrix/REMOVE.md +6 -0
- package/.claude/skills/add-matrix/SKILL.md +148 -0
- package/.claude/skills/add-matrix/VERIFY.md +3 -0
- package/.claude/skills/add-ollama-provider/SKILL.md +179 -0
- package/.claude/skills/add-ollama-tool/SKILL.md +193 -0
- package/.claude/skills/add-opencode/SKILL.md +229 -0
- package/.claude/skills/add-parallel/SKILL.md +290 -0
- package/.claude/skills/add-resend/REMOVE.md +6 -0
- package/.claude/skills/add-resend/SKILL.md +93 -0
- package/.claude/skills/add-resend/VERIFY.md +3 -0
- package/.claude/skills/add-signal/REMOVE.md +13 -0
- package/.claude/skills/add-signal/SKILL.md +318 -0
- package/.claude/skills/add-signal/VERIFY.md +5 -0
- package/.claude/skills/add-slack/REMOVE.md +6 -0
- package/.claude/skills/add-slack/SKILL.md +112 -0
- package/.claude/skills/add-slack/VERIFY.md +3 -0
- package/.claude/skills/add-teams/REMOVE.md +6 -0
- package/.claude/skills/add-teams/SKILL.md +207 -0
- package/.claude/skills/add-teams/VERIFY.md +3 -0
- package/.claude/skills/add-vercel/SKILL.md +147 -0
- package/.claude/skills/add-vercel/container-skills/vercel-cli/SKILL.md +103 -0
- package/.claude/skills/add-webex/REMOVE.md +6 -0
- package/.claude/skills/add-webex/SKILL.md +88 -0
- package/.claude/skills/add-webex/VERIFY.md +3 -0
- package/.claude/skills/add-wechat/REMOVE.md +49 -0
- package/.claude/skills/add-wechat/SKILL.md +170 -0
- package/.claude/skills/add-wechat/scripts/wire-dm.ts +172 -0
- package/.claude/skills/add-whatsapp/SKILL.md +264 -0
- package/.claude/skills/add-whatsapp-cloud/REMOVE.md +6 -0
- package/.claude/skills/add-whatsapp-cloud/SKILL.md +95 -0
- package/.claude/skills/add-whatsapp-cloud/VERIFY.md +3 -0
- package/.claude/skills/claw/SKILL.md +131 -0
- package/.claude/skills/claw/scripts/claw +374 -0
- package/.claude/skills/convert-to-apple-container/SKILL.md +212 -0
- package/.claude/skills/customize/SKILL.md +110 -0
- package/.claude/skills/debug/SKILL.md +349 -0
- package/.claude/skills/get-qodo-rules/SKILL.md +122 -0
- package/.claude/skills/get-qodo-rules/references/output-format.md +41 -0
- package/.claude/skills/get-qodo-rules/references/pagination.md +33 -0
- package/.claude/skills/get-qodo-rules/references/repository-scope.md +26 -0
- package/.claude/skills/init-first-agent/SKILL.md +120 -0
- package/.claude/skills/init-onecli/SKILL.md +270 -0
- package/.claude/skills/manage-channels/SKILL.md +87 -0
- package/.claude/skills/manage-mounts/SKILL.md +47 -0
- package/.claude/skills/migrate-from-openclaw/MIGRATE_CRONS.md +100 -0
- package/.claude/skills/migrate-from-openclaw/SKILL.md +447 -0
- package/.claude/skills/migrate-from-openclaw/scripts/discover-openclaw.ts +734 -0
- package/.claude/skills/migrate-from-openclaw/scripts/extract-channel-credentials.ts +476 -0
- package/.claude/skills/migrate-nanoclaw/SKILL.md +484 -0
- package/.claude/skills/migrate-nanoclaw/diagnostics.md +51 -0
- package/.claude/skills/qodo-pr-resolver/SKILL.md +326 -0
- package/.claude/skills/qodo-pr-resolver/resources/providers.md +329 -0
- package/.claude/skills/update-nanoclaw/SKILL.md +243 -0
- package/.claude/skills/update-nanoclaw/diagnostics.md +48 -0
- package/.claude/skills/update-skills/SKILL.md +130 -0
- package/.claude/skills/use-native-credential-proxy/SKILL.md +167 -0
- package/.claude/skills/x-integration/SKILL.md +417 -0
- package/.claude/skills/x-integration/agent.ts +243 -0
- package/.claude/skills/x-integration/host.ts +155 -0
- package/.claude/skills/x-integration/lib/browser.ts +148 -0
- package/.claude/skills/x-integration/lib/config.ts +62 -0
- package/.claude/skills/x-integration/scripts/like.ts +56 -0
- package/.claude/skills/x-integration/scripts/post.ts +66 -0
- package/.claude/skills/x-integration/scripts/quote.ts +80 -0
- package/.claude/skills/x-integration/scripts/reply.ts +74 -0
- package/.claude/skills/x-integration/scripts/retweet.ts +62 -0
- package/.claude/skills/x-integration/scripts/setup.ts +87 -0
- package/.github/CODEOWNERS +10 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +18 -0
- package/.github/workflows/bump-version.yml +35 -0
- package/.github/workflows/ci.yml +39 -0
- package/.github/workflows/label-pr.yml +40 -0
- package/.github/workflows/update-tokens.yml +43 -0
- package/.husky/pre-commit +1 -0
- package/.mcp.json +3 -0
- package/.nvmrc +1 -0
- package/.parachute/module.json +14 -0
- package/.prettierrc +4 -0
- package/CHANGELOG.md +215 -0
- package/CLAUDE.md +307 -0
- package/CODE_OF_CONDUCT.md +128 -0
- package/CONTRIBUTING.md +159 -0
- package/CONTRIBUTORS.md +26 -0
- package/LICENSE +21 -0
- package/README.md +190 -0
- package/README_ja.md +194 -0
- package/README_zh.md +194 -0
- package/assets/nanoclaw-favicon.png +0 -0
- package/assets/nanoclaw-icon.png +0 -0
- package/assets/nanoclaw-logo-dark.png +0 -0
- package/assets/nanoclaw-logo.png +0 -0
- package/assets/nanoclaw-profile.jpeg +0 -0
- package/assets/nanoclaw-sales.png +0 -0
- package/assets/social-preview.jpg +0 -0
- package/config-examples/mount-allowlist.json +25 -0
- package/container/.dockerignore +2 -0
- package/container/CLAUDE.md +21 -0
- package/container/Dockerfile +121 -0
- package/container/agent-runner/bun.lock +243 -0
- package/container/agent-runner/package.json +22 -0
- package/container/agent-runner/scripts/sdk-signal-probe.ts +169 -0
- package/container/agent-runner/src/config.ts +55 -0
- package/container/agent-runner/src/db/connection.ts +267 -0
- package/container/agent-runner/src/db/index.ts +20 -0
- package/container/agent-runner/src/db/messages-in.ts +138 -0
- package/container/agent-runner/src/db/messages-out.ts +143 -0
- package/container/agent-runner/src/db/session-routing.ts +30 -0
- package/container/agent-runner/src/db/session-state.test.ts +100 -0
- package/container/agent-runner/src/db/session-state.ts +79 -0
- package/container/agent-runner/src/destinations.ts +135 -0
- package/container/agent-runner/src/formatter.test.ts +167 -0
- package/container/agent-runner/src/formatter.ts +260 -0
- package/container/agent-runner/src/index.ts +110 -0
- package/container/agent-runner/src/integration.test.ts +121 -0
- package/container/agent-runner/src/mcp-tools/agents.instructions.md +26 -0
- package/container/agent-runner/src/mcp-tools/agents.ts +66 -0
- package/container/agent-runner/src/mcp-tools/core.instructions.md +27 -0
- package/container/agent-runner/src/mcp-tools/core.ts +262 -0
- package/container/agent-runner/src/mcp-tools/index.ts +22 -0
- package/container/agent-runner/src/mcp-tools/interactive.instructions.md +22 -0
- package/container/agent-runner/src/mcp-tools/interactive.ts +169 -0
- package/container/agent-runner/src/mcp-tools/scheduling.instructions.md +40 -0
- package/container/agent-runner/src/mcp-tools/scheduling.ts +299 -0
- package/container/agent-runner/src/mcp-tools/self-mod.instructions.md +25 -0
- package/container/agent-runner/src/mcp-tools/self-mod.ts +120 -0
- package/container/agent-runner/src/mcp-tools/server.ts +54 -0
- package/container/agent-runner/src/mcp-tools/types.ts +6 -0
- package/container/agent-runner/src/poll-loop.test.ts +248 -0
- package/container/agent-runner/src/poll-loop.ts +437 -0
- package/container/agent-runner/src/providers/claude.ts +379 -0
- package/container/agent-runner/src/providers/factory.test.ts +19 -0
- package/container/agent-runner/src/providers/factory.ts +13 -0
- package/container/agent-runner/src/providers/index.ts +6 -0
- package/container/agent-runner/src/providers/mock.ts +77 -0
- package/container/agent-runner/src/providers/provider-registry.ts +33 -0
- package/container/agent-runner/src/providers/types.ts +82 -0
- package/container/agent-runner/src/scheduling/task-script.ts +121 -0
- package/container/agent-runner/src/timezone.test.ts +93 -0
- package/container/agent-runner/src/timezone.ts +107 -0
- package/container/agent-runner/tsconfig.json +14 -0
- package/container/build.sh +48 -0
- package/container/entrypoint.sh +16 -0
- package/container/skills/agent-browser/SKILL.md +159 -0
- package/container/skills/frontend-engineer/SKILL.md +157 -0
- package/container/skills/self-customize/SKILL.md +87 -0
- package/container/skills/slack-formatting/SKILL.md +94 -0
- package/container/skills/vercel-cli/SKILL.md +111 -0
- package/container/skills/welcome/SKILL.md +85 -0
- package/docs/APPLE-CONTAINER-NETWORKING.md +90 -0
- package/docs/BRANCH-FORK-MAINTENANCE.md +81 -0
- package/docs/README.md +25 -0
- package/docs/SDK_DEEP_DIVE.md +643 -0
- package/docs/SECURITY.md +162 -0
- package/docs/agent-runner-details.md +749 -0
- package/docs/api-details.md +365 -0
- package/docs/architecture-diagram.html +422 -0
- package/docs/architecture-diagram.md +215 -0
- package/docs/architecture.md +751 -0
- package/docs/audit/2026-04-30-channel-endpoint-audit.md +36 -0
- package/docs/build-and-runtime.md +80 -0
- package/docs/cross-mount-stress/README.md +112 -0
- package/docs/cross-mount-stress/container-writer-retry.mjs +55 -0
- package/docs/cross-mount-stress/container-writer-slow.mjs +42 -0
- package/docs/cross-mount-stress/container-writer.mjs +47 -0
- package/docs/cross-mount-stress/host-writer-retry.mjs +55 -0
- package/docs/cross-mount-stress/host-writer-slow.mjs +43 -0
- package/docs/cross-mount-stress/host-writer.mjs +47 -0
- package/docs/db-central.md +316 -0
- package/docs/db-session.md +183 -0
- package/docs/db.md +119 -0
- package/docs/design/2026-04-29-vault-management-ui.md +231 -0
- package/docs/design/2026-04-30-channel-wiring-rework.md +234 -0
- package/docs/design/2026-05-01-channel-wiring-approvals-deep-dive.md +272 -0
- package/docs/design/2026-05-02-channel-policy-and-approval-routing.md +250 -0
- package/docs/docker-sandboxes.md +359 -0
- package/docs/isolation-model.md +88 -0
- package/docs/ollama.md +79 -0
- package/docs/parachute-integration.md +109 -0
- package/docs/post-night-rebirth-reflections.md +151 -0
- package/eslint.config.js +32 -0
- package/package.json +54 -0
- package/pnpm-workspace.yaml +8 -0
- package/repo-tokens/README.md +113 -0
- package/repo-tokens/action.yml +186 -0
- package/repo-tokens/badge.svg +23 -0
- package/repo-tokens/examples/green.svg +14 -0
- package/repo-tokens/examples/red.svg +14 -0
- package/repo-tokens/examples/yellow-green.svg +14 -0
- package/repo-tokens/examples/yellow.svg +14 -0
- package/scripts/chat.ts +101 -0
- package/scripts/cleanup-sessions.sh +150 -0
- package/scripts/init-cli-agent.ts +171 -0
- package/scripts/init-first-agent.ts +377 -0
- package/scripts/parachute.ts +158 -0
- package/scripts/run-migrations.ts +105 -0
- package/scripts/sanity-live-poll.ts +95 -0
- package/scripts/seed-discord.ts +79 -0
- package/scripts/test-v2-agent.ts +106 -0
- package/scripts/test-v2-channel-e2e.ts +265 -0
- package/scripts/test-v2-host.ts +184 -0
- package/src/channels/adapter.ts +214 -0
- package/src/channels/ask-question.ts +46 -0
- package/src/channels/channel-registry.test.ts +421 -0
- package/src/channels/channel-registry.ts +313 -0
- package/src/channels/chat-sdk-bridge.test.ts +84 -0
- package/src/channels/chat-sdk-bridge.ts +652 -0
- package/src/channels/cli.ts +276 -0
- package/src/channels/discord.ts +90 -0
- package/src/channels/index.ts +17 -0
- package/src/channels/telegram-markdown-sanitize.test.ts +78 -0
- package/src/channels/telegram-markdown-sanitize.ts +55 -0
- package/src/channels/telegram-pairing.test.ts +254 -0
- package/src/channels/telegram-pairing.ts +339 -0
- package/src/channels/telegram.ts +279 -0
- package/src/channels/trust-hint.test.ts +48 -0
- package/src/channels/trust-hint.ts +75 -0
- package/src/claude-md-compose.migrate.test.ts +64 -0
- package/src/claude-md-compose.ts +205 -0
- package/src/command-gate.ts +63 -0
- package/src/config.test.ts +93 -0
- package/src/config.ts +108 -0
- package/src/container-config.ts +167 -0
- package/src/container-runner.test.ts +32 -0
- package/src/container-runner.ts +576 -0
- package/src/container-runtime.test.ts +169 -0
- package/src/container-runtime.ts +92 -0
- package/src/db/_bun-sqlite-shim.ts +88 -0
- package/src/db/agent-activity.test.ts +155 -0
- package/src/db/agent-activity.ts +121 -0
- package/src/db/agent-groups.ts +77 -0
- package/src/db/connection.migrate.test.ts +143 -0
- package/src/db/connection.ts +224 -0
- package/src/db/db-v2.test.ts +440 -0
- package/src/db/dropped-messages.ts +44 -0
- package/src/db/index.ts +40 -0
- package/src/db/messaging-groups.ts +252 -0
- package/src/db/migrations/001-initial.ts +112 -0
- package/src/db/migrations/002-chat-sdk-state.ts +36 -0
- package/src/db/migrations/008-dropped-messages.ts +27 -0
- package/src/db/migrations/009-drop-pending-credentials.ts +13 -0
- package/src/db/migrations/010-engage-modes.ts +103 -0
- package/src/db/migrations/011-pending-sender-approvals.ts +40 -0
- package/src/db/migrations/012-channel-registration.ts +48 -0
- package/src/db/migrations/013-approval-render-metadata.ts +27 -0
- package/src/db/migrations/014-secrets.ts +44 -0
- package/src/db/migrations/015-secrets-drop-host-pattern.ts +18 -0
- package/src/db/migrations/016-secret-assignments.ts +30 -0
- package/src/db/migrations/017-agent-activity.ts +40 -0
- package/src/db/migrations/018-oauth-app-configs.ts +34 -0
- package/src/db/migrations/019-oauth-app-connections.ts +48 -0
- package/src/db/migrations/020-agent-app-connections.ts +28 -0
- package/src/db/migrations/021-pending-oauth-states.ts +35 -0
- package/src/db/migrations/022-app-connections-provider.ts +25 -0
- package/src/db/migrations/023-agent-group-secret-mode.test.ts +124 -0
- package/src/db/migrations/023-agent-group-secret-mode.ts +65 -0
- package/src/db/migrations/024-collapse-approvals.test.ts +249 -0
- package/src/db/migrations/024-collapse-approvals.ts +182 -0
- package/src/db/migrations/025-secret-mode-check.test.ts +155 -0
- package/src/db/migrations/025-secret-mode-check.ts +49 -0
- package/src/db/migrations/026-user-dms-bot-id.test.ts +116 -0
- package/src/db/migrations/026-user-dms-bot-id.ts +54 -0
- package/src/db/migrations/027-provider-credentials.ts +41 -0
- package/src/db/migrations/_test-helpers.ts +41 -0
- package/src/db/migrations/index.ts +127 -0
- package/src/db/migrations/module-agent-to-agent-destinations.ts +84 -0
- package/src/db/migrations/module-approvals-pending-approvals.ts +42 -0
- package/src/db/migrations/module-approvals-title-options.ts +40 -0
- package/src/db/schema.ts +258 -0
- package/src/db/session-db.test.ts +93 -0
- package/src/db/session-db.ts +325 -0
- package/src/db/sessions.ts +241 -0
- package/src/delivery.test.ts +148 -0
- package/src/delivery.ts +445 -0
- package/src/env.ts +74 -0
- package/src/group-folder.test.ts +35 -0
- package/src/group-folder.ts +44 -0
- package/src/group-init.ts +92 -0
- package/src/host-core.test.ts +456 -0
- package/src/host-sweep.test.ts +146 -0
- package/src/host-sweep.ts +287 -0
- package/src/index.ts +227 -0
- package/src/install-slug.ts +33 -0
- package/src/log.test.ts +81 -0
- package/src/log.ts +117 -0
- package/src/mcp/http.ts +72 -0
- package/src/mcp/server.ts +92 -0
- package/src/mcp/stdio.ts +51 -0
- package/src/mcp/tools/activity.ts +88 -0
- package/src/mcp/tools/agent-groups.ts +183 -0
- package/src/mcp/tools/approvals.ts +122 -0
- package/src/mcp/tools/channels.ts +199 -0
- package/src/mcp/tools/index.ts +27 -0
- package/src/mcp/tools/oauth.ts +48 -0
- package/src/mcp/tools/secrets.ts +169 -0
- package/src/mcp/tools/sessions.ts +135 -0
- package/src/mcp/types.ts +51 -0
- package/src/modules/agent-to-agent/agent-route.test.ts +46 -0
- package/src/modules/agent-to-agent/agent-route.ts +223 -0
- package/src/modules/agent-to-agent/create-agent.ts +127 -0
- package/src/modules/agent-to-agent/db/agent-destinations.ts +135 -0
- package/src/modules/agent-to-agent/index.ts +22 -0
- package/src/modules/agent-to-agent/write-destinations.ts +59 -0
- package/src/modules/approvals/agent.md +45 -0
- package/src/modules/approvals/index.ts +21 -0
- package/src/modules/approvals/picks.test.ts +291 -0
- package/src/modules/approvals/primitive.ts +279 -0
- package/src/modules/approvals/project.md +27 -0
- package/src/modules/approvals/response-handler.ts +87 -0
- package/src/modules/index.ts +24 -0
- package/src/modules/interactive/agent.md +21 -0
- package/src/modules/interactive/index.ts +69 -0
- package/src/modules/interactive/project.md +12 -0
- package/src/modules/mount-security/index.ts +448 -0
- package/src/modules/mount-security/migrate.test.ts +91 -0
- package/src/modules/permissions/access.ts +28 -0
- package/src/modules/permissions/channel-approval.test.ts +389 -0
- package/src/modules/permissions/channel-approval.ts +188 -0
- package/src/modules/permissions/db/agent-group-members.ts +44 -0
- package/src/modules/permissions/db/pending-channel-approvals.test.ts +86 -0
- package/src/modules/permissions/db/pending-channel-approvals.ts +66 -0
- package/src/modules/permissions/db/pending-sender-approvals.ts +60 -0
- package/src/modules/permissions/db/user-dms.ts +58 -0
- package/src/modules/permissions/db/user-roles.ts +85 -0
- package/src/modules/permissions/db/users.ts +38 -0
- package/src/modules/permissions/index.ts +421 -0
- package/src/modules/permissions/permissions.test.ts +358 -0
- package/src/modules/permissions/sender-approval.test.ts +470 -0
- package/src/modules/permissions/sender-approval.ts +165 -0
- package/src/modules/permissions/user-dm.ts +200 -0
- package/src/modules/provider-credentials/db.ts +121 -0
- package/src/modules/provider-credentials/index.ts +12 -0
- package/src/modules/provider-credentials/spawn.test.ts +206 -0
- package/src/modules/provider-credentials/spawn.ts +114 -0
- package/src/modules/scheduling/actions.ts +113 -0
- package/src/modules/scheduling/db.test.ts +282 -0
- package/src/modules/scheduling/db.ts +148 -0
- package/src/modules/scheduling/index.ts +34 -0
- package/src/modules/scheduling/recurrence.test.ts +98 -0
- package/src/modules/scheduling/recurrence.ts +54 -0
- package/src/modules/self-mod/agent.md +30 -0
- package/src/modules/self-mod/apply.ts +85 -0
- package/src/modules/self-mod/index.ts +30 -0
- package/src/modules/self-mod/project.md +39 -0
- package/src/modules/self-mod/request.ts +91 -0
- package/src/modules/typing/index.ts +165 -0
- package/src/oauth/agent-app-connections.ts +103 -0
- package/src/oauth/app-configs.test.ts +64 -0
- package/src/oauth/app-configs.ts +114 -0
- package/src/oauth/app-connections.test.ts +109 -0
- package/src/oauth/app-connections.ts +178 -0
- package/src/oauth/crypto.ts +56 -0
- package/src/oauth/flow.ts +104 -0
- package/src/oauth/providers/google.test.ts +38 -0
- package/src/oauth/providers/google.ts +46 -0
- package/src/oauth/providers/index.ts +48 -0
- package/src/oauth/state-store.test.ts +54 -0
- package/src/oauth/state-store.ts +93 -0
- package/src/parachute/README.md +27 -0
- package/src/parachute/create-agent.test.ts +83 -0
- package/src/parachute/create-agent.ts +122 -0
- package/src/parachute/group-status.test.ts +165 -0
- package/src/parachute/group-status.ts +136 -0
- package/src/parachute/types.ts +41 -0
- package/src/parachute/vault-mcp.test.ts +251 -0
- package/src/parachute/vault-mcp.ts +232 -0
- package/src/platform-id.test.ts +104 -0
- package/src/platform-id.ts +109 -0
- package/src/providers/index.ts +6 -0
- package/src/providers/provider-container-registry.ts +58 -0
- package/src/response-registry.ts +45 -0
- package/src/router.ts +530 -0
- package/src/secrets/crypto.test.ts +45 -0
- package/src/secrets/crypto.ts +55 -0
- package/src/secrets/index.ts +355 -0
- package/src/secrets/master-key.ts +70 -0
- package/src/secrets/secrets.test.ts +354 -0
- package/src/session-manager.migrate.test.ts +59 -0
- package/src/session-manager.ts +433 -0
- package/src/startup-bootstrap.test.ts +226 -0
- package/src/startup-bootstrap.ts +207 -0
- package/src/state-sqlite.ts +182 -0
- package/src/timezone.test.ts +64 -0
- package/src/timezone.ts +37 -0
- package/src/types.ts +230 -0
- package/src/web/auth.test.ts +335 -0
- package/src/web/auth.ts +214 -0
- package/src/web/discord-validate.test.ts +77 -0
- package/src/web/discord-validate.ts +88 -0
- package/src/web/hub-discovery.test.ts +98 -0
- package/src/web/hub-discovery.ts +69 -0
- package/src/web/routes/activity.ts +106 -0
- package/src/web/routes/agent-provider.test.ts +282 -0
- package/src/web/routes/agent-provider.ts +309 -0
- package/src/web/routes/approvals.ts +185 -0
- package/src/web/routes/apps.ts +434 -0
- package/src/web/routes/channels-mg-detail.test.ts +324 -0
- package/src/web/routes/channels-mga-detail.test.ts +425 -0
- package/src/web/routes/channels.ts +489 -0
- package/src/web/routes/oauth-providers.ts +42 -0
- package/src/web/routes/secrets.test.ts +175 -0
- package/src/web/routes/secrets.ts +282 -0
- package/src/web/routes/sessions.ts +123 -0
- package/src/web/routes/settings.test.ts +106 -0
- package/src/web/routes/settings.ts +247 -0
- package/src/web/routes/setup-status.ts +205 -0
- package/src/web/routes/vaults.test.ts +389 -0
- package/src/web/routes/vaults.ts +225 -0
- package/src/web/server-version.test.ts +16 -0
- package/src/web/server.ts +1003 -0
- package/src/web/services-manifest.test.ts +120 -0
- package/src/web/services-manifest.ts +61 -0
- package/src/web/static-serve.test.ts +255 -0
- package/src/web/static-serve.ts +104 -0
- package/src/web/telegram-validate.test.ts +116 -0
- package/src/web/telegram-validate.ts +107 -0
- package/src/web/vault-proxy.test.ts +214 -0
- package/src/web/vault-proxy.ts +120 -0
- package/src/web/wire-channel.ts +181 -0
- package/src/webhook-server.ts +134 -0
- package/tsconfig.json +21 -0
- package/vitest.config.ts +18 -0
- package/web/README.md +63 -0
- package/web/ui/index.html +13 -0
- package/web/ui/package.json +35 -0
- package/web/ui/pnpm-lock.yaml +2164 -0
- package/web/ui/scripts/verify-base.mjs +31 -0
- package/web/ui/src/App.tsx +88 -0
- package/web/ui/src/components/ActivityFeed.tsx +444 -0
- package/web/ui/src/components/AgentGroupPicker.tsx +263 -0
- package/web/ui/src/components/AgentProviderCards.tsx +220 -0
- package/web/ui/src/components/CredentialForm.tsx +214 -0
- package/web/ui/src/components/ScopeGrants.tsx +74 -0
- package/web/ui/src/components/StatusDot.tsx +43 -0
- package/web/ui/src/components/VaultPicker.tsx +127 -0
- package/web/ui/src/components/setup/AdapterInstallStep.tsx +178 -0
- package/web/ui/src/components/setup/AgentGroupStep.tsx +43 -0
- package/web/ui/src/components/setup/ChannelPickStep.tsx +74 -0
- package/web/ui/src/components/setup/DoneStep.tsx +49 -0
- package/web/ui/src/components/setup/PrereqStep.tsx +129 -0
- package/web/ui/src/components/setup/TestConnectionStep.tsx +108 -0
- package/web/ui/src/components/setup/TestMessageStep.tsx +104 -0
- package/web/ui/src/components/setup/WireChannelStep.tsx +166 -0
- package/web/ui/src/components/setup/types.ts +105 -0
- package/web/ui/src/lib/api.test.ts +410 -0
- package/web/ui/src/lib/api.ts +1210 -0
- package/web/ui/src/lib/auth.test.ts +139 -0
- package/web/ui/src/lib/auth.ts +348 -0
- package/web/ui/src/lib/channel-adapters.ts +136 -0
- package/web/ui/src/main.tsx +19 -0
- package/web/ui/src/routes/ApprovalsList.tsx +294 -0
- package/web/ui/src/routes/Apps.tsx +613 -0
- package/web/ui/src/routes/ChannelWireDetail.test.tsx +233 -0
- package/web/ui/src/routes/ChannelWireDetail.tsx +403 -0
- package/web/ui/src/routes/ChannelsList.tsx +158 -0
- package/web/ui/src/routes/GroupDetail.tsx +755 -0
- package/web/ui/src/routes/GroupList.tsx +187 -0
- package/web/ui/src/routes/MessagingGroupDetail.test.tsx +233 -0
- package/web/ui/src/routes/MessagingGroupDetail.tsx +306 -0
- package/web/ui/src/routes/NewGroupWizard.tsx +390 -0
- package/web/ui/src/routes/OAuthCallback.tsx +56 -0
- package/web/ui/src/routes/SecretsList.tsx +921 -0
- package/web/ui/src/routes/SessionsList.tsx +220 -0
- package/web/ui/src/routes/SettingsAgentProvider.tsx +109 -0
- package/web/ui/src/routes/SettingsApprovals.tsx +234 -0
- package/web/ui/src/routes/SetupWizard.tsx +219 -0
- package/web/ui/src/routes/VaultDetail.test.tsx +361 -0
- package/web/ui/src/routes/VaultDetail.tsx +960 -0
- package/web/ui/src/routes/VaultsList.tsx +295 -0
- package/web/ui/src/routes/WireChannelPage.tsx +413 -0
- package/web/ui/src/styles.css +608 -0
- package/web/ui/src/test/setup.ts +23 -0
- package/web/ui/src/vite-env.d.ts +10 -0
- package/web/ui/tsconfig.json +20 -0
- package/web/ui/vite.config.ts +34 -0
- package/web/ui/vitest.config.ts +25 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#!/usr/bin/env pnpm exec tsx
|
|
2
|
+
/**
|
|
3
|
+
* X Integration - Retweet
|
|
4
|
+
* Usage: echo '{"tweetUrl":"https://x.com/user/status/123"}' | pnpm exec tsx retweet.ts
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { getBrowserContext, navigateToTweet, runScript, config, ScriptResult } from '../lib/browser.js';
|
|
8
|
+
|
|
9
|
+
interface RetweetInput {
|
|
10
|
+
tweetUrl: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async function retweet(input: RetweetInput): Promise<ScriptResult> {
|
|
14
|
+
const { tweetUrl } = input;
|
|
15
|
+
|
|
16
|
+
if (!tweetUrl) {
|
|
17
|
+
return { success: false, message: 'Please provide a tweet URL' };
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
let context = null;
|
|
21
|
+
try {
|
|
22
|
+
context = await getBrowserContext();
|
|
23
|
+
const { page, success, error } = await navigateToTweet(context, tweetUrl);
|
|
24
|
+
|
|
25
|
+
if (!success) {
|
|
26
|
+
return { success: false, message: error || 'Navigation failed' };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const tweet = page.locator('article[data-testid="tweet"]').first();
|
|
30
|
+
const unretweetButton = tweet.locator('[data-testid="unretweet"]');
|
|
31
|
+
const retweetButton = tweet.locator('[data-testid="retweet"]');
|
|
32
|
+
|
|
33
|
+
// Check if already retweeted
|
|
34
|
+
const alreadyRetweeted = await unretweetButton.isVisible().catch(() => false);
|
|
35
|
+
if (alreadyRetweeted) {
|
|
36
|
+
return { success: true, message: 'Tweet already retweeted' };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
await retweetButton.waitFor({ timeout: config.timeouts.elementWait });
|
|
40
|
+
await retweetButton.click();
|
|
41
|
+
await page.waitForTimeout(config.timeouts.afterClick);
|
|
42
|
+
|
|
43
|
+
// Click retweet confirm option
|
|
44
|
+
const retweetConfirm = page.locator('[data-testid="retweetConfirm"]');
|
|
45
|
+
await retweetConfirm.waitFor({ timeout: config.timeouts.elementWait });
|
|
46
|
+
await retweetConfirm.click();
|
|
47
|
+
await page.waitForTimeout(config.timeouts.afterClick * 2);
|
|
48
|
+
|
|
49
|
+
// Verify
|
|
50
|
+
const nowRetweeted = await unretweetButton.isVisible().catch(() => false);
|
|
51
|
+
if (nowRetweeted) {
|
|
52
|
+
return { success: true, message: 'Retweet successful' };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return { success: false, message: 'Retweet action completed but could not verify success' };
|
|
56
|
+
|
|
57
|
+
} finally {
|
|
58
|
+
if (context) await context.close();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
runScript<RetweetInput>(retweet);
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#!/usr/bin/env pnpm exec tsx
|
|
2
|
+
/**
|
|
3
|
+
* X Integration - Authentication Setup
|
|
4
|
+
* Usage: pnpm exec tsx setup.ts
|
|
5
|
+
*
|
|
6
|
+
* Interactive script - opens browser for manual login
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { chromium } from 'playwright';
|
|
10
|
+
import * as readline from 'readline';
|
|
11
|
+
import fs from 'fs';
|
|
12
|
+
import path from 'path';
|
|
13
|
+
import { config, cleanupLockFiles } from '../lib/browser.js';
|
|
14
|
+
|
|
15
|
+
async function setup(): Promise<void> {
|
|
16
|
+
console.log('=== X (Twitter) Authentication Setup ===\n');
|
|
17
|
+
console.log('This will open Chrome for you to log in to X.');
|
|
18
|
+
console.log('Your login session will be saved for automated interactions.\n');
|
|
19
|
+
console.log(`Chrome path: ${config.chromePath}`);
|
|
20
|
+
console.log(`Profile dir: ${config.browserDataDir}\n`);
|
|
21
|
+
|
|
22
|
+
// Ensure directories exist
|
|
23
|
+
fs.mkdirSync(path.dirname(config.authPath), { recursive: true });
|
|
24
|
+
fs.mkdirSync(config.browserDataDir, { recursive: true });
|
|
25
|
+
|
|
26
|
+
cleanupLockFiles();
|
|
27
|
+
|
|
28
|
+
console.log('Launching browser...\n');
|
|
29
|
+
|
|
30
|
+
const context = await chromium.launchPersistentContext(config.browserDataDir, {
|
|
31
|
+
executablePath: config.chromePath,
|
|
32
|
+
headless: false,
|
|
33
|
+
viewport: config.viewport,
|
|
34
|
+
args: config.chromeArgs.slice(0, 3), // Use first 3 args for setup (less restrictive)
|
|
35
|
+
ignoreDefaultArgs: config.chromeIgnoreDefaultArgs,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const page = context.pages()[0] || await context.newPage();
|
|
39
|
+
|
|
40
|
+
// Navigate to login page
|
|
41
|
+
await page.goto('https://x.com/login');
|
|
42
|
+
|
|
43
|
+
console.log('Please log in to X in the browser window.');
|
|
44
|
+
console.log('After you see your home feed, come back here and press Enter.\n');
|
|
45
|
+
|
|
46
|
+
// Wait for user to complete login
|
|
47
|
+
const rl = readline.createInterface({
|
|
48
|
+
input: process.stdin,
|
|
49
|
+
output: process.stdout
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
await new Promise<void>(resolve => {
|
|
53
|
+
rl.question('Press Enter when logged in... ', () => {
|
|
54
|
+
rl.close();
|
|
55
|
+
resolve();
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// Verify login by navigating to home and checking for account button
|
|
60
|
+
console.log('\nVerifying login status...');
|
|
61
|
+
await page.goto('https://x.com/home');
|
|
62
|
+
await page.waitForTimeout(config.timeouts.pageLoad);
|
|
63
|
+
|
|
64
|
+
const isLoggedIn = await page.locator('[data-testid="SideNav_AccountSwitcher_Button"]').isVisible().catch(() => false);
|
|
65
|
+
|
|
66
|
+
if (isLoggedIn) {
|
|
67
|
+
// Save auth marker
|
|
68
|
+
fs.writeFileSync(config.authPath, JSON.stringify({
|
|
69
|
+
authenticated: true,
|
|
70
|
+
timestamp: new Date().toISOString()
|
|
71
|
+
}, null, 2));
|
|
72
|
+
|
|
73
|
+
console.log('\n✅ Authentication successful!');
|
|
74
|
+
console.log(`Session saved to: ${config.browserDataDir}`);
|
|
75
|
+
console.log('\nYou can now use X integration features.');
|
|
76
|
+
} else {
|
|
77
|
+
console.log('\n❌ Could not verify login status.');
|
|
78
|
+
console.log('Please try again and make sure you are logged in to X.');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
await context.close();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
setup().catch(err => {
|
|
85
|
+
console.error('Setup failed:', err.message);
|
|
86
|
+
process.exit(1);
|
|
87
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Core code - maintainer only
|
|
2
|
+
/src/ @gavrielc @gabi-simons
|
|
3
|
+
/container/ @gavrielc @gabi-simons
|
|
4
|
+
/groups/ @gavrielc @gabi-simons
|
|
5
|
+
/launchd/ @gavrielc @gabi-simons
|
|
6
|
+
/package.json @gavrielc @gabi-simons
|
|
7
|
+
/package-lock.json @gavrielc @gabi-simons
|
|
8
|
+
|
|
9
|
+
# Skills - open to contributors
|
|
10
|
+
/.claude/skills/
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<!-- contributing-guide: v1 -->
|
|
2
|
+
## Type of Change
|
|
3
|
+
|
|
4
|
+
- [ ] **Feature skill** - adds a channel or integration (source code changes + SKILL.md)
|
|
5
|
+
- [ ] **Utility skill** - adds a standalone tool (code files in `.claude/skills/<name>/`, no source changes)
|
|
6
|
+
- [ ] **Operational/container skill** - adds a workflow or agent skill (SKILL.md only, no source changes)
|
|
7
|
+
- [ ] **Fix** - bug fix or security fix to source code
|
|
8
|
+
- [ ] **Simplification** - reduces or simplifies source code
|
|
9
|
+
- [ ] **Documentation** - docs, README, or CONTRIBUTING changes only
|
|
10
|
+
|
|
11
|
+
## Description
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## For Skills
|
|
15
|
+
|
|
16
|
+
- [ ] SKILL.md contains instructions, not inline code (code goes in separate files)
|
|
17
|
+
- [ ] SKILL.md is under 500 lines
|
|
18
|
+
- [ ] I tested this skill on a fresh clone
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
name: Bump version
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
paths: ['src/**', 'container/**']
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
bump-version:
|
|
10
|
+
if: github.repository == 'qwibitai/nanoclaw'
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/create-github-app-token@v1
|
|
14
|
+
id: app-token
|
|
15
|
+
with:
|
|
16
|
+
app-id: ${{ secrets.APP_ID }}
|
|
17
|
+
private-key: ${{ secrets.APP_PRIVATE_KEY }}
|
|
18
|
+
|
|
19
|
+
- uses: actions/checkout@v4
|
|
20
|
+
with:
|
|
21
|
+
token: ${{ steps.app-token.outputs.token }}
|
|
22
|
+
|
|
23
|
+
- uses: pnpm/action-setup@v4
|
|
24
|
+
|
|
25
|
+
- name: Bump patch version
|
|
26
|
+
run: |
|
|
27
|
+
pnpm version patch --no-git-tag-version
|
|
28
|
+
git add package.json
|
|
29
|
+
git diff --cached --quiet && exit 0
|
|
30
|
+
git config user.name "github-actions[bot]"
|
|
31
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
32
|
+
VERSION=$(node -p "require('./package.json').version")
|
|
33
|
+
git commit -m "chore: bump version to $VERSION"
|
|
34
|
+
git pull --rebase
|
|
35
|
+
git push
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches: [main]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
ci:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v4
|
|
12
|
+
- uses: pnpm/action-setup@v4
|
|
13
|
+
- uses: actions/setup-node@v4
|
|
14
|
+
with:
|
|
15
|
+
node-version: 20
|
|
16
|
+
cache: pnpm
|
|
17
|
+
- uses: oven-sh/setup-bun@v2
|
|
18
|
+
with:
|
|
19
|
+
bun-version: 1.3.12
|
|
20
|
+
- run: pnpm install --frozen-lockfile
|
|
21
|
+
- name: Install agent-runner deps (Bun)
|
|
22
|
+
working-directory: container/agent-runner
|
|
23
|
+
run: bun install --frozen-lockfile
|
|
24
|
+
|
|
25
|
+
- name: Format check
|
|
26
|
+
run: pnpm run format:check
|
|
27
|
+
|
|
28
|
+
- name: Typecheck host
|
|
29
|
+
run: pnpm exec tsc --noEmit
|
|
30
|
+
|
|
31
|
+
- name: Typecheck container
|
|
32
|
+
run: pnpm exec tsc -p container/agent-runner/tsconfig.json --noEmit
|
|
33
|
+
|
|
34
|
+
- name: Host tests
|
|
35
|
+
run: pnpm exec vitest run
|
|
36
|
+
|
|
37
|
+
- name: Container tests
|
|
38
|
+
working-directory: container/agent-runner
|
|
39
|
+
run: bun test
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
name: Label PR
|
|
2
|
+
|
|
3
|
+
# SECURITY: this workflow runs with write access to the base repo on fork PRs,
|
|
4
|
+
# because `pull_request_target` executes in the context of the base branch.
|
|
5
|
+
# Keep it metadata-only — do NOT add actions/checkout or any step that
|
|
6
|
+
# executes PR-supplied content (install scripts, build commands, etc.).
|
|
7
|
+
# See https://securitylab.github.com/resources/github-actions-preventing-pwn-requests/
|
|
8
|
+
on:
|
|
9
|
+
pull_request_target:
|
|
10
|
+
types: [opened, edited]
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
label:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
permissions:
|
|
16
|
+
pull-requests: write
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/github-script@v7
|
|
19
|
+
with:
|
|
20
|
+
script: |
|
|
21
|
+
const body = context.payload.pull_request.body || '';
|
|
22
|
+
const labels = [];
|
|
23
|
+
|
|
24
|
+
if (body.includes('[x] **Feature skill**')) { labels.push('PR: Skill'); labels.push('PR: Feature'); }
|
|
25
|
+
else if (body.includes('[x] **Utility skill**')) labels.push('PR: Skill');
|
|
26
|
+
else if (body.includes('[x] **Operational/container skill**')) labels.push('PR: Skill');
|
|
27
|
+
else if (body.includes('[x] **Fix**')) labels.push('PR: Fix');
|
|
28
|
+
else if (body.includes('[x] **Simplification**')) labels.push('PR: Refactor');
|
|
29
|
+
else if (body.includes('[x] **Documentation**')) labels.push('PR: Docs');
|
|
30
|
+
|
|
31
|
+
if (body.includes('contributing-guide: v1')) labels.push('follows-guidelines');
|
|
32
|
+
|
|
33
|
+
if (labels.length > 0) {
|
|
34
|
+
await github.rest.issues.addLabels({
|
|
35
|
+
owner: context.repo.owner,
|
|
36
|
+
repo: context.repo.repo,
|
|
37
|
+
issue_number: context.payload.pull_request.number,
|
|
38
|
+
labels,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
name: Update token count
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
push:
|
|
6
|
+
branches: [main]
|
|
7
|
+
paths: ['src/**', 'container/**', 'launchd/**', 'CLAUDE.md']
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
update-tokens:
|
|
11
|
+
if: github.repository == 'qwibitai/nanoclaw'
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/create-github-app-token@v1
|
|
15
|
+
id: app-token
|
|
16
|
+
with:
|
|
17
|
+
app-id: ${{ secrets.APP_ID }}
|
|
18
|
+
private-key: ${{ secrets.APP_PRIVATE_KEY }}
|
|
19
|
+
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
with:
|
|
22
|
+
token: ${{ steps.app-token.outputs.token }}
|
|
23
|
+
|
|
24
|
+
- uses: actions/setup-python@v5
|
|
25
|
+
with:
|
|
26
|
+
python-version: '3.12'
|
|
27
|
+
|
|
28
|
+
- uses: ./repo-tokens
|
|
29
|
+
id: tokens
|
|
30
|
+
with:
|
|
31
|
+
include: 'src/**/*.ts container/agent-runner/src/**/*.ts container/Dockerfile container/build.sh launchd/com.nanoclaw.plist CLAUDE.md'
|
|
32
|
+
exclude: 'src/**/*.test.ts'
|
|
33
|
+
badge-path: 'repo-tokens/badge.svg'
|
|
34
|
+
|
|
35
|
+
- name: Commit if changed
|
|
36
|
+
run: |
|
|
37
|
+
git add README.md repo-tokens/badge.svg
|
|
38
|
+
git diff --cached --quiet && exit 0
|
|
39
|
+
git config user.name "github-actions[bot]"
|
|
40
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
41
|
+
git commit -m "docs: update token count to ${{ steps.tokens.outputs.badge }}"
|
|
42
|
+
git pull --rebase
|
|
43
|
+
git push
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
pnpm run format:fix
|
package/.mcp.json
ADDED
package/.nvmrc
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
22
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agent",
|
|
3
|
+
"manifestName": "parachute-agent",
|
|
4
|
+
"displayName": "Parachute Agent",
|
|
5
|
+
"tagline": "Manage your Parachute agent groups + vault attachments.",
|
|
6
|
+
"kind": "frontend",
|
|
7
|
+
"port": 1944,
|
|
8
|
+
"paths": ["/agent"],
|
|
9
|
+
"health": "/api/health",
|
|
10
|
+
"startCmd": ["bun", "src/index.ts"],
|
|
11
|
+
"scopes": {
|
|
12
|
+
"defines": ["agent:read", "agent:write", "agent:admin"]
|
|
13
|
+
}
|
|
14
|
+
}
|
package/.prettierrc
ADDED
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to parachute-agent will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [0.1.0] - 2026-05-05
|
|
6
|
+
|
|
7
|
+
Renamed paraclaw → **parachute-agent**, joining the Parachute ecosystem's named-after-purpose convention (vault, notes, scribe, hub). The name on disk, in the npm registry, on the mount path, and on the wire all change. Operator data migrates automatically on first boot; tokens, container labels, and module manifests carry one cycle of back-compat.
|
|
8
|
+
|
|
9
|
+
- **npm package.** `paraclaw` → `@openparachute/agent`. The `parachute-agent` bin wraps the same entry point.
|
|
10
|
+
- **`.parachute/module.json` `name`** → `parachute-agent`. The hub picks up the new identifier from the manifest; old installs that re-pull will see the rename without intervention.
|
|
11
|
+
- **Mount path.** `/claw/*` → `/agent/*`. Hub-fronted UI lives under `/agent/`. The SPA derives its mount from `import.meta.env.BASE_URL`, so the same bundle works at any prefix. **No 301 redirect** — hard cut. Re-bookmark.
|
|
12
|
+
- **Data dir.** `~/.parachute/claw/{paraclaw.db,master.key}` → `~/.parachute/agent/{agent.db,master.key}`. **Auto-migrated on startup** the first time 0.1.x boots: the legacy file copies to the new path with mode 0600, and the legacy file is left in place as a manual-rm backup. Honors `PARACHUTE_HOME`. Both legacies (pre-0.0.6 in-tree `data/v2.db` and pre-0.1.0 `~/.parachute/claw/paraclaw.db`) are preferred over an absent current; if both exist, the paraclaw-era file wins.
|
|
13
|
+
- **Container labels.** Spawn label is now `parachute-agent-install=<slug>`. Cleanup reaps both the new label and the legacy `paraclaw-install=<slug>` label for one upgrade cycle, so a 0.1.x host coming up against pre-0.1.0 orphan containers cleans them up correctly. **Drop `paraclaw-install` compat in 0.2.0** (tracked as a follow-up issue).
|
|
14
|
+
- **Container image tag.** `paraclaw-agent-<slug>:latest` → `parachute-agent-image-<slug>:latest`. `container/build.sh` produces the new tag; `container-runner` spawns from it. The `-image-` infix avoids colliding with the npm package name.
|
|
15
|
+
- **MCP scope strings + symbols.** Wire scopes are `agent:read|write|admin` (was `claw:*`). Hub-issued JWTs carrying legacy `claw:*` grants still pass — they normalize to their `agent:*` equivalents inside `hasScope` and `pickEffectiveScope`. **Drop `claw:*` normalization in 0.2.0.** TS symbols renamed: `ClawScope` → `AgentScope`; `SCOPE_CLAW_*` → `SCOPE_AGENT_*`.
|
|
16
|
+
- **MCP server name.** `paraclaw` → `parachute-agent`. Tools advertise as `mcp__parachute_agent__<verb>-<noun>` to clients. Renamed in three places that all need to agree: the host-side stdio entrypoint (operator wires this into Claude Code via `claude mcp add parachute-agent …`), the host-side HTTP `/mcp` endpoint, and the container-side built-in MCP server that the in-container agent calls. **⚠ Operator action**: restart any active sessions on first boot — existing in-flight sessions have message history referencing `mcp__paraclaw__*` tool calls and need a fresh container to pick up the new tool prefix. New tool calls in restarted sessions use the new prefix; the historical log entries stay (they're conversation history, not tool routing). Closes paraclaw#110.
|
|
17
|
+
- **Service registry.** `services-manifest` displayName `Paraclaw` → `Parachute Agent`; service identifiers (`parachute-agent-web-server`) and the `name: 'agent'` route entry follow.
|
|
18
|
+
- **launchd / systemd.** No service-file generator changes in this PR — service install is now owned by the hub install path. Operators on existing installs who still have the old `computer.parachute.claw-<slug>.plist` / `paraclaw-<slug>.service` units will continue to work; re-running the hub installer rewrites them with the new label/unit name.
|
|
19
|
+
|
|
20
|
+
### Operator migration steps (existing installs)
|
|
21
|
+
|
|
22
|
+
1. **Stop the daemon** (so the migration sees a quiescent state):
|
|
23
|
+
- macOS: `launchctl unload ~/Library/LaunchAgents/computer.parachute.claw-<slug>.plist`
|
|
24
|
+
- Linux: `systemctl --user stop paraclaw-<slug>`
|
|
25
|
+
2. **Pull the rename**: `git pull --ff-only` on the install dir, then `pnpm install` (the `postinstall` hook rebuilds the SPA bundle).
|
|
26
|
+
3. **Start the daemon**. On first boot, you'll see one or both of these log lines once and only once:
|
|
27
|
+
```
|
|
28
|
+
Central DB migrated from legacy location from=…/paraclaw.db to=…/agent.db
|
|
29
|
+
Master key migrated from legacy location from=…/claw/master.key to=…/agent/master.key
|
|
30
|
+
```
|
|
31
|
+
4. **Verify** via the web UI at the new mount: `/agent/` (was `/claw/`).
|
|
32
|
+
5. **Re-register the MCP server** in any Claude Code (or other MCP client) configs. The stdio entrypoint hasn't moved, but the server name has — old `claude mcp add paraclaw …` registrations keep pointing at the old name and tools advertise as `mcp__paraclaw__*` instead of `mcp__parachute_agent__*`:
|
|
33
|
+
```sh
|
|
34
|
+
claude mcp remove paraclaw
|
|
35
|
+
claude mcp add parachute-agent bun /path/to/install/src/mcp/stdio.ts
|
|
36
|
+
```
|
|
37
|
+
6. **Cleanup (optional)**: once you've verified the new install boots and decrypts secrets, delete the legacy backups: `rm ~/.parachute/claw/paraclaw.db ~/.parachute/claw/master.key && rmdir ~/.parachute/claw`.
|
|
38
|
+
|
|
39
|
+
Browser sessions auto-migrate the SPA's `paraclaw.*` localStorage / sessionStorage keys (cached OAuth discovery, DCR client_id, tokens, in-flight flow state, setup-wizard resume state) to `parachute-agent.*` on first reload after the upgrade — no manual action required.
|
|
40
|
+
|
|
41
|
+
- **Log filenames.** `logs/paraclaw.log` + `logs/paraclaw.error.log` → `logs/parachute-agent.log` + `logs/parachute-agent.error.log`. **Auto-renamed on first 0.1.0 boot** so historical entries stay accessible under the new name. The supervisor (launchd plist / systemd unit) is what routes the *live* daemon's stdout/stderr — until the operator re-runs `parachute install parachute-agent` to regenerate the unit, new entries continue landing in `paraclaw.log` (recreated by the supervisor after the rename) and the next supervisor-driven respawn opens it fresh. Once the unit is regenerated, subsequent boots write to `parachute-agent.log` directly. Operators tailing the new path see migrated history immediately; live writes follow on the next install-run.
|
|
42
|
+
- **Env var prefix.** `PARACLAW_*` → `PARACHUTE_AGENT_*` (six vars: `_HUB_ORIGIN`, `_WEB_PORT`, `_WEB_BIND`, `_WEB_MOUNT`, `_WEB_ORIGIN`, `_CENTRAL_DB_PATH`). Each callsite reads the new name first, falls back to the legacy `PARACLAW_*` name if only that's set, and emits a one-shot deprecation warning per legacy name read. Operators can update their `.env` files at their leisure through 0.1.x; the legacy compat-read drops in 0.2.0. The Vite type declaration `VITE_PARACLAW_WEB_SERVER_URL` is also renamed to `VITE_PARACHUTE_AGENT_WEB_SERVER_URL` (the SPA doesn't read the value — it's a leftover declaration), no operator action needed.
|
|
43
|
+
- **Allowlist directory.** `~/.config/paraclaw/{mount,sender}-allowlist.json` → `~/.config/parachute-agent/{mount,sender}-allowlist.json`. **Auto-moved on first 0.1.0 boot**: the legacy directory is left in place (operators may have stashed unrelated files there) but each known allowlist file is renamed to the new dir if the new path is absent. If both exist (e.g. operator pre-populated the new dir before upgrading), the new file wins and the legacy orphan is left for the operator to `rm`. Drop the auto-move in 0.2.0.
|
|
44
|
+
- **Vault token-label default.** Fresh mints from the web UI's attach-vault flow and the new-group wizard now default to `agent-<folder>` (was `claw-<folder>`). Existing operator-typed labels keep working — the label is opaque to the vault, so prior `claw-<folder>` tokens continue to authenticate. Operators who want consistency can re-mint via the vault tokens UI. Reverses the parachute-agent#108 §2 deliberation in favor of brand consistency at the 0.1.0-stable cut.
|
|
45
|
+
- **HKDF info strings — intentionally NOT renamed.** Five HKDF info constants (`paraclaw.secrets.v1`, `paraclaw.oauth.{client,access,refresh}.v1`, `paraclaw.provider-credentials.v1`) keep the `paraclaw.` prefix forever. They're cryptographic domain separators mixed into key derivation, not user-facing strings — renaming them would derive a different key and render every existing ciphertext row (secrets, OAuth tokens, provider credentials) undecryptable. Documented at each constant-definition site so a future brand sweep knows to skip these five lines. No operator action.
|
|
46
|
+
|
|
47
|
+
## [Unreleased]
|
|
48
|
+
|
|
49
|
+
Hard fork from NanoClaw v2. Paraclaw is now its own service: single Bun process (host + web merged), native AES-GCM secrets layer, channels inlined permanently, skills system retired, capability card published at `/.well-known/parachute.json`. OneCLI is no longer a dependency.
|
|
50
|
+
|
|
51
|
+
- **Schema relocate.** Central DB moved to `~/.parachute/claw/paraclaw.db`. Per-session two-file split (`inbound.db` + `outbound.db`) preserved — empirically validated as the only safe shape across Docker bind-mounts.
|
|
52
|
+
- **Native secrets.** Master key at `~/.parachute/claw/master.key` (32 bytes, mode 0600), AES-256-GCM with HKDF domain separation per subsystem, redacted error messages. Migration 015 drops the vestigial `host_pattern` column.
|
|
53
|
+
- **Web UI** ships native pages for paraclaw primitives: `/secrets`, `/approvals`, `/sessions`, `/channels`. Wizard's credential-capture step removed (replaced by `/secrets`).
|
|
54
|
+
- **Lifecycle.** Install via `parachute install paraclaw`; start runs `bun src/index.ts`. Module manifest at `.parachute/module.json`.
|
|
55
|
+
- **fix(secrets):** per-secret mode radio for global secrets was a silent UI illusion (paraclaw#9-era migration moved mode to `agent_groups.secret_mode`). Globals now hide the radio with explainer; scoped secrets reframe the radio as `<group> accepts: [all in-scope | only assigned]`, surfacing the per-group nature of the setting.
|
|
56
|
+
- **feat(secrets):** post-save staleness banner detects running containers spawned before the secret update + per-session `[Restart]` + `Restart all N`. Calls existing `closeSession`; next inbound message respawns fresh with new env. New `GET /api/secrets/:id/stale-sessions` (claw:read).
|
|
57
|
+
- **feat(GroupDetail):** per-session `[Restart]` button on the Live status list + inline help on the spawn-time env model — operators can restart any running container without leaving the agent group page, for code/env/agent-provider changes too, not just secrets.
|
|
58
|
+
|
|
59
|
+
## [2.0.0] - 2026-04-22 (NanoClaw v2 — paraclaw's ancestor)
|
|
60
|
+
|
|
61
|
+
Major version. NanoClaw v2 was a substantial architectural rewrite that paraclaw forks from.
|
|
62
|
+
|
|
63
|
+
- [BREAKING] **New entity model.** Users, roles (owner/admin), messaging groups, and agent groups are now tracked as separate entities, wired via `messaging_group_agents`. Privilege is user-level instead of channel-level, so the old "main channel = admin" concept is retired. See [docs/architecture.md](docs/architecture.md) and [docs/isolation-model.md](docs/isolation-model.md).
|
|
64
|
+
- [BREAKING] **Two-DB session split.** Each session now has `inbound.db` (host writes, container reads) and `outbound.db` (container writes, host reads) with exactly one writer each. Replaces the single shared session DB and eliminates cross-mount SQLite contention. See [docs/db-session.md](docs/db-session.md).
|
|
65
|
+
- [BREAKING] **Install flow replaced.** `bash nanoclaw.sh` is the new default: a scripted installer that hands off to Claude Code for error recovery and guided decisions. The `/setup` Claude-guided skill still works as an alternative.
|
|
66
|
+
- [BREAKING] **Channels moved to the `channels` branch.** Trunk no longer ships Discord, Slack, Telegram, WhatsApp, iMessage, Teams, Linear, GitHub, WeChat, Matrix, Google Chat, Webex, Resend, or WhatsApp Cloud. Install them per fork via `/add-<channel>` skills, which copy from the `channels` branch. `/update-nanoclaw` will re-install the channels your fork had.
|
|
67
|
+
- [BREAKING] **Alternative providers moved to the `providers` branch.** OpenCode, Codex, and Ollama install via `/add-opencode`, `/add-codex`, `/add-ollama-provider`. Claude remains the default provider baked into trunk.
|
|
68
|
+
- [BREAKING] **Three-level channel isolation.** Wire channels to their own agent (separate agent groups), share an agent with independent conversations (`session_mode: 'shared'`), or merge channels into one shared session (`session_mode: 'agent-shared'`). Chosen per channel via `/manage-channels`.
|
|
69
|
+
- [BREAKING] **Apple Container removed from default setup.** Still available as an opt-in via `/convert-to-apple-container`.
|
|
70
|
+
- **Shared-source agent-runner.** Per-group `agent-runner-src/` overlays are gone; all groups mount the same agent-runner read-only. Per-group customization flows through composed `CLAUDE.md` (shared base + per-group fragments).
|
|
71
|
+
- **Agent-runner runtime moved from Node to Bun.** Container image is self-contained; no host-side impact. Host remains on Node + pnpm.
|
|
72
|
+
- **OneCLI Agent Vault is the sole credential path.** Containers never receive raw API keys; credentials are injected at request time.
|
|
73
|
+
|
|
74
|
+
## [1.2.36] - 2026-03-26
|
|
75
|
+
|
|
76
|
+
- [BREAKING] Replaced pino logger with built-in logger. WhatsApp users must re-merge the WhatsApp fork to pick up the Baileys logger compatibility fix: `git fetch whatsapp main && git merge whatsapp/main`. If the `whatsapp` remote is not configured: `git remote add whatsapp https://github.com/qwibitai/nanoclaw-whatsapp.git`.
|
|
77
|
+
|
|
78
|
+
## [1.2.35] - 2026-03-26
|
|
79
|
+
|
|
80
|
+
- [BREAKING] OneCLI Agent Vault replaces the built-in credential proxy. Check your runtime: `grep CONTAINER_RUNTIME_BIN src/container-runtime.ts` — if it shows `'container'` you are on Apple Container, if `'docker'` you are on Docker. Docker users: run `/init-onecli` to install OneCLI and migrate `.env` credentials to the vault. Apple Container users: re-merge the skill branch (`git fetch upstream skill/apple-container && git merge upstream/skill/apple-container`) then run `/convert-to-apple-container` and follow all instructions (configures credential proxy networking) — do NOT run `/init-onecli`, it requires Docker.
|
|
81
|
+
|
|
82
|
+
## [1.2.21] - 2026-03-22
|
|
83
|
+
|
|
84
|
+
- Added opt-in diagnostics via PostHog with explicit user consent (Yes / No / Never ask again)
|
|
85
|
+
|
|
86
|
+
## [1.2.20] - 2026-03-21
|
|
87
|
+
|
|
88
|
+
- Added ESLint configuration with error-handling rules
|
|
89
|
+
|
|
90
|
+
## [1.2.19] - 2026-03-19
|
|
91
|
+
|
|
92
|
+
- Reduced `docker stop` timeout for faster container restarts (`-t 1` flag)
|
|
93
|
+
|
|
94
|
+
## [1.2.18] - 2026-03-19
|
|
95
|
+
|
|
96
|
+
- User prompt content no longer logged on container errors — only input metadata
|
|
97
|
+
- Added Japanese README translation
|
|
98
|
+
|
|
99
|
+
## [1.2.17] - 2026-03-18
|
|
100
|
+
|
|
101
|
+
- Added `/capabilities` and `/status` container-agent skills
|
|
102
|
+
|
|
103
|
+
## [1.2.16] - 2026-03-18
|
|
104
|
+
|
|
105
|
+
- Tasks snapshot now refreshes immediately after IPC task mutations
|
|
106
|
+
|
|
107
|
+
## [1.2.15] - 2026-03-16
|
|
108
|
+
|
|
109
|
+
- Fixed remote-control prompt auto-accept to prevent immediate exit
|
|
110
|
+
- Added `KillMode=process` so remote-control survives service restarts
|
|
111
|
+
|
|
112
|
+
## [1.2.14] - 2026-03-14
|
|
113
|
+
|
|
114
|
+
- Added `/remote-control` command for host-level Claude Code access from within containers
|
|
115
|
+
|
|
116
|
+
## [1.2.13] - 2026-03-14
|
|
117
|
+
|
|
118
|
+
**Breaking:** Skills are now git branches, channels are separate fork repos.
|
|
119
|
+
|
|
120
|
+
- Skills live as `skill/*` git branches merged via `git merge`
|
|
121
|
+
- Added Docker Sandboxes support
|
|
122
|
+
- Fixed setup registration to use correct CLI commands
|
|
123
|
+
|
|
124
|
+
## [1.2.12] - 2026-03-08
|
|
125
|
+
|
|
126
|
+
- Added `/compact` skill for manual context compaction
|
|
127
|
+
- Enhanced container environment isolation via credential proxy
|
|
128
|
+
|
|
129
|
+
## [1.2.11] - 2026-03-08
|
|
130
|
+
|
|
131
|
+
- Added PDF reader, image vision, and WhatsApp reactions skills
|
|
132
|
+
- Fixed task container to close promptly when agent uses IPC-only messaging
|
|
133
|
+
|
|
134
|
+
## [1.2.10] - 2026-03-06
|
|
135
|
+
|
|
136
|
+
- Added `LIMIT` to unbounded message history queries for better performance
|
|
137
|
+
|
|
138
|
+
## [1.2.9] - 2026-03-06
|
|
139
|
+
|
|
140
|
+
- Agent prompts now include timezone context for accurate time references
|
|
141
|
+
|
|
142
|
+
## [1.2.8] - 2026-03-06
|
|
143
|
+
|
|
144
|
+
- Fixed misleading `send_message` tool description for scheduled tasks
|
|
145
|
+
|
|
146
|
+
## [1.2.7] - 2026-03-06
|
|
147
|
+
|
|
148
|
+
- Added `/add-ollama` skill for local model inference
|
|
149
|
+
- Added `update_task` tool and return task ID from `schedule_task`
|
|
150
|
+
|
|
151
|
+
## [1.2.6] - 2026-03-04
|
|
152
|
+
|
|
153
|
+
- Updated `claude-agent-sdk` to 0.2.68
|
|
154
|
+
|
|
155
|
+
## [1.2.5] - 2026-03-04
|
|
156
|
+
|
|
157
|
+
- CI formatting fix
|
|
158
|
+
|
|
159
|
+
## [1.2.4] - 2026-03-04
|
|
160
|
+
|
|
161
|
+
- Fixed `_chatJid` rename to `chatJid` in `onMessage` callback
|
|
162
|
+
|
|
163
|
+
## [1.2.3] - 2026-03-04
|
|
164
|
+
|
|
165
|
+
- Added sender allowlist for per-chat access control
|
|
166
|
+
|
|
167
|
+
## [1.2.2] - 2026-03-04
|
|
168
|
+
|
|
169
|
+
- Added `/use-local-whisper` skill for local voice transcription
|
|
170
|
+
- Atomic task claims prevent scheduled tasks from executing twice
|
|
171
|
+
|
|
172
|
+
## [1.2.1] - 2026-03-02
|
|
173
|
+
|
|
174
|
+
- Version bump (no functional changes)
|
|
175
|
+
|
|
176
|
+
## [1.2.0] - 2026-03-02
|
|
177
|
+
|
|
178
|
+
**Breaking:** WhatsApp removed from core, now a skill. Run `/add-whatsapp` to re-add.
|
|
179
|
+
|
|
180
|
+
- Channel registry: channels self-register at startup via `registerChannel()` factory pattern
|
|
181
|
+
- `isMain` flag replaces folder-name-based main group detection
|
|
182
|
+
- `ENABLED_CHANNELS` removed — channels detected by credential presence
|
|
183
|
+
- Prevent scheduled tasks from executing twice when container runtime exceeds poll interval
|
|
184
|
+
|
|
185
|
+
## [1.1.6] - 2026-03-01
|
|
186
|
+
|
|
187
|
+
- Added CJK font support for Chromium screenshots
|
|
188
|
+
|
|
189
|
+
## [1.1.5] - 2026-03-01
|
|
190
|
+
|
|
191
|
+
- Fixed wrapped WhatsApp message normalization
|
|
192
|
+
|
|
193
|
+
## [1.1.4] - 2026-03-01
|
|
194
|
+
|
|
195
|
+
- Added third-party model support
|
|
196
|
+
- Added `/update-nanoclaw` skill for syncing with upstream
|
|
197
|
+
|
|
198
|
+
## [1.1.3] - 2026-02-25
|
|
199
|
+
|
|
200
|
+
- Added `/add-slack` skill
|
|
201
|
+
- Restructured Gmail skill for new architecture
|
|
202
|
+
|
|
203
|
+
## [1.1.2] - 2026-02-24
|
|
204
|
+
|
|
205
|
+
- Improved error handling for WhatsApp Web version fetch
|
|
206
|
+
|
|
207
|
+
## [1.1.1] - 2026-02-24
|
|
208
|
+
|
|
209
|
+
- Added Qodo skills and codebase intelligence
|
|
210
|
+
- Fixed WhatsApp 405 connection failures
|
|
211
|
+
|
|
212
|
+
## [1.1.0] - 2026-02-23
|
|
213
|
+
|
|
214
|
+
- Added `/update` skill to pull upstream changes from within Claude Code
|
|
215
|
+
- Enhanced container environment isolation via credential proxy
|