clawmini 0.0.7 → 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/{G_zz-Gou.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.CYS8iApT.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.Dr0ot9sV.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.BBGQ_i84.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 +42 -13
- 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 -176
- package/web/.svelte-kit/generated/server/internal.js +1 -1
- package/web/.svelte-kit/output/client/.vite/manifest.json +127 -137
- 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/{G_zz-Gou.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.CYS8iApT.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.Dr0ot9sV.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.BBGQ_i84.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/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/chunks/bBmtyQMj.js +0 -1
- package/dist/web/_app/immutable/entry/app.CJmSwntr.js +0 -2
- package/dist/web/_app/immutable/entry/start.ZpUrT2ak.js +0 -1
- package/dist/web/_app/immutable/nodes/1.Bli0Hqzn.js +0 -1
- package/dist/web/_app/immutable/nodes/4.oBhvQhcA.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/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/chunks/bBmtyQMj.js +0 -1
- package/web/.svelte-kit/output/client/_app/immutable/entry/app.CJmSwntr.js +0 -2
- package/web/.svelte-kit/output/client/_app/immutable/entry/start.ZpUrT2ak.js +0 -1
- package/web/.svelte-kit/output/client/_app/immutable/nodes/1.Bli0Hqzn.js +0 -1
- package/web/.svelte-kit/output/client/_app/immutable/nodes/4.oBhvQhcA.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
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
import crypto from 'node:crypto';
|
|
2
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
3
|
+
import { getTRPCClient } from '../../src/adapter-google-chat/client.js';
|
|
4
|
+
import {
|
|
5
|
+
readGoogleChatState,
|
|
6
|
+
updateGoogleChatState,
|
|
7
|
+
} from '../../src/adapter-google-chat/state.js';
|
|
8
|
+
import { getSocketPath } from '../../src/shared/workspace.js';
|
|
9
|
+
import { appendMessage, type ChatMessage } from '../../src/shared/chats.js';
|
|
10
|
+
import {
|
|
11
|
+
findCreateByText,
|
|
12
|
+
findCreateWithCard,
|
|
13
|
+
makeFakeChatApi,
|
|
14
|
+
runForwarder,
|
|
15
|
+
useGoogleChatAdapterEnv,
|
|
16
|
+
} from './_google-chat-fixtures.js';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Seed `chatId` with a marker user message and the caller-provided messages,
|
|
20
|
+
* then configure `lastSyncedMessageIds[chatId]` so the forwarder's initial
|
|
21
|
+
* catchup yield starts immediately after the marker. We use direct file
|
|
22
|
+
* appends because there is no tRPC API to inject non-user messages (policy
|
|
23
|
+
* requests, agent replies) into a chat, and those messages have to already be
|
|
24
|
+
* on disk by the time the forwarder subscribes.
|
|
25
|
+
*/
|
|
26
|
+
async function seedChatForForwarderCatchup(
|
|
27
|
+
startDir: string,
|
|
28
|
+
chatId: string,
|
|
29
|
+
messages: ChatMessage[]
|
|
30
|
+
) {
|
|
31
|
+
const marker: ChatMessage = {
|
|
32
|
+
id: crypto.randomUUID(),
|
|
33
|
+
role: 'user',
|
|
34
|
+
content: '__seed_marker__',
|
|
35
|
+
timestamp: new Date().toISOString(),
|
|
36
|
+
sessionId: undefined,
|
|
37
|
+
};
|
|
38
|
+
await appendMessage(chatId, marker, startDir);
|
|
39
|
+
for (const msg of messages) {
|
|
40
|
+
await appendMessage(chatId, msg, startDir);
|
|
41
|
+
}
|
|
42
|
+
return marker.id;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
describe('Google Chat Adapter E2E — outbound (daemon → chat API via forwarder)', () => {
|
|
46
|
+
const envRef = useGoogleChatAdapterEnv('e2e-google-chat-outbound');
|
|
47
|
+
|
|
48
|
+
it('forwards agent-visible messages from the daemon to the chat API', async () => {
|
|
49
|
+
const { env } = envRef;
|
|
50
|
+
const trpc = getTRPCClient({ socketPath: getSocketPath(env.e2eDir) });
|
|
51
|
+
const { api, create } = makeFakeChatApi();
|
|
52
|
+
|
|
53
|
+
// Map a fake space to our chat so the forwarder knows where to post.
|
|
54
|
+
await updateGoogleChatState(
|
|
55
|
+
{ channelChatMap: { 'spaces/outbound': { chatId: 'gc-chat' } } },
|
|
56
|
+
env.e2eDir
|
|
57
|
+
);
|
|
58
|
+
await env.addChat('gc-chat');
|
|
59
|
+
|
|
60
|
+
// user-role messages are filtered out by default; allow them through so we don't need
|
|
61
|
+
// a real agent to produce the side of the conversation.
|
|
62
|
+
await runForwarder(
|
|
63
|
+
{ trpc, chatApi: api, startDir: env.e2eDir, filters: { user: true } },
|
|
64
|
+
async () => {
|
|
65
|
+
await env.sendMessage('outbound payload', { chat: 'gc-chat', noWait: true });
|
|
66
|
+
|
|
67
|
+
await vi.waitFor(
|
|
68
|
+
() => {
|
|
69
|
+
expect(findCreateByText(create, 'outbound payload')).toBeDefined();
|
|
70
|
+
},
|
|
71
|
+
{ timeout: 10000 }
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
expect(findCreateByText(create, 'outbound payload')!.parent).toBe('spaces/outbound');
|
|
75
|
+
}
|
|
76
|
+
);
|
|
77
|
+
}, 30000);
|
|
78
|
+
|
|
79
|
+
it('drops messages when no mapped space exists for the chat', async () => {
|
|
80
|
+
const { env } = envRef;
|
|
81
|
+
const trpc = getTRPCClient({ socketPath: getSocketPath(env.e2eDir) });
|
|
82
|
+
const { api, create } = makeFakeChatApi();
|
|
83
|
+
|
|
84
|
+
// No channelChatMap entry → forwarder should advance lastSyncedMessageIds but not post.
|
|
85
|
+
await env.addChat('gc-chat');
|
|
86
|
+
|
|
87
|
+
await runForwarder(
|
|
88
|
+
{ trpc, chatApi: api, startDir: env.e2eDir, filters: { user: true } },
|
|
89
|
+
async () => {
|
|
90
|
+
// Capture the forwarder's baseline cursor (it seeds to the chat's current latest
|
|
91
|
+
// message id on start), then send and wait for that cursor to advance — which
|
|
92
|
+
// proves the drop path executed without relying on a wall-clock delay.
|
|
93
|
+
const baseline = (await readGoogleChatState(env.e2eDir)).lastSyncedMessageIds?.['gc-chat'];
|
|
94
|
+
await env.sendMessage('unmapped payload', { chat: 'gc-chat', noWait: true });
|
|
95
|
+
|
|
96
|
+
await vi.waitFor(
|
|
97
|
+
async () => {
|
|
98
|
+
const cur = (await readGoogleChatState(env.e2eDir)).lastSyncedMessageIds?.['gc-chat'];
|
|
99
|
+
expect(cur).toBeDefined();
|
|
100
|
+
expect(cur).not.toBe(baseline);
|
|
101
|
+
},
|
|
102
|
+
{ timeout: 10000 }
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
expect(findCreateByText(create, 'unmapped payload')).toBeUndefined();
|
|
106
|
+
}
|
|
107
|
+
);
|
|
108
|
+
}, 30000);
|
|
109
|
+
|
|
110
|
+
it('renders pending policy-request messages as a cardsV2 payload', async () => {
|
|
111
|
+
const { env } = envRef;
|
|
112
|
+
const trpc = getTRPCClient({ socketPath: getSocketPath(env.e2eDir) });
|
|
113
|
+
const { api, create } = makeFakeChatApi();
|
|
114
|
+
|
|
115
|
+
await env.addChat('gc-policy');
|
|
116
|
+
|
|
117
|
+
const policyMsg: ChatMessage = {
|
|
118
|
+
id: crypto.randomUUID(),
|
|
119
|
+
role: 'policy',
|
|
120
|
+
content: 'please approve rm -rf /tmp',
|
|
121
|
+
timestamp: new Date().toISOString(),
|
|
122
|
+
sessionId: undefined,
|
|
123
|
+
messageId: 'm-pol',
|
|
124
|
+
requestId: 'req-pol',
|
|
125
|
+
commandName: 'rm',
|
|
126
|
+
args: ['-rf', '/tmp'],
|
|
127
|
+
status: 'pending',
|
|
128
|
+
};
|
|
129
|
+
const markerId = await seedChatForForwarderCatchup(env.e2eDir, 'gc-policy', [policyMsg]);
|
|
130
|
+
|
|
131
|
+
await updateGoogleChatState(
|
|
132
|
+
{
|
|
133
|
+
channelChatMap: { 'spaces/policy': { chatId: 'gc-policy' } },
|
|
134
|
+
lastSyncedMessageIds: { 'gc-policy': markerId },
|
|
135
|
+
},
|
|
136
|
+
env.e2eDir
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
await runForwarder({ trpc, chatApi: api, startDir: env.e2eDir }, async () => {
|
|
140
|
+
await vi.waitFor(
|
|
141
|
+
() => {
|
|
142
|
+
expect(findCreateWithCard(create)).toBeDefined();
|
|
143
|
+
},
|
|
144
|
+
{ timeout: 10000 }
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
const cardCall = findCreateWithCard(create)!;
|
|
148
|
+
expect(cardCall.parent).toBe('spaces/policy');
|
|
149
|
+
expect(cardCall.requestBody.text).toBe('');
|
|
150
|
+
const cards = cardCall.requestBody.cardsV2 as Array<{
|
|
151
|
+
card: { sections: Array<{ widgets: unknown[] }> };
|
|
152
|
+
}>;
|
|
153
|
+
expect(cards[0]!.card.sections[0]!.widgets.length).toBeGreaterThan(0);
|
|
154
|
+
});
|
|
155
|
+
}, 30000);
|
|
156
|
+
|
|
157
|
+
it('falls back to plain text when the policy cardsV2 send fails', async () => {
|
|
158
|
+
const { env } = envRef;
|
|
159
|
+
const trpc = getTRPCClient({ socketPath: getSocketPath(env.e2eDir) });
|
|
160
|
+
const { api, create } = makeFakeChatApi();
|
|
161
|
+
|
|
162
|
+
// First call (the rich cardsV2 send) throws; subsequent calls (the plain
|
|
163
|
+
// text fallback) resolve. This exercises the catch path in forwarder.ts.
|
|
164
|
+
create.mockImplementationOnce(() => Promise.reject(new Error('card send failed')));
|
|
165
|
+
|
|
166
|
+
await env.addChat('gc-policy-fallback');
|
|
167
|
+
|
|
168
|
+
const policyMsg: ChatMessage = {
|
|
169
|
+
id: crypto.randomUUID(),
|
|
170
|
+
role: 'policy',
|
|
171
|
+
content: 'please approve dangerous-thing',
|
|
172
|
+
timestamp: new Date().toISOString(),
|
|
173
|
+
sessionId: undefined,
|
|
174
|
+
messageId: 'm-pol-fb',
|
|
175
|
+
requestId: 'req-pol-fb',
|
|
176
|
+
commandName: 'dangerous-thing',
|
|
177
|
+
args: [],
|
|
178
|
+
status: 'pending',
|
|
179
|
+
};
|
|
180
|
+
const markerId = await seedChatForForwarderCatchup(env.e2eDir, 'gc-policy-fallback', [
|
|
181
|
+
policyMsg,
|
|
182
|
+
]);
|
|
183
|
+
|
|
184
|
+
await updateGoogleChatState(
|
|
185
|
+
{
|
|
186
|
+
channelChatMap: { 'spaces/policy-fb': { chatId: 'gc-policy-fallback' } },
|
|
187
|
+
lastSyncedMessageIds: { 'gc-policy-fallback': markerId },
|
|
188
|
+
},
|
|
189
|
+
env.e2eDir
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
await runForwarder({ trpc, chatApi: api, startDir: env.e2eDir }, async () => {
|
|
193
|
+
await vi.waitFor(
|
|
194
|
+
() => {
|
|
195
|
+
const plain = findCreateByText(
|
|
196
|
+
create,
|
|
197
|
+
(text) =>
|
|
198
|
+
text.includes('Action Required: Policy Request') && text.includes('req-pol-fb')
|
|
199
|
+
);
|
|
200
|
+
expect(plain).toBeDefined();
|
|
201
|
+
expect(plain!.requestBody.cardsV2).toBeUndefined();
|
|
202
|
+
},
|
|
203
|
+
{ timeout: 10000 }
|
|
204
|
+
);
|
|
205
|
+
});
|
|
206
|
+
}, 30000);
|
|
207
|
+
|
|
208
|
+
it('splits daemon messages longer than 4000 chars into multiple chat API calls', async () => {
|
|
209
|
+
const { env } = envRef;
|
|
210
|
+
const trpc = getTRPCClient({ socketPath: getSocketPath(env.e2eDir) });
|
|
211
|
+
const { api, create } = makeFakeChatApi();
|
|
212
|
+
|
|
213
|
+
await env.addChat('gc-chunk');
|
|
214
|
+
|
|
215
|
+
const longContent = 'a'.repeat(4000) + 'b'.repeat(3000);
|
|
216
|
+
const longMsg: ChatMessage = {
|
|
217
|
+
id: crypto.randomUUID(),
|
|
218
|
+
role: 'user',
|
|
219
|
+
content: longContent,
|
|
220
|
+
timestamp: new Date().toISOString(),
|
|
221
|
+
sessionId: undefined,
|
|
222
|
+
};
|
|
223
|
+
const markerId = await seedChatForForwarderCatchup(env.e2eDir, 'gc-chunk', [longMsg]);
|
|
224
|
+
|
|
225
|
+
await updateGoogleChatState(
|
|
226
|
+
{
|
|
227
|
+
channelChatMap: { 'spaces/chunk': { chatId: 'gc-chunk' } },
|
|
228
|
+
lastSyncedMessageIds: { 'gc-chunk': markerId },
|
|
229
|
+
},
|
|
230
|
+
env.e2eDir
|
|
231
|
+
);
|
|
232
|
+
|
|
233
|
+
await runForwarder(
|
|
234
|
+
{ trpc, chatApi: api, startDir: env.e2eDir, filters: { user: true } },
|
|
235
|
+
async () => {
|
|
236
|
+
await vi.waitFor(
|
|
237
|
+
() => {
|
|
238
|
+
const chunkCalls = create.mock.calls
|
|
239
|
+
.map(([params]) => params)
|
|
240
|
+
.filter((p) => p.parent === 'spaces/chunk' && (p.requestBody.text?.length ?? 0) > 0);
|
|
241
|
+
// 7000 chars at 4000 per chunk -> 2 calls.
|
|
242
|
+
expect(chunkCalls.length).toBeGreaterThanOrEqual(2);
|
|
243
|
+
const joined = chunkCalls.map((p) => p.requestBody.text ?? '').join('');
|
|
244
|
+
expect(joined).toBe(longContent);
|
|
245
|
+
for (const p of chunkCalls) {
|
|
246
|
+
expect(p.requestBody.text!.length).toBeLessThanOrEqual(4000);
|
|
247
|
+
}
|
|
248
|
+
},
|
|
249
|
+
{ timeout: 15000 }
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
);
|
|
253
|
+
}, 30000);
|
|
254
|
+
|
|
255
|
+
it('formats attached files with a plain-text fallback when Drive upload is disabled', async () => {
|
|
256
|
+
const { env } = envRef;
|
|
257
|
+
const trpc = getTRPCClient({ socketPath: getSocketPath(env.e2eDir) });
|
|
258
|
+
const { api, create } = makeFakeChatApi();
|
|
259
|
+
|
|
260
|
+
await env.addChat('gc-files');
|
|
261
|
+
|
|
262
|
+
const fileMsg: ChatMessage = {
|
|
263
|
+
id: crypto.randomUUID(),
|
|
264
|
+
role: 'agent',
|
|
265
|
+
content: 'here is the report',
|
|
266
|
+
timestamp: new Date().toISOString(),
|
|
267
|
+
sessionId: undefined,
|
|
268
|
+
files: ['/tmp/report.pdf', '/tmp/diagram.png'],
|
|
269
|
+
};
|
|
270
|
+
const markerId = await seedChatForForwarderCatchup(env.e2eDir, 'gc-files', [fileMsg]);
|
|
271
|
+
|
|
272
|
+
await updateGoogleChatState(
|
|
273
|
+
{
|
|
274
|
+
channelChatMap: { 'spaces/files': { chatId: 'gc-files' } },
|
|
275
|
+
lastSyncedMessageIds: { 'gc-files': markerId },
|
|
276
|
+
},
|
|
277
|
+
env.e2eDir
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
// Default filters let agent messages through; no overrides needed.
|
|
281
|
+
await runForwarder({ trpc, chatApi: api, startDir: env.e2eDir }, async () => {
|
|
282
|
+
await vi.waitFor(
|
|
283
|
+
() => {
|
|
284
|
+
const fileCall = findCreateByText(
|
|
285
|
+
create,
|
|
286
|
+
(text) =>
|
|
287
|
+
text.includes('here is the report') &&
|
|
288
|
+
text.includes('(Files generated: report.pdf, diagram.png)')
|
|
289
|
+
);
|
|
290
|
+
expect(fileCall).toBeDefined();
|
|
291
|
+
expect(fileCall!.parent).toBe('spaces/files');
|
|
292
|
+
},
|
|
293
|
+
{ timeout: 10000 }
|
|
294
|
+
);
|
|
295
|
+
});
|
|
296
|
+
}, 30000);
|
|
297
|
+
});
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
+
import {
|
|
3
|
+
getTRPCClient,
|
|
4
|
+
startGoogleChatIngestion,
|
|
5
|
+
} from '../../src/adapter-google-chat/client.js';
|
|
6
|
+
import { updateGoogleChatState } from '../../src/adapter-google-chat/state.js';
|
|
7
|
+
import { getSocketPath } from '../../src/shared/workspace.js';
|
|
8
|
+
import {
|
|
9
|
+
BASE_CONFIG,
|
|
10
|
+
findCreateByText,
|
|
11
|
+
makeDmMessage,
|
|
12
|
+
makeFakeChatApi,
|
|
13
|
+
makeFakeSubscription,
|
|
14
|
+
runForwarder,
|
|
15
|
+
useGoogleChatAdapterEnv,
|
|
16
|
+
} from './_google-chat-fixtures.js';
|
|
17
|
+
|
|
18
|
+
describe('Google Chat Adapter E2E — round-trip (Pub/Sub → daemon → forwarder → chat API)', () => {
|
|
19
|
+
const envRef = useGoogleChatAdapterEnv('e2e-google-chat-roundtrip');
|
|
20
|
+
|
|
21
|
+
it('sends an inbound message through the daemon and back out to the chat API', async () => {
|
|
22
|
+
const { env } = envRef;
|
|
23
|
+
const trpc = getTRPCClient({ socketPath: getSocketPath(env.e2eDir) });
|
|
24
|
+
const subscription = makeFakeSubscription();
|
|
25
|
+
const { api, create } = makeFakeChatApi();
|
|
26
|
+
|
|
27
|
+
await updateGoogleChatState(
|
|
28
|
+
{ channelChatMap: { 'spaces/roundtrip': { chatId: 'gc-chat' } } },
|
|
29
|
+
env.e2eDir
|
|
30
|
+
);
|
|
31
|
+
await env.addChat('gc-chat');
|
|
32
|
+
|
|
33
|
+
startGoogleChatIngestion(
|
|
34
|
+
BASE_CONFIG,
|
|
35
|
+
trpc,
|
|
36
|
+
{},
|
|
37
|
+
{ subscription, chatApi: api, startDir: env.e2eDir }
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
await runForwarder(
|
|
41
|
+
{ trpc, chatApi: api, startDir: env.e2eDir, filters: { user: true } },
|
|
42
|
+
async () => {
|
|
43
|
+
subscription.emitMessage(
|
|
44
|
+
makeDmMessage({ space: 'spaces/roundtrip', messageId: 'rt1', text: 'round trip' })
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
await vi.waitFor(
|
|
48
|
+
() => {
|
|
49
|
+
expect(findCreateByText(create, 'round trip')).toBeDefined();
|
|
50
|
+
},
|
|
51
|
+
{ timeout: 10000 }
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
);
|
|
55
|
+
}, 30000);
|
|
56
|
+
});
|