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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["fs","path","fs","fs","shared.appendMessage","getMessages","findLastMessageFromStorage","crypto","fs","fs","fs","fetchMessages"],"sources":["../../src/daemon/api/trpc.ts","../../src/daemon/routers/slash-new.ts","../../src/daemon/routers/slash-command.ts","../../src/daemon/routers/utils.ts","../../src/daemon/routers/slash-stop.ts","../../src/daemon/routers/slash-interrupt.ts","../../src/daemon/request-store.ts","../../src/daemon/policy-utils.ts","../../src/daemon/events.ts","../../src/daemon/chats.ts","../../src/daemon/routers/slash-policies.ts","../../src/daemon/routers/session-timeout.ts","../../src/daemon/routers.ts","../../src/daemon/agent/agent-context.ts","../../src/daemon/agent/agent-extractors.ts","../../src/daemon/agent/utils.ts","../../src/daemon/agent/agent-runner.ts","../../src/daemon/utils/spawn.ts","../../src/daemon/agent/chat-logger.ts","../../src/shared/utils/env.ts","../../src/daemon/auth.ts","../../src/daemon/agent/task-scheduler.ts","../../src/daemon/agent/agent-session.ts","../../src/daemon/message.ts","../../src/daemon/cron.ts","../../src/daemon/api/router-utils.ts","../../src/daemon/api/user-router.ts","../../src/daemon/policy-request-service.ts","../../src/daemon/api/subagent-utils.ts","../../src/daemon/api/subagent-router.ts","../../src/daemon/api/agent-router.ts","../../src/daemon/index.ts"],"sourcesContent":["import { initTRPC, TRPCError } from '@trpc/server';\nimport type { IncomingMessage, ServerResponse } from 'node:http';\nimport type { TokenPayload } from '../auth.js';\n\nexport interface Context {\n req?: IncomingMessage | undefined;\n res?: ServerResponse | undefined;\n isApiServer?: boolean | undefined;\n tokenPayload?: TokenPayload | null | undefined;\n}\n\nconst t = initTRPC.context<Context>().create();\nexport const router = t.router;\nexport const publicProcedure = t.procedure;\n\nconst apiAuthMiddleware = t.middleware(({ ctx, next }) => {\n if (ctx.isApiServer) {\n if (!ctx.tokenPayload) {\n throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing or invalid token' });\n }\n }\n return next({\n ctx: {\n ...ctx,\n tokenPayload: ctx.tokenPayload,\n },\n });\n});\n\nexport const apiProcedure = t.procedure.use(apiAuthMiddleware);\n","import type { RouterState } from './types.js';\n\nexport function slashNew(state: RouterState): RouterState {\n if (/^\\/new(\\s|$)/.test(state.message)) {\n const newMessage = state.message.replace(/^\\/new(\\s+|$)/, '').trim();\n const id = crypto.randomUUID();\n return {\n ...state,\n message: newMessage,\n sessionId: id,\n nextSessionId: id,\n reply: '[@clawmini/slash-new] Starting a new session...',\n };\n }\n return state;\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { RouterState } from './types.js';\nimport { getClawminiDir } from '../../shared/workspace.js';\nimport { pathIsInsideDir } from '../../shared/utils/fs.js';\n\nexport async function slashCommand(state: RouterState): Promise<RouterState> {\n const commandsDir = path.resolve(getClawminiDir(), 'commands');\n let currentMessage = state.message;\n\n // Regex to match slash commands (e.g., /foo or /foo:bar) that appear as whole words.\n // We use lookbehind and lookahead to ensure it's bounded by whitespace or string start/end.\n const commandRegex = /(?<=^|\\s)\\/([a-zA-Z0-9_\\-:.]+)(?=\\s|$)/g;\n const matches = [...currentMessage.matchAll(commandRegex)];\n\n if (matches.length === 0) {\n return state;\n }\n\n for (const match of matches) {\n const fullMatch = match[0];\n const commandName = match[1];\n if (!commandName) continue;\n\n const targetPathMd = path.resolve(commandsDir, `${commandName}.md`);\n const targetPathTxt = path.resolve(commandsDir, `${commandName}.txt`);\n\n // Strict path traversal protection\n const baseTargetPath = path.resolve(commandsDir, commandName);\n if (!pathIsInsideDir(baseTargetPath, commandsDir)) {\n continue;\n }\n\n let content: string;\n\n try {\n content = await fs.readFile(targetPathMd, 'utf8');\n } catch {\n try {\n content = await fs.readFile(targetPathTxt, 'utf8');\n } catch {\n // If file doesn't exist or can't be read, leave it as is.\n continue;\n }\n }\n\n // Replace the command with the content. We only replace the exact occurrence.\n // Since replace replaces the first occurrence, and we are iterating over all matches,\n // it should replace them sequentially. If there are multiple identical commands,\n // it's fine, each will be replaced in turn.\n currentMessage = currentMessage.replace(fullMatch, content.trim());\n }\n\n return {\n ...state,\n message: currentMessage,\n };\n}\n","import type { RouterState } from './types.js';\n\nexport function createSlashActionRouter(\n command: string,\n action: NonNullable<RouterState['action']>,\n replyMessage: string\n) {\n return function (state: RouterState): RouterState {\n const regex = new RegExp(`^\\\\/${command}(\\\\s|$)`);\n if (regex.test(state.message)) {\n const replaceRegex = new RegExp(`^\\\\/${command}(\\\\s+|$)`);\n const newMessage = state.message.replace(replaceRegex, '').trim();\n return {\n ...state,\n message: newMessage,\n action,\n reply: replyMessage,\n };\n }\n return state;\n };\n}\n","import { createSlashActionRouter } from './utils.js';\n\nexport const slashStop = createSlashActionRouter('stop', 'stop', 'Stopping current task...');\n","import { createSlashActionRouter } from './utils.js';\n\nexport const slashInterrupt = createSlashActionRouter(\n 'interrupt',\n 'interrupt',\n 'Interrupting current task...'\n);\n","import fs from 'fs/promises';\nimport path from 'path';\nimport { z } from 'zod';\nimport { getClawminiDir } from '../shared/workspace.js';\nimport type { PolicyRequest } from '../shared/policies.js';\nimport { randomInt } from 'crypto';\n\nconst PolicyRequestSchema = z.object({\n id: z.string(),\n commandName: z.string(),\n args: z.array(z.string()),\n fileMappings: z.record(z.string(), z.string()),\n state: z.enum(['Pending', 'Approved', 'Rejected']),\n createdAt: z.number(),\n rejectionReason: z.string().optional(),\n chatId: z.string(),\n agentId: z.string(),\n});\n\nfunction isENOENT(err: unknown): boolean {\n return Boolean(\n err && typeof err === 'object' && 'code' in err && (err as { code: string }).code === 'ENOENT'\n );\n}\n\nexport class RequestStore {\n private baseDir: string;\n\n constructor(startDir = process.cwd()) {\n this.baseDir = path.join(getClawminiDir(startDir), 'tmp', 'requests');\n }\n\n async init(): Promise<void> {\n await fs.mkdir(this.baseDir, { recursive: true });\n }\n\n private getFilePath(id: string): string {\n return path.join(this.baseDir, `${id}.json`);\n }\n\n async save(request: PolicyRequest): Promise<void> {\n await this.init();\n const normalizedId = normalizePolicyId(request.id);\n request.id = normalizedId;\n const filePath = this.getFilePath(normalizedId);\n await fs.writeFile(filePath, JSON.stringify(request, null, 2), 'utf8');\n }\n\n async load(id: string): Promise<PolicyRequest | null> {\n const normalizedId = normalizePolicyId(id);\n const filePath = this.getFilePath(normalizedId);\n try {\n const data = await fs.readFile(filePath, 'utf8');\n return PolicyRequestSchema.parse(JSON.parse(data)) as PolicyRequest;\n } catch (err: unknown) {\n if (isENOENT(err)) {\n return null;\n }\n const msg = err instanceof Error ? err.message : String(err);\n console.warn(`Failed to parse request file ${filePath}:`, msg);\n return null;\n }\n }\n\n async list(): Promise<PolicyRequest[]> {\n await this.init();\n const requests: PolicyRequest[] = [];\n try {\n const files = await fs.readdir(this.baseDir);\n for (const file of files) {\n if (!file.endsWith('.json')) continue;\n const id = path.basename(file, '.json');\n const req = await this.load(id);\n if (req) {\n requests.push(req);\n }\n }\n } catch (err: unknown) {\n if (!isENOENT(err)) {\n throw err;\n }\n }\n return requests.sort((a, b) => b.createdAt - a.createdAt);\n }\n}\n\nexport function generateRandomAlphaNumericString(length: number): string {\n const characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';\n let result = '';\n for (let i = 0; i < length; i++) {\n result += characters[Math.floor(randomInt(characters.length))];\n }\n return result;\n}\n\nfunction normalizePolicyId(id: string): string {\n return id.toLocaleUpperCase().trim();\n}\n","import fs from 'node:fs/promises';\nimport { constants } from 'node:fs';\nimport path from 'node:path';\nimport { randomBytes } from 'node:crypto';\nimport { spawn } from 'node:child_process';\nimport { pathIsInsideDir } from '../shared/utils/fs.js';\nimport type { PolicyRequest, PolicyDefinition } from '../shared/policies.js';\n\nexport const MAX_SNAPSHOT_SIZE = 5 * 1024 * 1024;\n\nexport async function createSnapshot(\n requestedPath: string,\n agentDir: string,\n snapshotDir: string\n): Promise<string> {\n let realAgentDir: string;\n try {\n realAgentDir = await fs.realpath(agentDir);\n } catch (err) {\n throw new Error(`Agent directory not found or cannot be resolved: ${agentDir}`, { cause: err });\n }\n\n const resolvedRequestedPath = path.resolve(realAgentDir, requestedPath);\n\n // Verify it is inside the allowed agent directory\n if (!pathIsInsideDir(resolvedRequestedPath, realAgentDir, { allowSameDir: true })) {\n throw new Error(\n `Security Error: Path resolves outside the allowed agent directory: ${resolvedRequestedPath}`\n );\n }\n\n // Lstat prevents TOCTOU attacks by not following symlinks\n let stat;\n try {\n stat = await fs.lstat(resolvedRequestedPath);\n } catch (err) {\n throw new Error(`File not found or cannot be accessed: ${requestedPath}`, { cause: err });\n }\n\n if (stat.isSymbolicLink()) {\n throw new Error(`Security Error: Symlinks are not allowed: ${requestedPath}`);\n }\n\n if (!stat.isFile()) {\n throw new Error(`Requested path is not a file: ${requestedPath}`);\n }\n if (stat.size > MAX_SNAPSHOT_SIZE) {\n throw new Error(`File exceeds maximum snapshot size of 5MB: ${requestedPath}`);\n }\n\n // Generate unique filename for the snapshot\n const ext = path.extname(resolvedRequestedPath);\n const base = path.basename(resolvedRequestedPath, ext);\n\n await fs.mkdir(snapshotDir, { recursive: true });\n\n let snapshotPath: string;\n while (true) {\n const uniqueId = randomBytes(8).toString('hex');\n const snapshotFileName = `${base}_${uniqueId}${ext}`;\n snapshotPath = path.join(snapshotDir, snapshotFileName);\n\n try {\n await fs.copyFile(resolvedRequestedPath, snapshotPath, constants.COPYFILE_EXCL);\n break;\n } catch (err: unknown) {\n if (\n err instanceof Error &&\n 'code' in err &&\n (err as Error & { code?: string }).code === 'EEXIST'\n ) {\n continue;\n }\n throw err;\n }\n }\n\n return snapshotPath;\n}\n\nexport function interpolateArgs(args: string[], snapshots: Record<string, string>): string[] {\n return args.map((arg) => {\n let interpolated = arg;\n for (const [key, snapshotPath] of Object.entries(snapshots)) {\n const variable = `{{${key}}}`;\n interpolated = interpolated.replaceAll(variable, snapshotPath);\n }\n return interpolated;\n });\n}\n\nexport function executeSafe(\n command: string,\n args: string[],\n options?: { cwd?: string; env?: NodeJS.ProcessEnv }\n): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n return new Promise((resolve) => {\n // Safe execution: shell is strictly false to prevent command injection\n const p = spawn(command, args, {\n shell: false,\n cwd: options?.cwd,\n env: options?.env,\n });\n\n let stdout = '';\n let stderr = '';\n\n if (p.stdout) {\n p.stdout.on('data', (data) => {\n stdout += data.toString();\n });\n }\n\n if (p.stderr) {\n p.stderr.on('data', (data) => {\n stderr += data.toString();\n });\n }\n\n p.on('close', (code) => {\n resolve({ stdout, stderr, exitCode: code ?? 1 });\n });\n\n p.on('error', (err) => {\n resolve({ stdout: '', stderr: err.toString(), exitCode: 1 });\n });\n });\n}\n\nexport async function executeRequest(\n request: PolicyRequest,\n policy: PolicyDefinition,\n cwd?: string\n): Promise<{ stdout: string; stderr: string; exitCode: number; commandStr: string }> {\n const fullArgs = [...(policy.args || []), ...request.args];\n const interpolatedArgs = interpolateArgs(fullArgs, request.fileMappings);\n\n const { stdout, stderr, exitCode } = await executeSafe(\n policy.command,\n interpolatedArgs,\n cwd ? { cwd } : undefined\n );\n\n const commandStr = `${policy.command} ${interpolatedArgs.join(' ')}`;\n return { stdout, stderr, exitCode, commandStr };\n}\n\nexport async function generateRequestPreview(request: PolicyRequest): Promise<string> {\n let previewContent = `Sandbox Policy Request: ${request.commandName}\\n`;\n previewContent += `ID: ${request.id}\\n`;\n if (request.args.length > 0) {\n previewContent += `Args: ${request.args.join(' ')}\\n`;\n }\n\n for (const [name, snapPath] of Object.entries(request.fileMappings)) {\n previewContent += `File [${name}]:\\n`;\n try {\n let content = await fs.readFile(snapPath, 'utf8');\n if (content.length > 500) {\n content = content.substring(0, 500) + '\\n... (truncated)\\n';\n }\n previewContent += content;\n } catch (e: unknown) {\n previewContent += `<Error reading file: ${(e as Error).message}>\\n`;\n }\n }\n\n previewContent += `\\nUse /approve ${request.id} or /reject ${request.id} [reason]`;\n return previewContent;\n}\n","import { EventEmitter } from 'node:events';\nimport type { ChatMessage } from '../shared/chats.js';\n\nexport const daemonEvents = new EventEmitter();\n\nexport const DAEMON_EVENT_MESSAGE_APPENDED = 'message-appended';\nexport const DAEMON_EVENT_TYPING = 'typing';\n\nexport function emitMessageAppended(chatId: string, message: ChatMessage) {\n daemonEvents.emit(DAEMON_EVENT_MESSAGE_APPENDED, { chatId, message });\n}\n\nexport function emitTyping(chatId: string) {\n daemonEvents.emit(DAEMON_EVENT_TYPING, { chatId });\n}\n","import * as shared from '../shared/chats.js';\nimport { emitMessageAppended } from './events.js';\n\nexport async function appendMessage(\n id: string,\n message: shared.ChatMessage,\n startDir = process.cwd()\n): Promise<void> {\n await shared.appendMessage(id, message, startDir);\n emitMessageAppended(id, message);\n}\n\nexport {\n type ChatMessage,\n type UserMessage,\n type CommandLogMessage,\n type SystemMessage,\n type AgentReplyMessage,\n type ToolMessage,\n type PolicyRequestMessage,\n type SubagentStatusMessage,\n getChatsDir,\n isValidChatId,\n createChat,\n listChats,\n deleteChat,\n getMessages,\n findLastMessage,\n getDefaultChatId,\n setDefaultChatId,\n DEFAULT_CHAT_ID,\n} from '../shared/chats.js';\n","import { randomUUID } from 'node:crypto';\nimport type { RouterState } from './types.js';\nimport { RequestStore } from '../request-store.js';\nimport { readPolicies, getWorkspaceRoot } from '../../shared/workspace.js';\nimport { executeRequest } from '../policy-utils.js';\nimport { appendMessage } from '../chats.js';\nimport type { SystemMessage } from '../../shared/chats.js';\n\nasync function loadAndValidateRequest(id: string, state: RouterState) {\n const store = new RequestStore(getWorkspaceRoot());\n const req = await store.load(id);\n if (!req) return { error: { ...state, message: '', reply: `Request not found: ${id}` } };\n if (req.chatId && req.chatId !== state.chatId)\n return {\n error: { ...state, message: '', reply: `Request belongs to a different chat: ${req.chatId}` },\n };\n if (req.state !== 'Pending')\n return { error: { ...state, message: '', reply: `Request is not pending: ${id}` } };\n return { req, store };\n}\n\nexport async function slashPolicies(state: RouterState): Promise<RouterState> {\n const message = state.message.trim();\n\n if (message === '/pending') {\n const store = new RequestStore(getWorkspaceRoot());\n const requests = await store.list();\n const pending = requests.filter((r) => r.state === 'Pending');\n\n let reply = `Pending Requests (${pending.length}):\\n`;\n for (const req of pending) {\n reply += `- ID: ${req.id} | Command: ${req.commandName} ${req.args.join(' ')}\\n`;\n }\n\n return {\n ...state,\n reply,\n action: 'stop',\n };\n }\n\n const approveMatch = message.match(/^\\/approve\\s+([^\\s]+)/);\n if (approveMatch) {\n const id = approveMatch[1];\n if (!id) return state;\n const { req, store, error } = await loadAndValidateRequest(id, state);\n if (error) return error;\n if (!req || !store) return state; // Should not happen if error is undefined\n\n const config = await readPolicies();\n const policy = config?.policies?.[req.commandName];\n if (!policy) {\n return { ...state, message: '', reply: `Policy not found: ${req.commandName}` };\n }\n\n req.state = 'Approved';\n\n const { stdout, stderr, exitCode } = await executeRequest(req, policy, getWorkspaceRoot());\n\n req.executionResult = { stdout, stderr, exitCode };\n await store.save(req);\n\n const agentMessage = `Request ${id} approved.\\n\\n${wrapInHtml('stdout', stdout)}\\n\\n${wrapInHtml('stderr', stderr)}\\n\\nExit Code: ${exitCode}`;\n\n const logMsg: SystemMessage = {\n id: randomUUID(),\n messageId: state.messageId,\n role: 'system',\n event: 'policy_approved',\n displayRole: 'user',\n content: agentMessage,\n timestamp: new Date().toISOString(),\n ...(req.subagentId ? { subagentId: req.subagentId } : {}),\n };\n\n await appendMessage(state.chatId, logMsg);\n\n return {\n ...state,\n message: agentMessage,\n reply: `Approved request, running ${req.commandName}`,\n ...(req.subagentId ? { subagentId: req.subagentId } : {}),\n };\n }\n\n const rejectMatch = message.match(/^\\/reject\\s+([^\\s]+)(?:\\s+(.*))?/);\n if (rejectMatch) {\n const id = rejectMatch[1];\n if (!id) return state;\n const reason = rejectMatch[2] || 'No reason provided';\n const { req, store, error } = await loadAndValidateRequest(id, state);\n if (error) return error;\n if (!req || !store) return state; // Should not happen if error is undefined\n\n req.state = 'Rejected';\n req.rejectionReason = reason;\n await store.save(req);\n\n const agentMessage = `Request ${id} rejected. Reason: ${reason}`;\n\n const logMsg: SystemMessage = {\n id: randomUUID(),\n messageId: state.messageId,\n role: 'system',\n event: 'policy_rejected',\n displayRole: 'user',\n content: agentMessage,\n timestamp: new Date().toISOString(),\n ...(req.subagentId ? { subagentId: req.subagentId } : {}),\n };\n\n const userNotificationMsg: SystemMessage = {\n id: randomUUID(),\n messageId: state.messageId,\n role: 'system',\n event: 'policy_rejected',\n displayRole: 'agent',\n content: agentMessage,\n timestamp: new Date().toISOString(),\n ...(req.subagentId ? { subagentId: req.subagentId } : {}),\n };\n\n await appendMessage(state.chatId, logMsg);\n await appendMessage(state.chatId, userNotificationMsg);\n\n return {\n ...state,\n message: agentMessage,\n ...(req.subagentId ? { subagentId: req.subagentId } : {}),\n };\n }\n\n return state;\n}\n\nfunction wrapInHtml(tag: string, text: string): string {\n if (text.trim().length === 0) {\n return `<${tag}></${tag}>`;\n }\n return `<${tag}>\\n${text.trim()}\\n</${tag}>`;\n}\n","import type { RouterState } from './types.js';\nimport { randomUUID } from 'node:crypto';\n\nexport interface SessionTimeoutConfig {\n timeout?: string;\n prompt?: string;\n}\n\n/**\n * Router that automatically starts a new session after a period of inactivity.\n *\n * To register this router, add it to your `~/.gemini/settings.json`:\n * ```json\n * {\n * \"routers\": [\n * {\n * \"use\": \"session-timeout\",\n * \"with\": {\n * \"timeout\": \"60m\",\n * \"prompt\": \"This chat session has ended. Save any important details from it to your memory. When finished, reply with NO_REPLY_NECESSARY.\"\n * }\n * }\n * ]\n * }\n * ```\n */\nexport function createSessionTimeoutRouter(config: SessionTimeoutConfig = {}) {\n const timeStr = config.timeout ?? '60m';\n const prompt =\n config.prompt ??\n 'This chat session has ended. Save any important details from it to your memory. When finished, reply with NO_REPLY_NECESSARY.';\n\n return function (state: RouterState): RouterState {\n if (state.env?.__SESSION_TIMEOUT__ === 'true') {\n return state;\n }\n\n const sessionId = state.sessionId || crypto.randomUUID();\n const jobId = `__session_timeout__${sessionId}`;\n\n const jobs = {\n ...state.jobs,\n remove: [...(state.jobs?.remove || []), jobId, '__session_timeout__'],\n };\n\n return {\n ...state,\n sessionId,\n jobs: {\n ...jobs,\n add: [\n ...(jobs.add || []),\n // Add a job after the timeout that will send the prompt, reply to the user,\n // start a fresh session, and delete the job\n {\n id: jobId,\n schedule: { at: timeStr },\n message: prompt,\n reply: '[@clawmini/session-timeout] Starting a fresh session...',\n nextSessionId: randomUUID(),\n session: { type: 'existing', id: sessionId },\n env: { __SESSION_TIMEOUT__: 'true' },\n jobs: {\n remove: [jobId],\n },\n },\n ],\n },\n };\n };\n}\n","import { spawn } from 'node:child_process';\nimport type { RouterState } from './routers/types.js';\nimport { slashNew } from './routers/slash-new.js';\nimport { slashCommand } from './routers/slash-command.js';\nimport { slashStop } from './routers/slash-stop.js';\nimport { slashInterrupt } from './routers/slash-interrupt.js';\nimport { slashPolicies } from './routers/slash-policies.js';\nimport { createSessionTimeoutRouter } from './routers/session-timeout.js';\nimport type { RouterConfig } from '../shared/config.js';\n\nexport const GLOBAL_ROUTERS: RouterConfig[] = ['@clawmini/session-timeout'];\n\nexport const USER_ROUTERS: RouterConfig[] = [\n '@clawmini/slash-new',\n '@clawmini/slash-command',\n '@clawmini/slash-stop',\n '@clawmini/slash-interrupt',\n '@clawmini/slash-policies',\n];\n\nexport function resolveRouters(\n userRouters: RouterConfig[],\n isUserMessage: boolean\n): RouterConfig[] {\n const resolvedGlobals: RouterConfig[] = [];\n const resolvedUsers: RouterConfig[] = [];\n\n const userConfigMap = new Map<string, unknown>();\n for (const r of userRouters) {\n const name = typeof r === 'string' ? r : r.use;\n const config = typeof r === 'string' ? {} : r.with || {};\n\n if (name.startsWith('@clawmini/')) {\n userConfigMap.set(name, config);\n } else {\n resolvedUsers.push(r);\n }\n }\n\n for (const globalRouter of GLOBAL_ROUTERS) {\n const name = typeof globalRouter === 'string' ? globalRouter : globalRouter.use;\n const baseConfig = typeof globalRouter === 'string' ? {} : globalRouter.with || {};\n const userConfig = userConfigMap.get(name) || {};\n const mergedConfig = { ...baseConfig, ...userConfig };\n\n resolvedGlobals.push({ use: name, with: mergedConfig });\n }\n\n const defaultUserRouters: RouterConfig[] = [];\n for (const defaultUserRouter of USER_ROUTERS) {\n const name = typeof defaultUserRouter === 'string' ? defaultUserRouter : defaultUserRouter.use;\n const baseConfig = typeof defaultUserRouter === 'string' ? {} : defaultUserRouter.with || {};\n const userConfig = userConfigMap.get(name) || {};\n const mergedConfig = { ...baseConfig, ...userConfig };\n\n defaultUserRouters.push({ use: name, with: mergedConfig });\n }\n\n if (isUserMessage) {\n return [...resolvedGlobals, ...defaultUserRouters, ...resolvedUsers];\n } else {\n return resolvedGlobals;\n }\n}\n\nexport async function executeRouterPipeline(\n initialState: RouterState,\n routers: RouterConfig[]\n): Promise<RouterState> {\n let state = { ...initialState };\n\n for (const routerDef of routers) {\n if (state.action === 'stop') {\n break;\n }\n\n const router = typeof routerDef === 'string' ? routerDef : routerDef.use;\n const config = typeof routerDef === 'string' ? {} : routerDef.with || {};\n\n if (router === '@clawmini/slash-new') {\n state = slashNew(state);\n } else if (router === '@clawmini/slash-command') {\n state = await slashCommand(state);\n } else if (router === '@clawmini/slash-stop') {\n state = slashStop(state);\n } else if (router === '@clawmini/slash-interrupt') {\n state = slashInterrupt(state);\n } else if (router === '@clawmini/slash-policies') {\n state = await slashPolicies(state);\n } else if (router === '@clawmini/session-timeout') {\n state = createSessionTimeoutRouter(config)(state);\n } else {\n // Execute as custom shell command\n try {\n state = await executeCustomRouter(router, state);\n } catch (err) {\n // Silent failure handling: log but do not halt\n console.error(`Router error [${router}]:`, err);\n }\n }\n }\n\n return state;\n}\n\nasync function executeCustomRouter(command: string, state: RouterState): Promise<RouterState> {\n return new Promise((resolve, reject) => {\n // We run the command via shell\n const child = spawn(command, { shell: true });\n\n let stdout = '';\n let stderr = '';\n\n child.stdout.on('data', (chunk) => {\n stdout += chunk.toString();\n });\n child.stderr.on('data', (chunk) => {\n stderr += chunk.toString();\n });\n\n // timeout fallback to avoid hanging indefinitely\n const timer = setTimeout(() => {\n child.kill();\n reject(new Error('Router execution timed out'));\n }, 10000);\n\n child.on('close', (code) => {\n clearTimeout(timer);\n if (code !== 0) {\n return reject(new Error(`Process exited with code ${code}. Stderr: ${stderr}`));\n }\n\n try {\n const result = JSON.parse(stdout);\n const newState = { ...state };\n\n if (typeof result.message === 'string') newState.message = result.message;\n if (typeof result.agent === 'string') newState.agentId = result.agent;\n if (typeof result.session === 'string') newState.sessionId = result.session;\n if (typeof result.env === 'object' && result.env !== null) {\n newState.env = { ...newState.env, ...result.env };\n }\n if (typeof result.reply === 'string') newState.reply = result.reply;\n if (typeof result.action === 'string') newState.action = result.action;\n\n resolve(newState);\n } catch (err) {\n reject(new Error(`Failed to parse router output: ${err}. Stdout: ${stdout}`));\n }\n });\n\n child.on('error', (err) => {\n clearTimeout(timer);\n reject(err);\n });\n\n // Write state to stdin\n const inputState = {\n message: state.message,\n chatId: state.chatId,\n agentId: state.agentId,\n sessionId: state.sessionId,\n env: state.env,\n action: state.action,\n };\n\n if (child.stdin) {\n child.stdin.on('error', (err) => {\n if ((err as NodeJS.ErrnoException).code !== 'EPIPE') {\n console.error('stdin error:', err);\n }\n });\n child.stdin.write(JSON.stringify(inputState));\n child.stdin.end();\n }\n });\n}\n","import { type FallbackSchema } from '../../shared/config.js';\nimport {\n getActiveEnvironmentInfo,\n getEnvironmentPath,\n readEnvironment,\n} from '../../shared/workspace.js';\nimport { z } from 'zod';\n\nexport type Fallback = z.infer<typeof FallbackSchema>;\n\nfunction formatEnvironmentPrefix(\n prefix: string,\n replacements: { targetPath: string; executionCwd: string; envDir: string; envArgs: string }\n): string {\n const map: Record<string, string> = {\n '{WORKSPACE_DIR}': replacements.targetPath,\n '{AGENT_DIR}': replacements.executionCwd,\n '{ENV_DIR}': replacements.envDir,\n '{HOME_DIR}': process.env.HOME || '',\n '{ENV_ARGS}': replacements.envArgs,\n };\n return prefix.replace(\n /{(WORKSPACE_DIR|AGENT_DIR|ENV_DIR|HOME_DIR|ENV_ARGS)}/g,\n (match) => map[match] || match\n );\n}\n\nexport async function sandboxExecutionContext(\n initialCommand: string,\n env: Record<string, string>,\n agentSpecificEnvKeys: Set<string>,\n executionCwd: string,\n cwd: string\n): Promise<string> {\n let command = initialCommand;\n const activeEnvInfo = await getActiveEnvironmentInfo(executionCwd, cwd);\n if (!activeEnvInfo) return command;\n\n const activeEnvName = activeEnvInfo.name;\n const activeEnv = await readEnvironment(activeEnvName, cwd);\n\n if (activeEnv?.env) {\n for (const [key, value] of Object.entries(activeEnv.env)) {\n if (value === false) {\n delete env[key];\n agentSpecificEnvKeys.delete(key);\n } else {\n let interpolatedValue = String(value);\n interpolatedValue = interpolatedValue.replace(/\\{PATH\\}/g, process.env.PATH || '');\n interpolatedValue = interpolatedValue.replace(\n /\\{ENV_DIR\\}/g,\n getEnvironmentPath(activeEnvName, cwd)\n );\n interpolatedValue = interpolatedValue.replace(\n /\\{WORKSPACE_DIR\\}/g,\n activeEnvInfo.targetPath\n );\n env[key] = interpolatedValue;\n agentSpecificEnvKeys.add(key);\n }\n }\n }\n\n if (activeEnv?.prefix) {\n const envArgs = Array.from(agentSpecificEnvKeys)\n .map((key) => {\n if (activeEnv.envFormat) {\n return activeEnv.envFormat.replace('{key}', key);\n }\n return key;\n })\n .join(' ');\n\n const prefixReplaced = formatEnvironmentPrefix(activeEnv.prefix, {\n targetPath: activeEnvInfo.targetPath,\n executionCwd: executionCwd,\n envDir: getEnvironmentPath(activeEnvName, cwd),\n envArgs,\n });\n\n if (prefixReplaced.includes('{COMMAND}')) {\n command = prefixReplaced.replace('{COMMAND}', command);\n } else {\n command = `${prefixReplaced} ${command}`;\n }\n }\n\n return command;\n}\n","import type { RunCommandFn, RunCommandResult } from './types.js';\nimport type { Agent } from '../../shared/config.js';\n\nasync function runExtractionCommand(\n name: string,\n command: string,\n runCommand: RunCommandFn,\n cwd: string,\n env: Record<string, string>,\n mainResult: RunCommandResult,\n signal?: AbortSignal\n): Promise<{ result?: string; error?: string }> {\n try {\n console.log(`Executing extraction command (${name}): ${command}`);\n const res = await runCommand({\n command,\n cwd,\n env,\n stdin: mainResult.stdout,\n signal,\n });\n if (res.exitCode === 0) {\n return { result: res.stdout.trim() };\n } else {\n return { error: `${name} failed: ${res.stderr}` };\n }\n } catch (e) {\n return { error: `${name} error: ${(e as Error).message}` };\n }\n}\n\nexport async function extractMessageContent(\n context: { command: string; env: Record<string, string>; currentAgent: Agent },\n mainResult: RunCommandResult,\n runCommand: RunCommandFn,\n executionCwd: string,\n signal?: AbortSignal\n): Promise<{ result?: string; error?: string }> {\n if (!context.currentAgent.commands?.getMessageContent) return {};\n return runExtractionCommand(\n 'getMessageContent',\n context.currentAgent.commands.getMessageContent,\n runCommand,\n executionCwd,\n context.env,\n mainResult,\n signal\n );\n}\n\nexport async function extractSessionId(\n context: { command: string; env: Record<string, string>; currentAgent: Agent },\n mainResult: RunCommandResult,\n runCommand: RunCommandFn,\n executionCwd: string,\n signal?: AbortSignal\n): Promise<{ result?: string; error?: string }> {\n if (!context.currentAgent.commands?.getSessionId) return {};\n return runExtractionCommand(\n 'getSessionId',\n context.currentAgent.commands.getSessionId,\n runCommand,\n executionCwd,\n context.env,\n mainResult,\n signal\n );\n}\n","export function formatPendingMessages(payloads: string[]): string {\n return payloads.map((text) => `<message>\\n${text}\\n</message>`).join('\\n\\n');\n}\n\nexport function isNewSession(env: Record<string, string>): boolean {\n return env['SESSION_ID'] === undefined;\n}\n","import { emitTyping } from '../events.js';\nimport type { ExecutionResponse, Message, RunCommandFn } from './types.js';\nimport { type Fallback } from './agent-context.js';\nimport { extractMessageContent, extractSessionId } from './agent-extractors.js';\nimport type { AgentSession } from './agent-session.js';\nimport { isNewSession } from './utils.js';\n\nexport function calculateDelay(\n attempt: number,\n baseDelayMs: number,\n isFallback: boolean = false\n): number {\n const effectiveAttempt = isFallback ? attempt + 1 : attempt;\n if (effectiveAttempt <= 0) return 0;\n const delay = baseDelayMs * Math.pow(2, effectiveAttempt - 1);\n return Math.min(delay, 15000);\n}\n\nconst sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\n\nexport class AgentRunner {\n constructor(\n private readonly session: AgentSession,\n private readonly runCommand: RunCommandFn\n ) {}\n\n private async withTypingIndicator<T>(fn: () => Promise<T>): Promise<T> {\n const interval = setInterval(() => emitTyping(this.session.chatId), 5000);\n try {\n return await fn();\n } finally {\n clearInterval(interval);\n }\n }\n\n private *getExecutionAttempts() {\n const fallbacks = this.session.settings.fallbacks || [];\n const executionConfigs = [\n { fallback: undefined, retries: 0, delayMs: 1000 },\n ...fallbacks.map((f) => ({ fallback: f, retries: f.retries, delayMs: f.delayMs })),\n ];\n\n for (let configIdx = 0; configIdx < executionConfigs.length; configIdx++) {\n const config = executionConfigs[configIdx]!;\n const isFallbackConfig = configIdx > 0;\n\n for (let attempt = 0; attempt <= config.retries; attempt++) {\n yield {\n fallback: config.fallback,\n delay: calculateDelay(attempt, config.delayMs, isFallbackConfig),\n };\n }\n }\n }\n\n private async executeSingleAttempt(\n message: Message,\n fallback?: Fallback | undefined,\n signal?: AbortSignal | undefined\n ): Promise<{ success: boolean; response?: ExecutionResponse }> {\n const context = await this.session.buildExecutionContext(\n message.content,\n message.env,\n fallback\n );\n\n if (!context) return { success: false };\n\n const mainResult = await this.withTypingIndicator(() =>\n this.runCommand({\n command: context.command,\n cwd: this.session.workDirectory,\n env: context.env,\n signal,\n })\n );\n\n let success = mainResult.exitCode === 0;\n let finalContent = mainResult.stdout.trim();\n const additonalErrors = [];\n\n if (success && context.currentAgent.commands?.getMessageContent) {\n const extraction = await extractMessageContent(\n context,\n mainResult,\n this.runCommand,\n this.session.workDirectory,\n signal\n );\n if (extraction.error) additonalErrors.push(extraction.error);\n if (extraction.result !== undefined) finalContent = extraction.result.trim();\n if (!finalContent) success = false;\n }\n\n let extractedSessionId: string | undefined;\n\n if (success && isNewSession(message.env) && context.currentAgent.commands?.getSessionId) {\n const extraction = await extractSessionId(\n context,\n mainResult,\n this.runCommand,\n this.session.workDirectory,\n signal\n );\n if (extraction.error) additonalErrors.push(extraction.error);\n if (extraction.result) {\n extractedSessionId = extraction.result;\n }\n }\n\n return {\n success,\n response: {\n messageId: message.id,\n content: finalContent,\n command: context.command,\n cwd: this.session.workDirectory,\n extractedSessionId,\n result: {\n ...mainResult,\n stderr: [mainResult.stderr, ...additonalErrors].join('\\n\\n'),\n },\n },\n };\n }\n\n async executeWithFallbacks(\n message: Message,\n signal?: AbortSignal | undefined\n ): Promise<ExecutionResponse | undefined> {\n let lastResponse: ExecutionResponse | undefined;\n\n for (const attempt of this.getExecutionAttempts()) {\n if (attempt.delay > 0) {\n await this.session.logger.logCommandRetry({\n messageId: message.id,\n content: `Error running agent, retrying in ${Math.round(attempt.delay / 1000)} seconds...`,\n cwd: this.session.workDirectory,\n });\n await sleep(attempt.delay);\n }\n\n const attemptResult = await this.executeSingleAttempt(message, attempt.fallback, signal);\n\n lastResponse = attemptResult.response || lastResponse;\n if (attemptResult.success) {\n return lastResponse;\n }\n }\n\n return lastResponse;\n }\n}\n","import { spawn } from 'node:child_process';\nimport type { RunCommandFn } from '../agent/types.js';\n\nconst LOG_TO_TERMINAL = false;\n\nexport const runCommand: RunCommandFn = async ({\n command,\n cwd,\n env,\n stdin,\n signal,\n}: Parameters<RunCommandFn>[0] & { logToTerminal?: boolean }) => {\n return new Promise<{ stdout: string; stderr: string; exitCode: number }>((resolve, reject) => {\n console.log('RUN: ', command);\n const p = spawn(command, { shell: true, cwd, env, signal });\n\n if (stdin && p.stdin) {\n p.stdin.on('error', (err) => {\n if ((err as NodeJS.ErrnoException).code !== 'EPIPE') {\n console.error('stdin error:', err);\n }\n });\n p.stdin.write(stdin);\n p.stdin.end();\n }\n\n let stdout = '';\n let stderr = '';\n\n if (p.stdout) {\n p.stdout.on('data', (data) => {\n stdout += data.toString();\n if (LOG_TO_TERMINAL && !stdin) {\n process.stdout.write(data);\n }\n });\n }\n\n if (p.stderr) {\n p.stderr.on('data', (data) => {\n stderr += data.toString();\n if (LOG_TO_TERMINAL && !stdin) {\n process.stderr.write(data);\n }\n });\n }\n\n p.on('close', (code) => {\n resolve({ stdout, stderr, exitCode: code ?? 1 });\n });\n\n p.on('error', (err) => {\n if (err.name === 'AbortError') {\n reject(err);\n return;\n }\n resolve({ stdout: '', stderr: err.toString(), exitCode: 1 });\n });\n });\n};\n","import {\n appendMessage,\n getMessages,\n findLastMessage as findLastMessageFromStorage,\n type ChatMessage,\n type CommandLogMessage,\n type UserMessage,\n type SystemMessage,\n type AgentReplyMessage,\n type ToolMessage,\n type PolicyRequestMessage,\n type SubagentStatusMessage,\n} from '../chats.js';\nimport type { Logger } from './types.js';\n\nexport function createChatLogger(chatId: string, subagentId?: string): Logger {\n async function append<T extends ChatMessage>(msg: T): Promise<T> {\n const finalMsg = subagentId ? { ...msg, subagentId } : msg;\n await appendMessage(chatId, finalMsg);\n return finalMsg as T;\n }\n\n return {\n append,\n\n getMessages: async (limit?: number) => {\n const msgs = await getMessages(chatId);\n let filtered = msgs.filter((m) => m.subagentId === subagentId);\n if (limit !== undefined && limit > 0) {\n filtered = filtered.slice(-limit);\n }\n return filtered;\n },\n\n findLastMessage: async (predicate) => {\n return findLastMessageFromStorage(chatId, (msg: ChatMessage) => {\n if (msg.subagentId !== subagentId) return false;\n return predicate(msg);\n });\n },\n\n logUserMessage: async (msg) =>\n append({\n id: crypto.randomUUID(),\n role: 'user',\n content: msg,\n timestamp: new Date().toISOString(),\n } satisfies UserMessage),\n\n logCommandResult: async ({ messageId, content, command, cwd, result }) =>\n append({\n id: crypto.randomUUID(),\n role: 'command',\n content,\n timestamp: new Date().toISOString(),\n\n messageId,\n\n command,\n cwd,\n stdout: result.stdout,\n stderr: result.stderr,\n exitCode: result.exitCode,\n }),\n\n logSystemEvent: async ({ content }) =>\n append({\n id: crypto.randomUUID(),\n role: 'command',\n content,\n timestamp: new Date().toISOString(),\n\n messageId: crypto.randomUUID(),\n\n stderr: '',\n command: '',\n cwd: '',\n stdout: '',\n exitCode: 0,\n } satisfies CommandLogMessage),\n\n logAutomaticReply: async ({ messageId, content }) =>\n append({\n id: crypto.randomUUID(),\n role: 'system',\n content,\n timestamp: new Date().toISOString(),\n\n messageId,\n event: 'router',\n displayRole: 'agent',\n } satisfies SystemMessage),\n\n logCommandRetry: async ({ messageId, content, cwd }) =>\n append({\n id: crypto.randomUUID(),\n role: 'command',\n content,\n timestamp: new Date().toISOString(),\n\n messageId,\n\n // TODO remove these? Or include the actual command that was run?\n command: 'retry-delay',\n stderr: '',\n stdout: '',\n cwd,\n exitCode: 0,\n } satisfies CommandLogMessage),\n\n logSystemMessage: async ({ content, event, messageId, displayRole }) => {\n const msg: SystemMessage = {\n id: crypto.randomUUID(),\n role: 'system',\n content,\n event,\n timestamp: new Date().toISOString(),\n };\n if (messageId !== undefined) {\n msg.messageId = messageId;\n }\n if (displayRole !== undefined) {\n msg.displayRole = displayRole;\n }\n return append<SystemMessage>(msg);\n },\n\n logSubagentStatus: async ({ subagentId: targetSubagentId, status }) => {\n const msg: SubagentStatusMessage = {\n id: crypto.randomUUID(),\n role: 'subagent_status',\n content: `Subagent ${status}`,\n subagentId: targetSubagentId,\n status,\n timestamp: new Date().toISOString(),\n };\n return append<SubagentStatusMessage>(msg);\n },\n\n logAgentReply: async ({ content, files }) => {\n const msg: AgentReplyMessage = {\n id: crypto.randomUUID(),\n role: 'agent',\n content,\n timestamp: new Date().toISOString(),\n };\n if (files !== undefined) {\n msg.files = files;\n }\n return append<AgentReplyMessage>(msg);\n },\n\n logToolMessage: async ({ content, messageId, name, payload }) => {\n const msg: ToolMessage = {\n id: crypto.randomUUID(),\n role: 'tool',\n content,\n messageId,\n name,\n payload,\n timestamp: new Date().toISOString(),\n };\n return append<ToolMessage>(msg);\n },\n\n logPolicyRequestMessage: async ({\n content,\n messageId,\n requestId,\n commandName,\n args,\n status,\n }) => {\n const msg: PolicyRequestMessage = {\n id: crypto.randomUUID(),\n role: 'policy',\n content,\n messageId,\n requestId,\n commandName,\n args,\n status,\n timestamp: new Date().toISOString(),\n };\n return append<PolicyRequestMessage>(msg);\n },\n };\n}\n","export function applyEnvOverrides(\n targetEnv: Record<string, string>,\n overrides?: Record<string, string | boolean>\n): void {\n if (!overrides) return;\n\n for (const [key, val] of Object.entries(overrides)) {\n if (val === true && process.env[key] !== undefined) {\n targetEnv[key] = process.env[key];\n } else if (typeof val === 'string') {\n targetEnv[key] = val;\n }\n }\n}\n\nexport function getActiveEnvKeys(\n ...envs: (Record<string, string | boolean> | undefined)[]\n): Set<string> {\n const keys = new Set<string>();\n for (const env of envs) {\n if (!env) continue;\n Object.entries(env).forEach(([key, val]) => {\n if (val === true || typeof val === 'string') keys.add(key);\n });\n }\n return keys;\n}\n","import crypto from 'node:crypto';\nimport type { Settings } from '../shared/config.js';\n\n// In-memory secret generated on daemon startup.\n// Valid tokens will only last for the lifetime of the daemon process.\nconst DAEMON_SECRET = crypto.randomBytes(32);\n\nexport interface TokenPayload {\n chatId: string;\n agentId: string;\n sessionId: string;\n subagentId?: string;\n timestamp: number;\n}\n\nexport function generateToken(payload: TokenPayload): string {\n const payloadStr = Buffer.from(JSON.stringify(payload)).toString('base64');\n const hmac = crypto.createHmac('sha256', DAEMON_SECRET).update(payloadStr).digest('hex');\n return `${payloadStr}.${hmac}`;\n}\n\nexport function validateToken(token: string): TokenPayload | null {\n try {\n const parts = token.split('.');\n if (parts.length !== 2) return null;\n\n const [payloadStr, signature] = parts;\n if (!payloadStr || !signature) return null;\n\n const expectedHmac = crypto\n .createHmac('sha256', DAEMON_SECRET)\n .update(payloadStr)\n .digest('hex');\n\n const signatureBuffer = Buffer.from(signature, 'hex');\n const expectedHmacBuffer = Buffer.from(expectedHmac, 'hex');\n\n if (\n signatureBuffer.length !== expectedHmacBuffer.length ||\n !crypto.timingSafeEqual(signatureBuffer, expectedHmacBuffer)\n ) {\n return null;\n }\n\n const payloadJson = Buffer.from(payloadStr, 'base64').toString('utf8');\n return JSON.parse(payloadJson) as TokenPayload;\n } catch {\n return null;\n }\n}\n\nexport function getApiContext(settings?: Settings) {\n if (settings?.api === undefined) return null;\n let isApiEnabled = false;\n let apiHost = '127.0.0.1';\n let apiPort = 3000;\n let proxyHost: string | undefined = undefined;\n\n if (typeof settings.api === 'boolean') {\n isApiEnabled = settings.api;\n } else if (typeof settings.api === 'object') {\n isApiEnabled = true;\n apiHost = settings.api.host ?? '127.0.0.1';\n apiPort = settings.api.port ?? 3000;\n proxyHost = settings.api.proxy_host;\n }\n\n if (!isApiEnabled) return null;\n return { host: apiHost, port: apiPort, proxy_host: proxyHost };\n}\n","export interface AgentTask {\n id: string;\n rootChatId: string;\n dirPath: string;\n sessionId: string;\n text?: string;\n execute: (signal: AbortSignal) => Promise<void>;\n}\n\nclass ResourceLock {\n private resources = new Map<\n string,\n {\n activeWorkspace: string;\n count: number;\n waiters: Array<{\n workspaceId: string;\n resolve: () => void;\n reject: (err: Error) => void;\n }>;\n }\n >();\n\n async acquire(resourceId: string, workspaceId: string, signal?: AbortSignal): Promise<void> {\n if (signal?.aborted) {\n const error = new Error('Task aborted');\n error.name = 'AbortError';\n throw error;\n }\n\n const res = this.resources.get(resourceId);\n if (!res) {\n this.resources.set(resourceId, { activeWorkspace: workspaceId, count: 1, waiters: [] });\n return;\n }\n\n if (res.activeWorkspace === workspaceId) {\n // Allow re-entrancy for the same rootChatId (workspaceId) so that the\n // root agent and its subagents can run in parallel in the same directory.\n // This ensures the root agent remains available to coordinate its subagents,\n // assuming it will manage conflicts appropriately.\n // Note: This risks starvation if agents/subagents from this workspace never release the resource.\n res.count++;\n return;\n }\n\n return new Promise<void>((resolve, reject) => {\n const waiter = { workspaceId, resolve, reject };\n res!.waiters.push(waiter);\n\n if (signal) {\n const onAbort = () => {\n const idx = res!.waiters.indexOf(waiter);\n if (idx !== -1) {\n res!.waiters.splice(idx, 1);\n const error = new Error('Task aborted');\n error.name = 'AbortError';\n reject(error);\n }\n };\n signal.addEventListener('abort', onAbort);\n\n // Intercept resolve to clean up the listener\n waiter.resolve = () => {\n signal.removeEventListener('abort', onAbort);\n resolve();\n };\n // Intercept reject to clean up the listener\n waiter.reject = (err: Error) => {\n signal.removeEventListener('abort', onAbort);\n reject(err);\n };\n }\n });\n }\n\n release(resourceId: string, _workspaceId: string) {\n const res = this.resources.get(resourceId);\n if (!res) return;\n\n res.count--;\n if (res.count === 0) {\n if (res.waiters.length > 0) {\n const nextWorkspace = res.waiters[0]!.workspaceId;\n res.activeWorkspace = nextWorkspace;\n\n const remainingWaiters = [];\n for (const waiter of res.waiters) {\n if (waiter.workspaceId === nextWorkspace) {\n res.count++;\n waiter.resolve();\n } else {\n remainingWaiters.push(waiter);\n }\n }\n res.waiters = remainingWaiters;\n } else {\n this.resources.delete(resourceId);\n }\n }\n }\n}\n\nclass TaskQueue {\n private queue: Array<{\n task: AgentTask;\n resolve: () => void;\n reject: (err: unknown) => void;\n }> = [];\n private activeTask: { task: AgentTask; controller: AbortController } | null = null;\n private isProcessing = false;\n\n constructor(\n public readonly sessionId: string,\n private resourceLock: ResourceLock,\n private onEmpty: (sessionId: string) => void\n ) {}\n\n enqueue(task: AgentTask): Promise<void> {\n return new Promise((resolve, reject) => {\n this.queue.push({ task, resolve, reject });\n this.process();\n });\n }\n\n private async process() {\n if (this.isProcessing || this.activeTask || this.queue.length === 0) return;\n this.isProcessing = true;\n\n while (this.queue.length > 0) {\n const next = this.queue.shift()!;\n const controller = new AbortController();\n this.activeTask = { task: next.task, controller };\n\n let acquired = false;\n try {\n await this.resourceLock.acquire(next.task.dirPath, next.task.rootChatId, controller.signal);\n acquired = true;\n\n if (!controller.signal.aborted) {\n await next.task.execute(controller.signal);\n }\n next.resolve();\n } catch (err) {\n next.reject(err);\n } finally {\n if (acquired) {\n this.resourceLock.release(next.task.dirPath, next.task.rootChatId);\n }\n this.activeTask = null;\n }\n }\n\n this.isProcessing = false;\n this.onEmpty(this.sessionId);\n }\n\n abortAll() {\n const error = new Error('Task aborted');\n error.name = 'AbortError';\n\n if (this.activeTask) {\n this.activeTask.controller.abort(error);\n }\n\n for (const qTask of this.queue) {\n qTask.reject(error);\n }\n this.queue = [];\n }\n\n interruptAndExtract(): string[] {\n const payloads: string[] = [];\n\n const error = new Error('Task aborted');\n error.name = 'AbortError';\n\n if (this.activeTask) {\n if (this.activeTask.task.text !== undefined) {\n payloads.push(this.activeTask.task.text);\n }\n this.activeTask.controller.abort(error);\n }\n\n for (const qTask of this.queue) {\n if (qTask.task.text !== undefined) {\n payloads.push(qTask.task.text);\n }\n qTask.reject(error);\n }\n this.queue = [];\n\n return payloads;\n }\n\n extractPending(): string[] {\n const payloads: string[] = [];\n\n const error = new Error('Task extracted for batching');\n error.name = 'AbortError';\n\n for (const qTask of this.queue) {\n if (qTask.task.text !== undefined) {\n payloads.push(qTask.task.text);\n }\n qTask.reject(error);\n }\n this.queue = [];\n\n return payloads;\n }\n\n hasTasks(): boolean {\n return this.activeTask !== null || this.queue.length > 0;\n }\n}\n\nexport class TaskScheduler {\n private queues = new Map<string, TaskQueue>();\n private resourceLock = new ResourceLock();\n\n private getQueueKey(sessionId: string, rootChatId: string): string {\n return `${rootChatId}:${sessionId}`;\n }\n\n public schedule(task: AgentTask): Promise<void> {\n const key = this.getQueueKey(task.sessionId, task.rootChatId);\n let queue = this.queues.get(key);\n if (!queue) {\n queue = new TaskQueue(task.sessionId, this.resourceLock, () => {\n this.queues.delete(key);\n });\n this.queues.set(key, queue);\n }\n return queue.enqueue(task);\n }\n\n public hasTasks(sessionId: string): boolean {\n for (const queue of this.queues.values()) {\n if (queue.sessionId === sessionId && queue.hasTasks()) {\n return true;\n }\n }\n return false;\n }\n\n public extractPending(sessionId: string): string[] {\n const payloads: string[] = [];\n for (const queue of this.queues.values()) {\n if (queue.sessionId === sessionId) {\n payloads.push(...queue.extractPending());\n }\n }\n return payloads;\n }\n\n public abortTasks(sessionId: string): void {\n for (const queue of this.queues.values()) {\n if (queue.sessionId === sessionId) {\n queue.abortAll();\n }\n }\n }\n\n public interruptTasks(sessionId: string): string[] {\n const payloads: string[] = [];\n for (const queue of this.queues.values()) {\n if (queue.sessionId === sessionId) {\n payloads.push(...queue.interruptAndExtract());\n }\n }\n return payloads;\n }\n}\n\nexport const taskScheduler = new TaskScheduler();\n","import type { Agent, Settings } from '../../shared/config.js';\nimport { AgentRunner } from './agent-runner.js';\nimport type { Logger, Message } from './types.js';\nimport { runCommand } from '../utils/spawn.js';\nimport {\n getAgent,\n getWorkspaceRoot,\n readAgentSessionSettings,\n writeAgentSessionSettings,\n readSettings,\n resolveAgentWorkDir,\n} from '../../shared/workspace.js';\nimport { formatPendingMessages, isNewSession } from './utils.js';\nimport { createChatLogger } from './chat-logger.js';\nimport { sandboxExecutionContext, type Fallback } from './agent-context.js';\nimport { applyEnvOverrides, getActiveEnvKeys } from '../../shared/utils/env.js';\nimport { getApiContext, generateToken } from '../auth.js';\nimport { taskScheduler } from './task-scheduler.js';\nimport { randomUUID } from 'node:crypto';\n\nexport class AgentSession {\n public readonly agentId: string;\n public readonly sessionId: string;\n public readonly chatId: string;\n public readonly subagentId: string | undefined;\n public readonly settings: Agent;\n public readonly workspaceRoot: string;\n public readonly globalSettings: Settings | undefined;\n public readonly logger: Logger;\n\n constructor(config: {\n agentId: string;\n sessionId: string;\n chatId: string;\n subagentId?: string;\n settings: Agent;\n workspaceRoot: string;\n globalSettings: Settings | undefined;\n logger?: Logger;\n }) {\n this.agentId = config.agentId;\n this.sessionId = config.sessionId;\n this.chatId = config.chatId;\n this.subagentId = config.subagentId;\n this.settings = config.settings;\n this.workspaceRoot = config.workspaceRoot;\n this.globalSettings = config.globalSettings;\n\n this.logger = config.logger ?? createChatLogger(this.chatId, this.subagentId);\n }\n\n async buildExecutionContext(\n messageContent: string,\n routerEnv: Record<string, string>,\n fallback?: Fallback\n ): Promise<{ command: string; env: Record<string, string>; currentAgent: Agent } | null> {\n const currentAgent: Agent = {\n ...this.settings,\n commands: {\n ...this.settings.commands,\n ...(fallback?.commands || {}),\n },\n env: {\n ...this.settings.env,\n ...(this.subagentId && this.settings.subagentEnv ? this.settings.subagentEnv : {}),\n ...(fallback?.env || {}),\n },\n };\n\n let initialCommand = currentAgent.commands?.new ?? '';\n const env = {\n ...process.env,\n CLAW_CLI_MESSAGE: messageContent,\n } as Record<string, string>;\n\n applyEnvOverrides(env, currentAgent.env);\n\n if (!isNewSession(routerEnv) && currentAgent.commands?.append) {\n initialCommand = currentAgent.commands.append;\n }\n\n if (!initialCommand) {\n return null;\n }\n\n const agentSpecificEnvKeys = getActiveEnvKeys(currentAgent.env);\n agentSpecificEnvKeys.add('CLAW_CLI_MESSAGE');\n\n Object.assign(env, routerEnv);\n Object.keys(routerEnv).forEach((k) => agentSpecificEnvKeys.add(k));\n\n const apiCtx = getApiContext(this.globalSettings);\n if (apiCtx) {\n const proxyUrl = apiCtx.proxy_host\n ? `${apiCtx.proxy_host}:${apiCtx.port}`\n : `http://${apiCtx.host}:${apiCtx.port}`;\n\n if (currentAgent.apiUrlEnvVar) {\n env[currentAgent.apiUrlEnvVar] = proxyUrl;\n agentSpecificEnvKeys.add(currentAgent.apiUrlEnvVar);\n env['CLAW_LITE_URL_VAR'] = currentAgent.apiUrlEnvVar;\n agentSpecificEnvKeys.add('CLAW_LITE_URL_VAR');\n } else {\n env['CLAW_API_URL'] = proxyUrl;\n agentSpecificEnvKeys.add('CLAW_API_URL');\n }\n\n const token = generateToken({\n chatId: this.chatId,\n agentId: this.agentId,\n sessionId: this.sessionId,\n ...(this.subagentId ? { subagentId: this.subagentId } : {}),\n timestamp: Date.now(),\n });\n\n if (currentAgent.apiTokenEnvVar) {\n env[currentAgent.apiTokenEnvVar] = token;\n agentSpecificEnvKeys.add(currentAgent.apiTokenEnvVar);\n env['CLAW_LITE_API_VAR'] = currentAgent.apiTokenEnvVar;\n agentSpecificEnvKeys.add('CLAW_LITE_API_VAR');\n } else {\n env['CLAW_API_TOKEN'] = token;\n agentSpecificEnvKeys.add('CLAW_API_TOKEN');\n }\n }\n\n let command = initialCommand;\n command = await sandboxExecutionContext(\n command,\n env,\n agentSpecificEnvKeys,\n this.workDirectory,\n this.workspaceRoot\n );\n\n return { command, env, currentAgent };\n }\n\n createRunner(): AgentRunner {\n return new AgentRunner(this, runCommand);\n }\n\n get workDirectory(): string {\n return resolveAgentWorkDir(this.agentId, this.settings.directory, this.workspaceRoot);\n }\n\n stop() {\n taskScheduler.abortTasks(this.sessionId);\n }\n\n interrupt(message: Message): Message {\n const payloads = taskScheduler.interruptTasks(this.sessionId);\n\n if (payloads.length > 0) {\n // TODO: Figure out how to handle merging payloads when they have different env settings or other config.\n // Currently, we only preserve the text content and drop any specific configuration attached to individual messages.\n const pendingText = formatPendingMessages(payloads);\n return {\n ...message,\n content: `${pendingText}\\n\\n<message>\\n${message.content}\\n</message>`.trim(),\n };\n }\n return message;\n }\n\n async handleMessage(message: Message): Promise<void> {\n if (!message.content.trim()) {\n return;\n }\n\n await taskScheduler.schedule({\n id: `task-${this.agentId}-${randomUUID()}`,\n rootChatId: this.chatId,\n dirPath: this.workDirectory,\n sessionId: this.sessionId,\n text: message.content,\n execute: async (signal) => {\n // Refresh sessionSettings immediately before execution\n const sessionSettings = await readAgentSessionSettings(\n this.agentId,\n this.sessionId,\n this.workspaceRoot\n );\n // TODO: create a copy of the message first\n applyEnvOverrides(message.env, sessionSettings?.env);\n\n const runner = this.createRunner();\n const result = await runner.executeWithFallbacks(message, signal);\n if (!result) {\n // TODO: throw an error? Log an error?\n return;\n }\n\n if (result.extractedSessionId) {\n await writeAgentSessionSettings(\n this.agentId,\n this.sessionId,\n { env: { SESSION_ID: result.extractedSessionId } },\n this.workspaceRoot\n );\n }\n\n await this.logger.logCommandResult(result);\n\n if (!result.content.includes('NO_REPLY_NECESSARY')) {\n await this.logger.logAgentReply({ content: result.content });\n }\n },\n });\n }\n}\n\nexport async function createAgentSession(options: {\n chatId: string;\n agentId: string;\n sessionId: string;\n subagentId?: string;\n cwd: string;\n settings?: Settings | undefined;\n logger?: Logger;\n}) {\n // TODO: make it so that readSettings returns Settings|undefined\n const settings = options.settings ?? (await readSettings(options.cwd)) ?? undefined;\n const mergedAgent = await resolveMergedAgent(options.agentId, settings, options.cwd);\n const workspaceRoot = getWorkspaceRoot(options.cwd);\n\n return new AgentSession({\n agentId: options.agentId,\n sessionId: options.sessionId,\n chatId: options.chatId,\n ...(options.subagentId ? { subagentId: options.subagentId } : {}),\n settings: mergedAgent,\n workspaceRoot,\n globalSettings: settings,\n ...(options.logger ? { logger: options.logger } : {}),\n });\n}\n\nasync function resolveMergedAgent(\n agentId: string,\n settings: Settings | undefined,\n cwd: string\n): Promise<Agent> {\n let mergedAgent: Agent = settings?.defaultAgent || {};\n if (agentId !== 'default') {\n try {\n const customAgent = await getAgent(agentId, cwd);\n if (customAgent) {\n mergedAgent = {\n ...mergedAgent,\n ...customAgent,\n commands: { ...mergedAgent.commands, ...customAgent.commands },\n env: { ...mergedAgent.env, ...customAgent.env },\n };\n }\n } catch {\n // Fall back to default if agent not found\n }\n }\n return mergedAgent;\n}\n","import { executeRouterPipeline, resolveRouters } from './routers.js';\nimport type { RouterState } from './routers/types.js';\nimport { type ChatSettings, type Settings } from '../shared/config.js';\nimport { readChatSettings, writeChatSettings } from '../shared/workspace.js';\nimport { cronManager } from './cron.js';\nimport type { Message } from './agent/types.js';\nimport { createAgentSession } from './agent/agent-session.js';\nimport { createChatLogger } from './agent/chat-logger.js';\n\nexport { calculateDelay } from './agent/agent-runner.js';\n\nexport async function executeDirectMessage(\n chatId: string,\n state: RouterState,\n settings: Settings | undefined,\n cwd: string,\n noWait: boolean = false,\n userMessageContent?: string,\n subagentId?: string,\n systemEvent?:\n | 'cron'\n | 'policy_approved'\n | 'policy_rejected'\n | 'subagent_update'\n | 'router'\n | 'other',\n displayRole?: 'user' | 'agent'\n) {\n const logger = createChatLogger(chatId, subagentId);\n\n let msgId: string;\n if (systemEvent) {\n const sysMsg = await logger.logSystemMessage({\n content: userMessageContent ?? state.message,\n event: systemEvent,\n messageId: state.messageId,\n ...(displayRole ? { displayRole } : {}),\n });\n msgId = sysMsg.id;\n } else {\n const userMsg = await logger.logUserMessage(userMessageContent ?? state.message);\n msgId = userMsg.id;\n }\n\n if (state.reply) {\n await logger.logAutomaticReply({ messageId: msgId, content: state.reply });\n }\n\n if (!state.message.trim() && state.action !== 'stop' && state.action !== 'interrupt') {\n return;\n }\n\n // Load the agent\n const agentSession = await createAgentSession({\n chatId,\n agentId: state.agentId || 'default',\n sessionId: state.sessionId || 'default',\n ...(subagentId ? { subagentId } : {}),\n cwd,\n settings,\n logger,\n });\n let finalMessage: Message = {\n id: state.messageId,\n content: state.message,\n env: state.env ?? {},\n };\n\n // Process actions\n if (state.action === 'stop') {\n agentSession.stop();\n return;\n }\n if (state.action === 'interrupt') {\n finalMessage = agentSession.interrupt(finalMessage);\n }\n\n // Process message\n const taskPromise = agentSession.handleMessage(finalMessage);\n\n if (!noWait) {\n try {\n await taskPromise;\n } catch (err) {\n if (!(err instanceof Error && err.name === 'AbortError')) {\n throw err;\n }\n }\n } else {\n taskPromise.catch((err) => {\n if (err.name !== 'AbortError') {\n console.error('Task execution error:', err);\n }\n });\n }\n}\n\nexport async function getInitialRouterState(\n chatId: string,\n message: string,\n chatSettings: Partial<ChatSettings>,\n overrideAgentId?: string,\n overrideSessionId?: string\n): Promise<RouterState> {\n const agentId = overrideAgentId ?? chatSettings.defaultAgent ?? 'default';\n const sessionId = overrideSessionId ?? chatSettings.sessions?.[agentId] ?? 'default';\n const messageId = crypto.randomUUID();\n\n return {\n messageId,\n message,\n chatId,\n agentId,\n sessionId,\n env: {},\n };\n}\n\nexport async function handleUserMessage(\n chatId: string,\n message: string,\n settings: Settings | undefined,\n cwd: string = process.cwd(),\n noWait: boolean = false,\n sessionId?: string,\n overrideAgentId?: string\n): Promise<void> {\n const chatSettings = (await readChatSettings(chatId, cwd)) ?? {};\n\n if (overrideAgentId && chatSettings.defaultAgent !== overrideAgentId) {\n chatSettings.defaultAgent = overrideAgentId;\n await writeChatSettings(chatId, chatSettings, cwd);\n }\n\n const initialState = await getInitialRouterState(\n chatId,\n message,\n chatSettings,\n overrideAgentId,\n sessionId\n );\n\n const routers = chatSettings.routers ?? settings?.routers ?? [];\n const resolvedRouters = resolveRouters(routers, true);\n const finalState = await executeRouterPipeline(initialState, resolvedRouters);\n\n await applyRouterStateUpdates(chatId, cwd, finalState, chatSettings, initialState.agentId);\n\n await executeDirectMessage(chatId, finalState, settings, cwd, noWait, message);\n}\n\nexport async function applyRouterStateUpdates(\n chatId: string,\n cwd: string,\n finalState: RouterState,\n chatSettings: ChatSettings,\n initialAgent: string | undefined\n) {\n const finalAgentId = finalState.agentId;\n const finalSessionId = finalState.sessionId ?? crypto.randomUUID();\n const currentAgentId = finalAgentId ?? chatSettings.defaultAgent ?? 'default';\n\n let settingsChanged = false;\n if (finalAgentId && finalAgentId !== initialAgent) {\n chatSettings.defaultAgent = finalAgentId;\n settingsChanged = true;\n }\n\n if (finalState.nextSessionId) {\n chatSettings.sessions = chatSettings.sessions || {};\n chatSettings.sessions[currentAgentId] = finalState.nextSessionId;\n settingsChanged = true;\n }\n\n if (finalState.jobs) {\n chatSettings.jobs = chatSettings.jobs || [];\n\n if (finalState.jobs.remove?.length) {\n const removeSet = new Set(finalState.jobs.remove);\n for (const jobId of finalState.jobs.remove) {\n cronManager.unscheduleJob(chatId, jobId);\n }\n chatSettings.jobs = chatSettings.jobs.filter((job) => !removeSet.has(job.id));\n settingsChanged = true;\n }\n\n if (finalState.jobs.add?.length) {\n const addMap = new Map(finalState.jobs.add.map((job) => [job.id, job]));\n for (const job of finalState.jobs.add) {\n cronManager.scheduleJob(chatId, job);\n }\n chatSettings.jobs = chatSettings.jobs.filter((job) => !addMap.has(job.id));\n chatSettings.jobs.push(...finalState.jobs.add);\n settingsChanged = true;\n }\n }\n\n if (settingsChanged) {\n await writeChatSettings(chatId, chatSettings, cwd);\n }\n\n // Ensure finalSessionId is set on state so extractDirectState gets it.\n if (finalState.sessionId === undefined) {\n finalState.sessionId = finalSessionId;\n }\n if (finalState.agentId === undefined) {\n finalState.agentId = currentAgentId;\n }\n}\n","// @ts-expect-error - node-schedule types are missing\nimport schedule from 'node-schedule';\nimport { listChats } from '../shared/chats.js';\nimport { readChatSettings, writeChatSettings } from '../shared/workspace.js';\nimport { executeDirectMessage, getInitialRouterState, applyRouterStateUpdates } from './message.js';\nimport { executeRouterPipeline, resolveRouters } from './routers.js';\nimport type { CronJob, Settings } from '../shared/config.js';\nimport fs from 'node:fs/promises';\nimport { getSettingsPath } from '../shared/workspace.js';\nimport { applyEnvOverrides } from '../shared/utils/env.js';\n\nexport class CronManager {\n private jobs = new Map<string, schedule.Job>();\n\n private getJobKey(chatId: string, jobId: string) {\n return `${chatId}::${jobId}`;\n }\n\n async init() {\n const chats = await listChats();\n for (const chatId of chats) {\n const settings = await readChatSettings(chatId);\n if (settings?.jobs) {\n for (const job of settings.jobs) {\n try {\n this.scheduleJob(chatId, job);\n } catch (err) {\n console.error(\n `Failed to initialize job ${job.id} for chat ${chatId}:`,\n err instanceof Error ? err.message : err\n );\n }\n }\n }\n }\n }\n\n scheduleJob(chatId: string, job: CronJob) {\n this.unscheduleJob(chatId, job.id);\n\n let rule: string | Date;\n let isOneOff = false;\n\n if ('cron' in job.schedule) {\n rule = (job.schedule as { cron: string }).cron;\n } else if ('every' in job.schedule) {\n const everyStr = (job.schedule as { every: string }).every;\n const match = everyStr.match(/^(\\d+)\\s*(m|min|minutes?|h|hours?|d|days?)$/i);\n if (match) {\n const val = parseInt(match[1]!, 10);\n const unit = match[2]!.toLowerCase();\n if (unit.startsWith('m')) {\n rule = `*/${val} * * * *`;\n } else if (unit.startsWith('h')) {\n rule = `0 */${val} * * *`;\n } else if (unit.startsWith('d')) {\n rule = `0 0 */${val} * *`;\n } else {\n rule = everyStr;\n }\n } else {\n rule = everyStr;\n }\n } else if ('at' in job.schedule) {\n const atStr = (job.schedule as { at: string }).at;\n const match = atStr.match(/^(\\d+)\\s*(m|min|minutes?|h|hours?|d|days?|s|sec|seconds?)$/i);\n if (match) {\n const val = parseInt(match[1]!, 10);\n const unit = match[2]!.toLowerCase();\n let ms = 0;\n if (unit.startsWith('s')) ms = val * 1000;\n else if (unit.startsWith('m')) ms = val * 60 * 1000;\n else if (unit.startsWith('h')) ms = val * 60 * 60 * 1000;\n else if (unit.startsWith('d')) ms = val * 24 * 60 * 60 * 1000;\n rule = new Date(Date.now() + ms);\n } else {\n rule = new Date(atStr);\n if (isNaN(rule.getTime())) {\n throw new Error(`Invalid date format for 'at' schedule: ${atStr}`);\n }\n }\n isOneOff = true;\n } else {\n console.warn(`Unknown schedule format for job ${job.id}`);\n return;\n }\n\n try {\n const scheduledJob = schedule.scheduleJob(rule, async () => {\n await this.executeJob(chatId, job, isOneOff);\n });\n if (scheduledJob) {\n this.jobs.set(this.getJobKey(chatId, job.id), scheduledJob);\n }\n } catch (err) {\n console.error(`Failed to schedule job ${job.id} for chat ${chatId}:`, err);\n }\n }\n\n unscheduleJob(chatId: string, jobId: string) {\n const key = this.getJobKey(chatId, jobId);\n const job = this.jobs.get(key);\n if (job) {\n job.cancel();\n this.jobs.delete(key);\n }\n }\n\n private async executeJob(chatId: string, job: CronJob, isOneOff: boolean) {\n try {\n const settingsPath = getSettingsPath();\n let globalSettings: Settings | undefined;\n try {\n const settingsStr = await fs.readFile(settingsPath, 'utf8');\n globalSettings = JSON.parse(settingsStr) as Settings;\n } catch {\n globalSettings = undefined;\n }\n\n const overrideSessionId = job.session?.type === 'new' ? crypto.randomUUID() : job.session?.id;\n const chatSettings = (await readChatSettings(chatId, process.cwd())) ?? {};\n let routerState = await getInitialRouterState(\n chatId,\n job.message,\n chatSettings,\n job.agentId,\n overrideSessionId\n );\n\n if (job.env !== undefined) {\n routerState.env = routerState.env || {};\n applyEnvOverrides(routerState.env, job.env);\n }\n\n const currentAgentId = job.agentId ?? chatSettings.defaultAgent ?? 'default';\n const currentActiveSession = chatSettings.sessions?.[currentAgentId];\n const isOutdatedSession =\n job.session?.type === 'existing' &&\n currentActiveSession !== undefined &&\n currentActiveSession !== job.session.id;\n\n if (job.reply !== undefined && !isOutdatedSession) routerState.reply = job.reply;\n if (job.nextSessionId !== undefined && !isOutdatedSession)\n routerState.nextSessionId = job.nextSessionId;\n if (job.action !== undefined) routerState.action = job.action;\n if (job.jobs !== undefined) routerState.jobs = job.jobs;\n\n const routers = chatSettings.routers ?? globalSettings?.routers ?? [];\n const resolvedRouters = resolveRouters(routers, false);\n const initialState = { ...routerState };\n routerState = await executeRouterPipeline(routerState, resolvedRouters);\n\n await applyRouterStateUpdates(\n chatId,\n process.cwd(),\n routerState,\n chatSettings,\n initialState.agentId\n );\n\n await executeDirectMessage(\n chatId,\n routerState,\n globalSettings,\n process.cwd(),\n false,\n job.message,\n undefined,\n 'cron'\n );\n\n if (isOneOff) {\n const chatSettings = await readChatSettings(chatId);\n if (chatSettings && chatSettings.jobs) {\n chatSettings.jobs = chatSettings.jobs.filter((j) => j.id !== job.id);\n await writeChatSettings(chatId, chatSettings);\n }\n this.unscheduleJob(chatId, job.id);\n }\n } catch (err) {\n console.error(`Error executing cron job ${job.id} for chat ${chatId}:`, err);\n }\n }\n}\n\nexport const cronManager = new CronManager();\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { TRPCError } from '@trpc/server';\nimport { pathIsInsideDir } from '../../shared/utils/fs.js';\nimport {\n getAgent,\n getClawminiDir,\n readChatSettings,\n writeChatSettings,\n} from '../../shared/workspace.js';\nimport { cronManager } from '../cron.js';\nimport type { z } from 'zod';\nimport type { CronJobSchema } from '../../shared/config.js';\n\nexport async function getUniquePath(p: string): Promise<string> {\n let currentPath = p;\n let counter = 1;\n while (true) {\n try {\n await fs.stat(currentPath);\n const ext = path.extname(p);\n const base = path.basename(p, ext);\n currentPath = path.join(path.dirname(p), `${base}-${counter}${ext}`);\n counter++;\n } catch {\n return currentPath;\n }\n }\n}\n\nexport async function resolveAgentDir(\n agentId: string | undefined | null,\n workspaceRoot: string\n): Promise<string> {\n if (agentId && agentId !== 'default') {\n try {\n const agent = await getAgent(agentId, workspaceRoot);\n if (agent && agent.directory) {\n return path.resolve(workspaceRoot, agent.directory);\n }\n } catch (err: unknown) {\n console.warn(`Could not load custom agent '${agentId}' for resolving directory:`, err);\n }\n return path.resolve(workspaceRoot, agentId);\n }\n return workspaceRoot;\n}\n\nexport async function getAgentFilesDir(\n agentId: string | undefined,\n chatId: string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n settings: any,\n workspaceRoot: string\n): Promise<string> {\n const chatSettings = (await readChatSettings(chatId)) ?? {};\n const targetAgentId = agentId ?? chatSettings.defaultAgent ?? 'default';\n let agentFilesDir = settings?.defaultAgent?.files || './attachments';\n const agentDir = await resolveAgentDir(targetAgentId, workspaceRoot);\n\n if (targetAgentId !== 'default') {\n try {\n const customAgent = await getAgent(targetAgentId, workspaceRoot);\n if (customAgent?.files) {\n agentFilesDir = customAgent.files;\n }\n } catch (err: unknown) {\n console.warn(\n `Could not load custom agent '${targetAgentId}' for resolving files directory:`,\n err\n );\n }\n }\n\n return path.resolve(agentDir, agentFilesDir);\n}\n\nexport async function validateAttachments(files: string[]): Promise<void> {\n const tmpDir = path.join(getClawminiDir(process.cwd()), 'tmp');\n\n for (const file of files) {\n const absoluteFile = path.resolve(process.cwd(), file);\n if (!pathIsInsideDir(absoluteFile, tmpDir)) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'File must be inside the temporary directory.',\n });\n }\n try {\n await fs.access(absoluteFile);\n } catch {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: `File does not exist: ${file}`,\n });\n }\n }\n}\n\nexport async function validateLogFile(\n file: string,\n agentDir: string,\n workspaceRoot: string\n): Promise<string> {\n const resolvedPath = path.resolve(agentDir, file);\n\n if (!pathIsInsideDir(resolvedPath, agentDir, { allowSameDir: true })) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'File must be within the agent workspace.',\n });\n }\n\n try {\n await fs.access(resolvedPath);\n } catch {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: `File does not exist: ${file}`,\n });\n }\n\n return path.relative(workspaceRoot, resolvedPath);\n}\n\nexport async function listCronJobsShared(chatId: string) {\n const settings = await readChatSettings(chatId);\n return settings?.jobs ?? [];\n}\n\nexport async function addCronJobShared(chatId: string, job: z.infer<typeof CronJobSchema>) {\n const settings = (await readChatSettings(chatId)) || {};\n const cronJobs = settings.jobs ?? [];\n const existingIndex = cronJobs.findIndex((j) => j.id === job.id);\n if (existingIndex >= 0) {\n cronJobs[existingIndex] = job;\n } else {\n cronJobs.push(job);\n }\n settings.jobs = cronJobs;\n await writeChatSettings(chatId, settings);\n cronManager.scheduleJob(chatId, job);\n return { success: true };\n}\n\nexport async function deleteCronJobShared(chatId: string, id: string) {\n const settings = await readChatSettings(chatId);\n if (!settings || !settings.jobs) {\n return { success: true, deleted: false };\n }\n const initialLength = settings.jobs.length;\n settings.jobs = settings.jobs.filter((j) => j.id !== id);\n if (settings.jobs.length !== initialLength) {\n await writeChatSettings(chatId, settings);\n cronManager.unscheduleJob(chatId, id);\n return { success: true, deleted: true };\n }\n return { success: true, deleted: false };\n}\n","import { z } from 'zod';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { TRPCError } from '@trpc/server';\nimport { pathIsInsideDir } from '../../shared/utils/fs.js';\nimport { on } from 'node:events';\nimport { daemonEvents, DAEMON_EVENT_MESSAGE_APPENDED, DAEMON_EVENT_TYPING } from '../events.js';\nimport {\n getSettingsPath,\n readChatSettings,\n writeChatSettings,\n getWorkspaceRoot,\n listAgents,\n} from '../../shared/workspace.js';\nimport { CronJobSchema } from '../../shared/config.js';\nimport { handleUserMessage } from '../message.js';\nimport { getDefaultChatId, getMessages as fetchMessages, listChats, createChat } from '../chats.js';\nimport { apiProcedure, publicProcedure, router } from './trpc.js';\nimport {\n getUniquePath,\n resolveAgentDir,\n getAgentFilesDir,\n validateAttachments,\n listCronJobsShared,\n addCronJobShared,\n deleteCronJobShared,\n} from './router-utils.js';\n\nexport const sendMessage = apiProcedure\n .input(\n z.object({\n type: z.literal('send-message'),\n client: z.literal('cli'),\n data: z.object({\n message: z.string(),\n chatId: z.string().optional(),\n sessionId: z.string().optional(),\n agentId: z.string().optional(),\n noWait: z.boolean().optional(),\n files: z.array(z.string()).optional(),\n adapter: z.string().optional(),\n }),\n })\n )\n .mutation(async ({ input }) => {\n let message = input.data.message;\n const chatId = input.data.chatId ?? (await getDefaultChatId());\n const noWait = input.data.noWait ?? false;\n const sessionId = input.data.sessionId;\n const agentId = input.data.agentId;\n const settingsPath = getSettingsPath();\n\n let settings;\n try {\n const settingsStr = await fs.readFile(settingsPath, 'utf8');\n settings = JSON.parse(settingsStr);\n } catch (err) {\n throw new Error(`Failed to read settings from ${settingsPath}: ${err}`, { cause: err });\n }\n\n const files = input.data.files;\n if (files && files.length > 0) {\n const workspaceRoot = getWorkspaceRoot(process.cwd());\n const chatSettings = (await readChatSettings(chatId)) ?? {};\n const targetAgentId = agentId ?? chatSettings.defaultAgent ?? 'default';\n const agentDir = await resolveAgentDir(targetAgentId, workspaceRoot);\n const absoluteFilesDir = await getAgentFilesDir(agentId, chatId, settings, workspaceRoot);\n\n const adapterNamespace = input.data.adapter || 'cli';\n const targetDir = path.join(absoluteFilesDir, adapterNamespace);\n\n if (!pathIsInsideDir(targetDir, workspaceRoot, { allowSameDir: true })) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'Target directory must be within the workspace.',\n });\n }\n\n await validateAttachments(files);\n\n await fs.mkdir(targetDir, { recursive: true });\n\n const finalPaths: string[] = [];\n for (const file of files) {\n const fileName = path.basename(file);\n const targetPath = await getUniquePath(path.join(targetDir, fileName));\n\n try {\n await fs.rename(file, targetPath);\n } catch {\n await fs.copyFile(file, targetPath);\n await fs.unlink(file);\n }\n\n finalPaths.push(path.relative(agentDir, targetPath));\n }\n\n const fileList = `Attached files:\\n${finalPaths.map((p) => `- ${p}`).join('\\n')}`;\n message = message ? `${message}\\n\\n${fileList}` : fileList;\n }\n\n await handleUserMessage(chatId, message, settings, undefined, noWait, sessionId, agentId);\n\n return { success: true };\n });\n\nexport const getMessages = apiProcedure\n .input(z.object({ chatId: z.string().optional(), limit: z.number().optional() }))\n .query(async ({ input }) => {\n const chatId = input.chatId ?? (await getDefaultChatId());\n return fetchMessages(chatId, input.limit);\n });\n\nexport const waitForMessages = apiProcedure\n .input(\n z.object({\n chatId: z.string().optional(),\n lastMessageId: z.string().optional(),\n })\n )\n .subscription(async function* ({ input, signal }) {\n const chatId = input.chatId ?? (await getDefaultChatId());\n\n // 1. Check if there are already new messages\n if (input.lastMessageId) {\n const messages = await fetchMessages(chatId);\n const lastIndex = messages.findIndex((m) => m.id === input.lastMessageId);\n if (lastIndex !== -1 && lastIndex < messages.length - 1) {\n yield messages.slice(lastIndex + 1);\n }\n }\n\n // 2. Listen for new messages\n try {\n for await (const [event] of on(daemonEvents, DAEMON_EVENT_MESSAGE_APPENDED, { signal })) {\n if (event.chatId === chatId) {\n yield [event.message];\n }\n }\n } catch (err) {\n if (err instanceof Error && err.name === 'AbortError') {\n return;\n }\n throw err;\n }\n });\n\nexport const waitForTyping = apiProcedure\n .input(\n z.object({\n chatId: z.string().optional(),\n })\n )\n .subscription(async function* ({ input, signal }) {\n const chatId = input.chatId ?? (await getDefaultChatId());\n\n try {\n for await (const [event] of on(daemonEvents, DAEMON_EVENT_TYPING, { signal })) {\n if (event.chatId === chatId) {\n yield event;\n }\n }\n } catch (err) {\n if (err instanceof Error && err.name === 'AbortError') {\n return;\n }\n throw err;\n }\n });\n\nexport const ping = publicProcedure.query(() => {\n return { status: 'ok' };\n});\n\nexport const shutdown = publicProcedure.mutation(() => {\n // Schedule a shutdown shortly after the response is sent\n setTimeout(() => {\n console.log('Shutting down daemon...');\n process.kill(process.pid, 'SIGTERM');\n }, 100);\n return { success: true };\n});\n\nexport const userListCronJobs = apiProcedure\n .input(z.object({ chatId: z.string().optional() }))\n .query(async ({ input }) => {\n const chatId = input.chatId ?? (await getDefaultChatId());\n return listCronJobsShared(chatId);\n });\n\nexport const getChats = apiProcedure.query(async () => {\n return listChats();\n});\n\nexport const getAgents = apiProcedure.query(async () => {\n return listAgents();\n});\n\nexport const userCreateChat = apiProcedure\n .input(z.object({ chatId: z.string(), agent: z.string().optional() }))\n .mutation(async ({ input }) => {\n await createChat(input.chatId);\n if (input.agent) {\n await writeChatSettings(input.chatId, { defaultAgent: input.agent });\n }\n return { success: true, chatId: input.chatId };\n });\n\nexport const userAddCronJob = apiProcedure\n .input(z.object({ chatId: z.string().optional(), job: CronJobSchema }))\n .mutation(async ({ input }) => {\n const chatId = input.chatId ?? (await getDefaultChatId());\n return addCronJobShared(chatId, input.job);\n });\n\nexport const userDeleteCronJob = apiProcedure\n .input(z.object({ chatId: z.string().optional(), id: z.string() }))\n .mutation(async ({ input }) => {\n const chatId = input.chatId ?? (await getDefaultChatId());\n return deleteCronJobShared(chatId, input.id);\n });\n\nexport const userRouter = router({\n sendMessage,\n getMessages,\n waitForMessages,\n waitForTyping,\n ping,\n shutdown,\n listCronJobs: userListCronJobs,\n addCronJob: userAddCronJob,\n deleteCronJob: userDeleteCronJob,\n getChats,\n getAgents,\n createChat: userCreateChat,\n});\n\nexport type UserRouter = typeof userRouter;\n","import { RequestStore, generateRandomAlphaNumericString } from './request-store.js';\nimport { createSnapshot, interpolateArgs } from './policy-utils.js';\nimport type { PolicyRequest } from '../shared/policies.js';\n\nexport class PolicyRequestService {\n private store: RequestStore;\n private maxPending: number;\n private agentDir: string;\n private snapshotDir: string;\n\n constructor(store: RequestStore, agentDir: string, snapshotDir: string, maxPending = 100) {\n this.store = store;\n this.agentDir = agentDir;\n this.snapshotDir = snapshotDir;\n this.maxPending = maxPending;\n }\n\n async createRequest(\n commandName: string,\n args: string[],\n fileMappings: Record<string, string>,\n chatId: string,\n agentId: string,\n skipSave: boolean = false,\n subagentId?: string\n ): Promise<PolicyRequest> {\n const allRequests = await this.store.list();\n const pendingCount = allRequests.filter((r) => r.state === 'Pending').length;\n\n if (pendingCount >= this.maxPending) {\n throw new Error(`Maximum number of pending requests (${this.maxPending}) reached.`);\n }\n\n const snapshotMappings: Record<string, string> = {};\n\n for (const [key, requestedPath] of Object.entries(fileMappings)) {\n snapshotMappings[key] = await createSnapshot(requestedPath, this.agentDir, this.snapshotDir);\n }\n\n let id = '';\n do {\n id = generateRandomAlphaNumericString(3);\n } while (allRequests.some((r) => r.id === id));\n\n const request: PolicyRequest = {\n id,\n commandName,\n args,\n fileMappings: snapshotMappings,\n state: skipSave ? 'Approved' : 'Pending',\n createdAt: Date.now(),\n chatId,\n agentId,\n ...(subagentId ? { subagentId } : {}),\n };\n\n if (!skipSave) {\n await this.store.save(request);\n }\n\n return request;\n }\n\n getInterpolatedArgs(request: PolicyRequest): string[] {\n return interpolateArgs(request.args, request.fileMappings);\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport { updateChatSettings, readChatSettings } from '../../shared/workspace.js';\nimport { executeDirectMessage, applyRouterStateUpdates } from '../message.js';\nimport { executeRouterPipeline, resolveRouters } from '../routers.js';\nimport type { RouterState } from '../routers/types.js';\nimport { createChatLogger } from '../agent/chat-logger.js';\nimport type { ChatSettings } from '../../shared/config.js';\nimport { taskScheduler } from '../agent/task-scheduler.js';\n\nexport function getSubagentDepth(settings: ChatSettings, parentId: string | undefined): number {\n let depth = 0;\n let currentParentId = parentId;\n while (currentParentId && settings.subagents?.[currentParentId]) {\n depth++;\n currentParentId = settings.subagents[currentParentId]?.parentId;\n }\n return depth;\n}\n\nexport async function executeSubagent(\n chatId: string,\n subagentId: string,\n agentId: string,\n sessionId: string,\n prompt: string,\n isAsync: boolean | undefined,\n parentTokenPayload: { agentId?: string; subagentId?: string; sessionId?: string },\n workspaceRoot: string\n) {\n try {\n const settings = (await readChatSettings(chatId)) || {};\n const routers = settings.routers ?? [];\n const resolvedRouters = resolveRouters(routers, false);\n\n let routerState: RouterState = {\n messageId: randomUUID(),\n message: prompt,\n chatId,\n agentId,\n sessionId,\n env: {},\n };\n\n const initialState = { ...routerState };\n routerState = await executeRouterPipeline(routerState, resolvedRouters);\n\n await applyRouterStateUpdates(\n chatId,\n workspaceRoot,\n routerState,\n settings,\n initialState.agentId\n );\n\n await executeDirectMessage(\n chatId,\n routerState,\n undefined, // settings\n workspaceRoot,\n false, // noWait\n undefined, // userMessageContent\n subagentId // subagentId\n );\n\n if (taskScheduler.hasTasks(sessionId)) {\n return;\n }\n\n // Update status\n await updateChatSettings(chatId, (finalSettings) => {\n if (finalSettings.subagents?.[subagentId]) {\n finalSettings.subagents[subagentId]!.status = 'completed';\n }\n return finalSettings;\n });\n\n const logger = createChatLogger(chatId, subagentId);\n\n // Emit debug message to wake up waiters\n await logger.logSubagentStatus({ subagentId, status: 'completed' });\n\n if (isAsync) {\n const lastLogMessage = await logger.findLastMessage(\n (m) => m.role === 'agent' || m.displayRole === 'agent'\n );\n let outputContent = '';\n if (lastLogMessage && 'content' in lastLogMessage) {\n outputContent = `\\n\\n<subagent_output>\\n${lastLogMessage.content}\\n</subagent_output>`;\n }\n\n console.log(\n 'Notifying parent',\n chatId,\n parentTokenPayload?.agentId,\n parentTokenPayload?.subagentId\n );\n // TODO: We need to overhaul the log system in general, and should not try to do it in this PR.\n // Currently, if the parent is the root agent, this notification is logged as a normal user message\n // and appears in the chat UI, violating the PRD requirement to hide orchestration.\n await executeDirectMessage(\n chatId,\n {\n messageId: randomUUID(),\n message: `<notification>Subagent ${subagentId} completed.</notification>${outputContent}`,\n chatId,\n agentId: parentTokenPayload?.agentId || 'default',\n ...(parentTokenPayload?.subagentId ? { subagentId: parentTokenPayload.subagentId } : {}),\n sessionId: parentTokenPayload?.sessionId || 'default',\n env: {},\n },\n undefined,\n workspaceRoot,\n true,\n undefined,\n parentTokenPayload?.subagentId,\n 'subagent_update'\n );\n }\n } catch {\n // TODO: Wrap this in a safe try-catch to prevent unhandled promise rejections crashing the daemon if disk errors occur\n await updateChatSettings(chatId, (errSettings) => {\n if (errSettings.subagents?.[subagentId]) {\n errSettings.subagents[subagentId]!.status = 'failed';\n }\n return errSettings;\n });\n const logger = createChatLogger(chatId, subagentId);\n await logger.logSubagentStatus({ subagentId, status: 'failed' });\n }\n}\n","import { z } from 'zod';\nimport { randomUUID } from 'node:crypto';\nimport { TRPCError } from '@trpc/server';\nimport { getWorkspaceRoot, readChatSettings, updateChatSettings } from '../../shared/workspace.js';\nimport { apiProcedure } from './trpc.js';\nimport { createChatLogger } from '../agent/chat-logger.js';\nimport { on } from 'node:events';\nimport { daemonEvents, DAEMON_EVENT_MESSAGE_APPENDED } from '../events.js';\nimport { createAgentSession } from '../agent/agent-session.js';\nimport { executeSubagent, getSubagentDepth } from './subagent-utils.js';\nimport type { SubagentTracker } from '../../shared/config.js';\n\nconst MAX_SUBAGENT_DEPTH = 2;\n\nexport const subagentSpawn = apiProcedure\n .input(\n z.object({\n subagentId: z.string().optional(),\n targetAgentId: z.string().optional(),\n prompt: z.string(),\n async: z.boolean().optional(),\n })\n )\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n const parentAgentId = ctx.tokenPayload.agentId;\n const parentId = ctx.tokenPayload.subagentId;\n\n const id = input.subagentId || randomUUID();\n const sessionId = randomUUID();\n const agentId = input.targetAgentId || parentAgentId;\n let depth = 0;\n\n await updateChatSettings(chatId, (settings) => {\n settings.subagents = settings.subagents || {};\n\n depth = getSubagentDepth(settings, parentId);\n if (depth >= MAX_SUBAGENT_DEPTH) {\n throw new TRPCError({ code: 'BAD_REQUEST', message: 'Max subagent depth reached' });\n }\n\n // Make sure the id does not already exist\n if (settings.subagents[id]) {\n throw new TRPCError({ code: 'BAD_REQUEST', message: 'Subagent ID already exists' });\n }\n\n settings.subagents[id] = {\n id,\n agentId,\n sessionId,\n createdAt: new Date().toISOString(),\n status: 'active',\n parentId,\n };\n\n return settings;\n });\n\n const workspaceRoot = getWorkspaceRoot(process.cwd());\n\n const isAsync = input.async ?? depth === 0;\n\n // Execute asynchronously\n executeSubagent(\n chatId,\n id,\n agentId,\n sessionId,\n input.prompt,\n isAsync,\n ctx.tokenPayload,\n workspaceRoot\n );\n\n return { id, depth, isAsync };\n });\n\nexport const subagentSend = apiProcedure\n .input(\n z.object({\n subagentId: z.string(),\n prompt: z.string(),\n async: z.boolean().optional(),\n })\n )\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n\n let sub: SubagentTracker | undefined;\n\n await updateChatSettings(chatId, (settings) => {\n if (!settings.subagents?.[input.subagentId]) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Subagent not found' });\n }\n\n sub = settings.subagents[input.subagentId];\n sub!.status = 'active';\n return settings;\n });\n\n const workspaceRoot = getWorkspaceRoot(process.cwd());\n\n // Execute asynchronously\n executeSubagent(\n chatId,\n sub!.id,\n sub!.agentId || 'default',\n sub!.sessionId || 'default',\n input.prompt,\n input.async,\n ctx.tokenPayload,\n workspaceRoot\n );\n\n return { success: true };\n });\n\nasync function checkSubagentStatus(chatId: string, subagentId: string) {\n const settings = await readChatSettings(chatId);\n const sub = settings?.subagents?.[subagentId];\n if (!sub) throw new TRPCError({ code: 'NOT_FOUND', message: 'Subagent not found' });\n\n if (sub.status === 'completed' || sub.status === 'failed') {\n let outputContent: string | undefined;\n if (sub.status === 'completed') {\n const logger = createChatLogger(chatId, subagentId);\n const lastLogMessage = await logger.findLastMessage((m) => m.role === 'agent');\n if (lastLogMessage && 'content' in lastLogMessage) {\n outputContent = lastLogMessage.content;\n }\n }\n return { status: sub.status, output: outputContent };\n }\n return null;\n}\n\nexport const subagentWait = apiProcedure\n .input(z.object({ subagentId: z.string() }))\n .mutation(async ({ input, ctx, signal }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n\n const ac = new AbortController();\n const timeout = setTimeout(() => ac.abort(), 60000);\n\n // Bind to the TRPC request abort signal to clean up listeners if client disconnects\n const onAbort = () => {\n clearTimeout(timeout);\n ac.abort();\n };\n if (signal) {\n signal.addEventListener('abort', onAbort);\n }\n\n const eventIterator = on(daemonEvents, DAEMON_EVENT_MESSAGE_APPENDED, {\n signal: ac.signal,\n });\n\n try {\n // Check status immediately before listening, but after event iterator is buffering\n const initialStatus = await checkSubagentStatus(chatId, input.subagentId);\n if (initialStatus) {\n clearTimeout(timeout);\n if (signal) signal.removeEventListener('abort', onAbort);\n return initialStatus;\n }\n\n for await (const [event] of eventIterator) {\n if (event.chatId === chatId && event.message?.subagentId === input.subagentId) {\n const msg = event.message;\n if (msg.role === 'subagent_status') {\n const status = await checkSubagentStatus(chatId, input.subagentId);\n if (status) {\n clearTimeout(timeout);\n if (signal) signal.removeEventListener('abort', onAbort);\n return status;\n }\n }\n }\n }\n } catch (err: unknown) {\n if (err && typeof err === 'object' && 'name' in err && err.name === 'AbortError') {\n return { status: 'active' as const, output: undefined };\n }\n throw err;\n } finally {\n clearTimeout(timeout);\n if (signal) signal.removeEventListener('abort', onAbort);\n ac.abort();\n }\n\n return { status: 'active' as const, output: undefined };\n });\n\nexport const subagentStop = apiProcedure\n .input(z.object({ subagentId: z.string() }))\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n\n let subToStop: SubagentTracker | undefined;\n\n await updateChatSettings(chatId, (settings) => {\n if (settings.subagents) {\n const sub = settings.subagents[input.subagentId];\n if (sub) {\n sub.status = 'failed';\n subToStop = sub;\n }\n }\n return settings;\n });\n\n if (subToStop) {\n const session = await createAgentSession({\n chatId,\n agentId: subToStop.agentId || 'default',\n sessionId: subToStop.sessionId || 'default',\n subagentId: input.subagentId,\n cwd: process.cwd(),\n });\n session.stop();\n }\n\n return { success: true };\n });\n\nexport const subagentDelete = apiProcedure\n .input(z.object({ subagentId: z.string() }))\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n\n let subToDelete: SubagentTracker | undefined;\n\n await updateChatSettings(chatId, (settings) => {\n if (settings.subagents && settings.subagents[input.subagentId]) {\n subToDelete = settings.subagents[input.subagentId]!;\n delete settings.subagents[input.subagentId];\n }\n return settings;\n });\n\n if (subToDelete) {\n const session = await createAgentSession({\n chatId,\n agentId: subToDelete.agentId || 'default',\n sessionId: subToDelete.sessionId || 'default',\n subagentId: input.subagentId,\n cwd: process.cwd(),\n });\n session.stop();\n\n return { success: true, deleted: true };\n }\n\n return { success: true, deleted: false };\n });\n\nexport const subagentList = apiProcedure\n .input(z.object({ blocking: z.boolean().optional() }).optional())\n .query(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n const settings = await readChatSettings(chatId);\n\n let subagents = Object.values(settings?.subagents || {});\n\n const isSubagent = !!ctx.tokenPayload.subagentId;\n const myId = ctx.tokenPayload.subagentId;\n\n subagents = subagents.filter((s) => s.parentId === myId);\n\n if (input?.blocking) {\n if (!isSubagent) {\n subagents = [];\n } else {\n subagents = subagents.filter((s) => s.status === 'active');\n }\n }\n return { subagents };\n });\n\nexport const subagentTail = apiProcedure\n .input(z.object({ subagentId: z.string(), limit: z.number().optional() }))\n .query(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n\n const logger = createChatLogger(chatId, input.subagentId);\n const messages = await logger.getMessages(input.limit);\n\n return { messages };\n });\n","import { z } from 'zod';\nimport { randomUUID } from 'node:crypto';\nimport path from 'node:path';\nimport { TRPCError } from '@trpc/server';\nimport {\n appendMessage,\n type CommandLogMessage,\n type AgentReplyMessage,\n type ToolMessage,\n type PolicyRequestMessage,\n} from '../chats.js';\nimport { executeSafe, generateRequestPreview, executeRequest } from '../policy-utils.js';\nimport { getWorkspaceRoot, readPolicies, getClawminiDir } from '../../shared/workspace.js';\nimport { PolicyRequestService } from '../policy-request-service.js';\nimport { RequestStore } from '../request-store.js';\nimport { CronJobSchema } from '../../shared/config.js';\nimport { apiProcedure, router } from './trpc.js';\nimport { taskScheduler } from '../agent/task-scheduler.js';\nimport { formatPendingMessages } from '../agent/utils.js';\nimport {\n resolveAgentDir,\n validateLogFile,\n listCronJobsShared,\n addCronJobShared,\n deleteCronJobShared,\n} from './router-utils.js';\n\nexport const logMessage = apiProcedure\n .input(\n z.object({\n message: z.string().optional(),\n files: z.array(z.string()).optional(),\n })\n )\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n const timestamp = new Date().toISOString();\n const id = Date.now().toString() + Math.random().toString(36).substring(2, 7);\n\n const filePaths: string[] = [];\n if (input.files && input.files.length > 0) {\n const workspaceRoot = getWorkspaceRoot(process.cwd());\n const agentDir = await resolveAgentDir(ctx.tokenPayload?.agentId, workspaceRoot);\n\n for (const file of input.files) {\n const validPath = await validateLogFile(file, agentDir, workspaceRoot);\n filePaths.push(validPath);\n }\n }\n\n const filesArgStr = filePaths.map((p) => ` --file ${p}`).join('');\n const messageStr = input.message || '';\n const logMsg: CommandLogMessage = {\n id,\n messageId: id,\n role: 'command',\n content: messageStr,\n stdout: '',\n stderr: '',\n timestamp,\n command: `clawmini-lite log${filesArgStr}`,\n cwd: process.cwd(),\n exitCode: 0,\n ...(ctx.tokenPayload.subagentId ? { subagentId: ctx.tokenPayload.subagentId } : {}),\n ...(filePaths.length > 0 ? { files: filePaths } : {}),\n };\n\n await appendMessage(chatId, logMsg);\n return { success: true };\n });\n\nexport const logReplyMessage = apiProcedure\n .input(\n z.object({\n message: z.string(),\n files: z.array(z.string()).optional(),\n })\n )\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n const timestamp = new Date().toISOString();\n const id = Date.now().toString() + Math.random().toString(36).substring(2, 7);\n\n const filePaths: string[] = [];\n if (input.files && input.files.length > 0) {\n const workspaceRoot = getWorkspaceRoot(process.cwd());\n const agentDir = await resolveAgentDir(ctx.tokenPayload?.agentId, workspaceRoot);\n\n for (const file of input.files) {\n const validPath = await validateLogFile(file, agentDir, workspaceRoot);\n filePaths.push(validPath);\n }\n }\n\n const logMsg: AgentReplyMessage = {\n id,\n role: 'agent',\n content: input.message,\n timestamp,\n ...(ctx.tokenPayload.subagentId ? { subagentId: ctx.tokenPayload.subagentId } : {}),\n ...(filePaths.length > 0 ? { files: filePaths } : {}),\n };\n\n await appendMessage(chatId, logMsg);\n return { success: true };\n });\n\nexport const logToolMessage = apiProcedure\n .input(\n z.object({\n name: z.string(),\n payload: z.any().optional(),\n })\n )\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n const timestamp = new Date().toISOString();\n const id = Date.now().toString() + Math.random().toString(36).substring(2, 7);\n const messageId = randomUUID();\n\n const payloadObj = input.payload !== undefined ? input.payload : {};\n let contentStr: string;\n if (typeof payloadObj === 'string') {\n contentStr = payloadObj;\n } else {\n try {\n contentStr = JSON.stringify(payloadObj, null, 2);\n } catch {\n contentStr = String(payloadObj);\n }\n }\n\n const logMsg: ToolMessage = {\n id,\n messageId,\n role: 'tool',\n name: input.name,\n payload: payloadObj,\n content: contentStr,\n timestamp,\n ...(ctx.tokenPayload.subagentId ? { subagentId: ctx.tokenPayload.subagentId } : {}),\n };\n\n await appendMessage(chatId, logMsg);\n return { success: true };\n });\n\nexport const agentListCronJobs = apiProcedure.query(async ({ ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n return listCronJobsShared(chatId);\n});\n\nexport const agentAddCronJob = apiProcedure\n .input(z.object({ job: CronJobSchema }))\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n const job = { ...input.job, agentId: ctx.tokenPayload.agentId };\n return addCronJobShared(chatId, job);\n });\n\nexport const agentDeleteCronJob = apiProcedure\n .input(z.object({ id: z.string() }))\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n return deleteCronJobShared(chatId, input.id);\n });\n\nexport const listPolicies = apiProcedure.query(async () => {\n return await readPolicies();\n});\n\nexport const executePolicyHelp = apiProcedure\n .input(z.object({ commandName: z.string() }))\n .query(async ({ input }) => {\n const config = await readPolicies();\n const policy = config?.policies?.[input.commandName];\n\n if (!policy) {\n throw new TRPCError({\n code: 'NOT_FOUND',\n message: `Policy not found: ${input.commandName}`,\n });\n }\n\n if (!policy.allowHelp) {\n return { stdout: '', stderr: 'This command does not support --help\\n', exitCode: 1 };\n }\n\n const fullArgs = [...(policy.args || []), '--help'];\n const { stdout, stderr, exitCode } = await executeSafe(policy.command, fullArgs, {\n cwd: getWorkspaceRoot(),\n });\n\n return { stdout, stderr, exitCode };\n });\n\nexport const createPolicyRequest = apiProcedure\n .input(\n z.object({\n commandName: z.string(),\n args: z.array(z.string()),\n fileMappings: z.record(z.string(), z.string()),\n })\n )\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const workspaceRoot = getWorkspaceRoot(process.cwd());\n const snapshotDir = path.join(getClawminiDir(process.cwd()), 'tmp', 'snapshots');\n const store = new RequestStore(process.cwd());\n const agentDir = await resolveAgentDir(ctx.tokenPayload?.agentId, workspaceRoot);\n const service = new PolicyRequestService(store, agentDir, snapshotDir);\n\n const chatId = ctx.tokenPayload.chatId;\n const agentId = ctx.tokenPayload.agentId;\n\n const config = await readPolicies();\n const policy = config?.policies?.[input.commandName];\n\n if (!policy) {\n throw new TRPCError({\n code: 'NOT_FOUND',\n message: `Policy not found: ${input.commandName}`,\n });\n }\n\n const isAutoApprove = !!policy.autoApprove;\n\n const request = await service.createRequest(\n input.commandName,\n input.args,\n input.fileMappings,\n chatId,\n agentId,\n isAutoApprove,\n ctx.tokenPayload.subagentId\n );\n\n if (isAutoApprove) {\n const { stdout, stderr, exitCode, commandStr } = await executeRequest(\n request,\n policy,\n getWorkspaceRoot()\n );\n\n request.executionResult = { stdout, stderr, exitCode };\n await store.save(request);\n\n const logMsg: PolicyRequestMessage = {\n id: randomUUID(),\n // TODO: we should store the message ID in the CLAW_API_TOKEN, and extract it here\n messageId: randomUUID(),\n role: 'policy',\n requestId: request.id,\n commandName: input.commandName,\n args: input.args,\n status: 'approved',\n content: `[Auto-approved] Policy ${input.commandName} was executed.\\n\\nCommand: ${commandStr}\\nExit Code: ${exitCode}\\n\\nStdout:\\n${stdout}\\n\\nStderr:\\n${stderr}`,\n timestamp: new Date().toISOString(),\n ...(ctx.tokenPayload.subagentId ? { subagentId: ctx.tokenPayload.subagentId } : {}),\n };\n\n await appendMessage(chatId, logMsg);\n return request;\n }\n\n const previewContent = await generateRequestPreview(request);\n\n const logMsg: PolicyRequestMessage = {\n id: randomUUID(),\n // TODO: we should store the message ID in the CLAW_API_TOKEN, and extract it here\n messageId: randomUUID(),\n role: 'policy',\n requestId: request.id,\n commandName: input.commandName,\n args: input.args,\n status: 'pending',\n content: previewContent,\n timestamp: new Date().toISOString(),\n displayRole: 'agent',\n };\n\n await appendMessage(chatId, logMsg);\n return request;\n });\n\nimport { ping } from './user-router.js';\n\nexport const fetchPendingMessages = apiProcedure.mutation(async ({ ctx }) => {\n if (!ctx.tokenPayload?.agentId) {\n throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing agent ID' });\n }\n const targetSessionId = ctx.tokenPayload?.sessionId || 'default';\n\n const extracted = taskScheduler.extractPending(targetSessionId);\n if (extracted.length === 0) {\n return { messages: '' };\n }\n\n return { messages: formatPendingMessages(extracted) };\n});\n\nimport {\n subagentSpawn,\n subagentSend,\n subagentWait,\n subagentStop,\n subagentDelete,\n subagentList,\n subagentTail,\n} from './subagent-router.js';\n\nexport const agentRouter = router({\n logMessage,\n logReplyMessage,\n logToolMessage,\n listCronJobs: agentListCronJobs,\n addCronJob: agentAddCronJob,\n deleteCronJob: agentDeleteCronJob,\n listPolicies,\n executePolicyHelp,\n createPolicyRequest,\n fetchPendingMessages,\n ping,\n subagentSpawn,\n subagentSend,\n subagentWait,\n subagentStop,\n subagentDelete,\n subagentList,\n subagentTail,\n});\n\nexport type AgentRouter = typeof agentRouter;\n","import http from 'node:http';\nimport net from 'node:net';\nimport fs from 'node:fs';\nimport { execSync } from 'node:child_process';\nimport { createHTTPHandler } from '@trpc/server/adapters/standalone';\nimport { userRouter, agentRouter } from './api/index.js';\nimport {\n getSocketPath,\n getClawminiDir,\n getSettingsPath,\n readSettings,\n readEnvironment,\n getEnvironmentPath,\n getWorkspaceRoot,\n updateChatSettings,\n} from '../shared/workspace.js';\nimport { listChats } from '../shared/chats.js';\nimport { cronManager } from './cron.js';\nimport { SettingsSchema } from '../shared/config.js';\nimport { validateToken, getApiContext } from './auth.js';\nimport path from 'node:path';\nimport { exportLiteToEnvironment } from '../shared/lite.js';\n\nexport async function initDaemon() {\n const socketPath = getSocketPath();\n const clawminiDir = getClawminiDir();\n\n // Ensure the .clawmini directory exists\n if (!fs.existsSync(clawminiDir)) {\n throw new Error(`${clawminiDir} does not exist`);\n }\n\n // Read settings to check if API is enabled\n const settingsPath = getSettingsPath();\n let apiCtx: ReturnType<typeof getApiContext> = null;\n\n if (fs.existsSync(settingsPath)) {\n try {\n const settingsStr = fs.readFileSync(settingsPath, 'utf8');\n const settings = JSON.parse(settingsStr);\n const parsed = SettingsSchema.safeParse(settings);\n if (parsed.success) {\n apiCtx = getApiContext(parsed.data);\n }\n } catch (err) {\n console.warn(`Failed to read or parse settings from ${settingsPath}:`, err);\n }\n }\n\n const runHooks = async (hookType: 'up' | 'down') => {\n try {\n const currentSettings = await readSettings();\n const workspaceRoot = getWorkspaceRoot(process.cwd());\n if (!currentSettings?.environments) return;\n for (const [envPath, envName] of Object.entries(currentSettings.environments)) {\n try {\n const envConfig = await readEnvironment(envName);\n const envDir = getEnvironmentPath(envName);\n const affectedDir = path.resolve(workspaceRoot, envPath);\n\n // Try to export clawmini-lite to the environment directory\n if (hookType === 'up' && envConfig) {\n await exportLiteToEnvironment(envName, envConfig, affectedDir);\n }\n\n const command = envConfig?.[hookType];\n if (command) {\n console.log(`Executing '${hookType}' hook for environment '${envName}': ${command}`);\n execSync(command, {\n cwd: affectedDir,\n stdio: 'inherit',\n env: { ...process.env, ENV_DIR: envDir },\n timeout: hookType === 'down' ? 10000 : undefined,\n });\n }\n } catch (err) {\n console.error(`Failed to execute '${hookType}' hook for environment '${envName}':`, err);\n if (hookType === 'up') throw err;\n }\n }\n } catch (err) {\n console.error(`Failed to run '${hookType}' hooks:`, err);\n if (hookType === 'up') throw err;\n }\n };\n\n // Ensure the old socket file is removed, but first check if another daemon is actively listening\n if (fs.existsSync(socketPath)) {\n const isSocketInUse = await new Promise<boolean>((resolve) => {\n const client = net.createConnection({ path: socketPath });\n client.on('connect', () => {\n client.destroy();\n resolve(true);\n });\n client.on('error', () => {\n resolve(false);\n });\n });\n\n if (isSocketInUse) {\n console.log('Daemon is already running (socket is active). Exiting.');\n process.exit(0);\n }\n\n try {\n fs.unlinkSync(socketPath);\n } catch {\n // Ignore\n }\n }\n\n let isReady = false;\n let readyPromiseResolve: () => void;\n const readyPromise = new Promise<void>((resolve) => {\n readyPromiseResolve = resolve;\n });\n\n const handler = createHTTPHandler({\n router: userRouter,\n createContext: ({ req, res }) => ({ req, res, isApiServer: false }),\n });\n\n const server = http.createServer(async (req, res) => {\n if (!isReady) {\n await readyPromise;\n }\n // Only accept POST requests on /trpc/ path if needed, but since we are running over Unix socket, we map directly\n handler(req, res);\n });\n\n await new Promise<void>((resolve, reject) => {\n server.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE') {\n console.log('Daemon is already running (socket bind failed). Exiting.');\n process.exit(0);\n }\n reject(err);\n });\n server.listen(socketPath, () => {\n console.log(`Daemon initialized and listening on ${socketPath}`);\n resolve();\n });\n });\n\n const cleanOrphanedSubagents = async () => {\n try {\n const chats = await listChats();\n for (const chatId of chats) {\n await updateChatSettings(chatId, (settings) => {\n if (settings.subagents) {\n for (const subagent of Object.values(settings.subagents)) {\n if (subagent.status === 'active') {\n subagent.status = 'failed';\n }\n }\n }\n return settings;\n });\n }\n } catch (err) {\n console.warn('Failed to clean orphaned subagents:', err);\n }\n };\n await cleanOrphanedSubagents();\n\n await runHooks('up');\n\n isReady = true;\n readyPromiseResolve!();\n\n // Initialize cron jobs\n cronManager.init().catch((err) => {\n console.error('Failed to initialize cron manager:', err);\n });\n\n let apiServer: http.Server | undefined;\n if (apiCtx) {\n const apiHandler = createHTTPHandler({\n router: agentRouter,\n createContext: ({ req, res }) => {\n let tokenPayload = null;\n const authHeader = req.headers.authorization;\n if (authHeader && authHeader.startsWith('Bearer ')) {\n const token = authHeader.substring(7);\n tokenPayload = validateToken(token);\n }\n return { req, res, isApiServer: true, tokenPayload };\n },\n });\n\n apiServer = http.createServer((req, res) => {\n apiHandler(req, res);\n });\n\n const host = apiCtx.host;\n const port = apiCtx.port;\n apiServer.listen(port, host, () => {\n console.log(`Daemon HTTP API initialized and listening on http://${host}:${port}`);\n });\n }\n\n let isShuttingDown = false;\n const shutdown = async () => {\n if (isShuttingDown) return;\n isShuttingDown = true;\n console.log('Daemon shutting down...');\n\n await runHooks('down');\n\n server.close();\n if (apiServer) apiServer.close();\n process.exit(0);\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n process.on('exit', () => {\n if (fs.existsSync(socketPath)) {\n try {\n fs.unlinkSync(socketPath);\n } catch {\n // Ignore errors during exit cleanup\n }\n }\n });\n}\n\n// Only auto-initialize if run directly\nif (process.argv[1] === new URL(import.meta.url).pathname) {\n initDaemon().catch((err) => {\n console.error('Daemon initialization failed:', err);\n process.exit(1);\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["fs","path","fs","fsSync","fs","stop","stop","stop","getMessages","findLastMessageFromStorage","crypto","fs","fs","fs","fetchMessages","fs"],"sources":["../../src/daemon/api/trpc.ts","../../src/daemon/routers/slash-new.ts","../../src/daemon/routers/slash-command.ts","../../src/daemon/routers/utils.ts","../../src/daemon/routers/slash-stop.ts","../../src/daemon/routers/slash-interrupt.ts","../../src/daemon/request-store.ts","../../src/daemon/policy-utils.ts","../../src/daemon/routers/slash-policies.ts","../../src/daemon/routers/slash-model.ts","../../src/daemon/routers/slash-restart.ts","../../src/daemon/routers/slash-shutdown.ts","../../src/shared/version.ts","../../src/daemon/routers/slash-upgrade.ts","../../src/daemon/routers/session-timeout.ts","../../src/daemon/routers.ts","../../src/daemon/agent/agent-context.ts","../../src/daemon/agent/agent-extractors.ts","../../src/daemon/agent/utils.ts","../../src/daemon/agent/agent-runner.ts","../../src/daemon/utils/spawn.ts","../../src/daemon/agent/chat-logger.ts","../../src/shared/utils/env.ts","../../src/daemon/auth.ts","../../src/daemon/agent/task-scheduler.ts","../../src/daemon/agent/agent-session.ts","../../src/daemon/agent/turn-registry.ts","../../src/daemon/message.ts","../../src/daemon/cron.ts","../../src/daemon/api/router-utils.ts","../../src/daemon/api/user-router.ts","../../src/daemon/policy-request-service.ts","../../src/daemon/api/agent-policy-endpoints.ts","../../src/daemon/api/subagent-utils.ts","../../src/daemon/api/subagent-router.ts","../../src/daemon/api/agent-router.ts","../../src/daemon/index.ts"],"sourcesContent":["import { initTRPC, TRPCError } from '@trpc/server';\nimport type { IncomingMessage, ServerResponse } from 'node:http';\nimport type { TokenPayload } from '../auth.js';\n\nexport interface Context {\n req?: IncomingMessage | undefined;\n res?: ServerResponse | undefined;\n isApiServer?: boolean | undefined;\n tokenPayload?: TokenPayload | null | undefined;\n}\n\nconst t = initTRPC.context<Context>().create();\nexport const router = t.router;\nexport const publicProcedure = t.procedure;\n\nconst apiAuthMiddleware = t.middleware(({ ctx, next }) => {\n if (ctx.isApiServer) {\n if (!ctx.tokenPayload) {\n throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing or invalid token' });\n }\n }\n return next({\n ctx: {\n ...ctx,\n tokenPayload: ctx.tokenPayload,\n },\n });\n});\n\nexport const apiProcedure = t.procedure.use(apiAuthMiddleware);\n","import type { RouterState } from './types.js';\n\nexport function slashNew(state: RouterState): RouterState {\n if (/^\\/new(\\s|$)/.test(state.message)) {\n const newMessage = state.message.replace(/^\\/new(\\s+|$)/, '').trim();\n const id = crypto.randomUUID();\n return {\n ...state,\n message: newMessage,\n sessionId: id,\n nextSessionId: id,\n reply: '[@clawmini/slash-new] Starting a new session...',\n };\n }\n return state;\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { RouterState } from './types.js';\nimport { getClawminiDir } from '../../shared/workspace.js';\nimport { pathIsInsideDir } from '../../shared/utils/fs.js';\n\nexport async function slashCommand(state: RouterState): Promise<RouterState> {\n const commandsDir = path.resolve(getClawminiDir(), 'commands');\n let currentMessage = state.message;\n\n // Regex to match slash commands (e.g., /foo or /foo:bar) that appear as whole words.\n // We use lookbehind and lookahead to ensure it's bounded by whitespace or string start/end.\n const commandRegex = /(?<=^|\\s)\\/([a-zA-Z0-9_\\-:.]+)(?=\\s|$)/g;\n const matches = [...currentMessage.matchAll(commandRegex)];\n\n if (matches.length === 0) {\n return state;\n }\n\n for (const match of matches) {\n const fullMatch = match[0];\n const commandName = match[1];\n if (!commandName) continue;\n\n const targetPathMd = path.resolve(commandsDir, `${commandName}.md`);\n const targetPathTxt = path.resolve(commandsDir, `${commandName}.txt`);\n\n // Strict path traversal protection\n const baseTargetPath = path.resolve(commandsDir, commandName);\n if (!pathIsInsideDir(baseTargetPath, commandsDir)) {\n continue;\n }\n\n let content: string;\n\n try {\n content = await fs.readFile(targetPathMd, 'utf8');\n } catch {\n try {\n content = await fs.readFile(targetPathTxt, 'utf8');\n } catch {\n // If file doesn't exist or can't be read, leave it as is.\n continue;\n }\n }\n\n // Replace the command with the content. We only replace the exact occurrence.\n // Since replace replaces the first occurrence, and we are iterating over all matches,\n // it should replace them sequentially. If there are multiple identical commands,\n // it's fine, each will be replaced in turn.\n currentMessage = currentMessage.replace(fullMatch, content.trim());\n }\n\n return {\n ...state,\n message: currentMessage,\n };\n}\n","import type { RouterState } from './types.js';\n\nexport function createSlashActionRouter(\n command: string,\n action: NonNullable<RouterState['action']>,\n replyMessage: string\n) {\n return function (state: RouterState): RouterState {\n const regex = new RegExp(`^\\\\/${command}(\\\\s|$)`);\n if (regex.test(state.message)) {\n const replaceRegex = new RegExp(`^\\\\/${command}(\\\\s+|$)`);\n const newMessage = state.message.replace(replaceRegex, '').trim();\n return {\n ...state,\n message: newMessage,\n action,\n reply: replyMessage,\n };\n }\n return state;\n };\n}\n","import { createSlashActionRouter } from './utils.js';\n\nexport const slashStop = createSlashActionRouter('stop', 'stop', 'Stopping current task...');\n","import { createSlashActionRouter } from './utils.js';\n\nexport const slashInterrupt = createSlashActionRouter(\n 'interrupt',\n 'interrupt',\n 'Interrupting current task...'\n);\n","import fs from 'fs/promises';\nimport path from 'path';\nimport { z } from 'zod';\nimport { getClawminiDir } from '../shared/workspace.js';\nimport type { PolicyRequest } from '../shared/policies.js';\nimport { randomInt } from 'crypto';\n\nconst PolicyRequestSchema = z.object({\n id: z.string(),\n commandName: z.string(),\n args: z.array(z.string()),\n fileMappings: z.record(z.string(), z.string()),\n state: z.enum(['Pending', 'Approved', 'Rejected']),\n createdAt: z.number(),\n rejectionReason: z.string().optional(),\n chatId: z.string(),\n agentId: z.string(),\n subagentId: z.string().optional(),\n cwd: z.string().optional(),\n});\n\nfunction isENOENT(err: unknown): boolean {\n return Boolean(\n err && typeof err === 'object' && 'code' in err && (err as { code: string }).code === 'ENOENT'\n );\n}\n\nexport class RequestStore {\n private baseDir: string;\n\n constructor(startDir = process.cwd()) {\n this.baseDir = path.join(getClawminiDir(startDir), 'tmp', 'requests');\n }\n\n async init(): Promise<void> {\n await fs.mkdir(this.baseDir, { recursive: true });\n }\n\n private getFilePath(id: string): string {\n return path.join(this.baseDir, `${id}.json`);\n }\n\n async save(request: PolicyRequest): Promise<void> {\n await this.init();\n const normalizedId = normalizePolicyId(request.id);\n request.id = normalizedId;\n const filePath = this.getFilePath(normalizedId);\n await fs.writeFile(filePath, JSON.stringify(request, null, 2), 'utf8');\n }\n\n async delete(id: string): Promise<void> {\n const normalizedId = normalizePolicyId(id);\n const filePath = this.getFilePath(normalizedId);\n try {\n await fs.unlink(filePath);\n } catch (err: unknown) {\n if (!isENOENT(err)) throw err;\n }\n }\n\n async cleanupCompleted(): Promise<number> {\n let removed = 0;\n try {\n const files = await fs.readdir(this.baseDir);\n for (const file of files) {\n if (!file.endsWith('.json')) continue;\n const id = path.basename(file, '.json');\n const req = await this.load(id);\n if (req && req.state !== 'Pending') {\n await this.delete(id);\n removed++;\n }\n }\n } catch (err: unknown) {\n if (!isENOENT(err)) throw err;\n }\n return removed;\n }\n\n async load(id: string): Promise<PolicyRequest | null> {\n const normalizedId = normalizePolicyId(id);\n const filePath = this.getFilePath(normalizedId);\n try {\n const data = await fs.readFile(filePath, 'utf8');\n return PolicyRequestSchema.parse(JSON.parse(data)) as PolicyRequest;\n } catch (err: unknown) {\n if (isENOENT(err)) {\n return null;\n }\n const msg = err instanceof Error ? err.message : String(err);\n console.warn(`Failed to parse request file ${filePath}:`, msg);\n return null;\n }\n }\n\n async list(): Promise<PolicyRequest[]> {\n await this.init();\n const requests: PolicyRequest[] = [];\n try {\n const files = await fs.readdir(this.baseDir);\n for (const file of files) {\n if (!file.endsWith('.json')) continue;\n const id = path.basename(file, '.json');\n const req = await this.load(id);\n if (req) {\n requests.push(req);\n }\n }\n } catch (err: unknown) {\n if (!isENOENT(err)) {\n throw err;\n }\n }\n return requests.sort((a, b) => b.createdAt - a.createdAt);\n }\n}\n\nexport function generateRandomAlphaNumericString(length: number): string {\n const characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';\n let result = '';\n for (let i = 0; i < length; i++) {\n result += characters[Math.floor(randomInt(characters.length))];\n }\n return result;\n}\n\nfunction normalizePolicyId(id: string): string {\n return id.toLocaleUpperCase().trim();\n}\n","import fs from 'node:fs/promises';\nimport fsSync, { constants } from 'node:fs';\nimport path from 'node:path';\nimport { randomBytes } from 'node:crypto';\nimport { spawn } from 'node:child_process';\nimport { pathIsInsideDir } from '../shared/utils/fs.js';\nimport type { PolicyRequest, PolicyDefinition } from '../shared/policies.js';\nimport { resolveAgentDir } from './api/router-utils.js';\nimport {\n getWorkspaceRoot,\n getActiveEnvironmentInfo,\n readEnvironment,\n} from '../shared/workspace.js';\n\nexport const MAX_SNAPSHOT_SIZE = 5 * 1024 * 1024;\nexport const MAX_INLINE_OUTPUT_LENGTH = 500;\n\n/**\n * Strips the sandbox `baseDir` from `sandboxCwd` and resolves the remainder\n * against `hostTargetDir` (the host dir that mirrors baseDir inside the\n * sandbox). Pure translation — no security validation; callers must validate\n * the result with `assertPathInsideDir`.\n */\nexport function translateSandboxPath(\n sandboxCwd: string,\n baseDir: string,\n hostTargetDir: string\n): string {\n let relativePath = sandboxCwd;\n if (sandboxCwd.startsWith(baseDir)) {\n relativePath = sandboxCwd.slice(baseDir.length);\n }\n if (relativePath.startsWith('/') || relativePath.startsWith('\\\\')) {\n relativePath = relativePath.slice(1);\n }\n return path.resolve(hostTargetDir, relativePath);\n}\n\n/**\n * Throws if `cwd` (after symlink resolution) is not inside `boundaryDir`.\n *\n * Security note (TOCTOU): There is an inherent race between validating the\n * resolved path here and the moment `spawn` uses it as cwd. A symlink created\n * on the host filesystem in that window could redirect execution outside\n * boundaryDir. We accept this because the sandboxed agent cannot modify the\n * host filesystem — only a local user or process with host-level access could\n * exploit the gap, and that is outside our threat model.\n */\nexport function assertPathInsideDir(cwd: string, boundaryDir: string): void {\n const realCwd = tryRealpath(cwd);\n const realBoundary = tryRealpath(boundaryDir);\n if (!pathIsInsideDir(realCwd, realBoundary, { allowSameDir: true })) {\n throw new Error(`Security Error: Path resolves outside the allowed directory: ${cwd}`);\n }\n}\n\n// Realpath that tolerates missing leaves. Walks up to the nearest existing\n// ancestor, realpaths that, and re-appends the missing tail. Needed so that\n// symlinks in the existing prefix still resolve (e.g. macOS /var → /private/var)\n// when the full path is not yet on disk.\nfunction tryRealpath(p: string): string {\n const resolved = path.resolve(p);\n try {\n return fsSync.realpathSync(resolved);\n } catch (err: unknown) {\n if (\n !(err instanceof Error && 'code' in err && (err as NodeJS.ErrnoException).code === 'ENOENT')\n ) {\n throw err;\n }\n }\n const parent = path.dirname(resolved);\n if (parent === resolved) return resolved;\n return path.join(tryRealpath(parent), path.basename(resolved));\n}\n\nexport async function resolveRequestCwd(\n requestCwd: string | undefined,\n agentId: string | undefined,\n workspaceRoot: string\n): Promise<string> {\n if (!requestCwd) {\n // TODO throw error instead?\n return workspaceRoot;\n }\n\n const agentDir = await resolveAgentDir(agentId, workspaceRoot);\n const envInfo = await getActiveEnvironmentInfo(agentDir, workspaceRoot);\n const envConfig = envInfo ? await readEnvironment(envInfo.name, workspaceRoot) : null;\n\n // Translate sandbox → host only when the env declares a baseDir (VM-style\n // sandbox). Otherwise requestCwd is already a host path; resolve relative\n // paths against agentDir and keep absolute paths as-is.\n const hostCwd =\n envInfo && envConfig?.baseDir\n ? translateSandboxPath(requestCwd, envConfig.baseDir, envInfo.targetPath)\n : path.resolve(agentDir, requestCwd);\n\n // Boundary: the agent dir\n assertPathInsideDir(hostCwd, agentDir);\n return hostCwd;\n}\n\nexport async function createSnapshot(\n requestedPath: string,\n agentDir: string,\n snapshotDir: string\n): Promise<string> {\n let realAgentDir: string;\n try {\n realAgentDir = await fs.realpath(agentDir);\n } catch (err) {\n throw new Error(`Agent directory not found or cannot be resolved: ${agentDir}`, { cause: err });\n }\n\n const resolvedRequestedPath = path.resolve(realAgentDir, requestedPath);\n\n // Verify it is inside the allowed agent directory\n if (!pathIsInsideDir(resolvedRequestedPath, realAgentDir, { allowSameDir: true })) {\n throw new Error(\n `Security Error: Path resolves outside the allowed agent directory: ${resolvedRequestedPath}`\n );\n }\n\n // Lstat prevents TOCTOU attacks by not following symlinks\n let stat;\n try {\n stat = await fs.lstat(resolvedRequestedPath);\n } catch (err) {\n throw new Error(`File not found or cannot be accessed: ${requestedPath}`, { cause: err });\n }\n\n if (stat.isSymbolicLink()) {\n throw new Error(`Security Error: Symlinks are not allowed: ${requestedPath}`);\n }\n\n if (!stat.isFile()) {\n throw new Error(`Requested path is not a file: ${requestedPath}`);\n }\n if (stat.size > MAX_SNAPSHOT_SIZE) {\n throw new Error(`File exceeds maximum snapshot size of 5MB: ${requestedPath}`);\n }\n\n // Generate unique filename for the snapshot\n const ext = path.extname(resolvedRequestedPath);\n const base = path.basename(resolvedRequestedPath, ext);\n\n await fs.mkdir(snapshotDir, { recursive: true });\n\n let snapshotPath: string;\n while (true) {\n const uniqueId = randomBytes(8).toString('hex');\n const snapshotFileName = `${base}_${uniqueId}${ext}`;\n snapshotPath = path.join(snapshotDir, snapshotFileName);\n\n try {\n await fs.copyFile(resolvedRequestedPath, snapshotPath, constants.COPYFILE_EXCL);\n break;\n } catch (err: unknown) {\n if (\n err instanceof Error &&\n 'code' in err &&\n (err as Error & { code?: string }).code === 'EEXIST'\n ) {\n continue;\n }\n throw err;\n }\n }\n\n return snapshotPath;\n}\n\nexport function interpolateArgs(args: string[], snapshots: Record<string, string>): string[] {\n return args.map((arg) => {\n let interpolated = arg;\n for (const [key, snapshotPath] of Object.entries(snapshots)) {\n const variable = `{{${key}}}`;\n interpolated = interpolated.replaceAll(variable, snapshotPath);\n }\n return interpolated;\n });\n}\n\nexport function executeSafe(\n command: string,\n args: string[],\n options?: { cwd?: string; env?: NodeJS.ProcessEnv }\n): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n return new Promise((resolve) => {\n // Safe execution: shell is strictly false to prevent command injection\n const p = spawn(command, args, {\n shell: false,\n cwd: options?.cwd,\n env: options?.env,\n });\n\n let stdout = '';\n let stderr = '';\n\n if (p.stdout) {\n p.stdout.on('data', (data) => {\n stdout += data.toString();\n });\n }\n\n if (p.stderr) {\n p.stderr.on('data', (data) => {\n stderr += data.toString();\n });\n }\n\n p.on('close', (code) => {\n resolve({ stdout, stderr, exitCode: code ?? 1 });\n });\n\n p.on('error', (err) => {\n resolve({ stdout: '', stderr: err.toString(), exitCode: 1 });\n });\n });\n}\n\nexport async function executeRequest(\n request: PolicyRequest,\n policy: PolicyDefinition,\n cwd?: string\n): Promise<{ stdout: string; stderr: string; exitCode: number; commandStr: string }> {\n const fullArgs = [...(policy.args || []), ...request.args];\n const interpolatedArgs = interpolateArgs(fullArgs, request.fileMappings);\n\n const { stdout, stderr, exitCode } = await executeSafe(\n policy.command,\n interpolatedArgs,\n cwd ? { cwd } : undefined\n );\n\n const commandStr = `${policy.command} ${interpolatedArgs.join(' ')}`;\n return { stdout, stderr, exitCode, commandStr };\n}\n\n/**\n * Saves large stdout/stderr to files in the agent's tmp/ directory and returns\n * placeholder strings pointing to those files. Small outputs are returned as-is.\n */\nexport async function truncateLargeOutput(\n stdout: string,\n stderr: string,\n requestId: string,\n agentId: string | undefined\n): Promise<{ stdout: string; stderr: string }> {\n const agentDir = await resolveAgentDir(agentId, getWorkspaceRoot());\n const tmpDir = path.join(agentDir, 'tmp');\n const needsTmpDir =\n stdout.length >= MAX_INLINE_OUTPUT_LENGTH || stderr.length >= MAX_INLINE_OUTPUT_LENGTH;\n\n if (needsTmpDir) {\n await fs.mkdir(tmpDir, { recursive: true });\n }\n\n if (stdout.length >= MAX_INLINE_OUTPUT_LENGTH) {\n await fs.writeFile(path.join(tmpDir, `stdout-${requestId}.txt`), stdout, 'utf-8');\n stdout = `stdout is ${stdout.length} characters, saved to ./tmp/stdout-${requestId}.txt\\n`;\n }\n\n if (stderr.length >= MAX_INLINE_OUTPUT_LENGTH) {\n await fs.writeFile(path.join(tmpDir, `stderr-${requestId}.txt`), stderr, 'utf-8');\n stderr = `stderr is ${stderr.length} characters, saved to ./tmp/stderr-${requestId}.txt\\n`;\n }\n\n return { stdout, stderr };\n}\n\nexport async function generateRequestPreview(request: PolicyRequest): Promise<string> {\n let previewContent = `Sandbox Policy Request: ${request.commandName}\\n`;\n previewContent += `ID: ${request.id}\\n`;\n if (request.args.length > 0) {\n previewContent += `Args: ${request.args.join(' ')}\\n`;\n }\n\n for (const [name, snapPath] of Object.entries(request.fileMappings)) {\n previewContent += `File [${name}]:\\n`;\n try {\n let content = await fs.readFile(snapPath, 'utf8');\n if (content.length > 500) {\n content = content.substring(0, 500) + '\\n... (truncated)\\n';\n }\n previewContent += content;\n } catch (e: unknown) {\n previewContent += `<Error reading file: ${(e as Error).message}>\\n`;\n }\n }\n\n previewContent += `\\nUse /approve ${request.id} or /reject ${request.id} [reason]`;\n return previewContent;\n}\n","import { randomUUID } from 'node:crypto';\nimport type { RouterState } from './types.js';\nimport { RequestStore } from '../request-store.js';\nimport { readChatSettings, readPoliciesForPath, getWorkspaceRoot } from '../../shared/workspace.js';\nimport { resolveAgentDir } from '../api/router-utils.js';\nimport { executeRequest, resolveRequestCwd, truncateLargeOutput } from '../policy-utils.js';\nimport { appendMessage } from '../chats.js';\nimport type { SystemMessage } from '../../shared/chats.js';\nimport type { PolicyRequest } from '../../shared/policies.js';\nimport { executeDirectMessage } from '../message.js';\n\n// Resolve which session the approval/rejection should be replayed on. The\n// request may have been created in an earlier session (session-timeout, /new),\n// so we always consult the chat's *current* session for that agent/subagent.\nasync function resolveTargetSessionId(chatId: string, req: PolicyRequest): Promise<string> {\n const chatSettings = await readChatSettings(chatId);\n if (req.subagentId) {\n return chatSettings?.subagents?.[req.subagentId]?.sessionId ?? 'default';\n }\n return chatSettings?.sessions?.[req.agentId] ?? 'default';\n}\n\nasync function loadAndValidateRequest(id: string, state: RouterState) {\n const store = new RequestStore(getWorkspaceRoot());\n const req = await store.load(id);\n if (!req) return { error: { ...state, message: '', reply: `Request not found: ${id}` } };\n if (req.chatId && req.chatId !== state.chatId)\n return {\n error: { ...state, message: '', reply: `Request belongs to a different chat: ${req.chatId}` },\n };\n if (req.state !== 'Pending')\n return { error: { ...state, message: '', reply: `Request is not pending: ${id}` } };\n return { req, store };\n}\n\nexport async function slashPolicies(state: RouterState): Promise<RouterState> {\n const message = state.message.trim();\n\n if (message === '/pending') {\n const store = new RequestStore(getWorkspaceRoot());\n const requests = await store.list();\n const pending = requests.filter((r) => r.state === 'Pending');\n\n let reply = `Pending Requests (${pending.length}):\\n`;\n for (const req of pending) {\n reply += `- ID: ${req.id} | Command: ${req.commandName} ${req.args.join(' ')}\\n`;\n }\n\n return {\n ...state,\n reply,\n action: 'stop',\n };\n }\n\n const approveMatch = message.match(/^\\/approve\\s+([^\\s]+)/);\n if (approveMatch) {\n const id = approveMatch[1];\n if (!id) return state;\n const { req, store, error } = await loadAndValidateRequest(id, state);\n if (error) return error;\n if (!req || !store) return state; // Should not happen if error is undefined\n\n const workspaceRoot = getWorkspaceRoot();\n const agentDir = await resolveAgentDir(req.agentId, workspaceRoot);\n const config = await readPoliciesForPath(agentDir, workspaceRoot);\n const policy = config?.policies?.[req.commandName];\n if (!policy) {\n return { ...state, message: '', reply: `Policy not found: ${req.commandName}` };\n }\n\n const hostCwd = await resolveRequestCwd(req.cwd, state.agentId, workspaceRoot);\n\n const result = await executeRequest(req, policy, hostCwd);\n const { exitCode } = result;\n const { stdout, stderr } = await truncateLargeOutput(\n result.stdout,\n result.stderr,\n req.id,\n state.agentId\n );\n\n await store.delete(req.id);\n\n const agentMessage = `Request ${id} approved.\\n\\n${wrapInHtml('stdout', stdout)}\\n\\n${wrapInHtml('stderr', stderr)}\\n\\nExit Code: ${exitCode}`;\n\n const targetSessionId = await resolveTargetSessionId(state.chatId, req);\n\n const userNotificationMsg: SystemMessage = {\n id: randomUUID(),\n messageId: state.messageId,\n role: 'system',\n event: 'policy_approved',\n displayRole: 'agent',\n content: `Request ${id} (\\`${req.commandName}\\`) approved.`,\n timestamp: new Date().toISOString(),\n // Explicitly omitted subagentId to show in main chat\n sessionId: state.sessionId,\n };\n\n await appendMessage(state.chatId, userNotificationMsg);\n\n await executeDirectMessage(\n state.chatId,\n {\n messageId: randomUUID(),\n message: agentMessage,\n chatId: state.chatId,\n agentId: req.agentId,\n sessionId: targetSessionId,\n ...(req.subagentId ? { subagentId: req.subagentId } : {}),\n env: state.env || {},\n },\n undefined,\n getWorkspaceRoot(),\n true, // noWait\n agentMessage,\n req.subagentId,\n 'policy_approved',\n 'user'\n );\n\n return {\n ...state,\n message: '', // Prevents further router processing or duplicate user message logs\n };\n }\n\n const rejectMatch = message.match(/^\\/reject\\s+([^\\s]+)(?:\\s+(.*))?/);\n if (rejectMatch) {\n const id = rejectMatch[1];\n if (!id) return state;\n const reason = rejectMatch[2] || 'No reason provided';\n const { req, store, error } = await loadAndValidateRequest(id, state);\n if (error) return error;\n if (!req || !store) return state; // Should not happen if error is undefined\n\n await store.delete(req.id);\n\n const agentMessage = `Request ${id} rejected. Reason: ${reason}`;\n\n const targetSessionId = await resolveTargetSessionId(state.chatId, req);\n\n const userNotificationMsg: SystemMessage = {\n id: randomUUID(),\n messageId: state.messageId,\n role: 'system',\n event: 'policy_rejected',\n displayRole: 'agent',\n content: `Request ${id} (\\`${req.commandName}\\`) rejected. Reason: ${reason}`,\n timestamp: new Date().toISOString(),\n // Explicitly omitted subagentId to show in main chat\n sessionId: state.sessionId,\n };\n\n await appendMessage(state.chatId, userNotificationMsg);\n\n await executeDirectMessage(\n state.chatId,\n {\n messageId: randomUUID(),\n message: agentMessage,\n chatId: state.chatId,\n agentId: req.agentId,\n sessionId: targetSessionId,\n ...(req.subagentId ? { subagentId: req.subagentId } : {}),\n env: state.env || {},\n },\n undefined,\n getWorkspaceRoot(),\n true, // noWait\n agentMessage,\n req.subagentId,\n 'policy_rejected',\n 'user'\n );\n\n return {\n ...state,\n message: '', // Prevents further router processing or duplicate user message logs\n };\n }\n\n return state;\n}\n\nfunction wrapInHtml(tag: string, text: string): string {\n if (text.trim().length === 0) {\n return `<${tag}></${tag}>`;\n }\n return `<${tag}>\\n${text.trim()}\\n</${tag}>`;\n}\n","import type { RouterState } from './types.js';\nimport type { Agent } from '../../shared/config.js';\nimport {\n getAgent,\n getAgentOverlay,\n updateAgentOverlay,\n getWorkspaceRoot,\n} from '../../shared/workspace.js';\n\nconst RESERVED_SHORTHANDS = new Set(['help', 'add', 'remove', 'rm']);\n\nfunction stop(state: RouterState, reply: string): RouterState {\n return { ...state, message: '', reply, action: 'stop' };\n}\n\nfunction formatHelp(): string {\n return [\n 'Usage:',\n '- /model — List current model and shorthands.',\n '- /model <name> — Set MODEL (resolves shorthand if defined).',\n '- /model add <shorthand> <full-name> — Add or replace a shorthand.',\n '- /model remove <shorthand> — Remove a shorthand (alias: rm).',\n '- /model help — Show this help.',\n ].join('\\n');\n}\n\nfunction formatList(agent: Agent | null): string {\n const current = (agent?.env?.MODEL as string | undefined) ?? '(unset)';\n const shorthands = agent?.modelShorthands ?? {};\n const entries = Object.entries(shorthands);\n const lines = [`Current model: ${current}`];\n if (entries.length === 0) {\n lines.push('No shorthands defined. Add one with /model add <shorthand> <full-name>.');\n } else {\n lines.push('Shorthands:');\n for (const [short, full] of entries.sort(([a], [b]) => a.localeCompare(b))) {\n lines.push(`- ${short} -> ${full}`);\n }\n }\n return lines.join('\\n');\n}\n\n// Heuristic: a token that looks like a short, undecorated word a user might\n// reasonably mistake for a shorthand. Real model names typically contain at\n// least one separator (e.g. `gemini-3-pro`, `claude-opus-4-7`, `gpt-4.1`).\nfunction looksLikeShorthand(name: string): boolean {\n return name.length <= 16 && !/[-./:]/.test(name);\n}\n\nasync function setModel(agentId: string, fullModel: string, workspaceRoot: string): Promise<void> {\n await updateAgentOverlay(\n agentId,\n (overlay) => {\n const nextEnv = { ...(overlay.env ?? {}), MODEL: fullModel };\n return { ...overlay, env: nextEnv };\n },\n workspaceRoot\n );\n}\n\nasync function addShorthand(\n agentId: string,\n shorthand: string,\n fullModel: string,\n workspaceRoot: string\n): Promise<void> {\n await updateAgentOverlay(\n agentId,\n (overlay) => {\n const nextShorthands = { ...(overlay.modelShorthands ?? {}), [shorthand]: fullModel };\n return { ...overlay, modelShorthands: nextShorthands };\n },\n workspaceRoot\n );\n}\n\nasync function removeOverlayShorthand(\n agentId: string,\n shorthand: string,\n workspaceRoot: string\n): Promise<boolean> {\n return await updateAgentOverlay(\n agentId,\n (overlay) => {\n const overlayShorthands = overlay.modelShorthands ?? {};\n if (!(shorthand in overlayShorthands)) return null;\n const next = { ...overlayShorthands };\n delete next[shorthand];\n const updated: Agent = { ...overlay };\n if (Object.keys(next).length === 0) {\n delete updated.modelShorthands;\n } else {\n updated.modelShorthands = next;\n }\n return updated;\n },\n workspaceRoot\n );\n}\n\nasync function ensureOverlay(\n state: RouterState,\n agentId: string,\n workspaceRoot: string\n): Promise<RouterState | null> {\n const overlay = await getAgentOverlay(agentId, workspaceRoot);\n if (overlay !== null) return null;\n return stop(state, `Agent '${agentId}' has no settings overlay; cannot configure model.`);\n}\n\nexport async function slashModel(state: RouterState): Promise<RouterState> {\n const message = state.message.trim();\n if (!/^\\/model(\\s|$)/.test(message)) return state;\n\n const agentId = state.agentId;\n if (!agentId) {\n return stop(state, '/model requires an agent. Set a defaultAgent for this chat.');\n }\n\n const workspaceRoot = getWorkspaceRoot();\n const rest = message.slice('/model'.length).trim();\n\n if (rest === '') {\n const agent = await getAgent(agentId, workspaceRoot);\n return stop(state, formatList(agent));\n }\n\n const firstSpace = rest.search(/\\s/);\n const subcommand = firstSpace === -1 ? rest : rest.slice(0, firstSpace);\n const remainder = firstSpace === -1 ? '' : rest.slice(firstSpace + 1).trim();\n\n if (subcommand === 'help') {\n return stop(state, formatHelp());\n }\n\n if (subcommand === 'add') {\n // Require a single-token full name. Model identifiers don't contain\n // whitespace, and accepting trailing tokens silently swallows typos\n // (e.g. `/model add foo gemini-3 pro` storing `MODEL=gemini-3 pro`).\n const addMatch = remainder.match(/^(\\S+)\\s+(\\S+)\\s*$/);\n if (!addMatch) {\n return stop(state, 'Usage: /model add <shorthand> <full-name>');\n }\n const shorthand = addMatch[1]!;\n const fullModel = addMatch[2]!;\n if (RESERVED_SHORTHANDS.has(shorthand)) {\n return stop(state, `Invalid shorthand: '${shorthand}' is reserved.`);\n }\n const guard = await ensureOverlay(state, agentId, workspaceRoot);\n if (guard) return guard;\n await addShorthand(agentId, shorthand, fullModel, workspaceRoot);\n return stop(state, `Added shorthand: ${shorthand} -> ${fullModel}`);\n }\n\n if (subcommand === 'remove' || subcommand === 'rm') {\n if (!/^\\S+$/.test(remainder)) {\n return stop(state, 'Usage: /model remove <shorthand>');\n }\n const guard = await ensureOverlay(state, agentId, workspaceRoot);\n if (guard) return guard;\n const removed = await removeOverlayShorthand(agentId, remainder, workspaceRoot);\n if (!removed) {\n const merged = await getAgent(agentId, workspaceRoot);\n if (merged?.modelShorthands?.[remainder] !== undefined) {\n return stop(\n state,\n `Shorthand '${remainder}' is defined in the template, not the overlay. Edit the template to remove it.`\n );\n }\n return stop(state, `Shorthand '${remainder}' not found.`);\n }\n const merged = await getAgent(agentId, workspaceRoot);\n const fallback = merged?.modelShorthands?.[remainder];\n const note = fallback !== undefined ? ` (still resolves to '${fallback}' from template)` : '';\n return stop(state, `Removed shorthand: ${remainder}${note}.`);\n }\n\n if (subcommand.startsWith('-')) {\n return stop(state, `Unknown option: ${subcommand}\\n${formatHelp()}`);\n }\n\n // Bare model name / shorthand. Reject extra args so a typoed subcommand like\n // `/model rmove flash` doesn't get stored as MODEL=rmove.\n if (remainder !== '') {\n return stop(state, `Unknown subcommand: ${subcommand}\\n${formatHelp()}`);\n }\n\n const guard = await ensureOverlay(state, agentId, workspaceRoot);\n if (guard) return guard;\n\n const agent = await getAgent(agentId, workspaceRoot);\n const shorthands = agent?.modelShorthands ?? {};\n const matched = Object.prototype.hasOwnProperty.call(shorthands, subcommand);\n const fullModel = matched ? shorthands[subcommand]! : subcommand;\n await setModel(agentId, fullModel, workspaceRoot);\n\n if (matched) {\n return stop(state, `Set MODEL to ${fullModel} (shorthand '${subcommand}').`);\n }\n if (looksLikeShorthand(subcommand)) {\n return stop(\n state,\n `Set MODEL to ${fullModel}. (No shorthand matched — was that the literal model name? Run /model add ${subcommand} <full-name> if not.)`\n );\n }\n return stop(state, `Set MODEL to ${fullModel}.`);\n}\n","import type { RouterState } from './types.js';\nimport { sendControlRequest } from '../../cli/supervisor-control.js';\n\nexport async function slashRestart(state: RouterState): Promise<RouterState> {\n if (!/^\\/restart(\\s|$)/.test(state.message)) return state;\n\n // Gated to user messages by USER_ROUTERS in resolveRouters — an agent\n // tool output that happens to start with \"/restart\" never reaches us.\n // The supervisor enqueues the post-restart \"Clawmini restarted vX.Y.Z\"\n // SystemMessage on its side so the on-disk record reflects whether the\n // restart was actually scheduled. We just plumb chatId + messageId\n // through and surface any control-channel error to the user.\n let res;\n try {\n res = await sendControlRequest({\n action: 'restart',\n chatId: state.chatId,\n messageId: state.messageId,\n });\n } catch (err) {\n return stop(\n state,\n `Could not reach supervisor: ${err instanceof Error ? err.message : String(err)}.`\n );\n }\n\n if (!res.ok) {\n return stop(state, `Restart aborted: ${res.error ?? 'unknown error'}.`);\n }\n\n return stop(state, 'Restarting clawmini...');\n}\n\nfunction stop(state: RouterState, reply: string): RouterState {\n return { ...state, message: '', action: 'stop', reply };\n}\n","import type { RouterState } from './types.js';\nimport { sendControlRequest } from '../../cli/supervisor-control.js';\n\nexport async function slashShutdown(state: RouterState): Promise<RouterState> {\n if (!/^\\/shutdown(\\s|$)/.test(state.message)) return state;\n\n // Gated to user messages by USER_ROUTERS in resolveRouters — agents cannot\n // trigger this even via tool output that happens to start with /shutdown.\n let res;\n try {\n res = await sendControlRequest({ action: 'shutdown' });\n } catch (err) {\n return stop(\n state,\n `Could not reach supervisor: ${err instanceof Error ? err.message : String(err)}.`\n );\n }\n\n if (!res.ok) {\n return stop(state, `Shutdown aborted: ${res.error ?? 'unknown error'}.`);\n }\n\n return stop(state, 'Shutting down clawmini supervisor...');\n}\n\nfunction stop(state: RouterState, reply: string): RouterState {\n return { ...state, message: '', action: 'stop', reply };\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nlet cached: string | null = null;\n\n/**\n * Read the version from the clawmini package.json. Walks up from the current\n * module's location until a package.json named \"clawmini\" is found.\n */\nexport function getClawminiVersion(): string {\n if (cached !== null) return cached;\n let dir = path.dirname(fileURLToPath(import.meta.url));\n while (dir !== path.parse(dir).root) {\n const pkgPath = path.join(dir, 'package.json');\n if (fs.existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')) as {\n name?: string;\n version?: string;\n };\n if (pkg.name === 'clawmini' && typeof pkg.version === 'string') {\n cached = pkg.version;\n return cached;\n }\n } catch {\n // try parent\n }\n }\n dir = path.dirname(dir);\n }\n cached = 'unknown';\n return cached;\n}\n","import type { RouterState } from './types.js';\nimport { detectInstall } from '../../cli/install-detection.js';\nimport { sendControlRequest } from '../../cli/supervisor-control.js';\nimport { isAcceptableVersion } from '../../cli/supervisor-actions.js';\nimport { getClawminiVersion } from '../../shared/version.js';\n\nexport async function slashUpgrade(state: RouterState): Promise<RouterState> {\n const trimmed = state.message.trim();\n if (!/^\\/upgrade(\\s|$)/.test(trimmed)) return state;\n\n // Gated to user messages by USER_ROUTERS in resolveRouters.\n const info = detectInstall();\n if (!info.isNpmGlobal) {\n return stop(\n state,\n `Cannot upgrade: clawmini is not installed via \\`npm install -g\\` ` +\n `(running from ${info.entryRealPath}). Skipping.`\n );\n }\n\n const rest = trimmed.slice('/upgrade'.length).trim();\n\n // Bare `/upgrade` is informational. Requiring an explicit version means a\n // misclick (or a malicious tool output that somehow reached this router)\n // can't silently install whatever the npm registry currently calls\n // `latest`. The user has to opt in to the version they want.\n if (rest === '') {\n return stop(\n state,\n [\n `Currently running clawmini v${getClawminiVersion()}.`,\n '/upgrade requires an explicit target:',\n ' /upgrade latest — install whatever npm reports as the latest tag',\n ' /upgrade <version> — install a specific version (e.g. /upgrade 0.0.7)',\n ].join('\\n')\n );\n }\n\n // Single token only — extra args could be smuggled into the npm command\n // line otherwise (npm install -g clawmini@<rest> via shell).\n if (!/^\\S+$/.test(rest)) {\n return stop(state, 'Usage: /upgrade <version>');\n }\n\n const version = rest;\n if (!isAcceptableVersion(version)) {\n return stop(state, `Invalid version: ${version}`);\n }\n\n // The supervisor enqueues the post-upgrade reply on its side based on the\n // outcome of `npm install -g`, so we don't pre-queue anything here.\n let res;\n try {\n res = await sendControlRequest({\n action: 'upgrade',\n version,\n chatId: state.chatId,\n messageId: state.messageId,\n });\n } catch (err) {\n return stop(\n state,\n `Could not reach supervisor: ${err instanceof Error ? err.message : String(err)}.`\n );\n }\n\n if (!res.ok) {\n return stop(state, `Upgrade aborted: ${res.error ?? 'unknown error'}.`);\n }\n\n return stop(state, `Upgrading clawmini to ${version}... services will restart shortly.`);\n}\n\nfunction stop(state: RouterState, reply: string): RouterState {\n return { ...state, message: '', action: 'stop', reply };\n}\n","import type { RouterState } from './types.js';\nimport { randomUUID } from 'node:crypto';\n\nexport interface SessionTimeoutConfig {\n timeout?: string;\n prompt?: string;\n}\n\n/**\n * Router that automatically starts a new session after a period of inactivity.\n *\n * To register this router, add it to your `~/.gemini/settings.json`:\n * ```json\n * {\n * \"routers\": [\n * {\n * \"use\": \"session-timeout\",\n * \"with\": {\n * \"timeout\": \"60m\",\n * \"prompt\": \"This chat session has ended. Save any important details from it to your memory. When finished, reply with NO_REPLY_NECESSARY.\"\n * }\n * }\n * ]\n * }\n * ```\n */\nexport function createSessionTimeoutRouter(config: SessionTimeoutConfig = {}) {\n const timeStr = config.timeout ?? '60m';\n const prompt =\n config.prompt ??\n 'This chat session has ended. Save any important details from it to your memory. When finished, reply with NO_REPLY_NECESSARY.';\n\n return function (state: RouterState): RouterState {\n if (state.env?.__SESSION_TIMEOUT__ === 'true') {\n return state;\n }\n\n if (state.subagentId) {\n return state;\n }\n\n const sessionId = state.sessionId || crypto.randomUUID();\n const jobId = `__session_timeout__${sessionId}`;\n\n const jobs = {\n ...state.jobs,\n remove: [...(state.jobs?.remove || []), jobId, '__session_timeout__'],\n };\n\n return {\n ...state,\n sessionId,\n jobs: {\n ...jobs,\n add: [\n ...(jobs.add || []),\n // Add a job after the timeout that will send the prompt, reply to the user,\n // start a fresh session, and delete the job\n {\n id: jobId,\n schedule: { at: timeStr },\n message: prompt,\n reply: '[@clawmini/session-timeout] Starting a fresh session...',\n nextSessionId: randomUUID(),\n session: { type: 'existing', id: sessionId },\n env: { __SESSION_TIMEOUT__: 'true' },\n jobs: {\n remove: [jobId],\n },\n },\n ],\n },\n };\n };\n}\n","import { spawn } from 'node:child_process';\nimport type { RouterState } from './routers/types.js';\nimport { slashNew } from './routers/slash-new.js';\nimport { slashCommand } from './routers/slash-command.js';\nimport { slashStop } from './routers/slash-stop.js';\nimport { slashInterrupt } from './routers/slash-interrupt.js';\nimport { slashPolicies } from './routers/slash-policies.js';\nimport { slashModel } from './routers/slash-model.js';\nimport { slashRestart } from './routers/slash-restart.js';\nimport { slashShutdown } from './routers/slash-shutdown.js';\nimport { slashUpgrade } from './routers/slash-upgrade.js';\nimport { createSessionTimeoutRouter } from './routers/session-timeout.js';\nimport type { RouterConfig } from '../shared/config.js';\n\nexport const GLOBAL_ROUTERS: RouterConfig[] = ['@clawmini/session-timeout'];\n\nexport const USER_ROUTERS: RouterConfig[] = [\n '@clawmini/slash-new',\n '@clawmini/slash-command',\n '@clawmini/slash-stop',\n '@clawmini/slash-interrupt',\n '@clawmini/slash-policies',\n '@clawmini/slash-model',\n '@clawmini/slash-restart',\n '@clawmini/slash-shutdown',\n '@clawmini/slash-upgrade',\n];\n\nexport function resolveRouters(\n userRouters: RouterConfig[],\n isUserMessage: boolean\n): RouterConfig[] {\n const resolvedGlobals: RouterConfig[] = [];\n const resolvedUsers: RouterConfig[] = [];\n\n const userConfigMap = new Map<string, unknown>();\n for (const r of userRouters) {\n const name = typeof r === 'string' ? r : r.use;\n const config = typeof r === 'string' ? {} : r.with || {};\n\n if (name.startsWith('@clawmini/')) {\n userConfigMap.set(name, config);\n } else {\n resolvedUsers.push(r);\n }\n }\n\n for (const globalRouter of GLOBAL_ROUTERS) {\n const name = typeof globalRouter === 'string' ? globalRouter : globalRouter.use;\n const baseConfig = typeof globalRouter === 'string' ? {} : globalRouter.with || {};\n const userConfig = userConfigMap.get(name) || {};\n const mergedConfig = { ...baseConfig, ...userConfig };\n\n resolvedGlobals.push({ use: name, with: mergedConfig });\n }\n\n const defaultUserRouters: RouterConfig[] = [];\n for (const defaultUserRouter of USER_ROUTERS) {\n const name = typeof defaultUserRouter === 'string' ? defaultUserRouter : defaultUserRouter.use;\n const baseConfig = typeof defaultUserRouter === 'string' ? {} : defaultUserRouter.with || {};\n const userConfig = userConfigMap.get(name) || {};\n const mergedConfig = { ...baseConfig, ...userConfig };\n\n defaultUserRouters.push({ use: name, with: mergedConfig });\n }\n\n if (isUserMessage) {\n return [...resolvedGlobals, ...defaultUserRouters, ...resolvedUsers];\n } else {\n return resolvedGlobals;\n }\n}\n\nexport async function executeRouterPipeline(\n initialState: RouterState,\n routers: RouterConfig[]\n): Promise<RouterState> {\n let state = { ...initialState };\n\n for (const routerDef of routers) {\n if (state.action === 'stop') {\n break;\n }\n\n const router = typeof routerDef === 'string' ? routerDef : routerDef.use;\n const config = typeof routerDef === 'string' ? {} : routerDef.with || {};\n\n if (router === '@clawmini/slash-new') {\n state = slashNew(state);\n } else if (router === '@clawmini/slash-command') {\n state = await slashCommand(state);\n } else if (router === '@clawmini/slash-stop') {\n state = slashStop(state);\n } else if (router === '@clawmini/slash-interrupt') {\n state = slashInterrupt(state);\n } else if (router === '@clawmini/slash-policies') {\n state = await slashPolicies(state);\n } else if (router === '@clawmini/slash-model') {\n state = await slashModel(state);\n } else if (router === '@clawmini/slash-restart') {\n state = await slashRestart(state);\n } else if (router === '@clawmini/slash-shutdown') {\n state = await slashShutdown(state);\n } else if (router === '@clawmini/slash-upgrade') {\n state = await slashUpgrade(state);\n } else if (router === '@clawmini/session-timeout') {\n state = createSessionTimeoutRouter(config)(state);\n } else {\n // Execute as custom shell command\n try {\n state = await executeCustomRouter(router, state);\n } catch (err) {\n // Silent failure handling: log but do not halt\n console.error(`Router error [${router}]:`, err);\n }\n }\n }\n\n return state;\n}\n\nasync function executeCustomRouter(command: string, state: RouterState): Promise<RouterState> {\n return new Promise((resolve, reject) => {\n // We run the command via shell\n const child = spawn(command, { shell: true });\n\n let stdout = '';\n let stderr = '';\n\n child.stdout.on('data', (chunk) => {\n stdout += chunk.toString();\n });\n child.stderr.on('data', (chunk) => {\n stderr += chunk.toString();\n });\n\n // timeout fallback to avoid hanging indefinitely\n const timer = setTimeout(() => {\n child.kill();\n reject(new Error('Router execution timed out'));\n }, 10000);\n\n child.on('close', (code) => {\n clearTimeout(timer);\n if (code !== 0) {\n return reject(new Error(`Process exited with code ${code}. Stderr: ${stderr}`));\n }\n\n try {\n const result = JSON.parse(stdout);\n const newState = { ...state };\n\n if (typeof result.message === 'string') newState.message = result.message;\n if (typeof result.agent === 'string') newState.agentId = result.agent;\n if (typeof result.session === 'string') newState.sessionId = result.session;\n if (typeof result.env === 'object' && result.env !== null) {\n newState.env = { ...newState.env, ...result.env };\n }\n if (typeof result.reply === 'string') newState.reply = result.reply;\n if (typeof result.action === 'string') newState.action = result.action;\n\n resolve(newState);\n } catch (err) {\n reject(new Error(`Failed to parse router output: ${err}. Stdout: ${stdout}`));\n }\n });\n\n child.on('error', (err) => {\n clearTimeout(timer);\n reject(err);\n });\n\n // Write state to stdin\n const inputState = {\n message: state.message,\n chatId: state.chatId,\n agentId: state.agentId,\n sessionId: state.sessionId,\n env: state.env,\n action: state.action,\n };\n\n if (child.stdin) {\n child.stdin.on('error', (err) => {\n if ((err as NodeJS.ErrnoException).code !== 'EPIPE') {\n console.error('stdin error:', err);\n }\n });\n child.stdin.write(JSON.stringify(inputState));\n child.stdin.end();\n }\n });\n}\n","import { type FallbackSchema } from '../../shared/config.js';\nimport {\n getActiveEnvironmentInfo,\n getEnvironmentSearchDirs,\n readEnvironment,\n substituteLayeredEnvDir,\n} from '../../shared/workspace.js';\nimport { z } from 'zod';\n\nexport type Fallback = z.infer<typeof FallbackSchema>;\n\nfunction formatEnvironmentPrefix(\n prefix: string,\n searchDirs: string[],\n replacements: { targetPath: string; executionCwd: string; envArgs: string }\n): string {\n let out = substituteLayeredEnvDir(prefix, searchDirs);\n const map: Record<string, string> = {\n '{WORKSPACE_DIR}': replacements.targetPath,\n '{AGENT_DIR}': replacements.executionCwd,\n '{HOME_DIR}': process.env.HOME || '',\n '{ENV_ARGS}': replacements.envArgs,\n };\n out = out.replace(\n /{(WORKSPACE_DIR|AGENT_DIR|HOME_DIR|ENV_ARGS)}/g,\n (match) => map[match] || match\n );\n return out;\n}\n\nexport async function sandboxExecutionContext(\n initialCommand: string,\n env: Record<string, string>,\n agentSpecificEnvKeys: Set<string>,\n executionCwd: string,\n cwd: string\n): Promise<string> {\n let command = initialCommand;\n const activeEnvInfo = await getActiveEnvironmentInfo(executionCwd, cwd);\n if (!activeEnvInfo) return command;\n\n const activeEnvName = activeEnvInfo.name;\n const activeEnv = await readEnvironment(activeEnvName, cwd);\n const searchDirs = await getEnvironmentSearchDirs(activeEnvName, cwd);\n\n if (activeEnv?.env) {\n for (const [key, value] of Object.entries(activeEnv.env)) {\n if (value === false) {\n delete env[key];\n agentSpecificEnvKeys.delete(key);\n } else {\n let interpolatedValue = String(value);\n interpolatedValue = interpolatedValue.replace(/\\{PATH\\}/g, process.env.PATH || '');\n interpolatedValue = substituteLayeredEnvDir(interpolatedValue, searchDirs);\n interpolatedValue = interpolatedValue.replace(\n /\\{WORKSPACE_DIR\\}/g,\n activeEnvInfo.targetPath\n );\n env[key] = interpolatedValue;\n agentSpecificEnvKeys.add(key);\n }\n }\n }\n\n if (activeEnv?.prefix) {\n const envArgs = Array.from(agentSpecificEnvKeys)\n .map((key) => {\n if (activeEnv.envFormat) {\n return activeEnv.envFormat.replace('{key}', key);\n }\n return key;\n })\n .join(' ');\n\n const prefixReplaced = formatEnvironmentPrefix(activeEnv.prefix, searchDirs, {\n targetPath: activeEnvInfo.targetPath,\n executionCwd: executionCwd,\n envArgs,\n });\n\n if (prefixReplaced.includes('{COMMAND}')) {\n command = prefixReplaced.replace('{COMMAND}', command);\n } else {\n command = `${prefixReplaced} ${command}`;\n }\n }\n\n return command;\n}\n","import type { RunCommandFn, RunCommandResult } from './types.js';\nimport type { Agent } from '../../shared/config.js';\n\nasync function runExtractionCommand(\n name: string,\n command: string,\n runCommand: RunCommandFn,\n cwd: string,\n env: Record<string, string>,\n mainResult: RunCommandResult,\n signal?: AbortSignal\n): Promise<{ result?: string; error?: string }> {\n try {\n console.log(`Executing extraction command (${name}): ${command}`);\n const res = await runCommand({\n command,\n cwd,\n env,\n stdin: mainResult.stdout,\n signal,\n });\n if (res.exitCode === 0) {\n return { result: res.stdout.trim() };\n } else {\n return { error: `${name} failed: ${res.stderr}` };\n }\n } catch (e) {\n return { error: `${name} error: ${(e as Error).message}` };\n }\n}\n\nexport async function extractMessageContent(\n context: { command: string; env: Record<string, string>; currentAgent: Agent },\n mainResult: RunCommandResult,\n runCommand: RunCommandFn,\n executionCwd: string,\n signal?: AbortSignal\n): Promise<{ result?: string; error?: string }> {\n if (!context.currentAgent.commands?.getMessageContent) return {};\n return runExtractionCommand(\n 'getMessageContent',\n context.currentAgent.commands.getMessageContent,\n runCommand,\n executionCwd,\n context.env,\n mainResult,\n signal\n );\n}\n\nexport async function extractSessionId(\n context: { command: string; env: Record<string, string>; currentAgent: Agent },\n mainResult: RunCommandResult,\n runCommand: RunCommandFn,\n executionCwd: string,\n signal?: AbortSignal\n): Promise<{ result?: string; error?: string }> {\n if (!context.currentAgent.commands?.getSessionId) return {};\n return runExtractionCommand(\n 'getSessionId',\n context.currentAgent.commands.getSessionId,\n runCommand,\n executionCwd,\n context.env,\n mainResult,\n signal\n );\n}\n","export function formatPendingMessages(payloads: string[]): string {\n return payloads.map((text) => `<message>\\n${text}\\n</message>`).join('\\n\\n');\n}\n\nexport function isNewSession(env: Record<string, string>): boolean {\n return env['SESSION_ID'] === undefined;\n}\n","import { emitTyping } from '../events.js';\nimport type { ExecutionResponse, Message, RunCommandFn } from './types.js';\nimport { type Fallback } from './agent-context.js';\nimport { extractMessageContent, extractSessionId } from './agent-extractors.js';\nimport type { AgentSession } from './agent-session.js';\nimport { isNewSession } from './utils.js';\n\nexport function calculateDelay(\n attempt: number,\n baseDelayMs: number,\n isFallback: boolean = false\n): number {\n const effectiveAttempt = isFallback ? attempt + 1 : attempt;\n if (effectiveAttempt <= 0) return 0;\n const delay = baseDelayMs * Math.pow(2, effectiveAttempt - 1);\n return Math.min(delay, 15000);\n}\n\nconst sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\n\nexport class AgentRunner {\n constructor(\n private readonly session: AgentSession,\n private readonly runCommand: RunCommandFn\n ) {}\n\n private async withTypingIndicator<T>(fn: () => Promise<T>): Promise<T> {\n const interval = setInterval(() => emitTyping(this.session.chatId), 5000);\n try {\n return await fn();\n } finally {\n clearInterval(interval);\n }\n }\n\n private *getExecutionAttempts() {\n const fallbacks = this.session.settings.fallbacks || [];\n const executionConfigs = [\n { fallback: undefined, retries: 0, delayMs: 1000 },\n ...fallbacks.map((f) => ({ fallback: f, retries: f.retries, delayMs: f.delayMs })),\n ];\n\n for (let configIdx = 0; configIdx < executionConfigs.length; configIdx++) {\n const config = executionConfigs[configIdx]!;\n const isFallbackConfig = configIdx > 0;\n\n for (let attempt = 0; attempt <= config.retries; attempt++) {\n yield {\n fallback: config.fallback,\n delay: calculateDelay(attempt, config.delayMs, isFallbackConfig),\n };\n }\n }\n }\n\n private async executeSingleAttempt(\n message: Message,\n fallback?: Fallback | undefined,\n signal?: AbortSignal | undefined\n ): Promise<{ success: boolean; response?: ExecutionResponse }> {\n const context = await this.session.buildExecutionContext(\n message.content,\n message.env,\n fallback\n );\n\n if (!context) return { success: false };\n\n const mainResult = await this.withTypingIndicator(() =>\n this.runCommand({\n command: context.command,\n cwd: this.session.workDirectory,\n env: context.env,\n signal,\n })\n );\n\n let success = mainResult.exitCode === 0;\n let finalContent = mainResult.stdout.trim();\n const additonalErrors = [];\n\n if (success && context.currentAgent.commands?.getMessageContent) {\n const extraction = await extractMessageContent(\n context,\n mainResult,\n this.runCommand,\n this.session.workDirectory,\n signal\n );\n if (extraction.error) additonalErrors.push(extraction.error);\n if (extraction.result !== undefined) finalContent = extraction.result.trim();\n if (!finalContent) success = false;\n }\n\n let extractedSessionId: string | undefined;\n\n if (success && isNewSession(message.env) && context.currentAgent.commands?.getSessionId) {\n const extraction = await extractSessionId(\n context,\n mainResult,\n this.runCommand,\n this.session.workDirectory,\n signal\n );\n if (extraction.error) additonalErrors.push(extraction.error);\n if (extraction.result) {\n extractedSessionId = extraction.result;\n }\n }\n\n return {\n success,\n response: {\n messageId: message.id,\n content: finalContent,\n command: context.command,\n cwd: this.session.workDirectory,\n extractedSessionId,\n result: {\n ...mainResult,\n stderr: [mainResult.stderr, ...additonalErrors].join('\\n\\n'),\n },\n },\n };\n }\n\n async executeWithFallbacks(\n message: Message,\n signal?: AbortSignal | undefined\n ): Promise<ExecutionResponse | undefined> {\n let lastResponse: ExecutionResponse | undefined;\n\n for (const attempt of this.getExecutionAttempts()) {\n if (attempt.delay > 0) {\n await this.session.logger.logCommandRetry({\n messageId: message.id,\n content: `Error running agent, retrying in ${Math.round(attempt.delay / 1000)} seconds...`,\n cwd: this.session.workDirectory,\n });\n await sleep(attempt.delay);\n }\n\n const attemptResult = await this.executeSingleAttempt(message, attempt.fallback, signal);\n\n lastResponse = attemptResult.response || lastResponse;\n if (attemptResult.success) {\n return lastResponse;\n }\n }\n\n return lastResponse;\n }\n}\n","import { spawn } from 'node:child_process';\nimport type { RunCommandFn } from '../agent/types.js';\n\nconst LOG_TO_TERMINAL = false;\n\nexport const runCommand: RunCommandFn = async ({\n command,\n cwd,\n env,\n stdin,\n signal,\n}: Parameters<RunCommandFn>[0] & { logToTerminal?: boolean }) => {\n return new Promise<{ stdout: string; stderr: string; exitCode: number }>((resolve, reject) => {\n console.log('RUN: ', command);\n const p = spawn(command, { shell: true, cwd, env, signal });\n\n if (stdin && p.stdin) {\n p.stdin.on('error', (err) => {\n if ((err as NodeJS.ErrnoException).code !== 'EPIPE') {\n console.error('stdin error:', err);\n }\n });\n p.stdin.write(stdin);\n p.stdin.end();\n }\n\n let stdout = '';\n let stderr = '';\n\n if (p.stdout) {\n p.stdout.on('data', (data) => {\n stdout += data.toString();\n if (LOG_TO_TERMINAL && !stdin) {\n process.stdout.write(data);\n }\n });\n }\n\n if (p.stderr) {\n p.stderr.on('data', (data) => {\n stderr += data.toString();\n if (LOG_TO_TERMINAL && !stdin) {\n process.stderr.write(data);\n }\n });\n }\n\n p.on('close', (code) => {\n resolve({ stdout, stderr, exitCode: code ?? 1 });\n });\n\n p.on('error', (err) => {\n if (err.name === 'AbortError') {\n reject(err);\n return;\n }\n resolve({ stdout: '', stderr: err.toString(), exitCode: 1 });\n });\n });\n};\n","import {\n appendMessage,\n getMessages,\n findLastMessage as findLastMessageFromStorage,\n type ChatMessage,\n type CommandLogMessage,\n type UserMessage,\n type SystemMessage,\n type AgentReplyMessage,\n type ToolMessage,\n type PolicyRequestMessage,\n type SubagentStatusMessage,\n} from '../chats.js';\nimport type { Logger } from './types.js';\n\nexport function createChatLogger(\n chatId: string,\n subagentId?: string,\n sessionId?: string,\n turnId?: string\n): Logger {\n async function append<T extends ChatMessage>(msg: T): Promise<T> {\n let finalMsg: T = msg;\n if (subagentId) finalMsg = { ...finalMsg, subagentId };\n if (turnId) finalMsg = { ...finalMsg, turnId };\n await appendMessage(chatId, finalMsg);\n return finalMsg;\n }\n\n return {\n append,\n\n getMessages: async (limit?: number) => {\n const msgs = await getMessages(chatId);\n let filtered = msgs.filter((m) => m.subagentId === subagentId);\n if (limit !== undefined && limit > 0) {\n filtered = filtered.slice(-limit);\n }\n return filtered;\n },\n\n findLastMessage: async (predicate) => {\n return findLastMessageFromStorage(chatId, (msg: ChatMessage) => {\n if (msg.subagentId !== subagentId) return false;\n return predicate(msg);\n });\n },\n\n logUserMessage: async (msg) =>\n append({\n id: crypto.randomUUID(),\n role: 'user',\n content: msg,\n timestamp: new Date().toISOString(),\n sessionId,\n } satisfies UserMessage),\n\n logCommandResult: async ({ messageId, content, command, cwd, result }) =>\n append({\n id: crypto.randomUUID(),\n role: 'command',\n content,\n timestamp: new Date().toISOString(),\n sessionId,\n\n messageId,\n\n command,\n cwd,\n stdout: result.stdout,\n stderr: result.stderr,\n exitCode: result.exitCode,\n } satisfies CommandLogMessage),\n\n logSystemEvent: async ({ content }) =>\n append({\n id: crypto.randomUUID(),\n role: 'command',\n content,\n timestamp: new Date().toISOString(),\n sessionId,\n\n messageId: crypto.randomUUID(),\n\n stderr: '',\n command: '',\n cwd: '',\n stdout: '',\n exitCode: 0,\n } satisfies CommandLogMessage),\n\n logAutomaticReply: async ({ messageId, content }) =>\n append({\n id: crypto.randomUUID(),\n role: 'system',\n content,\n timestamp: new Date().toISOString(),\n sessionId,\n\n messageId,\n event: 'router',\n displayRole: 'agent',\n } satisfies SystemMessage),\n\n logCommandRetry: async ({ messageId, content, cwd }) =>\n append({\n id: crypto.randomUUID(),\n role: 'command',\n content,\n timestamp: new Date().toISOString(),\n sessionId,\n\n messageId,\n\n // TODO remove these? Or include the actual command that was run?\n command: 'retry-delay',\n stderr: '',\n stdout: '',\n cwd,\n exitCode: 0,\n } satisfies CommandLogMessage),\n\n logSystemMessage: async ({ content, event, messageId, displayRole, jobId }) => {\n const msg: SystemMessage = {\n id: crypto.randomUUID(),\n role: 'system',\n content,\n event,\n timestamp: new Date().toISOString(),\n sessionId,\n };\n if (messageId !== undefined) {\n msg.messageId = messageId;\n }\n if (displayRole !== undefined) {\n msg.displayRole = displayRole;\n }\n if (jobId !== undefined) {\n msg.jobId = jobId;\n }\n return append<SystemMessage>(msg);\n },\n\n logSubagentStatus: async ({ subagentId: targetSubagentId, status }) => {\n const msg: SubagentStatusMessage = {\n id: crypto.randomUUID(),\n role: 'subagent_status',\n content: `Subagent ${status}`,\n subagentId: targetSubagentId,\n status,\n timestamp: new Date().toISOString(),\n sessionId,\n };\n return append<SubagentStatusMessage>(msg);\n },\n\n logAgentReply: async ({ content, files }) => {\n const msg: AgentReplyMessage = {\n id: crypto.randomUUID(),\n role: 'agent',\n content,\n timestamp: new Date().toISOString(),\n sessionId,\n };\n if (files !== undefined) {\n msg.files = files;\n }\n return append<AgentReplyMessage>(msg);\n },\n\n logToolMessage: async ({ content, messageId, name, payload }) => {\n const msg: ToolMessage = {\n id: crypto.randomUUID(),\n role: 'tool',\n content,\n messageId,\n name,\n payload,\n timestamp: new Date().toISOString(),\n sessionId,\n };\n return append<ToolMessage>(msg);\n },\n\n logPolicyRequestMessage: async ({\n content,\n messageId,\n requestId,\n commandName,\n args,\n status,\n }) => {\n const msg: PolicyRequestMessage = {\n id: crypto.randomUUID(),\n role: 'policy',\n content,\n messageId,\n requestId,\n commandName,\n args,\n status,\n timestamp: new Date().toISOString(),\n sessionId,\n };\n return append<PolicyRequestMessage>(msg);\n },\n };\n}\n","export function applyEnvOverrides(\n targetEnv: Record<string, string>,\n overrides?: Record<string, string | boolean>\n): void {\n if (!overrides) return;\n\n for (const [key, val] of Object.entries(overrides)) {\n if (val === true && process.env[key] !== undefined) {\n targetEnv[key] = process.env[key];\n } else if (typeof val === 'string') {\n targetEnv[key] = val;\n }\n }\n}\n\nexport function getActiveEnvKeys(\n ...envs: (Record<string, string | boolean> | undefined)[]\n): Set<string> {\n const keys = new Set<string>();\n for (const env of envs) {\n if (!env) continue;\n Object.entries(env).forEach(([key, val]) => {\n if (val === true || typeof val === 'string') keys.add(key);\n });\n }\n return keys;\n}\n","import crypto from 'node:crypto';\nimport type { Settings } from '../shared/config.js';\n\n// In-memory secret generated on daemon startup.\n// Valid tokens will only last for the lifetime of the daemon process.\nconst DAEMON_SECRET = crypto.randomBytes(32);\n\nexport interface TokenPayload {\n chatId: string;\n agentId: string;\n sessionId: string;\n subagentId?: string;\n turnId?: string;\n timestamp: number;\n}\n\nexport function generateToken(payload: TokenPayload): string {\n const payloadStr = Buffer.from(JSON.stringify(payload)).toString('base64');\n const hmac = crypto.createHmac('sha256', DAEMON_SECRET).update(payloadStr).digest('hex');\n return `${payloadStr}.${hmac}`;\n}\n\nexport function validateToken(token: string): TokenPayload | null {\n try {\n const parts = token.split('.');\n if (parts.length !== 2) return null;\n\n const [payloadStr, signature] = parts;\n if (!payloadStr || !signature) return null;\n\n const expectedHmac = crypto\n .createHmac('sha256', DAEMON_SECRET)\n .update(payloadStr)\n .digest('hex');\n\n const signatureBuffer = Buffer.from(signature, 'hex');\n const expectedHmacBuffer = Buffer.from(expectedHmac, 'hex');\n\n if (\n signatureBuffer.length !== expectedHmacBuffer.length ||\n !crypto.timingSafeEqual(signatureBuffer, expectedHmacBuffer)\n ) {\n return null;\n }\n\n const payloadJson = Buffer.from(payloadStr, 'base64').toString('utf8');\n return JSON.parse(payloadJson) as TokenPayload;\n } catch {\n return null;\n }\n}\n\nexport function getApiContext(settings?: Settings) {\n if (settings?.api === undefined) return null;\n let isApiEnabled = false;\n let apiHost = '127.0.0.1';\n let apiPort = 3000;\n let proxyHost: string | undefined = undefined;\n\n if (typeof settings.api === 'boolean') {\n isApiEnabled = settings.api;\n } else if (typeof settings.api === 'object') {\n isApiEnabled = true;\n apiHost = settings.api.host ?? '127.0.0.1';\n apiPort = settings.api.port ?? 3000;\n proxyHost = settings.api.proxy_host;\n }\n\n if (!isApiEnabled) return null;\n return { host: apiHost, port: apiPort, proxy_host: proxyHost };\n}\n","export interface AgentTask {\n id: string;\n rootChatId: string;\n dirPath: string;\n sessionId: string;\n text?: string;\n execute: (signal: AbortSignal) => Promise<void>;\n}\n\nclass ResourceLock {\n private resources = new Map<\n string,\n {\n activeWorkspace: string;\n count: number;\n waiters: Array<{\n workspaceId: string;\n resolve: () => void;\n reject: (err: Error) => void;\n }>;\n }\n >();\n\n async acquire(resourceId: string, workspaceId: string, signal?: AbortSignal): Promise<void> {\n if (signal?.aborted) {\n const error = new Error('Task aborted');\n error.name = 'AbortError';\n throw error;\n }\n\n const res = this.resources.get(resourceId);\n if (!res) {\n this.resources.set(resourceId, { activeWorkspace: workspaceId, count: 1, waiters: [] });\n return;\n }\n\n if (res.activeWorkspace === workspaceId) {\n // Allow re-entrancy for the same rootChatId (workspaceId) so that the\n // root agent and its subagents can run in parallel in the same directory.\n // This ensures the root agent remains available to coordinate its subagents,\n // assuming it will manage conflicts appropriately.\n // Note: This risks starvation if agents/subagents from this workspace never release the resource.\n res.count++;\n return;\n }\n\n return new Promise<void>((resolve, reject) => {\n const waiter = { workspaceId, resolve, reject };\n res!.waiters.push(waiter);\n\n if (signal) {\n const onAbort = () => {\n const idx = res!.waiters.indexOf(waiter);\n if (idx !== -1) {\n res!.waiters.splice(idx, 1);\n const error = new Error('Task aborted');\n error.name = 'AbortError';\n reject(error);\n }\n };\n signal.addEventListener('abort', onAbort);\n\n // Intercept resolve to clean up the listener\n waiter.resolve = () => {\n signal.removeEventListener('abort', onAbort);\n resolve();\n };\n // Intercept reject to clean up the listener\n waiter.reject = (err: Error) => {\n signal.removeEventListener('abort', onAbort);\n reject(err);\n };\n }\n });\n }\n\n release(resourceId: string, _workspaceId: string) {\n const res = this.resources.get(resourceId);\n if (!res) return;\n\n res.count--;\n if (res.count === 0) {\n if (res.waiters.length > 0) {\n const nextWorkspace = res.waiters[0]!.workspaceId;\n res.activeWorkspace = nextWorkspace;\n\n const remainingWaiters = [];\n for (const waiter of res.waiters) {\n if (waiter.workspaceId === nextWorkspace) {\n res.count++;\n waiter.resolve();\n } else {\n remainingWaiters.push(waiter);\n }\n }\n res.waiters = remainingWaiters;\n } else {\n this.resources.delete(resourceId);\n }\n }\n }\n}\n\nclass TaskQueue {\n private queue: Array<{\n task: AgentTask;\n resolve: () => void;\n reject: (err: unknown) => void;\n }> = [];\n private activeTask: { task: AgentTask; controller: AbortController } | null = null;\n private isProcessing = false;\n\n constructor(\n public readonly sessionId: string,\n private resourceLock: ResourceLock,\n private onEmpty: (sessionId: string) => void\n ) {}\n\n enqueue(task: AgentTask): Promise<void> {\n return new Promise((resolve, reject) => {\n this.queue.push({ task, resolve, reject });\n this.process();\n });\n }\n\n private async process() {\n if (this.isProcessing || this.activeTask || this.queue.length === 0) return;\n this.isProcessing = true;\n\n while (this.queue.length > 0) {\n const next = this.queue.shift()!;\n const controller = new AbortController();\n this.activeTask = { task: next.task, controller };\n\n let acquired = false;\n try {\n await this.resourceLock.acquire(next.task.dirPath, next.task.rootChatId, controller.signal);\n acquired = true;\n\n if (!controller.signal.aborted) {\n await next.task.execute(controller.signal);\n }\n next.resolve();\n } catch (err) {\n next.reject(err);\n } finally {\n if (acquired) {\n this.resourceLock.release(next.task.dirPath, next.task.rootChatId);\n }\n this.activeTask = null;\n }\n }\n\n this.isProcessing = false;\n this.onEmpty(this.sessionId);\n }\n\n abortAll() {\n const error = new Error('Task aborted');\n error.name = 'AbortError';\n\n if (this.activeTask) {\n this.activeTask.controller.abort(error);\n }\n\n for (const qTask of this.queue) {\n qTask.reject(error);\n }\n this.queue = [];\n }\n\n interruptAndExtract(): string[] {\n const payloads: string[] = [];\n\n const error = new Error('Task aborted');\n error.name = 'AbortError';\n\n if (this.activeTask) {\n if (this.activeTask.task.text !== undefined) {\n payloads.push(this.activeTask.task.text);\n }\n this.activeTask.controller.abort(error);\n }\n\n for (const qTask of this.queue) {\n if (qTask.task.text !== undefined) {\n payloads.push(qTask.task.text);\n }\n qTask.reject(error);\n }\n this.queue = [];\n\n return payloads;\n }\n\n extractPending(): string[] {\n const payloads: string[] = [];\n\n const error = new Error('Task extracted for batching');\n error.name = 'AbortError';\n\n for (const qTask of this.queue) {\n if (qTask.task.text !== undefined) {\n payloads.push(qTask.task.text);\n }\n qTask.reject(error);\n }\n this.queue = [];\n\n return payloads;\n }\n\n hasTasks(): boolean {\n return this.activeTask !== null || this.queue.length > 0;\n }\n}\n\nexport class TaskScheduler {\n private queues = new Map<string, TaskQueue>();\n private resourceLock = new ResourceLock();\n\n private getQueueKey(sessionId: string, rootChatId: string): string {\n return `${rootChatId}:${sessionId}`;\n }\n\n public schedule(task: AgentTask): Promise<void> {\n const key = this.getQueueKey(task.sessionId, task.rootChatId);\n let queue = this.queues.get(key);\n if (!queue) {\n queue = new TaskQueue(task.sessionId, this.resourceLock, () => {\n this.queues.delete(key);\n });\n this.queues.set(key, queue);\n }\n return queue.enqueue(task);\n }\n\n public hasTasks(sessionId: string): boolean {\n for (const queue of this.queues.values()) {\n if (queue.sessionId === sessionId && queue.hasTasks()) {\n return true;\n }\n }\n return false;\n }\n\n public extractPending(sessionId: string): string[] {\n const payloads: string[] = [];\n for (const queue of this.queues.values()) {\n if (queue.sessionId === sessionId) {\n payloads.push(...queue.extractPending());\n }\n }\n return payloads;\n }\n\n public abortTasks(sessionId: string): void {\n for (const queue of this.queues.values()) {\n if (queue.sessionId === sessionId) {\n queue.abortAll();\n }\n }\n }\n\n public interruptTasks(sessionId: string): string[] {\n const payloads: string[] = [];\n for (const queue of this.queues.values()) {\n if (queue.sessionId === sessionId) {\n payloads.push(...queue.interruptAndExtract());\n }\n }\n return payloads;\n }\n}\n\nexport const taskScheduler = new TaskScheduler();\n","import type { Agent, Settings } from '../../shared/config.js';\nimport { AgentRunner } from './agent-runner.js';\nimport type { Logger, Message } from './types.js';\nimport { runCommand } from '../utils/spawn.js';\nimport {\n getAgent,\n getWorkspaceRoot,\n readAgentSessionSettings,\n writeAgentSessionSettings,\n readSettings,\n resolveAgentWorkDir,\n} from '../../shared/workspace.js';\nimport { formatPendingMessages, isNewSession } from './utils.js';\nimport { createChatLogger } from './chat-logger.js';\nimport { sandboxExecutionContext, type Fallback } from './agent-context.js';\nimport { applyEnvOverrides, getActiveEnvKeys } from '../../shared/utils/env.js';\nimport { getApiContext, generateToken } from '../auth.js';\nimport { taskScheduler } from './task-scheduler.js';\nimport { randomUUID } from 'node:crypto';\n\nexport class AgentSession {\n public readonly agentId: string;\n public readonly sessionId: string;\n public readonly chatId: string;\n public readonly subagentId: string | undefined;\n public readonly turnId: string | undefined;\n public readonly settings: Agent;\n public readonly workspaceRoot: string;\n public readonly globalSettings: Settings | undefined;\n public readonly logger: Logger;\n\n constructor(config: {\n agentId: string;\n sessionId: string;\n chatId: string;\n subagentId?: string;\n turnId?: string;\n settings: Agent;\n workspaceRoot: string;\n globalSettings: Settings | undefined;\n logger?: Logger;\n }) {\n this.agentId = config.agentId;\n this.sessionId = config.sessionId;\n this.chatId = config.chatId;\n this.subagentId = config.subagentId;\n this.turnId = config.turnId;\n this.settings = config.settings;\n this.workspaceRoot = config.workspaceRoot;\n this.globalSettings = config.globalSettings;\n\n this.logger =\n config.logger ?? createChatLogger(this.chatId, this.subagentId, this.sessionId, this.turnId);\n }\n\n async buildExecutionContext(\n messageContent: string,\n routerEnv: Record<string, string>,\n fallback?: Fallback\n ): Promise<{ command: string; env: Record<string, string>; currentAgent: Agent } | null> {\n const currentAgent: Agent = {\n ...this.settings,\n commands: {\n ...this.settings.commands,\n ...(fallback?.commands || {}),\n },\n env: {\n ...this.settings.env,\n ...(this.subagentId && this.settings.subagentEnv ? this.settings.subagentEnv : {}),\n ...(fallback?.env || {}),\n },\n };\n\n let initialCommand = currentAgent.commands?.new ?? '';\n const env = {\n ...process.env,\n CLAW_CLI_MESSAGE: messageContent,\n } as Record<string, string>;\n\n applyEnvOverrides(env, currentAgent.env);\n\n if (!isNewSession(routerEnv) && currentAgent.commands?.append) {\n initialCommand = currentAgent.commands.append;\n }\n\n if (!initialCommand) {\n return null;\n }\n\n const agentSpecificEnvKeys = getActiveEnvKeys(currentAgent.env);\n agentSpecificEnvKeys.add('CLAW_CLI_MESSAGE');\n\n Object.assign(env, routerEnv);\n Object.keys(routerEnv).forEach((k) => agentSpecificEnvKeys.add(k));\n\n const apiCtx = getApiContext(this.globalSettings);\n if (apiCtx) {\n const proxyUrl = apiCtx.proxy_host\n ? `${apiCtx.proxy_host}:${apiCtx.port}`\n : `http://${apiCtx.host}:${apiCtx.port}`;\n\n if (currentAgent.apiUrlEnvVar) {\n env[currentAgent.apiUrlEnvVar] = proxyUrl;\n agentSpecificEnvKeys.add(currentAgent.apiUrlEnvVar);\n env['CLAW_LITE_URL_VAR'] = currentAgent.apiUrlEnvVar;\n agentSpecificEnvKeys.add('CLAW_LITE_URL_VAR');\n } else {\n env['CLAW_API_URL'] = proxyUrl;\n agentSpecificEnvKeys.add('CLAW_API_URL');\n }\n\n const token = generateToken({\n chatId: this.chatId,\n agentId: this.agentId,\n sessionId: this.sessionId,\n ...(this.subagentId ? { subagentId: this.subagentId } : {}),\n ...(this.turnId ? { turnId: this.turnId } : {}),\n timestamp: Date.now(),\n });\n\n if (currentAgent.apiTokenEnvVar) {\n env[currentAgent.apiTokenEnvVar] = token;\n agentSpecificEnvKeys.add(currentAgent.apiTokenEnvVar);\n env['CLAW_LITE_API_VAR'] = currentAgent.apiTokenEnvVar;\n agentSpecificEnvKeys.add('CLAW_LITE_API_VAR');\n } else {\n env['CLAW_API_TOKEN'] = token;\n agentSpecificEnvKeys.add('CLAW_API_TOKEN');\n }\n }\n\n let command = initialCommand;\n command = await sandboxExecutionContext(\n command,\n env,\n agentSpecificEnvKeys,\n this.workDirectory,\n this.workspaceRoot\n );\n\n return { command, env, currentAgent };\n }\n\n createRunner(): AgentRunner {\n return new AgentRunner(this, runCommand);\n }\n\n get workDirectory(): string {\n return resolveAgentWorkDir(this.agentId, this.settings.directory, this.workspaceRoot);\n }\n\n stop() {\n taskScheduler.abortTasks(this.sessionId);\n }\n\n interrupt(message: Message): Message {\n const payloads = taskScheduler.interruptTasks(this.sessionId);\n\n if (payloads.length > 0) {\n // TODO: Figure out how to handle merging payloads when they have different env settings or other config.\n // Currently, we only preserve the text content and drop any specific configuration attached to individual messages.\n const pendingText = formatPendingMessages(payloads);\n return {\n ...message,\n content: `${pendingText}\\n\\n<message>\\n${message.content}\\n</message>`.trim(),\n };\n }\n return message;\n }\n\n async handleMessage(message: Message): Promise<void> {\n if (!message.content.trim()) {\n return;\n }\n\n await taskScheduler.schedule({\n id: `task-${this.agentId}-${randomUUID()}`,\n rootChatId: this.chatId,\n dirPath: this.workDirectory,\n sessionId: this.sessionId,\n text: message.content,\n execute: async (signal) => {\n // Refresh sessionSettings immediately before execution\n const sessionSettings = await readAgentSessionSettings(\n this.agentId,\n this.sessionId,\n this.workspaceRoot\n );\n // TODO: create a copy of the message first\n applyEnvOverrides(message.env, sessionSettings?.env);\n\n const runner = this.createRunner();\n const result = await runner.executeWithFallbacks(message, signal);\n if (!result) {\n // TODO: throw an error? Log an error?\n return;\n }\n\n if (result.extractedSessionId) {\n await writeAgentSessionSettings(\n this.agentId,\n this.sessionId,\n { env: { SESSION_ID: result.extractedSessionId } },\n this.workspaceRoot\n );\n }\n\n await this.logger.logCommandResult(result);\n\n if (!result.content.includes('NO_REPLY_NECESSARY')) {\n await this.logger.logAgentReply({ content: result.content });\n }\n },\n });\n }\n}\n\nexport async function createAgentSession(options: {\n chatId: string;\n agentId: string;\n sessionId: string;\n subagentId?: string;\n turnId?: string;\n cwd: string;\n settings?: Settings | undefined;\n logger?: Logger;\n}) {\n // TODO: make it so that readSettings returns Settings|undefined\n const settings = options.settings ?? (await readSettings(options.cwd)) ?? undefined;\n const mergedAgent = await resolveMergedAgent(options.agentId, settings, options.cwd);\n const workspaceRoot = getWorkspaceRoot(options.cwd);\n\n return new AgentSession({\n agentId: options.agentId,\n sessionId: options.sessionId,\n chatId: options.chatId,\n ...(options.subagentId ? { subagentId: options.subagentId } : {}),\n ...(options.turnId ? { turnId: options.turnId } : {}),\n settings: mergedAgent,\n workspaceRoot,\n globalSettings: settings,\n ...(options.logger ? { logger: options.logger } : {}),\n });\n}\n\nasync function resolveMergedAgent(\n agentId: string,\n settings: Settings | undefined,\n cwd: string\n): Promise<Agent> {\n let mergedAgent: Agent = settings?.defaultAgent || {};\n if (agentId !== 'default') {\n try {\n const customAgent = await getAgent(agentId, cwd);\n if (customAgent) {\n mergedAgent = {\n ...mergedAgent,\n ...customAgent,\n commands: { ...mergedAgent.commands, ...customAgent.commands },\n env: { ...mergedAgent.env, ...customAgent.env },\n };\n }\n } catch {\n // Fall back to default if agent not found\n }\n }\n return mergedAgent;\n}\n","import { emitTurnEnded } from '../events.js';\n\ninterface TurnState {\n chatId: string;\n outstanding: number;\n parentExited: boolean;\n outcome: 'ok' | 'error';\n timeoutHandle: NodeJS.Timeout;\n}\n\nconst turns = new Map<string, TurnState>();\n\n/**\n * Watchdog for turns whose subagent count never drains. Pathological cases\n * (crashed subagent, bug leaving the counter > 0) would otherwise pin the\n * turn's activity log open indefinitely. Default is a guess — instrument\n * before tuning.\n */\nexport const DEFAULT_TURN_MAX_DURATION_MS = 30 * 60 * 1000;\n\nexport function registerTurn(\n chatId: string,\n turnId: string,\n maxDurationMs: number = DEFAULT_TURN_MAX_DURATION_MS\n): void {\n if (turns.has(turnId)) return;\n const state: TurnState = {\n chatId,\n outstanding: 0,\n parentExited: false,\n outcome: 'ok',\n timeoutHandle: setTimeout(() => {\n const s = turns.get(turnId);\n if (!s) return;\n console.warn(\n `Turn ${turnId} force-ended after ${maxDurationMs}ms (outstanding=${s.outstanding}).`\n );\n turns.delete(turnId);\n emitTurnEnded({ chatId: s.chatId, turnId, outcome: 'error' });\n }, maxDurationMs),\n };\n state.timeoutHandle.unref();\n turns.set(turnId, state);\n}\n\nexport function incrementSubagent(turnId: string | undefined): void {\n if (!turnId) return;\n const state = turns.get(turnId);\n if (!state) return;\n state.outstanding++;\n}\n\nexport function decrementSubagent(turnId: string | undefined): void {\n if (!turnId) return;\n const state = turns.get(turnId);\n if (!state) return;\n state.outstanding = Math.max(0, state.outstanding - 1);\n maybeFinalize(turnId, state);\n}\n\n/**\n * Called once, when the parent agent's initial `handleMessage` promise\n * settles. Records the outcome; the turn actually ends (emits `turnEnded`)\n * only once the outstanding subagent count also reaches zero.\n */\nexport function markParentExited(turnId: string, outcome: 'ok' | 'error'): void {\n const state = turns.get(turnId);\n if (!state) return;\n if (state.parentExited) return;\n state.parentExited = true;\n state.outcome = outcome;\n maybeFinalize(turnId, state);\n}\n\nfunction maybeFinalize(turnId: string, state: TurnState): void {\n if (!state.parentExited) return;\n if (state.outstanding > 0) return;\n clearTimeout(state.timeoutHandle);\n turns.delete(turnId);\n emitTurnEnded({ chatId: state.chatId, turnId, outcome: state.outcome });\n}\n\n/** Test hook: drop all state without emitting events. */\nexport function _resetTurnRegistryForTests(): void {\n for (const state of turns.values()) {\n clearTimeout(state.timeoutHandle);\n }\n turns.clear();\n}\n\n/** Test hook: inspect registry state. */\nexport function _getTurnStateForTests(turnId: string): Readonly<TurnState> | undefined {\n return turns.get(turnId);\n}\n","import { randomUUID } from 'node:crypto';\nimport { executeRouterPipeline, resolveRouters } from './routers.js';\nimport type { RouterState } from './routers/types.js';\nimport { type ChatSettings, type Settings } from '../shared/config.js';\nimport { readChatSettings, updateChatSettings, writeChatSettings } from '../shared/workspace.js';\nimport { cronManager, normalizeJob } from './cron.js';\nimport type { Message } from './agent/types.js';\nimport { createAgentSession } from './agent/agent-session.js';\nimport { createChatLogger } from './agent/chat-logger.js';\nimport { taskScheduler } from './agent/task-scheduler.js';\nimport { emitTurnStarted } from './events.js';\nimport { registerTurn, markParentExited } from './agent/turn-registry.js';\n\nexport { calculateDelay } from './agent/agent-runner.js';\n\nexport async function executeDirectMessage(\n chatId: string,\n state: RouterState,\n settings: Settings | undefined,\n cwd: string,\n noWait: boolean = false,\n userMessageContent?: string,\n subagentId?: string,\n systemEvent?:\n | 'cron'\n | 'policy_approved'\n | 'policy_rejected'\n | 'subagent_update'\n | 'router'\n | 'other',\n displayRole?: 'user' | 'agent',\n parentTurnId?: string\n) {\n const turnId = parentTurnId ?? randomUUID();\n const emitLifecycle = !parentTurnId;\n const logger = createChatLogger(chatId, subagentId, state.sessionId, turnId);\n\n let msgId: string;\n if (systemEvent) {\n const sysMsg = await logger.logSystemMessage({\n content: userMessageContent ?? state.message,\n event: systemEvent,\n messageId: state.messageId,\n ...(displayRole ? { displayRole } : {}),\n ...(state.jobId ? { jobId: state.jobId } : {}),\n });\n msgId = sysMsg.id;\n } else {\n const userMsg = await logger.logUserMessage(userMessageContent ?? state.message);\n msgId = userMsg.id;\n }\n\n if (state.reply) {\n await logger.logAutomaticReply({ messageId: msgId, content: state.reply });\n }\n\n if (!state.message.trim() && state.action !== 'stop' && state.action !== 'interrupt') {\n return;\n }\n\n // Load the agent\n const agentSession = await createAgentSession({\n chatId,\n agentId: state.agentId || 'default',\n sessionId: state.sessionId || 'default',\n ...(subagentId ? { subagentId } : {}),\n cwd,\n settings,\n logger,\n turnId,\n });\n let finalMessage: Message = {\n id: state.messageId,\n content: state.message,\n env: state.env ?? {},\n turnId,\n };\n\n // Process actions\n if (state.action === 'stop') {\n agentSession.stop();\n if (!subagentId) {\n await stopActiveSubagents(chatId, cwd);\n }\n return;\n }\n if (state.action === 'interrupt') {\n finalMessage = agentSession.interrupt(finalMessage);\n }\n\n if (emitLifecycle) {\n registerTurn(chatId, turnId);\n emitTurnStarted({\n chatId,\n turnId,\n rootMessageId: msgId,\n ...(state.externalRef ? { externalRef: state.externalRef } : {}),\n });\n }\n\n // Process message\n const taskPromise = agentSession.handleMessage(finalMessage);\n\n const settleTurn = async () => {\n try {\n await taskPromise;\n if (emitLifecycle) markParentExited(turnId, 'ok');\n } catch (err) {\n if (emitLifecycle) markParentExited(turnId, 'error');\n if (!(err instanceof Error && err.name === 'AbortError')) {\n throw err;\n }\n }\n };\n\n if (!noWait) {\n await settleTurn();\n } else {\n settleTurn().catch((err) => {\n if (err?.name !== 'AbortError') {\n console.error('Task execution error:', err);\n }\n });\n }\n}\n\nexport async function getInitialRouterState(\n chatId: string,\n message: string,\n chatSettings: Partial<ChatSettings>,\n overrideAgentId?: string,\n overrideSessionId?: string,\n externalRef?: string\n): Promise<RouterState> {\n const agentId = overrideAgentId ?? chatSettings.defaultAgent ?? 'default';\n const sessionId = overrideSessionId ?? chatSettings.sessions?.[agentId] ?? 'default';\n const messageId = crypto.randomUUID();\n\n return {\n messageId,\n message,\n chatId,\n agentId,\n sessionId,\n env: {},\n ...(externalRef ? { externalRef } : {}),\n };\n}\n\nexport async function handleUserMessage(\n chatId: string,\n message: string,\n settings: Settings | undefined,\n cwd: string = process.cwd(),\n noWait: boolean = false,\n sessionId?: string,\n overrideAgentId?: string,\n externalRef?: string\n): Promise<void> {\n const chatSettings = (await readChatSettings(chatId, cwd)) ?? {};\n\n if (overrideAgentId && chatSettings.defaultAgent !== overrideAgentId) {\n chatSettings.defaultAgent = overrideAgentId;\n await writeChatSettings(chatId, chatSettings, cwd);\n }\n\n const initialState = await getInitialRouterState(\n chatId,\n message,\n chatSettings,\n overrideAgentId,\n sessionId,\n externalRef\n );\n\n const routers = chatSettings.routers ?? settings?.routers ?? [];\n const resolvedRouters = resolveRouters(routers, true);\n const finalState = await executeRouterPipeline(initialState, resolvedRouters);\n\n await applyRouterStateUpdates(chatId, cwd, finalState, chatSettings, initialState.agentId);\n\n await executeDirectMessage(\n chatId,\n finalState,\n settings,\n cwd,\n noWait,\n message,\n finalState.subagentId\n );\n}\n\nexport async function applyRouterStateUpdates(\n chatId: string,\n cwd: string,\n finalState: RouterState,\n chatSettings: ChatSettings,\n initialAgent: string | undefined\n) {\n const finalAgentId = finalState.agentId;\n const finalSessionId = finalState.sessionId ?? crypto.randomUUID();\n const currentAgentId = finalAgentId ?? chatSettings.defaultAgent ?? 'default';\n\n let settingsChanged = false;\n if (finalAgentId && finalAgentId !== initialAgent) {\n chatSettings.defaultAgent = finalAgentId;\n settingsChanged = true;\n }\n\n if (finalState.nextSessionId) {\n chatSettings.sessions = chatSettings.sessions || {};\n chatSettings.sessions[currentAgentId] = finalState.nextSessionId;\n settingsChanged = true;\n }\n\n if (finalState.jobs) {\n chatSettings.jobs = chatSettings.jobs || [];\n\n if (finalState.jobs.remove?.length) {\n const removeSet = new Set(finalState.jobs.remove);\n for (const jobId of finalState.jobs.remove) {\n cronManager.unscheduleJob(chatId, jobId);\n }\n chatSettings.jobs = chatSettings.jobs.filter((job) => !removeSet.has(job.id));\n settingsChanged = true;\n }\n\n if (finalState.jobs.add?.length) {\n const normalized = finalState.jobs.add.map(normalizeJob);\n const addMap = new Map(normalized.map((job) => [job.id, job]));\n for (const job of normalized) {\n cronManager.scheduleJob(chatId, job);\n }\n chatSettings.jobs = chatSettings.jobs.filter((job) => !addMap.has(job.id));\n chatSettings.jobs.push(...normalized);\n settingsChanged = true;\n }\n }\n\n if (settingsChanged) {\n await writeChatSettings(chatId, chatSettings, cwd);\n }\n\n // Ensure finalSessionId is set on state so extractDirectState gets it.\n if (finalState.sessionId === undefined) {\n finalState.sessionId = finalSessionId;\n }\n if (finalState.agentId === undefined) {\n finalState.agentId = currentAgentId;\n }\n}\n\nasync function stopActiveSubagents(chatId: string, cwd: string): Promise<void> {\n const sessionsToAbort: string[] = [];\n await updateChatSettings(\n chatId,\n (settings) => {\n if (settings.subagents) {\n for (const sub of Object.values(settings.subagents)) {\n if (sub.status === 'active') {\n if (sub.sessionId) sessionsToAbort.push(sub.sessionId);\n sub.status = 'failed';\n }\n }\n }\n return settings;\n },\n cwd\n );\n for (const sessionId of sessionsToAbort) {\n taskScheduler.abortTasks(sessionId);\n }\n}\n","// @ts-expect-error - node-schedule types are missing\nimport schedule from 'node-schedule';\nimport { listChats } from '../shared/chats.js';\nimport { readChatSettings, writeChatSettings } from '../shared/workspace.js';\nimport { executeDirectMessage, getInitialRouterState, applyRouterStateUpdates } from './message.js';\nimport { executeRouterPipeline, resolveRouters } from './routers.js';\nimport type { CronJob, Settings } from '../shared/config.js';\nimport fs from 'node:fs/promises';\nimport { getSettingsPath } from '../shared/workspace.js';\nimport { applyEnvOverrides } from '../shared/utils/env.js';\n\n// Resolves relative `at` intervals (e.g. \"2s\", \"5m\") to absolute ISO timestamps\n// so a job's target time is stable across daemon restarts. Throws on unparseable\n// `at` values so invalid input is rejected at creation rather than silently\n// shifted by `scheduleJob`. `cron` and `every` schedules pass through unchanged.\nexport function normalizeJob(job: CronJob): CronJob {\n if (!('at' in job.schedule)) return job;\n\n const atStr = job.schedule.at;\n const match = atStr.match(/^(\\d+)\\s*(m|min|minutes?|h|hours?|d|days?|s|sec|seconds?)$/i);\n let absolute: Date;\n if (match) {\n const val = parseInt(match[1]!, 10);\n const unit = match[2]!.toLowerCase();\n let ms = 0;\n if (unit.startsWith('s')) ms = val * 1000;\n else if (unit.startsWith('m')) ms = val * 60 * 1000;\n else if (unit.startsWith('h')) ms = val * 60 * 60 * 1000;\n else if (unit.startsWith('d')) ms = val * 24 * 60 * 60 * 1000;\n absolute = new Date(Date.now() + ms);\n } else {\n absolute = new Date(atStr);\n if (isNaN(absolute.getTime())) {\n throw new Error(`Invalid date format for 'at' schedule: ${atStr}`);\n }\n }\n return { ...job, schedule: { at: absolute.toISOString() } };\n}\n\nexport class CronManager {\n private jobs = new Map<string, schedule.Job>();\n\n private getJobKey(chatId: string, jobId: string) {\n return `${chatId}::${jobId}`;\n }\n\n async init() {\n const chats = await listChats();\n for (const chatId of chats) {\n const settings = await readChatSettings(chatId);\n if (settings?.jobs) {\n for (const job of settings.jobs) {\n try {\n this.scheduleJob(chatId, job);\n } catch (err) {\n console.error(\n `Failed to initialize job ${job.id} for chat ${chatId}:`,\n err instanceof Error ? err.message : err\n );\n }\n }\n }\n }\n }\n\n scheduleJob(chatId: string, job: CronJob) {\n this.unscheduleJob(chatId, job.id);\n\n let rule: string | Date;\n let isOneOff = false;\n\n if ('cron' in job.schedule) {\n rule = (job.schedule as { cron: string }).cron;\n } else if ('every' in job.schedule) {\n const everyStr = (job.schedule as { every: string }).every;\n const match = everyStr.match(/^(\\d+)\\s*(m|min|minutes?|h|hours?|d|days?)$/i);\n if (match) {\n const val = parseInt(match[1]!, 10);\n const unit = match[2]!.toLowerCase();\n if (unit.startsWith('m')) {\n rule = `*/${val} * * * *`;\n } else if (unit.startsWith('h')) {\n rule = `0 */${val} * * *`;\n } else if (unit.startsWith('d')) {\n rule = `0 0 */${val} * *`;\n } else {\n rule = everyStr;\n }\n } else {\n rule = everyStr;\n }\n } else if ('at' in job.schedule) {\n const atStr = job.schedule.at;\n rule = new Date(atStr);\n if (isNaN(rule.getTime())) {\n throw new Error(`Invalid date format for 'at' schedule: ${atStr}`);\n }\n // If the target time has already passed (e.g. daemon was down past it),\n // node-schedule returns null and the job silently never fires. Push it\n // just into the future so it executes on the next tick and cleans up.\n if (rule.getTime() <= Date.now()) {\n console.warn(\n `One-off job ${job.id} for chat ${chatId} is overdue (target ${atStr}); firing immediately.`\n );\n rule = new Date(Date.now() + 100);\n }\n isOneOff = true;\n } else {\n console.warn(`Unknown schedule format for job ${job.id}`);\n return;\n }\n\n try {\n const scheduledJob = schedule.scheduleJob(rule, async () => {\n await this.executeJob(chatId, job, isOneOff);\n });\n if (scheduledJob) {\n this.jobs.set(this.getJobKey(chatId, job.id), scheduledJob);\n }\n } catch (err) {\n console.error(`Failed to schedule job ${job.id} for chat ${chatId}:`, err);\n }\n }\n\n unscheduleJob(chatId: string, jobId: string) {\n const key = this.getJobKey(chatId, jobId);\n const job = this.jobs.get(key);\n if (job) {\n job.cancel();\n this.jobs.delete(key);\n }\n }\n\n private async executeJob(chatId: string, job: CronJob, isOneOff: boolean) {\n try {\n const settingsPath = getSettingsPath();\n let globalSettings: Settings | undefined;\n try {\n const settingsStr = await fs.readFile(settingsPath, 'utf8');\n globalSettings = JSON.parse(settingsStr) as Settings;\n } catch {\n globalSettings = undefined;\n }\n\n const overrideSessionId = job.session?.type === 'new' ? crypto.randomUUID() : job.session?.id;\n const chatSettings = (await readChatSettings(chatId, process.cwd())) ?? {};\n let routerState = await getInitialRouterState(\n chatId,\n job.message,\n chatSettings,\n job.agentId,\n overrideSessionId\n );\n\n if (job.env !== undefined) {\n routerState.env = routerState.env || {};\n applyEnvOverrides(routerState.env, job.env);\n }\n\n const currentAgentId = job.agentId ?? chatSettings.defaultAgent ?? 'default';\n const currentActiveSession = chatSettings.sessions?.[currentAgentId];\n const isOutdatedSession =\n job.session?.type === 'existing' &&\n currentActiveSession !== undefined &&\n currentActiveSession !== job.session.id;\n\n if (job.reply !== undefined && !isOutdatedSession) routerState.reply = job.reply;\n if (job.nextSessionId !== undefined && !isOutdatedSession)\n routerState.nextSessionId = job.nextSessionId;\n if (job.action !== undefined) routerState.action = job.action;\n if (job.jobs !== undefined) routerState.jobs = job.jobs;\n routerState.jobId = job.id;\n\n const routers = chatSettings.routers ?? globalSettings?.routers ?? [];\n const resolvedRouters = resolveRouters(routers, false);\n const initialState = { ...routerState };\n routerState = await executeRouterPipeline(routerState, resolvedRouters);\n\n await applyRouterStateUpdates(\n chatId,\n process.cwd(),\n routerState,\n chatSettings,\n initialState.agentId\n );\n\n await executeDirectMessage(\n chatId,\n routerState,\n globalSettings,\n process.cwd(),\n false,\n job.message,\n undefined,\n 'cron'\n );\n\n if (isOneOff) {\n const chatSettings = await readChatSettings(chatId);\n if (chatSettings && chatSettings.jobs) {\n chatSettings.jobs = chatSettings.jobs.filter((j) => j.id !== job.id);\n await writeChatSettings(chatId, chatSettings);\n }\n this.unscheduleJob(chatId, job.id);\n }\n } catch (err) {\n console.error(`Error executing cron job ${job.id} for chat ${chatId}:`, err);\n }\n }\n}\n\nexport const cronManager = new CronManager();\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { TRPCError } from '@trpc/server';\nimport { pathIsInsideDir } from '../../shared/utils/fs.js';\nimport {\n getAgent,\n getClawminiDir,\n readChatSettings,\n writeChatSettings,\n} from '../../shared/workspace.js';\nimport { cronManager, normalizeJob } from '../cron.js';\nimport type { z } from 'zod';\nimport type { CronJobSchema } from '../../shared/config.js';\n\nexport async function getUniquePath(p: string): Promise<string> {\n let currentPath = p;\n let counter = 1;\n while (true) {\n try {\n await fs.stat(currentPath);\n const ext = path.extname(p);\n const base = path.basename(p, ext);\n currentPath = path.join(path.dirname(p), `${base}-${counter}${ext}`);\n counter++;\n } catch {\n return currentPath;\n }\n }\n}\n\nexport async function resolveAgentDir(\n agentId: string | undefined | null,\n workspaceRoot: string\n): Promise<string> {\n if (agentId && agentId !== 'default') {\n try {\n const agent = await getAgent(agentId, workspaceRoot);\n if (agent && agent.directory) {\n return path.resolve(workspaceRoot, agent.directory);\n }\n } catch (err: unknown) {\n console.warn(`Could not load custom agent '${agentId}' for resolving directory:`, err);\n }\n return path.resolve(workspaceRoot, agentId);\n }\n return workspaceRoot;\n}\n\nexport async function getAgentFilesDir(\n agentId: string | undefined,\n chatId: string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n settings: any,\n workspaceRoot: string\n): Promise<string> {\n const chatSettings = (await readChatSettings(chatId)) ?? {};\n const targetAgentId = agentId ?? chatSettings.defaultAgent ?? 'default';\n let agentFilesDir = settings?.defaultAgent?.files || './attachments';\n const agentDir = await resolveAgentDir(targetAgentId, workspaceRoot);\n\n if (targetAgentId !== 'default') {\n try {\n const customAgent = await getAgent(targetAgentId, workspaceRoot);\n if (customAgent?.files) {\n agentFilesDir = customAgent.files;\n }\n } catch (err: unknown) {\n console.warn(\n `Could not load custom agent '${targetAgentId}' for resolving files directory:`,\n err\n );\n }\n }\n\n return path.resolve(agentDir, agentFilesDir);\n}\n\nexport async function validateAttachments(files: string[]): Promise<void> {\n const tmpDir = path.join(getClawminiDir(process.cwd()), 'tmp');\n\n for (const file of files) {\n const absoluteFile = path.resolve(process.cwd(), file);\n if (!pathIsInsideDir(absoluteFile, tmpDir)) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'File must be inside the temporary directory.',\n });\n }\n try {\n await fs.access(absoluteFile);\n } catch {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: `File does not exist: ${file}`,\n });\n }\n }\n}\n\nexport async function validateLogFile(\n file: string,\n agentDir: string,\n workspaceRoot: string\n): Promise<string> {\n const resolvedPath = path.resolve(agentDir, file);\n\n if (!pathIsInsideDir(resolvedPath, agentDir, { allowSameDir: true })) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'File must be within the agent workspace.',\n });\n }\n\n try {\n await fs.access(resolvedPath);\n } catch {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: `File does not exist: ${file}`,\n });\n }\n\n return path.relative(workspaceRoot, resolvedPath);\n}\n\nexport async function listCronJobsShared(chatId: string) {\n const settings = await readChatSettings(chatId);\n return settings?.jobs ?? [];\n}\n\nexport async function addCronJobShared(chatId: string, job: z.infer<typeof CronJobSchema>) {\n const normalized = normalizeJob(job);\n const settings = (await readChatSettings(chatId)) || {};\n const cronJobs = settings.jobs ?? [];\n const existingIndex = cronJobs.findIndex((j) => j.id === normalized.id);\n if (existingIndex >= 0) {\n cronJobs[existingIndex] = normalized;\n } else {\n cronJobs.push(normalized);\n }\n settings.jobs = cronJobs;\n await writeChatSettings(chatId, settings);\n cronManager.scheduleJob(chatId, normalized);\n return { success: true };\n}\n\nexport async function deleteCronJobShared(chatId: string, id: string) {\n const settings = await readChatSettings(chatId);\n if (!settings || !settings.jobs) {\n return { success: true, deleted: false };\n }\n const initialLength = settings.jobs.length;\n settings.jobs = settings.jobs.filter((j) => j.id !== id);\n if (settings.jobs.length !== initialLength) {\n await writeChatSettings(chatId, settings);\n cronManager.unscheduleJob(chatId, id);\n return { success: true, deleted: true };\n }\n return { success: true, deleted: false };\n}\n","import { z } from 'zod';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { TRPCError } from '@trpc/server';\nimport { pathIsInsideDir } from '../../shared/utils/fs.js';\nimport { on } from 'node:events';\nimport {\n daemonEvents,\n DAEMON_EVENT_CHAT_STREAM,\n DAEMON_EVENT_TYPING,\n type ChatStreamEnvelope,\n type ChatStreamItem,\n} from '../events.js';\nimport {\n getSettingsPath,\n readChatSettings,\n writeChatSettings,\n getWorkspaceRoot,\n listAgents,\n} from '../../shared/workspace.js';\nimport { CronJobSchema } from '../../shared/config.js';\nimport { handleUserMessage } from '../message.js';\nimport { getDefaultChatId, getMessages as fetchMessages, listChats, createChat } from '../chats.js';\nimport { apiProcedure, publicProcedure, router } from './trpc.js';\nimport {\n getUniquePath,\n resolveAgentDir,\n getAgentFilesDir,\n validateAttachments,\n listCronJobsShared,\n addCronJobShared,\n deleteCronJobShared,\n} from './router-utils.js';\n\nexport const sendMessage = apiProcedure\n .input(\n z.object({\n type: z.literal('send-message'),\n client: z.literal('cli'),\n data: z.object({\n message: z.string(),\n chatId: z.string().optional(),\n sessionId: z.string().optional(),\n agentId: z.string().optional(),\n noWait: z.boolean().optional(),\n files: z.array(z.string()).optional(),\n adapter: z.string().optional(),\n externalRef: z.string().optional(),\n }),\n })\n )\n .mutation(async ({ input }) => {\n let message = input.data.message;\n const chatId = input.data.chatId ?? (await getDefaultChatId());\n const noWait = input.data.noWait ?? false;\n const sessionId = input.data.sessionId;\n const agentId = input.data.agentId;\n const settingsPath = getSettingsPath();\n\n let settings;\n try {\n const settingsStr = await fs.readFile(settingsPath, 'utf8');\n settings = JSON.parse(settingsStr);\n } catch (err) {\n throw new Error(`Failed to read settings from ${settingsPath}: ${err}`, { cause: err });\n }\n\n const files = input.data.files;\n if (files && files.length > 0) {\n const workspaceRoot = getWorkspaceRoot(process.cwd());\n const chatSettings = (await readChatSettings(chatId)) ?? {};\n const targetAgentId = agentId ?? chatSettings.defaultAgent ?? 'default';\n const agentDir = await resolveAgentDir(targetAgentId, workspaceRoot);\n const absoluteFilesDir = await getAgentFilesDir(agentId, chatId, settings, workspaceRoot);\n\n const adapterNamespace = input.data.adapter || 'cli';\n const targetDir = path.join(absoluteFilesDir, adapterNamespace);\n\n if (!pathIsInsideDir(targetDir, workspaceRoot, { allowSameDir: true })) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'Target directory must be within the workspace.',\n });\n }\n\n await validateAttachments(files);\n\n await fs.mkdir(targetDir, { recursive: true });\n\n const finalPaths: string[] = [];\n for (const file of files) {\n const fileName = path.basename(file);\n const targetPath = await getUniquePath(path.join(targetDir, fileName));\n\n try {\n await fs.rename(file, targetPath);\n } catch {\n await fs.copyFile(file, targetPath);\n await fs.unlink(file);\n }\n\n finalPaths.push(path.relative(agentDir, targetPath));\n }\n\n const fileList = `Attached files:\\n${finalPaths.map((p) => `- ${p}`).join('\\n')}`;\n message = message ? `${message}\\n\\n${fileList}` : fileList;\n }\n\n await handleUserMessage(\n chatId,\n message,\n settings,\n undefined,\n noWait,\n sessionId,\n agentId,\n input.data.externalRef\n );\n\n return { success: true };\n });\n\nexport const getMessages = apiProcedure\n .input(z.object({ chatId: z.string().optional(), limit: z.number().optional() }))\n .query(async ({ input }) => {\n const chatId = input.chatId ?? (await getDefaultChatId());\n return fetchMessages(chatId, input.limit);\n });\n\n/**\n * Interleaved chat stream: `ChatMessage` appends and turn lifecycle events\n * arrive on a single subscription in emission order. Consumers that only\n * care about messages can ignore items with `kind: 'turn'`.\n */\nexport const waitForMessages = apiProcedure\n .input(\n z.object({\n chatId: z.string().optional(),\n lastMessageId: z.string().optional(),\n })\n )\n .subscription(async function* ({ input, signal }) {\n const chatId = input.chatId ?? (await getDefaultChatId());\n\n // 1. Catch up on any messages missed since `lastMessageId`. Turn events\n // have no persisted backlog — they're live-only, like today.\n if (input.lastMessageId) {\n const messages = await fetchMessages(chatId);\n const lastIndex = messages.findIndex((m) => m.id === input.lastMessageId);\n if (lastIndex !== -1 && lastIndex < messages.length - 1) {\n const items: ChatStreamItem[] = messages\n .slice(lastIndex + 1)\n .map((message) => ({ kind: 'message', message }));\n yield items;\n }\n }\n\n // 2. Live: messages and turn events on the same channel, in emission order.\n try {\n for await (const [envelope] of on(daemonEvents, DAEMON_EVENT_CHAT_STREAM, { signal })) {\n const e = envelope as ChatStreamEnvelope;\n if (e.chatId === chatId) {\n yield [e.item];\n }\n }\n } catch (err) {\n if (err instanceof Error && err.name === 'AbortError') {\n return;\n }\n throw err;\n }\n });\n\nexport const waitForTyping = apiProcedure\n .input(\n z.object({\n chatId: z.string().optional(),\n })\n )\n .subscription(async function* ({ input, signal }) {\n const chatId = input.chatId ?? (await getDefaultChatId());\n\n try {\n for await (const [event] of on(daemonEvents, DAEMON_EVENT_TYPING, { signal })) {\n if (event.chatId === chatId) {\n yield event;\n }\n }\n } catch (err) {\n if (err instanceof Error && err.name === 'AbortError') {\n return;\n }\n throw err;\n }\n });\n\nexport const ping = publicProcedure.query(() => {\n return { status: 'ok' };\n});\n\nexport const shutdown = publicProcedure.mutation(() => {\n // Schedule a shutdown shortly after the response is sent\n setTimeout(() => {\n console.log('Shutting down daemon...');\n process.kill(process.pid, 'SIGTERM');\n }, 100);\n return { success: true };\n});\n\nexport const userListCronJobs = apiProcedure\n .input(z.object({ chatId: z.string().optional() }))\n .query(async ({ input }) => {\n const chatId = input.chatId ?? (await getDefaultChatId());\n return listCronJobsShared(chatId);\n });\n\nexport const getChats = apiProcedure.query(async () => {\n return listChats();\n});\n\nexport const getAgents = apiProcedure.query(async () => {\n return listAgents();\n});\n\nexport const userCreateChat = apiProcedure\n .input(z.object({ chatId: z.string(), agent: z.string().optional() }))\n .mutation(async ({ input }) => {\n await createChat(input.chatId);\n if (input.agent) {\n await writeChatSettings(input.chatId, { defaultAgent: input.agent });\n }\n return { success: true, chatId: input.chatId };\n });\n\nexport const userAddCronJob = apiProcedure\n .input(z.object({ chatId: z.string().optional(), job: CronJobSchema }))\n .mutation(async ({ input }) => {\n const chatId = input.chatId ?? (await getDefaultChatId());\n return addCronJobShared(chatId, input.job);\n });\n\nexport const userDeleteCronJob = apiProcedure\n .input(z.object({ chatId: z.string().optional(), id: z.string() }))\n .mutation(async ({ input }) => {\n const chatId = input.chatId ?? (await getDefaultChatId());\n return deleteCronJobShared(chatId, input.id);\n });\n\nexport const userRouter = router({\n sendMessage,\n getMessages,\n waitForMessages,\n waitForTyping,\n ping,\n shutdown,\n listCronJobs: userListCronJobs,\n addCronJob: userAddCronJob,\n deleteCronJob: userDeleteCronJob,\n getChats,\n getAgents,\n createChat: userCreateChat,\n});\n\nexport type UserRouter = typeof userRouter;\n","import { RequestStore, generateRandomAlphaNumericString } from './request-store.js';\nimport { createSnapshot, interpolateArgs } from './policy-utils.js';\nimport type { PolicyRequest } from '../shared/policies.js';\n\nexport class PolicyRequestService {\n private store: RequestStore;\n private maxPending: number;\n private agentDir: string;\n private snapshotDir: string;\n\n constructor(store: RequestStore, agentDir: string, snapshotDir: string, maxPending = 100) {\n this.store = store;\n this.agentDir = agentDir;\n this.snapshotDir = snapshotDir;\n this.maxPending = maxPending;\n }\n\n async createRequest(\n commandName: string,\n args: string[],\n fileMappings: Record<string, string>,\n chatId: string,\n agentId: string,\n skipSave: boolean = false,\n subagentId?: string,\n cwd?: string\n ): Promise<PolicyRequest> {\n const allRequests = await this.store.list();\n const pendingCount = allRequests.filter((r) => r.state === 'Pending').length;\n\n if (pendingCount >= this.maxPending) {\n throw new Error(`Maximum number of pending requests (${this.maxPending}) reached.`);\n }\n\n const snapshotMappings: Record<string, string> = {};\n\n for (const [key, requestedPath] of Object.entries(fileMappings)) {\n snapshotMappings[key] = await createSnapshot(requestedPath, this.agentDir, this.snapshotDir);\n }\n\n let id = '';\n do {\n id = generateRandomAlphaNumericString(3);\n } while (allRequests.some((r) => r.id === id));\n\n const request: PolicyRequest = {\n id,\n commandName,\n args,\n fileMappings: snapshotMappings,\n ...(cwd ? { cwd } : {}),\n state: skipSave ? 'Approved' : 'Pending',\n createdAt: Date.now(),\n chatId,\n agentId,\n ...(subagentId ? { subagentId } : {}),\n };\n\n if (!skipSave) {\n await this.store.save(request);\n }\n\n return request;\n }\n\n getInterpolatedArgs(request: PolicyRequest): string[] {\n return interpolateArgs(request.args, request.fileMappings);\n }\n}\n","import { z } from 'zod';\nimport { TRPCError } from '@trpc/server';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { randomUUID } from 'node:crypto';\nimport { apiProcedure } from './trpc.js';\nimport { getWorkspaceRoot, readPoliciesForPath, getClawminiDir } from '../../shared/workspace.js';\nimport { pathIsInsideDir } from '../../shared/utils/fs.js';\nimport { resolveAgentDir } from './router-utils.js';\nimport { PolicyRequestService } from '../policy-request-service.js';\nimport { RequestStore } from '../request-store.js';\nimport {\n executeSafe,\n generateRequestPreview,\n executeRequest,\n resolveRequestCwd,\n truncateLargeOutput,\n} from '../policy-utils.js';\nimport { appendMessage, type PolicyRequestMessage } from '../chats.js';\n\nconst MAX_POLICY_SCRIPT_BYTES = 1 * 1024 * 1024;\n// Above this, the script is copied into the agent's tmp/ instead of being\n// inlined in the response, so `requests show` does not flood the agent's\n// context with a long script body. Mirrors truncateLargeOutput in policy-utils.\nconst MAX_INLINE_SCRIPT_LENGTH = 4000;\n\nexport const listPolicies = apiProcedure.query(async ({ ctx }) => {\n const workspaceRoot = getWorkspaceRoot();\n const agentDir = await resolveAgentDir(ctx.tokenPayload?.agentId, workspaceRoot);\n const config = await readPoliciesForPath(agentDir, workspaceRoot);\n return { policies: config?.policies || {} };\n});\n\n// Returns the contents of a policy's script file. Restricted to scripts inside\n// `.clawmini/policy-scripts/` so an arbitrary `command` path (e.g. `/etc/passwd`\n// or a built-in node binary) cannot be exfiltrated through this endpoint.\nexport const readPolicyScript = apiProcedure\n .input(z.object({ commandName: z.string() }))\n .query(async ({ input, ctx }) => {\n const workspaceRoot = getWorkspaceRoot();\n const agentDir = await resolveAgentDir(ctx.tokenPayload?.agentId, workspaceRoot);\n const config = await readPoliciesForPath(agentDir, workspaceRoot);\n const policy = config?.policies?.[input.commandName];\n\n if (!policy) {\n throw new TRPCError({\n code: 'NOT_FOUND',\n message: `Policy not found: ${input.commandName}`,\n });\n }\n\n const scriptsDir = path.join(getClawminiDir(), 'policy-scripts');\n const resolvedCommand = path.resolve(policy.command);\n\n if (!pathIsInsideDir(resolvedCommand, scriptsDir, { allowSameDir: false })) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: `Policy '${input.commandName}' does not point at a script in policy-scripts/.`,\n });\n }\n\n // realpath resolves symlinks in both paths; without this, a symlink inside\n // policy-scripts/ pointing at /etc/passwd would pass the string-prefix\n // check above, then fs.stat/readFile would dereference and exfiltrate.\n let realCommand: string;\n let realScriptsDir: string;\n try {\n realCommand = await fs.realpath(resolvedCommand);\n } catch (err) {\n throw new TRPCError({\n code: 'NOT_FOUND',\n message: `Script file not found for policy '${input.commandName}': ${\n err instanceof Error ? err.message : String(err)\n }`,\n });\n }\n try {\n realScriptsDir = await fs.realpath(scriptsDir);\n } catch {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: `Policy '${input.commandName}' does not point at a script in policy-scripts/.`,\n });\n }\n if (!pathIsInsideDir(realCommand, realScriptsDir, { allowSameDir: false })) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: `Policy '${input.commandName}' does not point at a script in policy-scripts/.`,\n });\n }\n\n let stat;\n try {\n stat = await fs.stat(realCommand);\n } catch (err) {\n throw new TRPCError({\n code: 'NOT_FOUND',\n message: `Script file not found for policy '${input.commandName}': ${\n err instanceof Error ? err.message : String(err)\n }`,\n });\n }\n\n if (!stat.isFile()) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: `Script path for policy '${input.commandName}' is not a regular file.`,\n });\n }\n\n if (stat.size > MAX_POLICY_SCRIPT_BYTES) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: `Script file exceeds the ${MAX_POLICY_SCRIPT_BYTES}-byte limit.`,\n });\n }\n\n if (stat.size > MAX_INLINE_SCRIPT_LENGTH) {\n const tmpDir = path.join(agentDir, 'tmp');\n await fs.mkdir(tmpDir, { recursive: true });\n const ext = path.extname(realCommand);\n const safeName = input.commandName.replace(/[^a-zA-Z0-9._-]/g, '_');\n const destPath = path.join(tmpDir, `policy-script-${safeName}${ext}`);\n await fs.copyFile(realCommand, destPath);\n return {\n path: realCommand,\n size: stat.size,\n spilledTo: `./tmp/policy-script-${safeName}${ext}`,\n };\n }\n\n const content = await fs.readFile(realCommand, 'utf8');\n return { path: realCommand, size: stat.size, content };\n });\n\nexport const executePolicyHelp = apiProcedure\n .input(z.object({ commandName: z.string() }))\n .query(async ({ input, ctx }) => {\n const workspaceRoot = getWorkspaceRoot();\n const agentDir = await resolveAgentDir(ctx.tokenPayload?.agentId, workspaceRoot);\n const config = await readPoliciesForPath(agentDir, workspaceRoot);\n const policy = config?.policies?.[input.commandName];\n\n if (!policy) {\n throw new TRPCError({\n code: 'NOT_FOUND',\n message: `Policy not found: ${input.commandName}`,\n });\n }\n\n if (!policy.allowHelp) {\n return { stdout: '', stderr: 'This command does not support --help\\n', exitCode: 1 };\n }\n\n const fullArgs = [...(policy.args || []), '--help'];\n const { stdout, stderr, exitCode } = await executeSafe(policy.command, fullArgs, {\n cwd: getWorkspaceRoot(),\n });\n\n return { stdout, stderr, exitCode };\n });\n\nexport const createPolicyRequest = apiProcedure\n .input(\n z.object({\n commandName: z.string(),\n args: z.array(z.string()),\n fileMappings: z.record(z.string(), z.string()),\n // Path traversal is guarded by assertPathInsideDir in resolveRequestCwd\n // (policy-utils.ts), which realpath-resolves the cwd before comparing —\n // so it covers encoded separators, symlinks, etc.\n cwd: z.string().optional(),\n })\n )\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const workspaceRoot = getWorkspaceRoot(process.cwd());\n const snapshotDir = path.join(getClawminiDir(process.cwd()), 'tmp', 'snapshots');\n const store = new RequestStore(process.cwd());\n const agentDir = await resolveAgentDir(ctx.tokenPayload?.agentId, workspaceRoot);\n const service = new PolicyRequestService(store, agentDir, snapshotDir);\n\n const chatId = ctx.tokenPayload.chatId;\n const agentId = ctx.tokenPayload.agentId;\n\n const config = await readPoliciesForPath(agentDir, workspaceRoot);\n const policy = config?.policies?.[input.commandName];\n\n if (!policy) {\n throw new TRPCError({\n code: 'NOT_FOUND',\n message: `Policy not found: ${input.commandName}`,\n });\n }\n\n const isAutoApprove = !!policy.autoApprove;\n\n const request = await service.createRequest(\n input.commandName,\n input.args,\n input.fileMappings,\n chatId,\n agentId,\n isAutoApprove,\n ctx.tokenPayload.subagentId,\n input.cwd\n );\n\n if (isAutoApprove) {\n const hostCwd = await resolveRequestCwd(request.cwd, agentId, workspaceRoot);\n\n const result = await executeRequest(request, policy, hostCwd);\n const { exitCode, commandStr } = result;\n const { stdout, stderr } = await truncateLargeOutput(\n result.stdout,\n result.stderr,\n request.id,\n agentId\n );\n\n request.executionResult = { stdout, stderr, exitCode };\n\n const logMsg: PolicyRequestMessage = {\n id: randomUUID(),\n // TODO: we should store the message ID in the CLAW_API_TOKEN, and extract it here\n messageId: randomUUID(),\n role: 'policy',\n requestId: request.id,\n commandName: input.commandName,\n args: input.args,\n status: 'approved',\n content: `[Auto-approved] Policy ${input.commandName} was executed.\\n\\nCommand: ${commandStr}\\nExit Code: ${exitCode}\\n\\nStdout:\\n${stdout}\\n\\nStderr:\\n${stderr}`,\n timestamp: new Date().toISOString(),\n sessionId: ctx.tokenPayload.sessionId,\n ...(ctx.tokenPayload.subagentId ? { subagentId: ctx.tokenPayload.subagentId } : {}),\n ...(ctx.tokenPayload.turnId ? { turnId: ctx.tokenPayload.turnId } : {}),\n };\n\n await appendMessage(chatId, logMsg);\n return request;\n }\n\n const previewContent = await generateRequestPreview(request);\n\n const logMsg: PolicyRequestMessage = {\n id: randomUUID(),\n // TODO: we should store the message ID in the CLAW_API_TOKEN, and extract it here\n messageId: randomUUID(),\n role: 'policy',\n requestId: request.id,\n commandName: input.commandName,\n args: input.args,\n status: 'pending',\n content: previewContent,\n timestamp: new Date().toISOString(),\n displayRole: 'agent',\n sessionId: ctx.tokenPayload.sessionId,\n ...(ctx.tokenPayload.turnId ? { turnId: ctx.tokenPayload.turnId } : {}),\n };\n\n await appendMessage(chatId, logMsg);\n return request;\n });\n","import { randomUUID } from 'node:crypto';\nimport { updateChatSettings, readChatSettings } from '../../shared/workspace.js';\nimport { executeDirectMessage, applyRouterStateUpdates } from '../message.js';\nimport { executeRouterPipeline, resolveRouters } from '../routers.js';\nimport type { RouterState } from '../routers/types.js';\nimport { createChatLogger } from '../agent/chat-logger.js';\nimport type { ChatSettings } from '../../shared/config.js';\nimport { taskScheduler } from '../agent/task-scheduler.js';\nimport { decrementSubagent } from '../agent/turn-registry.js';\n\nexport function getSubagentDepth(settings: ChatSettings, parentId: string | undefined): number {\n let depth = 0;\n let currentParentId = parentId;\n while (currentParentId && settings.subagents?.[currentParentId]) {\n depth++;\n currentParentId = settings.subagents[currentParentId]?.parentId;\n }\n return depth;\n}\n\n/**\n * Executes a subagent. Callers MUST have already called `incrementSubagent`\n * for the parent's turn synchronously before any `await` — this function's\n * `finally` block decrements, and we need the caller to increment earlier\n * so that a sibling's completing task cannot decrement the parent's counter\n * to zero (firing `turnEnded`) before this call's task is enqueued.\n */\nexport async function executeSubagent(\n chatId: string,\n subagentId: string,\n agentId: string,\n sessionId: string,\n prompt: string,\n isAsync: boolean | undefined,\n parentTokenPayload: {\n agentId?: string;\n subagentId?: string;\n sessionId?: string;\n turnId?: string;\n },\n workspaceRoot: string\n) {\n const parentTurnId = parentTokenPayload?.turnId;\n try {\n try {\n const settings = (await readChatSettings(chatId)) || {};\n const routers = settings.routers ?? [];\n const resolvedRouters = resolveRouters(routers, false);\n\n let routerState: RouterState = {\n messageId: randomUUID(),\n message: prompt,\n chatId,\n agentId,\n sessionId,\n subagentId,\n env: {},\n };\n\n const initialState = { ...routerState };\n routerState = await executeRouterPipeline(routerState, resolvedRouters);\n\n await applyRouterStateUpdates(\n chatId,\n workspaceRoot,\n routerState,\n settings,\n initialState.agentId\n );\n\n await executeDirectMessage(\n chatId,\n routerState,\n undefined, // settings\n workspaceRoot,\n false, // noWait\n undefined, // userMessageContent\n subagentId, // subagentId\n undefined, // systemEvent\n undefined, // displayRole\n parentTurnId // parentTurnId — inherit from parent agent's turn\n );\n\n if (taskScheduler.hasTasks(sessionId)) {\n return;\n }\n\n // Update status\n await updateChatSettings(chatId, (finalSettings) => {\n if (finalSettings.subagents?.[subagentId]) {\n finalSettings.subagents[subagentId]!.status = 'completed';\n }\n return finalSettings;\n });\n\n const logger = createChatLogger(chatId, subagentId, sessionId, parentTurnId);\n\n // Emit debug message to wake up waiters\n await logger.logSubagentStatus({ subagentId, status: 'completed' });\n\n if (isAsync) {\n const lastLogMessage = await logger.findLastMessage(\n (m) => m.role === 'agent' || m.displayRole === 'agent'\n );\n let outputContent = '';\n if (lastLogMessage && 'content' in lastLogMessage) {\n outputContent = `\\n\\n<subagent_output>\\n${lastLogMessage.content}\\n</subagent_output>`;\n }\n\n console.log(\n 'Notifying parent',\n chatId,\n parentTokenPayload?.agentId,\n parentTokenPayload?.subagentId\n );\n // TODO: We need to overhaul the log system in general, and should not try to do it in this PR.\n // Currently, if the parent is the root agent, this notification is logged as a normal user message\n // and appears in the chat UI, violating the PRD requirement to hide orchestration.\n await executeDirectMessage(\n chatId,\n {\n messageId: randomUUID(),\n message: `<notification>Subagent ${subagentId} completed.</notification>${outputContent}`,\n chatId,\n agentId: parentTokenPayload?.agentId || 'default',\n ...(parentTokenPayload?.subagentId\n ? { subagentId: parentTokenPayload.subagentId }\n : {}),\n sessionId: parentTokenPayload?.sessionId || 'default',\n env: {},\n },\n undefined,\n workspaceRoot,\n true,\n undefined,\n parentTokenPayload?.subagentId,\n 'subagent_update',\n undefined,\n parentTurnId\n );\n }\n } catch {\n // TODO: Wrap this in a safe try-catch to prevent unhandled promise rejections crashing the daemon if disk errors occur\n await updateChatSettings(chatId, (errSettings) => {\n if (errSettings.subagents?.[subagentId]) {\n errSettings.subagents[subagentId]!.status = 'failed';\n }\n return errSettings;\n });\n const logger = createChatLogger(chatId, subagentId, sessionId, parentTurnId);\n await logger.logSubagentStatus({ subagentId, status: 'failed' });\n }\n } finally {\n decrementSubagent(parentTurnId);\n }\n}\n","import { z } from 'zod';\nimport { randomUUID } from 'node:crypto';\nimport { TRPCError } from '@trpc/server';\nimport { getWorkspaceRoot, readChatSettings, updateChatSettings } from '../../shared/workspace.js';\nimport { apiProcedure } from './trpc.js';\nimport { createChatLogger } from '../agent/chat-logger.js';\nimport { on } from 'node:events';\nimport { daemonEvents, DAEMON_EVENT_MESSAGE_APPENDED } from '../events.js';\nimport { createAgentSession } from '../agent/agent-session.js';\nimport { executeSubagent, getSubagentDepth } from './subagent-utils.js';\nimport { incrementSubagent, decrementSubagent } from '../agent/turn-registry.js';\nimport type { ChatSettings, SubagentTracker } from '../../shared/config.js';\n\nconst MAX_SUBAGENT_DEPTH = 2;\n\nfunction assertSubagentAccess(\n settings: ChatSettings | null | undefined,\n subagentId: string,\n callerSubagentId: string | undefined\n): SubagentTracker {\n const sub = settings?.subagents?.[subagentId];\n if (!sub) throw new TRPCError({ code: 'NOT_FOUND', message: 'Subagent not found' });\n if (sub.parentId !== callerSubagentId) {\n throw new TRPCError({ code: 'FORBIDDEN', message: 'Subagent is not a child of the caller' });\n }\n return sub;\n}\n\nexport const subagentSpawn = apiProcedure\n .input(\n z.object({\n subagentId: z.string().optional(),\n targetAgentId: z.string().optional(),\n prompt: z.string(),\n async: z.boolean().optional(),\n })\n )\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n const parentAgentId = ctx.tokenPayload.agentId;\n const parentId = ctx.tokenPayload.subagentId;\n const parentTurnId = ctx.tokenPayload.turnId;\n\n const id = input.subagentId || randomUUID();\n const sessionId = randomUUID();\n const agentId = input.targetAgentId || parentAgentId;\n let depth = 0;\n\n // Increment synchronously before any await so a sibling subagent's\n // completion cannot decrement the parent's counter to zero (firing\n // turnEnded) during the window before executeSubagent is called.\n incrementSubagent(parentTurnId);\n let handedOff = false;\n try {\n await updateChatSettings(chatId, (settings) => {\n settings.subagents = settings.subagents || {};\n\n depth = getSubagentDepth(settings, parentId);\n if (depth >= MAX_SUBAGENT_DEPTH) {\n throw new TRPCError({ code: 'BAD_REQUEST', message: 'Max subagent depth reached' });\n }\n\n // Make sure the id does not already exist\n if (settings.subagents[id]) {\n throw new TRPCError({ code: 'BAD_REQUEST', message: 'Subagent ID already exists' });\n }\n\n settings.subagents[id] = {\n id,\n agentId,\n sessionId,\n createdAt: new Date().toISOString(),\n status: 'active',\n parentId,\n };\n\n return settings;\n });\n\n const workspaceRoot = getWorkspaceRoot(process.cwd());\n\n const isAsync = input.async ?? depth === 0;\n\n // Execute asynchronously — executeSubagent's finally decrements.\n handedOff = true;\n executeSubagent(\n chatId,\n id,\n agentId,\n sessionId,\n input.prompt,\n isAsync,\n ctx.tokenPayload,\n workspaceRoot\n );\n\n return { id, depth, isAsync };\n } finally {\n if (!handedOff) decrementSubagent(parentTurnId);\n }\n });\n\nexport const subagentSend = apiProcedure\n .input(\n z.object({\n subagentId: z.string(),\n prompt: z.string(),\n async: z.boolean().optional(),\n })\n )\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n const parentTurnId = ctx.tokenPayload.turnId;\n\n let sub: SubagentTracker | undefined;\n\n incrementSubagent(parentTurnId);\n let handedOff = false;\n try {\n await updateChatSettings(chatId, (settings) => {\n sub = assertSubagentAccess(settings, input.subagentId, ctx.tokenPayload!.subagentId);\n sub.status = 'active';\n return settings;\n });\n\n const workspaceRoot = getWorkspaceRoot(process.cwd());\n\n handedOff = true;\n executeSubagent(\n chatId,\n sub!.id,\n sub!.agentId || 'default',\n sub!.sessionId || 'default',\n input.prompt,\n input.async,\n ctx.tokenPayload,\n workspaceRoot\n );\n\n return { success: true };\n } finally {\n if (!handedOff) decrementSubagent(parentTurnId);\n }\n });\n\nasync function checkSubagentStatus(\n chatId: string,\n subagentId: string,\n callerSubagentId: string | undefined\n) {\n const settings = await readChatSettings(chatId);\n const sub = assertSubagentAccess(settings, subagentId, callerSubagentId);\n\n if (sub.status === 'completed' || sub.status === 'failed') {\n let outputContent: string | undefined;\n if (sub.status === 'completed') {\n const logger = createChatLogger(chatId, subagentId);\n const lastLogMessage = await logger.findLastMessage((m) => m.role === 'agent');\n if (lastLogMessage && 'content' in lastLogMessage) {\n outputContent = lastLogMessage.content;\n }\n }\n return { status: sub.status, output: outputContent };\n }\n return null;\n}\n\nexport const subagentWait = apiProcedure\n .input(z.object({ subagentId: z.string() }))\n .mutation(async ({ input, ctx, signal }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n\n const ac = new AbortController();\n const timeout = setTimeout(() => ac.abort(), 60000);\n\n // Bind to the TRPC request abort signal to clean up listeners if client disconnects\n const onAbort = () => {\n clearTimeout(timeout);\n ac.abort();\n };\n if (signal) {\n signal.addEventListener('abort', onAbort);\n }\n\n const eventIterator = on(daemonEvents, DAEMON_EVENT_MESSAGE_APPENDED, {\n signal: ac.signal,\n });\n\n try {\n // Check status immediately before listening, but after event iterator is buffering\n const initialStatus = await checkSubagentStatus(\n chatId,\n input.subagentId,\n ctx.tokenPayload.subagentId\n );\n if (initialStatus) {\n clearTimeout(timeout);\n if (signal) signal.removeEventListener('abort', onAbort);\n return initialStatus;\n }\n\n for await (const [event] of eventIterator) {\n if (event.chatId === chatId && event.message?.subagentId === input.subagentId) {\n const msg = event.message;\n if (msg.role === 'subagent_status') {\n const status = await checkSubagentStatus(\n chatId,\n input.subagentId,\n ctx.tokenPayload.subagentId\n );\n if (status) {\n clearTimeout(timeout);\n if (signal) signal.removeEventListener('abort', onAbort);\n return status;\n }\n }\n }\n }\n } catch (err: unknown) {\n if (err && typeof err === 'object' && 'name' in err && err.name === 'AbortError') {\n return { status: 'active' as const, output: undefined };\n }\n throw err;\n } finally {\n clearTimeout(timeout);\n if (signal) signal.removeEventListener('abort', onAbort);\n ac.abort();\n }\n\n return { status: 'active' as const, output: undefined };\n });\n\nexport const subagentStop = apiProcedure\n .input(z.object({ subagentId: z.string() }))\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n\n let subToStop: SubagentTracker | undefined;\n\n await updateChatSettings(chatId, (settings) => {\n const sub = assertSubagentAccess(settings, input.subagentId, ctx.tokenPayload!.subagentId);\n sub.status = 'failed';\n subToStop = sub;\n return settings;\n });\n\n if (subToStop) {\n const session = await createAgentSession({\n chatId,\n agentId: subToStop.agentId || 'default',\n sessionId: subToStop.sessionId || 'default',\n subagentId: input.subagentId,\n cwd: process.cwd(),\n });\n session.stop();\n }\n\n return { success: true };\n });\n\nexport const subagentDelete = apiProcedure\n .input(z.object({ subagentId: z.string() }))\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n\n let subToDelete: SubagentTracker | undefined;\n\n await updateChatSettings(chatId, (settings) => {\n subToDelete = assertSubagentAccess(settings, input.subagentId, ctx.tokenPayload!.subagentId);\n delete settings.subagents![input.subagentId];\n return settings;\n });\n\n if (subToDelete) {\n const session = await createAgentSession({\n chatId,\n agentId: subToDelete.agentId || 'default',\n sessionId: subToDelete.sessionId || 'default',\n subagentId: input.subagentId,\n cwd: process.cwd(),\n });\n session.stop();\n\n return { success: true, deleted: true };\n }\n\n return { success: true, deleted: false };\n });\n\nexport const subagentList = apiProcedure\n .input(z.object({ blocking: z.boolean().optional() }).optional())\n .query(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n const settings = await readChatSettings(chatId);\n\n let subagents = Object.values(settings?.subagents || {});\n\n const isSubagent = !!ctx.tokenPayload.subagentId;\n const myId = ctx.tokenPayload.subagentId;\n\n subagents = subagents.filter((s) => s.parentId === myId);\n\n if (input?.blocking) {\n if (!isSubagent) {\n subagents = [];\n } else {\n subagents = subagents.filter((s) => s.status === 'active');\n }\n }\n return { subagents };\n });\n\nexport const subagentTail = apiProcedure\n .input(z.object({ subagentId: z.string(), limit: z.number().optional() }))\n .query(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n\n const settings = await readChatSettings(chatId);\n assertSubagentAccess(settings, input.subagentId, ctx.tokenPayload.subagentId);\n\n const logger = createChatLogger(chatId, input.subagentId);\n const messages = await logger.getMessages(input.limit);\n\n return { messages };\n });\n","import { z } from 'zod';\nimport { randomUUID } from 'node:crypto';\nimport { TRPCError } from '@trpc/server';\nimport {\n appendMessage,\n type CommandLogMessage,\n type AgentReplyMessage,\n type ToolMessage,\n} from '../chats.js';\nimport { getWorkspaceRoot } from '../../shared/workspace.js';\nimport type { CronJob } from '../../shared/config.js';\nimport { apiProcedure, router } from './trpc.js';\nimport { taskScheduler } from '../agent/task-scheduler.js';\nimport { formatPendingMessages } from '../agent/utils.js';\nimport {\n resolveAgentDir,\n validateLogFile,\n listCronJobsShared,\n addCronJobShared,\n deleteCronJobShared,\n} from './router-utils.js';\n\nexport const logMessage = apiProcedure\n .input(\n z.object({\n message: z.string().optional(),\n files: z.array(z.string()).optional(),\n })\n )\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n const timestamp = new Date().toISOString();\n const id = Date.now().toString() + Math.random().toString(36).substring(2, 7);\n\n const filePaths: string[] = [];\n if (input.files && input.files.length > 0) {\n const workspaceRoot = getWorkspaceRoot(process.cwd());\n const agentDir = await resolveAgentDir(ctx.tokenPayload?.agentId, workspaceRoot);\n\n for (const file of input.files) {\n const validPath = await validateLogFile(file, agentDir, workspaceRoot);\n filePaths.push(validPath);\n }\n }\n\n const filesArgStr = filePaths.map((p) => ` --file ${p}`).join('');\n const messageStr = input.message || '';\n const logMsg: CommandLogMessage = {\n id,\n messageId: id,\n role: 'command',\n content: messageStr,\n stdout: '',\n stderr: '',\n timestamp,\n command: `clawmini-lite log${filesArgStr}`,\n cwd: process.cwd(),\n exitCode: 0,\n sessionId: ctx.tokenPayload.sessionId,\n ...(ctx.tokenPayload.subagentId ? { subagentId: ctx.tokenPayload.subagentId } : {}),\n ...(ctx.tokenPayload.turnId ? { turnId: ctx.tokenPayload.turnId } : {}),\n ...(filePaths.length > 0 ? { files: filePaths } : {}),\n };\n\n await appendMessage(chatId, logMsg);\n return { success: true };\n });\n\nexport const logReplyMessage = apiProcedure\n .input(\n z.object({\n message: z.string(),\n files: z.array(z.string()).optional(),\n })\n )\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n const timestamp = new Date().toISOString();\n const id = Date.now().toString() + Math.random().toString(36).substring(2, 7);\n\n const filePaths: string[] = [];\n if (input.files && input.files.length > 0) {\n const workspaceRoot = getWorkspaceRoot(process.cwd());\n const agentDir = await resolveAgentDir(ctx.tokenPayload?.agentId, workspaceRoot);\n\n for (const file of input.files) {\n const validPath = await validateLogFile(file, agentDir, workspaceRoot);\n filePaths.push(validPath);\n }\n }\n\n const logMsg: AgentReplyMessage = {\n id,\n role: 'agent',\n content: input.message,\n timestamp,\n sessionId: ctx.tokenPayload.sessionId,\n ...(ctx.tokenPayload.subagentId ? { subagentId: ctx.tokenPayload.subagentId } : {}),\n ...(ctx.tokenPayload.turnId ? { turnId: ctx.tokenPayload.turnId } : {}),\n ...(filePaths.length > 0 ? { files: filePaths } : {}),\n };\n\n await appendMessage(chatId, logMsg);\n return { success: true };\n });\n\nexport const logToolMessage = apiProcedure\n .input(\n z.object({\n name: z.string(),\n payload: z.any().optional(),\n })\n )\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n const timestamp = new Date().toISOString();\n const id = Date.now().toString() + Math.random().toString(36).substring(2, 7);\n const messageId = randomUUID();\n\n const payloadObj = input.payload !== undefined ? input.payload : {};\n let contentStr: string;\n if (typeof payloadObj === 'string') {\n contentStr = payloadObj;\n } else {\n try {\n contentStr = JSON.stringify(payloadObj, null, 2);\n } catch {\n contentStr = String(payloadObj);\n }\n }\n\n const logMsg: ToolMessage = {\n id,\n messageId,\n role: 'tool',\n name: input.name,\n payload: payloadObj,\n content: contentStr,\n timestamp,\n sessionId: ctx.tokenPayload.sessionId,\n ...(ctx.tokenPayload.subagentId ? { subagentId: ctx.tokenPayload.subagentId } : {}),\n ...(ctx.tokenPayload.turnId ? { turnId: ctx.tokenPayload.turnId } : {}),\n };\n\n await appendMessage(chatId, logMsg);\n return { success: true };\n });\n\nexport const agentListCronJobs = apiProcedure.query(async ({ ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n return listCronJobsShared(chatId);\n});\n\n// Agents may only set a restricted subset of CronJob fields. The remaining\n// fields (agentId, createdAt, env, nextSessionId, action, jobs) are reserved\n// for internal use and filled in by the server.\nexport const AgentCronJobInputSchema = z.strictObject({\n id: z.string().min(1),\n message: z.string().default(''),\n reply: z.string().optional(),\n session: z\n .union([\n z.strictObject({ type: z.literal('new') }),\n z.strictObject({ type: z.literal('existing'), id: z.string() }),\n ])\n .optional(),\n schedule: z.union([\n z.strictObject({ cron: z.string() }),\n z.strictObject({ every: z.string() }),\n z.strictObject({ at: z.string() }),\n ]),\n});\n\nexport type AgentCronJobInput = z.infer<typeof AgentCronJobInputSchema>;\n\nexport const agentAddCronJob = apiProcedure\n .input(z.object({ job: AgentCronJobInputSchema }))\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n const job: CronJob = {\n id: input.job.id,\n message: input.job.message,\n schedule: input.job.schedule,\n createdAt: new Date().toISOString(),\n agentId: ctx.tokenPayload.agentId,\n ...(input.job.reply !== undefined ? { reply: input.job.reply } : {}),\n ...(input.job.session !== undefined ? { session: input.job.session } : {}),\n };\n return addCronJobShared(chatId, job);\n });\n\nexport const agentDeleteCronJob = apiProcedure\n .input(z.object({ id: z.string() }))\n .mutation(async ({ input, ctx }) => {\n if (!ctx.tokenPayload) throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing token' });\n const chatId = ctx.tokenPayload.chatId;\n return deleteCronJobShared(chatId, input.id);\n });\n\nimport {\n listPolicies,\n executePolicyHelp,\n createPolicyRequest,\n readPolicyScript,\n} from './agent-policy-endpoints.js';\n\nimport { ping } from './user-router.js';\n\nexport const fetchPendingMessages = apiProcedure.mutation(async ({ ctx }) => {\n if (!ctx.tokenPayload?.agentId) {\n throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Missing agent ID' });\n }\n const targetSessionId = ctx.tokenPayload?.sessionId || 'default';\n\n const extracted = taskScheduler.extractPending(targetSessionId);\n if (extracted.length === 0) {\n return { messages: '' };\n }\n\n return { messages: formatPendingMessages(extracted) };\n});\n\nimport {\n subagentSpawn,\n subagentSend,\n subagentWait,\n subagentStop,\n subagentDelete,\n subagentList,\n subagentTail,\n} from './subagent-router.js';\n\nexport const agentRouter = router({\n logMessage,\n logReplyMessage,\n logToolMessage,\n listCronJobs: agentListCronJobs,\n addCronJob: agentAddCronJob,\n deleteCronJob: agentDeleteCronJob,\n listPolicies,\n executePolicyHelp,\n createPolicyRequest,\n readPolicyScript,\n fetchPendingMessages,\n ping,\n subagentSpawn,\n subagentSend,\n subagentWait,\n subagentStop,\n subagentDelete,\n subagentList,\n subagentTail,\n});\n\nexport type AgentRouter = typeof agentRouter;\n","import http from 'node:http';\nimport net from 'node:net';\nimport fs from 'node:fs';\nimport { execSync } from 'node:child_process';\nimport { createHTTPHandler } from '@trpc/server/adapters/standalone';\nimport { userRouter, agentRouter } from './api/index.js';\nimport {\n getSocketPath,\n getClawminiDir,\n getSettingsPath,\n readSettings,\n readEnvironment,\n getEnvironmentPath,\n getWorkspaceRoot,\n updateChatSettings,\n} from '../shared/workspace.js';\nimport { listChats } from '../shared/chats.js';\nimport { cronManager } from './cron.js';\nimport { SettingsSchema } from '../shared/config.js';\nimport { validateToken, getApiContext } from './auth.js';\nimport path from 'node:path';\nimport { exportLiteToEnvironment } from '../shared/lite.js';\nimport { RequestStore } from './request-store.js';\nimport { drainPendingReplies } from './pending-replies.js';\nimport { getClawminiVersion } from '../shared/version.js';\n\nexport async function initDaemon() {\n const socketPath = getSocketPath();\n const clawminiDir = getClawminiDir();\n\n // Ensure the .clawmini directory exists\n if (!fs.existsSync(clawminiDir)) {\n throw new Error(`${clawminiDir} does not exist`);\n }\n\n // Read settings to check if API is enabled\n const settingsPath = getSettingsPath();\n let apiCtx: ReturnType<typeof getApiContext> = null;\n\n if (fs.existsSync(settingsPath)) {\n try {\n const settingsStr = fs.readFileSync(settingsPath, 'utf8');\n const settings = JSON.parse(settingsStr);\n const parsed = SettingsSchema.safeParse(settings);\n if (parsed.success) {\n apiCtx = getApiContext(parsed.data);\n }\n } catch (err) {\n console.warn(`Failed to read or parse settings from ${settingsPath}:`, err);\n }\n }\n\n const runHooks = async (hookType: 'up' | 'down') => {\n try {\n const currentSettings = await readSettings();\n const workspaceRoot = getWorkspaceRoot(process.cwd());\n if (!currentSettings?.environments) return;\n for (const [envPath, envName] of Object.entries(currentSettings.environments)) {\n try {\n const envConfig = await readEnvironment(envName);\n const envDir = getEnvironmentPath(envName);\n const affectedDir = path.resolve(workspaceRoot, envPath);\n\n // Try to export clawmini-lite to the environment directory\n if (hookType === 'up' && envConfig) {\n await exportLiteToEnvironment(envName, envConfig, affectedDir);\n }\n\n const command = envConfig?.[hookType];\n if (command) {\n console.log(`Executing '${hookType}' hook for environment '${envName}': ${command}`);\n // No timeout: a SIGTERM mid-hook risks partial teardown (e.g.\n // containers left running). The supervisor's per-service SIGKILL\n // timer is the ultimate backstop for runaway hooks.\n execSync(command, {\n cwd: affectedDir,\n stdio: 'inherit',\n env: { ...process.env, ENV_DIR: envDir },\n });\n }\n } catch (err) {\n console.error(`Failed to execute '${hookType}' hook for environment '${envName}':`, err);\n if (hookType === 'up') throw err;\n }\n }\n } catch (err) {\n console.error(`Failed to run '${hookType}' hooks:`, err);\n if (hookType === 'up') throw err;\n }\n };\n\n // Ensure the old socket file is removed, but first check if another daemon is actively listening\n if (fs.existsSync(socketPath)) {\n const isSocketInUse = await new Promise<boolean>((resolve) => {\n const client = net.createConnection({ path: socketPath });\n client.on('connect', () => {\n client.destroy();\n resolve(true);\n });\n client.on('error', () => {\n resolve(false);\n });\n });\n\n if (isSocketInUse) {\n console.log('Daemon is already running (socket is active). Exiting.');\n process.exit(0);\n }\n\n try {\n fs.unlinkSync(socketPath);\n } catch {\n // Ignore\n }\n }\n\n let isReady = false;\n let readyPromiseResolve: () => void;\n const readyPromise = new Promise<void>((resolve) => {\n readyPromiseResolve = resolve;\n });\n\n const handler = createHTTPHandler({\n router: userRouter,\n createContext: ({ req, res }) => ({ req, res, isApiServer: false }),\n });\n\n const server = http.createServer(async (req, res) => {\n if (!isReady) {\n await readyPromise;\n }\n // Only accept POST requests on /trpc/ path if needed, but since we are running over Unix socket, we map directly\n handler(req, res);\n });\n\n await new Promise<void>((resolve, reject) => {\n server.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE') {\n console.log('Daemon is already running (socket bind failed). Exiting.');\n process.exit(0);\n }\n reject(err);\n });\n server.listen(socketPath, () => {\n console.log(`Daemon initialized and listening on ${socketPath}`);\n resolve();\n });\n });\n\n const cleanOrphanedSubagents = async () => {\n try {\n const chats = await listChats();\n for (const chatId of chats) {\n await updateChatSettings(chatId, (settings) => {\n if (settings.subagents) {\n for (const subagent of Object.values(settings.subagents)) {\n if (subagent.status === 'active') {\n subagent.status = 'failed';\n }\n }\n }\n return settings;\n });\n }\n } catch (err) {\n console.warn('Failed to clean orphaned subagents:', err);\n }\n };\n await cleanOrphanedSubagents();\n\n try {\n const removed = await new RequestStore(getWorkspaceRoot()).cleanupCompleted();\n if (removed > 0) {\n console.log(`Cleaned up ${removed} completed policy request file(s).`);\n }\n } catch (err) {\n console.warn('Failed to clean completed policy requests:', err);\n }\n\n await runHooks('up');\n\n isReady = true;\n readyPromiseResolve!();\n\n // Drain any replies queued by the previous daemon instance (e.g. /restart\n // or /upgrade). This must run after the daemon is `isReady` so the tRPC\n // subscription that the adapter forwarder reconnects to can deliver them.\n try {\n await drainPendingReplies(getClawminiVersion());\n } catch (err) {\n console.warn('Failed to drain pending replies:', err);\n }\n\n // Initialize cron jobs\n cronManager.init().catch((err) => {\n console.error('Failed to initialize cron manager:', err);\n });\n\n let apiServer: http.Server | undefined;\n if (apiCtx) {\n const apiHandler = createHTTPHandler({\n router: agentRouter,\n createContext: ({ req, res }) => {\n let tokenPayload = null;\n const authHeader = req.headers.authorization;\n if (authHeader && authHeader.startsWith('Bearer ')) {\n const token = authHeader.substring(7);\n tokenPayload = validateToken(token);\n }\n return { req, res, isApiServer: true, tokenPayload };\n },\n });\n\n apiServer = http.createServer((req, res) => {\n apiHandler(req, res);\n });\n\n const host = apiCtx.host;\n const port = apiCtx.port;\n apiServer.listen(port, host, () => {\n console.log(`Daemon HTTP API initialized and listening on http://${host}:${port}`);\n });\n }\n\n let isShuttingDown = false;\n const shutdown = async () => {\n if (isShuttingDown) return;\n isShuttingDown = true;\n console.log('Daemon shutting down...');\n\n await runHooks('down');\n\n server.close();\n if (apiServer) apiServer.close();\n process.exit(0);\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n process.on('exit', () => {\n if (fs.existsSync(socketPath)) {\n try {\n fs.unlinkSync(socketPath);\n } catch {\n // Ignore errors during exit cleanup\n }\n }\n });\n}\n\n// Only auto-initialize if run directly\nif (process.argv[1] === new URL(import.meta.url).pathname) {\n initDaemon().catch((err) => {\n console.error('Daemon initialization failed:', err);\n process.exit(1);\n });\n}\n"],"mappings":"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"}
|