@aitne/daemon 0.1.3 → 0.1.6
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/dist/adapters/notification-manager.d.ts +12 -0
- package/dist/adapters/notification-manager.d.ts.map +1 -1
- package/dist/adapters/notification-manager.js +39 -1
- package/dist/adapters/notification-manager.js.map +1 -1
- package/dist/adapters/whatsapp-adapter.d.ts.map +1 -1
- package/dist/adapters/whatsapp-adapter.js +0 -1
- package/dist/adapters/whatsapp-adapter.js.map +1 -1
- package/dist/api/integration-route-gate.d.ts +15 -11
- package/dist/api/integration-route-gate.d.ts.map +1 -1
- package/dist/api/integration-route-gate.js +60 -23
- package/dist/api/integration-route-gate.js.map +1 -1
- package/dist/api/json-body.d.ts +22 -7
- package/dist/api/json-body.d.ts.map +1 -1
- package/dist/api/json-body.js +27 -8
- package/dist/api/json-body.js.map +1 -1
- package/dist/api/routes/agent.d.ts.map +1 -1
- package/dist/api/routes/agent.js +25 -0
- package/dist/api/routes/agent.js.map +1 -1
- package/dist/api/routes/backends.d.ts.map +1 -1
- package/dist/api/routes/backends.js +96 -1
- package/dist/api/routes/backends.js.map +1 -1
- package/dist/api/routes/books.js +1 -1
- package/dist/api/routes/books.js.map +1 -1
- package/dist/api/routes/commands.d.ts.map +1 -1
- package/dist/api/routes/commands.js +16 -13
- package/dist/api/routes/commands.js.map +1 -1
- package/dist/api/routes/context.d.ts.map +1 -1
- package/dist/api/routes/context.js +26 -3
- package/dist/api/routes/context.js.map +1 -1
- package/dist/api/routes/dashboard.d.ts.map +1 -1
- package/dist/api/routes/dashboard.js +103 -5
- package/dist/api/routes/dashboard.js.map +1 -1
- package/dist/api/routes/fs.d.ts +23 -0
- package/dist/api/routes/fs.d.ts.map +1 -0
- package/dist/api/routes/fs.js +156 -0
- package/dist/api/routes/fs.js.map +1 -0
- package/dist/api/routes/fs.logic.d.ts +62 -0
- package/dist/api/routes/fs.logic.d.ts.map +1 -0
- package/dist/api/routes/fs.logic.js +137 -0
- package/dist/api/routes/fs.logic.js.map +1 -0
- package/dist/api/routes/github.d.ts.map +1 -1
- package/dist/api/routes/github.js +38 -5
- package/dist/api/routes/github.js.map +1 -1
- package/dist/api/routes/health.d.ts.map +1 -1
- package/dist/api/routes/health.js +4 -2
- package/dist/api/routes/health.js.map +1 -1
- package/dist/api/routes/integrations.d.ts +35 -6
- package/dist/api/routes/integrations.d.ts.map +1 -1
- package/dist/api/routes/integrations.js +192 -15
- package/dist/api/routes/integrations.js.map +1 -1
- package/dist/api/routes/mail.d.ts.map +1 -1
- package/dist/api/routes/mail.js +112 -46
- package/dist/api/routes/mail.js.map +1 -1
- package/dist/api/routes/metrics.d.ts +1 -0
- package/dist/api/routes/metrics.d.ts.map +1 -1
- package/dist/api/routes/metrics.js +24 -0
- package/dist/api/routes/metrics.js.map +1 -1
- package/dist/api/routes/observations.d.ts.map +1 -1
- package/dist/api/routes/observations.js +696 -30
- package/dist/api/routes/observations.js.map +1 -1
- package/dist/api/routes/setup-migrate.d.ts +9 -1
- package/dist/api/routes/setup-migrate.d.ts.map +1 -1
- package/dist/api/routes/setup-migrate.js +4 -2
- package/dist/api/routes/setup-migrate.js.map +1 -1
- package/dist/api/routes/skills.d.ts +9 -1
- package/dist/api/routes/skills.d.ts.map +1 -1
- package/dist/api/routes/skills.js +77 -17
- package/dist/api/routes/skills.js.map +1 -1
- package/dist/api/routes/voice.d.ts.map +1 -1
- package/dist/api/routes/voice.js +62 -4
- package/dist/api/routes/voice.js.map +1 -1
- package/dist/api/routes/wiki.d.ts +4 -0
- package/dist/api/routes/wiki.d.ts.map +1 -0
- package/dist/api/routes/wiki.js +1075 -0
- package/dist/api/routes/wiki.js.map +1 -0
- package/dist/api/server.d.ts +13 -0
- package/dist/api/server.d.ts.map +1 -1
- package/dist/api/server.js +27 -1
- package/dist/api/server.js.map +1 -1
- package/dist/bootstrap/adapters.d.ts +109 -0
- package/dist/bootstrap/adapters.d.ts.map +1 -0
- package/dist/bootstrap/adapters.js +237 -0
- package/dist/bootstrap/adapters.js.map +1 -0
- package/dist/bootstrap/catchup.d.ts +23 -0
- package/dist/bootstrap/catchup.d.ts.map +1 -0
- package/dist/bootstrap/catchup.js +124 -0
- package/dist/bootstrap/catchup.js.map +1 -0
- package/dist/bootstrap/schedule-helpers.d.ts +18 -0
- package/dist/bootstrap/schedule-helpers.d.ts.map +1 -0
- package/dist/bootstrap/schedule-helpers.js +96 -0
- package/dist/bootstrap/schedule-helpers.js.map +1 -0
- package/dist/bootstrap/services.d.ts +60 -0
- package/dist/bootstrap/services.d.ts.map +1 -0
- package/dist/bootstrap/services.js +209 -0
- package/dist/bootstrap/services.js.map +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +26 -0
- package/dist/config.js.map +1 -1
- package/dist/core/agent-core.d.ts +25 -0
- package/dist/core/agent-core.d.ts.map +1 -1
- package/dist/core/agent-core.js.map +1 -1
- package/dist/core/backends/backend-router.d.ts +28 -1
- package/dist/core/backends/backend-router.d.ts.map +1 -1
- package/dist/core/backends/backend-router.js +58 -4
- package/dist/core/backends/backend-router.js.map +1 -1
- package/dist/core/backends/claude-auth.d.ts +70 -0
- package/dist/core/backends/claude-auth.d.ts.map +1 -0
- package/dist/core/backends/claude-auth.js +198 -0
- package/dist/core/backends/claude-auth.js.map +1 -0
- package/dist/core/backends/claude-code-core.d.ts +47 -119
- package/dist/core/backends/claude-code-core.d.ts.map +1 -1
- package/dist/core/backends/claude-code-core.js +166 -1561
- package/dist/core/backends/claude-code-core.js.map +1 -1
- package/dist/core/backends/claude-delegated.d.ts +86 -0
- package/dist/core/backends/claude-delegated.d.ts.map +1 -0
- package/dist/core/backends/claude-delegated.js +801 -0
- package/dist/core/backends/claude-delegated.js.map +1 -0
- package/dist/core/backends/claude-errors.d.ts +39 -0
- package/dist/core/backends/claude-errors.d.ts.map +1 -0
- package/dist/core/backends/claude-errors.js +71 -0
- package/dist/core/backends/claude-errors.js.map +1 -0
- package/dist/core/backends/claude-probe.d.ts +103 -0
- package/dist/core/backends/claude-probe.d.ts.map +1 -0
- package/dist/core/backends/claude-probe.js +336 -0
- package/dist/core/backends/claude-probe.js.map +1 -0
- package/dist/core/backends/claude-tool-collection.d.ts +135 -0
- package/dist/core/backends/claude-tool-collection.d.ts.map +1 -0
- package/dist/core/backends/claude-tool-collection.js +1093 -0
- package/dist/core/backends/claude-tool-collection.js.map +1 -0
- package/dist/core/backends/codex-core.d.ts.map +1 -1
- package/dist/core/backends/codex-core.js +36 -0
- package/dist/core/backends/codex-core.js.map +1 -1
- package/dist/core/backends/gemini-cli-core.d.ts +45 -5
- package/dist/core/backends/gemini-cli-core.d.ts.map +1 -1
- package/dist/core/backends/gemini-cli-core.js +146 -36
- package/dist/core/backends/gemini-cli-core.js.map +1 -1
- package/dist/core/backends/plan-presets.d.ts +3 -1
- package/dist/core/backends/plan-presets.d.ts.map +1 -1
- package/dist/core/backends/plan-presets.js +42 -2
- package/dist/core/backends/plan-presets.js.map +1 -1
- package/dist/core/backends/prompt-utils.d.ts +1 -0
- package/dist/core/backends/prompt-utils.d.ts.map +1 -1
- package/dist/core/backends/prompt-utils.js +60 -3
- package/dist/core/backends/prompt-utils.js.map +1 -1
- package/dist/core/bang-commands/commands-help.d.ts +5 -0
- package/dist/core/bang-commands/commands-help.d.ts.map +1 -0
- package/dist/core/bang-commands/commands-help.js +69 -0
- package/dist/core/bang-commands/commands-help.js.map +1 -0
- package/dist/core/bang-commands/commands-wiki.d.ts +75 -0
- package/dist/core/bang-commands/commands-wiki.d.ts.map +1 -0
- package/dist/core/bang-commands/commands-wiki.js +574 -0
- package/dist/core/bang-commands/commands-wiki.js.map +1 -0
- package/dist/core/bang-commands/index.d.ts +4 -2
- package/dist/core/bang-commands/index.d.ts.map +1 -1
- package/dist/core/bang-commands/index.js +15 -1
- package/dist/core/bang-commands/index.js.map +1 -1
- package/dist/core/bang-commands/registry.d.ts +47 -4
- package/dist/core/bang-commands/registry.d.ts.map +1 -1
- package/dist/core/bang-commands/registry.js +85 -15
- package/dist/core/bang-commands/registry.js.map +1 -1
- package/dist/core/context-builder.d.ts +53 -12
- package/dist/core/context-builder.d.ts.map +1 -1
- package/dist/core/context-builder.js +240 -92
- package/dist/core/context-builder.js.map +1 -1
- package/dist/core/daemon-api-cli.d.ts.map +1 -1
- package/dist/core/daemon-api-cli.js +50 -2
- package/dist/core/daemon-api-cli.js.map +1 -1
- package/dist/core/dispatcher-date-utils.d.ts +49 -0
- package/dist/core/dispatcher-date-utils.d.ts.map +1 -0
- package/dist/core/dispatcher-date-utils.js +132 -0
- package/dist/core/dispatcher-date-utils.js.map +1 -0
- package/dist/core/dispatcher-error-handling.d.ts +159 -0
- package/dist/core/dispatcher-error-handling.d.ts.map +1 -0
- package/dist/core/dispatcher-error-handling.js +393 -0
- package/dist/core/dispatcher-error-handling.js.map +1 -0
- package/dist/core/dispatcher-hourly-check.d.ts +150 -0
- package/dist/core/dispatcher-hourly-check.d.ts.map +1 -0
- package/dist/core/dispatcher-hourly-check.js +665 -0
- package/dist/core/dispatcher-hourly-check.js.map +1 -0
- package/dist/core/dispatcher-message-handler.d.ts +170 -0
- package/dist/core/dispatcher-message-handler.d.ts.map +1 -0
- package/dist/core/dispatcher-message-handler.js +1064 -0
- package/dist/core/dispatcher-message-handler.js.map +1 -0
- package/dist/core/dispatcher-morning-routine.d.ts +169 -0
- package/dist/core/dispatcher-morning-routine.d.ts.map +1 -0
- package/dist/core/dispatcher-morning-routine.js +449 -0
- package/dist/core/dispatcher-morning-routine.js.map +1 -0
- package/dist/core/dispatcher-prompt.d.ts +107 -0
- package/dist/core/dispatcher-prompt.d.ts.map +1 -0
- package/dist/core/dispatcher-prompt.js +227 -0
- package/dist/core/dispatcher-prompt.js.map +1 -0
- package/dist/core/dispatcher-repository-helpers.d.ts +39 -0
- package/dist/core/dispatcher-repository-helpers.d.ts.map +1 -0
- package/dist/core/dispatcher-repository-helpers.js +86 -0
- package/dist/core/dispatcher-repository-helpers.js.map +1 -0
- package/dist/core/dispatcher-result-processor.d.ts +168 -0
- package/dist/core/dispatcher-result-processor.d.ts.map +1 -0
- package/dist/core/dispatcher-result-processor.js +533 -0
- package/dist/core/dispatcher-result-processor.js.map +1 -0
- package/dist/core/dispatcher-scheduled-tasks.d.ts +406 -0
- package/dist/core/dispatcher-scheduled-tasks.d.ts.map +1 -0
- package/dist/core/dispatcher-scheduled-tasks.js +1032 -0
- package/dist/core/dispatcher-scheduled-tasks.js.map +1 -0
- package/dist/core/dispatcher-types.d.ts +411 -0
- package/dist/core/dispatcher-types.d.ts.map +1 -0
- package/dist/core/dispatcher-types.js +106 -0
- package/dist/core/dispatcher-types.js.map +1 -0
- package/dist/core/dispatcher.d.ts +122 -610
- package/dist/core/dispatcher.d.ts.map +1 -1
- package/dist/core/dispatcher.js +365 -3521
- package/dist/core/dispatcher.js.map +1 -1
- package/dist/core/integration-health.d.ts +18 -10
- package/dist/core/integration-health.d.ts.map +1 -1
- package/dist/core/integration-health.js +31 -1
- package/dist/core/integration-health.js.map +1 -1
- package/dist/core/integration-lifecycle.d.ts +65 -0
- package/dist/core/integration-lifecycle.d.ts.map +1 -1
- package/dist/core/integration-lifecycle.js +163 -14
- package/dist/core/integration-lifecycle.js.map +1 -1
- package/dist/core/integration-main-backend.d.ts +40 -0
- package/dist/core/integration-main-backend.d.ts.map +1 -1
- package/dist/core/integration-main-backend.js +89 -2
- package/dist/core/integration-main-backend.js.map +1 -1
- package/dist/core/management-md.d.ts +51 -17
- package/dist/core/management-md.d.ts.map +1 -1
- package/dist/core/management-md.js +233 -56
- package/dist/core/management-md.js.map +1 -1
- package/dist/core/metrics.d.ts +127 -0
- package/dist/core/metrics.d.ts.map +1 -1
- package/dist/core/metrics.js +256 -1
- package/dist/core/metrics.js.map +1 -1
- package/dist/core/output-language-policy.d.ts +74 -0
- package/dist/core/output-language-policy.d.ts.map +1 -0
- package/dist/core/output-language-policy.js +194 -0
- package/dist/core/output-language-policy.js.map +1 -0
- package/dist/core/prompts.d.ts +3 -1
- package/dist/core/prompts.d.ts.map +1 -1
- package/dist/core/prompts.js +161 -3
- package/dist/core/prompts.js.map +1 -1
- package/dist/core/repository-management-docs.d.ts +24 -0
- package/dist/core/repository-management-docs.d.ts.map +1 -1
- package/dist/core/repository-management-docs.js +210 -26
- package/dist/core/repository-management-docs.js.map +1 -1
- package/dist/core/roadmap-validate.js +13 -1
- package/dist/core/roadmap-validate.js.map +1 -1
- package/dist/core/routine-acquisition-plan.d.ts +182 -0
- package/dist/core/routine-acquisition-plan.d.ts.map +1 -0
- package/dist/core/routine-acquisition-plan.js +367 -0
- package/dist/core/routine-acquisition-plan.js.map +1 -0
- package/dist/core/routine-fetch-window-retry.d.ts +109 -0
- package/dist/core/routine-fetch-window-retry.d.ts.map +1 -0
- package/dist/core/routine-fetch-window-retry.js +210 -0
- package/dist/core/routine-fetch-window-retry.js.map +1 -0
- package/dist/core/routine-fetch-window-runner.d.ts +427 -0
- package/dist/core/routine-fetch-window-runner.d.ts.map +1 -0
- package/dist/core/routine-fetch-window-runner.js +1591 -0
- package/dist/core/routine-fetch-window-runner.js.map +1 -0
- package/dist/core/routine-windows.d.ts +171 -0
- package/dist/core/routine-windows.d.ts.map +1 -0
- package/dist/core/routine-windows.js +377 -0
- package/dist/core/routine-windows.js.map +1 -0
- package/dist/core/scheduler.d.ts +50 -2
- package/dist/core/scheduler.d.ts.map +1 -1
- package/dist/core/scheduler.js +88 -7
- package/dist/core/scheduler.js.map +1 -1
- package/dist/core/skill-curation/declarations.d.ts.map +1 -1
- package/dist/core/skill-curation/declarations.js +11 -12
- package/dist/core/skill-curation/declarations.js.map +1 -1
- package/dist/core/skill-source-paths.d.ts +14 -0
- package/dist/core/skill-source-paths.d.ts.map +1 -0
- package/dist/core/skill-source-paths.js +82 -0
- package/dist/core/skill-source-paths.js.map +1 -0
- package/dist/core/skills-compiler.d.ts +29 -0
- package/dist/core/skills-compiler.d.ts.map +1 -1
- package/dist/core/skills-compiler.js +166 -30
- package/dist/core/skills-compiler.js.map +1 -1
- package/dist/core/skills-manifest.d.ts.map +1 -1
- package/dist/core/skills-manifest.js +72 -0
- package/dist/core/skills-manifest.js.map +1 -1
- package/dist/core/system-reset.d.ts +25 -0
- package/dist/core/system-reset.d.ts.map +1 -1
- package/dist/core/system-reset.js +72 -2
- package/dist/core/system-reset.js.map +1 -1
- package/dist/core/wiki/approval-queue.d.ts +31 -0
- package/dist/core/wiki/approval-queue.d.ts.map +1 -0
- package/dist/core/wiki/approval-queue.js +44 -0
- package/dist/core/wiki/approval-queue.js.map +1 -0
- package/dist/core/wiki/bridge.d.ts +74 -0
- package/dist/core/wiki/bridge.d.ts.map +1 -0
- package/dist/core/wiki/bridge.js +405 -0
- package/dist/core/wiki/bridge.js.map +1 -0
- package/dist/core/wiki/compile-lock.d.ts +42 -0
- package/dist/core/wiki/compile-lock.d.ts.map +1 -0
- package/dist/core/wiki/compile-lock.js +55 -0
- package/dist/core/wiki/compile-lock.js.map +1 -0
- package/dist/core/wiki/compile-preview.d.ts +8 -0
- package/dist/core/wiki/compile-preview.d.ts.map +1 -0
- package/dist/core/wiki/compile-preview.js +200 -0
- package/dist/core/wiki/compile-preview.js.map +1 -0
- package/dist/core/wiki/cost-estimate.d.ts +30 -0
- package/dist/core/wiki/cost-estimate.d.ts.map +1 -0
- package/dist/core/wiki/cost-estimate.js +243 -0
- package/dist/core/wiki/cost-estimate.js.map +1 -0
- package/dist/core/wiki/dispatcher.d.ts +48 -0
- package/dist/core/wiki/dispatcher.d.ts.map +1 -0
- package/dist/core/wiki/dispatcher.js +92 -0
- package/dist/core/wiki/dispatcher.js.map +1 -0
- package/dist/core/wiki/git-precompile.d.ts +86 -0
- package/dist/core/wiki/git-precompile.d.ts.map +1 -0
- package/dist/core/wiki/git-precompile.js +96 -0
- package/dist/core/wiki/git-precompile.js.map +1 -0
- package/dist/core/wiki/import-migrate.d.ts +38 -0
- package/dist/core/wiki/import-migrate.d.ts.map +1 -0
- package/dist/core/wiki/import-migrate.js +310 -0
- package/dist/core/wiki/import-migrate.js.map +1 -0
- package/dist/core/wiki/import-probe.d.ts +76 -0
- package/dist/core/wiki/import-probe.d.ts.map +1 -0
- package/dist/core/wiki/import-probe.js +245 -0
- package/dist/core/wiki/import-probe.js.map +1 -0
- package/dist/core/wiki/index-cache.d.ts +39 -0
- package/dist/core/wiki/index-cache.d.ts.map +1 -0
- package/dist/core/wiki/index-cache.js +152 -0
- package/dist/core/wiki/index-cache.js.map +1 -0
- package/dist/core/wiki/multi-url-dispatch.d.ts +52 -0
- package/dist/core/wiki/multi-url-dispatch.d.ts.map +1 -0
- package/dist/core/wiki/multi-url-dispatch.js +72 -0
- package/dist/core/wiki/multi-url-dispatch.js.map +1 -0
- package/dist/core/wiki/wiki-fts.d.ts +75 -0
- package/dist/core/wiki/wiki-fts.d.ts.map +1 -0
- package/dist/core/wiki/wiki-fts.js +265 -0
- package/dist/core/wiki/wiki-fts.js.map +1 -0
- package/dist/core/wiki/workspaces.d.ts +101 -0
- package/dist/core/wiki/workspaces.d.ts.map +1 -0
- package/dist/core/wiki/workspaces.js +352 -0
- package/dist/core/wiki/workspaces.js.map +1 -0
- package/dist/core/wiki/write-strategy.d.ts +70 -0
- package/dist/core/wiki/write-strategy.d.ts.map +1 -0
- package/dist/core/wiki/write-strategy.js +112 -0
- package/dist/core/wiki/write-strategy.js.map +1 -0
- package/dist/core/workdir.d.ts +8 -1
- package/dist/core/workdir.d.ts.map +1 -1
- package/dist/core/workdir.js +4 -1
- package/dist/core/workdir.js.map +1 -1
- package/dist/db/observations.d.ts +45 -2
- package/dist/db/observations.d.ts.map +1 -1
- package/dist/db/observations.js +112 -14
- package/dist/db/observations.js.map +1 -1
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js +135 -25
- package/dist/db/schema.js.map +1 -1
- package/dist/db/wiki-store.d.ts +3 -0
- package/dist/db/wiki-store.d.ts.map +1 -0
- package/dist/db/wiki-store.js +7 -0
- package/dist/db/wiki-store.js.map +1 -0
- package/dist/index.js +159 -610
- package/dist/index.js.map +1 -1
- package/dist/messaging/url-extract.d.ts +8 -0
- package/dist/messaging/url-extract.d.ts.map +1 -0
- package/dist/messaging/url-extract.js +41 -0
- package/dist/messaging/url-extract.js.map +1 -0
- package/dist/observers/delegated-sync-worker.d.ts +52 -1
- package/dist/observers/delegated-sync-worker.d.ts.map +1 -1
- package/dist/observers/delegated-sync-worker.js +75 -18
- package/dist/observers/delegated-sync-worker.js.map +1 -1
- package/dist/observers/imminent-event-scheduler.d.ts +20 -7
- package/dist/observers/imminent-event-scheduler.d.ts.map +1 -1
- package/dist/observers/imminent-event-scheduler.js +134 -29
- package/dist/observers/imminent-event-scheduler.js.map +1 -1
- package/dist/observers/mail-poller.d.ts +12 -5
- package/dist/observers/mail-poller.d.ts.map +1 -1
- package/dist/observers/mail-poller.js +36 -14
- package/dist/observers/mail-poller.js.map +1 -1
- package/dist/observers/manager.d.ts +37 -5
- package/dist/observers/manager.d.ts.map +1 -1
- package/dist/observers/manager.js +28 -10
- package/dist/observers/manager.js.map +1 -1
- package/dist/safety/always-disallowed.d.ts +65 -0
- package/dist/safety/always-disallowed.d.ts.map +1 -1
- package/dist/safety/always-disallowed.js +106 -10
- package/dist/safety/always-disallowed.js.map +1 -1
- package/dist/safety/audit.d.ts +46 -1
- package/dist/safety/audit.d.ts.map +1 -1
- package/dist/safety/audit.js +79 -16
- package/dist/safety/audit.js.map +1 -1
- package/dist/safety/risk-classifier.d.ts.map +1 -1
- package/dist/safety/risk-classifier.js +29 -0
- package/dist/safety/risk-classifier.js.map +1 -1
- package/dist/services/delegated-backend-invoker.d.ts +1 -51
- package/dist/services/delegated-backend-invoker.d.ts.map +1 -1
- package/dist/services/delegated-backend-invoker.js +41 -480
- package/dist/services/delegated-backend-invoker.js.map +1 -1
- package/dist/services/delegated-invoker-audit.d.ts +94 -0
- package/dist/services/delegated-invoker-audit.d.ts.map +1 -0
- package/dist/services/delegated-invoker-audit.js +238 -0
- package/dist/services/delegated-invoker-audit.js.map +1 -0
- package/dist/services/delegated-invoker-cache-hits.d.ts +34 -0
- package/dist/services/delegated-invoker-cache-hits.d.ts.map +1 -0
- package/dist/services/delegated-invoker-cache-hits.js +104 -0
- package/dist/services/delegated-invoker-cache-hits.js.map +1 -0
- package/dist/services/delegated-invoker-janitors.d.ts +28 -0
- package/dist/services/delegated-invoker-janitors.d.ts.map +1 -0
- package/dist/services/delegated-invoker-janitors.js +104 -0
- package/dist/services/delegated-invoker-janitors.js.map +1 -0
- package/dist/services/delegated-invoker-utils.d.ts +42 -0
- package/dist/services/delegated-invoker-utils.d.ts.map +1 -0
- package/dist/services/delegated-invoker-utils.js +100 -0
- package/dist/services/delegated-invoker-utils.js.map +1 -0
- package/dist/services/delegated-task-runtime.d.ts +1 -1
- package/dist/services/delegated-task-runtime.js +1 -1
- package/dist/services/integrations/snapshot-partitions.d.ts +5 -0
- package/dist/services/integrations/snapshot-partitions.d.ts.map +1 -1
- package/dist/services/integrations/snapshot-partitions.js +12 -0
- package/dist/services/integrations/snapshot-partitions.js.map +1 -1
- package/dist/services/voice/transcriber-impl.d.ts.map +1 -1
- package/dist/services/voice/transcriber-impl.js +7 -8
- package/dist/services/voice/transcriber-impl.js.map +1 -1
- package/dist/settings/runtime-settings.d.ts +12 -1
- package/dist/settings/runtime-settings.d.ts.map +1 -1
- package/dist/settings/runtime-settings.js +59 -1
- package/dist/settings/runtime-settings.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { serve } from "@hono/node-server";
|
|
2
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
3
2
|
import { join, resolve } from "node:path";
|
|
3
|
+
import { rmSync } from "node:fs";
|
|
4
4
|
import { randomBytes } from "node:crypto";
|
|
5
5
|
import { loadConfig, getContextDir, isRoadmapStale, mergeRuntimeSettingsFromDb, runVaultHealthProbe, validateExternalObsidianVaultPath, } from "./config.js";
|
|
6
6
|
import { getDegradedMode, isSetupCompleted, isUserPaused, isDegraded as readDegradedMode, } from "./db/runtime-state.js";
|
|
@@ -37,20 +37,14 @@ import { DiscordAdapter } from "./adapters/discord.js";
|
|
|
37
37
|
import { SlackAdapter } from "./adapters/slack-adapter.js";
|
|
38
38
|
import { TelegramAdapter } from "./adapters/telegram-adapter.js";
|
|
39
39
|
import { DashboardAdapter } from "./adapters/dashboard-adapter.js";
|
|
40
|
-
import { WhatsAppAdapter } from "./adapters/whatsapp-adapter.js";
|
|
41
|
-
import { CalendarService } from "./services/calendar.js";
|
|
42
|
-
import { AppleCalendarService } from "./services/apple-calendar/index.js";
|
|
43
|
-
import { GmailService } from "./services/gmail.js";
|
|
44
|
-
import { detectGoogleCredentialType } from "./services/google-auth.js";
|
|
45
40
|
import { ObsidianService } from "./services/obsidian.js";
|
|
46
|
-
import { NotionService } from "./services/notion.js";
|
|
47
|
-
import { GitHubService } from "./services/github.js";
|
|
48
41
|
import { createServiceRegistry } from "./services/service-registry.js";
|
|
49
42
|
import { SignalDetector } from "./core/signal-detector.js";
|
|
50
43
|
import { EventDispatcher } from "./core/dispatcher.js";
|
|
51
44
|
import { ClaudeCodeCore } from "./core/backends/claude-code-core.js";
|
|
52
45
|
import { BackendRouter } from "./core/backends/backend-router.js";
|
|
53
46
|
import { ensureBackendMaterialized, syncAllUserSkills, buildConfiguredServices, refreshDmSessionWorkdirs, validateDelegatedStartup, } from "./core/workdir.js";
|
|
47
|
+
import { setWikiWorkspaceTokenResolver } from "./core/skills-compiler.js";
|
|
54
48
|
import { CodexCore } from "./core/backends/codex-core.js";
|
|
55
49
|
import { GeminiCliCore } from "./core/backends/gemini-cli-core.js";
|
|
56
50
|
import { PriceFetcher } from "./core/backends/price-fetcher.js";
|
|
@@ -59,6 +53,8 @@ import { AuthHealthMonitor, AUTH_PROBE_NOTIFICATION_CATEGORY } from "./core/back
|
|
|
59
53
|
import { AuthRecovery } from "./core/backends/auth-recovery.js";
|
|
60
54
|
import { ContextBuilder } from "./core/context-builder.js";
|
|
61
55
|
import { getTaskFlow, initTaskFlows } from "./core/prompts.js";
|
|
56
|
+
import { listWikiWorkspaces, readDefaultWikiWorkspace, readWikiWorkspaceByName, } from "./core/wiki/workspaces.js";
|
|
57
|
+
import { backfillWikiFulltext } from "./core/wiki/wiki-fts.js";
|
|
62
58
|
import { ensureSkeletonFiles, resolveTemplatesRoot } from "./core/skeleton.js";
|
|
63
59
|
import { normalizeGitWatchedRepos, queueGitProjectUpdate, queueMissingGitProjectInits, seedGitProjectDocTemplates, } from "./core/git-project-docs.js";
|
|
64
60
|
import { reconcileTemplateAssets, recordInstructionAssetStatus, recordSkillAssetStatus, } from "./core/release-assets.js";
|
|
@@ -69,7 +65,7 @@ import { NotificationManager } from "./adapters/notification-manager.js";
|
|
|
69
65
|
import { recordProactiveForwardDeliveries } from "./core/channel-timeline.js";
|
|
70
66
|
import { continueDashboardSession as continueDashboardSessionFromHistory, endDashboardSession as endDashboardSessionFromChannel, markContextChanged, } from "./core/dashboard-session-controls.js";
|
|
71
67
|
import { AuditLogger } from "./safety/audit.js";
|
|
72
|
-
import { bootstrapManagementMd,
|
|
68
|
+
import { bootstrapManagementMd, startManagementMdWatcher, } from "./core/management-md.js";
|
|
73
69
|
import { bootstrapManagementRegistry, startManagementRegistryWatcher, } from "./core/management-registry.js";
|
|
74
70
|
import { bootstrapManagedTaskSeq } from "./db/managed-tasks-store.js";
|
|
75
71
|
import { startDocsIndexer, } from "./core/docs/indexer.js";
|
|
@@ -79,11 +75,10 @@ import { DocsQAAdapter } from "./adapters/docs-qa-adapter.js";
|
|
|
79
75
|
import { CompositeDashboardStream } from "./adapters/composite-dashboard-stream.js";
|
|
80
76
|
import { createApp } from "./api/server.js";
|
|
81
77
|
import { EventBroadcaster } from "./api/routes/sse.js";
|
|
82
|
-
import { APP_NAME,
|
|
78
|
+
import { APP_NAME, EventPriority, getBackendIds, } from "@aitne/shared";
|
|
83
79
|
import { getOwnerChannel } from "./messaging/owner-channels.js";
|
|
84
80
|
import { SUPPORTED_MESSAGING_PLATFORMS, } from "./messaging/constants.js";
|
|
85
81
|
import { AgentWriteTracker } from "./safety/agent-write-tracker.js";
|
|
86
|
-
import { discardStalePendingSchedules, hasActionInWindow, recoverOrphanedRunningSchedules, } from "./core/schedule-maintenance.js";
|
|
87
82
|
import { ContextWriteGate, InMemoryTodayWriteLockManager, MigrationLock, getTodayWriteLockTimeoutMs, } from "./core/today-write-lock.js";
|
|
88
83
|
import { applyPromptContextStaleness, } from "./core/context-staleness.js";
|
|
89
84
|
import { InMemoryRoadmapWriteLockManager, getRoadmapWriteLockTimeoutMs, } from "./core/roadmap-write-lock.js";
|
|
@@ -103,13 +98,15 @@ import { parseImapAccountSecret } from "./services/mail/imap/app-password.js";
|
|
|
103
98
|
import { ICloudImapProvider } from "./services/mail/imap/icloud-provider.js";
|
|
104
99
|
import { YahooImapProvider } from "./services/mail/imap/yahoo-provider.js";
|
|
105
100
|
import { GmailProvider } from "./services/mail/gmail/gmail-provider.js";
|
|
106
|
-
import { ensureLegacyGmailRow } from "./services/mail/gmail/legacy-row.js";
|
|
107
|
-
import { syncLegacyGmailAccountState } from "./services/mail/gmail/legacy-row.js";
|
|
108
101
|
import { MailPoller } from "./observers/mail-poller.js";
|
|
109
102
|
import { MailReconciliationJob } from "./observers/mail-reconciliation.js";
|
|
110
103
|
import { SecretBroker } from "./secrets/secret-broker.js";
|
|
111
104
|
import { captureOriginalShellEnv, syncBackendApiKeyToEnv, } from "./secrets/backend-api-key-env.js";
|
|
112
105
|
import { createLogger, toSafeErrorMessage } from "./logging.js";
|
|
106
|
+
import { runCatchup, runPostMessagingCatchup, } from "./bootstrap/catchup.js";
|
|
107
|
+
import { hasFreshAgentDayTodayMd, readSkillCurationCadence, } from "./bootstrap/schedule-helpers.js";
|
|
108
|
+
import { createAdapterReloaders, whatsappQrResponseFromAdapter, } from "./bootstrap/adapters.js";
|
|
109
|
+
import { createInitialSecretState, createServiceReloaders, } from "./bootstrap/services.js";
|
|
113
110
|
const logger = createLogger("daemon", {
|
|
114
111
|
transport: {
|
|
115
112
|
target: "pino-pretty",
|
|
@@ -146,6 +143,32 @@ async function startup() {
|
|
|
146
143
|
// ── 3. Database ──
|
|
147
144
|
const db = createDatabase(config);
|
|
148
145
|
applySchema(db);
|
|
146
|
+
setWikiWorkspaceTokenResolver((processKey, workspaceName) => {
|
|
147
|
+
if (!processKey.startsWith("wiki."))
|
|
148
|
+
return null;
|
|
149
|
+
// Match `context-builder.ts`'s per-event lookup: prefer the named
|
|
150
|
+
// workspace, fall back to the default. Without this, multi-workspace
|
|
151
|
+
// installs would render the `<wiki_workspace>` XML against the target
|
|
152
|
+
// workspace while skill prose (`{{vault_path}}` etc.) referenced the
|
|
153
|
+
// default — the agent would then operate on the wrong vault.
|
|
154
|
+
const workspace = (workspaceName ? readWikiWorkspaceByName(db, workspaceName) : null)
|
|
155
|
+
?? readDefaultWikiWorkspace(db);
|
|
156
|
+
if (!workspace)
|
|
157
|
+
return null;
|
|
158
|
+
return {
|
|
159
|
+
vault_path: workspace.root_path,
|
|
160
|
+
language: workspace.language,
|
|
161
|
+
workspace_name: workspace.name,
|
|
162
|
+
schema_version: String(workspace.schema_version),
|
|
163
|
+
};
|
|
164
|
+
});
|
|
165
|
+
// WIKI_BUILDER_DESIGN.md §P4.A — boot-time FTS backfill. The
|
|
166
|
+
// `fts_wiki` virtual table is content-less and lives outside the
|
|
167
|
+
// mail-style trigger chain (the source is the filesystem, not a SQL
|
|
168
|
+
// table), so a fresh DB or a workspace seeded before P4 landed needs
|
|
169
|
+
// a one-shot rebuild. Per-workspace gate inside `backfillWikiFulltext`
|
|
170
|
+
// keeps this near-free in steady state.
|
|
171
|
+
backfillWikiFulltext(db, listWikiWorkspaces(db));
|
|
149
172
|
// §12 ("managed_tasks.id collision after restore from backup") — ensure
|
|
150
173
|
// `managed_task_seq.next_id` is greater than the max existing mt id so a
|
|
151
174
|
// backup-restored DB cannot collide with the seq counter on the next
|
|
@@ -227,7 +250,6 @@ async function startup() {
|
|
|
227
250
|
let managementMdWatcher = null;
|
|
228
251
|
let managementRegistryWatcher = null;
|
|
229
252
|
try {
|
|
230
|
-
migrateLegacyManagementMd(config.dataDir);
|
|
231
253
|
await bootstrapManagementMd(config.dataDir, db, config.workspaceDir, {
|
|
232
254
|
externalObsidianVaultPath: config.externalObsidianVaultPath,
|
|
233
255
|
externalObsidianWatch: config.externalObsidianWatch,
|
|
@@ -407,185 +429,34 @@ async function startup() {
|
|
|
407
429
|
logger.warn({ err, platform }, "Failed to deliver welcome DM after auto-pairing");
|
|
408
430
|
}
|
|
409
431
|
}
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
}
|
|
425
|
-
messageHub.unregister("discord");
|
|
426
|
-
discordAdapter = null;
|
|
427
|
-
}
|
|
428
|
-
if (!botToken) {
|
|
429
|
-
return;
|
|
430
|
-
}
|
|
431
|
-
discordAdapter = new DiscordAdapter({
|
|
432
|
-
botToken,
|
|
433
|
-
ownerUserId: config.discordOwnerUserId,
|
|
434
|
-
onMessage: (event) => void eventBus.put(event),
|
|
435
|
-
onOwnerDetected: (userId) => recordDetectedOwner("discord", userId),
|
|
436
|
-
attachmentStore,
|
|
437
|
-
});
|
|
438
|
-
messageHub.register(discordAdapter);
|
|
439
|
-
if (startNow) {
|
|
440
|
-
// Mark as "connecting" while the websocket handshake is in flight so
|
|
441
|
-
// /health doesn't briefly report "ok" before the adapter actually
|
|
442
|
-
// comes up (register() defaults to "ok" to keep the notification
|
|
443
|
-
// pipeline usable in unit tests; this override is the real state).
|
|
444
|
-
messageHub.setPlatformRuntimeStatus("discord", { runtimeState: "connecting", error: null });
|
|
445
|
-
try {
|
|
446
|
-
await discordAdapter.start();
|
|
447
|
-
messageHub.setPlatformRuntimeStatus("discord", { runtimeState: "ok", error: null });
|
|
448
|
-
}
|
|
449
|
-
catch (err) {
|
|
450
|
-
const message = toSafeErrorMessage(err, "Discord adapter failed to start");
|
|
451
|
-
messageHub.setPlatformRuntimeStatus("discord", { runtimeState: "error", error: message });
|
|
452
|
-
logger.error({ err }, "Failed to start Discord adapter during reload");
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
async function reloadSlackAdapter(startNow) {
|
|
457
|
-
const [botToken, appToken] = await Promise.all([
|
|
458
|
-
secretBroker.getSlackBotToken(),
|
|
459
|
-
secretBroker.getSlackAppToken(),
|
|
460
|
-
]);
|
|
461
|
-
const configured = !!(botToken && appToken);
|
|
462
|
-
messageHub.setPlatformConfigured("slack", configured);
|
|
463
|
-
if (slackAdapter) {
|
|
464
|
-
try {
|
|
465
|
-
await slackAdapter.stop();
|
|
466
|
-
}
|
|
467
|
-
catch (err) {
|
|
468
|
-
logger.warn({ err }, "Failed to stop Slack adapter during reload");
|
|
469
|
-
}
|
|
470
|
-
messageHub.unregister("slack");
|
|
471
|
-
slackAdapter = null;
|
|
472
|
-
}
|
|
473
|
-
if (!botToken || !appToken) {
|
|
474
|
-
return;
|
|
475
|
-
}
|
|
476
|
-
slackAdapter = new SlackAdapter({
|
|
477
|
-
botToken,
|
|
478
|
-
appToken,
|
|
479
|
-
ownerUserId: config.slackOwnerUserId,
|
|
480
|
-
onMessage: (event) => void eventBus.put(event),
|
|
481
|
-
onOwnerDetected: (userId) => recordDetectedOwner("slack", userId),
|
|
482
|
-
attachmentStore,
|
|
483
|
-
});
|
|
484
|
-
messageHub.register(slackAdapter);
|
|
485
|
-
if (startNow) {
|
|
486
|
-
messageHub.setPlatformRuntimeStatus("slack", { runtimeState: "connecting", error: null });
|
|
487
|
-
try {
|
|
488
|
-
await slackAdapter.start();
|
|
489
|
-
messageHub.setPlatformRuntimeStatus("slack", { runtimeState: "ok", error: null });
|
|
490
|
-
}
|
|
491
|
-
catch (err) {
|
|
492
|
-
const message = toSafeErrorMessage(err, "Slack adapter failed to start");
|
|
493
|
-
messageHub.setPlatformRuntimeStatus("slack", { runtimeState: "error", error: message });
|
|
494
|
-
logger.error({ err }, "Failed to start Slack adapter during reload");
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
async function reloadTelegramAdapter(startNow) {
|
|
499
|
-
const botToken = await secretBroker.getTelegramBotToken();
|
|
500
|
-
const configured = !!botToken;
|
|
501
|
-
messageHub.setPlatformConfigured("telegram", configured);
|
|
502
|
-
if (telegramAdapter) {
|
|
503
|
-
try {
|
|
504
|
-
await telegramAdapter.stop();
|
|
505
|
-
}
|
|
506
|
-
catch (err) {
|
|
507
|
-
logger.warn({ err }, "Failed to stop Telegram adapter during reload");
|
|
508
|
-
}
|
|
509
|
-
messageHub.unregister("telegram");
|
|
510
|
-
telegramAdapter = null;
|
|
511
|
-
}
|
|
512
|
-
if (!botToken) {
|
|
513
|
-
return;
|
|
514
|
-
}
|
|
515
|
-
telegramAdapter = new TelegramAdapter({
|
|
516
|
-
botToken,
|
|
517
|
-
ownerChatId: config.telegramOwnerChatId,
|
|
518
|
-
onMessage: (event) => void eventBus.put(event),
|
|
519
|
-
onOwnerDetected: (chatId) => recordDetectedOwner("telegram", chatId),
|
|
520
|
-
attachmentStore,
|
|
521
|
-
});
|
|
522
|
-
messageHub.register(telegramAdapter);
|
|
523
|
-
if (startNow) {
|
|
524
|
-
messageHub.setPlatformRuntimeStatus("telegram", { runtimeState: "connecting", error: null });
|
|
432
|
+
const adapterState = {
|
|
433
|
+
discord: null,
|
|
434
|
+
slack: null,
|
|
435
|
+
telegram: null,
|
|
436
|
+
whatsapp: null,
|
|
437
|
+
};
|
|
438
|
+
const { reloadDiscordAdapter, reloadSlackAdapter, reloadTelegramAdapter, buildWhatsAppAdapter, teardownWhatsAppAdapter, enableWhatsAppAdapter, } = createAdapterReloaders({
|
|
439
|
+
config,
|
|
440
|
+
secretBroker,
|
|
441
|
+
messageHub,
|
|
442
|
+
eventBus,
|
|
443
|
+
attachmentStore,
|
|
444
|
+
recordDetectedOwner,
|
|
445
|
+
onWhatsAppLoggedOut: async () => {
|
|
525
446
|
try {
|
|
526
|
-
await
|
|
527
|
-
messageHub.setPlatformRuntimeStatus("telegram", { runtimeState: "ok", error: null });
|
|
447
|
+
await messageHub.sendToUser("WhatsApp session logged out — re-run foreground pairing");
|
|
528
448
|
}
|
|
529
449
|
catch (err) {
|
|
530
|
-
|
|
531
|
-
messageHub.setPlatformRuntimeStatus("telegram", { runtimeState: "error", error: message });
|
|
532
|
-
logger.error({ err }, "Failed to start Telegram adapter during reload");
|
|
450
|
+
logger.error({ err }, "Failed to deliver WhatsApp logout notification via fallback channel");
|
|
533
451
|
}
|
|
534
|
-
}
|
|
535
|
-
|
|
452
|
+
},
|
|
453
|
+
state: adapterState,
|
|
454
|
+
});
|
|
536
455
|
await Promise.all([
|
|
537
456
|
reloadDiscordAdapter(false),
|
|
538
457
|
reloadSlackAdapter(false),
|
|
539
458
|
reloadTelegramAdapter(false),
|
|
540
459
|
]);
|
|
541
|
-
/**
|
|
542
|
-
* Build (or rebuild) the WhatsApp adapter from current config and register
|
|
543
|
-
* it with the MessageHub. Idempotent: returns the existing adapter if config
|
|
544
|
-
* is unchanged. Throws if whatsappOwnerPhone is missing.
|
|
545
|
-
*/
|
|
546
|
-
function buildWhatsAppAdapter() {
|
|
547
|
-
if (!config.whatsappOwnerPhone) {
|
|
548
|
-
throw new Error("Cannot enable WhatsApp: PA_WHATSAPP_OWNER_PHONE is not set");
|
|
549
|
-
}
|
|
550
|
-
const existing = messageHub.getAdapter("whatsapp");
|
|
551
|
-
if (existing && whatsappAdapter && existing === whatsappAdapter) {
|
|
552
|
-
return whatsappAdapter;
|
|
553
|
-
}
|
|
554
|
-
const adapter = new WhatsAppAdapter({
|
|
555
|
-
ownerPhone: config.whatsappOwnerPhone,
|
|
556
|
-
authDir: config.whatsappAuthDir ?? join(config.dataDir, "whatsapp", "auth"),
|
|
557
|
-
onMessage: (event) => void eventBus.put(event),
|
|
558
|
-
attachmentStore,
|
|
559
|
-
onLoggedOut: async () => {
|
|
560
|
-
try {
|
|
561
|
-
await messageHub.sendToUser("WhatsApp session logged out — re-run foreground pairing");
|
|
562
|
-
}
|
|
563
|
-
catch (err) {
|
|
564
|
-
logger.error({ err }, "Failed to deliver WhatsApp logout notification via fallback channel");
|
|
565
|
-
}
|
|
566
|
-
},
|
|
567
|
-
});
|
|
568
|
-
messageHub.register(adapter);
|
|
569
|
-
whatsappAdapter = adapter;
|
|
570
|
-
return adapter;
|
|
571
|
-
}
|
|
572
|
-
/**
|
|
573
|
-
* Tear down the WhatsApp adapter completely. Used by the dashboard
|
|
574
|
-
* `whatsappEnabled=false` toggle so we don't keep a stale Baileys socket
|
|
575
|
-
* around. Logs but does not throw on socket close errors.
|
|
576
|
-
*/
|
|
577
|
-
async function teardownWhatsAppAdapter() {
|
|
578
|
-
if (!whatsappAdapter)
|
|
579
|
-
return;
|
|
580
|
-
try {
|
|
581
|
-
await whatsappAdapter.stop();
|
|
582
|
-
}
|
|
583
|
-
catch (err) {
|
|
584
|
-
logger.warn({ err }, "Error stopping WhatsApp adapter during teardown");
|
|
585
|
-
}
|
|
586
|
-
messageHub.unregister("whatsapp");
|
|
587
|
-
whatsappAdapter = null;
|
|
588
|
-
}
|
|
589
460
|
if (config.whatsappEnabled) {
|
|
590
461
|
if (!config.whatsappOwnerPhone) {
|
|
591
462
|
throw new Error("PA_WHATSAPP_ENABLED=true but PA_WHATSAPP_OWNER_PHONE is not set");
|
|
@@ -637,7 +508,7 @@ async function startup() {
|
|
|
637
508
|
},
|
|
638
509
|
startPairing: async (ttlMs = 5 * 60_000) => {
|
|
639
510
|
assertAdapterReady("telegram");
|
|
640
|
-
const adapter =
|
|
511
|
+
const adapter = adapterState.telegram;
|
|
641
512
|
if (!adapter) {
|
|
642
513
|
throw new Error("Telegram adapter is not initialized. Save the token and retry.");
|
|
643
514
|
}
|
|
@@ -697,12 +568,12 @@ async function startup() {
|
|
|
697
568
|
};
|
|
698
569
|
},
|
|
699
570
|
getPairingStatus: () => ({
|
|
700
|
-
paired:
|
|
701
|
-
ownerChatId:
|
|
702
|
-
pairingActive:
|
|
571
|
+
paired: adapterState.telegram?.getOwnerChatId() !== null,
|
|
572
|
+
ownerChatId: adapterState.telegram?.getOwnerChatId() ?? null,
|
|
573
|
+
pairingActive: adapterState.telegram?.isPairingActive() ?? false,
|
|
703
574
|
}),
|
|
704
575
|
cancelPairing: () => {
|
|
705
|
-
|
|
576
|
+
adapterState.telegram?.cancelPairing();
|
|
706
577
|
},
|
|
707
578
|
};
|
|
708
579
|
}
|
|
@@ -724,7 +595,7 @@ async function startup() {
|
|
|
724
595
|
},
|
|
725
596
|
startPairing: async (ttlMs = 5 * 60_000) => {
|
|
726
597
|
assertAdapterReady("slack");
|
|
727
|
-
const adapter =
|
|
598
|
+
const adapter = adapterState.slack;
|
|
728
599
|
if (!adapter) {
|
|
729
600
|
throw new Error("Slack adapter is not initialized. Save the tokens and retry.");
|
|
730
601
|
}
|
|
@@ -743,12 +614,12 @@ async function startup() {
|
|
|
743
614
|
return { phrase, expiresAt };
|
|
744
615
|
},
|
|
745
616
|
cancelPairing: () => {
|
|
746
|
-
|
|
617
|
+
adapterState.slack?.cancelPairing();
|
|
747
618
|
},
|
|
748
619
|
getPairingStatus: () => ({
|
|
749
|
-
paired:
|
|
750
|
-
ownerUserId:
|
|
751
|
-
pairingActive:
|
|
620
|
+
paired: adapterState.slack?.getOwnerUserId() !== null,
|
|
621
|
+
ownerUserId: adapterState.slack?.getOwnerUserId() ?? null,
|
|
622
|
+
pairingActive: adapterState.slack?.isPairingActive() ?? false,
|
|
752
623
|
}),
|
|
753
624
|
};
|
|
754
625
|
}
|
|
@@ -770,7 +641,7 @@ async function startup() {
|
|
|
770
641
|
},
|
|
771
642
|
startPairing: async (ttlMs = 5 * 60_000) => {
|
|
772
643
|
assertAdapterReady("discord");
|
|
773
|
-
const adapter =
|
|
644
|
+
const adapter = adapterState.discord;
|
|
774
645
|
if (!adapter) {
|
|
775
646
|
throw new Error("Discord adapter is not initialized. Save the token and retry.");
|
|
776
647
|
}
|
|
@@ -784,38 +655,15 @@ async function startup() {
|
|
|
784
655
|
return { phrase, expiresAt };
|
|
785
656
|
},
|
|
786
657
|
cancelPairing: () => {
|
|
787
|
-
|
|
658
|
+
adapterState.discord?.cancelPairing();
|
|
788
659
|
},
|
|
789
660
|
getPairingStatus: () => ({
|
|
790
|
-
paired:
|
|
791
|
-
ownerUserId:
|
|
792
|
-
pairingActive:
|
|
661
|
+
paired: adapterState.discord?.getOwnerUserId() !== null,
|
|
662
|
+
ownerUserId: adapterState.discord?.getOwnerUserId() ?? null,
|
|
663
|
+
pairingActive: adapterState.discord?.isPairingActive() ?? false,
|
|
793
664
|
}),
|
|
794
665
|
};
|
|
795
666
|
}
|
|
796
|
-
function whatsappQrResponseFromAdapter(adapter, snapshotOverride) {
|
|
797
|
-
if (!adapter) {
|
|
798
|
-
return {
|
|
799
|
-
dataUrl: null,
|
|
800
|
-
payload: null,
|
|
801
|
-
generatedAt: null,
|
|
802
|
-
expiresAt: null,
|
|
803
|
-
state: "not_initialized",
|
|
804
|
-
error: "WhatsApp adapter not enabled",
|
|
805
|
-
};
|
|
806
|
-
}
|
|
807
|
-
const snapshot = snapshotOverride !== undefined
|
|
808
|
-
? snapshotOverride
|
|
809
|
-
: adapter.getQrSnapshot();
|
|
810
|
-
return {
|
|
811
|
-
dataUrl: snapshot?.dataUrl ?? null,
|
|
812
|
-
payload: snapshot?.payload ?? null,
|
|
813
|
-
generatedAt: snapshot?.generatedAt ?? null,
|
|
814
|
-
expiresAt: snapshot?.expiresAt ?? null,
|
|
815
|
-
state: adapter.getStatus(),
|
|
816
|
-
error: adapter.getStatusError(),
|
|
817
|
-
};
|
|
818
|
-
}
|
|
819
667
|
// Dashboard adapter — always registered (activates on SSE connect)
|
|
820
668
|
const dashboardAdapter = new DashboardAdapter((event) => void eventBus.put(event));
|
|
821
669
|
messageHub.register(dashboardAdapter);
|
|
@@ -882,96 +730,14 @@ async function startup() {
|
|
|
882
730
|
},
|
|
883
731
|
},
|
|
884
732
|
});
|
|
885
|
-
const secretState =
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
};
|
|
893
|
-
async function refreshGoogleSecretState() {
|
|
894
|
-
const [credentialsRaw, tokenRaw] = await Promise.all([
|
|
895
|
-
secretBroker.getGoogleCredentialsJson(),
|
|
896
|
-
secretBroker.getGoogleTokenJson(),
|
|
897
|
-
]);
|
|
898
|
-
secretState.googleCredentialsConfigured = !!credentialsRaw;
|
|
899
|
-
secretState.googleTokenConfigured = !!tokenRaw;
|
|
900
|
-
secretState.googleCredentialType = detectGoogleCredentialType(credentialsRaw);
|
|
901
|
-
}
|
|
902
|
-
async function reloadGoogleServices() {
|
|
903
|
-
await refreshGoogleSecretState();
|
|
904
|
-
services.calendar = null;
|
|
905
|
-
services.gmail = null;
|
|
906
|
-
delete services.errors.googleCalendar;
|
|
907
|
-
delete services.errors.gmail;
|
|
908
|
-
if (!secretState.googleCredentialsConfigured) {
|
|
909
|
-
if (services.mail) {
|
|
910
|
-
syncLegacyGmailAccountState(db, services.mail, {
|
|
911
|
-
available: false,
|
|
912
|
-
error: "Google credentials are not configured.",
|
|
913
|
-
});
|
|
914
|
-
}
|
|
915
|
-
return;
|
|
916
|
-
}
|
|
917
|
-
// OAuth2 pre-auth: credentials uploaded but the user has not completed the
|
|
918
|
-
// browser flow yet (no token in the keychain). Initializing the services
|
|
919
|
-
// would fail with a "missing token" error that the dashboard would then
|
|
920
|
-
// render as red "Error" under the Google card — but this is the expected
|
|
921
|
-
// mid-setup state, not a failure. Skip init and leave services.errors
|
|
922
|
-
// unset so /health reports error: null until the user finishes OAuth or a
|
|
923
|
-
// real init error occurs.
|
|
924
|
-
const oauth2PreAuth = secretState.googleCredentialType === "oauth2"
|
|
925
|
-
&& !secretState.googleTokenConfigured;
|
|
926
|
-
if (oauth2PreAuth) {
|
|
927
|
-
if (services.mail) {
|
|
928
|
-
syncLegacyGmailAccountState(db, services.mail, {
|
|
929
|
-
available: false,
|
|
930
|
-
error: "Awaiting Google OAuth authorization.",
|
|
931
|
-
});
|
|
932
|
-
}
|
|
933
|
-
return;
|
|
934
|
-
}
|
|
935
|
-
const calendarService = new CalendarService(config, secretBroker);
|
|
936
|
-
try {
|
|
937
|
-
await calendarService.init();
|
|
938
|
-
services.calendar = calendarService;
|
|
939
|
-
}
|
|
940
|
-
catch (err) {
|
|
941
|
-
const msg = err.message;
|
|
942
|
-
logger.error({ error: msg }, "Calendar service init failed, continuing without it");
|
|
943
|
-
services.errors.googleCalendar = msg;
|
|
944
|
-
}
|
|
945
|
-
const gmailService = new GmailService(secretBroker);
|
|
946
|
-
try {
|
|
947
|
-
await gmailService.init();
|
|
948
|
-
services.gmail = gmailService;
|
|
949
|
-
}
|
|
950
|
-
catch (err) {
|
|
951
|
-
const msg = err.message;
|
|
952
|
-
logger.error({ error: msg }, "Gmail service init failed, continuing without it");
|
|
953
|
-
services.errors.gmail = msg;
|
|
954
|
-
}
|
|
955
|
-
// Ensure the shared-Google-OAuth Gmail identity exists as a unified
|
|
956
|
-
// mail account (idempotent; returns `exists` on subsequent boots).
|
|
957
|
-
if (services.gmail?.available) {
|
|
958
|
-
try {
|
|
959
|
-
await ensureLegacyGmailRow(db, services.gmail);
|
|
960
|
-
}
|
|
961
|
-
catch (err) {
|
|
962
|
-
logger.error({ err }, "Failed to ensure shared-Google-OAuth Gmail mail_accounts row");
|
|
963
|
-
}
|
|
964
|
-
if (services.mail) {
|
|
965
|
-
syncLegacyGmailAccountState(db, services.mail, { available: true });
|
|
966
|
-
}
|
|
967
|
-
}
|
|
968
|
-
else if (services.mail) {
|
|
969
|
-
syncLegacyGmailAccountState(db, services.mail, {
|
|
970
|
-
available: false,
|
|
971
|
-
error: services.errors.gmail ?? "Gmail is not configured.",
|
|
972
|
-
});
|
|
973
|
-
}
|
|
974
|
-
}
|
|
733
|
+
const secretState = createInitialSecretState();
|
|
734
|
+
const { reloadGoogleServices, reloadAppleCalendarService, reloadNotionService, reloadGitHubService, } = createServiceReloaders({
|
|
735
|
+
db,
|
|
736
|
+
config,
|
|
737
|
+
secretBroker,
|
|
738
|
+
services,
|
|
739
|
+
secretState,
|
|
740
|
+
});
|
|
975
741
|
// Google Maps (F-08: commute optimization)
|
|
976
742
|
{
|
|
977
743
|
const { GoogleMapsService } = await import("./services/google-maps.js");
|
|
@@ -1007,78 +773,6 @@ async function startup() {
|
|
|
1007
773
|
else if (config.externalObsidianVaultPath && !config.externalObsidianVaultName) {
|
|
1008
774
|
services.errors.obsidian = "externalObsidianVaultName is required for the Obsidian CLI service (externalObsidianVaultPath alone enables file watching only)";
|
|
1009
775
|
}
|
|
1010
|
-
async function reloadAppleCalendarService() {
|
|
1011
|
-
const raw = await secretBroker.getAppleCalendarCredentialsJson();
|
|
1012
|
-
services.appleCalendar = null;
|
|
1013
|
-
delete services.errors.appleCalendar;
|
|
1014
|
-
if (!raw) {
|
|
1015
|
-
return;
|
|
1016
|
-
}
|
|
1017
|
-
const service = new AppleCalendarService(secretBroker);
|
|
1018
|
-
try {
|
|
1019
|
-
await service.init();
|
|
1020
|
-
if (service.available) {
|
|
1021
|
-
services.appleCalendar = service;
|
|
1022
|
-
}
|
|
1023
|
-
else {
|
|
1024
|
-
// Surface the underlying iCloud error verbatim — the dashboard
|
|
1025
|
-
// shows it on the Connections card so the user can act
|
|
1026
|
-
// (`401 Unauthorized` → regenerate password; network error →
|
|
1027
|
-
// retry; etc.). Falls back to a generic placeholder only if
|
|
1028
|
-
// init() failed without recording a message.
|
|
1029
|
-
services.errors.appleCalendar =
|
|
1030
|
-
service.initError
|
|
1031
|
-
?? "Apple Calendar credentials present but iCloud discovery did not return a usable calendar — verify the app-specific password.";
|
|
1032
|
-
}
|
|
1033
|
-
}
|
|
1034
|
-
catch (err) {
|
|
1035
|
-
const msg = err.message;
|
|
1036
|
-
logger.error({ error: msg }, "Apple Calendar service init failed, continuing without it");
|
|
1037
|
-
services.errors.appleCalendar = msg;
|
|
1038
|
-
}
|
|
1039
|
-
}
|
|
1040
|
-
async function reloadNotionService() {
|
|
1041
|
-
const apiKey = await secretBroker.getNotionApiKey();
|
|
1042
|
-
secretState.notionConfigured = !!apiKey;
|
|
1043
|
-
services.notion = null;
|
|
1044
|
-
delete services.errors.notion;
|
|
1045
|
-
if (!apiKey) {
|
|
1046
|
-
return;
|
|
1047
|
-
}
|
|
1048
|
-
const notionService = new NotionService(config, secretBroker);
|
|
1049
|
-
try {
|
|
1050
|
-
await notionService.init();
|
|
1051
|
-
services.notion = notionService;
|
|
1052
|
-
}
|
|
1053
|
-
catch (err) {
|
|
1054
|
-
const msg = err.message;
|
|
1055
|
-
logger.error({ error: msg }, "Notion service init failed, continuing without it");
|
|
1056
|
-
services.errors.notion = msg;
|
|
1057
|
-
}
|
|
1058
|
-
}
|
|
1059
|
-
async function reloadGitHubService() {
|
|
1060
|
-
const [token, webhookSecret] = await Promise.all([
|
|
1061
|
-
secretBroker.getGitHubToken(),
|
|
1062
|
-
secretBroker.getGitHubWebhookSecret(),
|
|
1063
|
-
]);
|
|
1064
|
-
secretState.githubConfigured = !!token;
|
|
1065
|
-
secretState.githubWebhookConfigured = !!webhookSecret;
|
|
1066
|
-
services.github = null;
|
|
1067
|
-
delete services.errors.github;
|
|
1068
|
-
if (!token) {
|
|
1069
|
-
return;
|
|
1070
|
-
}
|
|
1071
|
-
const githubService = new GitHubService(token, webhookSecret);
|
|
1072
|
-
try {
|
|
1073
|
-
await githubService.init();
|
|
1074
|
-
services.github = githubService;
|
|
1075
|
-
}
|
|
1076
|
-
catch (err) {
|
|
1077
|
-
const msg = err.message;
|
|
1078
|
-
logger.error({ error: msg }, "GitHub service init failed, continuing without it");
|
|
1079
|
-
services.errors.github = msg;
|
|
1080
|
-
}
|
|
1081
|
-
}
|
|
1082
776
|
await Promise.all([
|
|
1083
777
|
reloadGoogleServices(),
|
|
1084
778
|
reloadAppleCalendarService(),
|
|
@@ -1088,7 +782,7 @@ async function startup() {
|
|
|
1088
782
|
/** Build integration status snapshot for /api/health */
|
|
1089
783
|
const getIntegrationStatus = () => {
|
|
1090
784
|
const whatsappState = config.whatsappEnabled
|
|
1091
|
-
? (
|
|
785
|
+
? (adapterState.whatsapp?.getStatus() ?? "disabled")
|
|
1092
786
|
: "not_configured";
|
|
1093
787
|
return {
|
|
1094
788
|
google: {
|
|
@@ -1828,7 +1522,7 @@ async function startup() {
|
|
|
1828
1522
|
// the newly created backend-specific dir (e.g. .codex/skills/) also
|
|
1829
1523
|
// receives user skills. The dispatcher's syncAllUserSkills ran BEFORE
|
|
1830
1524
|
// router.execute(), so the fallback dir didn't exist at that point.
|
|
1831
|
-
(sessionDir, backendId, eventType, processKey) => {
|
|
1525
|
+
(sessionDir, backendId, eventType, processKey, wikiWorkspaceName) => {
|
|
1832
1526
|
// services is the mutable ServiceRegistry — reading .calendar here
|
|
1833
1527
|
// picks up the current availability (e.g. after mid-flight OAuth).
|
|
1834
1528
|
// GitHub presence is read fresh from the unified `repositories` table
|
|
@@ -1838,7 +1532,7 @@ async function startup() {
|
|
|
1838
1532
|
github: selectGithubRepoSlugs(db).length > 0,
|
|
1839
1533
|
});
|
|
1840
1534
|
const mailAccounts = services.mail?.listActiveAccounts() ?? [];
|
|
1841
|
-
ensureBackendMaterialized(config.workspaceDir, sessionDir, backendId, eventType, processKey, cfgServices, mailAccounts, readIntegrations(db), config.character);
|
|
1535
|
+
ensureBackendMaterialized(config.workspaceDir, sessionDir, backendId, eventType, processKey, cfgServices, mailAccounts, readIntegrations(db), config.character, wikiWorkspaceName);
|
|
1842
1536
|
syncAllUserSkills(sessionDir, join(config.dataDir, "skills"));
|
|
1843
1537
|
});
|
|
1844
1538
|
// Startup validation — warn if any delegated-mode variant files are
|
|
@@ -1965,6 +1659,13 @@ async function startup() {
|
|
|
1965
1659
|
// safe (DOCS_QA_B7_DESIGN.md §9 F3.4 / §11.4).
|
|
1966
1660
|
dispatcher.setDashboardStream(new CompositeDashboardStream([dashboardAdapter, docsQAAdapter]));
|
|
1967
1661
|
dispatcher.setAttachmentStore(attachmentStore);
|
|
1662
|
+
// Real-time routine progress for the dashboard. `dispatchSafe` emits
|
|
1663
|
+
// `kind: "routine_started"` / `"routine_completed"` on the default
|
|
1664
|
+
// SSE `event` channel — same pipe as `kind: "main_backend_changed"`
|
|
1665
|
+
// — so the setup wizard's "今日の状況を生成中…" indicator can render
|
|
1666
|
+
// without waiting on `/api/events` REST polling. Failure containment
|
|
1667
|
+
// lives in `broadcastRoutineProgress` (swallows + warns).
|
|
1668
|
+
dispatcher.setEventBroadcaster(eventBroadcaster);
|
|
1968
1669
|
// Local-Whisper voice transcription for inbound audio attachments.
|
|
1969
1670
|
// See docs/design/appendices/voice-transcription.md.
|
|
1970
1671
|
//
|
|
@@ -2071,17 +1772,7 @@ async function startup() {
|
|
|
2071
1772
|
// (same logic as runCatchup, ensures schedule generation after first auth)
|
|
2072
1773
|
const contextDir = getContextDir(config);
|
|
2073
1774
|
const todayMdPath = join(contextDir, "today.md");
|
|
2074
|
-
|
|
2075
|
-
if (existsSync(todayMdPath)) {
|
|
2076
|
-
const firstLine = readFileSync(todayMdPath, "utf-8").split("\n")[0];
|
|
2077
|
-
const today = getAgentDayDateStr(config.timezone || undefined, config.dayBoundaryHour);
|
|
2078
|
-
if (!firstLine.includes(today)) {
|
|
2079
|
-
needsMorning = true;
|
|
2080
|
-
}
|
|
2081
|
-
}
|
|
2082
|
-
else {
|
|
2083
|
-
needsMorning = true;
|
|
2084
|
-
}
|
|
1775
|
+
const needsMorning = !hasFreshAgentDayTodayMd(todayMdPath, config.timezone || undefined, config.dayBoundaryHour);
|
|
2085
1776
|
if (needsMorning) {
|
|
2086
1777
|
// Morning routine's post-completion hook will also check roadmap staleness.
|
|
2087
1778
|
logger.info("Google services ready — today.md stale, queueing morning_routine wake");
|
|
@@ -2433,7 +2124,7 @@ async function startup() {
|
|
|
2433
2124
|
auditLogger,
|
|
2434
2125
|
validateAttachmentTurnToken: (token) => dispatcher.validateAttachmentTurnToken(token),
|
|
2435
2126
|
whatsappControls: {
|
|
2436
|
-
isInitialized: () =>
|
|
2127
|
+
isInitialized: () => adapterState.whatsapp !== null,
|
|
2437
2128
|
enable: async () => {
|
|
2438
2129
|
const adapter = buildWhatsAppAdapter();
|
|
2439
2130
|
if (adapter.getStatus() === "disabled") {
|
|
@@ -2444,19 +2135,58 @@ async function startup() {
|
|
|
2444
2135
|
await teardownWhatsAppAdapter();
|
|
2445
2136
|
},
|
|
2446
2137
|
requestQr: async () => {
|
|
2447
|
-
if (!
|
|
2448
|
-
await
|
|
2138
|
+
if (!adapterState.whatsapp) {
|
|
2139
|
+
await enableWhatsAppAdapter();
|
|
2449
2140
|
}
|
|
2450
|
-
await
|
|
2141
|
+
await adapterState.whatsapp.requestQR();
|
|
2451
2142
|
},
|
|
2452
2143
|
waitForQr: async (timeoutMs = 10_000) => {
|
|
2453
|
-
if (!
|
|
2454
|
-
await
|
|
2144
|
+
if (!adapterState.whatsapp) {
|
|
2145
|
+
await enableWhatsAppAdapter();
|
|
2146
|
+
}
|
|
2147
|
+
const snapshot = await adapterState.whatsapp.waitForQr(timeoutMs);
|
|
2148
|
+
return whatsappQrResponseFromAdapter(adapterState.whatsapp, snapshot);
|
|
2149
|
+
},
|
|
2150
|
+
getQrResponse: () => whatsappQrResponseFromAdapter(adapterState.whatsapp),
|
|
2151
|
+
reset: async (timeoutMs = 10_000) => {
|
|
2152
|
+
// 1. Stop + unregister any live adapter so no Baileys callbacks fire
|
|
2153
|
+
// against the auth dir while we delete it.
|
|
2154
|
+
await teardownWhatsAppAdapter();
|
|
2155
|
+
// 2. Wipe Baileys' multi-file auth state. Without this, a fresh
|
|
2156
|
+
// enable() would re-load the stale creds and never emit a QR —
|
|
2157
|
+
// which is exactly the "前のデータが残っているのか pair できない"
|
|
2158
|
+
// failure mode the dashboard's "Reset connection" button exists
|
|
2159
|
+
// to recover from. Recursive + force so a partially-written dir
|
|
2160
|
+
// (e.g. only qr.txt present, no creds.json yet) still wipes
|
|
2161
|
+
// cleanly. `force: true` also no-ops if the dir is already gone.
|
|
2162
|
+
const authDir = config.whatsappAuthDir ?? join(config.dataDir, "whatsapp", "auth");
|
|
2163
|
+
try {
|
|
2164
|
+
rmSync(authDir, { recursive: true, force: true });
|
|
2165
|
+
}
|
|
2166
|
+
catch (err) {
|
|
2167
|
+
logger.warn({ err, authDir }, "Failed to wipe WhatsApp auth directory during reset");
|
|
2168
|
+
}
|
|
2169
|
+
// 3. Drop the cached owner_channels mapping so a freshly-paired
|
|
2170
|
+
// session re-discovers the channel id from the inbound auth
|
|
2171
|
+
// handshake rather than reusing the prior LID alias.
|
|
2172
|
+
try {
|
|
2173
|
+
db
|
|
2174
|
+
.prepare("DELETE FROM owner_channels WHERE platform = ?")
|
|
2175
|
+
.run("whatsapp");
|
|
2176
|
+
}
|
|
2177
|
+
catch (err) {
|
|
2178
|
+
logger.warn({ err }, "Failed to clear WhatsApp owner_channels row during reset");
|
|
2455
2179
|
}
|
|
2456
|
-
|
|
2457
|
-
|
|
2180
|
+
// 4. If the integration is still enabled, rebuild the adapter and
|
|
2181
|
+
// await the first scannable QR so the dashboard can render it
|
|
2182
|
+
// in the same request that triggered the reset.
|
|
2183
|
+
if (!config.whatsappEnabled) {
|
|
2184
|
+
return whatsappQrResponseFromAdapter(null);
|
|
2185
|
+
}
|
|
2186
|
+
await enableWhatsAppAdapter();
|
|
2187
|
+
const snapshot = await adapterState.whatsapp.waitForQr(timeoutMs);
|
|
2188
|
+
return whatsappQrResponseFromAdapter(adapterState.whatsapp, snapshot);
|
|
2458
2189
|
},
|
|
2459
|
-
getQrResponse: () => whatsappQrResponseFromAdapter(whatsappAdapter),
|
|
2460
2190
|
},
|
|
2461
2191
|
messagingControls: {
|
|
2462
2192
|
telegram: buildTelegramControls(),
|
|
@@ -2464,13 +2194,6 @@ async function startup() {
|
|
|
2464
2194
|
discord: buildDiscordControls(),
|
|
2465
2195
|
},
|
|
2466
2196
|
});
|
|
2467
|
-
// Local helper avoiding circular reference inside the object literal above.
|
|
2468
|
-
async function whatsappControls_enable() {
|
|
2469
|
-
const adapter = buildWhatsAppAdapter();
|
|
2470
|
-
if (adapter.getStatus() === "disabled") {
|
|
2471
|
-
await adapter.start();
|
|
2472
|
-
}
|
|
2473
|
-
}
|
|
2474
2197
|
// Mount /api/docs/* (DOCS_QA_DESIGN.md §10.4 + DOCS_QA_B7_DESIGN.md
|
|
2475
2198
|
// §S5–S6) after createApp so the indexer handle and the QA SSE
|
|
2476
2199
|
// adapter can be threaded in without extending ApiDependencies. The
|
|
@@ -2486,6 +2209,22 @@ async function startup() {
|
|
|
2486
2209
|
fetch: app.fetch,
|
|
2487
2210
|
hostname: "127.0.0.1",
|
|
2488
2211
|
port: config.apiPort,
|
|
2212
|
+
// @hono/node-server's getRequestListener defaults to replacing
|
|
2213
|
+
// `globalThis.Request` / `globalThis.Response` with its own lazy
|
|
2214
|
+
// wrapper classes (named `_Request` / `_Response`) for response-
|
|
2215
|
+
// body materialization performance. The wrappers are prototype-
|
|
2216
|
+
// chained to the native classes — fine for Hono's own response
|
|
2217
|
+
// path — but they break `instanceof Response` checks for objects
|
|
2218
|
+
// returned by native `fetch()`, because a native Response's
|
|
2219
|
+
// prototype chain doesn't include `_Response.prototype`. This
|
|
2220
|
+
// makes `@huggingface/transformers`'s `toCacheResponse` check
|
|
2221
|
+
// (`response instanceof Response && response.status === 200`)
|
|
2222
|
+
// evaluate to false on fresh fetches, which silently skips
|
|
2223
|
+
// `cache.put` and then throws "Unable to get model file path or
|
|
2224
|
+
// buffer." Disabling the override keeps the native globals
|
|
2225
|
+
// intact and costs us nothing — we don't construct Hono's
|
|
2226
|
+
// `Response` instances directly anywhere in the daemon.
|
|
2227
|
+
overrideGlobalObjects: false,
|
|
2489
2228
|
});
|
|
2490
2229
|
logger.info({ port: config.apiPort }, "API server listening");
|
|
2491
2230
|
void dispatcher.run(); // Start consuming dashboard events as soon as the API is live
|
|
@@ -2706,202 +2445,12 @@ async function startup() {
|
|
|
2706
2445
|
}
|
|
2707
2446
|
logger.info(`${APP_NAME} Daemon ready`);
|
|
2708
2447
|
}
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
// catchup will run on the first normal boot *after* setup completes.
|
|
2716
|
-
const gateReason = dispatcher.isAutonomousAllowed();
|
|
2717
|
-
if (gateReason !== null) {
|
|
2718
|
-
logger.info({ reason: gateReason }, "Skipping startup catchup — autonomous work paused for setup");
|
|
2719
|
-
return {
|
|
2720
|
-
postMessagingRoadmapRefresh: false,
|
|
2721
|
-
postMessagingRoutines: [],
|
|
2722
|
-
postMessagingHourlyCheck: false,
|
|
2723
|
-
};
|
|
2724
|
-
}
|
|
2725
|
-
const now = new Date();
|
|
2726
|
-
const tz = config.timezone || undefined;
|
|
2727
|
-
const contextDir = getContextDir(config);
|
|
2728
|
-
const todayMdPath = join(contextDir, "today.md");
|
|
2729
|
-
const { start: agentDayStartUtc, end: agentDayEndUtc } = getAgentDayBoundsUtc(tz, config.dayBoundaryHour, now);
|
|
2730
|
-
const skippedPending = discardStalePendingSchedules(db, agentDayStartUtc);
|
|
2731
|
-
if (skippedPending > 0) {
|
|
2732
|
-
logger.warn({ count: skippedPending }, "Discarded stale pending schedules at startup");
|
|
2733
|
-
}
|
|
2734
|
-
const runningRecovery = recoverOrphanedRunningSchedules(db, agentDayStartUtc);
|
|
2735
|
-
if (runningRecovery.skipped > 0 || runningRecovery.failed > 0) {
|
|
2736
|
-
logger.warn(runningRecovery, "Recovered orphaned running schedules without replay");
|
|
2737
|
-
}
|
|
2738
|
-
// Check if morning routine is needed
|
|
2739
|
-
let needsMorning = false;
|
|
2740
|
-
if (existsSync(todayMdPath)) {
|
|
2741
|
-
const firstLine = readFileSync(todayMdPath, "utf-8").split("\n")[0];
|
|
2742
|
-
const today = getAgentDayDateStr(tz, config.dayBoundaryHour, now);
|
|
2743
|
-
if (!firstLine.includes(today)) {
|
|
2744
|
-
needsMorning = true;
|
|
2745
|
-
}
|
|
2746
|
-
}
|
|
2747
|
-
else {
|
|
2748
|
-
needsMorning = true;
|
|
2749
|
-
}
|
|
2750
|
-
const dueCatchupRoutines = getDueCatchupRoutines(db, config, agentDayStartUtc, agentDayEndUtc, now);
|
|
2751
|
-
const needsHourlyCheckCatchup = shouldCatchUpHourlyCheck(db, config, now);
|
|
2752
|
-
let ranMorningCatchup = false;
|
|
2753
|
-
if (needsMorning) {
|
|
2754
|
-
try {
|
|
2755
|
-
await dispatcher.summarizeDmSessions();
|
|
2756
|
-
}
|
|
2757
|
-
catch (err) {
|
|
2758
|
-
logger.error({ err }, "DM summarization catchup failed before morning routine");
|
|
2759
|
-
}
|
|
2760
|
-
logger.info("Stale today.md detected, running morning_routine catchup inline");
|
|
2761
|
-
await dispatcher.processInline({
|
|
2762
|
-
...createEvent({
|
|
2763
|
-
type: "routine.morning_routine",
|
|
2764
|
-
source: "catchup",
|
|
2765
|
-
priority: EventPriority.HIGH,
|
|
2766
|
-
data: {
|
|
2767
|
-
postCatchupRoutines: dueCatchupRoutines,
|
|
2768
|
-
postCatchupHourlyCheck: needsHourlyCheckCatchup,
|
|
2769
|
-
deferPostMorningCatchupsUntilStartupReady: true,
|
|
2770
|
-
},
|
|
2771
|
-
}),
|
|
2772
|
-
routine: "morning_routine",
|
|
2773
|
-
});
|
|
2774
|
-
ranMorningCatchup = true;
|
|
2775
|
-
if (!hasFreshAgentDayTodayMd(todayMdPath, tz, config.dayBoundaryHour)) {
|
|
2776
|
-
logger.warn("Startup morning catchup did not produce a fresh today.md — deferring remaining catchup work");
|
|
2777
|
-
return {
|
|
2778
|
-
postMessagingRoadmapRefresh: false,
|
|
2779
|
-
postMessagingRoutines: [],
|
|
2780
|
-
postMessagingHourlyCheck: false,
|
|
2781
|
-
};
|
|
2782
|
-
}
|
|
2783
|
-
return {
|
|
2784
|
-
postMessagingRoadmapRefresh: isRoadmapStale(contextDir),
|
|
2785
|
-
postMessagingRoutines: dueCatchupRoutines,
|
|
2786
|
-
postMessagingHourlyCheck: needsHourlyCheckCatchup,
|
|
2787
|
-
};
|
|
2788
|
-
}
|
|
2789
|
-
if (!ranMorningCatchup && isRoadmapStale(contextDir)) {
|
|
2790
|
-
logger.info("Roadmap stale at startup, running roadmap_refresh catchup inline");
|
|
2791
|
-
await processRoutineCatchup(dispatcher, "roadmap_refresh");
|
|
2792
|
-
}
|
|
2793
|
-
return {
|
|
2794
|
-
postMessagingRoadmapRefresh: false,
|
|
2795
|
-
postMessagingRoutines: dueCatchupRoutines,
|
|
2796
|
-
postMessagingHourlyCheck: needsHourlyCheckCatchup,
|
|
2797
|
-
};
|
|
2798
|
-
}
|
|
2799
|
-
async function runPostMessagingCatchup(dispatcher, catchup) {
|
|
2800
|
-
if (catchup.postMessagingRoadmapRefresh) {
|
|
2801
|
-
logger.info("Running roadmap_refresh catchup after messaging startup");
|
|
2802
|
-
await processRoutineCatchup(dispatcher, "roadmap_refresh");
|
|
2803
|
-
}
|
|
2804
|
-
for (const routine of catchup.postMessagingRoutines) {
|
|
2805
|
-
logger.info({ routine }, "Running same-day routine catchup after messaging startup");
|
|
2806
|
-
await processRoutineCatchup(dispatcher, routine);
|
|
2807
|
-
}
|
|
2808
|
-
if (catchup.postMessagingHourlyCheck) {
|
|
2809
|
-
logger.info("Triggering hourly_check catchup after messaging startup");
|
|
2810
|
-
await dispatcher.triggerHourlyCheck("catchup_startup", { force: false });
|
|
2811
|
-
}
|
|
2812
|
-
}
|
|
2813
|
-
async function processRoutineCatchup(dispatcher, routine) {
|
|
2814
|
-
await dispatcher.processInline({
|
|
2815
|
-
...createEvent({
|
|
2816
|
-
type: `routine.${routine}`,
|
|
2817
|
-
source: "catchup",
|
|
2818
|
-
priority: routine === "hourly_check" ? EventPriority.NORMAL : EventPriority.HIGH,
|
|
2819
|
-
}),
|
|
2820
|
-
routine,
|
|
2821
|
-
});
|
|
2822
|
-
}
|
|
2823
|
-
function getDueCatchupRoutines(db, config, agentDayStartUtc, agentDayEndUtc, now) {
|
|
2824
|
-
const tz = config.timezone || undefined;
|
|
2825
|
-
const progressMinutes = getAgentDayProgressMinutes(tz, config.dayBoundaryHour, now);
|
|
2826
|
-
const dueAt18 = getProgressMinutesForHour(18, config.dayBoundaryHour);
|
|
2827
|
-
if (progressMinutes < dueAt18) {
|
|
2828
|
-
return [];
|
|
2829
|
-
}
|
|
2830
|
-
const routines = [];
|
|
2831
|
-
const agentDayStartMs = parseSqliteUtcMs(agentDayStartUtc);
|
|
2832
|
-
const agentDayLocal = nowInTimezone(tz, new Date(agentDayStartMs));
|
|
2833
|
-
const tomorrowLocal = nowInTimezone(tz, new Date(agentDayStartMs + 24 * 60 * 60 * 1000));
|
|
2834
|
-
if (!hasActionInWindow(db, "routine.evening_review", agentDayStartUtc, agentDayEndUtc)) {
|
|
2835
|
-
routines.push("evening_review");
|
|
2836
|
-
}
|
|
2837
|
-
if (agentDayLocal.dayOfWeek === 5 &&
|
|
2838
|
-
!hasActionInWindow(db, "routine.weekly_review", agentDayStartUtc, agentDayEndUtc)) {
|
|
2839
|
-
routines.push("weekly_review");
|
|
2840
|
-
}
|
|
2841
|
-
if (tomorrowLocal.day === 1 &&
|
|
2842
|
-
!hasActionInWindow(db, "routine.monthly_review", agentDayStartUtc, agentDayEndUtc)) {
|
|
2843
|
-
routines.push("monthly_review");
|
|
2844
|
-
}
|
|
2845
|
-
return routines;
|
|
2846
|
-
}
|
|
2847
|
-
function shouldCatchUpHourlyCheck(db, config, now) {
|
|
2848
|
-
if (!config.hourlyCheckEnabled) {
|
|
2849
|
-
return false;
|
|
2850
|
-
}
|
|
2851
|
-
const tz = config.timezone || undefined;
|
|
2852
|
-
const local = nowInTimezone(tz, now);
|
|
2853
|
-
if (local.hours < config.hourlyCheckActiveStartHour ||
|
|
2854
|
-
local.hours >= config.hourlyCheckActiveEndHour ||
|
|
2855
|
-
local.hours === config.dayBoundaryHour) {
|
|
2856
|
-
return false;
|
|
2857
|
-
}
|
|
2858
|
-
// Slot anchors to `activeStartHour`, mirroring shouldFireHourlyTickAt
|
|
2859
|
-
// in scheduler.ts so the catch-up function picks the same slot the
|
|
2860
|
-
// cron callback would have fired at. The earlier branch already
|
|
2861
|
-
// returned false when local.hours < activeStartHour, so the offset is
|
|
2862
|
-
// always non-negative here.
|
|
2863
|
-
const anchorMinutes = config.hourlyCheckActiveStartHour * 60;
|
|
2864
|
-
const offsetFromAnchor = local.hours * 60 + local.minutes - anchorMinutes;
|
|
2865
|
-
const slotOffsetFromAnchor = Math.floor(offsetFromAnchor / config.hourlyCheckIntervalMinutes) *
|
|
2866
|
-
config.hourlyCheckIntervalMinutes;
|
|
2867
|
-
const slotMinutesSinceMidnight = anchorMinutes + slotOffsetFromAnchor;
|
|
2868
|
-
const dayStartUtc = getAgentDayBoundsUtc(tz, 0, now).start;
|
|
2869
|
-
const slotStartMs = parseSqliteUtcMs(dayStartUtc) + slotMinutesSinceMidnight * 60 * 1000;
|
|
2870
|
-
const slotStartUtc = formatSqliteDatetime(new Date(slotStartMs));
|
|
2871
|
-
return !hasActionInWindow(db, "routine.hourly_check", slotStartUtc, formatSqliteDatetime(now));
|
|
2872
|
-
}
|
|
2873
|
-
function getProgressMinutesForHour(hour, dayBoundaryHour) {
|
|
2874
|
-
const scheduledMinutes = hour * 60;
|
|
2875
|
-
const boundaryMinutes = dayBoundaryHour * 60;
|
|
2876
|
-
return scheduledMinutes >= boundaryMinutes
|
|
2877
|
-
? scheduledMinutes - boundaryMinutes
|
|
2878
|
-
: 24 * 60 - boundaryMinutes + scheduledMinutes;
|
|
2879
|
-
}
|
|
2880
|
-
function hasFreshAgentDayTodayMd(todayMdPath, timezone, dayBoundaryHour) {
|
|
2881
|
-
if (!existsSync(todayMdPath)) {
|
|
2882
|
-
return false;
|
|
2883
|
-
}
|
|
2884
|
-
const firstLine = readFileSync(todayMdPath, "utf-8").split("\n")[0] ?? "";
|
|
2885
|
-
const today = getAgentDayDateStr(timezone, dayBoundaryHour);
|
|
2886
|
-
return firstLine.includes(today);
|
|
2887
|
-
}
|
|
2888
|
-
// P22 — read the operator's chosen cadence for skill curation runs.
|
|
2889
|
-
// Mirrors the helper in `core/scheduler.ts` so the dispatcher hook here can
|
|
2890
|
-
// resolve cadence at runtime without crossing module boundaries.
|
|
2891
|
-
function readSkillCurationCadence(db) {
|
|
2892
|
-
const row = db
|
|
2893
|
-
.prepare(`SELECT value_json FROM runtime_state WHERE key = 'skill_curation.config'`)
|
|
2894
|
-
.get();
|
|
2895
|
-
if (!row)
|
|
2896
|
-
return "weekly";
|
|
2897
|
-
try {
|
|
2898
|
-
const v = JSON.parse(row.value_json);
|
|
2899
|
-
return v.cadence ?? "weekly";
|
|
2900
|
-
}
|
|
2901
|
-
catch {
|
|
2902
|
-
return "weekly";
|
|
2903
|
-
}
|
|
2904
|
-
}
|
|
2448
|
+
// Catchup (`runCatchup` / `runPostMessagingCatchup`) and the pure schedule
|
|
2449
|
+
// predicates (`getDueCatchupRoutines`, `shouldCatchUpHourlyCheck`,
|
|
2450
|
+
// `getProgressMinutesForHour`, `hasFreshAgentDayTodayMd`,
|
|
2451
|
+
// `readSkillCurationCadence`) live in `./bootstrap/` — see
|
|
2452
|
+
// `docs/design/appendices/file-split-plan.md` §10. Imports are at the top
|
|
2453
|
+
// of this file.
|
|
2905
2454
|
// ── Global safety net ──
|
|
2906
2455
|
// Catch unhandled rejections from fire-and-forget patterns (void async calls)
|
|
2907
2456
|
// so they are logged before Node.js 22+ terminates the process.
|