@openparachute/agent 0.1.2 → 0.2.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/.parachute/module.json +124 -8
- package/LICENSE +2 -16
- package/README.md +118 -166
- package/package.json +32 -43
- package/scripts/spawn-agent.ts +371 -0
- package/src/_parked/interactive-spawn.test.ts +324 -0
- package/src/_parked/interactive-spawn.ts +701 -0
- package/src/agent-defs.test.ts +1504 -0
- package/src/agent-defs.ts +1702 -0
- package/src/agent-mcp-config.test.ts +115 -0
- package/src/agent-mcp-config.ts +115 -0
- package/src/agents.test.ts +360 -0
- package/src/agents.ts +379 -0
- package/src/auth.test.ts +46 -0
- package/src/auth.ts +140 -0
- package/src/backends/attached-queue.test.ts +376 -0
- package/src/backends/attached-queue.ts +372 -0
- package/src/backends/programmatic.test.ts +1715 -0
- package/src/backends/programmatic.ts +927 -0
- package/src/backends/registry.test.ts +1494 -0
- package/src/backends/registry.ts +1202 -0
- package/src/backends/stream-json.test.ts +570 -0
- package/src/backends/stream-json.ts +392 -0
- package/src/backends/types.ts +223 -0
- package/src/bridge.ts +417 -0
- package/src/channel-backend-wiring.test.ts +237 -0
- package/src/credentials.test.ts +274 -0
- package/src/credentials.ts +380 -0
- package/src/cron.test.ts +342 -0
- package/src/cron.ts +380 -0
- package/src/daemon-agent-def-api.test.ts +166 -0
- package/src/daemon-agent-defs-api.test.ts +953 -0
- package/src/daemon-agent-env-api.test.ts +338 -0
- package/src/daemon-attached-queue-store.test.ts +65 -0
- package/src/daemon-config-api.test.ts +962 -0
- package/src/daemon-jobs-api.test.ts +271 -0
- package/src/daemon-vault-chat.test.ts +250 -0
- package/src/daemon.test.ts +746 -0
- package/src/daemon.ts +3314 -0
- package/src/def-vaults.test.ts +136 -0
- package/src/def-vaults.ts +165 -0
- package/src/delivery-state.test.ts +110 -0
- package/src/delivery-state.ts +154 -0
- package/src/effective-env.test.ts +114 -0
- package/src/effective-env.ts +184 -0
- package/src/env-compat.ts +39 -0
- package/src/grants.test.ts +638 -0
- package/src/grants.ts +675 -0
- package/src/hub-jwt.test.ts +161 -0
- package/src/hub-jwt.ts +182 -0
- package/src/jobs.test.ts +245 -0
- package/src/jobs.ts +266 -0
- package/src/mcp-http.test.ts +265 -0
- package/src/mcp-http.ts +771 -0
- package/src/mint-token.test.ts +152 -0
- package/src/mint-token.ts +139 -0
- package/src/module-manifest.test.ts +158 -0
- package/src/oauth-discovery.ts +134 -0
- package/src/programmatic-wiring.test.ts +838 -0
- package/src/registry.test.ts +227 -0
- package/src/registry.ts +228 -0
- package/src/resolve-port.test.ts +64 -0
- package/src/routing.test.ts +184 -0
- package/src/routing.ts +76 -0
- package/src/runner.test.ts +506 -0
- package/src/runner.ts +255 -0
- package/src/sandbox/config.test.ts +150 -0
- package/src/sandbox/config.ts +102 -0
- package/src/sandbox/egress.test.ts +113 -0
- package/src/sandbox/egress.ts +123 -0
- package/src/sandbox/index.ts +180 -0
- package/src/sandbox/live-seatbelt.test.ts +277 -0
- package/src/sandbox/mounts.test.ts +154 -0
- package/src/sandbox/mounts.ts +133 -0
- package/src/sandbox/sandbox.test.ts +168 -0
- package/src/sandbox/types.ts +382 -0
- package/src/services-manifest.test.ts +106 -0
- package/src/services-manifest.ts +95 -0
- package/src/spa-serve.test.ts +116 -0
- package/src/spa-serve.ts +116 -0
- package/src/spawn-agent-cli.test.ts +172 -0
- package/src/spawn-agent.test.ts +1218 -0
- package/src/spawn-agent.ts +569 -0
- package/src/spawn-deps.test.ts +54 -0
- package/src/spawn-deps.ts +166 -0
- package/src/telegram/api.ts +153 -0
- package/src/terminal-assets.test.ts +50 -0
- package/src/terminal-assets.ts +79 -0
- package/src/terminal-ui.ts +305 -0
- package/src/terminal.test.ts +530 -0
- package/src/terminal.ts +458 -0
- package/src/transport.ts +270 -0
- package/src/transports/http-ui.test.ts +455 -0
- package/src/transports/http-ui.ts +201 -0
- package/src/transports/telegram.test.ts +174 -0
- package/src/transports/telegram.ts +426 -0
- package/src/transports/vault.test.ts +2011 -0
- package/src/transports/vault.ts +1790 -0
- package/src/ui-kit.test.ts +178 -0
- package/src/ui-kit.ts +402 -0
- package/tsconfig.json +8 -14
- package/web/ui/tsconfig.json +2 -1
- package/.claude/scheduled_tasks.lock +0 -1
- package/.claude/settings.json +0 -5
- package/.claude/skills/add-atomic-chat-tool/SKILL.md +0 -243
- package/.claude/skills/add-atomic-chat-tool/atomic-chat-mcp-stdio.ts +0 -229
- package/.claude/skills/add-codex/SKILL.md +0 -161
- package/.claude/skills/add-dashboard/SKILL.md +0 -138
- package/.claude/skills/add-dashboard/resources/dashboard-pusher.ts +0 -495
- package/.claude/skills/add-emacs/SKILL.md +0 -296
- package/.claude/skills/add-gcal-tool/SKILL.md +0 -210
- package/.claude/skills/add-gchat/REMOVE.md +0 -6
- package/.claude/skills/add-gchat/SKILL.md +0 -92
- package/.claude/skills/add-gchat/VERIFY.md +0 -3
- package/.claude/skills/add-github/REMOVE.md +0 -6
- package/.claude/skills/add-github/SKILL.md +0 -148
- package/.claude/skills/add-github/VERIFY.md +0 -3
- package/.claude/skills/add-gmail-tool/SKILL.md +0 -229
- package/.claude/skills/add-imessage/REMOVE.md +0 -6
- package/.claude/skills/add-imessage/SKILL.md +0 -113
- package/.claude/skills/add-imessage/VERIFY.md +0 -3
- package/.claude/skills/add-karpathy-llm-wiki/SKILL.md +0 -110
- package/.claude/skills/add-karpathy-llm-wiki/llm-wiki.md +0 -75
- package/.claude/skills/add-linear/REMOVE.md +0 -6
- package/.claude/skills/add-linear/SKILL.md +0 -168
- package/.claude/skills/add-linear/VERIFY.md +0 -3
- package/.claude/skills/add-macos-statusbar/SKILL.md +0 -133
- package/.claude/skills/add-macos-statusbar/add/src/statusbar.swift +0 -147
- package/.claude/skills/add-matrix/REMOVE.md +0 -6
- package/.claude/skills/add-matrix/SKILL.md +0 -148
- package/.claude/skills/add-matrix/VERIFY.md +0 -3
- package/.claude/skills/add-ollama-provider/SKILL.md +0 -179
- package/.claude/skills/add-ollama-tool/SKILL.md +0 -193
- package/.claude/skills/add-opencode/SKILL.md +0 -229
- package/.claude/skills/add-parallel/SKILL.md +0 -290
- package/.claude/skills/add-resend/REMOVE.md +0 -6
- package/.claude/skills/add-resend/SKILL.md +0 -93
- package/.claude/skills/add-resend/VERIFY.md +0 -3
- package/.claude/skills/add-signal/REMOVE.md +0 -13
- package/.claude/skills/add-signal/SKILL.md +0 -318
- package/.claude/skills/add-signal/VERIFY.md +0 -5
- package/.claude/skills/add-slack/REMOVE.md +0 -6
- package/.claude/skills/add-slack/SKILL.md +0 -112
- package/.claude/skills/add-slack/VERIFY.md +0 -3
- package/.claude/skills/add-teams/REMOVE.md +0 -6
- package/.claude/skills/add-teams/SKILL.md +0 -207
- package/.claude/skills/add-teams/VERIFY.md +0 -3
- package/.claude/skills/add-vercel/SKILL.md +0 -147
- package/.claude/skills/add-vercel/container-skills/vercel-cli/SKILL.md +0 -103
- package/.claude/skills/add-webex/REMOVE.md +0 -6
- package/.claude/skills/add-webex/SKILL.md +0 -88
- package/.claude/skills/add-webex/VERIFY.md +0 -3
- package/.claude/skills/add-wechat/REMOVE.md +0 -49
- package/.claude/skills/add-wechat/SKILL.md +0 -170
- package/.claude/skills/add-wechat/scripts/wire-dm.ts +0 -172
- package/.claude/skills/add-whatsapp/SKILL.md +0 -264
- package/.claude/skills/add-whatsapp-cloud/REMOVE.md +0 -6
- package/.claude/skills/add-whatsapp-cloud/SKILL.md +0 -95
- package/.claude/skills/add-whatsapp-cloud/VERIFY.md +0 -3
- package/.claude/skills/claw/SKILL.md +0 -131
- package/.claude/skills/claw/scripts/claw +0 -374
- package/.claude/skills/convert-to-apple-container/SKILL.md +0 -212
- package/.claude/skills/customize/SKILL.md +0 -110
- package/.claude/skills/debug/SKILL.md +0 -349
- package/.claude/skills/get-qodo-rules/SKILL.md +0 -122
- package/.claude/skills/get-qodo-rules/references/output-format.md +0 -41
- package/.claude/skills/get-qodo-rules/references/pagination.md +0 -33
- package/.claude/skills/get-qodo-rules/references/repository-scope.md +0 -26
- package/.claude/skills/init-first-agent/SKILL.md +0 -120
- package/.claude/skills/init-onecli/SKILL.md +0 -270
- package/.claude/skills/manage-channels/SKILL.md +0 -87
- package/.claude/skills/manage-mounts/SKILL.md +0 -47
- package/.claude/skills/migrate-from-openclaw/MIGRATE_CRONS.md +0 -100
- package/.claude/skills/migrate-from-openclaw/SKILL.md +0 -447
- package/.claude/skills/migrate-from-openclaw/scripts/discover-openclaw.ts +0 -734
- package/.claude/skills/migrate-from-openclaw/scripts/extract-channel-credentials.ts +0 -476
- package/.claude/skills/migrate-nanoclaw/SKILL.md +0 -484
- package/.claude/skills/migrate-nanoclaw/diagnostics.md +0 -51
- package/.claude/skills/qodo-pr-resolver/SKILL.md +0 -326
- package/.claude/skills/qodo-pr-resolver/resources/providers.md +0 -329
- package/.claude/skills/update-nanoclaw/SKILL.md +0 -243
- package/.claude/skills/update-nanoclaw/diagnostics.md +0 -48
- package/.claude/skills/update-skills/SKILL.md +0 -130
- package/.claude/skills/use-native-credential-proxy/SKILL.md +0 -167
- package/.claude/skills/x-integration/SKILL.md +0 -417
- package/.claude/skills/x-integration/agent.ts +0 -243
- package/.claude/skills/x-integration/host.ts +0 -155
- package/.claude/skills/x-integration/lib/browser.ts +0 -148
- package/.claude/skills/x-integration/lib/config.ts +0 -62
- package/.claude/skills/x-integration/scripts/like.ts +0 -56
- package/.claude/skills/x-integration/scripts/post.ts +0 -66
- package/.claude/skills/x-integration/scripts/quote.ts +0 -80
- package/.claude/skills/x-integration/scripts/reply.ts +0 -74
- package/.claude/skills/x-integration/scripts/retweet.ts +0 -62
- package/.claude/skills/x-integration/scripts/setup.ts +0 -87
- package/.github/CODEOWNERS +0 -10
- package/.github/PULL_REQUEST_TEMPLATE.md +0 -18
- package/.github/workflows/bump-version.yml +0 -35
- package/.github/workflows/ci.yml +0 -39
- package/.github/workflows/label-pr.yml +0 -40
- package/.github/workflows/update-tokens.yml +0 -43
- package/.husky/pre-commit +0 -1
- package/.mcp.json +0 -3
- package/.nvmrc +0 -1
- package/.prettierrc +0 -4
- package/CHANGELOG.md +0 -263
- package/CLAUDE.md +0 -307
- package/CODE_OF_CONDUCT.md +0 -128
- package/CONTRIBUTING.md +0 -159
- package/CONTRIBUTORS.md +0 -26
- package/LICENSE-NANOCLAW-MIT +0 -21
- package/README_ja.md +0 -194
- package/README_zh.md +0 -194
- 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 +0 -25
- package/container/.dockerignore +0 -2
- package/container/CLAUDE.md +0 -21
- package/container/Dockerfile +0 -121
- package/container/agent-runner/bun.lock +0 -243
- package/container/agent-runner/package.json +0 -22
- package/container/agent-runner/scripts/sdk-signal-probe.ts +0 -169
- package/container/agent-runner/src/config.ts +0 -55
- package/container/agent-runner/src/db/connection.ts +0 -267
- package/container/agent-runner/src/db/index.ts +0 -20
- package/container/agent-runner/src/db/messages-in.ts +0 -138
- package/container/agent-runner/src/db/messages-out.ts +0 -143
- package/container/agent-runner/src/db/session-routing.ts +0 -30
- package/container/agent-runner/src/db/session-state.test.ts +0 -100
- package/container/agent-runner/src/db/session-state.ts +0 -79
- package/container/agent-runner/src/destinations.ts +0 -135
- package/container/agent-runner/src/formatter.test.ts +0 -167
- package/container/agent-runner/src/formatter.ts +0 -260
- package/container/agent-runner/src/index.ts +0 -110
- package/container/agent-runner/src/integration.test.ts +0 -121
- package/container/agent-runner/src/mcp-tools/agents.instructions.md +0 -26
- package/container/agent-runner/src/mcp-tools/agents.ts +0 -66
- package/container/agent-runner/src/mcp-tools/core.instructions.md +0 -27
- package/container/agent-runner/src/mcp-tools/core.ts +0 -262
- package/container/agent-runner/src/mcp-tools/index.ts +0 -22
- package/container/agent-runner/src/mcp-tools/interactive.instructions.md +0 -22
- package/container/agent-runner/src/mcp-tools/interactive.ts +0 -169
- package/container/agent-runner/src/mcp-tools/scheduling.instructions.md +0 -40
- package/container/agent-runner/src/mcp-tools/scheduling.ts +0 -299
- package/container/agent-runner/src/mcp-tools/self-mod.instructions.md +0 -25
- package/container/agent-runner/src/mcp-tools/self-mod.ts +0 -120
- package/container/agent-runner/src/mcp-tools/server.ts +0 -54
- package/container/agent-runner/src/mcp-tools/types.ts +0 -6
- package/container/agent-runner/src/poll-loop.test.ts +0 -248
- package/container/agent-runner/src/poll-loop.ts +0 -437
- package/container/agent-runner/src/providers/claude.ts +0 -379
- package/container/agent-runner/src/providers/factory.test.ts +0 -19
- package/container/agent-runner/src/providers/factory.ts +0 -13
- package/container/agent-runner/src/providers/index.ts +0 -6
- package/container/agent-runner/src/providers/mock.ts +0 -77
- package/container/agent-runner/src/providers/provider-registry.ts +0 -33
- package/container/agent-runner/src/providers/types.ts +0 -82
- package/container/agent-runner/src/scheduling/task-script.ts +0 -121
- package/container/agent-runner/src/timezone.test.ts +0 -93
- package/container/agent-runner/src/timezone.ts +0 -107
- package/container/agent-runner/tsconfig.json +0 -14
- package/container/build.sh +0 -48
- package/container/entrypoint.sh +0 -16
- package/container/skills/agent-browser/SKILL.md +0 -159
- package/container/skills/frontend-engineer/SKILL.md +0 -157
- package/container/skills/self-customize/SKILL.md +0 -87
- package/container/skills/slack-formatting/SKILL.md +0 -94
- package/container/skills/vercel-cli/SKILL.md +0 -111
- package/container/skills/welcome/SKILL.md +0 -85
- package/docs/APPLE-CONTAINER-NETWORKING.md +0 -90
- package/docs/BRANCH-FORK-MAINTENANCE.md +0 -81
- package/docs/README.md +0 -25
- package/docs/SDK_DEEP_DIVE.md +0 -643
- package/docs/SECURITY.md +0 -162
- package/docs/agent-runner-details.md +0 -749
- package/docs/api-details.md +0 -365
- package/docs/architecture-diagram.html +0 -422
- package/docs/architecture-diagram.md +0 -215
- package/docs/architecture.md +0 -751
- package/docs/audit/2026-04-30-channel-endpoint-audit.md +0 -36
- package/docs/build-and-runtime.md +0 -80
- package/docs/cross-mount-stress/README.md +0 -112
- package/docs/cross-mount-stress/container-writer-retry.mjs +0 -55
- package/docs/cross-mount-stress/container-writer-slow.mjs +0 -42
- package/docs/cross-mount-stress/container-writer.mjs +0 -47
- package/docs/cross-mount-stress/host-writer-retry.mjs +0 -55
- package/docs/cross-mount-stress/host-writer-slow.mjs +0 -43
- package/docs/cross-mount-stress/host-writer.mjs +0 -47
- package/docs/db-central.md +0 -316
- package/docs/db-session.md +0 -183
- package/docs/db.md +0 -119
- package/docs/design/2026-04-29-vault-management-ui.md +0 -231
- package/docs/design/2026-04-30-channel-wiring-rework.md +0 -234
- package/docs/design/2026-05-01-channel-wiring-approvals-deep-dive.md +0 -272
- package/docs/design/2026-05-02-channel-policy-and-approval-routing.md +0 -250
- package/docs/docker-sandboxes.md +0 -359
- package/docs/isolation-model.md +0 -88
- package/docs/ollama.md +0 -79
- package/docs/parachute-integration.md +0 -109
- package/docs/post-night-rebirth-reflections.md +0 -151
- package/eslint.config.js +0 -32
- package/pnpm-workspace.yaml +0 -8
- package/repo-tokens/README.md +0 -113
- package/repo-tokens/action.yml +0 -186
- package/repo-tokens/badge.svg +0 -23
- package/repo-tokens/examples/green.svg +0 -14
- package/repo-tokens/examples/red.svg +0 -14
- package/repo-tokens/examples/yellow-green.svg +0 -14
- package/repo-tokens/examples/yellow.svg +0 -14
- package/scripts/chat.ts +0 -101
- package/scripts/cleanup-sessions.sh +0 -150
- package/scripts/init-cli-agent.ts +0 -172
- package/scripts/init-first-agent.ts +0 -378
- package/scripts/parachute.ts +0 -158
- package/scripts/run-migrations.ts +0 -105
- package/scripts/sanity-live-poll.ts +0 -95
- package/scripts/seed-discord.ts +0 -80
- package/scripts/test-v2-agent.ts +0 -106
- package/scripts/test-v2-channel-e2e.ts +0 -265
- package/scripts/test-v2-host.ts +0 -184
- package/src/channels/adapter.ts +0 -214
- package/src/channels/api-translator.test.ts +0 -306
- package/src/channels/api-translator.ts +0 -214
- package/src/channels/ask-question.ts +0 -46
- package/src/channels/channel-registry.test.ts +0 -421
- package/src/channels/channel-registry.ts +0 -313
- package/src/channels/chat-sdk-bridge.test.ts +0 -84
- package/src/channels/chat-sdk-bridge.ts +0 -652
- package/src/channels/cli.ts +0 -276
- package/src/channels/discord.ts +0 -90
- package/src/channels/index.ts +0 -17
- package/src/channels/telegram-markdown-sanitize.test.ts +0 -78
- package/src/channels/telegram-markdown-sanitize.ts +0 -55
- package/src/channels/telegram-pairing.test.ts +0 -254
- package/src/channels/telegram-pairing.ts +0 -339
- package/src/channels/telegram.ts +0 -279
- package/src/channels/trust-hint.test.ts +0 -48
- package/src/channels/trust-hint.ts +0 -75
- package/src/claude-md-compose.migrate.test.ts +0 -64
- package/src/claude-md-compose.ts +0 -205
- package/src/command-gate.ts +0 -63
- package/src/config.test.ts +0 -93
- package/src/config.ts +0 -128
- package/src/container-config.ts +0 -167
- package/src/container-runner.test.ts +0 -32
- package/src/container-runner.ts +0 -576
- package/src/container-runtime.test.ts +0 -269
- package/src/container-runtime.ts +0 -167
- package/src/db/_bun-sqlite-shim.ts +0 -88
- package/src/db/agent-activity.test.ts +0 -155
- package/src/db/agent-activity.ts +0 -121
- package/src/db/agent-groups.ts +0 -77
- package/src/db/connection.migrate.test.ts +0 -176
- package/src/db/connection.ts +0 -259
- package/src/db/db-v2.test.ts +0 -440
- package/src/db/dropped-messages.ts +0 -44
- package/src/db/index.ts +0 -40
- package/src/db/messaging-groups.ts +0 -252
- package/src/db/migrations/001-initial.ts +0 -112
- package/src/db/migrations/002-chat-sdk-state.ts +0 -36
- package/src/db/migrations/008-dropped-messages.ts +0 -27
- package/src/db/migrations/009-drop-pending-credentials.ts +0 -13
- package/src/db/migrations/010-engage-modes.ts +0 -103
- package/src/db/migrations/011-pending-sender-approvals.ts +0 -40
- package/src/db/migrations/012-channel-registration.ts +0 -48
- package/src/db/migrations/013-approval-render-metadata.ts +0 -27
- package/src/db/migrations/014-secrets.ts +0 -44
- package/src/db/migrations/015-secrets-drop-host-pattern.ts +0 -18
- package/src/db/migrations/016-secret-assignments.ts +0 -30
- package/src/db/migrations/017-agent-activity.ts +0 -40
- package/src/db/migrations/018-oauth-app-configs.ts +0 -34
- package/src/db/migrations/019-oauth-app-connections.ts +0 -48
- package/src/db/migrations/020-agent-app-connections.ts +0 -28
- package/src/db/migrations/021-pending-oauth-states.ts +0 -35
- package/src/db/migrations/022-app-connections-provider.ts +0 -25
- package/src/db/migrations/023-agent-group-secret-mode.test.ts +0 -124
- package/src/db/migrations/023-agent-group-secret-mode.ts +0 -65
- package/src/db/migrations/024-collapse-approvals.test.ts +0 -249
- package/src/db/migrations/024-collapse-approvals.ts +0 -182
- package/src/db/migrations/025-secret-mode-check.test.ts +0 -155
- package/src/db/migrations/025-secret-mode-check.ts +0 -49
- package/src/db/migrations/026-user-dms-bot-id.test.ts +0 -116
- package/src/db/migrations/026-user-dms-bot-id.ts +0 -54
- package/src/db/migrations/027-provider-credentials.ts +0 -41
- package/src/db/migrations/_test-helpers.ts +0 -41
- package/src/db/migrations/index.ts +0 -127
- package/src/db/migrations/module-agent-to-agent-destinations.ts +0 -84
- package/src/db/migrations/module-approvals-pending-approvals.ts +0 -42
- package/src/db/migrations/module-approvals-title-options.ts +0 -40
- package/src/db/schema.ts +0 -258
- package/src/db/session-db.test.ts +0 -93
- package/src/db/session-db.ts +0 -325
- package/src/db/sessions.ts +0 -241
- package/src/delivery.test.ts +0 -148
- package/src/delivery.ts +0 -445
- package/src/env.ts +0 -74
- package/src/group-folder.test.ts +0 -35
- package/src/group-folder.ts +0 -44
- package/src/group-init.ts +0 -92
- package/src/host-core.test.ts +0 -456
- package/src/host-sweep.test.ts +0 -146
- package/src/host-sweep.ts +0 -287
- package/src/index.ts +0 -232
- package/src/install-slug.ts +0 -33
- package/src/log.test.ts +0 -81
- package/src/log.ts +0 -117
- package/src/mcp/http.ts +0 -72
- package/src/mcp/server.ts +0 -92
- package/src/mcp/stdio.ts +0 -51
- package/src/mcp/tools/activity.ts +0 -88
- package/src/mcp/tools/agent-groups.ts +0 -183
- package/src/mcp/tools/approvals.ts +0 -122
- package/src/mcp/tools/channels.test.ts +0 -126
- package/src/mcp/tools/channels.ts +0 -134
- package/src/mcp/tools/index.ts +0 -27
- package/src/mcp/tools/oauth.ts +0 -48
- package/src/mcp/tools/secrets.ts +0 -169
- package/src/mcp/tools/sessions.ts +0 -135
- package/src/mcp/types.ts +0 -51
- package/src/modules/agent-to-agent/agent-route.test.ts +0 -46
- package/src/modules/agent-to-agent/agent-route.ts +0 -223
- package/src/modules/agent-to-agent/create-agent.ts +0 -127
- package/src/modules/agent-to-agent/db/agent-destinations.ts +0 -135
- package/src/modules/agent-to-agent/index.ts +0 -22
- package/src/modules/agent-to-agent/write-destinations.ts +0 -59
- package/src/modules/approvals/agent.md +0 -45
- package/src/modules/approvals/index.ts +0 -21
- package/src/modules/approvals/picks.test.ts +0 -291
- package/src/modules/approvals/primitive.ts +0 -279
- package/src/modules/approvals/project.md +0 -27
- package/src/modules/approvals/response-handler.ts +0 -87
- package/src/modules/index.ts +0 -24
- package/src/modules/interactive/agent.md +0 -21
- package/src/modules/interactive/index.ts +0 -69
- package/src/modules/interactive/project.md +0 -12
- package/src/modules/mount-security/expand-path.test.ts +0 -82
- package/src/modules/mount-security/index.ts +0 -459
- package/src/modules/mount-security/migrate.test.ts +0 -91
- package/src/modules/permissions/access.ts +0 -28
- package/src/modules/permissions/channel-approval.test.ts +0 -389
- package/src/modules/permissions/channel-approval.ts +0 -188
- package/src/modules/permissions/db/agent-group-members.ts +0 -44
- package/src/modules/permissions/db/pending-channel-approvals.test.ts +0 -86
- package/src/modules/permissions/db/pending-channel-approvals.ts +0 -66
- package/src/modules/permissions/db/pending-sender-approvals.ts +0 -60
- package/src/modules/permissions/db/user-dms.ts +0 -58
- package/src/modules/permissions/db/user-roles.ts +0 -85
- package/src/modules/permissions/db/users.ts +0 -38
- package/src/modules/permissions/index.ts +0 -421
- package/src/modules/permissions/permissions.test.ts +0 -358
- package/src/modules/permissions/sender-approval.test.ts +0 -641
- package/src/modules/permissions/sender-approval.ts +0 -165
- package/src/modules/permissions/user-dm.ts +0 -200
- package/src/modules/provider-credentials/db.ts +0 -121
- package/src/modules/provider-credentials/index.ts +0 -12
- package/src/modules/provider-credentials/spawn.test.ts +0 -206
- package/src/modules/provider-credentials/spawn.ts +0 -114
- package/src/modules/scheduling/actions.ts +0 -113
- package/src/modules/scheduling/db.test.ts +0 -282
- package/src/modules/scheduling/db.ts +0 -148
- package/src/modules/scheduling/index.ts +0 -34
- package/src/modules/scheduling/recurrence.test.ts +0 -98
- package/src/modules/scheduling/recurrence.ts +0 -54
- package/src/modules/self-mod/agent.md +0 -30
- package/src/modules/self-mod/apply.ts +0 -85
- package/src/modules/self-mod/index.ts +0 -30
- package/src/modules/self-mod/project.md +0 -39
- package/src/modules/self-mod/request.ts +0 -91
- package/src/modules/typing/index.ts +0 -165
- package/src/oauth/agent-app-connections.ts +0 -103
- package/src/oauth/app-configs.test.ts +0 -64
- package/src/oauth/app-configs.ts +0 -114
- package/src/oauth/app-connections.test.ts +0 -109
- package/src/oauth/app-connections.ts +0 -178
- package/src/oauth/crypto.ts +0 -56
- package/src/oauth/flow.ts +0 -104
- package/src/oauth/providers/google.test.ts +0 -38
- package/src/oauth/providers/google.ts +0 -46
- package/src/oauth/providers/index.ts +0 -48
- package/src/oauth/state-store.test.ts +0 -54
- package/src/oauth/state-store.ts +0 -93
- package/src/parachute/README.md +0 -27
- package/src/parachute/create-agent.test.ts +0 -83
- package/src/parachute/create-agent.ts +0 -122
- package/src/parachute/group-status.test.ts +0 -165
- package/src/parachute/group-status.ts +0 -136
- package/src/parachute/types.ts +0 -41
- package/src/parachute/vault-mcp.test.ts +0 -251
- package/src/parachute/vault-mcp.ts +0 -232
- package/src/platform-id.test.ts +0 -104
- package/src/platform-id.ts +0 -109
- package/src/providers/index.ts +0 -6
- package/src/providers/provider-container-registry.ts +0 -58
- package/src/response-registry.ts +0 -45
- package/src/router.ts +0 -530
- package/src/secrets/crypto.test.ts +0 -45
- package/src/secrets/crypto.ts +0 -55
- package/src/secrets/index.ts +0 -461
- package/src/secrets/master-key.ts +0 -70
- package/src/secrets/secrets.test.ts +0 -651
- package/src/session-manager.attachments.test.ts +0 -171
- package/src/session-manager.dup-skip.test.ts +0 -173
- package/src/session-manager.migrate.test.ts +0 -59
- package/src/session-manager.ts +0 -451
- package/src/startup-bootstrap.test.ts +0 -226
- package/src/startup-bootstrap.ts +0 -207
- package/src/state-sqlite.ts +0 -182
- package/src/timezone.test.ts +0 -64
- package/src/timezone.ts +0 -37
- package/src/types.ts +0 -233
- package/src/web/auth.test.ts +0 -335
- package/src/web/auth.ts +0 -214
- package/src/web/discord-validate.test.ts +0 -77
- package/src/web/discord-validate.ts +0 -88
- package/src/web/hub-discovery.test.ts +0 -98
- package/src/web/hub-discovery.ts +0 -69
- package/src/web/routes/activity.ts +0 -106
- package/src/web/routes/agent-provider.test.ts +0 -282
- package/src/web/routes/agent-provider.ts +0 -309
- package/src/web/routes/approvals.ts +0 -185
- package/src/web/routes/apps.ts +0 -434
- package/src/web/routes/channels-mg-detail.test.ts +0 -324
- package/src/web/routes/channels-mga-detail.test.ts +0 -472
- package/src/web/routes/channels.ts +0 -311
- package/src/web/routes/oauth-providers.ts +0 -42
- package/src/web/routes/secrets.test.ts +0 -220
- package/src/web/routes/secrets.ts +0 -317
- package/src/web/routes/sessions.ts +0 -123
- package/src/web/routes/settings.test.ts +0 -106
- package/src/web/routes/settings.ts +0 -247
- package/src/web/routes/setup-status.ts +0 -205
- package/src/web/routes/vaults.test.ts +0 -389
- package/src/web/routes/vaults.ts +0 -225
- package/src/web/server-version.test.ts +0 -16
- package/src/web/server.ts +0 -1024
- package/src/web/services-manifest.test.ts +0 -148
- package/src/web/services-manifest.ts +0 -66
- package/src/web/static-serve.test.ts +0 -255
- package/src/web/static-serve.ts +0 -104
- package/src/web/telegram-validate.test.ts +0 -116
- package/src/web/telegram-validate.ts +0 -107
- package/src/web/vault-proxy.test.ts +0 -214
- package/src/web/vault-proxy.ts +0 -120
- package/src/web/wire-channel.ts +0 -181
- package/src/webhook-server.ts +0 -134
- package/vitest.config.ts +0 -18
- package/web/README.md +0 -63
- package/web/ui/index.html +0 -13
- package/web/ui/package.json +0 -35
- package/web/ui/pnpm-lock.yaml +0 -2164
- package/web/ui/scripts/verify-base.mjs +0 -31
- package/web/ui/src/App.tsx +0 -88
- package/web/ui/src/components/ActivityFeed.tsx +0 -444
- package/web/ui/src/components/AgentGroupPicker.tsx +0 -263
- package/web/ui/src/components/AgentProviderCards.tsx +0 -220
- package/web/ui/src/components/CredentialForm.tsx +0 -214
- package/web/ui/src/components/ScopeGrants.tsx +0 -74
- package/web/ui/src/components/StatusDot.tsx +0 -43
- package/web/ui/src/components/VaultPicker.tsx +0 -127
- package/web/ui/src/components/setup/AdapterInstallStep.tsx +0 -178
- package/web/ui/src/components/setup/AgentGroupStep.tsx +0 -43
- package/web/ui/src/components/setup/ChannelPickStep.tsx +0 -74
- package/web/ui/src/components/setup/DoneStep.tsx +0 -49
- package/web/ui/src/components/setup/PrereqStep.tsx +0 -129
- package/web/ui/src/components/setup/TestConnectionStep.tsx +0 -108
- package/web/ui/src/components/setup/TestMessageStep.tsx +0 -104
- package/web/ui/src/components/setup/WireChannelStep.tsx +0 -166
- package/web/ui/src/components/setup/types.ts +0 -105
- package/web/ui/src/lib/api.test.ts +0 -410
- package/web/ui/src/lib/api.ts +0 -1248
- package/web/ui/src/lib/auth.test.ts +0 -352
- package/web/ui/src/lib/auth.ts +0 -405
- package/web/ui/src/lib/channel-adapters.ts +0 -136
- package/web/ui/src/main.tsx +0 -19
- package/web/ui/src/routes/ApprovalsList.tsx +0 -294
- package/web/ui/src/routes/Apps.tsx +0 -613
- package/web/ui/src/routes/ChannelWireDetail.test.tsx +0 -233
- package/web/ui/src/routes/ChannelWireDetail.tsx +0 -403
- package/web/ui/src/routes/ChannelsList.tsx +0 -158
- package/web/ui/src/routes/GroupDetail.test.tsx +0 -206
- package/web/ui/src/routes/GroupDetail.tsx +0 -880
- package/web/ui/src/routes/GroupList.tsx +0 -187
- package/web/ui/src/routes/MessagingGroupDetail.test.tsx +0 -233
- package/web/ui/src/routes/MessagingGroupDetail.tsx +0 -306
- package/web/ui/src/routes/NewGroupWizard.tsx +0 -390
- package/web/ui/src/routes/OAuthCallback.tsx +0 -56
- package/web/ui/src/routes/SecretsList.tsx +0 -942
- package/web/ui/src/routes/SessionsList.tsx +0 -220
- package/web/ui/src/routes/SettingsAgentProvider.tsx +0 -109
- package/web/ui/src/routes/SettingsApprovals.tsx +0 -234
- package/web/ui/src/routes/SetupWizard.tsx +0 -219
- package/web/ui/src/routes/VaultDetail.test.tsx +0 -363
- package/web/ui/src/routes/VaultDetail.tsx +0 -960
- package/web/ui/src/routes/VaultsList.tsx +0 -295
- package/web/ui/src/routes/WireChannelPage.tsx +0 -413
- package/web/ui/src/styles.css +0 -608
- package/web/ui/src/test/setup.ts +0 -23
- package/web/ui/src/vite-env.d.ts +0 -10
- package/web/ui/vite.config.ts +0 -34
- package/web/ui/vitest.config.ts +0 -25
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
# Post-night reflections — paraclaw rebirth
|
|
2
|
-
|
|
3
|
-
A short retrospective written the morning after `night/paraclaw-rebirth` landed.
|
|
4
|
-
The branch carried roughly seven mergeable PRs plus a handful of merges from
|
|
5
|
-
sibling subtrees (`night/server`, `night/ui`, `night/arch`), and ended up
|
|
6
|
-
absorbing the OneCLI debrand, the AES-GCM secrets cutover, the activity log,
|
|
7
|
-
the OAuth-apps scaffold, and the host-side MCP server. The point of this note
|
|
8
|
-
is not to inventory what shipped — `git log` does that — but to say what the
|
|
9
|
-
process actually felt like, which parts of it earned their keep, and where the
|
|
10
|
-
next push should aim.
|
|
11
|
-
|
|
12
|
-
## A. What worked well
|
|
13
|
-
|
|
14
|
-
**Tentacle-per-repo stewardship paid off as soon as the merge train started
|
|
15
|
-
moving.** Each PR had a single steward who could read the diff cold without
|
|
16
|
-
needing to be re-briefed on what `inbound.db` was or why the secret-assignment
|
|
17
|
-
table didn't get folded into `agent_groups`. When PR #2's UI-side polish ran
|
|
18
|
-
into a missing `assignedMode` field on `/api/secrets`, the fix landed as
|
|
19
|
-
`38aa7cf feat(server): surface assignedMode on /api/secrets responses` from
|
|
20
|
-
the server tentacle within the same merge window — without a context handoff
|
|
21
|
-
or a re-litigation of the contract. The cohesive-PR rule meant the migration
|
|
22
|
-
file, the API surface, and the UI consumer were all in the same diff, so the
|
|
23
|
-
ack-loop between tentacles was tight.
|
|
24
|
-
|
|
25
|
-
**Three-tier governance held under load.** The reviewer-then-team-lead-then-Aaron
|
|
26
|
-
chain was tested seven times in close succession, and the failure mode that
|
|
27
|
-
governance is supposed to prevent — an automated merge that nobody actually
|
|
28
|
-
read — never occurred. Even the hotfix PR (#16, the localhost translation)
|
|
29
|
-
went through the same three gates. The cost of the discipline was small:
|
|
30
|
-
maybe a minute per PR for the human click. The benefit shows up in the kind
|
|
31
|
-
of bug that *didn't* land — there's no record of a regression PR, no revert
|
|
32
|
-
commit on the branch.
|
|
33
|
-
|
|
34
|
-
**The serial merge train, with #1→#2→#3→#4→#7→#5→#16→#6 in order, prevented
|
|
35
|
-
the migration-index collision class entirely.** Every PR that touched
|
|
36
|
-
`src/db/migrations/index.ts` was the only PR in flight that touched it at
|
|
37
|
-
that moment. Migration `019_…` slotted in cleanly because `018_…` had already
|
|
38
|
-
landed and been numbered. The earlier-era pattern of "open three migration
|
|
39
|
-
PRs in parallel and resolve numbering at the end" would have been
|
|
40
|
-
correspondingly painful — this branch demonstrated empirically that the
|
|
41
|
-
serial-train cost (waiting your turn) is cheaper than the parallel-merge cost
|
|
42
|
-
(rebasing migrations against a moving target).
|
|
43
|
-
|
|
44
|
-
**The /spawn → /report → /loop cadence kept the human out of the inner loop
|
|
45
|
-
without losing the human review at the outer loop.** Aaron didn't have to
|
|
46
|
-
remember which tentacle was on which PR; the dashboard showed it. Tentacles
|
|
47
|
-
didn't have to ask permission to read files or run tests; they just did. The
|
|
48
|
-
moments Aaron *did* show up — the merge clicks, the redirect on PR #7 about
|
|
49
|
-
the mount-aware OAuth callback URI — were the moments where his judgment was
|
|
50
|
-
actually load-bearing. That ratio is the right one.
|
|
51
|
-
|
|
52
|
-
## B. Friction worth fixing
|
|
53
|
-
|
|
54
|
-
**The localhost-translation bug (#16) is the most interesting friction
|
|
55
|
-
point — not because of when it landed, but because of how it was found.**
|
|
56
|
-
#16 landed just before #6, so the host-side MCP server got the fix on
|
|
57
|
-
landing; that part of the sequencing was clean. The friction is that the
|
|
58
|
-
architectural gap (a `url: http://localhost:1939/mcp` baked into
|
|
59
|
-
`container.json` is unreachable from inside the container, because
|
|
60
|
-
container-loopback is not host-loopback) was latent through every prior
|
|
61
|
-
MCP-server attach paraclaw had ever done, and would still be latent today
|
|
62
|
-
if a real techne agent hadn't tripped over it trying to call its vault. The fix in `src/parachute/vault-mcp.ts:65–81` is
|
|
63
|
-
clean — translate at spawn time, leave the on-disk URL operator-facing — but
|
|
64
|
-
the *detection* came late.
|
|
65
|
-
|
|
66
|
-
The lesson is not "write more tests"; it's that paraclaw lacks an
|
|
67
|
-
operator-facing surface that says "here is what this container can actually
|
|
68
|
-
reach." A `/api/groups/<id>/diagnose` endpoint that, at session-spawn time,
|
|
69
|
-
ran a synthetic curl from inside the container against every MCP URL would
|
|
70
|
-
have caught this on the first attached vault, before any agent message round-tripped.
|
|
71
|
-
The same surface would catch DNS, TLS, and missing-auth-header failures —
|
|
72
|
-
all in the same shape. This is the kind of thing the setup wizard
|
|
73
|
-
(`web/ui/src/routes/SetupWizard.tsx:23`) should be growing toward; right now
|
|
74
|
-
it walks the operator through configuration, but it doesn't *prove*
|
|
75
|
-
configuration. Proving it would shift a class of bugs from
|
|
76
|
-
"reported-by-confused-user" to "caught-at-attach-time."
|
|
77
|
-
|
|
78
|
-
**Version skew between npm-published and locally-linked packages bit
|
|
79
|
-
twice.** The vault-routing pluralization issue earlier in the cycle (vault
|
|
80
|
-
exposing `notes/by-tag/:tag` while paraclaw's vault MCP integration assumed
|
|
81
|
-
`note/by-tag/:tag`) was an avoidable consequence of two repos shipping
|
|
82
|
-
independently with no schema-pinning between them. The night's fix was
|
|
83
|
-
ad-hoc; the structural fix is to either (a) pin paraclaw to a specific
|
|
84
|
-
parachute-vault version and lockstep them, or (b) treat the vault MCP surface
|
|
85
|
-
as an external API and version it with a content-negotiation header. We've
|
|
86
|
-
been operating as if both repos are pre-1.0 enough to be "just keep them in
|
|
87
|
-
sync mentally," but the empirical record says we drift faster than mental
|
|
88
|
-
sync can keep up.
|
|
89
|
-
|
|
90
|
-
**The reviewer hit usage limits mid-review on at least one of the larger
|
|
91
|
-
PRs.** That's not a process bug per se, but it's a signal that some PRs are
|
|
92
|
-
too large for a single review session even with cohesive-PR discipline.
|
|
93
|
-
The OAuth-apps PR (#7) was the worst offender — it spanned a migration, four
|
|
94
|
-
new endpoints, the OAuth flow, the redirect-URI plumbing, and the
|
|
95
|
-
mount-aware callback handling. In retrospect, splitting it into "OAuth state
|
|
96
|
-
table + scaffolding" then "Google provider" would have kept each review
|
|
97
|
-
under the limit and exposed the provider abstraction earlier.
|
|
98
|
-
|
|
99
|
-
**`c854dc2 fix(web): restore wire-channel route (was dropped in web-merge)`
|
|
100
|
-
is a quiet warning.** A route was silently dropped during a subtree merge
|
|
101
|
-
and only noticed when the UI lost a feature. The recovery was easy; the
|
|
102
|
-
detection was not — there's no test that says "the wire-channel route
|
|
103
|
-
exists." Smoke tests at the route level (mount the SPA in test mode, walk
|
|
104
|
-
the router tree, assert each known route responds 200) would catch
|
|
105
|
-
silent-drop bugs in the cheapest possible way.
|
|
106
|
-
|
|
107
|
-
## C. Where paraclaw goes next
|
|
108
|
-
|
|
109
|
-
**The natural next step after the host-side MCP server is the second
|
|
110
|
-
tentacle of self-modification.** Today the agent can install packages and
|
|
111
|
-
add MCP servers via approval-gated tools (`container/agent-runner/src/mcp-tools/self-mod.ts`).
|
|
112
|
-
The absent tier is direct source-level edits — the agent draftng a change
|
|
113
|
-
to its own `CLAUDE.md`, its own skills, or even its own host code, and the
|
|
114
|
-
draft entering the same approval flow that vault attach goes through. The
|
|
115
|
-
scaffolding is mostly there: `pending_approvals`, the approver-routing in
|
|
116
|
-
`src/modules/approvals/primitive.ts`, the decide endpoint at
|
|
117
|
-
`/api/approvals/:id/decide`. What's missing is the diff-presentation surface
|
|
118
|
-
in the UI (we have an approval card, but it shows a JSON payload — for
|
|
119
|
-
source edits we want a syntax-highlighted diff) and a sandboxed "apply this
|
|
120
|
-
draft to a throwaway worktree, run tests, present the result" step before
|
|
121
|
-
the human ever sees the approval card.
|
|
122
|
-
|
|
123
|
-
**OAuth providers beyond Google are the next obvious extension after PR #5,
|
|
124
|
-
and the abstraction is currently thin.** The `oauthTools` in
|
|
125
|
-
`src/mcp/tools/oauth.ts` and the `/claw/apps` UI route are Google-shaped in
|
|
126
|
-
their assumptions (PKCE, the specific scope strings, the callback contract).
|
|
127
|
-
A second provider — Notion, Linear, GitHub — will reveal which of those
|
|
128
|
-
assumptions are actually generic and which are accidentally Google. Doing
|
|
129
|
-
the second provider sooner rather than later is the cheapest way to find
|
|
130
|
-
out.
|
|
131
|
-
|
|
132
|
-
**Pre-1.0 structural simplifications already flagged in
|
|
133
|
-
`docs/fresh-start-thinking.md` (drafted on `research/fresh-start-thinking`,
|
|
134
|
-
not yet merged) are the right size for this window.** Move
|
|
135
|
-
`assigned_mode` from `secrets` to `agent_groups` (so the assignment lives
|
|
136
|
-
where the consumer is, not where the producer is). Drop `secrets.host_pattern`
|
|
137
|
-
— it was an OneCLI-era idea that paraclaw never used. Consolidate
|
|
138
|
-
`pending_questions` and `pending_approvals` into one table with a `kind`
|
|
139
|
-
column — the divergence is purely historical. Retire the `v2-sessions`
|
|
140
|
-
naming on the filesystem; we are no longer "v2 of nano-claw," we are
|
|
141
|
-
paraclaw. None of these are urgent; all of them get more expensive the
|
|
142
|
-
longer we wait.
|
|
143
|
-
|
|
144
|
-
**The single thing I would not do next is add another channel adapter.**
|
|
145
|
-
We have over a dozen on the `channels` branch, the install skills are
|
|
146
|
-
stable, and the marginal value of the next one is low compared to closing
|
|
147
|
-
the self-modification loop or proving the OAuth abstraction. The temptation is
|
|
148
|
-
strong because new channels are crowd-pleasers, but the right move is to
|
|
149
|
-
deepen what's there.
|
|
150
|
-
|
|
151
|
-
— paraclaw-research, 2026-04-28
|
package/eslint.config.js
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import globals from 'globals'
|
|
2
|
-
import pluginJs from '@eslint/js'
|
|
3
|
-
import tseslint from 'typescript-eslint'
|
|
4
|
-
import noCatchAll from 'eslint-plugin-no-catch-all'
|
|
5
|
-
|
|
6
|
-
export default [
|
|
7
|
-
{ ignores: ['node_modules/', 'dist/', 'container/', 'groups/'] },
|
|
8
|
-
{ files: ['src/**/*.{js,ts}'] },
|
|
9
|
-
{ languageOptions: { globals: globals.node } },
|
|
10
|
-
pluginJs.configs.recommended,
|
|
11
|
-
...tseslint.configs.recommended,
|
|
12
|
-
{
|
|
13
|
-
plugins: { 'no-catch-all': noCatchAll },
|
|
14
|
-
rules: {
|
|
15
|
-
'preserve-caught-error': ['error', { requireCatchParameter: true }],
|
|
16
|
-
'@typescript-eslint/no-unused-vars': [
|
|
17
|
-
'error',
|
|
18
|
-
{
|
|
19
|
-
args: 'all',
|
|
20
|
-
argsIgnorePattern: '^_',
|
|
21
|
-
caughtErrors: 'all',
|
|
22
|
-
caughtErrorsIgnorePattern: '^_',
|
|
23
|
-
destructuredArrayIgnorePattern: '^_',
|
|
24
|
-
varsIgnorePattern: '^_',
|
|
25
|
-
ignoreRestSiblings: true,
|
|
26
|
-
},
|
|
27
|
-
],
|
|
28
|
-
'no-catch-all/no-catch-all': 'warn',
|
|
29
|
-
'@typescript-eslint/no-explicit-any': 'warn',
|
|
30
|
-
},
|
|
31
|
-
},
|
|
32
|
-
]
|
package/pnpm-workspace.yaml
DELETED
package/repo-tokens/README.md
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
# Repo Tokens
|
|
2
|
-
|
|
3
|
-
A GitHub Action that calculates the size of your codebase in terms of tokens and updates a badge in your README.
|
|
4
|
-
|
|
5
|
-
<p>
|
|
6
|
-
<img src="examples/green.svg" alt="tokens 12.4k">
|
|
7
|
-
<img src="examples/yellow-green.svg" alt="tokens 74.8k">
|
|
8
|
-
<img src="examples/yellow.svg" alt="tokens 120k">
|
|
9
|
-
<img src="examples/red.svg" alt="tokens 158k">
|
|
10
|
-
</p>
|
|
11
|
-
|
|
12
|
-
## Usage
|
|
13
|
-
|
|
14
|
-
```yaml
|
|
15
|
-
- uses: qwibitai/nanoclaw/repo-tokens@v1
|
|
16
|
-
with:
|
|
17
|
-
include: 'src/**/*.ts'
|
|
18
|
-
exclude: 'src/**/*.test.ts'
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
This counts tokens using [tiktoken](https://github.com/openai/tiktoken) and writes the result between HTML comment markers in your README:
|
|
22
|
-
|
|
23
|
-
The badge color reflects what percentage of an LLMs context window the codebase fills (context window size is configurable, defaults to 200k which is the size of Claude Opus). Green for under 30%, yellow-green for 30%-50%, yellow for 50%-70%, red for 70%+.
|
|
24
|
-
|
|
25
|
-
## Why
|
|
26
|
-
|
|
27
|
-
Small codebases were always a good thing. With coding agents, there's now a huge advantage to having a codebase small enough that an agent can hold the full thing in context.
|
|
28
|
-
|
|
29
|
-
This badge gives some indication of how easy it will be to work with an agent on the codebase, and will hopefully be a visual reminder to avoid bloat.
|
|
30
|
-
|
|
31
|
-
## Examples
|
|
32
|
-
|
|
33
|
-
Repos using repo-tokens:
|
|
34
|
-
|
|
35
|
-
| Repo | Badge |
|
|
36
|
-
|------|-------|
|
|
37
|
-
| [NanoClaw](https://github.com/qwibitai/NanoClaw) |  |
|
|
38
|
-
|
|
39
|
-
### Full workflow example
|
|
40
|
-
|
|
41
|
-
```yaml
|
|
42
|
-
name: Update token count
|
|
43
|
-
|
|
44
|
-
on:
|
|
45
|
-
push:
|
|
46
|
-
branches: [main]
|
|
47
|
-
paths: ['src/**']
|
|
48
|
-
|
|
49
|
-
permissions:
|
|
50
|
-
contents: write
|
|
51
|
-
|
|
52
|
-
jobs:
|
|
53
|
-
update-tokens:
|
|
54
|
-
runs-on: ubuntu-latest
|
|
55
|
-
steps:
|
|
56
|
-
- uses: actions/checkout@v4
|
|
57
|
-
|
|
58
|
-
- uses: actions/setup-python@v5
|
|
59
|
-
with:
|
|
60
|
-
python-version: '3.12'
|
|
61
|
-
|
|
62
|
-
- uses: qwibitai/nanoclaw/repo-tokens@v1
|
|
63
|
-
id: tokens
|
|
64
|
-
with:
|
|
65
|
-
include: 'src/**/*.ts'
|
|
66
|
-
exclude: 'src/**/*.test.ts'
|
|
67
|
-
badge-path: '.github/badges/tokens.svg'
|
|
68
|
-
|
|
69
|
-
- name: Commit if changed
|
|
70
|
-
run: |
|
|
71
|
-
git add README.md .github/badges/tokens.svg
|
|
72
|
-
git diff --cached --quiet && exit 0
|
|
73
|
-
git config user.name "github-actions[bot]"
|
|
74
|
-
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
75
|
-
git commit -m "docs: update token count to ${{ steps.tokens.outputs.badge }}"
|
|
76
|
-
git push
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
### README setup
|
|
80
|
-
|
|
81
|
-
Add markers where you want the token count text to appear:
|
|
82
|
-
|
|
83
|
-
```html
|
|
84
|
-
<!-- token-count --><!-- /token-count -->
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
The action replaces everything between the markers with the token count.
|
|
88
|
-
|
|
89
|
-
## Inputs
|
|
90
|
-
|
|
91
|
-
| Input | Default | Description |
|
|
92
|
-
|-------|---------|-------------|
|
|
93
|
-
| `include` | *required* | Glob patterns for files to count (space-separated) |
|
|
94
|
-
| `exclude` | `''` | Glob patterns to exclude (space-separated) |
|
|
95
|
-
| `context-window` | `200000` | Context window size for percentage calculation |
|
|
96
|
-
| `readme` | `README.md` | Path to README file |
|
|
97
|
-
| `encoding` | `cl100k_base` | Tiktoken encoding name |
|
|
98
|
-
| `marker` | `token-count` | HTML comment marker name |
|
|
99
|
-
| `badge-path` | `''` | Path to write SVG badge (empty = no SVG) |
|
|
100
|
-
|
|
101
|
-
## Outputs
|
|
102
|
-
|
|
103
|
-
| Output | Description |
|
|
104
|
-
|--------|-------------|
|
|
105
|
-
| `tokens` | Total token count (e.g., `34940`) |
|
|
106
|
-
| `percentage` | Percentage of context window (e.g., `17`) |
|
|
107
|
-
| `badge` | The formatted text that was inserted (e.g., `34.9k tokens · 17% of context window`) |
|
|
108
|
-
|
|
109
|
-
## How it works
|
|
110
|
-
|
|
111
|
-
Composite GitHub Action. Installs tiktoken, runs ~60 lines of inline Python. Takes about 10 seconds.
|
|
112
|
-
|
|
113
|
-
The action counts tokens and updates the README but does not commit. Your workflow decides the git strategy.
|
package/repo-tokens/action.yml
DELETED
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
name: Repo Tokens
|
|
2
|
-
description: Count codebase tokens with tiktoken and update a README badge
|
|
3
|
-
|
|
4
|
-
inputs:
|
|
5
|
-
include:
|
|
6
|
-
description: 'Glob patterns for files to count (space-separated)'
|
|
7
|
-
required: true
|
|
8
|
-
exclude:
|
|
9
|
-
description: 'Glob patterns to exclude (space-separated)'
|
|
10
|
-
required: false
|
|
11
|
-
default: ''
|
|
12
|
-
context-window:
|
|
13
|
-
description: 'Context window size for percentage calculation'
|
|
14
|
-
required: false
|
|
15
|
-
default: '200000'
|
|
16
|
-
readme:
|
|
17
|
-
description: 'Path to README file'
|
|
18
|
-
required: false
|
|
19
|
-
default: 'README.md'
|
|
20
|
-
encoding:
|
|
21
|
-
description: 'Tiktoken encoding name'
|
|
22
|
-
required: false
|
|
23
|
-
default: 'cl100k_base'
|
|
24
|
-
marker:
|
|
25
|
-
description: 'HTML comment marker name'
|
|
26
|
-
required: false
|
|
27
|
-
default: 'token-count'
|
|
28
|
-
badge-path:
|
|
29
|
-
description: 'Path to write SVG badge (empty = no SVG)'
|
|
30
|
-
required: false
|
|
31
|
-
default: ''
|
|
32
|
-
|
|
33
|
-
outputs:
|
|
34
|
-
tokens:
|
|
35
|
-
description: 'Total token count'
|
|
36
|
-
value: ${{ steps.count.outputs.tokens }}
|
|
37
|
-
percentage:
|
|
38
|
-
description: 'Percentage of context window'
|
|
39
|
-
value: ${{ steps.count.outputs.percentage }}
|
|
40
|
-
badge:
|
|
41
|
-
description: 'Badge text that was inserted'
|
|
42
|
-
value: ${{ steps.count.outputs.badge }}
|
|
43
|
-
|
|
44
|
-
runs:
|
|
45
|
-
using: composite
|
|
46
|
-
steps:
|
|
47
|
-
- name: Install tiktoken
|
|
48
|
-
shell: bash
|
|
49
|
-
run: pip install tiktoken
|
|
50
|
-
|
|
51
|
-
- name: Count tokens and update README
|
|
52
|
-
id: count
|
|
53
|
-
shell: python
|
|
54
|
-
env:
|
|
55
|
-
INPUT_INCLUDE: ${{ inputs.include }}
|
|
56
|
-
INPUT_EXCLUDE: ${{ inputs.exclude }}
|
|
57
|
-
INPUT_CONTEXT_WINDOW: ${{ inputs.context-window }}
|
|
58
|
-
INPUT_README: ${{ inputs.readme }}
|
|
59
|
-
INPUT_ENCODING: ${{ inputs.encoding }}
|
|
60
|
-
INPUT_MARKER: ${{ inputs.marker }}
|
|
61
|
-
INPUT_BADGE_PATH: ${{ inputs.badge-path }}
|
|
62
|
-
run: |
|
|
63
|
-
import glob, os, re, tiktoken
|
|
64
|
-
|
|
65
|
-
include_patterns = os.environ["INPUT_INCLUDE"].split()
|
|
66
|
-
exclude_patterns = os.environ["INPUT_EXCLUDE"].split()
|
|
67
|
-
context_window = int(os.environ["INPUT_CONTEXT_WINDOW"])
|
|
68
|
-
readme_path = os.environ["INPUT_README"]
|
|
69
|
-
encoding_name = os.environ["INPUT_ENCODING"]
|
|
70
|
-
marker = os.environ["INPUT_MARKER"]
|
|
71
|
-
badge_path = os.environ.get("INPUT_BADGE_PATH", "").strip()
|
|
72
|
-
|
|
73
|
-
# Expand globs
|
|
74
|
-
included = set()
|
|
75
|
-
for pattern in include_patterns:
|
|
76
|
-
included.update(glob.glob(pattern, recursive=True))
|
|
77
|
-
|
|
78
|
-
excluded = set()
|
|
79
|
-
for pattern in exclude_patterns:
|
|
80
|
-
excluded.update(glob.glob(pattern, recursive=True))
|
|
81
|
-
|
|
82
|
-
files = sorted(included - excluded)
|
|
83
|
-
files = [f for f in files if os.path.isfile(f)]
|
|
84
|
-
|
|
85
|
-
# Count tokens
|
|
86
|
-
enc = tiktoken.get_encoding(encoding_name)
|
|
87
|
-
total = 0
|
|
88
|
-
for path in files:
|
|
89
|
-
try:
|
|
90
|
-
with open(path, "r", encoding="utf-8", errors="ignore") as f:
|
|
91
|
-
total += len(enc.encode(f.read()))
|
|
92
|
-
except Exception as e:
|
|
93
|
-
print(f"Skipping {path}: {e}")
|
|
94
|
-
|
|
95
|
-
# Format
|
|
96
|
-
if total >= 100000:
|
|
97
|
-
display = f"{round(total / 1000)}k"
|
|
98
|
-
elif total >= 1000:
|
|
99
|
-
display = f"{total / 1000:.1f}k"
|
|
100
|
-
else:
|
|
101
|
-
display = str(total)
|
|
102
|
-
|
|
103
|
-
pct = round(total / context_window * 100)
|
|
104
|
-
badge = f"{display} tokens \u00b7 {pct}% of context window"
|
|
105
|
-
|
|
106
|
-
print(f"Files: {len(files)}, Tokens: {total}, Badge: {badge}")
|
|
107
|
-
|
|
108
|
-
# Update README (text between markers)
|
|
109
|
-
marker_re = re.compile(
|
|
110
|
-
rf"(<!--\s*{re.escape(marker)}\s*-->).*?(<!--\s*/{re.escape(marker)}\s*-->)",
|
|
111
|
-
re.DOTALL,
|
|
112
|
-
)
|
|
113
|
-
|
|
114
|
-
with open(readme_path, "r", encoding="utf-8") as f:
|
|
115
|
-
content = f.read()
|
|
116
|
-
|
|
117
|
-
repo_tokens_url = "https://github.com/qwibitai/nanoclaw/tree/main/repo-tokens"
|
|
118
|
-
linked_badge = f'<a href="{repo_tokens_url}">{badge}</a>'
|
|
119
|
-
new_content = marker_re.sub(rf"\1{linked_badge}\2", content)
|
|
120
|
-
|
|
121
|
-
if new_content != content:
|
|
122
|
-
with open(readme_path, "w", encoding="utf-8") as f:
|
|
123
|
-
f.write(new_content)
|
|
124
|
-
print("README updated")
|
|
125
|
-
else:
|
|
126
|
-
print("No change to README")
|
|
127
|
-
|
|
128
|
-
# Generate SVG badge
|
|
129
|
-
if badge_path:
|
|
130
|
-
label_text = "tokens"
|
|
131
|
-
value_text = display
|
|
132
|
-
full_desc = f"{display} tokens, {pct}% of context window"
|
|
133
|
-
|
|
134
|
-
cw = 7.0
|
|
135
|
-
label_w = round(len(label_text) * cw) + 10
|
|
136
|
-
value_w = round(len(value_text) * cw) + 10
|
|
137
|
-
total_w = label_w + value_w
|
|
138
|
-
|
|
139
|
-
if pct < 30:
|
|
140
|
-
color = "#4c1"
|
|
141
|
-
elif pct < 50:
|
|
142
|
-
color = "#97ca00"
|
|
143
|
-
elif pct < 70:
|
|
144
|
-
color = "#dfb317"
|
|
145
|
-
else:
|
|
146
|
-
color = "#e05d44"
|
|
147
|
-
|
|
148
|
-
lx = label_w // 2
|
|
149
|
-
vx = label_w + value_w // 2
|
|
150
|
-
|
|
151
|
-
repo_tokens_url = "https://github.com/qwibitai/nanoclaw/tree/main/repo-tokens"
|
|
152
|
-
|
|
153
|
-
svg = f'''<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="{total_w}" height="20" role="img" aria-label="{full_desc}">
|
|
154
|
-
<title>{full_desc}</title>
|
|
155
|
-
<linearGradient id="s" x2="0" y2="100%">
|
|
156
|
-
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
|
|
157
|
-
<stop offset="1" stop-opacity=".1"/>
|
|
158
|
-
</linearGradient>
|
|
159
|
-
<clipPath id="r">
|
|
160
|
-
<rect width="{total_w}" height="20" rx="3" fill="#fff"/>
|
|
161
|
-
</clipPath>
|
|
162
|
-
<a xlink:href="{repo_tokens_url}">
|
|
163
|
-
<g clip-path="url(#r)">
|
|
164
|
-
<rect width="{label_w}" height="20" fill="#555"/>
|
|
165
|
-
<rect x="{label_w}" width="{value_w}" height="20" fill="{color}"/>
|
|
166
|
-
<rect width="{total_w}" height="20" fill="url(#s)"/>
|
|
167
|
-
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" font-size="11">
|
|
168
|
-
<text aria-hidden="true" x="{lx}" y="15" fill="#010101" fill-opacity=".3">{label_text}</text>
|
|
169
|
-
<text x="{lx}" y="14">{label_text}</text>
|
|
170
|
-
<text aria-hidden="true" x="{vx}" y="15" fill="#010101" fill-opacity=".3">{value_text}</text>
|
|
171
|
-
<text x="{vx}" y="14">{value_text}</text>
|
|
172
|
-
</g>
|
|
173
|
-
</g>
|
|
174
|
-
</a>
|
|
175
|
-
</svg>'''
|
|
176
|
-
|
|
177
|
-
os.makedirs(os.path.dirname(badge_path) or ".", exist_ok=True)
|
|
178
|
-
with open(badge_path, "w", encoding="utf-8") as f:
|
|
179
|
-
f.write(svg)
|
|
180
|
-
print(f"Badge SVG written to {badge_path}")
|
|
181
|
-
|
|
182
|
-
# Set outputs
|
|
183
|
-
with open(os.environ["GITHUB_OUTPUT"], "a") as f:
|
|
184
|
-
f.write(f"tokens={total}\n")
|
|
185
|
-
f.write(f"percentage={pct}\n")
|
|
186
|
-
f.write(f"badge={badge}\n")
|
package/repo-tokens/badge.svg
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="90" height="20" role="img" aria-label="132k tokens, 66% of context window">
|
|
2
|
-
<title>132k tokens, 66% of context window</title>
|
|
3
|
-
<linearGradient id="s" x2="0" y2="100%">
|
|
4
|
-
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
|
|
5
|
-
<stop offset="1" stop-opacity=".1"/>
|
|
6
|
-
</linearGradient>
|
|
7
|
-
<clipPath id="r">
|
|
8
|
-
<rect width="90" height="20" rx="3" fill="#fff"/>
|
|
9
|
-
</clipPath>
|
|
10
|
-
<a xlink:href="https://github.com/qwibitai/nanoclaw/tree/main/repo-tokens">
|
|
11
|
-
<g clip-path="url(#r)">
|
|
12
|
-
<rect width="52" height="20" fill="#555"/>
|
|
13
|
-
<rect x="52" width="38" height="20" fill="#dfb317"/>
|
|
14
|
-
<rect width="90" height="20" fill="url(#s)"/>
|
|
15
|
-
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" font-size="11">
|
|
16
|
-
<text aria-hidden="true" x="26" y="15" fill="#010101" fill-opacity=".3">tokens</text>
|
|
17
|
-
<text x="26" y="14">tokens</text>
|
|
18
|
-
<text aria-hidden="true" x="71" y="15" fill="#010101" fill-opacity=".3">132k</text>
|
|
19
|
-
<text x="71" y="14">132k</text>
|
|
20
|
-
</g>
|
|
21
|
-
</g>
|
|
22
|
-
</a>
|
|
23
|
-
</svg>
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="97" height="20" role="img" aria-label="12.4k tokens">
|
|
2
|
-
<title>12.4k tokens</title>
|
|
3
|
-
<linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient>
|
|
4
|
-
<clipPath id="r"><rect width="97" height="20" rx="3"/></clipPath>
|
|
5
|
-
<g clip-path="url(#r)">
|
|
6
|
-
<rect width="52" height="20" fill="#555"/>
|
|
7
|
-
<rect x="52" width="45" height="20" fill="#4c1"/>
|
|
8
|
-
<rect width="97" height="20" fill="url(#s)"/>
|
|
9
|
-
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" font-size="11">
|
|
10
|
-
<text x="26" y="15" fill="#010101" fill-opacity=".3">tokens</text><text x="26" y="14">tokens</text>
|
|
11
|
-
<text x="74" y="15" fill="#010101" fill-opacity=".3">12.4k</text><text x="74" y="14">12.4k</text>
|
|
12
|
-
</g>
|
|
13
|
-
</g>
|
|
14
|
-
</svg>
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="90" height="20" role="img" aria-label="158k tokens">
|
|
2
|
-
<title>158k tokens</title>
|
|
3
|
-
<linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient>
|
|
4
|
-
<clipPath id="r"><rect width="90" height="20" rx="3"/></clipPath>
|
|
5
|
-
<g clip-path="url(#r)">
|
|
6
|
-
<rect width="52" height="20" fill="#555"/>
|
|
7
|
-
<rect x="52" width="38" height="20" fill="#e05d44"/>
|
|
8
|
-
<rect width="90" height="20" fill="url(#s)"/>
|
|
9
|
-
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" font-size="11">
|
|
10
|
-
<text x="26" y="15" fill="#010101" fill-opacity=".3">tokens</text><text x="26" y="14">tokens</text>
|
|
11
|
-
<text x="71" y="15" fill="#010101" fill-opacity=".3">158k</text><text x="71" y="14">158k</text>
|
|
12
|
-
</g>
|
|
13
|
-
</g>
|
|
14
|
-
</svg>
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="97" height="20" role="img" aria-label="74.8k tokens">
|
|
2
|
-
<title>74.8k tokens</title>
|
|
3
|
-
<linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient>
|
|
4
|
-
<clipPath id="r"><rect width="97" height="20" rx="3"/></clipPath>
|
|
5
|
-
<g clip-path="url(#r)">
|
|
6
|
-
<rect width="52" height="20" fill="#555"/>
|
|
7
|
-
<rect x="52" width="45" height="20" fill="#97ca00"/>
|
|
8
|
-
<rect width="97" height="20" fill="url(#s)"/>
|
|
9
|
-
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" font-size="11">
|
|
10
|
-
<text x="26" y="15" fill="#010101" fill-opacity=".3">tokens</text><text x="26" y="14">tokens</text>
|
|
11
|
-
<text x="74" y="15" fill="#010101" fill-opacity=".3">74.8k</text><text x="74" y="14">74.8k</text>
|
|
12
|
-
</g>
|
|
13
|
-
</g>
|
|
14
|
-
</svg>
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="90" height="20" role="img" aria-label="120k tokens">
|
|
2
|
-
<title>120k tokens</title>
|
|
3
|
-
<linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient>
|
|
4
|
-
<clipPath id="r"><rect width="90" height="20" rx="3"/></clipPath>
|
|
5
|
-
<g clip-path="url(#r)">
|
|
6
|
-
<rect width="52" height="20" fill="#555"/>
|
|
7
|
-
<rect x="52" width="38" height="20" fill="#dfb317"/>
|
|
8
|
-
<rect width="90" height="20" fill="url(#s)"/>
|
|
9
|
-
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" font-size="11">
|
|
10
|
-
<text x="26" y="15" fill="#010101" fill-opacity=".3">tokens</text><text x="26" y="14">tokens</text>
|
|
11
|
-
<text x="71" y="15" fill="#010101" fill-opacity=".3">120k</text><text x="71" y="14">120k</text>
|
|
12
|
-
</g>
|
|
13
|
-
</g>
|
|
14
|
-
</svg>
|