agim-cli 1.2.44 → 1.2.48
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/CHANGELOG.md +295 -0
- package/README.md +39 -5
- package/README.zh-CN.md +40 -6
- package/dist/cli-ui/config-wizard.js +15 -2
- package/dist/cli-ui/config-wizard.js.map +1 -1
- package/dist/cli-ui/diag.d.ts +29 -0
- package/dist/cli-ui/diag.d.ts.map +1 -0
- package/dist/cli-ui/diag.js +135 -0
- package/dist/cli-ui/diag.js.map +1 -0
- package/dist/cli-ui/i18n.d.ts +36 -0
- package/dist/cli-ui/i18n.d.ts.map +1 -1
- package/dist/cli-ui/i18n.js +97 -0
- package/dist/cli-ui/i18n.js.map +1 -1
- package/dist/cli-ui/setup-llm.d.ts +30 -0
- package/dist/cli-ui/setup-llm.d.ts.map +1 -0
- package/dist/cli-ui/setup-llm.js +460 -0
- package/dist/cli-ui/setup-llm.js.map +1 -0
- package/dist/cli-ui/setup-mcp.d.ts +19 -0
- package/dist/cli-ui/setup-mcp.d.ts.map +1 -0
- package/dist/cli-ui/setup-mcp.js +308 -0
- package/dist/cli-ui/setup-mcp.js.map +1 -0
- package/dist/cli-ui/token-menu.js +2 -2
- package/dist/cli-ui/token-menu.js.map +1 -1
- package/dist/cli.js +100 -22
- package/dist/cli.js.map +1 -1
- package/dist/core/access-token.d.ts +16 -5
- package/dist/core/access-token.d.ts.map +1 -1
- package/dist/core/access-token.js +82 -13
- package/dist/core/access-token.js.map +1 -1
- package/dist/core/agent-cwd.d.ts.map +1 -1
- package/dist/core/agent-cwd.js +46 -0
- package/dist/core/agent-cwd.js.map +1 -1
- package/dist/core/approval-bus.d.ts +22 -0
- package/dist/core/approval-bus.d.ts.map +1 -1
- package/dist/core/approval-bus.js +93 -0
- package/dist/core/approval-bus.js.map +1 -1
- package/dist/core/ask-user-router.d.ts +24 -0
- package/dist/core/ask-user-router.d.ts.map +1 -0
- package/dist/core/ask-user-router.js +84 -0
- package/dist/core/ask-user-router.js.map +1 -0
- package/dist/core/ask-user-rpc.d.ts +80 -0
- package/dist/core/ask-user-rpc.d.ts.map +1 -0
- package/dist/core/ask-user-rpc.js +388 -0
- package/dist/core/ask-user-rpc.js.map +1 -0
- package/dist/core/audit-log.d.ts +1 -1
- package/dist/core/audit-log.d.ts.map +1 -1
- package/dist/core/audit-log.js.map +1 -1
- package/dist/core/commands/builtin.d.ts.map +1 -1
- package/dist/core/commands/builtin.js +21 -5
- package/dist/core/commands/builtin.js.map +1 -1
- package/dist/core/commands/goal.d.ts +3 -0
- package/dist/core/commands/goal.d.ts.map +1 -0
- package/dist/core/commands/goal.js +240 -0
- package/dist/core/commands/goal.js.map +1 -0
- package/dist/core/commands/heartbeat.d.ts +3 -0
- package/dist/core/commands/heartbeat.d.ts.map +1 -0
- package/dist/core/commands/heartbeat.js +219 -0
- package/dist/core/commands/heartbeat.js.map +1 -0
- package/dist/core/commands/router-compare.d.ts +3 -0
- package/dist/core/commands/router-compare.d.ts.map +1 -0
- package/dist/core/commands/router-compare.js +81 -0
- package/dist/core/commands/router-compare.js.map +1 -0
- package/dist/core/commands/router.d.ts.map +1 -1
- package/dist/core/commands/router.js +9 -1
- package/dist/core/commands/router.js.map +1 -1
- package/dist/core/commands/skill.d.ts +3 -0
- package/dist/core/commands/skill.d.ts.map +1 -0
- package/dist/core/commands/skill.js +91 -0
- package/dist/core/commands/skill.js.map +1 -0
- package/dist/core/config-schema.d.ts +28 -0
- package/dist/core/config-schema.d.ts.map +1 -1
- package/dist/core/config-schema.js +124 -0
- package/dist/core/config-schema.js.map +1 -1
- package/dist/core/goals.d.ts +81 -0
- package/dist/core/goals.d.ts.map +1 -0
- package/dist/core/goals.js +361 -0
- package/dist/core/goals.js.map +1 -0
- package/dist/core/heartbeat-store.d.ts +90 -0
- package/dist/core/heartbeat-store.d.ts.map +1 -0
- package/dist/core/heartbeat-store.js +302 -0
- package/dist/core/heartbeat-store.js.map +1 -0
- package/dist/core/heartbeat.d.ts +35 -0
- package/dist/core/heartbeat.d.ts.map +1 -0
- package/dist/core/heartbeat.js +332 -0
- package/dist/core/heartbeat.js.map +1 -0
- package/dist/core/intent-llm.d.ts +9 -0
- package/dist/core/intent-llm.d.ts.map +1 -1
- package/dist/core/intent-llm.js +77 -32
- package/dist/core/intent-llm.js.map +1 -1
- package/dist/core/llm/agent-loop.d.ts +112 -0
- package/dist/core/llm/agent-loop.d.ts.map +1 -0
- package/dist/core/llm/agent-loop.js +313 -0
- package/dist/core/llm/agent-loop.js.map +1 -0
- package/dist/core/llm/anthropic-provider.d.ts +53 -0
- package/dist/core/llm/anthropic-provider.d.ts.map +1 -0
- package/dist/core/llm/anthropic-provider.js +339 -0
- package/dist/core/llm/anthropic-provider.js.map +1 -0
- package/dist/core/llm/auto-compact.d.ts +35 -0
- package/dist/core/llm/auto-compact.d.ts.map +1 -0
- package/dist/core/llm/auto-compact.js +149 -0
- package/dist/core/llm/auto-compact.js.map +1 -0
- package/dist/core/llm/builtin-dispatcher.d.ts +21 -0
- package/dist/core/llm/builtin-dispatcher.d.ts.map +1 -0
- package/dist/core/llm/builtin-dispatcher.js +196 -0
- package/dist/core/llm/builtin-dispatcher.js.map +1 -0
- package/dist/core/llm/imhub-dispatcher.d.ts +27 -0
- package/dist/core/llm/imhub-dispatcher.d.ts.map +1 -0
- package/dist/core/llm/imhub-dispatcher.js +308 -0
- package/dist/core/llm/imhub-dispatcher.js.map +1 -0
- package/dist/core/llm/index.d.ts +11 -0
- package/dist/core/llm/index.d.ts.map +1 -0
- package/dist/core/llm/index.js +16 -0
- package/dist/core/llm/index.js.map +1 -0
- package/dist/core/llm/introspection.d.ts +73 -0
- package/dist/core/llm/introspection.d.ts.map +1 -0
- package/dist/core/llm/introspection.js +90 -0
- package/dist/core/llm/introspection.js.map +1 -0
- package/dist/core/llm/mcp-client.d.ts +80 -0
- package/dist/core/llm/mcp-client.d.ts.map +1 -0
- package/dist/core/llm/mcp-client.js +270 -0
- package/dist/core/llm/mcp-client.js.map +1 -0
- package/dist/core/llm/mcp-registry.d.ts +57 -0
- package/dist/core/llm/mcp-registry.d.ts.map +1 -0
- package/dist/core/llm/mcp-registry.js +155 -0
- package/dist/core/llm/mcp-registry.js.map +1 -0
- package/dist/core/llm/openai-compat-provider.d.ts +65 -0
- package/dist/core/llm/openai-compat-provider.d.ts.map +1 -0
- package/dist/core/llm/openai-compat-provider.js +451 -0
- package/dist/core/llm/openai-compat-provider.js.map +1 -0
- package/dist/core/llm/policy-approval-gate.d.ts +30 -0
- package/dist/core/llm/policy-approval-gate.d.ts.map +1 -0
- package/dist/core/llm/policy-approval-gate.js +86 -0
- package/dist/core/llm/policy-approval-gate.js.map +1 -0
- package/dist/core/llm/provider-base.d.ts +302 -0
- package/dist/core/llm/provider-base.d.ts.map +1 -0
- package/dist/core/llm/provider-base.js +222 -0
- package/dist/core/llm/provider-base.js.map +1 -0
- package/dist/core/llm/registry.d.ts +44 -0
- package/dist/core/llm/registry.d.ts.map +1 -0
- package/dist/core/llm/registry.js +160 -0
- package/dist/core/llm/registry.js.map +1 -0
- package/dist/core/llm/secrets.d.ts +46 -0
- package/dist/core/llm/secrets.d.ts.map +1 -0
- package/dist/core/llm/secrets.js +157 -0
- package/dist/core/llm/secrets.js.map +1 -0
- package/dist/core/llm/tool-dispatcher.d.ts +37 -0
- package/dist/core/llm/tool-dispatcher.d.ts.map +1 -0
- package/dist/core/llm/tool-dispatcher.js +85 -0
- package/dist/core/llm/tool-dispatcher.js.map +1 -0
- package/dist/core/memory-consolidate.d.ts.map +1 -1
- package/dist/core/memory-consolidate.js +38 -23
- package/dist/core/memory-consolidate.js.map +1 -1
- package/dist/core/memory-distill.d.ts.map +1 -1
- package/dist/core/memory-distill.js +51 -25
- package/dist/core/memory-distill.js.map +1 -1
- package/dist/core/memory-rpc.d.ts.map +1 -1
- package/dist/core/memory-rpc.js +6 -0
- package/dist/core/memory-rpc.js.map +1 -1
- package/dist/core/message-sink.d.ts.map +1 -1
- package/dist/core/message-sink.js +76 -0
- package/dist/core/message-sink.js.map +1 -1
- package/dist/core/notification-evaluator.d.ts +49 -0
- package/dist/core/notification-evaluator.d.ts.map +1 -0
- package/dist/core/notification-evaluator.js +232 -0
- package/dist/core/notification-evaluator.js.map +1 -0
- package/dist/core/onboarding.d.ts.map +1 -1
- package/dist/core/onboarding.js +10 -0
- package/dist/core/onboarding.js.map +1 -1
- package/dist/core/persona.d.ts +10 -0
- package/dist/core/persona.d.ts.map +1 -1
- package/dist/core/persona.js +28 -14
- package/dist/core/persona.js.map +1 -1
- package/dist/core/push-rpc.d.ts +8 -0
- package/dist/core/push-rpc.d.ts.map +1 -1
- package/dist/core/push-rpc.js +41 -1
- package/dist/core/push-rpc.js.map +1 -1
- package/dist/core/registry.d.ts.map +1 -1
- package/dist/core/registry.js +6 -0
- package/dist/core/registry.js.map +1 -1
- package/dist/core/render-router.d.ts.map +1 -1
- package/dist/core/render-router.js +23 -6
- package/dist/core/render-router.js.map +1 -1
- package/dist/core/router-compare.d.ts +76 -0
- package/dist/core/router-compare.d.ts.map +1 -0
- package/dist/core/router-compare.js +253 -0
- package/dist/core/router-compare.js.map +1 -0
- package/dist/core/router.d.ts.map +1 -1
- package/dist/core/router.js +25 -1
- package/dist/core/router.js.map +1 -1
- package/dist/core/skills/builtin/agim-self/SKILL.md +81 -0
- package/dist/core/skills/loader.d.ts +120 -0
- package/dist/core/skills/loader.d.ts.map +1 -0
- package/dist/core/skills/loader.js +577 -0
- package/dist/core/skills/loader.js.map +1 -0
- package/dist/core/skills-rpc.d.ts +44 -0
- package/dist/core/skills-rpc.d.ts.map +1 -0
- package/dist/core/skills-rpc.js +71 -0
- package/dist/core/skills-rpc.js.map +1 -0
- package/dist/core/types.d.ts +35 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/util/format-age.d.ts +20 -0
- package/dist/core/util/format-age.d.ts.map +1 -0
- package/dist/core/util/format-age.js +86 -0
- package/dist/core/util/format-age.js.map +1 -0
- package/dist/core/viewer-config.d.ts +15 -7
- package/dist/core/viewer-config.d.ts.map +1 -1
- package/dist/core/viewer-config.js +18 -12
- package/dist/core/viewer-config.js.map +1 -1
- package/dist/plugins/agents/acp/acp-adapter.d.ts +3 -0
- package/dist/plugins/agents/acp/acp-adapter.d.ts.map +1 -1
- package/dist/plugins/agents/acp/acp-adapter.js +12 -0
- package/dist/plugins/agents/acp/acp-adapter.js.map +1 -1
- package/dist/plugins/agents/antigravity/index.d.ts +1 -0
- package/dist/plugins/agents/antigravity/index.d.ts.map +1 -1
- package/dist/plugins/agents/antigravity/index.js +1 -0
- package/dist/plugins/agents/antigravity/index.js.map +1 -1
- package/dist/plugins/agents/claude-code/index.d.ts +1 -0
- package/dist/plugins/agents/claude-code/index.d.ts.map +1 -1
- package/dist/plugins/agents/claude-code/index.js +1 -0
- package/dist/plugins/agents/claude-code/index.js.map +1 -1
- package/dist/plugins/agents/claude-code/mcp-approval-server.d.ts +22 -0
- package/dist/plugins/agents/claude-code/mcp-approval-server.d.ts.map +1 -1
- package/dist/plugins/agents/claude-code/mcp-approval-server.js +157 -0
- package/dist/plugins/agents/claude-code/mcp-approval-server.js.map +1 -1
- package/dist/plugins/agents/codex/index.d.ts +1 -0
- package/dist/plugins/agents/codex/index.d.ts.map +1 -1
- package/dist/plugins/agents/codex/index.js +1 -0
- package/dist/plugins/agents/codex/index.js.map +1 -1
- package/dist/plugins/agents/native/index.d.ts +34 -0
- package/dist/plugins/agents/native/index.d.ts.map +1 -0
- package/dist/plugins/agents/native/index.js +598 -0
- package/dist/plugins/agents/native/index.js.map +1 -0
- package/dist/plugins/agents/opencode/opencode-stdio-adapter.d.ts +1 -0
- package/dist/plugins/agents/opencode/opencode-stdio-adapter.d.ts.map +1 -1
- package/dist/plugins/agents/opencode/opencode-stdio-adapter.js +1 -0
- package/dist/plugins/agents/opencode/opencode-stdio-adapter.js.map +1 -1
- package/dist/plugins/messengers/wechat/ilink-adapter.d.ts +4 -0
- package/dist/plugins/messengers/wechat/ilink-adapter.d.ts.map +1 -1
- package/dist/plugins/messengers/wechat/ilink-adapter.js +26 -1
- package/dist/plugins/messengers/wechat/ilink-adapter.js.map +1 -1
- package/dist/web/agim-skills-api.d.ts +4 -0
- package/dist/web/agim-skills-api.d.ts.map +1 -0
- package/dist/web/agim-skills-api.js +150 -0
- package/dist/web/agim-skills-api.js.map +1 -0
- package/dist/web/background-tasks-api.d.ts +7 -0
- package/dist/web/background-tasks-api.d.ts.map +1 -0
- package/dist/web/background-tasks-api.js +225 -0
- package/dist/web/background-tasks-api.js.map +1 -0
- package/dist/web/llm-api.d.ts +8 -0
- package/dist/web/llm-api.d.ts.map +1 -0
- package/dist/web/llm-api.js +300 -0
- package/dist/web/llm-api.js.map +1 -0
- package/dist/web/mcp-api.d.ts +8 -0
- package/dist/web/mcp-api.d.ts.map +1 -0
- package/dist/web/mcp-api.js +205 -0
- package/dist/web/mcp-api.js.map +1 -0
- package/dist/web/public/assets/{a2a-Bg_mT0z1.js → a2a-Mke0F7ZM.js} +3 -3
- package/dist/web/public/assets/{a2a-Bg_mT0z1.js.map → a2a-Mke0F7ZM.js.map} +1 -1
- package/dist/web/public/assets/{activity-U9AaNlDt.js → activity-0zGnf1_m.js} +2 -2
- package/dist/web/public/assets/{activity-U9AaNlDt.js.map → activity-0zGnf1_m.js.map} +1 -1
- package/dist/web/public/assets/{admins-BTC_YEK9.js → admins-DSi3KRky.js} +3 -3
- package/dist/web/public/assets/{admins-BTC_YEK9.js.map → admins-DSi3KRky.js.map} +1 -1
- package/dist/web/public/assets/agents-BLWe20EJ.js +7 -0
- package/dist/web/public/assets/agents-BLWe20EJ.js.map +1 -0
- package/dist/web/public/assets/{approvals-Boj7iXz4.js → approvals-Cu_JdM-8.js} +3 -3
- package/dist/web/public/assets/{approvals-Boj7iXz4.js.map → approvals-Cu_JdM-8.js.map} +1 -1
- package/dist/web/public/assets/asks-DfV8vxey.js +7 -0
- package/dist/web/public/assets/asks-DfV8vxey.js.map +1 -0
- package/dist/web/public/assets/{audit-MprCFoy_.js → audit-2EVhhvGV.js} +2 -2
- package/dist/web/public/assets/{audit-MprCFoy_.js.map → audit-2EVhhvGV.js.map} +1 -1
- package/dist/web/public/assets/bell-Wz_wuOa_.js +7 -0
- package/dist/web/public/assets/bell-Wz_wuOa_.js.map +1 -0
- package/dist/web/public/assets/{bgjobs-B6XvxURz.js → bgjobs-DXROZFAW.js} +2 -2
- package/dist/web/public/assets/{bgjobs-B6XvxURz.js.map → bgjobs-DXROZFAW.js.map} +1 -1
- package/dist/web/public/assets/{brain-C5HejASN.js → brain-Dh5VOzRL.js} +2 -2
- package/dist/web/public/assets/{brain-C5HejASN.js.map → brain-Dh5VOzRL.js.map} +1 -1
- package/dist/web/public/assets/{briefcase-DkCTxO1A.js → briefcase-DfxbvM9i.js} +2 -2
- package/dist/web/public/assets/{briefcase-DkCTxO1A.js.map → briefcase-DfxbvM9i.js.map} +1 -1
- package/dist/web/public/assets/{chevron-right-DEyrYFz4.js → chevron-right-DU8Xla1M.js} +2 -2
- package/dist/web/public/assets/{chevron-right-DEyrYFz4.js.map → chevron-right-DU8Xla1M.js.map} +1 -1
- package/dist/web/public/assets/{circle-check-bADFEXGw.js → circle-check-Be_S993G.js} +2 -2
- package/dist/web/public/assets/{circle-check-bADFEXGw.js.map → circle-check-Be_S993G.js.map} +1 -1
- package/dist/web/public/assets/{circle-check-big-U4xrkHiS.js → circle-check-big-CsQkLR1u.js} +2 -2
- package/dist/web/public/assets/{circle-check-big-U4xrkHiS.js.map → circle-check-big-CsQkLR1u.js.map} +1 -1
- package/dist/web/public/assets/{circle-x-C6qY5UUl.js → circle-x-qkQu1Swu.js} +2 -2
- package/dist/web/public/assets/{circle-x-C6qY5UUl.js.map → circle-x-qkQu1Swu.js.map} +1 -1
- package/dist/web/public/assets/{confirm-dialog-B53cbWzX.js → confirm-dialog-Bm6MsLXZ.js} +2 -2
- package/dist/web/public/assets/{confirm-dialog-B53cbWzX.js.map → confirm-dialog-Bm6MsLXZ.js.map} +1 -1
- package/dist/web/public/assets/{data-table-BKTemkw9.js → data-table-Dw4Df09-.js} +5 -5
- package/dist/web/public/assets/{data-table-BKTemkw9.js.map → data-table-Dw4Df09-.js.map} +1 -1
- package/dist/web/public/assets/{dialog-Cevi7KvQ.js → dialog-CNsc4COh.js} +3 -3
- package/dist/web/public/assets/{dialog-Cevi7KvQ.js.map → dialog-CNsc4COh.js.map} +1 -1
- package/dist/web/public/assets/{download-DwJNwdwV.js → download-Bnhk_vDY.js} +2 -2
- package/dist/web/public/assets/{download-DwJNwdwV.js.map → download-Bnhk_vDY.js.map} +1 -1
- package/dist/web/public/assets/{email-CZVaRhG_.js → email-jgAX8liM.js} +3 -3
- package/dist/web/public/assets/{email-CZVaRhG_.js.map → email-jgAX8liM.js.map} +1 -1
- package/dist/web/public/assets/{empty-state-C87S9Wor.js → empty-state-D8QXQ5y9.js} +2 -2
- package/dist/web/public/assets/{empty-state-C87S9Wor.js.map → empty-state-D8QXQ5y9.js.map} +1 -1
- package/dist/web/public/assets/{external-link-CIM1wjHP.js → external-link-C8AYvhBb.js} +2 -2
- package/dist/web/public/assets/{external-link-CIM1wjHP.js.map → external-link-C8AYvhBb.js.map} +1 -1
- package/dist/web/public/assets/{eye-TUAOhz72.js → eye-pmI_4E8x.js} +4 -4
- package/dist/web/public/assets/{eye-TUAOhz72.js.map → eye-pmI_4E8x.js.map} +1 -1
- package/dist/web/public/assets/{facts-ByM1VHCp.js → facts-BRHLLX2u.js} +2 -2
- package/dist/web/public/assets/{facts-ByM1VHCp.js.map → facts-BRHLLX2u.js.map} +1 -1
- package/dist/web/public/assets/goals-p7cNp01l.js +17 -0
- package/dist/web/public/assets/goals-p7cNp01l.js.map +1 -0
- package/dist/web/public/assets/{health-B4GF06J-.js → health-CuGIXg8C.js} +2 -2
- package/dist/web/public/assets/{health-B4GF06J-.js.map → health-CuGIXg8C.js.map} +1 -1
- package/dist/web/public/assets/heart-pulse-D0AHQl1d.js +7 -0
- package/dist/web/public/assets/heart-pulse-D0AHQl1d.js.map +1 -0
- package/dist/web/public/assets/heartbeat-DJRDS2GQ.js +7 -0
- package/dist/web/public/assets/heartbeat-DJRDS2GQ.js.map +1 -0
- package/dist/web/public/assets/hot-B1qKTiGD.js +17 -0
- package/dist/web/public/assets/hot-B1qKTiGD.js.map +1 -0
- package/dist/web/public/assets/index-B7QRVy9N.css +1 -0
- package/dist/web/public/assets/index-XJngV1gH.js +166 -0
- package/dist/web/public/assets/index-XJngV1gH.js.map +1 -0
- package/dist/web/public/assets/installed-Dz4-KevJ.js +31 -0
- package/dist/web/public/assets/installed-Dz4-KevJ.js.map +1 -0
- package/dist/web/public/assets/{jobs-DwA9Ip87.js → jobs-kwOypiWd.js} +2 -2
- package/dist/web/public/assets/{jobs-DwA9Ip87.js.map → jobs-kwOypiWd.js.map} +1 -1
- package/dist/web/public/assets/layout-01n3Aibo.js +2 -0
- package/dist/web/public/assets/layout-01n3Aibo.js.map +1 -0
- package/dist/web/public/assets/layout-CVYe2vN8.js +2 -0
- package/dist/web/public/assets/layout-CVYe2vN8.js.map +1 -0
- package/dist/web/public/assets/{layout-CR5gLapT.js → layout-CbHxH58i.js} +2 -2
- package/dist/web/public/assets/{layout-CR5gLapT.js.map → layout-CbHxH58i.js.map} +1 -1
- package/dist/web/public/assets/layout-DD1Dei48.js +2 -0
- package/dist/web/public/assets/layout-DD1Dei48.js.map +1 -0
- package/dist/web/public/assets/{layout-zotlJ5fW.js → layout-s11iwkL-.js} +2 -2
- package/dist/web/public/assets/{layout-zotlJ5fW.js.map → layout-s11iwkL-.js.map} +1 -1
- package/dist/web/public/assets/llm-DPlK10Lg.js +7 -0
- package/dist/web/public/assets/llm-DPlK10Lg.js.map +1 -0
- package/dist/web/public/assets/{loader-circle-BFp6Oc8_.js → loader-circle-DymEG5Cl.js} +2 -2
- package/dist/web/public/assets/{loader-circle-BFp6Oc8_.js.map → loader-circle-DymEG5Cl.js.map} +1 -1
- package/dist/web/public/assets/{map-pin-DPqnsBIG.js → map-pin-CyZg1-Jk.js} +2 -2
- package/dist/web/public/assets/{map-pin-DPqnsBIG.js.map → map-pin-CyZg1-Jk.js.map} +1 -1
- package/dist/web/public/assets/mcp-CiifW_qp.js +7 -0
- package/dist/web/public/assets/mcp-CiifW_qp.js.map +1 -0
- package/dist/web/public/assets/{memos-DCACQN26.js → memos-Bsiq64qW.js} +2 -2
- package/dist/web/public/assets/{memos-DCACQN26.js.map → memos-Bsiq64qW.js.map} +1 -1
- package/dist/web/public/assets/{messengers-CwWP1qI4.js → messengers-alGJK9dO.js} +3 -3
- package/dist/web/public/assets/{messengers-CwWP1qI4.js.map → messengers-alGJK9dO.js.map} +1 -1
- package/dist/web/public/assets/native-agent-CgzcqRsU.js +7 -0
- package/dist/web/public/assets/native-agent-CgzcqRsU.js.map +1 -0
- package/dist/web/public/assets/{network-CrMEVz4-.js → network-BSRJfeGk.js} +2 -2
- package/dist/web/public/assets/{network-CrMEVz4-.js.map → network-BSRJfeGk.js.map} +1 -1
- package/dist/web/public/assets/{outbox-C7FpZzwS.js → outbox-DSDls9xU.js} +3 -3
- package/dist/web/public/assets/{outbox-C7FpZzwS.js.map → outbox-DSDls9xU.js.map} +1 -1
- package/dist/web/public/assets/{pagination-Cgt8W6EX.js → pagination-DVXNZ2ti.js} +3 -3
- package/dist/web/public/assets/{pagination-Cgt8W6EX.js.map → pagination-DVXNZ2ti.js.map} +1 -1
- package/dist/web/public/assets/{persona-Bjty6uqM.js → persona-BB1gIwTX.js} +2 -2
- package/dist/web/public/assets/{persona-Bjty6uqM.js.map → persona-BB1gIwTX.js.map} +1 -1
- package/dist/web/public/assets/{play-CEoS1N8t.js → play-CcECAHfL.js} +2 -2
- package/dist/web/public/assets/{play-CEoS1N8t.js.map → play-CcECAHfL.js.map} +1 -1
- package/dist/web/public/assets/plus-DrStBHss.js +7 -0
- package/dist/web/public/assets/plus-DrStBHss.js.map +1 -0
- package/dist/web/public/assets/policy-BgDYTxy7.js +2 -0
- package/dist/web/public/assets/{policy-DwI-ov9J.js.map → policy-BgDYTxy7.js.map} +1 -1
- package/dist/web/public/assets/{refresh-ccw-CPSYEbgh.js → refresh-ccw-BBRPVLH8.js} +2 -2
- package/dist/web/public/assets/{refresh-ccw-CPSYEbgh.js.map → refresh-ccw-BBRPVLH8.js.map} +1 -1
- package/dist/web/public/assets/{reminders-X-QFSWvZ.js → reminders-jwy196Xw.js} +4 -9
- package/dist/web/public/assets/reminders-jwy196Xw.js.map +1 -0
- package/dist/web/public/assets/{save-tS3IBPf3.js → save-iBtyruco.js} +2 -2
- package/dist/web/public/assets/{save-tS3IBPf3.js.map → save-iBtyruco.js.map} +1 -1
- package/dist/web/public/assets/{schedules-CfCNvhCV.js → schedules-DDl_Sr5r.js} +3 -3
- package/dist/web/public/assets/{schedules-CfCNvhCV.js.map → schedules-DDl_Sr5r.js.map} +1 -1
- package/dist/web/public/assets/{search-BPvPCccn.js → search-Yb1S22sv.js} +2 -2
- package/dist/web/public/assets/{search-BPvPCccn.js.map → search-Yb1S22sv.js.map} +1 -1
- package/dist/web/public/assets/{service-DSitDFzD.js → service-jrg0kMtK.js} +3 -3
- package/dist/web/public/assets/{service-DSitDFzD.js.map → service-jrg0kMtK.js.map} +1 -1
- package/dist/web/public/assets/{status-badge-HSHkhdur.js → status-badge-Arxyw3TL.js} +2 -2
- package/dist/web/public/assets/{status-badge-HSHkhdur.js.map → status-badge-Arxyw3TL.js.map} +1 -1
- package/dist/web/public/assets/{subtasks-eKq_P0v6.js → subtasks-CkyuMv_X.js} +3 -3
- package/dist/web/public/assets/{subtasks-eKq_P0v6.js.map → subtasks-CkyuMv_X.js.map} +1 -1
- package/dist/web/public/assets/{table-BBISYTH-.js → table-BKdG9tsY.js} +2 -2
- package/dist/web/public/assets/{table-BBISYTH-.js.map → table-BKdG9tsY.js.map} +1 -1
- package/dist/web/public/assets/{topn-JA8llaUI.js → topn-BpX8BKWS.js} +3 -3
- package/dist/web/public/assets/{topn-JA8llaUI.js.map → topn-BpX8BKWS.js.map} +1 -1
- package/dist/web/public/assets/{trash-2-D8F96aYm.js → trash-2-DxKJo_-6.js} +3 -3
- package/dist/web/public/assets/{trash-2-D8F96aYm.js.map → trash-2-DxKJo_-6.js.map} +1 -1
- package/dist/web/public/assets/use-background-tasks-vqoDXiAq.js +2 -0
- package/dist/web/public/assets/use-background-tasks-vqoDXiAq.js.map +1 -0
- package/dist/web/public/assets/use-llm-admin-D4snixaM.js +2 -0
- package/dist/web/public/assets/use-llm-admin-D4snixaM.js.map +1 -0
- package/dist/web/public/assets/{use-memory-BDa1R8Tf.js → use-memory-Cqf3xywK.js} +2 -2
- package/dist/web/public/assets/{use-memory-BDa1R8Tf.js.map → use-memory-Cqf3xywK.js.map} +1 -1
- package/dist/web/public/assets/{use-observability-XgxLMQsY.js → use-observability-Thh7LWoE.js} +2 -2
- package/dist/web/public/assets/{use-observability-XgxLMQsY.js.map → use-observability-Thh7LWoE.js.map} +1 -1
- package/dist/web/public/assets/{use-settings-Bc4s-JUD.js → use-settings-DRhH8owt.js} +2 -2
- package/dist/web/public/assets/{use-settings-Bc4s-JUD.js.map → use-settings-DRhH8owt.js.map} +1 -1
- package/dist/web/public/assets/{use-workspace-JalfqH6H.js → use-workspace-iLKz-h_7.js} +2 -2
- package/dist/web/public/assets/{use-workspace-JalfqH6H.js.map → use-workspace-iLKz-h_7.js.map} +1 -1
- package/dist/web/public/assets/useQuery-gnz30xMJ.js +2 -0
- package/dist/web/public/assets/{useQuery-DFryK9Pn.js.map → useQuery-gnz30xMJ.js.map} +1 -1
- package/dist/web/public/assets/{vector-G2dN_aut.js → vector-COjljy_4.js} +2 -2
- package/dist/web/public/assets/{vector-G2dN_aut.js.map → vector-COjljy_4.js.map} +1 -1
- package/dist/web/public/assets/viewer-AQHSc8hZ.js +12 -0
- package/dist/web/public/assets/viewer-AQHSc8hZ.js.map +1 -0
- package/dist/web/public/assets/{workspace-BaLZIgGn.js → workspace-DRtSCbx5.js} +4 -4
- package/dist/web/public/assets/{workspace-BaLZIgGn.js.map → workspace-DRtSCbx5.js.map} +1 -1
- package/dist/web/public/assets/{workspaces-cX_rV523.js → workspaces-BLR5ZBu6.js} +3 -3
- package/dist/web/public/assets/{workspaces-cX_rV523.js.map → workspaces-BLR5ZBu6.js.map} +1 -1
- package/dist/web/public/assets/{x-D5196-9X.js → x-DGQ0qjhc.js} +2 -2
- package/dist/web/public/assets/{x-D5196-9X.js.map → x-DGQ0qjhc.js.map} +1 -1
- package/dist/web/public/index.html +2 -2
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +45 -0
- package/dist/web/server.js.map +1 -1
- package/package.json +2 -2
- package/dist/web/public/assets/agents-o9odac79.js +0 -12
- package/dist/web/public/assets/agents-o9odac79.js.map +0 -1
- package/dist/web/public/assets/hot-O9Z19xXa.js +0 -17
- package/dist/web/public/assets/hot-O9Z19xXa.js.map +0 -1
- package/dist/web/public/assets/index-CITyis5g.js +0 -166
- package/dist/web/public/assets/index-CITyis5g.js.map +0 -1
- package/dist/web/public/assets/index-Cvacw7Jg.css +0 -1
- package/dist/web/public/assets/installed-CM34mlDU.js +0 -7
- package/dist/web/public/assets/installed-CM34mlDU.js.map +0 -1
- package/dist/web/public/assets/layout-BxrFilDN.js +0 -2
- package/dist/web/public/assets/layout-BxrFilDN.js.map +0 -1
- package/dist/web/public/assets/layout-CcJQxFci.js +0 -2
- package/dist/web/public/assets/layout-CcJQxFci.js.map +0 -1
- package/dist/web/public/assets/layout-DRRveTaR.js +0 -2
- package/dist/web/public/assets/layout-DRRveTaR.js.map +0 -1
- package/dist/web/public/assets/policy-DwI-ov9J.js +0 -2
- package/dist/web/public/assets/reminders-X-QFSWvZ.js.map +0 -1
- package/dist/web/public/assets/use-skills-DCOYAQ8s.js +0 -2
- package/dist/web/public/assets/use-skills-DCOYAQ8s.js.map +0 -1
- package/dist/web/public/assets/useQuery-DFryK9Pn.js +0 -2
- package/dist/web/public/assets/viewer-DliYQkQQ.js +0 -12
- package/dist/web/public/assets/viewer-DliYQkQQ.js.map +0 -1
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
// heartbeat-store — persistent state for the heartbeat service (P0 #1).
|
|
2
|
+
//
|
|
3
|
+
// One row per IM thread that has a heartbeat configured. The row holds
|
|
4
|
+
// the markdown "body" the heartbeat agent reasons against, the tick
|
|
5
|
+
// recurrence, the latest tick outcome (for /heartbeat show), and a tiny
|
|
6
|
+
// preview of the most recent delivery (so users can see "I last pinged
|
|
7
|
+
// you about X at HH:MM").
|
|
8
|
+
//
|
|
9
|
+
// Storage layout decision: SQLite, NOT a file-per-workspace markdown
|
|
10
|
+
// store (nanobot's HEARTBEAT.md design). agim is multi-tenant by IM
|
|
11
|
+
// thread; co-locating heartbeat config with the rest of agim's state
|
|
12
|
+
// (reminders.db, audit.db, etc.) keeps backup / restore / migration
|
|
13
|
+
// simple and avoids creating workspace directories for users who never
|
|
14
|
+
// touch the CLI agents.
|
|
15
|
+
//
|
|
16
|
+
// All public APIs return / accept plain objects (HeartbeatRow). Callers
|
|
17
|
+
// don't see SQLite directly so swapping the backend later is easy.
|
|
18
|
+
import { join } from 'node:path';
|
|
19
|
+
import { AGIM_HOME } from './agim-paths.js';
|
|
20
|
+
import { logger as rootLogger } from './logger.js';
|
|
21
|
+
import { createSqliteHelper } from './sqlite-helper.js';
|
|
22
|
+
const HEARTBEAT_DB = process.env.IMHUB_HEARTBEAT_DB
|
|
23
|
+
?? join(AGIM_HOME, 'heartbeat.db');
|
|
24
|
+
/** Per-thread tick recurrence, in minutes. The default lines up with
|
|
25
|
+
* nanobot's 30-min cadence; operators can override per binding with
|
|
26
|
+
* `/heartbeat interval N` or the IMHUB_HEARTBEAT_DEFAULT_INTERVAL env. */
|
|
27
|
+
export const DEFAULT_INTERVAL_MIN = 30;
|
|
28
|
+
/** Hard lower bound on the recurrence. 1-minute heartbeats are almost
|
|
29
|
+
* always a misconfiguration (the agent burns through API calls and
|
|
30
|
+
* there's no time for the previous tick to even finish). */
|
|
31
|
+
export const MIN_INTERVAL_MIN = 5;
|
|
32
|
+
/** Hard upper bound — 24h. Above this just use cron + reminders. */
|
|
33
|
+
export const MAX_INTERVAL_MIN = 24 * 60;
|
|
34
|
+
/** Max characters in a heartbeat body. Keeps prompt size bounded; the
|
|
35
|
+
* body is the entire context the cheap decide-step LLM sees, so
|
|
36
|
+
* unbounded text would silently blow the context window. */
|
|
37
|
+
export const MAX_BODY_CHARS = 8_000;
|
|
38
|
+
/** Max characters of the last delivered text we keep around for the
|
|
39
|
+
* /heartbeat show preview. Beyond this is truncated with "…". */
|
|
40
|
+
const MAX_PREVIEW_CHARS = 240;
|
|
41
|
+
const helper = createSqliteHelper({
|
|
42
|
+
file: HEARTBEAT_DB,
|
|
43
|
+
component: 'heartbeat-store',
|
|
44
|
+
logger: rootLogger,
|
|
45
|
+
schema: `
|
|
46
|
+
CREATE TABLE IF NOT EXISTS heartbeats (
|
|
47
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
48
|
+
platform TEXT NOT NULL,
|
|
49
|
+
channel_id TEXT NOT NULL,
|
|
50
|
+
thread_id TEXT NOT NULL,
|
|
51
|
+
user_id TEXT NOT NULL DEFAULT '',
|
|
52
|
+
body TEXT NOT NULL,
|
|
53
|
+
interval_minutes INTEGER NOT NULL,
|
|
54
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
55
|
+
last_tick_at TEXT,
|
|
56
|
+
last_status TEXT NOT NULL DEFAULT 'pending',
|
|
57
|
+
last_reason TEXT NOT NULL DEFAULT '',
|
|
58
|
+
last_text_preview TEXT NOT NULL DEFAULT '',
|
|
59
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
60
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
61
|
+
UNIQUE (platform, channel_id, thread_id)
|
|
62
|
+
);
|
|
63
|
+
CREATE INDEX IF NOT EXISTS idx_heartbeats_tick ON heartbeats(enabled, last_tick_at);
|
|
64
|
+
CREATE INDEX IF NOT EXISTS idx_heartbeats_owner ON heartbeats(platform, user_id);
|
|
65
|
+
`,
|
|
66
|
+
});
|
|
67
|
+
function getDb() {
|
|
68
|
+
return helper.get();
|
|
69
|
+
}
|
|
70
|
+
function rowFromRaw(r) {
|
|
71
|
+
return {
|
|
72
|
+
id: r.id,
|
|
73
|
+
platform: r.platform,
|
|
74
|
+
channelId: r.channel_id,
|
|
75
|
+
threadId: r.thread_id,
|
|
76
|
+
userId: r.user_id,
|
|
77
|
+
body: r.body,
|
|
78
|
+
intervalMinutes: r.interval_minutes,
|
|
79
|
+
enabled: r.enabled !== 0,
|
|
80
|
+
lastTickAt: r.last_tick_at,
|
|
81
|
+
lastStatus: (r.last_status || 'pending'),
|
|
82
|
+
lastReason: r.last_reason || '',
|
|
83
|
+
lastTextPreview: r.last_text_preview || '',
|
|
84
|
+
createdAt: r.created_at,
|
|
85
|
+
updatedAt: r.updated_at,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/** Read the operator-provided default interval (env override or constant). */
|
|
89
|
+
export function defaultIntervalMinutes() {
|
|
90
|
+
const raw = process.env.IMHUB_HEARTBEAT_DEFAULT_INTERVAL_MIN;
|
|
91
|
+
if (raw) {
|
|
92
|
+
const n = parseInt(raw, 10);
|
|
93
|
+
if (Number.isFinite(n) && n >= MIN_INTERVAL_MIN && n <= MAX_INTERVAL_MIN) {
|
|
94
|
+
return n;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return DEFAULT_INTERVAL_MIN;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Create or replace the heartbeat for a thread. UPSERT semantics — one
|
|
101
|
+
* binding per thread, calling bind() again overwrites the body and
|
|
102
|
+
* resets last_tick_at so the new body takes effect on the next tick
|
|
103
|
+
* (not 30 min later).
|
|
104
|
+
*/
|
|
105
|
+
export function upsertBinding(input) {
|
|
106
|
+
const d = getDb();
|
|
107
|
+
if (!d)
|
|
108
|
+
return null;
|
|
109
|
+
const body = input.body.slice(0, MAX_BODY_CHARS);
|
|
110
|
+
const interval = clampInterval(input.intervalMinutes ?? defaultIntervalMinutes());
|
|
111
|
+
try {
|
|
112
|
+
// ON CONFLICT preserves the auto-increment id and timestamps while
|
|
113
|
+
// refreshing the user-visible fields. We deliberately RESET
|
|
114
|
+
// last_tick_at to NULL on rebind so the new body runs at the next
|
|
115
|
+
// scheduler tick — otherwise the user's "/heartbeat bind X" sits
|
|
116
|
+
// dormant for up to `intervalMinutes` minutes.
|
|
117
|
+
d.prepare(`
|
|
118
|
+
INSERT INTO heartbeats
|
|
119
|
+
(platform, channel_id, thread_id, user_id, body, interval_minutes,
|
|
120
|
+
enabled, last_tick_at, last_status, last_reason, last_text_preview,
|
|
121
|
+
updated_at)
|
|
122
|
+
VALUES (?, ?, ?, ?, ?, ?, 1, NULL, 'pending', '', '', datetime('now'))
|
|
123
|
+
ON CONFLICT (platform, channel_id, thread_id) DO UPDATE SET
|
|
124
|
+
user_id = excluded.user_id,
|
|
125
|
+
body = excluded.body,
|
|
126
|
+
interval_minutes = excluded.interval_minutes,
|
|
127
|
+
enabled = 1,
|
|
128
|
+
last_tick_at = NULL,
|
|
129
|
+
last_status = 'pending',
|
|
130
|
+
last_reason = '',
|
|
131
|
+
updated_at = datetime('now')
|
|
132
|
+
`).run(input.platform, input.channelId, input.threadId, input.userId, body, interval);
|
|
133
|
+
return getBinding(input.platform, input.channelId, input.threadId);
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
rootLogger.warn({ event: 'heartbeat-store.upsert_failed', err: String(err) });
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/** Disable (don't delete) a binding for the given thread. */
|
|
141
|
+
export function disableBinding(platform, channelId, threadId) {
|
|
142
|
+
const d = getDb();
|
|
143
|
+
if (!d)
|
|
144
|
+
return false;
|
|
145
|
+
try {
|
|
146
|
+
const info = d.prepare(`
|
|
147
|
+
UPDATE heartbeats SET enabled = 0, updated_at = datetime('now')
|
|
148
|
+
WHERE platform = ? AND channel_id = ? AND thread_id = ?
|
|
149
|
+
`).run(platform, channelId, threadId);
|
|
150
|
+
return info.changes > 0;
|
|
151
|
+
}
|
|
152
|
+
catch (err) {
|
|
153
|
+
rootLogger.warn({ event: 'heartbeat-store.disable_failed', err: String(err) });
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/** Soft-enable an existing binding (no-op if missing). */
|
|
158
|
+
export function enableBinding(platform, channelId, threadId) {
|
|
159
|
+
const d = getDb();
|
|
160
|
+
if (!d)
|
|
161
|
+
return false;
|
|
162
|
+
try {
|
|
163
|
+
const info = d.prepare(`
|
|
164
|
+
UPDATE heartbeats SET enabled = 1, updated_at = datetime('now')
|
|
165
|
+
WHERE platform = ? AND channel_id = ? AND thread_id = ?
|
|
166
|
+
`).run(platform, channelId, threadId);
|
|
167
|
+
return info.changes > 0;
|
|
168
|
+
}
|
|
169
|
+
catch (err) {
|
|
170
|
+
rootLogger.warn({ event: 'heartbeat-store.enable_failed', err: String(err) });
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/** Replace the interval for an existing binding (no-op if missing). */
|
|
175
|
+
export function updateInterval(platform, channelId, threadId, intervalMinutes) {
|
|
176
|
+
const d = getDb();
|
|
177
|
+
if (!d)
|
|
178
|
+
return false;
|
|
179
|
+
const interval = clampInterval(intervalMinutes);
|
|
180
|
+
try {
|
|
181
|
+
const info = d.prepare(`
|
|
182
|
+
UPDATE heartbeats
|
|
183
|
+
SET interval_minutes = ?, updated_at = datetime('now')
|
|
184
|
+
WHERE platform = ? AND channel_id = ? AND thread_id = ?
|
|
185
|
+
`).run(interval, platform, channelId, threadId);
|
|
186
|
+
return info.changes > 0;
|
|
187
|
+
}
|
|
188
|
+
catch (err) {
|
|
189
|
+
rootLogger.warn({ event: 'heartbeat-store.update_interval_failed', err: String(err) });
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/** Stamp the outcome of a tick. Caller is the scheduler / runForBinding. */
|
|
194
|
+
export function recordTick(input) {
|
|
195
|
+
const d = getDb();
|
|
196
|
+
if (!d)
|
|
197
|
+
return;
|
|
198
|
+
try {
|
|
199
|
+
if (input.status === 'delivered') {
|
|
200
|
+
const preview = (input.deliveredText ?? '').slice(0, MAX_PREVIEW_CHARS);
|
|
201
|
+
d.prepare(`
|
|
202
|
+
UPDATE heartbeats SET
|
|
203
|
+
last_tick_at = datetime('now'),
|
|
204
|
+
last_status = ?,
|
|
205
|
+
last_reason = ?,
|
|
206
|
+
last_text_preview = ?,
|
|
207
|
+
updated_at = datetime('now')
|
|
208
|
+
WHERE id = ?
|
|
209
|
+
`).run(input.status, input.reason.slice(0, 240), preview, input.id);
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
d.prepare(`
|
|
213
|
+
UPDATE heartbeats SET
|
|
214
|
+
last_tick_at = datetime('now'),
|
|
215
|
+
last_status = ?,
|
|
216
|
+
last_reason = ?,
|
|
217
|
+
updated_at = datetime('now')
|
|
218
|
+
WHERE id = ?
|
|
219
|
+
`).run(input.status, input.reason.slice(0, 240), input.id);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
catch (err) {
|
|
223
|
+
rootLogger.warn({ event: 'heartbeat-store.record_tick_failed', err: String(err) });
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
export function getBinding(platform, channelId, threadId) {
|
|
227
|
+
const d = getDb();
|
|
228
|
+
if (!d)
|
|
229
|
+
return null;
|
|
230
|
+
try {
|
|
231
|
+
const row = d.prepare(`
|
|
232
|
+
SELECT * FROM heartbeats
|
|
233
|
+
WHERE platform = ? AND channel_id = ? AND thread_id = ?
|
|
234
|
+
`).get(platform, channelId, threadId);
|
|
235
|
+
return row ? rowFromRaw(row) : null;
|
|
236
|
+
}
|
|
237
|
+
catch (err) {
|
|
238
|
+
rootLogger.warn({ event: 'heartbeat-store.get_failed', err: String(err) });
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
/** All bindings, regardless of enabled state. Admin-facing /heartbeat list. */
|
|
243
|
+
export function listAllBindings() {
|
|
244
|
+
const d = getDb();
|
|
245
|
+
if (!d)
|
|
246
|
+
return [];
|
|
247
|
+
try {
|
|
248
|
+
const rows = d.prepare(`SELECT * FROM heartbeats ORDER BY id ASC`).all();
|
|
249
|
+
return rows.map(rowFromRaw);
|
|
250
|
+
}
|
|
251
|
+
catch (err) {
|
|
252
|
+
rootLogger.warn({ event: 'heartbeat-store.list_failed', err: String(err) });
|
|
253
|
+
return [];
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* All enabled bindings whose next tick is due. "Due" = `last_tick_at IS
|
|
258
|
+
* NULL` OR `datetime(last_tick_at) <= datetime('now', '-N minutes')`.
|
|
259
|
+
*
|
|
260
|
+
* Each row carries its own interval, so we can't precompute a single
|
|
261
|
+
* cutoff — the SQL filter checks per-row using interval_minutes.
|
|
262
|
+
*/
|
|
263
|
+
export function listDueBindings() {
|
|
264
|
+
const d = getDb();
|
|
265
|
+
if (!d)
|
|
266
|
+
return [];
|
|
267
|
+
try {
|
|
268
|
+
const rows = d.prepare(`
|
|
269
|
+
SELECT * FROM heartbeats
|
|
270
|
+
WHERE enabled = 1
|
|
271
|
+
AND (
|
|
272
|
+
last_tick_at IS NULL
|
|
273
|
+
OR datetime(last_tick_at, '+' || interval_minutes || ' minutes') <= datetime('now')
|
|
274
|
+
)
|
|
275
|
+
ORDER BY (last_tick_at IS NULL) DESC, last_tick_at ASC
|
|
276
|
+
LIMIT 50
|
|
277
|
+
`).all();
|
|
278
|
+
return rows.map(rowFromRaw);
|
|
279
|
+
}
|
|
280
|
+
catch (err) {
|
|
281
|
+
rootLogger.warn({ event: 'heartbeat-store.list_due_failed', err: String(err) });
|
|
282
|
+
return [];
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
/** Strictly for tests: drop the table contents. NEVER call from runtime
|
|
286
|
+
* paths — the alternative is `disableBinding` per row. */
|
|
287
|
+
export function _truncateForTests() {
|
|
288
|
+
const d = getDb();
|
|
289
|
+
if (!d)
|
|
290
|
+
return;
|
|
291
|
+
d.exec('DELETE FROM heartbeats');
|
|
292
|
+
}
|
|
293
|
+
function clampInterval(n) {
|
|
294
|
+
if (!Number.isFinite(n))
|
|
295
|
+
return DEFAULT_INTERVAL_MIN;
|
|
296
|
+
if (n < MIN_INTERVAL_MIN)
|
|
297
|
+
return MIN_INTERVAL_MIN;
|
|
298
|
+
if (n > MAX_INTERVAL_MIN)
|
|
299
|
+
return MAX_INTERVAL_MIN;
|
|
300
|
+
return Math.floor(n);
|
|
301
|
+
}
|
|
302
|
+
//# sourceMappingURL=heartbeat-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heartbeat-store.js","sourceRoot":"","sources":["../../src/core/heartbeat-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type HeartbeatRow } from './heartbeat-store.js';
|
|
2
|
+
export interface RunResult {
|
|
3
|
+
status: 'skipped' | 'delivered' | 'suppressed' | 'no-agent' | 'failed';
|
|
4
|
+
reason: string;
|
|
5
|
+
/** Populated only when status='delivered'. */
|
|
6
|
+
deliveredText?: string;
|
|
7
|
+
/** Populated when status='delivered' or 'suppressed' so /heartbeat
|
|
8
|
+
* run-now can print "the gate / sink got this much". */
|
|
9
|
+
rawAgentOutput?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Single binding tick. ALL exceptions caught + logged + stamped onto
|
|
13
|
+
* the row; never throws. Returns the result so the slash command's
|
|
14
|
+
* `/heartbeat run-now` can show it back to the user synchronously.
|
|
15
|
+
*/
|
|
16
|
+
export declare function runForBinding(row: HeartbeatRow): Promise<RunResult>;
|
|
17
|
+
/**
|
|
18
|
+
* One scheduler pass. Picks up to 50 due bindings and runs them
|
|
19
|
+
* sequentially; concurrent ticks on the same scheduler are intentional
|
|
20
|
+
* (avoids stampedes on the user's agent, keeps memory bounded). Returns
|
|
21
|
+
* a summary so tests can assert on it.
|
|
22
|
+
*/
|
|
23
|
+
export declare function tickOnce(): Promise<{
|
|
24
|
+
scanned: number;
|
|
25
|
+
results: Record<string, number>;
|
|
26
|
+
}>;
|
|
27
|
+
export declare function startHeartbeatScheduler(): void;
|
|
28
|
+
export declare function stopHeartbeatScheduler(): void;
|
|
29
|
+
/** Reflect current scheduler state for /heartbeat status output. */
|
|
30
|
+
export declare function schedulerInfo(): {
|
|
31
|
+
enabled: boolean;
|
|
32
|
+
running: boolean;
|
|
33
|
+
periodMs: number;
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=heartbeat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heartbeat.d.ts","sourceRoot":"","sources":["../../src/core/heartbeat.ts"],"names":[],"mappings":"AAmCA,OAAO,EAEL,KAAK,YAAY,EAClB,MAAM,sBAAsB,CAAA;AAmK7B,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,YAAY,GAAG,UAAU,GAAG,QAAQ,CAAA;IACtE,MAAM,EAAE,MAAM,CAAA;IACd,8CAA8C;IAC9C,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;6DACyD;IACzD,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC,CAsFzE;AAED;;;;;GAKG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAAC,CAmB9F;AAQD,wBAAgB,uBAAuB,IAAI,IAAI,CAiB9C;AAED,wBAAgB,sBAAsB,IAAI,IAAI,CAK7C;AAED,oEAAoE;AACpE,wBAAgB,aAAa,IAAI;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAMxF"}
|