clawmini 0.0.8 → 0.0.9
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/.changeset/README.md +8 -0
- package/.changeset/config.json +14 -0
- package/.github/workflows/release.yml +49 -0
- package/CHANGELOG.md +36 -0
- package/README.md +5 -4
- package/dist/adapter-discord/index.d.mts.map +1 -1
- package/dist/adapter-discord/index.mjs +465 -282
- package/dist/adapter-discord/index.mjs.map +1 -1
- package/dist/adapter-google-chat/index.mjs +367 -243
- package/dist/adapter-google-chat/index.mjs.map +1 -1
- package/dist/cli/index.mjs +684 -24
- package/dist/cli/index.mjs.map +1 -1
- package/dist/cli/lite.mjs +43 -13
- package/dist/cli/lite.mjs.map +1 -1
- package/dist/cli/{propose-policy.mjs → manage-policies.mjs} +270 -47
- package/dist/cli/manage-policies.mjs.map +1 -0
- package/dist/cli/run-host.d.mts +1 -0
- package/dist/cli/run-host.mjs +3090 -0
- package/dist/cli/run-host.mjs.map +1 -0
- package/dist/config-CPFQIGdG.mjs +57 -0
- package/dist/config-CPFQIGdG.mjs.map +1 -0
- package/dist/config-Dvl-Pov4.mjs +76 -0
- package/dist/config-Dvl-Pov4.mjs.map +1 -0
- package/dist/daemon/index.d.mts.map +1 -1
- package/dist/daemon/index.mjs +970 -332
- package/dist/daemon/index.mjs.map +1 -1
- package/dist/supervisor-actions-CiW56eLi.mjs +843 -0
- package/dist/supervisor-actions-CiW56eLi.mjs.map +1 -0
- package/dist/turn-log-buffer-DRgW53gl.mjs +767 -0
- package/dist/turn-log-buffer-DRgW53gl.mjs.map +1 -0
- package/dist/web/_app/immutable/chunks/{Drm9vgeP.js → 3AZlWB6U.js} +1 -1
- package/dist/web/_app/immutable/chunks/BhRSsUCh.js +2 -0
- package/dist/web/_app/immutable/chunks/BiLeM2i1.js +1 -0
- package/{web/.svelte-kit/output/client/_app/immutable/chunks/CME08kGM.js → dist/web/_app/immutable/chunks/BmBj85Ll.js} +1 -1
- package/dist/web/_app/immutable/chunks/BrERcKAH.js +1 -0
- package/dist/web/_app/immutable/chunks/Bv9252RM.js +1 -0
- package/dist/web/_app/immutable/chunks/CIXNBPKi.js +1 -0
- package/dist/web/_app/immutable/chunks/DISKL3GN.js +2 -0
- package/dist/web/_app/immutable/chunks/{Zeh-C-mx.js → DcpaLzmX.js} +1 -1
- package/dist/web/_app/immutable/chunks/DnQ3vS13.js +1 -0
- package/dist/web/_app/immutable/chunks/KsloHTKS.js +1 -0
- package/{web/.svelte-kit/output/client/_app/immutable/chunks/Ck-be5J2.js → dist/web/_app/immutable/chunks/RsHsUj-8.js} +2 -2
- package/dist/web/_app/immutable/chunks/{vDehDcuJ.js → wpfV79dV.js} +1 -1
- package/dist/web/_app/immutable/entry/app.CIw1Qj0n.js +2 -0
- package/dist/web/_app/immutable/entry/start.Di0-Jhte.js +1 -0
- package/dist/web/_app/immutable/nodes/{0.CUGC2p-K.js → 0.DYyUA1au.js} +1 -1
- package/dist/web/_app/immutable/nodes/1.D-3QEMMZ.js +1 -0
- package/dist/web/_app/immutable/nodes/{2.BnwnD1Ki.js → 2.4olHnH7U.js} +1 -1
- package/{web/.svelte-kit/output/client/_app/immutable/nodes/3.0arZe_Uf.js → dist/web/_app/immutable/nodes/3.4w0bE-m2.js} +3 -3
- package/dist/web/_app/immutable/nodes/4.CZvjhVHt.js +60 -0
- package/dist/web/_app/immutable/nodes/{5.Bq2JzCEj.js → 5.DLbPVJY2.js} +1 -1
- package/dist/web/_app/version.json +1 -1
- package/dist/web/index.html +12 -12
- package/dist/workspace-oWmVh5mi.mjs +1001 -0
- package/dist/workspace-oWmVh5mi.mjs.map +1 -0
- package/docs/23_adapter_slash_autocomplete/development_log.md +19 -0
- package/docs/23_adapter_slash_autocomplete/notes.md +18 -0
- package/docs/23_adapter_slash_autocomplete/prd.md +46 -0
- package/docs/23_adapter_slash_autocomplete/questions.md +6 -0
- package/docs/23_adapter_slash_autocomplete/tickets.md +21 -0
- package/docs/24_subagent_job_policy_fixes/development_log.md +22 -0
- package/docs/24_subagent_job_policy_fixes/notes.md +28 -0
- package/docs/24_subagent_job_policy_fixes/prd.md +59 -0
- package/docs/24_subagent_job_policy_fixes/questions.md +3 -0
- package/docs/24_subagent_job_policy_fixes/tickets.md +49 -0
- package/docs/25_e2e_test_improvements/development_log.md +30 -0
- package/docs/25_e2e_test_improvements/notes.md +29 -0
- package/docs/25_e2e_test_improvements/prd.md +43 -0
- package/docs/25_e2e_test_improvements/questions.md +12 -0
- package/docs/25_e2e_test_improvements/tickets-2.md +22 -0
- package/docs/25_e2e_test_improvements/tickets.md +22 -0
- package/docs/25_policy_cwd/development_log.md +30 -0
- package/docs/25_policy_cwd/notes.md +28 -0
- package/docs/25_policy_cwd/prd.md +77 -0
- package/docs/25_policy_cwd/questions.md +6 -0
- package/docs/25_policy_cwd/tickets.md +77 -0
- package/docs/CLI_REFERENCE.md +3 -1
- package/docs/PHILOSOPHY.md +35 -0
- package/docs/adapter-visibility/SPEC.md +461 -0
- package/docs/adapter-visibility/SPEC_v2.md +202 -0
- package/docs/auto-update/SPEC.md +344 -0
- package/docs/backups/SPEC.md +296 -0
- package/docs/backups/clawmini.gitignore +69 -0
- package/docs/guides/assets/clawmini-avatar.png +0 -0
- package/docs/guides/backups.md +332 -0
- package/docs/guides/discord_adapter_setup.md +1 -1
- package/docs/guides/google_chat_adapter_setup.md +81 -0
- package/docs/unified-startup/SPEC.md +203 -0
- package/e2e/_helpers/test-environment.test.ts +49 -0
- package/e2e/_helpers/test-environment.ts +548 -0
- package/e2e/adapters/_google-chat-fixtures.ts +340 -0
- package/{src/cli/e2e → e2e/adapters}/adapter-discord.test.ts +22 -23
- package/e2e/adapters/adapter-google-chat-downtime.test.ts +157 -0
- package/e2e/adapters/adapter-google-chat-inbound.test.ts +697 -0
- package/e2e/adapters/adapter-google-chat-outbound.test.ts +297 -0
- package/e2e/adapters/adapter-google-chat-roundtrip.test.ts +56 -0
- package/e2e/adapters/adapter-google-chat-threads.test.ts +1078 -0
- package/e2e/agents/custom-api-env.test.ts +80 -0
- package/e2e/agents/export-lite-func.test.ts +104 -0
- package/e2e/agents/fallbacks.test.ts +124 -0
- package/e2e/agents/interrupt.test.ts +50 -0
- package/e2e/agents/no-reply-necessary.test.ts +57 -0
- package/e2e/agents/session-timeout-subagents.test.ts +76 -0
- package/e2e/agents/subagent-authorization.test.ts +246 -0
- package/e2e/agents/subagent-env.test.ts +49 -0
- package/e2e/agents/subagent-lifecycle.test.ts +782 -0
- package/e2e/agents/subagents-depth.test.ts +47 -0
- package/e2e/cli/agents.test.ts +176 -0
- package/e2e/cli/auto-update.test.ts +741 -0
- package/e2e/cli/basic.test.ts +44 -0
- package/{src/cli/e2e → e2e/cli}/export-lite.test.ts +16 -12
- package/e2e/cli/init-gitignore.test.ts +86 -0
- package/e2e/cli/init.test.ts +76 -0
- package/e2e/cli/messages.test.ts +363 -0
- package/e2e/cli/serve.test.ts +76 -0
- package/{src/cli/e2e → e2e/cli}/skills.test.ts +11 -10
- package/{src/cli/e2e → e2e/daemon}/daemon.test.ts +57 -195
- package/e2e/jobs/agent-jobs.test.ts +216 -0
- package/e2e/jobs/cron.test.ts +64 -0
- package/e2e/jobs/restart.test.ts +108 -0
- package/e2e/policies/approval-session.test.ts +69 -0
- package/e2e/policies/auto-create-policies-file.test.ts +35 -0
- package/e2e/policies/builtin-manage-policies.test.ts +184 -0
- package/e2e/policies/builtin-run-host.test.ts +180 -0
- package/e2e/policies/environment-policies.test.ts +177 -0
- package/e2e/policies/manage-policies.test.ts +566 -0
- package/e2e/policies/output-size.test.ts +98 -0
- package/e2e/policies/policies-context-cwd.test.ts +160 -0
- package/e2e/policies/relative-script-path.test.ts +60 -0
- package/e2e/policies/requests-show.test.ts +135 -0
- package/e2e/policies/requests.test.ts +208 -0
- package/e2e/policies/slash-policies.test.ts +308 -0
- package/e2e/policies/startup-cleanup.test.ts +48 -0
- package/e2e/routers/session-timeout.test.ts +106 -0
- package/e2e/routers/slash-model.test.ts +152 -0
- package/e2e/routers/slash-new.test.ts +50 -0
- package/e2e/routers/slash-restart-adapter.test.ts +96 -0
- package/e2e/routers/slash-restart.test.ts +114 -0
- package/e2e/routers/slash-shutdown.test.ts +55 -0
- package/e2e/routers/slash-stop.test.ts +232 -0
- package/e2e/routers/slash-upgrade.test.ts +88 -0
- package/{src/cli/e2e → e2e/sandbox}/environments.test.ts +14 -13
- package/eslint.config.js +6 -0
- package/napkin.md +1 -1
- package/package.json +8 -3
- package/src/adapter-discord/commands.test.ts +42 -0
- package/src/adapter-discord/commands.ts +33 -0
- package/src/adapter-discord/config.ts +12 -0
- package/src/adapter-discord/forwarder.test.ts +499 -21
- package/src/adapter-discord/forwarder.ts +343 -124
- package/src/adapter-discord/inbound-cache.test.ts +47 -0
- package/src/adapter-discord/inbound-cache.ts +37 -0
- package/src/adapter-discord/index.test.ts +67 -2
- package/src/adapter-discord/index.ts +84 -216
- package/src/adapter-discord/interactions.test.ts +54 -3
- package/src/adapter-discord/interactions.ts +97 -53
- package/src/adapter-discord/processMessage.ts +239 -0
- package/src/adapter-discord/state.ts +1 -0
- package/src/adapter-google-chat/auth.test.ts +9 -5
- package/src/adapter-google-chat/auth.ts +29 -23
- package/src/adapter-google-chat/cards.ts +7 -2
- package/src/adapter-google-chat/client.test.ts +37 -2
- package/src/adapter-google-chat/client.ts +138 -38
- package/src/adapter-google-chat/config.ts +19 -0
- package/src/adapter-google-chat/forwarder.test.ts +81 -56
- package/src/adapter-google-chat/forwarder.ts +394 -185
- package/src/adapter-google-chat/inbound-cache.test.ts +61 -0
- package/src/adapter-google-chat/inbound-cache.ts +36 -0
- package/src/adapter-google-chat/state.test.ts +1 -0
- package/src/adapter-google-chat/state.ts +9 -1
- package/src/adapter-google-chat/subscriptions.ts +8 -6
- package/src/cli/builtin-policies.ts +44 -0
- package/src/cli/commands/agents.ts +59 -5
- package/src/cli/commands/down.ts +54 -2
- package/src/cli/commands/environments.ts +8 -2
- package/src/cli/commands/init.ts +31 -0
- package/src/cli/commands/logs.ts +116 -0
- package/src/cli/commands/policies.ts +6 -4
- package/src/cli/commands/serve.test.ts +67 -0
- package/src/cli/commands/serve.ts +284 -0
- package/src/cli/commands/up.ts +122 -2
- package/src/cli/commands/web-api/agents.ts +3 -2
- package/src/cli/index.ts +4 -0
- package/src/cli/install-detection.test.ts +72 -0
- package/src/cli/install-detection.ts +48 -0
- package/src/cli/lite.ts +54 -22
- package/src/cli/manage-policies-utils.ts +104 -0
- package/src/cli/manage-policies.ts +291 -0
- package/src/cli/run-host.ts +45 -0
- package/src/cli/supervisor-actions.ts +267 -0
- package/src/cli/supervisor-control.test.ts +129 -0
- package/src/cli/supervisor-control.ts +155 -0
- package/src/cli/supervisor-pid.ts +68 -0
- package/src/cli/supervisor.ts +277 -0
- package/src/daemon/agent/agent-context.ts +11 -11
- package/src/daemon/agent/agent-session.ts +8 -1
- package/src/daemon/agent/chat-logger.test.ts +78 -9
- package/src/daemon/agent/chat-logger.ts +25 -5
- package/src/daemon/agent/turn-registry.test.ts +89 -0
- package/src/daemon/agent/turn-registry.ts +94 -0
- package/src/daemon/agent/types.ts +2 -0
- package/src/daemon/api/agent-policy-endpoints.ts +263 -0
- package/src/daemon/api/agent-router.ts +47 -126
- package/src/daemon/api/index.test.ts +1 -0
- package/src/daemon/api/policy-request.test.ts +7 -5
- package/src/daemon/api/router-utils.ts +6 -5
- package/src/daemon/api/subagent-router.ts +110 -74
- package/src/daemon/api/subagent-utils.test.ts +60 -0
- package/src/daemon/api/subagent-utils.ts +113 -87
- package/src/daemon/api/user-router.ts +34 -8
- package/src/daemon/auth.ts +1 -0
- package/src/daemon/cron.test.ts +62 -4
- package/src/daemon/cron.ts +42 -16
- package/src/daemon/events.ts +65 -0
- package/src/daemon/index.ts +24 -1
- package/src/daemon/message-interruption.test.ts +1 -0
- package/src/daemon/message-jobs.test.ts +1 -0
- package/src/daemon/message.ts +78 -14
- package/src/daemon/observation.test.ts +26 -18
- package/src/daemon/pending-replies.test.ts +112 -0
- package/src/daemon/pending-replies.ts +162 -0
- package/src/daemon/policy-request-service.ts +3 -1
- package/src/daemon/policy-utils.test.ts +66 -1
- package/src/daemon/policy-utils.ts +126 -1
- package/src/daemon/request-store.ts +31 -0
- package/src/daemon/routers/session-timeout.ts +4 -0
- package/src/daemon/routers/slash-model.test.ts +344 -0
- package/src/daemon/routers/slash-model.ts +207 -0
- package/src/daemon/routers/slash-policies.test.ts +38 -32
- package/src/daemon/routers/slash-policies.ts +84 -33
- package/src/daemon/routers/slash-restart.test.ts +69 -0
- package/src/daemon/routers/slash-restart.ts +36 -0
- package/src/daemon/routers/slash-shutdown.test.ts +50 -0
- package/src/daemon/routers/slash-shutdown.ts +28 -0
- package/src/daemon/routers/slash-upgrade.test.ts +116 -0
- package/src/daemon/routers/slash-upgrade.ts +76 -0
- package/src/daemon/routers/types.ts +7 -0
- package/src/daemon/routers.ts +16 -0
- package/src/shared/adapters/blockquote.test.ts +28 -0
- package/src/shared/adapters/blockquote.ts +20 -0
- package/src/shared/adapters/filtering.test.ts +224 -10
- package/src/shared/adapters/filtering.ts +95 -7
- package/src/shared/adapters/inbound-cache.test.ts +48 -0
- package/src/shared/adapters/inbound-cache.ts +54 -0
- package/src/shared/adapters/turn-log-buffer.ts +266 -0
- package/src/shared/adapters/turn-log.test.ts +389 -0
- package/src/shared/adapters/turn-log.ts +357 -0
- package/src/shared/agent-utils.ts +12 -5
- package/src/shared/chats.test.ts +4 -0
- package/src/shared/chats.ts +9 -0
- package/src/shared/config.ts +16 -1
- package/src/shared/lite.ts +76 -2
- package/src/shared/policies.ts +26 -0
- package/src/shared/template-manifest.ts +267 -0
- package/src/shared/utils/shell.ts +61 -0
- package/src/shared/version.ts +34 -0
- package/src/shared/workspace.test.ts +217 -0
- package/src/shared/workspace.ts +626 -48
- package/templates/environments/cladding/allowlist-domain.mjs +125 -0
- package/templates/environments/cladding/env.json +21 -1
- package/templates/environments/cladding/run-with-network.mjs +54 -0
- package/templates/environments/macos-proxy/allowlist-domain.mjs +95 -0
- package/templates/environments/macos-proxy/env.json +8 -1
- package/templates/environments/macos-proxy/proxy.mjs +0 -1
- package/templates/gemini/template.json +5 -0
- package/templates/gemini-claw/template.json +13 -0
- package/templates/skills/clawmini-requests/SKILL.md +69 -10
- package/templates/skills/run-host/SKILL.md +51 -0
- package/templates/skills/skill-creator/SKILL.md +4 -3
- package/templates/skills/skill-creator/scripts/validate.sh +52 -0
- package/tsdown.config.ts +10 -1
- package/vitest.config.ts +2 -2
- package/web/.svelte-kit/ambient.d.ts +292 -118
- package/web/.svelte-kit/generated/server/internal.js +1 -1
- package/web/.svelte-kit/output/client/.vite/manifest.json +126 -136
- package/web/.svelte-kit/output/client/_app/immutable/chunks/{Drm9vgeP.js → 3AZlWB6U.js} +1 -1
- package/web/.svelte-kit/output/client/_app/immutable/chunks/BhRSsUCh.js +2 -0
- package/web/.svelte-kit/output/client/_app/immutable/chunks/BiLeM2i1.js +1 -0
- package/{dist/web/_app/immutable/chunks/CME08kGM.js → web/.svelte-kit/output/client/_app/immutable/chunks/BmBj85Ll.js} +1 -1
- package/web/.svelte-kit/output/client/_app/immutable/chunks/BrERcKAH.js +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/chunks/Bv9252RM.js +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/chunks/CIXNBPKi.js +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/chunks/DISKL3GN.js +2 -0
- package/web/.svelte-kit/output/client/_app/immutable/chunks/{Zeh-C-mx.js → DcpaLzmX.js} +1 -1
- package/web/.svelte-kit/output/client/_app/immutable/chunks/DnQ3vS13.js +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/chunks/KsloHTKS.js +1 -0
- package/{dist/web/_app/immutable/chunks/Ck-be5J2.js → web/.svelte-kit/output/client/_app/immutable/chunks/RsHsUj-8.js} +2 -2
- package/web/.svelte-kit/output/client/_app/immutable/chunks/{vDehDcuJ.js → wpfV79dV.js} +1 -1
- package/web/.svelte-kit/output/client/_app/immutable/entry/app.CIw1Qj0n.js +2 -0
- package/web/.svelte-kit/output/client/_app/immutable/entry/start.Di0-Jhte.js +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/nodes/{0.CUGC2p-K.js → 0.DYyUA1au.js} +1 -1
- package/web/.svelte-kit/output/client/_app/immutable/nodes/1.D-3QEMMZ.js +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/nodes/{2.BnwnD1Ki.js → 2.4olHnH7U.js} +1 -1
- package/{dist/web/_app/immutable/nodes/3.0arZe_Uf.js → web/.svelte-kit/output/client/_app/immutable/nodes/3.4w0bE-m2.js} +3 -3
- package/web/.svelte-kit/output/client/_app/immutable/nodes/4.CZvjhVHt.js +60 -0
- package/web/.svelte-kit/output/client/_app/immutable/nodes/{5.Bq2JzCEj.js → 5.DLbPVJY2.js} +1 -1
- package/web/.svelte-kit/output/client/_app/version.json +1 -1
- package/web/.svelte-kit/output/server/.vite/manifest.json +12 -10
- package/web/.svelte-kit/output/server/chunks/Icon.js +1 -1
- package/web/.svelte-kit/output/server/chunks/client.js +1 -1
- package/web/.svelte-kit/output/server/chunks/exports.js +1 -1
- package/web/.svelte-kit/output/server/chunks/index-server.js +2 -1
- package/web/.svelte-kit/output/server/chunks/internal.js +1 -1
- package/web/.svelte-kit/output/server/chunks/render-context.js +77 -0
- package/web/.svelte-kit/output/server/chunks/root.js +739 -788
- package/web/.svelte-kit/output/server/chunks/shared.js +234 -21
- package/web/.svelte-kit/output/server/index.js +126 -90
- package/web/.svelte-kit/output/server/manifest-full.js +1 -1
- package/web/.svelte-kit/output/server/manifest.js +1 -1
- package/web/.svelte-kit/output/server/nodes/0.js +1 -1
- package/web/.svelte-kit/output/server/nodes/1.js +1 -1
- package/web/.svelte-kit/output/server/nodes/2.js +1 -1
- package/web/.svelte-kit/output/server/nodes/3.js +1 -1
- package/web/.svelte-kit/output/server/nodes/4.js +1 -1
- package/web/.svelte-kit/output/server/nodes/5.js +1 -1
- package/web/.svelte-kit/output/server/remote-entry.js +245 -81
- package/web/.svelte-kit/tsconfig.json +4 -1
- package/dist/cli/propose-policy.mjs.map +0 -1
- package/dist/lite-CBxOT1y5.mjs +0 -241
- package/dist/lite-CBxOT1y5.mjs.map +0 -1
- package/dist/routing-D8rTxtaV.mjs +0 -245
- package/dist/routing-D8rTxtaV.mjs.map +0 -1
- package/dist/web/_app/immutable/chunks/B6YN0Nuq.js +0 -1
- package/dist/web/_app/immutable/chunks/BmRlVmv6.js +0 -1
- package/dist/web/_app/immutable/chunks/CK9JZLaG.js +0 -2
- package/dist/web/_app/immutable/chunks/Ck3rYNON.js +0 -1
- package/dist/web/_app/immutable/chunks/D5iV40bG.js +0 -1
- package/dist/web/_app/immutable/chunks/DMtIqaiV.js +0 -2
- package/dist/web/_app/immutable/chunks/DhD271EB.js +0 -1
- package/dist/web/_app/immutable/chunks/DpuLqk8d.js +0 -1
- package/dist/web/_app/immutable/chunks/DsIToJCP.js +0 -1
- package/dist/web/_app/immutable/entry/app.BCSV3nrG.js +0 -2
- package/dist/web/_app/immutable/entry/start.D4eLEZUM.js +0 -1
- package/dist/web/_app/immutable/nodes/1.CGC_42IQ.js +0 -1
- package/dist/web/_app/immutable/nodes/4.ClM1bXLE.js +0 -60
- package/dist/workspace-BJmJBfKi.mjs +0 -456
- package/dist/workspace-BJmJBfKi.mjs.map +0 -1
- package/src/cli/e2e/agents.test.ts +0 -140
- package/src/cli/e2e/basic.test.ts +0 -43
- package/src/cli/e2e/cron.test.ts +0 -132
- package/src/cli/e2e/export-lite-func.test.ts +0 -206
- package/src/cli/e2e/fallbacks.test.ts +0 -175
- package/src/cli/e2e/init.test.ts +0 -77
- package/src/cli/e2e/messages.test.ts +0 -332
- package/src/cli/e2e/propose-policy.test.ts +0 -203
- package/src/cli/e2e/requests.test.ts +0 -180
- package/src/cli/e2e/session-timeout.test.ts +0 -192
- package/src/cli/e2e/slash-new.test.ts +0 -93
- package/src/cli/e2e/subagents.test.ts +0 -106
- package/src/cli/e2e/utils.ts +0 -66
- package/src/cli/propose-policy.ts +0 -91
- package/web/.svelte-kit/output/client/_app/immutable/chunks/B6YN0Nuq.js +0 -1
- package/web/.svelte-kit/output/client/_app/immutable/chunks/BmRlVmv6.js +0 -1
- package/web/.svelte-kit/output/client/_app/immutable/chunks/CK9JZLaG.js +0 -2
- package/web/.svelte-kit/output/client/_app/immutable/chunks/Ck3rYNON.js +0 -1
- package/web/.svelte-kit/output/client/_app/immutable/chunks/D5iV40bG.js +0 -1
- package/web/.svelte-kit/output/client/_app/immutable/chunks/DMtIqaiV.js +0 -2
- package/web/.svelte-kit/output/client/_app/immutable/chunks/DhD271EB.js +0 -1
- package/web/.svelte-kit/output/client/_app/immutable/chunks/DpuLqk8d.js +0 -1
- package/web/.svelte-kit/output/client/_app/immutable/chunks/DsIToJCP.js +0 -1
- package/web/.svelte-kit/output/client/_app/immutable/entry/app.BCSV3nrG.js +0 -2
- package/web/.svelte-kit/output/client/_app/immutable/entry/start.D4eLEZUM.js +0 -1
- package/web/.svelte-kit/output/client/_app/immutable/nodes/1.CGC_42IQ.js +0 -1
- package/web/.svelte-kit/output/client/_app/immutable/nodes/4.ClM1bXLE.js +0 -60
- package/web/.svelte-kit/output/server/chunks/false.js +0 -4
- /package/dist/cli/{propose-policy.d.mts → manage-policies.d.mts} +0 -0
- /package/{src/cli/e2e → e2e/_helpers}/global-setup.ts +0 -0
|
@@ -11,7 +11,7 @@ This guide describes how to set up and configure the Discord adapter for Clawmin
|
|
|
11
11
|
|
|
12
12
|
1. Go to the [Discord Developer Portal](https://discord.com/developers/applications).
|
|
13
13
|
2. Click **New Application**.
|
|
14
|
-
3. Give your application a name (e.g., "Clawmini-Bot") and click **Create**.
|
|
14
|
+
3. Give your application a name (e.g., "Clawmini-Bot") and click **Create**. (Optional: Set the App Icon using [this default avatar image](./assets/clawmini-avatar.png)).
|
|
15
15
|
4. In the left sidebar, click **Bot**.
|
|
16
16
|
5. Under **Bot Token**, click **Reset Token** (or **Copy Token**) to retrieve your bot's token. **Save this token securely; you will need it later.**
|
|
17
17
|
6. Scroll down to the **Privileged Gateway Intents** section.
|
|
@@ -34,9 +34,19 @@ This step is optional, but recommended.
|
|
|
34
34
|
4. Navigate to the Google Chat API configuration page.
|
|
35
35
|
5. Uncheck **Build this Chat app as a Workspace add-on**.
|
|
36
36
|
6. Provide App Information (Name, Avatar URL, Description).
|
|
37
|
+
* **Avatar URL:** You can use [this default avatar image](./assets/clawmini-avatar.png).
|
|
37
38
|
7. Under **Interactive features**, optionally check **Join spaces and group conversations**.
|
|
38
39
|
8. Under **Connection settings**, select **Cloud Pub/Sub**.
|
|
39
40
|
9. Set the Pub/Sub topic to the topic you created earlier (e.g., `projects/YOUR_PROJECT_ID/topics/chat`).
|
|
41
|
+
10. Under **Slash commands**, click **Add a slash command** to configure the following supported commands (Command IDs can be any unique number, but these are recommended):
|
|
42
|
+
- **Name:** `/new`, **Command ID:** `1`, **Description:** Clear previous context and start a new conversation thread.
|
|
43
|
+
- **Name:** `/stop`, **Command ID:** `2`, **Description:** Stop all running commands and drop any queued messages.
|
|
44
|
+
- **Name:** `/approve`, **Command ID:** `3`, **Description:** Approve a specific pending agent request. (Usage: `/approve [policy_id]`)
|
|
45
|
+
- **Name:** `/reject`, **Command ID:** `4`, **Description:** Reject a specific pending agent request. (Usage: `/reject [policy_id] [rationale]`)
|
|
46
|
+
- **Name:** `/pending`, **Command ID:** `5`, **Description:** View any pending permission requests from your agent.
|
|
47
|
+
- **Name:** `/show`, **Command ID:** `6`, **Description:** Show the debug view.
|
|
48
|
+
- **Name:** `/hide`, **Command ID:** `7`, **Description:** Hide the debug view.
|
|
49
|
+
- **Name:** `/debug`, **Command ID:** `8`, **Description:** Toggle the debug view.
|
|
40
50
|
|
|
41
51
|
## Step 4: Setup Application Default Credentials (ADC)
|
|
42
52
|
|
|
@@ -143,3 +153,74 @@ By default, the adapter connects to a single chat (the one specified as `chatId`
|
|
|
143
153
|
4. Alternatively, use `/chat [chat-id]` in that space to map it to an existing Clawmini chat.
|
|
144
154
|
|
|
145
155
|
_Note: Each Space/DM can only be mapped to one Clawmini chat, and each Clawmini chat can only be mapped to one channel/space across all adapters._
|
|
156
|
+
|
|
157
|
+
## Advanced Configuration
|
|
158
|
+
|
|
159
|
+
Once the adapter is running, you can tune how it surfaces agent activity.
|
|
160
|
+
None of this is required for basic use.
|
|
161
|
+
|
|
162
|
+
### Visibility Settings (`config.json`)
|
|
163
|
+
|
|
164
|
+
The adapter can publish agent activity — tool calls, subagent updates, policy
|
|
165
|
+
decisions — into a per-turn GChat **thread** anchored on the triggering user
|
|
166
|
+
message, edited in place as events arrive. The final agent reply still lands
|
|
167
|
+
top-level. All settings are optional; defaults are shown.
|
|
168
|
+
|
|
169
|
+
```json
|
|
170
|
+
{
|
|
171
|
+
"visibility": {
|
|
172
|
+
"threads": true,
|
|
173
|
+
"threadLog": {
|
|
174
|
+
"maxToolPreview": 400,
|
|
175
|
+
"maxLogMessageChars": 3500,
|
|
176
|
+
"editDebounceMs": 1000
|
|
177
|
+
},
|
|
178
|
+
"jobs": "silent"
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
- `threads` — global kill switch. Set to `false` to drop thread-log
|
|
184
|
+
activity (tool calls, subagent updates, policy decisions) entirely. The
|
|
185
|
+
final agent reply still posts top-level; debug-style firehose output is
|
|
186
|
+
only available via `filters` (e.g. `/show`).
|
|
187
|
+
- `threadLog.maxToolPreview` — per-entry character cap on tool arguments
|
|
188
|
+
before `…[truncated]`.
|
|
189
|
+
- `threadLog.maxLogMessageChars` — size budget for a single log message;
|
|
190
|
+
exceeding it rolls over to a fresh message in the same thread.
|
|
191
|
+
- `threadLog.editDebounceMs` — coalescing window for burst activity. Higher
|
|
192
|
+
values reduce edit calls; lower values feel more live.
|
|
193
|
+
- `jobs` — how cron-triggered (proactive) turns surface:
|
|
194
|
+
- `'silent'` (default) — the cron prompt is never posted. If the agent
|
|
195
|
+
replies, that reply becomes the thread anchor; if it stays silent,
|
|
196
|
+
nothing posts.
|
|
197
|
+
- `'header'` — a terse `🕒 <jobId>` heartbeat posts top-level and anchors
|
|
198
|
+
the activity log, making scheduled work visible even when the agent
|
|
199
|
+
doesn't reply.
|
|
200
|
+
|
|
201
|
+
### Per-Space Overrides (`state.json`)
|
|
202
|
+
|
|
203
|
+
The adapter's runtime state lives at
|
|
204
|
+
`.clawmini/adapters/google-chat/state.json`. The `channelChatMap` entry for
|
|
205
|
+
each space supports per-space overrides that take precedence over
|
|
206
|
+
`config.json`:
|
|
207
|
+
|
|
208
|
+
```json
|
|
209
|
+
{
|
|
210
|
+
"channelChatMap": {
|
|
211
|
+
"spaces/AAA": {
|
|
212
|
+
"chatId": "my-chat",
|
|
213
|
+
"requireMention": true,
|
|
214
|
+
"threadsDisabled": true
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
- `requireMention` — per-space mention gate (overrides the global `requireMention`).
|
|
221
|
+
- `threadsDisabled` — when `true`, thread-log activity for this space is
|
|
222
|
+
dropped (same semantics as the global `visibility.threads: false`, scoped
|
|
223
|
+
to one space). The final agent reply still posts top-level.
|
|
224
|
+
|
|
225
|
+
Most entries under `channelChatMap` are written automatically by the adapter
|
|
226
|
+
as users run `/agent` or `/chat` (see [Routing and Creating Chats](#routing-and-creating-chats)); edit the file only to set these overrides.
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
# Unified startup for clawmini
|
|
2
|
+
|
|
3
|
+
**Status:** brainstorm. Not a decided plan — exploring the design space so we can pick a direction.
|
|
4
|
+
|
|
5
|
+
## Problem
|
|
6
|
+
|
|
7
|
+
Starting clawmini today requires three-to-four separate commands:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
clawmini down && clawmini up # restart daemon
|
|
11
|
+
clawmini-adapter-discord # adapter (foreground)
|
|
12
|
+
clawmini-adapter-google-chat # another adapter (foreground)
|
|
13
|
+
clawmini web # web UI (foreground)
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Each runs in its own terminal. If you're not tailing terminals, logs end up in `.clawmini/daemon.log` (for the backgrounded daemon) and nowhere for adapters (they go to whatever terminal you launched them in). Finding what went wrong means hopping between terminals or SSH sessions.
|
|
17
|
+
|
|
18
|
+
Three things feel wrong:
|
|
19
|
+
|
|
20
|
+
1. **Too many commands** to start a working setup.
|
|
21
|
+
2. **Logs are hard to watch** — daemon logs go to a file you have to know about; adapter logs are scattered across terminals.
|
|
22
|
+
3. **No clean upgrade path.** You can't currently tell a running agent "/update yourself" — there's no orchestrator that knows how to stop-upgrade-restart the full constellation.
|
|
23
|
+
|
|
24
|
+
The user's goals (in priority order):
|
|
25
|
+
1. One command to start everything, with logs visible by default.
|
|
26
|
+
2. Still be able to run detached / in the background when wanted.
|
|
27
|
+
3. Future: expose an "update" operation to the agent that safely rolls over the whole stack after an `npm install -g clawmini@latest`.
|
|
28
|
+
|
|
29
|
+
## Design space
|
|
30
|
+
|
|
31
|
+
The interesting axes:
|
|
32
|
+
|
|
33
|
+
- **Process model:** single process (everything in one Node) vs. supervised children (one parent spawns daemon + adapters + web) vs. status-quo (each its own top-level process).
|
|
34
|
+
- **Log model:** stdout in foreground vs. log files + `clawmini logs -f` command vs. both.
|
|
35
|
+
- **Config for "what to start":** CLI flags (`clawmini run --discord --web`) vs. settings-driven (enabled services listed in `.clawmini/settings.json`) vs. auto-detect (adapter configured → start it).
|
|
36
|
+
- **Backgrounding:** built-in `--detach` flag vs. rely on `nohup` / `screen` / system service manager vs. write a launchd/systemd template.
|
|
37
|
+
|
|
38
|
+
These compose. Below I sketch four directions and note what each gets right / wrong.
|
|
39
|
+
|
|
40
|
+
## Option A — `clawmini serve` (supervisor command)
|
|
41
|
+
|
|
42
|
+
A new top-level command that becomes the one-and-only launcher:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
clawmini serve # foreground, all enabled services, interleaved logs
|
|
46
|
+
clawmini serve --detach # daemonize, logs to .clawmini/logs/*.log
|
|
47
|
+
clawmini serve --only daemon,web # subset
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
`serve` spawns a parent process that:
|
|
51
|
+
- Runs the daemon in-process (reuse `initDaemon()` directly — no subprocess needed).
|
|
52
|
+
- Spawns `adapter-discord` / `adapter-google-chat` / `web` as child processes if configured/enabled.
|
|
53
|
+
- Multiplexes their stdio into prefixed output lines (`[daemon] listening on ...`, `[discord] ready`, `[web] http://localhost:8080`).
|
|
54
|
+
- On Ctrl-C, sends SIGTERM to children, calls daemon `shutdown()`, waits for clean exit.
|
|
55
|
+
- On child crash, restarts with backoff (optional — or just log + exit).
|
|
56
|
+
|
|
57
|
+
**How do we know which services to start?** Auto-detect based on what's configured in `.clawmini/`:
|
|
58
|
+
- Daemon: always.
|
|
59
|
+
- Web: always (or opt-out flag — it's basically free).
|
|
60
|
+
- `adapter-discord`: if `.clawmini/adapters/discord/config.json` exists.
|
|
61
|
+
- `adapter-google-chat`: if `.clawmini/adapters/google-chat/config.json` exists.
|
|
62
|
+
|
|
63
|
+
Optional override via `--only`/`--exclude` flags.
|
|
64
|
+
|
|
65
|
+
**Detach mode (`--detach`):** fork a supervisor into the background, open log files at `.clawmini/logs/{daemon,discord,google-chat,web}.log`, exit the foreground shell. `clawmini logs [-f] [--service <n>]` tails them.
|
|
66
|
+
|
|
67
|
+
**Pros:**
|
|
68
|
+
- One command. Matches mental model of `docker compose up`, `foreman start`, `overmind start`.
|
|
69
|
+
- Logs are multiplexed and visible by default (addresses goal #1).
|
|
70
|
+
- Backgrounding preserved via `--detach` (addresses goal #2).
|
|
71
|
+
- Sets up the infrastructure needed for `/update`: there's now a single parent to SIGTERM, wait for, re-exec after upgrade (addresses goal #3).
|
|
72
|
+
- Adapters don't need to change their main logic — they just get spawned by a different process.
|
|
73
|
+
|
|
74
|
+
**Cons:**
|
|
75
|
+
- `clawmini up` / `clawmini down` semantics get murky. Does `clawmini up` still work (daemon-only)? Do we deprecate it? Keep it as an alias?
|
|
76
|
+
- Child-process log multiplexing is annoying to get right (line buffering, ANSI colors, interleaving).
|
|
77
|
+
- Adapters become coupled to the supervisor's lifecycle — less flexible for people who want to run the discord adapter on a different host. (Probably fine: if you need that, you can still `npx clawmini-adapter-discord` manually.)
|
|
78
|
+
|
|
79
|
+
## Option B — Teach the daemon to supervise adapters
|
|
80
|
+
|
|
81
|
+
Same end result, different split: the daemon itself gains a service manager. On `clawmini up`, the daemon reads `.clawmini/settings.json`, sees which adapters are enabled, spawns them as children. On `clawmini down`, it kills them.
|
|
82
|
+
|
|
83
|
+
```json
|
|
84
|
+
// .clawmini/settings.json
|
|
85
|
+
{
|
|
86
|
+
"services": {
|
|
87
|
+
"web": { "enabled": true, "port": 8080 },
|
|
88
|
+
"adapter-discord": { "enabled": true },
|
|
89
|
+
"adapter-google-chat": { "enabled": false }
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Pros:**
|
|
95
|
+
- No new top-level command; `clawmini up` / `clawmini down` keep meaning.
|
|
96
|
+
- The daemon is already the stateful orchestrator; extending it to own adapter lifecycle is consistent.
|
|
97
|
+
- Settings-driven: `clawmini services enable discord` toggles a flag, next `up` picks it up. Feels like `clawmini environments enable`.
|
|
98
|
+
|
|
99
|
+
**Cons:**
|
|
100
|
+
- The daemon runs detached already — logs for children would still go to files, not foreground. Doesn't directly solve goal #1 unless we also add a `clawmini logs -f` tail command *and* tell users to use it.
|
|
101
|
+
- More responsibility in an already-complex process.
|
|
102
|
+
- The daemon currently runs as a detached background process; if an adapter crashes the user has no visibility unless they're already tailing logs.
|
|
103
|
+
|
|
104
|
+
**Variant B':** daemon supervises adapters *and* the `up` command runs in the foreground by default (only detaches if `--detach`). This converges with Option A but keeps the `up`/`down` command names.
|
|
105
|
+
|
|
106
|
+
## Option C — Minimum-change: `clawmini logs` + better docs
|
|
107
|
+
|
|
108
|
+
Leave the process model alone. Add:
|
|
109
|
+
- `clawmini logs [-f] [--service <daemon|discord|google-chat|web>]` that tails `.clawmini/logs/*.log`.
|
|
110
|
+
- Make adapters log to `.clawmini/logs/adapter-<name>.log` when started (respecting existing stdout for interactive use).
|
|
111
|
+
- A one-liner helper script or Makefile-equivalent in the README: `clawmini start-all` shell function that backgrounds the four processes and tails their logs.
|
|
112
|
+
|
|
113
|
+
**Pros:**
|
|
114
|
+
- Cheap. Ships in a day.
|
|
115
|
+
- Doesn't close any doors.
|
|
116
|
+
|
|
117
|
+
**Cons:**
|
|
118
|
+
- Doesn't really solve the "too many commands" feeling — users still orchestrate four things.
|
|
119
|
+
- Makes goal #3 (`/update`) harder: no single parent to signal, no single source of truth for "what's running right now."
|
|
120
|
+
|
|
121
|
+
## Option D — Single-process everything
|
|
122
|
+
|
|
123
|
+
Bundle daemon + adapters + web into one Node process. `clawmini serve` imports each adapter module and starts its lifecycle inline. No subprocesses.
|
|
124
|
+
|
|
125
|
+
**Pros:**
|
|
126
|
+
- Simplest runtime model. One process, one log stream.
|
|
127
|
+
- Fastest IPC (they're all in-process — but they already talk over a Unix socket, so this doesn't matter much in practice).
|
|
128
|
+
|
|
129
|
+
**Cons:**
|
|
130
|
+
- Ties adapter crashes to daemon crashes. A Discord.js bug that throws on an unhandled promise kills the daemon.
|
|
131
|
+
- Harder to reason about memory limits / CPU.
|
|
132
|
+
- Breaks the clean separation where adapters can run on different machines (over TCP) if we ever want that.
|
|
133
|
+
- Adapters currently call the daemon over a Unix socket via a tRPC client — merging them means wiring them up differently in "local" mode vs. "remote" mode, which is more code, not less.
|
|
134
|
+
|
|
135
|
+
I don't think this is the right call — but worth naming to frame the others against.
|
|
136
|
+
|
|
137
|
+
## Directional preference (for discussion)
|
|
138
|
+
|
|
139
|
+
**Option A (`clawmini serve` as supervisor of child processes)** is where I'd lean, for three reasons:
|
|
140
|
+
|
|
141
|
+
1. It's the only option that unambiguously solves goal #1 (visible logs) without relying on a secondary `logs` command.
|
|
142
|
+
2. It gives us a clean home for the `/update` operation (goal #3): the supervisor is the thing that knows how to stop, upgrade, and restart the whole constellation. No need to coordinate across multiple independent processes.
|
|
143
|
+
3. It maps to patterns users already know (`docker compose up`, `overmind`, `foreman`), so there's no new mental model to learn.
|
|
144
|
+
|
|
145
|
+
`clawmini up` / `clawmini down` stay as daemon-only commands for people who already have scripts using them — no deprecation needed short-term.
|
|
146
|
+
|
|
147
|
+
The things I'd still want to pin down (see Open questions) are around how `serve` auto-detects what to run, and exactly what the `/update` protocol looks like.
|
|
148
|
+
|
|
149
|
+
## Sketch: the `/update` flow (Option A assumed)
|
|
150
|
+
|
|
151
|
+
Putting this down concretely to see if the design holds:
|
|
152
|
+
|
|
153
|
+
1. Agent runs `clawmini-lite /update` (or a custom command that ends up sending this signal — TBD how the agent triggers it).
|
|
154
|
+
2. The daemon receives the request and dispatches to a new handler: `updateSelf()`.
|
|
155
|
+
3. `updateSelf` writes a "restart-requested" marker to `.clawmini/update-pending.json` with:
|
|
156
|
+
- Requested version (or `latest`).
|
|
157
|
+
- Timestamp.
|
|
158
|
+
- Which services were running (so restart is idempotent).
|
|
159
|
+
4. The daemon shuts itself down (same path as `clawmini down`).
|
|
160
|
+
5. The **supervisor** (not the daemon — the parent `clawmini serve` process) sees the daemon exit cleanly with the marker present. It:
|
|
161
|
+
- Stops all child adapters / web.
|
|
162
|
+
- Runs `npm install -g clawmini@<version>` (or `npm install clawmini@<version>` if local).
|
|
163
|
+
- Re-execs itself (`execvp`) with the new binary on PATH.
|
|
164
|
+
6. On restart, the supervisor reads the marker, starts the same set of services, deletes the marker.
|
|
165
|
+
7. Agent can notice the restart by the new version string in its next `/ping` response (or via a message from the supervisor once it's back up).
|
|
166
|
+
|
|
167
|
+
**Why this structure:** the daemon cannot upgrade itself because it's the thing being replaced. It needs a parent that outlives the upgrade. The supervisor is exactly that parent.
|
|
168
|
+
|
|
169
|
+
**Open edges:**
|
|
170
|
+
- If clawmini is installed locally (in the workspace `node_modules`), who runs `npm install`? The supervisor's `cwd` is the workspace — `npm install clawmini@latest` there would update the local install. But if the user installed globally (`npm install -g clawmini`), the supervisor needs to run `npm install -g` — which may need sudo on some setups. We might detect the install location by inspecting `process.execPath` / `require.resolve('clawmini/package.json')`.
|
|
171
|
+
- If the install fails mid-way, the supervisor needs a fallback ("old version still works, keep running it") rather than crash-looping.
|
|
172
|
+
- If a user invokes `/update` while actively chatting with the agent, there's a dead period. Probably fine (announce it, then do it), but worth naming.
|
|
173
|
+
- Agent trust: `/update` runs `npm install` which executes arbitrary scripts. This *is* a privileged operation. Needs the same policy approval flow as any other host-level command — not a built-in "agent can always do this."
|
|
174
|
+
|
|
175
|
+
## Open questions
|
|
176
|
+
|
|
177
|
+
1. **What does `clawmini up` / `clawmini down` mean after this ships?** Options: (a) deprecate and alias to `clawmini serve` / `clawmini serve --stop`, (b) keep as daemon-only commands forever, (c) redefine so `up` = `serve --detach` and `down` stops the supervisor. My instinct: (b) — don't break existing workflows; add `serve` alongside.
|
|
178
|
+
2. **Auto-detect vs. explicit enable for services?** "Config file present" is a good default heuristic for adapters but ambiguous for web (no config file). Maybe: web is always on, adapters auto-detect, user can `--exclude` to suppress. Or add `services` to `settings.json` (Option B's idea) as an explicit override.
|
|
179
|
+
3. **Log format.** Prefixed-line multiplexing is the standard approach; should we ship a JSON mode (`--log-format=json`) for machine consumers? Probably yes eventually, not for MVP.
|
|
180
|
+
4. **Log files on disk even in foreground mode?** If `serve` is in the foreground and you `Ctrl+C`, do the logs persist? Teeing stdout to `.clawmini/logs/*.log` even in foreground mode makes post-mortems possible. Cheap to include.
|
|
181
|
+
5. **Child restart policy.** If `adapter-discord` crashes, should the supervisor restart it? Backoff? Max retries? I'd say yes with exponential backoff capped at N retries, then give up and log — this is what users expect.
|
|
182
|
+
6. **Adapter logs before they connect.** Currently `initGoogleChatConfig` needs to succeed before anything useful happens. The supervisor needs to surface config errors clearly, not just exit code 1.
|
|
183
|
+
7. **How does the agent invoke `/update`?** Not a supervisor-design question per se, but: is `/update` a slash command that the daemon interprets, a built-in policy the agent can request, or something else? Easiest path: a router (like `@clawmini/slash-new`) that intercepts `/update` and calls the daemon's `updateSelf` tRPC method.
|
|
184
|
+
8. **Does the supervisor need its own PID file / IPC socket?** If we want `clawmini serve --stop` to work from another terminal (instead of only Ctrl+C in the owning terminal), yes — we need a way to find the running supervisor and signal it.
|
|
185
|
+
9. **Windows?** Currently the daemon uses a Unix socket; `detached: true` / `unref` semantics differ on Windows. Do we target Windows with this? Status quo is macOS/Linux; probably keep that scope.
|
|
186
|
+
|
|
187
|
+
## Non-goals
|
|
188
|
+
|
|
189
|
+
- Reinventing a process manager. If the above gets complicated, we just recommend `tmux` / `overmind` / a launchd plist in the docs and stop there.
|
|
190
|
+
- Multi-host orchestration (adapter on server A, daemon on server B).
|
|
191
|
+
- Hot-reload of adapters without restart.
|
|
192
|
+
- Replacing `.clawmini/daemon.log` outright — it can keep existing as a compatibility artifact; `clawmini logs` just reads the new location.
|
|
193
|
+
|
|
194
|
+
## Next steps (if we pick Option A)
|
|
195
|
+
|
|
196
|
+
Rough shipping order that would let us validate before committing fully:
|
|
197
|
+
|
|
198
|
+
1. **`clawmini serve` foreground-only, no backgrounding.** Spawn daemon inline + adapters as children + web. Multiplex logs with prefixes. Ctrl-C shuts everything cleanly. This is the MVP; it alone addresses goals #1 and #2 (users can `nohup clawmini serve &` if they want detach).
|
|
199
|
+
2. **Auto-detect which adapters to start.** Look for config files; optional `--only` / `--exclude`.
|
|
200
|
+
3. **`--detach` + `clawmini logs`.** First-class backgrounding with log tailing.
|
|
201
|
+
4. **`/update` plumbing.** Supervisor-managed re-exec after `npm install`. Separate spec for that once serve is shipped.
|
|
202
|
+
|
|
203
|
+
Each step is independently shippable and independently useful.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { TestEnvironment } from './test-environment.js';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
5
|
+
|
|
6
|
+
describe('TestEnvironment', () => {
|
|
7
|
+
let env: TestEnvironment;
|
|
8
|
+
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
env = new TestEnvironment('test-env');
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
afterEach(async () => {
|
|
14
|
+
await env.teardown();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('generates a unique id and creates an e2e directory', () => {
|
|
18
|
+
expect(env.id).toMatch(/^test-env-\d+-\d+$/);
|
|
19
|
+
expect(env.e2eDir).toContain(`clawmini-${env.id}`);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('setup creates directory and init git', async () => {
|
|
23
|
+
await env.setup();
|
|
24
|
+
expect(fs.existsSync(env.e2eDir)).toBe(true);
|
|
25
|
+
expect(fs.existsSync(path.join(env.e2eDir, '.git'))).toBe(true);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('updates settings', async () => {
|
|
29
|
+
await env.setup();
|
|
30
|
+
fs.mkdirSync(path.join(env.e2eDir, '.clawmini'), { recursive: true });
|
|
31
|
+
|
|
32
|
+
env.updateSettings({ api: { port: 8080 } });
|
|
33
|
+
|
|
34
|
+
const settingsPath = path.join(env.e2eDir, '.clawmini', 'settings.json');
|
|
35
|
+
const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
|
|
36
|
+
|
|
37
|
+
expect(settings.api.port).toBe(8080);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('writes policies', async () => {
|
|
41
|
+
await env.setup();
|
|
42
|
+
env.writePolicies([{ name: 'test-policy' }]);
|
|
43
|
+
|
|
44
|
+
const policiesPath = path.join(env.e2eDir, '.clawmini', 'policies.json');
|
|
45
|
+
expect(fs.existsSync(policiesPath)).toBe(true);
|
|
46
|
+
const parsed = JSON.parse(fs.readFileSync(policiesPath, 'utf8'));
|
|
47
|
+
expect(parsed.policies[0].name).toBe('test-policy');
|
|
48
|
+
});
|
|
49
|
+
});
|