@aitne/daemon 0.1.3 → 0.1.4
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/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 +18 -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/context.d.ts.map +1 -1
- package/dist/api/routes/context.js +13 -1
- 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 +75 -5
- package/dist/api/routes/dashboard.js.map +1 -1
- 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/integrations.d.ts +35 -6
- package/dist/api/routes/integrations.d.ts.map +1 -1
- package/dist/api/routes/integrations.js +191 -16
- 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/observations.d.ts.map +1 -1
- package/dist/api/routes/observations.js +161 -8
- 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.map +1 -1
- package/dist/api/routes/skills.js +39 -1
- 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/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/core/backends/backend-router.d.ts +23 -0
- package/dist/core/backends/backend-router.d.ts.map +1 -1
- package/dist/core/backends/backend-router.js +48 -3
- 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 +112 -1565
- 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 +831 -0
- package/dist/core/backends/claude-tool-collection.js.map +1 -0
- package/dist/core/backends/gemini-cli-core.d.ts +21 -0
- package/dist/core/backends/gemini-cli-core.d.ts.map +1 -1
- package/dist/core/backends/gemini-cli-core.js +84 -6
- package/dist/core/backends/gemini-cli-core.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/context-builder.d.ts +36 -12
- package/dist/core/context-builder.d.ts.map +1 -1
- package/dist/core/context-builder.js +179 -89
- package/dist/core/context-builder.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 +1054 -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 +434 -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 +145 -0
- package/dist/core/dispatcher-result-processor.d.ts.map +1 -0
- package/dist/core/dispatcher-result-processor.js +414 -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 +998 -0
- package/dist/core/dispatcher-scheduled-tasks.js.map +1 -0
- package/dist/core/dispatcher-types.d.ts +296 -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 +86 -610
- package/dist/core/dispatcher.d.ts.map +1 -1
- package/dist/core/dispatcher.js +293 -3542
- 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 +167 -16
- 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/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 +1 -0
- package/dist/core/prompts.d.ts.map +1 -1
- package/dist/core/prompts.js +121 -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/routine-acquisition-plan.d.ts +131 -0
- package/dist/core/routine-acquisition-plan.d.ts.map +1 -0
- package/dist/core/routine-acquisition-plan.js +268 -0
- package/dist/core/routine-acquisition-plan.js.map +1 -0
- package/dist/core/routine-fetch-window-runner.d.ts +201 -0
- package/dist/core/routine-fetch-window-runner.d.ts.map +1 -0
- package/dist/core/routine-fetch-window-runner.js +661 -0
- package/dist/core/routine-fetch-window-runner.js.map +1 -0
- package/dist/core/routine-windows.d.ts +156 -0
- package/dist/core/routine-windows.d.ts.map +1 -0
- package/dist/core/routine-windows.js +330 -0
- package/dist/core/routine-windows.js.map +1 -0
- package/dist/core/skills-compiler.d.ts +11 -0
- package/dist/core/skills-compiler.d.ts.map +1 -1
- package/dist/core/skills-compiler.js +102 -13
- 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 +26 -0
- package/dist/core/skills-manifest.js.map +1 -1
- package/dist/core/system-reset.d.ts.map +1 -1
- package/dist/core/system-reset.js +25 -2
- package/dist/core/system-reset.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 +13 -25
- package/dist/db/schema.js.map +1 -1
- package/dist/index.js +83 -610
- package/dist/index.js.map +1 -1
- package/dist/observers/delegated-sync-worker.d.ts +45 -2
- package/dist/observers/delegated-sync-worker.d.ts.map +1 -1
- package/dist/observers/delegated-sync-worker.js +71 -21
- package/dist/observers/delegated-sync-worker.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/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/package.json +2 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catchup.d.ts","sourceRoot":"","sources":["../../src/bootstrap/catchup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAO3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAc7D,MAAM,WAAW,oBAAoB;IACnC,2BAA2B,EAAE,OAAO,CAAC;IACrC,qBAAqB,EAAE,MAAM,EAAE,CAAC;IAChC,wBAAwB,EAAE,OAAO,CAAC;CACnC;AAED,wBAAsB,UAAU,CAC9B,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,UAAU,EAAE,eAAe,EAC3B,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,oBAAoB,CAAC,CAkH/B;AAED,wBAAsB,uBAAuB,CAC3C,UAAU,EAAE,eAAe,EAC3B,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,IAAI,CAAC,CAef;AAED,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,eAAe,EAC3B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CASf"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Boot-time catchup sequence — pure-move from `index.ts` per
|
|
3
|
+
* `docs/design/appendices/file-split-plan.md` §10. Pattern A: each function
|
|
4
|
+
* takes its dependencies (db, dispatcher, config) as arguments so the
|
|
5
|
+
* startup IIFE can compose them without going through `this`.
|
|
6
|
+
*
|
|
7
|
+
* Policy (unchanged from origin):
|
|
8
|
+
* - discard previous-agent-day pending tasks instead of replaying them
|
|
9
|
+
* - fail/skip orphaned running tasks instead of blindly retrying side effects
|
|
10
|
+
* - catch up same-agent-day routines only once
|
|
11
|
+
*/
|
|
12
|
+
import { join } from "node:path";
|
|
13
|
+
import { createEvent, EventPriority, getAgentDayBoundsUtc, } from "@aitne/shared";
|
|
14
|
+
import { getContextDir, isRoadmapStale } from "../config.js";
|
|
15
|
+
import { discardStalePendingSchedules, recoverOrphanedRunningSchedules, } from "../core/schedule-maintenance.js";
|
|
16
|
+
import { createLogger } from "../logging.js";
|
|
17
|
+
import { getDueCatchupRoutines, hasFreshAgentDayTodayMd, shouldCatchUpHourlyCheck, } from "./schedule-helpers.js";
|
|
18
|
+
const logger = createLogger("daemon-bootstrap-catchup");
|
|
19
|
+
export async function runCatchup(db, dispatcher, config) {
|
|
20
|
+
// Setup gate — on first boot (before rules/management.md exists) we must
|
|
21
|
+
// NOT run the morning routine. Without user/profile.md / rules/management.md
|
|
22
|
+
// the generated today.md is meaningless AND it fires
|
|
23
|
+
// onPromptContextChanged → markActiveDmSessionsStale, which destroys the
|
|
24
|
+
// dashboard setup conversation on the user's next turn. Autonomous
|
|
25
|
+
// catchup will run on the first normal boot *after* setup completes.
|
|
26
|
+
const gateReason = dispatcher.isAutonomousAllowed();
|
|
27
|
+
if (gateReason !== null) {
|
|
28
|
+
logger.info({ reason: gateReason }, "Skipping startup catchup — autonomous work paused for setup");
|
|
29
|
+
return {
|
|
30
|
+
postMessagingRoadmapRefresh: false,
|
|
31
|
+
postMessagingRoutines: [],
|
|
32
|
+
postMessagingHourlyCheck: false,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
const now = new Date();
|
|
36
|
+
const tz = config.timezone || undefined;
|
|
37
|
+
const contextDir = getContextDir(config);
|
|
38
|
+
const todayMdPath = join(contextDir, "today.md");
|
|
39
|
+
const { start: agentDayStartUtc, end: agentDayEndUtc } = getAgentDayBoundsUtc(tz, config.dayBoundaryHour, now);
|
|
40
|
+
const skippedPending = discardStalePendingSchedules(db, agentDayStartUtc);
|
|
41
|
+
if (skippedPending > 0) {
|
|
42
|
+
logger.warn({ count: skippedPending }, "Discarded stale pending schedules at startup");
|
|
43
|
+
}
|
|
44
|
+
const runningRecovery = recoverOrphanedRunningSchedules(db, agentDayStartUtc);
|
|
45
|
+
if (runningRecovery.skipped > 0 || runningRecovery.failed > 0) {
|
|
46
|
+
logger.warn(runningRecovery, "Recovered orphaned running schedules without replay");
|
|
47
|
+
}
|
|
48
|
+
// Pin to the same `now` so the day-boundary check sees a consistent
|
|
49
|
+
// clock across the catchup's pre / post freshness probes.
|
|
50
|
+
const needsMorning = !hasFreshAgentDayTodayMd(todayMdPath, tz, config.dayBoundaryHour, now);
|
|
51
|
+
const dueCatchupRoutines = getDueCatchupRoutines(db, config, agentDayStartUtc, agentDayEndUtc, now);
|
|
52
|
+
const needsHourlyCheckCatchup = shouldCatchUpHourlyCheck(db, config, now);
|
|
53
|
+
let ranMorningCatchup = false;
|
|
54
|
+
if (needsMorning) {
|
|
55
|
+
try {
|
|
56
|
+
await dispatcher.summarizeDmSessions();
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
logger.error({ err }, "DM summarization catchup failed before morning routine");
|
|
60
|
+
}
|
|
61
|
+
logger.info("Stale today.md detected, running morning_routine catchup inline");
|
|
62
|
+
await dispatcher.processInline({
|
|
63
|
+
...createEvent({
|
|
64
|
+
type: "routine.morning_routine",
|
|
65
|
+
source: "catchup",
|
|
66
|
+
priority: EventPriority.HIGH,
|
|
67
|
+
data: {
|
|
68
|
+
postCatchupRoutines: dueCatchupRoutines,
|
|
69
|
+
postCatchupHourlyCheck: needsHourlyCheckCatchup,
|
|
70
|
+
deferPostMorningCatchupsUntilStartupReady: true,
|
|
71
|
+
},
|
|
72
|
+
}),
|
|
73
|
+
routine: "morning_routine",
|
|
74
|
+
});
|
|
75
|
+
ranMorningCatchup = true;
|
|
76
|
+
if (!hasFreshAgentDayTodayMd(todayMdPath, tz, config.dayBoundaryHour)) {
|
|
77
|
+
logger.warn("Startup morning catchup did not produce a fresh today.md — deferring remaining catchup work");
|
|
78
|
+
return {
|
|
79
|
+
postMessagingRoadmapRefresh: false,
|
|
80
|
+
postMessagingRoutines: [],
|
|
81
|
+
postMessagingHourlyCheck: false,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
postMessagingRoadmapRefresh: isRoadmapStale(contextDir),
|
|
86
|
+
postMessagingRoutines: dueCatchupRoutines,
|
|
87
|
+
postMessagingHourlyCheck: needsHourlyCheckCatchup,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
if (!ranMorningCatchup && isRoadmapStale(contextDir)) {
|
|
91
|
+
logger.info("Roadmap stale at startup, running roadmap_refresh catchup inline");
|
|
92
|
+
await processRoutineCatchup(dispatcher, "roadmap_refresh");
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
postMessagingRoadmapRefresh: false,
|
|
96
|
+
postMessagingRoutines: dueCatchupRoutines,
|
|
97
|
+
postMessagingHourlyCheck: needsHourlyCheckCatchup,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
export async function runPostMessagingCatchup(dispatcher, catchup) {
|
|
101
|
+
if (catchup.postMessagingRoadmapRefresh) {
|
|
102
|
+
logger.info("Running roadmap_refresh catchup after messaging startup");
|
|
103
|
+
await processRoutineCatchup(dispatcher, "roadmap_refresh");
|
|
104
|
+
}
|
|
105
|
+
for (const routine of catchup.postMessagingRoutines) {
|
|
106
|
+
logger.info({ routine }, "Running same-day routine catchup after messaging startup");
|
|
107
|
+
await processRoutineCatchup(dispatcher, routine);
|
|
108
|
+
}
|
|
109
|
+
if (catchup.postMessagingHourlyCheck) {
|
|
110
|
+
logger.info("Triggering hourly_check catchup after messaging startup");
|
|
111
|
+
await dispatcher.triggerHourlyCheck("catchup_startup", { force: false });
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
export async function processRoutineCatchup(dispatcher, routine) {
|
|
115
|
+
await dispatcher.processInline({
|
|
116
|
+
...createEvent({
|
|
117
|
+
type: `routine.${routine}`,
|
|
118
|
+
source: "catchup",
|
|
119
|
+
priority: routine === "hourly_check" ? EventPriority.NORMAL : EventPriority.HIGH,
|
|
120
|
+
}),
|
|
121
|
+
routine,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=catchup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catchup.js","sourceRoot":"","sources":["../../src/bootstrap/catchup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure schedule predicates and progress math used by the boot-time catchup
|
|
3
|
+
* sequence in `bootstrap/catchup.ts` and by the inline routine-readiness
|
|
4
|
+
* check in `index.ts`. Pattern A pure-move from `index.ts` per
|
|
5
|
+
* `docs/design/appendices/file-split-plan.md` §10.
|
|
6
|
+
*
|
|
7
|
+
* No instance state, no captured closures. Every function takes its
|
|
8
|
+
* dependencies (db handle, config, clock) as arguments so the boot
|
|
9
|
+
* sequence can compose them without going through `this`.
|
|
10
|
+
*/
|
|
11
|
+
import type Database from "better-sqlite3";
|
|
12
|
+
import type { AgentConfig } from "../config.js";
|
|
13
|
+
export declare function getDueCatchupRoutines(db: Database.Database, config: AgentConfig, agentDayStartUtc: string, agentDayEndUtc: string, now: Date): string[];
|
|
14
|
+
export declare function shouldCatchUpHourlyCheck(db: Database.Database, config: AgentConfig, now: Date): boolean;
|
|
15
|
+
export declare function getProgressMinutesForHour(hour: number, dayBoundaryHour: number): number;
|
|
16
|
+
export declare function hasFreshAgentDayTodayMd(todayMdPath: string, timezone: string | undefined, dayBoundaryHour: number, now?: Date): boolean;
|
|
17
|
+
export declare function readSkillCurationCadence(db: Database.Database): "daily" | "weekly" | "monthly";
|
|
18
|
+
//# sourceMappingURL=schedule-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedule-helpers.d.ts","sourceRoot":"","sources":["../../src/bootstrap/schedule-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAU3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,wBAAgB,qBAAqB,CACnC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,MAAM,EAAE,WAAW,EACnB,gBAAgB,EAAE,MAAM,EACxB,cAAc,EAAE,MAAM,EACtB,GAAG,EAAE,IAAI,GACR,MAAM,EAAE,CAuCV;AAED,wBAAgB,wBAAwB,CACtC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,MAAM,EAAE,WAAW,EACnB,GAAG,EAAE,IAAI,GACR,OAAO,CAsCT;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,MAAM,CAMvF;AAED,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,eAAe,EAAE,MAAM,EACvB,GAAG,CAAC,EAAE,IAAI,GACT,OAAO,CAQT;AAKD,wBAAgB,wBAAwB,CACtC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GACpB,OAAO,GAAG,QAAQ,GAAG,SAAS,CAWhC"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure schedule predicates and progress math used by the boot-time catchup
|
|
3
|
+
* sequence in `bootstrap/catchup.ts` and by the inline routine-readiness
|
|
4
|
+
* check in `index.ts`. Pattern A pure-move from `index.ts` per
|
|
5
|
+
* `docs/design/appendices/file-split-plan.md` §10.
|
|
6
|
+
*
|
|
7
|
+
* No instance state, no captured closures. Every function takes its
|
|
8
|
+
* dependencies (db handle, config, clock) as arguments so the boot
|
|
9
|
+
* sequence can compose them without going through `this`.
|
|
10
|
+
*/
|
|
11
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
12
|
+
import { formatSqliteDatetime, getAgentDayBoundsUtc, getAgentDayDateStr, getAgentDayProgressMinutes, nowInTimezone, parseSqliteUtcMs, } from "@aitne/shared";
|
|
13
|
+
import { hasActionInWindow } from "../core/schedule-maintenance.js";
|
|
14
|
+
export function getDueCatchupRoutines(db, config, agentDayStartUtc, agentDayEndUtc, now) {
|
|
15
|
+
const tz = config.timezone || undefined;
|
|
16
|
+
const progressMinutes = getAgentDayProgressMinutes(tz, config.dayBoundaryHour, now);
|
|
17
|
+
const dueAt18 = getProgressMinutesForHour(18, config.dayBoundaryHour);
|
|
18
|
+
if (progressMinutes < dueAt18) {
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
const routines = [];
|
|
22
|
+
const agentDayStartMs = parseSqliteUtcMs(agentDayStartUtc);
|
|
23
|
+
const agentDayLocal = nowInTimezone(tz, new Date(agentDayStartMs));
|
|
24
|
+
const tomorrowLocal = nowInTimezone(tz, new Date(agentDayStartMs + 24 * 60 * 60 * 1000));
|
|
25
|
+
if (!hasActionInWindow(db, "routine.evening_review", agentDayStartUtc, agentDayEndUtc)) {
|
|
26
|
+
routines.push("evening_review");
|
|
27
|
+
}
|
|
28
|
+
if (agentDayLocal.dayOfWeek === 5 &&
|
|
29
|
+
!hasActionInWindow(db, "routine.weekly_review", agentDayStartUtc, agentDayEndUtc)) {
|
|
30
|
+
routines.push("weekly_review");
|
|
31
|
+
}
|
|
32
|
+
if (tomorrowLocal.day === 1 &&
|
|
33
|
+
!hasActionInWindow(db, "routine.monthly_review", agentDayStartUtc, agentDayEndUtc)) {
|
|
34
|
+
routines.push("monthly_review");
|
|
35
|
+
}
|
|
36
|
+
return routines;
|
|
37
|
+
}
|
|
38
|
+
export function shouldCatchUpHourlyCheck(db, config, now) {
|
|
39
|
+
if (!config.hourlyCheckEnabled) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
const tz = config.timezone || undefined;
|
|
43
|
+
const local = nowInTimezone(tz, now);
|
|
44
|
+
if (local.hours < config.hourlyCheckActiveStartHour ||
|
|
45
|
+
local.hours >= config.hourlyCheckActiveEndHour ||
|
|
46
|
+
local.hours === config.dayBoundaryHour) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
// Slot anchors to `activeStartHour`, mirroring shouldFireHourlyTickAt
|
|
50
|
+
// in scheduler.ts so the catch-up function picks the same slot the
|
|
51
|
+
// cron callback would have fired at. The earlier branch already
|
|
52
|
+
// returned false when local.hours < activeStartHour, so the offset is
|
|
53
|
+
// always non-negative here.
|
|
54
|
+
const anchorMinutes = config.hourlyCheckActiveStartHour * 60;
|
|
55
|
+
const offsetFromAnchor = local.hours * 60 + local.minutes - anchorMinutes;
|
|
56
|
+
const slotOffsetFromAnchor = Math.floor(offsetFromAnchor / config.hourlyCheckIntervalMinutes) *
|
|
57
|
+
config.hourlyCheckIntervalMinutes;
|
|
58
|
+
const slotMinutesSinceMidnight = anchorMinutes + slotOffsetFromAnchor;
|
|
59
|
+
const dayStartUtc = getAgentDayBoundsUtc(tz, 0, now).start;
|
|
60
|
+
const slotStartMs = parseSqliteUtcMs(dayStartUtc) + slotMinutesSinceMidnight * 60 * 1000;
|
|
61
|
+
const slotStartUtc = formatSqliteDatetime(new Date(slotStartMs));
|
|
62
|
+
return !hasActionInWindow(db, "routine.hourly_check", slotStartUtc, formatSqliteDatetime(now));
|
|
63
|
+
}
|
|
64
|
+
export function getProgressMinutesForHour(hour, dayBoundaryHour) {
|
|
65
|
+
const scheduledMinutes = hour * 60;
|
|
66
|
+
const boundaryMinutes = dayBoundaryHour * 60;
|
|
67
|
+
return scheduledMinutes >= boundaryMinutes
|
|
68
|
+
? scheduledMinutes - boundaryMinutes
|
|
69
|
+
: 24 * 60 - boundaryMinutes + scheduledMinutes;
|
|
70
|
+
}
|
|
71
|
+
export function hasFreshAgentDayTodayMd(todayMdPath, timezone, dayBoundaryHour, now) {
|
|
72
|
+
if (!existsSync(todayMdPath)) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
const firstLine = readFileSync(todayMdPath, "utf-8").split("\n")[0] ?? "";
|
|
76
|
+
const today = getAgentDayDateStr(timezone, dayBoundaryHour, now);
|
|
77
|
+
return firstLine.includes(today);
|
|
78
|
+
}
|
|
79
|
+
// P22 — read the operator's chosen cadence for skill curation runs.
|
|
80
|
+
// Mirrors the helper in `core/scheduler.ts` so the dispatcher hook here can
|
|
81
|
+
// resolve cadence at runtime without crossing module boundaries.
|
|
82
|
+
export function readSkillCurationCadence(db) {
|
|
83
|
+
const row = db
|
|
84
|
+
.prepare(`SELECT value_json FROM runtime_state WHERE key = 'skill_curation.config'`)
|
|
85
|
+
.get();
|
|
86
|
+
if (!row)
|
|
87
|
+
return "weekly";
|
|
88
|
+
try {
|
|
89
|
+
const v = JSON.parse(row.value_json);
|
|
90
|
+
return v.cadence ?? "weekly";
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return "weekly";
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=schedule-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedule-helpers.js","sourceRoot":"","sources":["../../src/bootstrap/schedule-helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External-service hot-reload routines — Google (calendar/gmail), Apple
|
|
3
|
+
* Calendar, Notion, GitHub.
|
|
4
|
+
*
|
|
5
|
+
* Extracted from the `startup()` IIFE in `index.ts` per
|
|
6
|
+
* `docs/design/appendices/file-split-plan.md` §10 (Tier 2, Pattern C).
|
|
7
|
+
* Goal: lift the four reload routines and the shared
|
|
8
|
+
* `refreshGoogleSecretState` helper out of the startup lambda so the
|
|
9
|
+
* lambda reads as a sequence rather than a 3,000-line bag of closures.
|
|
10
|
+
*
|
|
11
|
+
* Shape: `createServiceReloaders(deps)` is a factory that captures a
|
|
12
|
+
* `BootstrapServiceDeps` record once and returns the reload closures.
|
|
13
|
+
* Mutable state lives in two shared holders passed in via `deps`:
|
|
14
|
+
* - `services` — `ServiceRegistry` instance shared with every route,
|
|
15
|
+
* observer, and the context builder. Reload routines write
|
|
16
|
+
* `services.calendar` / `services.gmail` / ... and the corresponding
|
|
17
|
+
* `services.errors.<key>` entries.
|
|
18
|
+
* - `secretState` — read by `/api/health.integrations` and observer
|
|
19
|
+
* start gates. Reload routines update the corresponding boolean +
|
|
20
|
+
* Google credential-type field.
|
|
21
|
+
*
|
|
22
|
+
* Both holders are passed by reference; reading them after a reload
|
|
23
|
+
* completes observes the post-reload values, exactly matching the
|
|
24
|
+
* pre-extraction inlined behavior.
|
|
25
|
+
*/
|
|
26
|
+
import type Database from "better-sqlite3";
|
|
27
|
+
import type { AgentConfig } from "../config.js";
|
|
28
|
+
import type { SecretBroker } from "../secrets/secret-broker.js";
|
|
29
|
+
import type { ServiceRegistry } from "../services/service-registry.js";
|
|
30
|
+
import { type GoogleCredentialType } from "../services/google-auth.js";
|
|
31
|
+
/**
|
|
32
|
+
* Mutable holder for the per-service "is configured" booleans + the
|
|
33
|
+
* Google credential type. Read by `/api/health.integrations` and the
|
|
34
|
+
* observer start gates; written by the reload routines.
|
|
35
|
+
*/
|
|
36
|
+
export interface BootstrapSecretState {
|
|
37
|
+
googleCredentialsConfigured: boolean;
|
|
38
|
+
googleTokenConfigured: boolean;
|
|
39
|
+
googleCredentialType: GoogleCredentialType | null;
|
|
40
|
+
notionConfigured: boolean;
|
|
41
|
+
githubConfigured: boolean;
|
|
42
|
+
githubWebhookConfigured: boolean;
|
|
43
|
+
}
|
|
44
|
+
export declare function createInitialSecretState(): BootstrapSecretState;
|
|
45
|
+
export interface BootstrapServiceDeps {
|
|
46
|
+
readonly db: Database.Database;
|
|
47
|
+
readonly config: AgentConfig;
|
|
48
|
+
readonly secretBroker: SecretBroker;
|
|
49
|
+
readonly services: ServiceRegistry;
|
|
50
|
+
readonly secretState: BootstrapSecretState;
|
|
51
|
+
}
|
|
52
|
+
export interface ServiceReloaders {
|
|
53
|
+
refreshGoogleSecretState(): Promise<void>;
|
|
54
|
+
reloadGoogleServices(): Promise<void>;
|
|
55
|
+
reloadAppleCalendarService(): Promise<void>;
|
|
56
|
+
reloadNotionService(): Promise<void>;
|
|
57
|
+
reloadGitHubService(): Promise<void>;
|
|
58
|
+
}
|
|
59
|
+
export declare function createServiceReloaders(deps: BootstrapServiceDeps): ServiceReloaders;
|
|
60
|
+
//# sourceMappingURL=services.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"services.d.ts","sourceRoot":"","sources":["../../src/bootstrap/services.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAIvE,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,4BAA4B,CAAC;AAWpC;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,2BAA2B,EAAE,OAAO,CAAC;IACrC,qBAAqB,EAAE,OAAO,CAAC;IAC/B,oBAAoB,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAClD,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,uBAAuB,EAAE,OAAO,CAAC;CAClC;AAED,wBAAgB,wBAAwB,IAAI,oBAAoB,CAS/D;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;IACnC,QAAQ,CAAC,WAAW,EAAE,oBAAoB,CAAC;CAC5C;AAED,MAAM,WAAW,gBAAgB;IAC/B,wBAAwB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,0BAA0B,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC;AAED,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,oBAAoB,GACzB,gBAAgB,CAyKlB"}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External-service hot-reload routines — Google (calendar/gmail), Apple
|
|
3
|
+
* Calendar, Notion, GitHub.
|
|
4
|
+
*
|
|
5
|
+
* Extracted from the `startup()` IIFE in `index.ts` per
|
|
6
|
+
* `docs/design/appendices/file-split-plan.md` §10 (Tier 2, Pattern C).
|
|
7
|
+
* Goal: lift the four reload routines and the shared
|
|
8
|
+
* `refreshGoogleSecretState` helper out of the startup lambda so the
|
|
9
|
+
* lambda reads as a sequence rather than a 3,000-line bag of closures.
|
|
10
|
+
*
|
|
11
|
+
* Shape: `createServiceReloaders(deps)` is a factory that captures a
|
|
12
|
+
* `BootstrapServiceDeps` record once and returns the reload closures.
|
|
13
|
+
* Mutable state lives in two shared holders passed in via `deps`:
|
|
14
|
+
* - `services` — `ServiceRegistry` instance shared with every route,
|
|
15
|
+
* observer, and the context builder. Reload routines write
|
|
16
|
+
* `services.calendar` / `services.gmail` / ... and the corresponding
|
|
17
|
+
* `services.errors.<key>` entries.
|
|
18
|
+
* - `secretState` — read by `/api/health.integrations` and observer
|
|
19
|
+
* start gates. Reload routines update the corresponding boolean +
|
|
20
|
+
* Google credential-type field.
|
|
21
|
+
*
|
|
22
|
+
* Both holders are passed by reference; reading them after a reload
|
|
23
|
+
* completes observes the post-reload values, exactly matching the
|
|
24
|
+
* pre-extraction inlined behavior.
|
|
25
|
+
*/
|
|
26
|
+
import { CalendarService } from "../services/calendar.js";
|
|
27
|
+
import { AppleCalendarService } from "../services/apple-calendar/index.js";
|
|
28
|
+
import { GmailService } from "../services/gmail.js";
|
|
29
|
+
import { detectGoogleCredentialType, } from "../services/google-auth.js";
|
|
30
|
+
import { NotionService } from "../services/notion.js";
|
|
31
|
+
import { GitHubService } from "../services/github.js";
|
|
32
|
+
import { ensureLegacyGmailRow, syncLegacyGmailAccountState, } from "../services/mail/gmail/legacy-row.js";
|
|
33
|
+
import { createLogger } from "../logging.js";
|
|
34
|
+
const logger = createLogger("daemon-bootstrap-services");
|
|
35
|
+
export function createInitialSecretState() {
|
|
36
|
+
return {
|
|
37
|
+
googleCredentialsConfigured: false,
|
|
38
|
+
googleTokenConfigured: false,
|
|
39
|
+
googleCredentialType: null,
|
|
40
|
+
notionConfigured: false,
|
|
41
|
+
githubConfigured: false,
|
|
42
|
+
githubWebhookConfigured: false,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export function createServiceReloaders(deps) {
|
|
46
|
+
const { db, config, secretBroker, services, secretState } = deps;
|
|
47
|
+
async function refreshGoogleSecretState() {
|
|
48
|
+
const [credentialsRaw, tokenRaw] = await Promise.all([
|
|
49
|
+
secretBroker.getGoogleCredentialsJson(),
|
|
50
|
+
secretBroker.getGoogleTokenJson(),
|
|
51
|
+
]);
|
|
52
|
+
secretState.googleCredentialsConfigured = !!credentialsRaw;
|
|
53
|
+
secretState.googleTokenConfigured = !!tokenRaw;
|
|
54
|
+
secretState.googleCredentialType = detectGoogleCredentialType(credentialsRaw);
|
|
55
|
+
}
|
|
56
|
+
async function reloadGoogleServices() {
|
|
57
|
+
await refreshGoogleSecretState();
|
|
58
|
+
services.calendar = null;
|
|
59
|
+
services.gmail = null;
|
|
60
|
+
delete services.errors.googleCalendar;
|
|
61
|
+
delete services.errors.gmail;
|
|
62
|
+
if (!secretState.googleCredentialsConfigured) {
|
|
63
|
+
if (services.mail) {
|
|
64
|
+
syncLegacyGmailAccountState(db, services.mail, {
|
|
65
|
+
available: false,
|
|
66
|
+
error: "Google credentials are not configured.",
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
// OAuth2 pre-auth: credentials uploaded but the user has not completed the
|
|
72
|
+
// browser flow yet (no token in the keychain). Initializing the services
|
|
73
|
+
// would fail with a "missing token" error that the dashboard would then
|
|
74
|
+
// render as red "Error" under the Google card — but this is the expected
|
|
75
|
+
// mid-setup state, not a failure. Skip init and leave services.errors
|
|
76
|
+
// unset so /health reports error: null until the user finishes OAuth or a
|
|
77
|
+
// real init error occurs.
|
|
78
|
+
const oauth2PreAuth = secretState.googleCredentialType === "oauth2"
|
|
79
|
+
&& !secretState.googleTokenConfigured;
|
|
80
|
+
if (oauth2PreAuth) {
|
|
81
|
+
if (services.mail) {
|
|
82
|
+
syncLegacyGmailAccountState(db, services.mail, {
|
|
83
|
+
available: false,
|
|
84
|
+
error: "Awaiting Google OAuth authorization.",
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
const calendarService = new CalendarService(config, secretBroker);
|
|
90
|
+
try {
|
|
91
|
+
await calendarService.init();
|
|
92
|
+
services.calendar = calendarService;
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
const msg = err.message;
|
|
96
|
+
logger.error({ error: msg }, "Calendar service init failed, continuing without it");
|
|
97
|
+
services.errors.googleCalendar = msg;
|
|
98
|
+
}
|
|
99
|
+
const gmailService = new GmailService(secretBroker);
|
|
100
|
+
try {
|
|
101
|
+
await gmailService.init();
|
|
102
|
+
services.gmail = gmailService;
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
const msg = err.message;
|
|
106
|
+
logger.error({ error: msg }, "Gmail service init failed, continuing without it");
|
|
107
|
+
services.errors.gmail = msg;
|
|
108
|
+
}
|
|
109
|
+
// Ensure the shared-Google-OAuth Gmail identity exists as a unified
|
|
110
|
+
// mail account (idempotent; returns `exists` on subsequent boots).
|
|
111
|
+
if (services.gmail?.available) {
|
|
112
|
+
try {
|
|
113
|
+
await ensureLegacyGmailRow(db, services.gmail);
|
|
114
|
+
}
|
|
115
|
+
catch (err) {
|
|
116
|
+
logger.error({ err }, "Failed to ensure shared-Google-OAuth Gmail mail_accounts row");
|
|
117
|
+
}
|
|
118
|
+
if (services.mail) {
|
|
119
|
+
syncLegacyGmailAccountState(db, services.mail, { available: true });
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
else if (services.mail) {
|
|
123
|
+
syncLegacyGmailAccountState(db, services.mail, {
|
|
124
|
+
available: false,
|
|
125
|
+
error: services.errors.gmail ?? "Gmail is not configured.",
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
async function reloadAppleCalendarService() {
|
|
130
|
+
const raw = await secretBroker.getAppleCalendarCredentialsJson();
|
|
131
|
+
services.appleCalendar = null;
|
|
132
|
+
delete services.errors.appleCalendar;
|
|
133
|
+
if (!raw) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
const service = new AppleCalendarService(secretBroker);
|
|
137
|
+
try {
|
|
138
|
+
await service.init();
|
|
139
|
+
if (service.available) {
|
|
140
|
+
services.appleCalendar = service;
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
// Surface the underlying iCloud error verbatim — the dashboard
|
|
144
|
+
// shows it on the Connections card so the user can act
|
|
145
|
+
// (`401 Unauthorized` → regenerate password; network error →
|
|
146
|
+
// retry; etc.). Falls back to a generic placeholder only if
|
|
147
|
+
// init() failed without recording a message.
|
|
148
|
+
services.errors.appleCalendar =
|
|
149
|
+
service.initError
|
|
150
|
+
?? "Apple Calendar credentials present but iCloud discovery did not return a usable calendar — verify the app-specific password.";
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
catch (err) {
|
|
154
|
+
const msg = err.message;
|
|
155
|
+
logger.error({ error: msg }, "Apple Calendar service init failed, continuing without it");
|
|
156
|
+
services.errors.appleCalendar = msg;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
async function reloadNotionService() {
|
|
160
|
+
const apiKey = await secretBroker.getNotionApiKey();
|
|
161
|
+
secretState.notionConfigured = !!apiKey;
|
|
162
|
+
services.notion = null;
|
|
163
|
+
delete services.errors.notion;
|
|
164
|
+
if (!apiKey) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
const notionService = new NotionService(config, secretBroker);
|
|
168
|
+
try {
|
|
169
|
+
await notionService.init();
|
|
170
|
+
services.notion = notionService;
|
|
171
|
+
}
|
|
172
|
+
catch (err) {
|
|
173
|
+
const msg = err.message;
|
|
174
|
+
logger.error({ error: msg }, "Notion service init failed, continuing without it");
|
|
175
|
+
services.errors.notion = msg;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
async function reloadGitHubService() {
|
|
179
|
+
const [token, webhookSecret] = await Promise.all([
|
|
180
|
+
secretBroker.getGitHubToken(),
|
|
181
|
+
secretBroker.getGitHubWebhookSecret(),
|
|
182
|
+
]);
|
|
183
|
+
secretState.githubConfigured = !!token;
|
|
184
|
+
secretState.githubWebhookConfigured = !!webhookSecret;
|
|
185
|
+
services.github = null;
|
|
186
|
+
delete services.errors.github;
|
|
187
|
+
if (!token) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
const githubService = new GitHubService(token, webhookSecret);
|
|
191
|
+
try {
|
|
192
|
+
await githubService.init();
|
|
193
|
+
services.github = githubService;
|
|
194
|
+
}
|
|
195
|
+
catch (err) {
|
|
196
|
+
const msg = err.message;
|
|
197
|
+
logger.error({ error: msg }, "GitHub service init failed, continuing without it");
|
|
198
|
+
services.errors.github = msg;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return {
|
|
202
|
+
refreshGoogleSecretState,
|
|
203
|
+
reloadGoogleServices,
|
|
204
|
+
reloadAppleCalendarService,
|
|
205
|
+
reloadNotionService,
|
|
206
|
+
reloadGitHubService,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
//# sourceMappingURL=services.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"services.js","sourceRoot":"","sources":["../../src/bootstrap/services.ts"],"names":[],"mappings":"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"}
|
|
@@ -232,6 +232,29 @@ export declare class BackendRouter implements IAgentRouter {
|
|
|
232
232
|
* Missing `backendConnectors[fallbackBackend]` → no connector → drop.
|
|
233
233
|
*/
|
|
234
234
|
private refineFallbackForDelegation;
|
|
235
|
+
/**
|
|
236
|
+
* INTEGRATION_NATIVE_MODE_DESIGN.md §10.1 — native fallback gate.
|
|
237
|
+
*
|
|
238
|
+
* Native mode pins the integration to a specific backend (`nativeBackend`).
|
|
239
|
+
* The data path is the backend's own MCP — there is no proxy. So a
|
|
240
|
+
* fallback whose `backendId` differs from `nativeBackend` cannot serve
|
|
241
|
+
* the ProcessKey: it lacks the connector entirely and the daemon route
|
|
242
|
+
* is 410-gated in native mode (§9.1). Drop the fallback rather than
|
|
243
|
+
* silently route into a half-functional backend.
|
|
244
|
+
*
|
|
245
|
+
* This is stricter than the delegated gate above: delegated cross-backend
|
|
246
|
+
* routes daemon-side via `/api/integrations/:key/exec`, so a fallback
|
|
247
|
+
* with the right descriptor connector entry is still serviceable.
|
|
248
|
+
* Native has no such proxy fallback, hence equality on `nativeBackend`
|
|
249
|
+
* is the contract.
|
|
250
|
+
*/
|
|
251
|
+
private refineFallbackForNative;
|
|
252
|
+
/**
|
|
253
|
+
* Chain `refineFallbackForDelegation` + `refineFallbackForNative` —
|
|
254
|
+
* a fallback that any one of the gates drops stays dropped. Single
|
|
255
|
+
* helper so the two call sites stay 1-line.
|
|
256
|
+
*/
|
|
257
|
+
private refineFallback;
|
|
235
258
|
private tierFromModelId;
|
|
236
259
|
/**
|
|
237
260
|
* Pick a canonical model for (backendId, tier) when the caller requests an
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backend-router.d.ts","sourceRoot":"","sources":["../../../src/core/backends/backend-router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EACV,WAAW,EACX,SAAS,EACT,KAAK,EAEL,UAAU,EACV,gBAAgB,EACjB,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"backend-router.d.ts","sourceRoot":"","sources":["../../../src/core/backends/backend-router.ts"],"names":[],"mappings":"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"}
|