@aitne/daemon 0.1.2 → 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.
Files changed (253) hide show
  1. package/LICENSE +21 -0
  2. package/dist/adapters/whatsapp-adapter.d.ts.map +1 -1
  3. package/dist/adapters/whatsapp-adapter.js +0 -1
  4. package/dist/adapters/whatsapp-adapter.js.map +1 -1
  5. package/dist/api/integration-route-gate.d.ts +15 -11
  6. package/dist/api/integration-route-gate.d.ts.map +1 -1
  7. package/dist/api/integration-route-gate.js +60 -23
  8. package/dist/api/integration-route-gate.js.map +1 -1
  9. package/dist/api/json-body.d.ts +22 -7
  10. package/dist/api/json-body.d.ts.map +1 -1
  11. package/dist/api/json-body.js +27 -8
  12. package/dist/api/json-body.js.map +1 -1
  13. package/dist/api/routes/agent.d.ts.map +1 -1
  14. package/dist/api/routes/agent.js +18 -0
  15. package/dist/api/routes/agent.js.map +1 -1
  16. package/dist/api/routes/backends.d.ts.map +1 -1
  17. package/dist/api/routes/backends.js +96 -1
  18. package/dist/api/routes/backends.js.map +1 -1
  19. package/dist/api/routes/books.js +1 -1
  20. package/dist/api/routes/books.js.map +1 -1
  21. package/dist/api/routes/context.d.ts.map +1 -1
  22. package/dist/api/routes/context.js +13 -1
  23. package/dist/api/routes/context.js.map +1 -1
  24. package/dist/api/routes/dashboard.d.ts.map +1 -1
  25. package/dist/api/routes/dashboard.js +75 -5
  26. package/dist/api/routes/dashboard.js.map +1 -1
  27. package/dist/api/routes/github.d.ts.map +1 -1
  28. package/dist/api/routes/github.js +38 -5
  29. package/dist/api/routes/github.js.map +1 -1
  30. package/dist/api/routes/integrations.d.ts +35 -6
  31. package/dist/api/routes/integrations.d.ts.map +1 -1
  32. package/dist/api/routes/integrations.js +191 -16
  33. package/dist/api/routes/integrations.js.map +1 -1
  34. package/dist/api/routes/mail.d.ts.map +1 -1
  35. package/dist/api/routes/mail.js +112 -46
  36. package/dist/api/routes/mail.js.map +1 -1
  37. package/dist/api/routes/observations.d.ts.map +1 -1
  38. package/dist/api/routes/observations.js +161 -8
  39. package/dist/api/routes/observations.js.map +1 -1
  40. package/dist/api/routes/setup-migrate.d.ts +9 -1
  41. package/dist/api/routes/setup-migrate.d.ts.map +1 -1
  42. package/dist/api/routes/setup-migrate.js +4 -2
  43. package/dist/api/routes/setup-migrate.js.map +1 -1
  44. package/dist/api/routes/skills.d.ts.map +1 -1
  45. package/dist/api/routes/skills.js +39 -1
  46. package/dist/api/routes/skills.js.map +1 -1
  47. package/dist/api/routes/voice.d.ts.map +1 -1
  48. package/dist/api/routes/voice.js +154 -14
  49. package/dist/api/routes/voice.js.map +1 -1
  50. package/dist/bootstrap/adapters.d.ts +109 -0
  51. package/dist/bootstrap/adapters.d.ts.map +1 -0
  52. package/dist/bootstrap/adapters.js +237 -0
  53. package/dist/bootstrap/adapters.js.map +1 -0
  54. package/dist/bootstrap/catchup.d.ts +23 -0
  55. package/dist/bootstrap/catchup.d.ts.map +1 -0
  56. package/dist/bootstrap/catchup.js +124 -0
  57. package/dist/bootstrap/catchup.js.map +1 -0
  58. package/dist/bootstrap/schedule-helpers.d.ts +18 -0
  59. package/dist/bootstrap/schedule-helpers.d.ts.map +1 -0
  60. package/dist/bootstrap/schedule-helpers.js +96 -0
  61. package/dist/bootstrap/schedule-helpers.js.map +1 -0
  62. package/dist/bootstrap/services.d.ts +60 -0
  63. package/dist/bootstrap/services.d.ts.map +1 -0
  64. package/dist/bootstrap/services.js +209 -0
  65. package/dist/bootstrap/services.js.map +1 -0
  66. package/dist/core/backends/backend-router.d.ts +23 -0
  67. package/dist/core/backends/backend-router.d.ts.map +1 -1
  68. package/dist/core/backends/backend-router.js +48 -3
  69. package/dist/core/backends/backend-router.js.map +1 -1
  70. package/dist/core/backends/claude-auth.d.ts +70 -0
  71. package/dist/core/backends/claude-auth.d.ts.map +1 -0
  72. package/dist/core/backends/claude-auth.js +198 -0
  73. package/dist/core/backends/claude-auth.js.map +1 -0
  74. package/dist/core/backends/claude-code-core.d.ts +47 -119
  75. package/dist/core/backends/claude-code-core.d.ts.map +1 -1
  76. package/dist/core/backends/claude-code-core.js +112 -1565
  77. package/dist/core/backends/claude-code-core.js.map +1 -1
  78. package/dist/core/backends/claude-delegated.d.ts +86 -0
  79. package/dist/core/backends/claude-delegated.d.ts.map +1 -0
  80. package/dist/core/backends/claude-delegated.js +801 -0
  81. package/dist/core/backends/claude-delegated.js.map +1 -0
  82. package/dist/core/backends/claude-errors.d.ts +39 -0
  83. package/dist/core/backends/claude-errors.d.ts.map +1 -0
  84. package/dist/core/backends/claude-errors.js +71 -0
  85. package/dist/core/backends/claude-errors.js.map +1 -0
  86. package/dist/core/backends/claude-probe.d.ts +103 -0
  87. package/dist/core/backends/claude-probe.d.ts.map +1 -0
  88. package/dist/core/backends/claude-probe.js +336 -0
  89. package/dist/core/backends/claude-probe.js.map +1 -0
  90. package/dist/core/backends/claude-tool-collection.d.ts +135 -0
  91. package/dist/core/backends/claude-tool-collection.d.ts.map +1 -0
  92. package/dist/core/backends/claude-tool-collection.js +831 -0
  93. package/dist/core/backends/claude-tool-collection.js.map +1 -0
  94. package/dist/core/backends/gemini-cli-core.d.ts +21 -0
  95. package/dist/core/backends/gemini-cli-core.d.ts.map +1 -1
  96. package/dist/core/backends/gemini-cli-core.js +84 -6
  97. package/dist/core/backends/gemini-cli-core.js.map +1 -1
  98. package/dist/core/backends/prompt-utils.d.ts +1 -0
  99. package/dist/core/backends/prompt-utils.d.ts.map +1 -1
  100. package/dist/core/backends/prompt-utils.js +60 -3
  101. package/dist/core/backends/prompt-utils.js.map +1 -1
  102. package/dist/core/context-builder.d.ts +36 -12
  103. package/dist/core/context-builder.d.ts.map +1 -1
  104. package/dist/core/context-builder.js +179 -89
  105. package/dist/core/context-builder.js.map +1 -1
  106. package/dist/core/dispatcher-date-utils.d.ts +49 -0
  107. package/dist/core/dispatcher-date-utils.d.ts.map +1 -0
  108. package/dist/core/dispatcher-date-utils.js +132 -0
  109. package/dist/core/dispatcher-date-utils.js.map +1 -0
  110. package/dist/core/dispatcher-error-handling.d.ts +159 -0
  111. package/dist/core/dispatcher-error-handling.d.ts.map +1 -0
  112. package/dist/core/dispatcher-error-handling.js +393 -0
  113. package/dist/core/dispatcher-error-handling.js.map +1 -0
  114. package/dist/core/dispatcher-hourly-check.d.ts +150 -0
  115. package/dist/core/dispatcher-hourly-check.d.ts.map +1 -0
  116. package/dist/core/dispatcher-hourly-check.js +665 -0
  117. package/dist/core/dispatcher-hourly-check.js.map +1 -0
  118. package/dist/core/dispatcher-message-handler.d.ts +170 -0
  119. package/dist/core/dispatcher-message-handler.d.ts.map +1 -0
  120. package/dist/core/dispatcher-message-handler.js +1054 -0
  121. package/dist/core/dispatcher-message-handler.js.map +1 -0
  122. package/dist/core/dispatcher-morning-routine.d.ts +169 -0
  123. package/dist/core/dispatcher-morning-routine.d.ts.map +1 -0
  124. package/dist/core/dispatcher-morning-routine.js +434 -0
  125. package/dist/core/dispatcher-morning-routine.js.map +1 -0
  126. package/dist/core/dispatcher-prompt.d.ts +107 -0
  127. package/dist/core/dispatcher-prompt.d.ts.map +1 -0
  128. package/dist/core/dispatcher-prompt.js +227 -0
  129. package/dist/core/dispatcher-prompt.js.map +1 -0
  130. package/dist/core/dispatcher-repository-helpers.d.ts +39 -0
  131. package/dist/core/dispatcher-repository-helpers.d.ts.map +1 -0
  132. package/dist/core/dispatcher-repository-helpers.js +86 -0
  133. package/dist/core/dispatcher-repository-helpers.js.map +1 -0
  134. package/dist/core/dispatcher-result-processor.d.ts +145 -0
  135. package/dist/core/dispatcher-result-processor.d.ts.map +1 -0
  136. package/dist/core/dispatcher-result-processor.js +414 -0
  137. package/dist/core/dispatcher-result-processor.js.map +1 -0
  138. package/dist/core/dispatcher-scheduled-tasks.d.ts +406 -0
  139. package/dist/core/dispatcher-scheduled-tasks.d.ts.map +1 -0
  140. package/dist/core/dispatcher-scheduled-tasks.js +998 -0
  141. package/dist/core/dispatcher-scheduled-tasks.js.map +1 -0
  142. package/dist/core/dispatcher-types.d.ts +296 -0
  143. package/dist/core/dispatcher-types.d.ts.map +1 -0
  144. package/dist/core/dispatcher-types.js +106 -0
  145. package/dist/core/dispatcher-types.js.map +1 -0
  146. package/dist/core/dispatcher.d.ts +86 -610
  147. package/dist/core/dispatcher.d.ts.map +1 -1
  148. package/dist/core/dispatcher.js +293 -3542
  149. package/dist/core/dispatcher.js.map +1 -1
  150. package/dist/core/integration-health.d.ts +18 -10
  151. package/dist/core/integration-health.d.ts.map +1 -1
  152. package/dist/core/integration-health.js +31 -1
  153. package/dist/core/integration-health.js.map +1 -1
  154. package/dist/core/integration-lifecycle.d.ts +65 -0
  155. package/dist/core/integration-lifecycle.d.ts.map +1 -1
  156. package/dist/core/integration-lifecycle.js +167 -16
  157. package/dist/core/integration-lifecycle.js.map +1 -1
  158. package/dist/core/integration-main-backend.d.ts +40 -0
  159. package/dist/core/integration-main-backend.d.ts.map +1 -1
  160. package/dist/core/integration-main-backend.js +89 -2
  161. package/dist/core/integration-main-backend.js.map +1 -1
  162. package/dist/core/management-md.d.ts +51 -17
  163. package/dist/core/management-md.d.ts.map +1 -1
  164. package/dist/core/management-md.js +233 -56
  165. package/dist/core/management-md.js.map +1 -1
  166. package/dist/core/output-language-policy.d.ts +74 -0
  167. package/dist/core/output-language-policy.d.ts.map +1 -0
  168. package/dist/core/output-language-policy.js +194 -0
  169. package/dist/core/output-language-policy.js.map +1 -0
  170. package/dist/core/prompts.d.ts +1 -0
  171. package/dist/core/prompts.d.ts.map +1 -1
  172. package/dist/core/prompts.js +121 -3
  173. package/dist/core/prompts.js.map +1 -1
  174. package/dist/core/repository-management-docs.d.ts +24 -0
  175. package/dist/core/repository-management-docs.d.ts.map +1 -1
  176. package/dist/core/repository-management-docs.js +210 -26
  177. package/dist/core/repository-management-docs.js.map +1 -1
  178. package/dist/core/routine-acquisition-plan.d.ts +131 -0
  179. package/dist/core/routine-acquisition-plan.d.ts.map +1 -0
  180. package/dist/core/routine-acquisition-plan.js +268 -0
  181. package/dist/core/routine-acquisition-plan.js.map +1 -0
  182. package/dist/core/routine-fetch-window-runner.d.ts +201 -0
  183. package/dist/core/routine-fetch-window-runner.d.ts.map +1 -0
  184. package/dist/core/routine-fetch-window-runner.js +661 -0
  185. package/dist/core/routine-fetch-window-runner.js.map +1 -0
  186. package/dist/core/routine-windows.d.ts +156 -0
  187. package/dist/core/routine-windows.d.ts.map +1 -0
  188. package/dist/core/routine-windows.js +330 -0
  189. package/dist/core/routine-windows.js.map +1 -0
  190. package/dist/core/skills-compiler.d.ts +11 -0
  191. package/dist/core/skills-compiler.d.ts.map +1 -1
  192. package/dist/core/skills-compiler.js +102 -13
  193. package/dist/core/skills-compiler.js.map +1 -1
  194. package/dist/core/skills-manifest.d.ts.map +1 -1
  195. package/dist/core/skills-manifest.js +26 -0
  196. package/dist/core/skills-manifest.js.map +1 -1
  197. package/dist/core/system-reset.d.ts.map +1 -1
  198. package/dist/core/system-reset.js +25 -2
  199. package/dist/core/system-reset.js.map +1 -1
  200. package/dist/db/observations.d.ts +45 -2
  201. package/dist/db/observations.d.ts.map +1 -1
  202. package/dist/db/observations.js +112 -14
  203. package/dist/db/observations.js.map +1 -1
  204. package/dist/db/schema.d.ts.map +1 -1
  205. package/dist/db/schema.js +13 -25
  206. package/dist/db/schema.js.map +1 -1
  207. package/dist/index.js +83 -610
  208. package/dist/index.js.map +1 -1
  209. package/dist/observers/delegated-sync-worker.d.ts +45 -2
  210. package/dist/observers/delegated-sync-worker.d.ts.map +1 -1
  211. package/dist/observers/delegated-sync-worker.js +71 -21
  212. package/dist/observers/delegated-sync-worker.js.map +1 -1
  213. package/dist/observers/mail-poller.d.ts +12 -5
  214. package/dist/observers/mail-poller.d.ts.map +1 -1
  215. package/dist/observers/mail-poller.js +36 -14
  216. package/dist/observers/mail-poller.js.map +1 -1
  217. package/dist/observers/manager.d.ts +37 -5
  218. package/dist/observers/manager.d.ts.map +1 -1
  219. package/dist/observers/manager.js +28 -10
  220. package/dist/observers/manager.js.map +1 -1
  221. package/dist/safety/risk-classifier.d.ts.map +1 -1
  222. package/dist/safety/risk-classifier.js +5 -0
  223. package/dist/safety/risk-classifier.js.map +1 -1
  224. package/dist/services/delegated-backend-invoker.d.ts +1 -51
  225. package/dist/services/delegated-backend-invoker.d.ts.map +1 -1
  226. package/dist/services/delegated-backend-invoker.js +41 -480
  227. package/dist/services/delegated-backend-invoker.js.map +1 -1
  228. package/dist/services/delegated-invoker-audit.d.ts +94 -0
  229. package/dist/services/delegated-invoker-audit.d.ts.map +1 -0
  230. package/dist/services/delegated-invoker-audit.js +238 -0
  231. package/dist/services/delegated-invoker-audit.js.map +1 -0
  232. package/dist/services/delegated-invoker-cache-hits.d.ts +34 -0
  233. package/dist/services/delegated-invoker-cache-hits.d.ts.map +1 -0
  234. package/dist/services/delegated-invoker-cache-hits.js +104 -0
  235. package/dist/services/delegated-invoker-cache-hits.js.map +1 -0
  236. package/dist/services/delegated-invoker-janitors.d.ts +28 -0
  237. package/dist/services/delegated-invoker-janitors.d.ts.map +1 -0
  238. package/dist/services/delegated-invoker-janitors.js +104 -0
  239. package/dist/services/delegated-invoker-janitors.js.map +1 -0
  240. package/dist/services/delegated-invoker-utils.d.ts +42 -0
  241. package/dist/services/delegated-invoker-utils.d.ts.map +1 -0
  242. package/dist/services/delegated-invoker-utils.js +100 -0
  243. package/dist/services/delegated-invoker-utils.js.map +1 -0
  244. package/dist/services/delegated-task-runtime.d.ts +1 -1
  245. package/dist/services/delegated-task-runtime.js +1 -1
  246. package/dist/services/integrations/snapshot-partitions.d.ts +5 -0
  247. package/dist/services/integrations/snapshot-partitions.d.ts.map +1 -1
  248. package/dist/services/integrations/snapshot-partitions.js +12 -0
  249. package/dist/services/integrations/snapshot-partitions.js.map +1 -1
  250. package/dist/services/voice/transcriber-impl.d.ts.map +1 -1
  251. package/dist/services/voice/transcriber-impl.js +46 -0
  252. package/dist/services/voice/transcriber-impl.js.map +1 -1
  253. package/package.json +12 -12
@@ -1,7 +1,8 @@
1
1
  import { INTEGRATION_DESCRIPTORS, } from "@aitne/shared";
2
2
  import { readIntegrationState } from "../db/integrations-store.js";
3
+ import { deleteRuntimeState, readRuntimeState, writeRuntimeState, } from "../db/runtime-state.js";
3
4
  import { createLogger } from "../logging.js";
4
- import { DELEGATED_SYNC_OBSERVER_NAME, hasActiveDelegatedSyncIntegration, } from "../observers/delegated-sync-worker.js";
5
+ import { DELEGATED_SYNC_OBSERVER_NAME, hasActiveCadenceSyncIntegration, } from "../observers/delegated-sync-worker.js";
5
6
  import { GIT_DELEGATED_CRON_OBSERVER_NAME, hasActiveDelegatedGitLifecycleIntegration, } from "../observers/git-delegated-cron.js";
6
7
  import { purgeStaleSnapshotPartitions } from "../services/integrations/snapshot-partitions.js";
7
8
  const logger = createLogger("integration-lifecycle");
@@ -14,6 +15,15 @@ const logger = createLogger("integration-lifecycle");
14
15
  * with the PATCH route handler so the lifecycle module is a thin,
15
16
  * testable orchestrator.
16
17
  *
18
+ * INTEGRATION_NATIVE_MODE_DESIGN.md §11.3 extends the same path to cover
19
+ * the new `native` boundary transitions (`direct ↔ native`,
20
+ * `delegated ↔ native`, `native ↔ disabled`). No new observer is started
21
+ * for `native` — the agent reaches the connector directly through the
22
+ * main backend's MCP — so the existing direct-flip observer gate is
23
+ * sufficient. Workdir re-materialization fires on every mode change so
24
+ * the per-session SKILL.*.md / task-flow variant is refreshed before the
25
+ * next turn.
26
+ *
17
27
  * Idempotent: re-running with the same `prev`/`next` does the same set
18
28
  * of starts/stops (which `ObserverManager.registerAndStart` /
19
29
  * `stopAndUnregister` themselves no-op when state already matches) and
@@ -39,10 +49,24 @@ export async function applyIntegrationModeChange(deps, key, prev, next) {
39
49
  }
40
50
  }
41
51
  else {
42
- const removed = await deps.observerManager.stopAndUnregister(observerName);
43
- logger.info({ key, observerName, removed }, removed
44
- ? "Stopped observer after integration left direct mode"
45
- : "No observer to stop already absent");
52
+ const result = await deps.observerManager.stopAndUnregister(observerName);
53
+ switch (result.status) {
54
+ case "removed":
55
+ logger.info({ key, observerName }, "Stopped observer after integration left direct mode");
56
+ break;
57
+ case "absent":
58
+ logger.info({ key, observerName }, "No observer to stop — already absent");
59
+ break;
60
+ case "stop_failed":
61
+ // Observer stayed in the registry; the next mode-change
62
+ // cycle (or daemon shutdown's stopAll) will retry. We do
63
+ // NOT throw here because the calling PATCH has already
64
+ // committed the DB state — propagating would leave the
65
+ // operator with a 5xx after the change is durable, which
66
+ // is more confusing than the logged warning + retry.
67
+ logger.warn({ key, observerName, err: result.error }, "Observer.stop failed during integration mode change — observer left registered for retry");
68
+ break;
69
+ }
46
70
  }
47
71
  }
48
72
  }
@@ -100,35 +124,59 @@ async function applyGitDelegatedCronLifecycle(deps, key, next) {
100
124
  }
101
125
  return;
102
126
  }
103
- const removed = await deps.observerManager.stopAndUnregister(GIT_DELEGATED_CRON_OBSERVER_NAME);
104
- logger.info({ key, removed }, removed
105
- ? "Stopped git delegated cron after last delegated integration left"
106
- : "No git delegated cron to stop already absent");
127
+ const result = await deps.observerManager.stopAndUnregister(GIT_DELEGATED_CRON_OBSERVER_NAME);
128
+ switch (result.status) {
129
+ case "removed":
130
+ logger.info({ key }, "Stopped git delegated cron after last delegated integration left");
131
+ break;
132
+ case "absent":
133
+ logger.info({ key }, "No git delegated cron to stop — already absent");
134
+ break;
135
+ case "stop_failed":
136
+ logger.warn({ key, err: result.error }, "Git delegated cron stop failed — left registered for retry by next mode change or daemon shutdown");
137
+ break;
138
+ }
107
139
  }
140
+ /**
141
+ * INTEGRATION_NATIVE_MODE_DESIGN.md §19.7 — stand the cadence-sync worker
142
+ * up when at least one cadence-eligible integration is in a mode that
143
+ * runs the worker (`delegated` or `native`); tear it down when the last
144
+ * one leaves. The worker symbol set still lives under
145
+ * `delegated-sync-worker` for one cycle; the predicate is `hasActive
146
+ * CadenceSyncIntegration` which covers both modes.
147
+ */
108
148
  async function applyDelegatedSyncLifecycle(deps, key, next) {
109
149
  if (!deps.buildDelegatedSyncWorker)
110
150
  return;
111
- const shouldRun = hasActiveDelegatedSyncIntegration(deps.db, { key, state: next });
151
+ const shouldRun = hasActiveCadenceSyncIntegration(deps.db, { key, state: next });
112
152
  if (shouldRun) {
113
153
  if (deps.observerManager.has(DELEGATED_SYNC_OBSERVER_NAME))
114
154
  return;
115
155
  const worker = deps.buildDelegatedSyncWorker();
116
156
  if (!worker) {
117
- logger.warn({ key }, "Cannot start delegated sync worker — builder returned null");
157
+ logger.warn({ key }, "Cannot start cadence sync worker — builder returned null");
118
158
  return;
119
159
  }
120
160
  try {
121
161
  await deps.observerManager.registerAndStart(worker);
122
162
  }
123
163
  catch (err) {
124
- logger.error({ err, key }, "Failed to hot-start delegated sync worker after integration mode change");
164
+ logger.error({ err, key }, "Failed to hot-start cadence sync worker after integration mode change");
125
165
  }
126
166
  return;
127
167
  }
128
- const removed = await deps.observerManager.stopAndUnregister(DELEGATED_SYNC_OBSERVER_NAME);
129
- logger.info({ key, removed }, removed
130
- ? "Stopped delegated sync worker after last delegated integration left sync"
131
- : "No delegated sync worker to stop already absent");
168
+ const result = await deps.observerManager.stopAndUnregister(DELEGATED_SYNC_OBSERVER_NAME);
169
+ switch (result.status) {
170
+ case "removed":
171
+ logger.info({ key }, "Stopped cadence sync worker after last cadence-eligible integration left");
172
+ break;
173
+ case "absent":
174
+ logger.info({ key }, "No cadence sync worker to stop — already absent");
175
+ break;
176
+ case "stop_failed":
177
+ logger.warn({ key, err: result.error }, "Cadence sync worker stop failed — left registered for retry by next mode change or daemon shutdown");
178
+ break;
179
+ }
132
180
  }
133
181
  /**
134
182
  * Decide whether an integration's observers should be started during the
@@ -150,4 +198,107 @@ export function shouldStartObserversFor(db, key) {
150
198
  export function isIntegrationDelegated(db, key) {
151
199
  return readIntegrationState(db, key).mode === "delegated";
152
200
  }
201
+ /**
202
+ * True when the integration's data path is NOT the daemon poller — any of
203
+ * `delegated`, `native`, or `disabled` (INTEGRATION_NATIVE_MODE_DESIGN.md
204
+ * §5.6).
205
+ *
206
+ * Used by multi-provider surfaces that own polling for several integration
207
+ * kinds at once (e.g. {@link "../observers/mail-poller.js" MailPoller}). They
208
+ * must skip per-account when the integration governing that kind is not
209
+ * direct-mode — but cannot stop the whole observer because sibling kinds
210
+ * (iCloud, IMAP, Yahoo) belong to integrations whose mode is unrelated.
211
+ *
212
+ * Phase A fixed the pre-native bug where the per-account gate only checked
213
+ * `delegated`, leaving `disabled`-mode Gmail still being polled by the
214
+ * unified mail poller. Phase B1 extends the same predicate to recognise
215
+ * the new `native` mode.
216
+ */
217
+ export function isIntegrationPollerless(db, key) {
218
+ const mode = readIntegrationState(db, key).mode;
219
+ return mode === "delegated" || mode === "native" || mode === "disabled";
220
+ }
221
+ /**
222
+ * INTEGRATION_NATIVE_MODE_DESIGN.md §5.6 — true when the integration is
223
+ * currently in `native` mode. Used by route-gate logic, health builders,
224
+ * and the BackendRouter's native-fallback gate. Read once per call from
225
+ * `readIntegrationState`; callers that need the `nativeBackend` value
226
+ * should consult the full state via `readIntegrationState` directly.
227
+ */
228
+ export function isIntegrationNative(db, key) {
229
+ return readIntegrationState(db, key).mode === "native";
230
+ }
231
+ /**
232
+ * INTEGRATION_NATIVE_MODE_DESIGN.md §5.6 — true when the integration's
233
+ * data path is NOT the daemon (neither poller nor proxy) — `native` or
234
+ * `disabled`. Used by the API route gate to 410 daemon endpoints; the
235
+ * agent reaches the connector directly via the main backend's MCP (native)
236
+ * or not at all (disabled).
237
+ *
238
+ * Distinct from {@link isIntegrationDelegated} (`delegated` only) and
239
+ * {@link isIntegrationPollerless} (`delegated ∪ native ∪ disabled`).
240
+ */
241
+ export function isIntegrationDaemonless(db, key) {
242
+ const mode = readIntegrationState(db, key).mode;
243
+ return mode === "native" || mode === "disabled";
244
+ }
245
+ // ── Flip-lock orchestration (§11.3.1) ───────────────────────────────────────
246
+ /**
247
+ * INTEGRATION_NATIVE_MODE_DESIGN.md §11.3.1 — per-key flip lock keyed in
248
+ * `runtime_state`. The PATCH handler acquires the lock before signalling
249
+ * the outgoing data path to stop and releases it after the audit row is
250
+ * written. A concurrent flip on the same key sees the lock and is rejected
251
+ * with 409; concurrent flips on different keys proceed independently.
252
+ *
253
+ * Stored shape: `{ acquiredAt: ISO, processId: number, byKey: <key> }`.
254
+ * The lock is not strictly necessary on a single-process daemon (Node is
255
+ * single-threaded and Better-SQLite3 is synchronous), but the PATCH
256
+ * handler interleaves `await` boundaries while running the live probe and
257
+ * the optional cancel-delegated-tick drain — so concurrent flips ARE
258
+ * possible at the JavaScript-microtask level. The lock makes that race
259
+ * explicit instead of relying on call-site ordering.
260
+ */
261
+ const FLIP_LOCK_PREFIX = "integration_flip_lock:";
262
+ function flipLockKey(key) {
263
+ return `${FLIP_LOCK_PREFIX}${key}`;
264
+ }
265
+ /**
266
+ * Attempt to acquire the flip lock for `key`. Returns `{ ok: true }` on
267
+ * success and `{ ok: false, current }` when the lock is already held —
268
+ * the PATCH handler maps the latter to HTTP 409. Stale locks older than
269
+ * `STALE_LOCK_MS` are silently reclaimed: the PATCH handler's drain step
270
+ * has a 5s timeout, so a holder older than ~30s is a crashed/abandoned
271
+ * process and not a live competitor.
272
+ */
273
+ const STALE_LOCK_MS = 30_000;
274
+ export function acquireIntegrationFlipLock(db, key, now = Date.now()) {
275
+ const existing = readRuntimeState(db, flipLockKey(key));
276
+ if (existing) {
277
+ const acquiredMs = Date.parse(existing.acquiredAt);
278
+ const isStale = Number.isFinite(acquiredMs) && now - acquiredMs > STALE_LOCK_MS;
279
+ if (!isStale) {
280
+ return { ok: false, current: existing };
281
+ }
282
+ logger.warn({ key, lock: existing, ageMs: now - acquiredMs }, "Reclaiming stale integration flip lock");
283
+ }
284
+ const lock = {
285
+ acquiredAt: new Date(now).toISOString(),
286
+ processId: process.pid,
287
+ byKey: key,
288
+ };
289
+ writeRuntimeState(db, flipLockKey(key), lock);
290
+ return { ok: true, lock };
291
+ }
292
+ export function releaseIntegrationFlipLock(db, key) {
293
+ deleteRuntimeState(db, flipLockKey(key));
294
+ }
295
+ /**
296
+ * Read-only inspection helper — used by tests and the §15 risk-register
297
+ * defensive check on `POST /api/observations` ("reject rows whose
298
+ * `(source, refs.<id>)` already has a newer row written under a different
299
+ * mode within the lock window"). Returns null when no lock is held.
300
+ */
301
+ export function readIntegrationFlipLock(db, key) {
302
+ return readRuntimeState(db, flipLockKey(key));
303
+ }
153
304
  //# sourceMappingURL=integration-lifecycle.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"integration-lifecycle.js","sourceRoot":"","sources":["../../src/core/integration-lifecycle.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"integration-lifecycle.js","sourceRoot":"","sources":["../../src/core/integration-lifecycle.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,14 @@
1
1
  import type Database from "better-sqlite3";
2
2
  import { type BackendId, type IntegrationKey } from "@aitne/shared";
3
+ /**
4
+ * Read the currently-configured main backend id from
5
+ * `backend_global_defaults.default_backend`. Returns null when the row is
6
+ * absent (fresh installs before setup) or carries a value that does not
7
+ * match `BackendId` — both treated by callers as "no main backend known
8
+ * yet". A single source of truth so the integrations PATCH route and the
9
+ * main-backend cascade agree on the value.
10
+ */
11
+ export declare function readMainBackend(db: Database.Database): BackendId | null;
3
12
  export interface DelegationCompatReport {
4
13
  key: IntegrationKey;
5
14
  /** User's explicit delegated backend choice (preserved across main switches). */
@@ -33,4 +42,35 @@ export interface DelegationCompatReport {
33
42
  * in the daemon log without burning an owner notification.
34
43
  */
35
44
  export declare function checkDelegatedCompatForNewMain(db: Database.Database, newMainBackendId: BackendId): DelegationCompatReport[];
45
+ export interface NativeCascadeEntry {
46
+ key: IntegrationKey;
47
+ /** The native-backend binding that just became invalid. */
48
+ priorNativeBackend: BackendId;
49
+ /** The new main backend that triggered the cascade. */
50
+ newMainBackend: BackendId;
51
+ }
52
+ /**
53
+ * INTEGRATION_NATIVE_MODE_DESIGN.md §11.4 — main-backend change cascade.
54
+ *
55
+ * When the operator switches the main backend, every `native` integration
56
+ * whose `nativeBackend` no longer matches is **flipped to `disabled`** and
57
+ * a setup-required entry is returned to the caller. The caller is
58
+ * responsible for:
59
+ *
60
+ * - writing an `agent_actions` audit row of type
61
+ * `integration.native_unbound` per entry (carrying `priorNativeBackend`
62
+ * and `newMainBackend` so the forensic chain survives the schema's
63
+ * `superRefine` clearing `nativeBackend` once `mode !== "native"`);
64
+ * - firing a notification telling the user their native integration is
65
+ * now disabled until they re-configure;
66
+ * - calling the integration mode-change side-effects callback (the
67
+ * workdir re-materialisation + observer-stop logic).
68
+ *
69
+ * Returns the entries that were flipped so the caller can build the audit
70
+ * + notification batch atomically.
71
+ *
72
+ * No silent re-routing. Native is an explicit contract — the user must
73
+ * confirm the new backend binding via the setup wizard.
74
+ */
75
+ export declare function cascadeNativeBindingsOnMainSwitch(db: Database.Database, newMainBackendId: BackendId): NativeCascadeEntry[];
36
76
  //# sourceMappingURL=integration-main-backend.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"integration-main-backend.d.ts","sourceRoot":"","sources":["../../src/core/integration-main-backend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAGL,KAAK,SAAS,EACd,KAAK,cAAc,EAEpB,MAAM,eAAe,CAAC;AAMvB,MAAM,WAAW,sBAAsB;IACrC,GAAG,EAAE,cAAc,CAAC;IACpB,iFAAiF;IACjF,gBAAgB,EAAE,SAAS,CAAC;IAC5B,oFAAoF;IACpF,qBAAqB,EAAE,OAAO,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,8BAA8B,CAC5C,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,gBAAgB,EAAE,SAAS,GAC1B,sBAAsB,EAAE,CAiC1B"}
1
+ {"version":3,"file":"integration-main-backend.d.ts","sourceRoot":"","sources":["../../src/core/integration-main-backend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,cAAc,EAEpB,MAAM,eAAe,CAAC;AASvB;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,SAAS,GAAG,IAAI,CAgBvE;AAED,MAAM,WAAW,sBAAsB;IACrC,GAAG,EAAE,cAAc,CAAC;IACpB,iFAAiF;IACjF,gBAAgB,EAAE,SAAS,CAAC;IAC5B,oFAAoF;IACpF,qBAAqB,EAAE,OAAO,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,8BAA8B,CAC5C,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,gBAAgB,EAAE,SAAS,GAC1B,sBAAsB,EAAE,CAiC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,cAAc,CAAC;IACpB,2DAA2D;IAC3D,kBAAkB,EAAE,SAAS,CAAC;IAC9B,uDAAuD;IACvD,cAAc,EAAE,SAAS,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,iCAAiC,CAC/C,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,gBAAgB,EAAE,SAAS,GAC1B,kBAAkB,EAAE,CA6CtB"}
@@ -1,7 +1,32 @@
1
- import { INTEGRATION_KEYS, backendHasIntegrationConnector, } from "@aitne/shared";
2
- import { readIntegrations } from "../db/integrations-store.js";
1
+ import { INTEGRATION_KEYS, backendHasIntegrationConnector, isBackendId, } from "@aitne/shared";
2
+ import { readIntegrations, updateIntegrationState, } from "../db/integrations-store.js";
3
3
  import { createLogger } from "../logging.js";
4
4
  const logger = createLogger("integration-main-backend");
5
+ /**
6
+ * Read the currently-configured main backend id from
7
+ * `backend_global_defaults.default_backend`. Returns null when the row is
8
+ * absent (fresh installs before setup) or carries a value that does not
9
+ * match `BackendId` — both treated by callers as "no main backend known
10
+ * yet". A single source of truth so the integrations PATCH route and the
11
+ * main-backend cascade agree on the value.
12
+ */
13
+ export function readMainBackend(db) {
14
+ let row;
15
+ try {
16
+ row = db
17
+ .prepare("SELECT default_backend FROM backend_global_defaults WHERE singleton = 1")
18
+ .get();
19
+ }
20
+ catch {
21
+ // Table missing (test harnesses without the multi-backend schema) —
22
+ // surface as "unknown" so callers can degrade safely.
23
+ return null;
24
+ }
25
+ const raw = row?.default_backend;
26
+ if (typeof raw !== "string")
27
+ return null;
28
+ return isBackendId(raw) ? raw : null;
29
+ }
5
30
  /**
6
31
  * §4.12.4 "Backend change while delegated" — read-only detection.
7
32
  *
@@ -56,4 +81,66 @@ export function checkDelegatedCompatForNewMain(db, newMainBackendId) {
56
81
  }
57
82
  return reports;
58
83
  }
84
+ /**
85
+ * INTEGRATION_NATIVE_MODE_DESIGN.md §11.4 — main-backend change cascade.
86
+ *
87
+ * When the operator switches the main backend, every `native` integration
88
+ * whose `nativeBackend` no longer matches is **flipped to `disabled`** and
89
+ * a setup-required entry is returned to the caller. The caller is
90
+ * responsible for:
91
+ *
92
+ * - writing an `agent_actions` audit row of type
93
+ * `integration.native_unbound` per entry (carrying `priorNativeBackend`
94
+ * and `newMainBackend` so the forensic chain survives the schema's
95
+ * `superRefine` clearing `nativeBackend` once `mode !== "native"`);
96
+ * - firing a notification telling the user their native integration is
97
+ * now disabled until they re-configure;
98
+ * - calling the integration mode-change side-effects callback (the
99
+ * workdir re-materialisation + observer-stop logic).
100
+ *
101
+ * Returns the entries that were flipped so the caller can build the audit
102
+ * + notification batch atomically.
103
+ *
104
+ * No silent re-routing. Native is an explicit contract — the user must
105
+ * confirm the new backend binding via the setup wizard.
106
+ */
107
+ export function cascadeNativeBindingsOnMainSwitch(db, newMainBackendId) {
108
+ const integrations = readIntegrations(db);
109
+ const flipped = [];
110
+ const now = new Date().toISOString();
111
+ for (const key of INTEGRATION_KEYS) {
112
+ const state = integrations[key];
113
+ if (state.mode !== "native")
114
+ continue;
115
+ const priorNativeBackend = state.nativeBackend;
116
+ if (!priorNativeBackend) {
117
+ // Defensive — superRefine guarantees nativeBackend exists in native
118
+ // mode. A row missing it indicates registry drift; flip to disabled
119
+ // and log so the operator notices.
120
+ logger.warn({ key }, "native integration carried no nativeBackend — flipping to disabled (registry drift)");
121
+ }
122
+ if (priorNativeBackend === newMainBackendId)
123
+ continue;
124
+ updateIntegrationState(db, key, {
125
+ mode: "disabled",
126
+ deniedTools: state.deniedTools ?? [],
127
+ lastChangedAt: now,
128
+ });
129
+ flipped.push({
130
+ key,
131
+ // Cast safe because we just checked truthiness above and the only
132
+ // un-truthy branch logs and falls through to here with a synthetic
133
+ // value (`unknown` would be misleading); we mirror what the audit
134
+ // row needs.
135
+ priorNativeBackend: (priorNativeBackend ?? newMainBackendId),
136
+ newMainBackend: newMainBackendId,
137
+ });
138
+ logger.warn({
139
+ key,
140
+ priorNativeBackend,
141
+ newMainBackend: newMainBackendId,
142
+ }, "native integration cascaded to disabled on main-backend change");
143
+ }
144
+ return flipped;
145
+ }
59
146
  //# sourceMappingURL=integration-main-backend.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"integration-main-backend.js","sourceRoot":"","sources":["../../src/core/integration-main-backend.ts"],"names":[],"mappings":"AACA,OAAO,EACL,gBAAgB,EAChB,8BAA8B,GAI/B,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,MAAM,MAAM,GAAG,YAAY,CAAC,0BAA0B,CAAC,CAAC;AAUxD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,8BAA8B,CAC5C,EAAqB,EACrB,gBAA2B;IAE3B,MAAM,YAAY,GAAG,gBAAgB,CAAC,EAAE,CAAC,CAAC;IAC1C,MAAM,OAAO,GAA6B,EAAE,CAAC;IAE7C,KAAK,MAAM,GAAG,IAAI,gBAAgB,EAAE,CAAC;QACnC,MAAM,KAAK,GAAqB,YAAY,CAAC,GAAG,CAAC,CAAC;QAClD,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW;YAAE,SAAS;QAEzC,MAAM,UAAU,GAAG,8BAA8B,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;QACzE,oEAAoE;QACpE,wEAAwE;QACxE,uBAAuB;QACvB,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,CAAC,IAAI,CACT;gBACE,GAAG;gBACH,gBAAgB;gBAChB,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;aACzC,EACD,qJAAqJ,CACtJ,CAAC;QACJ,CAAC;QACD,OAAO,CAAC,IAAI,CAAC;YACX,GAAG;YACH,yDAAyD;YACzD,oEAAoE;YACpE,wDAAwD;YACxD,gBAAgB,EAAE,KAAK,CAAC,gBAA6B;YACrD,qBAAqB,EAAE,UAAU;SAClC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"integration-main-backend.js","sourceRoot":"","sources":["../../src/core/integration-main-backend.ts"],"names":[],"mappings":"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"}
@@ -25,23 +25,6 @@ import { type IntegrationsRecord } from "../db/integrations-store.js";
25
25
  * parser produce identical bytes on the next render (no churn).
26
26
  */
27
27
  export declare function getManagementMdPath(dataDir: string): string;
28
- export declare function getLegacyManagementMdPath(dataDir: string): string;
29
- export type LegacyManagementMdMigrationResult = {
30
- migrated: true;
31
- from: string;
32
- to: string;
33
- } | {
34
- migrated: false;
35
- from: string;
36
- to: string;
37
- reason: "legacy_missing" | "target_exists";
38
- };
39
- /**
40
- * One-shot compatibility migration for installs that predate the
41
- * `integrations.md` rename. If both files exist, keep `integrations.md` as
42
- * authoritative and leave the legacy file untouched for manual inspection.
43
- */
44
- export declare function migrateLegacyManagementMd(dataDir: string): LegacyManagementMdMigrationResult;
45
28
  /**
46
29
  * SETUP-FLOW-REDESIGN-PLAN §6.2 — declarative "where do the user's notes
47
30
  * live" routing for the agent. The body is regenerated from the
@@ -57,6 +40,57 @@ export interface NoteSourcesInput {
57
40
  externalObsidianWatch: boolean;
58
41
  }
59
42
  export declare function renderNoteSourcesSection(integrations: IntegrationsRecord, notes: NoteSourcesInput): string;
43
+ /**
44
+ * INTEGRATION_NATIVE_MODE_DESIGN.md §7.3 — render the full per-session
45
+ * routing table that the per-backend instruction file (`CLAUDE.md` /
46
+ * `AGENTS.md` / `GEMINI.md`) and the hourly_check / DM task-flow files
47
+ * substitute in for the `<integration-routing-table>` placeholder.
48
+ *
49
+ * Always renders every registered integration, even when all rows are
50
+ * `direct`, so the agent's mental model converges on "read the routing
51
+ * table first, then dispatch." Disabled rows appear as `(disabled)` so
52
+ * the agent can answer "do I have Gmail?" honestly even when the audit
53
+ * surface is suppressed.
54
+ *
55
+ * Pure function — no I/O, no DB reads. Callers pass the integration
56
+ * snapshot they want rendered (typically from `readIntegrations(db)`).
57
+ */
58
+ export declare function renderIntegrationRoutingTable(integrations: IntegrationsRecord): string;
59
+ /**
60
+ * INTEGRATION_NATIVE_MODE_DESIGN.md §6.5.2 — the actionable variant of
61
+ * the routing table. Identical rendering for `direct` / `delegated` /
62
+ * `native` rows; `disabled` rows are filtered out entirely so the
63
+ * task-flow's "for each integration" loop has zero iterations for them.
64
+ *
65
+ * This is what the hourly_check and DM task-flow files iterate over;
66
+ * the full {@link renderIntegrationRoutingTable} is for the instruction
67
+ * file's read-only audit summary.
68
+ */
69
+ export declare function renderIntegrationRoutingTableActionable(integrations: IntegrationsRecord): string;
70
+ /**
71
+ * INTEGRATION_NATIVE_MODE_DESIGN.md §7.3 / §6.5.2 — substitute the two
72
+ * angle-bracket placeholders documented in the design with their
73
+ * rendered tables. The placeholders are deliberately literal strings
74
+ * (not `{handlebars}` template tokens) so they survive the existing
75
+ * `resolveTemplate` pass in `prompt-utils.ts` (which only touches
76
+ * `{…}` braces) without escaping. Substitution is idempotent — running
77
+ * the helper twice on already-substituted text is a no-op because the
78
+ * placeholder strings have already been replaced.
79
+ *
80
+ * Callers:
81
+ * - `prompts.getTaskFlow` substitutes after `applyIntegrationModeFilter`
82
+ * so the rendered template carries the final per-session table
83
+ * before `resolveTemplate` fills `{context}` and `{event_data[*]}`.
84
+ * - `skills-compiler.materializeClaudeSession` /
85
+ * `materializeCliSession` substitute inside the rendered profile
86
+ * body before writing `CLAUDE.md` / `AGENTS.md` / `GEMINI.md`.
87
+ *
88
+ * Returns `content` unchanged when neither placeholder is present so
89
+ * call sites can apply this unconditionally without measuring impact.
90
+ */
91
+ export declare const INTEGRATION_ROUTING_TABLE_PLACEHOLDER = "<integration-routing-table>";
92
+ export declare const INTEGRATION_ROUTING_TABLE_ACTIONABLE_PLACEHOLDER = "<integration-routing-table-actionable>";
93
+ export declare function substituteIntegrationRoutingTables(content: string, integrations: IntegrationsRecord | Partial<Record<IntegrationKey, IntegrationState>>): string;
60
94
  export declare function renderManagementMd(integrations: IntegrationsRecord, notes?: NoteSourcesInput): string;
61
95
  export interface ParsedCurrentStateRow {
62
96
  key: string;
@@ -1 +1 @@
1
- {"version":3,"file":"management-md.d.ts","sourceRoot":"","sources":["../../src/core/management-md.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"management-md.d.ts","sourceRoot":"","sources":["../../src/core/management-md.ts"],"names":[],"mappings":"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"}