@aitne/daemon 0.1.0

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 (1386) hide show
  1. package/LICENSE +21 -0
  2. package/dist/adapters/composite-dashboard-stream.d.ts +42 -0
  3. package/dist/adapters/composite-dashboard-stream.d.ts.map +1 -0
  4. package/dist/adapters/composite-dashboard-stream.js +49 -0
  5. package/dist/adapters/composite-dashboard-stream.js.map +1 -0
  6. package/dist/adapters/dashboard-adapter.d.ts +104 -0
  7. package/dist/adapters/dashboard-adapter.d.ts.map +1 -0
  8. package/dist/adapters/dashboard-adapter.js +216 -0
  9. package/dist/adapters/dashboard-adapter.js.map +1 -0
  10. package/dist/adapters/discord.d.ts +77 -0
  11. package/dist/adapters/discord.d.ts.map +1 -0
  12. package/dist/adapters/discord.js +339 -0
  13. package/dist/adapters/discord.js.map +1 -0
  14. package/dist/adapters/docs-qa-adapter.d.ts +123 -0
  15. package/dist/adapters/docs-qa-adapter.d.ts.map +1 -0
  16. package/dist/adapters/docs-qa-adapter.js +218 -0
  17. package/dist/adapters/docs-qa-adapter.js.map +1 -0
  18. package/dist/adapters/message-hub.d.ts +70 -0
  19. package/dist/adapters/message-hub.d.ts.map +1 -0
  20. package/dist/adapters/message-hub.js +359 -0
  21. package/dist/adapters/message-hub.js.map +1 -0
  22. package/dist/adapters/notification-manager.d.ts +99 -0
  23. package/dist/adapters/notification-manager.d.ts.map +1 -0
  24. package/dist/adapters/notification-manager.js +498 -0
  25. package/dist/adapters/notification-manager.js.map +1 -0
  26. package/dist/adapters/outbound-text.d.ts +28 -0
  27. package/dist/adapters/outbound-text.d.ts.map +1 -0
  28. package/dist/adapters/outbound-text.js +58 -0
  29. package/dist/adapters/outbound-text.js.map +1 -0
  30. package/dist/adapters/slack-adapter.d.ts +82 -0
  31. package/dist/adapters/slack-adapter.d.ts.map +1 -0
  32. package/dist/adapters/slack-adapter.js +359 -0
  33. package/dist/adapters/slack-adapter.js.map +1 -0
  34. package/dist/adapters/telegram-adapter.d.ts +107 -0
  35. package/dist/adapters/telegram-adapter.d.ts.map +1 -0
  36. package/dist/adapters/telegram-adapter.js +477 -0
  37. package/dist/adapters/telegram-adapter.js.map +1 -0
  38. package/dist/adapters/types.d.ts +92 -0
  39. package/dist/adapters/types.d.ts.map +1 -0
  40. package/dist/adapters/types.js +2 -0
  41. package/dist/adapters/types.js.map +1 -0
  42. package/dist/adapters/whatsapp-adapter.d.ts +213 -0
  43. package/dist/adapters/whatsapp-adapter.d.ts.map +1 -0
  44. package/dist/adapters/whatsapp-adapter.js +1216 -0
  45. package/dist/adapters/whatsapp-adapter.js.map +1 -0
  46. package/dist/api/chat-binding-query.d.ts +36 -0
  47. package/dist/api/chat-binding-query.d.ts.map +1 -0
  48. package/dist/api/chat-binding-query.js +63 -0
  49. package/dist/api/chat-binding-query.js.map +1 -0
  50. package/dist/api/chat-session-resume.d.ts +12 -0
  51. package/dist/api/chat-session-resume.d.ts.map +1 -0
  52. package/dist/api/chat-session-resume.js +21 -0
  53. package/dist/api/chat-session-resume.js.map +1 -0
  54. package/dist/api/delegated-proxy-helper.d.ts +33 -0
  55. package/dist/api/delegated-proxy-helper.d.ts.map +1 -0
  56. package/dist/api/delegated-proxy-helper.js +54 -0
  57. package/dist/api/delegated-proxy-helper.js.map +1 -0
  58. package/dist/api/directory-picker.d.ts +38 -0
  59. package/dist/api/directory-picker.d.ts.map +1 -0
  60. package/dist/api/directory-picker.js +278 -0
  61. package/dist/api/directory-picker.js.map +1 -0
  62. package/dist/api/env-writer.d.ts +25 -0
  63. package/dist/api/env-writer.d.ts.map +1 -0
  64. package/dist/api/env-writer.js +421 -0
  65. package/dist/api/env-writer.js.map +1 -0
  66. package/dist/api/integration-route-gate.d.ts +60 -0
  67. package/dist/api/integration-route-gate.d.ts.map +1 -0
  68. package/dist/api/integration-route-gate.js +83 -0
  69. package/dist/api/integration-route-gate.js.map +1 -0
  70. package/dist/api/json-body.d.ts +29 -0
  71. package/dist/api/json-body.d.ts.map +1 -0
  72. package/dist/api/json-body.js +87 -0
  73. package/dist/api/json-body.js.map +1 -0
  74. package/dist/api/routes/activity-sources.d.ts +20 -0
  75. package/dist/api/routes/activity-sources.d.ts.map +1 -0
  76. package/dist/api/routes/activity-sources.js +18 -0
  77. package/dist/api/routes/activity-sources.js.map +1 -0
  78. package/dist/api/routes/agent.d.ts +4 -0
  79. package/dist/api/routes/agent.d.ts.map +1 -0
  80. package/dist/api/routes/agent.js +619 -0
  81. package/dist/api/routes/agent.js.map +1 -0
  82. package/dist/api/routes/apple-calendar.d.ts +31 -0
  83. package/dist/api/routes/apple-calendar.d.ts.map +1 -0
  84. package/dist/api/routes/apple-calendar.js +310 -0
  85. package/dist/api/routes/apple-calendar.js.map +1 -0
  86. package/dist/api/routes/attachments.d.ts +36 -0
  87. package/dist/api/routes/attachments.d.ts.map +1 -0
  88. package/dist/api/routes/attachments.js +305 -0
  89. package/dist/api/routes/attachments.js.map +1 -0
  90. package/dist/api/routes/backends.d.ts +4 -0
  91. package/dist/api/routes/backends.d.ts.map +1 -0
  92. package/dist/api/routes/backends.js +1132 -0
  93. package/dist/api/routes/backends.js.map +1 -0
  94. package/dist/api/routes/books.d.ts +63 -0
  95. package/dist/api/routes/books.d.ts.map +1 -0
  96. package/dist/api/routes/books.js +467 -0
  97. package/dist/api/routes/books.js.map +1 -0
  98. package/dist/api/routes/calendar.d.ts +36 -0
  99. package/dist/api/routes/calendar.d.ts.map +1 -0
  100. package/dist/api/routes/calendar.js +351 -0
  101. package/dist/api/routes/calendar.js.map +1 -0
  102. package/dist/api/routes/commands.d.ts +4 -0
  103. package/dist/api/routes/commands.d.ts.map +1 -0
  104. package/dist/api/routes/commands.js +251 -0
  105. package/dist/api/routes/commands.js.map +1 -0
  106. package/dist/api/routes/context.d.ts +57 -0
  107. package/dist/api/routes/context.d.ts.map +1 -0
  108. package/dist/api/routes/context.js +1765 -0
  109. package/dist/api/routes/context.js.map +1 -0
  110. package/dist/api/routes/dashboard.d.ts +29 -0
  111. package/dist/api/routes/dashboard.d.ts.map +1 -0
  112. package/dist/api/routes/dashboard.js +2062 -0
  113. package/dist/api/routes/dashboard.js.map +1 -0
  114. package/dist/api/routes/delegated-sync.d.ts +4 -0
  115. package/dist/api/routes/delegated-sync.d.ts.map +1 -0
  116. package/dist/api/routes/delegated-sync.js +192 -0
  117. package/dist/api/routes/delegated-sync.js.map +1 -0
  118. package/dist/api/routes/delegated.d.ts +42 -0
  119. package/dist/api/routes/delegated.d.ts.map +1 -0
  120. package/dist/api/routes/delegated.js +250 -0
  121. package/dist/api/routes/delegated.js.map +1 -0
  122. package/dist/api/routes/docs.d.ts +34 -0
  123. package/dist/api/routes/docs.d.ts.map +1 -0
  124. package/dist/api/routes/docs.js +580 -0
  125. package/dist/api/routes/docs.js.map +1 -0
  126. package/dist/api/routes/entities.d.ts +9 -0
  127. package/dist/api/routes/entities.d.ts.map +1 -0
  128. package/dist/api/routes/entities.js +176 -0
  129. package/dist/api/routes/entities.js.map +1 -0
  130. package/dist/api/routes/git-accounts.d.ts +23 -0
  131. package/dist/api/routes/git-accounts.d.ts.map +1 -0
  132. package/dist/api/routes/git-accounts.js +227 -0
  133. package/dist/api/routes/git-accounts.js.map +1 -0
  134. package/dist/api/routes/git-templates.d.ts +50 -0
  135. package/dist/api/routes/git-templates.d.ts.map +1 -0
  136. package/dist/api/routes/git-templates.js +276 -0
  137. package/dist/api/routes/git-templates.js.map +1 -0
  138. package/dist/api/routes/git.d.ts +34 -0
  139. package/dist/api/routes/git.d.ts.map +1 -0
  140. package/dist/api/routes/git.js +126 -0
  141. package/dist/api/routes/git.js.map +1 -0
  142. package/dist/api/routes/github.d.ts +34 -0
  143. package/dist/api/routes/github.d.ts.map +1 -0
  144. package/dist/api/routes/github.js +465 -0
  145. package/dist/api/routes/github.js.map +1 -0
  146. package/dist/api/routes/health.d.ts +4 -0
  147. package/dist/api/routes/health.d.ts.map +1 -0
  148. package/dist/api/routes/health.js +257 -0
  149. package/dist/api/routes/health.js.map +1 -0
  150. package/dist/api/routes/integrations-reconcile.d.ts +33 -0
  151. package/dist/api/routes/integrations-reconcile.d.ts.map +1 -0
  152. package/dist/api/routes/integrations-reconcile.js +463 -0
  153. package/dist/api/routes/integrations-reconcile.js.map +1 -0
  154. package/dist/api/routes/integrations.d.ts +19 -0
  155. package/dist/api/routes/integrations.d.ts.map +1 -0
  156. package/dist/api/routes/integrations.js +1384 -0
  157. package/dist/api/routes/integrations.js.map +1 -0
  158. package/dist/api/routes/knowledge.d.ts +4 -0
  159. package/dist/api/routes/knowledge.d.ts.map +1 -0
  160. package/dist/api/routes/knowledge.js +224 -0
  161. package/dist/api/routes/knowledge.js.map +1 -0
  162. package/dist/api/routes/mail.d.ts +39 -0
  163. package/dist/api/routes/mail.d.ts.map +1 -0
  164. package/dist/api/routes/mail.js +1406 -0
  165. package/dist/api/routes/mail.js.map +1 -0
  166. package/dist/api/routes/managed-tasks.d.ts +48 -0
  167. package/dist/api/routes/managed-tasks.d.ts.map +1 -0
  168. package/dist/api/routes/managed-tasks.js +844 -0
  169. package/dist/api/routes/managed-tasks.js.map +1 -0
  170. package/dist/api/routes/mcp.d.ts +50 -0
  171. package/dist/api/routes/mcp.d.ts.map +1 -0
  172. package/dist/api/routes/mcp.js +470 -0
  173. package/dist/api/routes/mcp.js.map +1 -0
  174. package/dist/api/routes/metrics.d.ts +13 -0
  175. package/dist/api/routes/metrics.d.ts.map +1 -0
  176. package/dist/api/routes/metrics.js +117 -0
  177. package/dist/api/routes/metrics.js.map +1 -0
  178. package/dist/api/routes/notion.d.ts +35 -0
  179. package/dist/api/routes/notion.d.ts.map +1 -0
  180. package/dist/api/routes/notion.js +442 -0
  181. package/dist/api/routes/notion.js.map +1 -0
  182. package/dist/api/routes/observations.d.ts +4 -0
  183. package/dist/api/routes/observations.d.ts.map +1 -0
  184. package/dist/api/routes/observations.js +177 -0
  185. package/dist/api/routes/observations.js.map +1 -0
  186. package/dist/api/routes/obsidian.d.ts +16 -0
  187. package/dist/api/routes/obsidian.d.ts.map +1 -0
  188. package/dist/api/routes/obsidian.js +321 -0
  189. package/dist/api/routes/obsidian.js.map +1 -0
  190. package/dist/api/routes/profile-questions.d.ts +17 -0
  191. package/dist/api/routes/profile-questions.d.ts.map +1 -0
  192. package/dist/api/routes/profile-questions.js +115 -0
  193. package/dist/api/routes/profile-questions.js.map +1 -0
  194. package/dist/api/routes/receipts.d.ts +4 -0
  195. package/dist/api/routes/receipts.d.ts.map +1 -0
  196. package/dist/api/routes/receipts.js +155 -0
  197. package/dist/api/routes/receipts.js.map +1 -0
  198. package/dist/api/routes/recurring-schedules.d.ts +4 -0
  199. package/dist/api/routes/recurring-schedules.d.ts.map +1 -0
  200. package/dist/api/routes/recurring-schedules.js +137 -0
  201. package/dist/api/routes/recurring-schedules.js.map +1 -0
  202. package/dist/api/routes/repositories.d.ts +40 -0
  203. package/dist/api/routes/repositories.d.ts.map +1 -0
  204. package/dist/api/routes/repositories.js +857 -0
  205. package/dist/api/routes/repositories.js.map +1 -0
  206. package/dist/api/routes/setup-migrate.d.ts +74 -0
  207. package/dist/api/routes/setup-migrate.d.ts.map +1 -0
  208. package/dist/api/routes/setup-migrate.js +944 -0
  209. package/dist/api/routes/setup-migrate.js.map +1 -0
  210. package/dist/api/routes/setup.d.ts +4 -0
  211. package/dist/api/routes/setup.d.ts.map +1 -0
  212. package/dist/api/routes/setup.js +443 -0
  213. package/dist/api/routes/setup.js.map +1 -0
  214. package/dist/api/routes/skill-curation.d.ts +5 -0
  215. package/dist/api/routes/skill-curation.d.ts.map +1 -0
  216. package/dist/api/routes/skill-curation.js +728 -0
  217. package/dist/api/routes/skill-curation.js.map +1 -0
  218. package/dist/api/routes/skills.d.ts +52 -0
  219. package/dist/api/routes/skills.d.ts.map +1 -0
  220. package/dist/api/routes/skills.js +429 -0
  221. package/dist/api/routes/skills.js.map +1 -0
  222. package/dist/api/routes/sot-bindings.d.ts +20 -0
  223. package/dist/api/routes/sot-bindings.d.ts.map +1 -0
  224. package/dist/api/routes/sot-bindings.js +163 -0
  225. package/dist/api/routes/sot-bindings.js.map +1 -0
  226. package/dist/api/routes/sse.d.ts +86 -0
  227. package/dist/api/routes/sse.d.ts.map +1 -0
  228. package/dist/api/routes/sse.js +378 -0
  229. package/dist/api/routes/sse.js.map +1 -0
  230. package/dist/api/routes/system.d.ts +4 -0
  231. package/dist/api/routes/system.d.ts.map +1 -0
  232. package/dist/api/routes/system.js +207 -0
  233. package/dist/api/routes/system.js.map +1 -0
  234. package/dist/api/routes/task-flows.d.ts +30 -0
  235. package/dist/api/routes/task-flows.d.ts.map +1 -0
  236. package/dist/api/routes/task-flows.js +155 -0
  237. package/dist/api/routes/task-flows.js.map +1 -0
  238. package/dist/api/routes/travel-bookings.d.ts +4 -0
  239. package/dist/api/routes/travel-bookings.d.ts.map +1 -0
  240. package/dist/api/routes/travel-bookings.js +142 -0
  241. package/dist/api/routes/travel-bookings.js.map +1 -0
  242. package/dist/api/routes/travel-time.d.ts +8 -0
  243. package/dist/api/routes/travel-time.d.ts.map +1 -0
  244. package/dist/api/routes/travel-time.js +87 -0
  245. package/dist/api/routes/travel-time.js.map +1 -0
  246. package/dist/api/routes/triggers.d.ts +4 -0
  247. package/dist/api/routes/triggers.d.ts.map +1 -0
  248. package/dist/api/routes/triggers.js +101 -0
  249. package/dist/api/routes/triggers.js.map +1 -0
  250. package/dist/api/routes/voice.d.ts +48 -0
  251. package/dist/api/routes/voice.d.ts.map +1 -0
  252. package/dist/api/routes/voice.js +232 -0
  253. package/dist/api/routes/voice.js.map +1 -0
  254. package/dist/api/server.d.ts +428 -0
  255. package/dist/api/server.d.ts.map +1 -0
  256. package/dist/api/server.js +558 -0
  257. package/dist/api/server.js.map +1 -0
  258. package/dist/config.d.ts +136 -0
  259. package/dist/config.d.ts.map +1 -0
  260. package/dist/config.js +699 -0
  261. package/dist/config.js.map +1 -0
  262. package/dist/core/agent-core.d.ts +517 -0
  263. package/dist/core/agent-core.d.ts.map +1 -0
  264. package/dist/core/agent-core.js +102 -0
  265. package/dist/core/agent-core.js.map +1 -0
  266. package/dist/core/alerts.d.ts +86 -0
  267. package/dist/core/alerts.d.ts.map +1 -0
  268. package/dist/core/alerts.js +304 -0
  269. package/dist/core/alerts.js.map +1 -0
  270. package/dist/core/atomic-write.d.ts +51 -0
  271. package/dist/core/atomic-write.d.ts.map +1 -0
  272. package/dist/core/atomic-write.js +135 -0
  273. package/dist/core/atomic-write.js.map +1 -0
  274. package/dist/core/backends/api-key-probe.d.ts +40 -0
  275. package/dist/core/backends/api-key-probe.d.ts.map +1 -0
  276. package/dist/core/backends/api-key-probe.js +116 -0
  277. package/dist/core/backends/api-key-probe.js.map +1 -0
  278. package/dist/core/backends/auth-health-monitor.d.ts +373 -0
  279. package/dist/core/backends/auth-health-monitor.d.ts.map +1 -0
  280. package/dist/core/backends/auth-health-monitor.js +950 -0
  281. package/dist/core/backends/auth-health-monitor.js.map +1 -0
  282. package/dist/core/backends/auth-recovery.d.ts +263 -0
  283. package/dist/core/backends/auth-recovery.d.ts.map +1 -0
  284. package/dist/core/backends/auth-recovery.js +1086 -0
  285. package/dist/core/backends/auth-recovery.js.map +1 -0
  286. package/dist/core/backends/auth-telemetry.d.ts +81 -0
  287. package/dist/core/backends/auth-telemetry.d.ts.map +1 -0
  288. package/dist/core/backends/auth-telemetry.js +108 -0
  289. package/dist/core/backends/auth-telemetry.js.map +1 -0
  290. package/dist/core/backends/backend-router.d.ts +272 -0
  291. package/dist/core/backends/backend-router.d.ts.map +1 -0
  292. package/dist/core/backends/backend-router.js +759 -0
  293. package/dist/core/backends/backend-router.js.map +1 -0
  294. package/dist/core/backends/claude-code-core.d.ts +299 -0
  295. package/dist/core/backends/claude-code-core.d.ts.map +1 -0
  296. package/dist/core/backends/claude-code-core.js +2541 -0
  297. package/dist/core/backends/claude-code-core.js.map +1 -0
  298. package/dist/core/backends/claude-credentials-store.d.ts +83 -0
  299. package/dist/core/backends/claude-credentials-store.d.ts.map +1 -0
  300. package/dist/core/backends/claude-credentials-store.js +243 -0
  301. package/dist/core/backends/claude-credentials-store.js.map +1 -0
  302. package/dist/core/backends/cli-utils.d.ts +95 -0
  303. package/dist/core/backends/cli-utils.d.ts.map +1 -0
  304. package/dist/core/backends/cli-utils.js +464 -0
  305. package/dist/core/backends/cli-utils.js.map +1 -0
  306. package/dist/core/backends/codex-core.d.ts +127 -0
  307. package/dist/core/backends/codex-core.d.ts.map +1 -0
  308. package/dist/core/backends/codex-core.js +1693 -0
  309. package/dist/core/backends/codex-core.js.map +1 -0
  310. package/dist/core/backends/gemini-cli-core.d.ts +367 -0
  311. package/dist/core/backends/gemini-cli-core.d.ts.map +1 -0
  312. package/dist/core/backends/gemini-cli-core.js +2331 -0
  313. package/dist/core/backends/gemini-cli-core.js.map +1 -0
  314. package/dist/core/backends/idle-watchdog.d.ts +77 -0
  315. package/dist/core/backends/idle-watchdog.d.ts.map +1 -0
  316. package/dist/core/backends/idle-watchdog.js +94 -0
  317. package/dist/core/backends/idle-watchdog.js.map +1 -0
  318. package/dist/core/backends/install-methods.d.ts +93 -0
  319. package/dist/core/backends/install-methods.d.ts.map +1 -0
  320. package/dist/core/backends/install-methods.js +267 -0
  321. package/dist/core/backends/install-methods.js.map +1 -0
  322. package/dist/core/backends/model-registry.d.ts +58 -0
  323. package/dist/core/backends/model-registry.d.ts.map +1 -0
  324. package/dist/core/backends/model-registry.js +539 -0
  325. package/dist/core/backends/model-registry.js.map +1 -0
  326. package/dist/core/backends/plan-presets.d.ts +123 -0
  327. package/dist/core/backends/plan-presets.d.ts.map +1 -0
  328. package/dist/core/backends/plan-presets.js +235 -0
  329. package/dist/core/backends/plan-presets.js.map +1 -0
  330. package/dist/core/backends/price-fetcher.d.ts +48 -0
  331. package/dist/core/backends/price-fetcher.d.ts.map +1 -0
  332. package/dist/core/backends/price-fetcher.js +248 -0
  333. package/dist/core/backends/price-fetcher.js.map +1 -0
  334. package/dist/core/backends/process-config-cascade.d.ts +68 -0
  335. package/dist/core/backends/process-config-cascade.d.ts.map +1 -0
  336. package/dist/core/backends/process-config-cascade.js +173 -0
  337. package/dist/core/backends/process-config-cascade.js.map +1 -0
  338. package/dist/core/backends/prompt-utils.d.ts +6 -0
  339. package/dist/core/backends/prompt-utils.d.ts.map +1 -0
  340. package/dist/core/backends/prompt-utils.js +80 -0
  341. package/dist/core/backends/prompt-utils.js.map +1 -0
  342. package/dist/core/backends/proxy-model-registry.d.ts +110 -0
  343. package/dist/core/backends/proxy-model-registry.d.ts.map +1 -0
  344. package/dist/core/backends/proxy-model-registry.js +195 -0
  345. package/dist/core/backends/proxy-model-registry.js.map +1 -0
  346. package/dist/core/backends/silent-api-error-detector.d.ts +31 -0
  347. package/dist/core/backends/silent-api-error-detector.d.ts.map +1 -0
  348. package/dist/core/backends/silent-api-error-detector.js +44 -0
  349. package/dist/core/backends/silent-api-error-detector.js.map +1 -0
  350. package/dist/core/bang-commands/commands-cost.d.ts +13 -0
  351. package/dist/core/bang-commands/commands-cost.d.ts.map +1 -0
  352. package/dist/core/bang-commands/commands-cost.js +91 -0
  353. package/dist/core/bang-commands/commands-cost.js.map +1 -0
  354. package/dist/core/bang-commands/commands-report.d.ts +18 -0
  355. package/dist/core/bang-commands/commands-report.d.ts.map +1 -0
  356. package/dist/core/bang-commands/commands-report.js +105 -0
  357. package/dist/core/bang-commands/commands-report.js.map +1 -0
  358. package/dist/core/bang-commands/commands-stop-start.d.ts +4 -0
  359. package/dist/core/bang-commands/commands-stop-start.d.ts.map +1 -0
  360. package/dist/core/bang-commands/commands-stop-start.js +88 -0
  361. package/dist/core/bang-commands/commands-stop-start.js.map +1 -0
  362. package/dist/core/bang-commands/format-utils.d.ts +34 -0
  363. package/dist/core/bang-commands/format-utils.d.ts.map +1 -0
  364. package/dist/core/bang-commands/format-utils.js +118 -0
  365. package/dist/core/bang-commands/format-utils.js.map +1 -0
  366. package/dist/core/bang-commands/index.d.ts +20 -0
  367. package/dist/core/bang-commands/index.d.ts.map +1 -0
  368. package/dist/core/bang-commands/index.js +31 -0
  369. package/dist/core/bang-commands/index.js.map +1 -0
  370. package/dist/core/bang-commands/registry.d.ts +72 -0
  371. package/dist/core/bang-commands/registry.d.ts.map +1 -0
  372. package/dist/core/bang-commands/registry.js +174 -0
  373. package/dist/core/bang-commands/registry.js.map +1 -0
  374. package/dist/core/bang-commands/user-commands.d.ts +86 -0
  375. package/dist/core/bang-commands/user-commands.d.ts.map +1 -0
  376. package/dist/core/bang-commands/user-commands.js +212 -0
  377. package/dist/core/bang-commands/user-commands.js.map +1 -0
  378. package/dist/core/channel-timeline.d.ts +28 -0
  379. package/dist/core/channel-timeline.d.ts.map +1 -0
  380. package/dist/core/channel-timeline.js +117 -0
  381. package/dist/core/channel-timeline.js.map +1 -0
  382. package/dist/core/character-block.d.ts +37 -0
  383. package/dist/core/character-block.d.ts.map +1 -0
  384. package/dist/core/character-block.js +162 -0
  385. package/dist/core/character-block.js.map +1 -0
  386. package/dist/core/context/activity-sources.d.ts +37 -0
  387. package/dist/core/context/activity-sources.d.ts.map +1 -0
  388. package/dist/core/context/activity-sources.js +69 -0
  389. package/dist/core/context/activity-sources.js.map +1 -0
  390. package/dist/core/context/activity-view-reconciler.d.ts +110 -0
  391. package/dist/core/context/activity-view-reconciler.d.ts.map +1 -0
  392. package/dist/core/context/activity-view-reconciler.js +252 -0
  393. package/dist/core/context/activity-view-reconciler.js.map +1 -0
  394. package/dist/core/context/activity-view-runner.d.ts +38 -0
  395. package/dist/core/context/activity-view-runner.d.ts.map +1 -0
  396. package/dist/core/context/activity-view-runner.js +402 -0
  397. package/dist/core/context/activity-view-runner.js.map +1 -0
  398. package/dist/core/context/default-schedules-reconciler.d.ts +85 -0
  399. package/dist/core/context/default-schedules-reconciler.d.ts.map +1 -0
  400. package/dist/core/context/default-schedules-reconciler.js +153 -0
  401. package/dist/core/context/default-schedules-reconciler.js.map +1 -0
  402. package/dist/core/context/default-schedules-runner.d.ts +40 -0
  403. package/dist/core/context/default-schedules-runner.d.ts.map +1 -0
  404. package/dist/core/context/default-schedules-runner.js +233 -0
  405. package/dist/core/context/default-schedules-runner.js.map +1 -0
  406. package/dist/core/context/domain-index-reconciler.d.ts +81 -0
  407. package/dist/core/context/domain-index-reconciler.d.ts.map +1 -0
  408. package/dist/core/context/domain-index-reconciler.js +199 -0
  409. package/dist/core/context/domain-index-reconciler.js.map +1 -0
  410. package/dist/core/context/domain-index-runner.d.ts +35 -0
  411. package/dist/core/context/domain-index-runner.d.ts.map +1 -0
  412. package/dist/core/context/domain-index-runner.js +223 -0
  413. package/dist/core/context/domain-index-runner.js.map +1 -0
  414. package/dist/core/context/entity-mirror.d.ts +227 -0
  415. package/dist/core/context/entity-mirror.d.ts.map +1 -0
  416. package/dist/core/context/entity-mirror.js +629 -0
  417. package/dist/core/context/entity-mirror.js.map +1 -0
  418. package/dist/core/context/entity-source-rename.d.ts +61 -0
  419. package/dist/core/context/entity-source-rename.d.ts.map +1 -0
  420. package/dist/core/context/entity-source-rename.js +237 -0
  421. package/dist/core/context/entity-source-rename.js.map +1 -0
  422. package/dist/core/context/index-reconciler.d.ts +61 -0
  423. package/dist/core/context/index-reconciler.d.ts.map +1 -0
  424. package/dist/core/context/index-reconciler.js +329 -0
  425. package/dist/core/context/index-reconciler.js.map +1 -0
  426. package/dist/core/context/policy-index-reconciler.d.ts +102 -0
  427. package/dist/core/context/policy-index-reconciler.d.ts.map +1 -0
  428. package/dist/core/context/policy-index-reconciler.js +202 -0
  429. package/dist/core/context/policy-index-reconciler.js.map +1 -0
  430. package/dist/core/context/policy-index-runner.d.ts +66 -0
  431. package/dist/core/context/policy-index-runner.d.ts.map +1 -0
  432. package/dist/core/context/policy-index-runner.js +406 -0
  433. package/dist/core/context/policy-index-runner.js.map +1 -0
  434. package/dist/core/context/reconciler-runner.d.ts +44 -0
  435. package/dist/core/context/reconciler-runner.d.ts.map +1 -0
  436. package/dist/core/context/reconciler-runner.js +273 -0
  437. package/dist/core/context/reconciler-runner.js.map +1 -0
  438. package/dist/core/context-builder.d.ts +115 -0
  439. package/dist/core/context-builder.d.ts.map +1 -0
  440. package/dist/core/context-builder.js +1148 -0
  441. package/dist/core/context-builder.js.map +1 -0
  442. package/dist/core/context-frontmatter-backfill.d.ts +33 -0
  443. package/dist/core/context-frontmatter-backfill.d.ts.map +1 -0
  444. package/dist/core/context-frontmatter-backfill.js +111 -0
  445. package/dist/core/context-frontmatter-backfill.js.map +1 -0
  446. package/dist/core/context-frontmatter.d.ts +13 -0
  447. package/dist/core/context-frontmatter.d.ts.map +1 -0
  448. package/dist/core/context-frontmatter.js +325 -0
  449. package/dist/core/context-frontmatter.js.map +1 -0
  450. package/dist/core/context-health.d.ts +51 -0
  451. package/dist/core/context-health.d.ts.map +1 -0
  452. package/dist/core/context-health.js +304 -0
  453. package/dist/core/context-health.js.map +1 -0
  454. package/dist/core/context-paths.d.ts +183 -0
  455. package/dist/core/context-paths.d.ts.map +1 -0
  456. package/dist/core/context-paths.js +241 -0
  457. package/dist/core/context-paths.js.map +1 -0
  458. package/dist/core/context-staleness.d.ts +45 -0
  459. package/dist/core/context-staleness.d.ts.map +1 -0
  460. package/dist/core/context-staleness.js +88 -0
  461. package/dist/core/context-staleness.js.map +1 -0
  462. package/dist/core/custom-routine-scheduler.d.ts +151 -0
  463. package/dist/core/custom-routine-scheduler.d.ts.map +1 -0
  464. package/dist/core/custom-routine-scheduler.js +335 -0
  465. package/dist/core/custom-routine-scheduler.js.map +1 -0
  466. package/dist/core/daemon-api-cli.d.ts +33 -0
  467. package/dist/core/daemon-api-cli.d.ts.map +1 -0
  468. package/dist/core/daemon-api-cli.js +614 -0
  469. package/dist/core/daemon-api-cli.js.map +1 -0
  470. package/dist/core/dashboard-session-cleanup.d.ts +39 -0
  471. package/dist/core/dashboard-session-cleanup.d.ts.map +1 -0
  472. package/dist/core/dashboard-session-cleanup.js +108 -0
  473. package/dist/core/dashboard-session-cleanup.js.map +1 -0
  474. package/dist/core/dashboard-session-controls.d.ts +41 -0
  475. package/dist/core/dashboard-session-controls.d.ts.map +1 -0
  476. package/dist/core/dashboard-session-controls.js +154 -0
  477. package/dist/core/dashboard-session-controls.js.map +1 -0
  478. package/dist/core/delegated-connector-health.d.ts +63 -0
  479. package/dist/core/delegated-connector-health.d.ts.map +1 -0
  480. package/dist/core/delegated-connector-health.js +157 -0
  481. package/dist/core/delegated-connector-health.js.map +1 -0
  482. package/dist/core/dispatcher.d.ts +999 -0
  483. package/dist/core/dispatcher.d.ts.map +1 -0
  484. package/dist/core/dispatcher.js +4378 -0
  485. package/dist/core/dispatcher.js.map +1 -0
  486. package/dist/core/dm-freshness-metrics.d.ts +73 -0
  487. package/dist/core/dm-freshness-metrics.d.ts.map +1 -0
  488. package/dist/core/dm-freshness-metrics.js +138 -0
  489. package/dist/core/dm-freshness-metrics.js.map +1 -0
  490. package/dist/core/docs/citation-validator.d.ts +73 -0
  491. package/dist/core/docs/citation-validator.d.ts.map +1 -0
  492. package/dist/core/docs/citation-validator.js +195 -0
  493. package/dist/core/docs/citation-validator.js.map +1 -0
  494. package/dist/core/docs/extract-terms.d.ts +78 -0
  495. package/dist/core/docs/extract-terms.d.ts.map +1 -0
  496. package/dist/core/docs/extract-terms.js +147 -0
  497. package/dist/core/docs/extract-terms.js.map +1 -0
  498. package/dist/core/docs/indexer.d.ts +104 -0
  499. package/dist/core/docs/indexer.d.ts.map +1 -0
  500. package/dist/core/docs/indexer.js +340 -0
  501. package/dist/core/docs/indexer.js.map +1 -0
  502. package/dist/core/drift-effects.d.ts +30 -0
  503. package/dist/core/drift-effects.d.ts.map +1 -0
  504. package/dist/core/drift-effects.js +384 -0
  505. package/dist/core/drift-effects.js.map +1 -0
  506. package/dist/core/event-bus.d.ts +56 -0
  507. package/dist/core/event-bus.d.ts.map +1 -0
  508. package/dist/core/event-bus.js +135 -0
  509. package/dist/core/event-bus.js.map +1 -0
  510. package/dist/core/git-project-docs.d.ts +77 -0
  511. package/dist/core/git-project-docs.d.ts.map +1 -0
  512. package/dist/core/git-project-docs.js +439 -0
  513. package/dist/core/git-project-docs.js.map +1 -0
  514. package/dist/core/health-monitor.d.ts +57 -0
  515. package/dist/core/health-monitor.d.ts.map +1 -0
  516. package/dist/core/health-monitor.js +137 -0
  517. package/dist/core/health-monitor.js.map +1 -0
  518. package/dist/core/heartbeat.d.ts +26 -0
  519. package/dist/core/heartbeat.d.ts.map +1 -0
  520. package/dist/core/heartbeat.js +48 -0
  521. package/dist/core/heartbeat.js.map +1 -0
  522. package/dist/core/integration-health.d.ts +49 -0
  523. package/dist/core/integration-health.d.ts.map +1 -0
  524. package/dist/core/integration-health.js +89 -0
  525. package/dist/core/integration-health.js.map +1 -0
  526. package/dist/core/integration-lifecycle.d.ts +79 -0
  527. package/dist/core/integration-lifecycle.d.ts.map +1 -0
  528. package/dist/core/integration-lifecycle.js +153 -0
  529. package/dist/core/integration-lifecycle.js.map +1 -0
  530. package/dist/core/integration-main-backend.d.ts +36 -0
  531. package/dist/core/integration-main-backend.d.ts.map +1 -0
  532. package/dist/core/integration-main-backend.js +59 -0
  533. package/dist/core/integration-main-backend.js.map +1 -0
  534. package/dist/core/integration-probe.d.ts +98 -0
  535. package/dist/core/integration-probe.d.ts.map +1 -0
  536. package/dist/core/integration-probe.js +152 -0
  537. package/dist/core/integration-probe.js.map +1 -0
  538. package/dist/core/management-md-write-lock.d.ts +68 -0
  539. package/dist/core/management-md-write-lock.d.ts.map +1 -0
  540. package/dist/core/management-md-write-lock.js +93 -0
  541. package/dist/core/management-md-write-lock.js.map +1 -0
  542. package/dist/core/management-md.d.ts +186 -0
  543. package/dist/core/management-md.d.ts.map +1 -0
  544. package/dist/core/management-md.js +652 -0
  545. package/dist/core/management-md.js.map +1 -0
  546. package/dist/core/management-registry.d.ts +245 -0
  547. package/dist/core/management-registry.d.ts.map +1 -0
  548. package/dist/core/management-registry.js +906 -0
  549. package/dist/core/management-registry.js.map +1 -0
  550. package/dist/core/management-telemetry.d.ts +100 -0
  551. package/dist/core/management-telemetry.d.ts.map +1 -0
  552. package/dist/core/management-telemetry.js +156 -0
  553. package/dist/core/management-telemetry.js.map +1 -0
  554. package/dist/core/message-recorder.d.ts +38 -0
  555. package/dist/core/message-recorder.d.ts.map +1 -0
  556. package/dist/core/message-recorder.js +88 -0
  557. package/dist/core/message-recorder.js.map +1 -0
  558. package/dist/core/metrics.d.ts +338 -0
  559. package/dist/core/metrics.d.ts.map +1 -0
  560. package/dist/core/metrics.js +747 -0
  561. package/dist/core/metrics.js.map +1 -0
  562. package/dist/core/migration-backup.d.ts +218 -0
  563. package/dist/core/migration-backup.d.ts.map +1 -0
  564. package/dist/core/migration-backup.js +934 -0
  565. package/dist/core/migration-backup.js.map +1 -0
  566. package/dist/core/overview-write-lock.d.ts +48 -0
  567. package/dist/core/overview-write-lock.d.ts.map +1 -0
  568. package/dist/core/overview-write-lock.js +56 -0
  569. package/dist/core/overview-write-lock.js.map +1 -0
  570. package/dist/core/path-compat.d.ts +22 -0
  571. package/dist/core/path-compat.d.ts.map +1 -0
  572. package/dist/core/path-compat.js +67 -0
  573. package/dist/core/path-compat.js.map +1 -0
  574. package/dist/core/path-rewrite.d.ts +58 -0
  575. package/dist/core/path-rewrite.d.ts.map +1 -0
  576. package/dist/core/path-rewrite.js +141 -0
  577. package/dist/core/path-rewrite.js.map +1 -0
  578. package/dist/core/policy-files.d.ts +108 -0
  579. package/dist/core/policy-files.d.ts.map +1 -0
  580. package/dist/core/policy-files.js +198 -0
  581. package/dist/core/policy-files.js.map +1 -0
  582. package/dist/core/profile-questions/seed.d.ts +44 -0
  583. package/dist/core/profile-questions/seed.d.ts.map +1 -0
  584. package/dist/core/profile-questions/seed.js +173 -0
  585. package/dist/core/profile-questions/seed.js.map +1 -0
  586. package/dist/core/profile-questions/slot-filled.d.ts +51 -0
  587. package/dist/core/profile-questions/slot-filled.d.ts.map +1 -0
  588. package/dist/core/profile-questions/slot-filled.js +118 -0
  589. package/dist/core/profile-questions/slot-filled.js.map +1 -0
  590. package/dist/core/prompts.d.ts +111 -0
  591. package/dist/core/prompts.d.ts.map +1 -0
  592. package/dist/core/prompts.js +267 -0
  593. package/dist/core/prompts.js.map +1 -0
  594. package/dist/core/quiet-hours-sync.d.ts +15 -0
  595. package/dist/core/quiet-hours-sync.d.ts.map +1 -0
  596. package/dist/core/quiet-hours-sync.js +51 -0
  597. package/dist/core/quiet-hours-sync.js.map +1 -0
  598. package/dist/core/read-sensitive-token-manager.d.ts +19 -0
  599. package/dist/core/read-sensitive-token-manager.d.ts.map +1 -0
  600. package/dist/core/read-sensitive-token-manager.js +29 -0
  601. package/dist/core/read-sensitive-token-manager.js.map +1 -0
  602. package/dist/core/recurrence.d.ts +24 -0
  603. package/dist/core/recurrence.d.ts.map +1 -0
  604. package/dist/core/recurrence.js +162 -0
  605. package/dist/core/recurrence.js.map +1 -0
  606. package/dist/core/reinstall.d.ts +107 -0
  607. package/dist/core/reinstall.d.ts.map +1 -0
  608. package/dist/core/reinstall.js +163 -0
  609. package/dist/core/reinstall.js.map +1 -0
  610. package/dist/core/release-assets.d.ts +106 -0
  611. package/dist/core/release-assets.d.ts.map +1 -0
  612. package/dist/core/release-assets.js +434 -0
  613. package/dist/core/release-assets.js.map +1 -0
  614. package/dist/core/repository-management-docs.d.ts +216 -0
  615. package/dist/core/repository-management-docs.d.ts.map +1 -0
  616. package/dist/core/repository-management-docs.js +855 -0
  617. package/dist/core/repository-management-docs.js.map +1 -0
  618. package/dist/core/retention.d.ts +164 -0
  619. package/dist/core/retention.d.ts.map +1 -0
  620. package/dist/core/retention.js +1008 -0
  621. package/dist/core/retention.js.map +1 -0
  622. package/dist/core/review-context.d.ts +48 -0
  623. package/dist/core/review-context.d.ts.map +1 -0
  624. package/dist/core/review-context.js +282 -0
  625. package/dist/core/review-context.js.map +1 -0
  626. package/dist/core/roadmap-horizon.d.ts +48 -0
  627. package/dist/core/roadmap-horizon.d.ts.map +1 -0
  628. package/dist/core/roadmap-horizon.js +213 -0
  629. package/dist/core/roadmap-horizon.js.map +1 -0
  630. package/dist/core/roadmap-ids.d.ts +57 -0
  631. package/dist/core/roadmap-ids.d.ts.map +1 -0
  632. package/dist/core/roadmap-ids.js +118 -0
  633. package/dist/core/roadmap-ids.js.map +1 -0
  634. package/dist/core/roadmap-merge.d.ts +7 -0
  635. package/dist/core/roadmap-merge.d.ts.map +1 -0
  636. package/dist/core/roadmap-merge.js +187 -0
  637. package/dist/core/roadmap-merge.js.map +1 -0
  638. package/dist/core/roadmap-refresh-triggers.d.ts +32 -0
  639. package/dist/core/roadmap-refresh-triggers.d.ts.map +1 -0
  640. package/dist/core/roadmap-refresh-triggers.js +51 -0
  641. package/dist/core/roadmap-refresh-triggers.js.map +1 -0
  642. package/dist/core/roadmap-truncate.d.ts +49 -0
  643. package/dist/core/roadmap-truncate.d.ts.map +1 -0
  644. package/dist/core/roadmap-truncate.js +152 -0
  645. package/dist/core/roadmap-truncate.js.map +1 -0
  646. package/dist/core/roadmap-validate.d.ts +31 -0
  647. package/dist/core/roadmap-validate.d.ts.map +1 -0
  648. package/dist/core/roadmap-validate.js +403 -0
  649. package/dist/core/roadmap-validate.js.map +1 -0
  650. package/dist/core/roadmap-write-lock.d.ts +53 -0
  651. package/dist/core/roadmap-write-lock.d.ts.map +1 -0
  652. package/dist/core/roadmap-write-lock.js +59 -0
  653. package/dist/core/roadmap-write-lock.js.map +1 -0
  654. package/dist/core/schedule-insert-helper.d.ts +46 -0
  655. package/dist/core/schedule-insert-helper.d.ts.map +1 -0
  656. package/dist/core/schedule-insert-helper.js +52 -0
  657. package/dist/core/schedule-insert-helper.js.map +1 -0
  658. package/dist/core/schedule-maintenance.d.ts +22 -0
  659. package/dist/core/schedule-maintenance.d.ts.map +1 -0
  660. package/dist/core/schedule-maintenance.js +57 -0
  661. package/dist/core/schedule-maintenance.js.map +1 -0
  662. package/dist/core/scheduler.d.ts +208 -0
  663. package/dist/core/scheduler.d.ts.map +1 -0
  664. package/dist/core/scheduler.js +896 -0
  665. package/dist/core/scheduler.js.map +1 -0
  666. package/dist/core/semaphore.d.ts +13 -0
  667. package/dist/core/semaphore.d.ts.map +1 -0
  668. package/dist/core/semaphore.js +31 -0
  669. package/dist/core/semaphore.js.map +1 -0
  670. package/dist/core/session-gate.d.ts +37 -0
  671. package/dist/core/session-gate.d.ts.map +1 -0
  672. package/dist/core/session-gate.js +69 -0
  673. package/dist/core/session-gate.js.map +1 -0
  674. package/dist/core/session-manager.d.ts +252 -0
  675. package/dist/core/session-manager.d.ts.map +1 -0
  676. package/dist/core/session-manager.js +716 -0
  677. package/dist/core/session-manager.js.map +1 -0
  678. package/dist/core/signal-detector.d.ts +97 -0
  679. package/dist/core/signal-detector.d.ts.map +1 -0
  680. package/dist/core/signal-detector.js +215 -0
  681. package/dist/core/signal-detector.js.map +1 -0
  682. package/dist/core/skeleton.d.ts +83 -0
  683. package/dist/core/skeleton.d.ts.map +1 -0
  684. package/dist/core/skeleton.js +255 -0
  685. package/dist/core/skeleton.js.map +1 -0
  686. package/dist/core/skill-curation/apply-proposal.d.ts +71 -0
  687. package/dist/core/skill-curation/apply-proposal.d.ts.map +1 -0
  688. package/dist/core/skill-curation/apply-proposal.js +175 -0
  689. package/dist/core/skill-curation/apply-proposal.js.map +1 -0
  690. package/dist/core/skill-curation/auto-revert.d.ts +43 -0
  691. package/dist/core/skill-curation/auto-revert.d.ts.map +1 -0
  692. package/dist/core/skill-curation/auto-revert.js +155 -0
  693. package/dist/core/skill-curation/auto-revert.js.map +1 -0
  694. package/dist/core/skill-curation/classify-diff.d.ts +27 -0
  695. package/dist/core/skill-curation/classify-diff.d.ts.map +1 -0
  696. package/dist/core/skill-curation/classify-diff.js +0 -0
  697. package/dist/core/skill-curation/classify-diff.js.map +1 -0
  698. package/dist/core/skill-curation/declarations.d.ts +32 -0
  699. package/dist/core/skill-curation/declarations.d.ts.map +1 -0
  700. package/dist/core/skill-curation/declarations.js +171 -0
  701. package/dist/core/skill-curation/declarations.js.map +1 -0
  702. package/dist/core/skill-curation/knowledge-map.d.ts +26 -0
  703. package/dist/core/skill-curation/knowledge-map.d.ts.map +1 -0
  704. package/dist/core/skill-curation/knowledge-map.js +154 -0
  705. package/dist/core/skill-curation/knowledge-map.js.map +1 -0
  706. package/dist/core/skill-curation/orphan-overlay.d.ts +35 -0
  707. package/dist/core/skill-curation/orphan-overlay.d.ts.map +1 -0
  708. package/dist/core/skill-curation/orphan-overlay.js +167 -0
  709. package/dist/core/skill-curation/orphan-overlay.js.map +1 -0
  710. package/dist/core/skill-curation/overlay-store.d.ts +41 -0
  711. package/dist/core/skill-curation/overlay-store.d.ts.map +1 -0
  712. package/dist/core/skill-curation/overlay-store.js +143 -0
  713. package/dist/core/skill-curation/overlay-store.js.map +1 -0
  714. package/dist/core/skill-curation/render/convention-notes.d.ts +4 -0
  715. package/dist/core/skill-curation/render/convention-notes.d.ts.map +1 -0
  716. package/dist/core/skill-curation/render/convention-notes.js +13 -0
  717. package/dist/core/skill-curation/render/convention-notes.js.map +1 -0
  718. package/dist/core/skill-curation/render/cross-references.d.ts +4 -0
  719. package/dist/core/skill-curation/render/cross-references.d.ts.map +1 -0
  720. package/dist/core/skill-curation/render/cross-references.js +10 -0
  721. package/dist/core/skill-curation/render/cross-references.js.map +1 -0
  722. package/dist/core/skill-curation/render/frontmatter-schema.d.ts +4 -0
  723. package/dist/core/skill-curation/render/frontmatter-schema.d.ts.map +1 -0
  724. package/dist/core/skill-curation/render/frontmatter-schema.js +25 -0
  725. package/dist/core/skill-curation/render/frontmatter-schema.js.map +1 -0
  726. package/dist/core/skill-curation/render/index.d.ts +5 -0
  727. package/dist/core/skill-curation/render/index.d.ts.map +1 -0
  728. package/dist/core/skill-curation/render/index.js +42 -0
  729. package/dist/core/skill-curation/render/index.js.map +1 -0
  730. package/dist/core/skill-curation/render/knowledge-layout.d.ts +4 -0
  731. package/dist/core/skill-curation/render/knowledge-layout.d.ts.map +1 -0
  732. package/dist/core/skill-curation/render/knowledge-layout.js +36 -0
  733. package/dist/core/skill-curation/render/knowledge-layout.js.map +1 -0
  734. package/dist/core/skill-curation/render/routing-table.d.ts +4 -0
  735. package/dist/core/skill-curation/render/routing-table.d.ts.map +1 -0
  736. package/dist/core/skill-curation/render/routing-table.js +37 -0
  737. package/dist/core/skill-curation/render/routing-table.js.map +1 -0
  738. package/dist/core/skill-curation/render/search-recipes.d.ts +4 -0
  739. package/dist/core/skill-curation/render/search-recipes.d.ts.map +1 -0
  740. package/dist/core/skill-curation/render/search-recipes.js +39 -0
  741. package/dist/core/skill-curation/render/search-recipes.js.map +1 -0
  742. package/dist/core/skill-curation/run-token.d.ts +27 -0
  743. package/dist/core/skill-curation/run-token.d.ts.map +1 -0
  744. package/dist/core/skill-curation/run-token.js +81 -0
  745. package/dist/core/skill-curation/run-token.js.map +1 -0
  746. package/dist/core/skill-curation/signals.d.ts +49 -0
  747. package/dist/core/skill-curation/signals.d.ts.map +1 -0
  748. package/dist/core/skill-curation/signals.js +149 -0
  749. package/dist/core/skill-curation/signals.js.map +1 -0
  750. package/dist/core/skill-curation/smoke-test.d.ts +39 -0
  751. package/dist/core/skill-curation/smoke-test.d.ts.map +1 -0
  752. package/dist/core/skill-curation/smoke-test.js +313 -0
  753. package/dist/core/skill-curation/smoke-test.js.map +1 -0
  754. package/dist/core/skill-curation/splicer.d.ts +16 -0
  755. package/dist/core/skill-curation/splicer.d.ts.map +1 -0
  756. package/dist/core/skill-curation/splicer.js +78 -0
  757. package/dist/core/skill-curation/splicer.js.map +1 -0
  758. package/dist/core/skill-curation/workdir.d.ts +40 -0
  759. package/dist/core/skill-curation/workdir.d.ts.map +1 -0
  760. package/dist/core/skill-curation/workdir.js +242 -0
  761. package/dist/core/skill-curation/workdir.js.map +1 -0
  762. package/dist/core/skills-compiler.d.ts +391 -0
  763. package/dist/core/skills-compiler.d.ts.map +1 -0
  764. package/dist/core/skills-compiler.js +1271 -0
  765. package/dist/core/skills-compiler.js.map +1 -0
  766. package/dist/core/skills-manifest.d.ts +8 -0
  767. package/dist/core/skills-manifest.d.ts.map +1 -0
  768. package/dist/core/skills-manifest.js +408 -0
  769. package/dist/core/skills-manifest.js.map +1 -0
  770. package/dist/core/system-reset.d.ts +268 -0
  771. package/dist/core/system-reset.d.ts.map +1 -0
  772. package/dist/core/system-reset.js +816 -0
  773. package/dist/core/system-reset.js.map +1 -0
  774. package/dist/core/template-store.d.ts +170 -0
  775. package/dist/core/template-store.d.ts.map +1 -0
  776. package/dist/core/template-store.js +388 -0
  777. package/dist/core/template-store.js.map +1 -0
  778. package/dist/core/template-versions.d.ts +95 -0
  779. package/dist/core/template-versions.d.ts.map +1 -0
  780. package/dist/core/template-versions.js +175 -0
  781. package/dist/core/template-versions.js.map +1 -0
  782. package/dist/core/today-agent-plan.d.ts +33 -0
  783. package/dist/core/today-agent-plan.d.ts.map +1 -0
  784. package/dist/core/today-agent-plan.js +120 -0
  785. package/dist/core/today-agent-plan.js.map +1 -0
  786. package/dist/core/today-direct-writer.d.ts +62 -0
  787. package/dist/core/today-direct-writer.d.ts.map +1 -0
  788. package/dist/core/today-direct-writer.js +132 -0
  789. package/dist/core/today-direct-writer.js.map +1 -0
  790. package/dist/core/today-write-lock.d.ts +89 -0
  791. package/dist/core/today-write-lock.d.ts.map +1 -0
  792. package/dist/core/today-write-lock.js +154 -0
  793. package/dist/core/today-write-lock.js.map +1 -0
  794. package/dist/core/trigger-dispatch.d.ts +31 -0
  795. package/dist/core/trigger-dispatch.d.ts.map +1 -0
  796. package/dist/core/trigger-dispatch.js +100 -0
  797. package/dist/core/trigger-dispatch.js.map +1 -0
  798. package/dist/core/trigger-evaluator.d.ts +59 -0
  799. package/dist/core/trigger-evaluator.d.ts.map +1 -0
  800. package/dist/core/trigger-evaluator.js +243 -0
  801. package/dist/core/trigger-evaluator.js.map +1 -0
  802. package/dist/core/workdir.d.ts +241 -0
  803. package/dist/core/workdir.d.ts.map +1 -0
  804. package/dist/core/workdir.js +565 -0
  805. package/dist/core/workdir.js.map +1 -0
  806. package/dist/db/automation-triggers.d.ts +90 -0
  807. package/dist/db/automation-triggers.d.ts.map +1 -0
  808. package/dist/db/automation-triggers.js +199 -0
  809. package/dist/db/automation-triggers.js.map +1 -0
  810. package/dist/db/client.d.ts +6 -0
  811. package/dist/db/client.d.ts.map +1 -0
  812. package/dist/db/client.js +47 -0
  813. package/dist/db/client.js.map +1 -0
  814. package/dist/db/entities-store.d.ts +92 -0
  815. package/dist/db/entities-store.d.ts.map +1 -0
  816. package/dist/db/entities-store.js +180 -0
  817. package/dist/db/entities-store.js.map +1 -0
  818. package/dist/db/hourly-check-signals.d.ts +78 -0
  819. package/dist/db/hourly-check-signals.d.ts.map +1 -0
  820. package/dist/db/hourly-check-signals.js +289 -0
  821. package/dist/db/hourly-check-signals.js.map +1 -0
  822. package/dist/db/integration-probe-store.d.ts +27 -0
  823. package/dist/db/integration-probe-store.d.ts.map +1 -0
  824. package/dist/db/integration-probe-store.js +75 -0
  825. package/dist/db/integration-probe-store.js.map +1 -0
  826. package/dist/db/integrations-store.d.ts +19 -0
  827. package/dist/db/integrations-store.d.ts.map +1 -0
  828. package/dist/db/integrations-store.js +85 -0
  829. package/dist/db/integrations-store.js.map +1 -0
  830. package/dist/db/managed-tasks-store.d.ts +130 -0
  831. package/dist/db/managed-tasks-store.d.ts.map +1 -0
  832. package/dist/db/managed-tasks-store.js +238 -0
  833. package/dist/db/managed-tasks-store.js.map +1 -0
  834. package/dist/db/management-parse-failures-store.d.ts +45 -0
  835. package/dist/db/management-parse-failures-store.d.ts.map +1 -0
  836. package/dist/db/management-parse-failures-store.js +36 -0
  837. package/dist/db/management-parse-failures-store.js.map +1 -0
  838. package/dist/db/observations.d.ts +145 -0
  839. package/dist/db/observations.d.ts.map +1 -0
  840. package/dist/db/observations.js +287 -0
  841. package/dist/db/observations.js.map +1 -0
  842. package/dist/db/recurring-schedules.d.ts +70 -0
  843. package/dist/db/recurring-schedules.d.ts.map +1 -0
  844. package/dist/db/recurring-schedules.js +213 -0
  845. package/dist/db/recurring-schedules.js.map +1 -0
  846. package/dist/db/repositories-store.d.ts +296 -0
  847. package/dist/db/repositories-store.d.ts.map +1 -0
  848. package/dist/db/repositories-store.js +754 -0
  849. package/dist/db/repositories-store.js.map +1 -0
  850. package/dist/db/runtime-state.d.ts +61 -0
  851. package/dist/db/runtime-state.d.ts.map +1 -0
  852. package/dist/db/runtime-state.js +104 -0
  853. package/dist/db/runtime-state.js.map +1 -0
  854. package/dist/db/schema.d.ts +4 -0
  855. package/dist/db/schema.d.ts.map +1 -0
  856. package/dist/db/schema.js +1338 -0
  857. package/dist/db/schema.js.map +1 -0
  858. package/dist/db/sot-bindings-store.d.ts +41 -0
  859. package/dist/db/sot-bindings-store.d.ts.map +1 -0
  860. package/dist/db/sot-bindings-store.js +64 -0
  861. package/dist/db/sot-bindings-store.js.map +1 -0
  862. package/dist/db/test-schemas.d.ts +23 -0
  863. package/dist/db/test-schemas.d.ts.map +1 -0
  864. package/dist/db/test-schemas.js +111 -0
  865. package/dist/db/test-schemas.js.map +1 -0
  866. package/dist/db/voice-transcripts-store.d.ts +28 -0
  867. package/dist/db/voice-transcripts-store.d.ts.map +1 -0
  868. package/dist/db/voice-transcripts-store.js +43 -0
  869. package/dist/db/voice-transcripts-store.js.map +1 -0
  870. package/dist/index.d.ts +2 -0
  871. package/dist/index.d.ts.map +1 -0
  872. package/dist/index.js +2913 -0
  873. package/dist/index.js.map +1 -0
  874. package/dist/init.d.ts +7 -0
  875. package/dist/init.d.ts.map +1 -0
  876. package/dist/init.js +32 -0
  877. package/dist/init.js.map +1 -0
  878. package/dist/log-buffer.d.ts +71 -0
  879. package/dist/log-buffer.d.ts.map +1 -0
  880. package/dist/log-buffer.js +201 -0
  881. package/dist/log-buffer.js.map +1 -0
  882. package/dist/logging.d.ts +5 -0
  883. package/dist/logging.d.ts.map +1 -0
  884. package/dist/logging.js +130 -0
  885. package/dist/logging.js.map +1 -0
  886. package/dist/management-rules.d.ts +2 -0
  887. package/dist/management-rules.d.ts.map +1 -0
  888. package/dist/management-rules.js +62 -0
  889. package/dist/management-rules.js.map +1 -0
  890. package/dist/messaging/constants.d.ts +33 -0
  891. package/dist/messaging/constants.d.ts.map +1 -0
  892. package/dist/messaging/constants.js +52 -0
  893. package/dist/messaging/constants.js.map +1 -0
  894. package/dist/messaging/magic-phrase.d.ts +16 -0
  895. package/dist/messaging/magic-phrase.d.ts.map +1 -0
  896. package/dist/messaging/magic-phrase.js +103 -0
  897. package/dist/messaging/magic-phrase.js.map +1 -0
  898. package/dist/messaging/owner-channels.d.ts +20 -0
  899. package/dist/messaging/owner-channels.d.ts.map +1 -0
  900. package/dist/messaging/owner-channels.js +41 -0
  901. package/dist/messaging/owner-channels.js.map +1 -0
  902. package/dist/observers/calendar-poller.d.ts +51 -0
  903. package/dist/observers/calendar-poller.d.ts.map +1 -0
  904. package/dist/observers/calendar-poller.js +128 -0
  905. package/dist/observers/calendar-poller.js.map +1 -0
  906. package/dist/observers/context-index-reconciler-observer.d.ts +72 -0
  907. package/dist/observers/context-index-reconciler-observer.d.ts.map +1 -0
  908. package/dist/observers/context-index-reconciler-observer.js +253 -0
  909. package/dist/observers/context-index-reconciler-observer.js.map +1 -0
  910. package/dist/observers/delegated-probe-observer.d.ts +83 -0
  911. package/dist/observers/delegated-probe-observer.d.ts.map +1 -0
  912. package/dist/observers/delegated-probe-observer.js +237 -0
  913. package/dist/observers/delegated-probe-observer.js.map +1 -0
  914. package/dist/observers/delegated-sync-worker.d.ts +375 -0
  915. package/dist/observers/delegated-sync-worker.d.ts.map +1 -0
  916. package/dist/observers/delegated-sync-worker.js +1087 -0
  917. package/dist/observers/delegated-sync-worker.js.map +1 -0
  918. package/dist/observers/entity-mirror-observer.d.ts +55 -0
  919. package/dist/observers/entity-mirror-observer.d.ts.map +1 -0
  920. package/dist/observers/entity-mirror-observer.js +73 -0
  921. package/dist/observers/entity-mirror-observer.js.map +1 -0
  922. package/dist/observers/git-delegated-cron.d.ts +41 -0
  923. package/dist/observers/git-delegated-cron.d.ts.map +1 -0
  924. package/dist/observers/git-delegated-cron.js +159 -0
  925. package/dist/observers/git-delegated-cron.js.map +1 -0
  926. package/dist/observers/git-event-classifier.d.ts +52 -0
  927. package/dist/observers/git-event-classifier.d.ts.map +1 -0
  928. package/dist/observers/git-event-classifier.js +70 -0
  929. package/dist/observers/git-event-classifier.js.map +1 -0
  930. package/dist/observers/git-watcher.d.ts +162 -0
  931. package/dist/observers/git-watcher.d.ts.map +1 -0
  932. package/dist/observers/git-watcher.js +768 -0
  933. package/dist/observers/git-watcher.js.map +1 -0
  934. package/dist/observers/github-poller-classifier.d.ts +101 -0
  935. package/dist/observers/github-poller-classifier.d.ts.map +1 -0
  936. package/dist/observers/github-poller-classifier.js +199 -0
  937. package/dist/observers/github-poller-classifier.js.map +1 -0
  938. package/dist/observers/github-poller.d.ts +291 -0
  939. package/dist/observers/github-poller.d.ts.map +1 -0
  940. package/dist/observers/github-poller.js +609 -0
  941. package/dist/observers/github-poller.js.map +1 -0
  942. package/dist/observers/imminent-event-scheduler.d.ts +34 -0
  943. package/dist/observers/imminent-event-scheduler.d.ts.map +1 -0
  944. package/dist/observers/imminent-event-scheduler.js +125 -0
  945. package/dist/observers/imminent-event-scheduler.js.map +1 -0
  946. package/dist/observers/mail-poller.d.ts +133 -0
  947. package/dist/observers/mail-poller.d.ts.map +1 -0
  948. package/dist/observers/mail-poller.js +563 -0
  949. package/dist/observers/mail-poller.js.map +1 -0
  950. package/dist/observers/mail-reconciliation.d.ts +87 -0
  951. package/dist/observers/mail-reconciliation.d.ts.map +1 -0
  952. package/dist/observers/mail-reconciliation.js +241 -0
  953. package/dist/observers/mail-reconciliation.js.map +1 -0
  954. package/dist/observers/manager.d.ts +67 -0
  955. package/dist/observers/manager.d.ts.map +1 -0
  956. package/dist/observers/manager.js +136 -0
  957. package/dist/observers/manager.js.map +1 -0
  958. package/dist/observers/notion-poller.d.ts +43 -0
  959. package/dist/observers/notion-poller.d.ts.map +1 -0
  960. package/dist/observers/notion-poller.js +184 -0
  961. package/dist/observers/notion-poller.js.map +1 -0
  962. package/dist/observers/observation-summarizer/index.d.ts +13 -0
  963. package/dist/observers/observation-summarizer/index.d.ts.map +1 -0
  964. package/dist/observers/observation-summarizer/index.js +13 -0
  965. package/dist/observers/observation-summarizer/index.js.map +1 -0
  966. package/dist/observers/observation-summarizer/pre-filter.d.ts +62 -0
  967. package/dist/observers/observation-summarizer/pre-filter.d.ts.map +1 -0
  968. package/dist/observers/observation-summarizer/pre-filter.js +189 -0
  969. package/dist/observers/observation-summarizer/pre-filter.js.map +1 -0
  970. package/dist/observers/observation-summarizer/response-parser.d.ts +30 -0
  971. package/dist/observers/observation-summarizer/response-parser.d.ts.map +1 -0
  972. package/dist/observers/observation-summarizer/response-parser.js +106 -0
  973. package/dist/observers/observation-summarizer/response-parser.js.map +1 -0
  974. package/dist/observers/observation-summarizer/summarizer-client.d.ts +83 -0
  975. package/dist/observers/observation-summarizer/summarizer-client.d.ts.map +1 -0
  976. package/dist/observers/observation-summarizer/summarizer-client.js +185 -0
  977. package/dist/observers/observation-summarizer/summarizer-client.js.map +1 -0
  978. package/dist/observers/observation-summarizer/summarizer-prompts.d.ts +51 -0
  979. package/dist/observers/observation-summarizer/summarizer-prompts.d.ts.map +1 -0
  980. package/dist/observers/observation-summarizer/summarizer-prompts.js +286 -0
  981. package/dist/observers/observation-summarizer/summarizer-prompts.js.map +1 -0
  982. package/dist/observers/observation-summarizer/worker.d.ts +106 -0
  983. package/dist/observers/observation-summarizer/worker.d.ts.map +1 -0
  984. package/dist/observers/observation-summarizer/worker.js +311 -0
  985. package/dist/observers/observation-summarizer/worker.js.map +1 -0
  986. package/dist/observers/obsidian-watcher.d.ts +90 -0
  987. package/dist/observers/obsidian-watcher.d.ts.map +1 -0
  988. package/dist/observers/obsidian-watcher.js +166 -0
  989. package/dist/observers/obsidian-watcher.js.map +1 -0
  990. package/dist/observers/primary-vault-watcher.d.ts +73 -0
  991. package/dist/observers/primary-vault-watcher.d.ts.map +1 -0
  992. package/dist/observers/primary-vault-watcher.js +115 -0
  993. package/dist/observers/primary-vault-watcher.js.map +1 -0
  994. package/dist/observers/repository-management-cron.d.ts +70 -0
  995. package/dist/observers/repository-management-cron.d.ts.map +1 -0
  996. package/dist/observers/repository-management-cron.js +166 -0
  997. package/dist/observers/repository-management-cron.js.map +1 -0
  998. package/dist/observers/skill-curation-walker.d.ts +33 -0
  999. package/dist/observers/skill-curation-walker.d.ts.map +1 -0
  1000. package/dist/observers/skill-curation-walker.js +216 -0
  1001. package/dist/observers/skill-curation-walker.js.map +1 -0
  1002. package/dist/safety/absolute-block-audit.d.ts +22 -0
  1003. package/dist/safety/absolute-block-audit.d.ts.map +1 -0
  1004. package/dist/safety/absolute-block-audit.js +32 -0
  1005. package/dist/safety/absolute-block-audit.js.map +1 -0
  1006. package/dist/safety/agent-write-tracker.d.ts +42 -0
  1007. package/dist/safety/agent-write-tracker.d.ts.map +1 -0
  1008. package/dist/safety/agent-write-tracker.js +82 -0
  1009. package/dist/safety/agent-write-tracker.js.map +1 -0
  1010. package/dist/safety/always-disallowed.d.ts +66 -0
  1011. package/dist/safety/always-disallowed.d.ts.map +1 -0
  1012. package/dist/safety/always-disallowed.js +347 -0
  1013. package/dist/safety/always-disallowed.js.map +1 -0
  1014. package/dist/safety/audit.d.ts +118 -0
  1015. package/dist/safety/audit.d.ts.map +1 -0
  1016. package/dist/safety/audit.js +324 -0
  1017. package/dist/safety/audit.js.map +1 -0
  1018. package/dist/safety/integration-write-tracker.d.ts +58 -0
  1019. package/dist/safety/integration-write-tracker.d.ts.map +1 -0
  1020. package/dist/safety/integration-write-tracker.js +41 -0
  1021. package/dist/safety/integration-write-tracker.js.map +1 -0
  1022. package/dist/safety/risk-classifier.d.ts +65 -0
  1023. package/dist/safety/risk-classifier.d.ts.map +1 -0
  1024. package/dist/safety/risk-classifier.js +763 -0
  1025. package/dist/safety/risk-classifier.js.map +1 -0
  1026. package/dist/scheduler/hourly-check-gate.d.ts +73 -0
  1027. package/dist/scheduler/hourly-check-gate.d.ts.map +1 -0
  1028. package/dist/scheduler/hourly-check-gate.js +128 -0
  1029. package/dist/scheduler/hourly-check-gate.js.map +1 -0
  1030. package/dist/secrets/backend-api-key-env.d.ts +104 -0
  1031. package/dist/secrets/backend-api-key-env.d.ts.map +1 -0
  1032. package/dist/secrets/backend-api-key-env.js +197 -0
  1033. package/dist/secrets/backend-api-key-env.js.map +1 -0
  1034. package/dist/secrets/codex-home-materializer.d.ts +35 -0
  1035. package/dist/secrets/codex-home-materializer.d.ts.map +1 -0
  1036. package/dist/secrets/codex-home-materializer.js +76 -0
  1037. package/dist/secrets/codex-home-materializer.js.map +1 -0
  1038. package/dist/secrets/encrypted-blob-store.d.ts +20 -0
  1039. package/dist/secrets/encrypted-blob-store.d.ts.map +1 -0
  1040. package/dist/secrets/encrypted-blob-store.js +80 -0
  1041. package/dist/secrets/encrypted-blob-store.js.map +1 -0
  1042. package/dist/secrets/platform-secret-store.d.ts +17 -0
  1043. package/dist/secrets/platform-secret-store.d.ts.map +1 -0
  1044. package/dist/secrets/platform-secret-store.js +37 -0
  1045. package/dist/secrets/platform-secret-store.js.map +1 -0
  1046. package/dist/secrets/redaction.d.ts +2 -0
  1047. package/dist/secrets/redaction.d.ts.map +1 -0
  1048. package/dist/secrets/redaction.js +2 -0
  1049. package/dist/secrets/redaction.js.map +1 -0
  1050. package/dist/secrets/secret-broker.d.ts +61 -0
  1051. package/dist/secrets/secret-broker.d.ts.map +1 -0
  1052. package/dist/secrets/secret-broker.js +160 -0
  1053. package/dist/secrets/secret-broker.js.map +1 -0
  1054. package/dist/secrets/secret-names.d.ts +34 -0
  1055. package/dist/secrets/secret-names.d.ts.map +1 -0
  1056. package/dist/secrets/secret-names.js +39 -0
  1057. package/dist/secrets/secret-names.js.map +1 -0
  1058. package/dist/secrets/secret-store.d.ts +8 -0
  1059. package/dist/secrets/secret-store.d.ts.map +1 -0
  1060. package/dist/secrets/secret-store.js +2 -0
  1061. package/dist/secrets/secret-store.js.map +1 -0
  1062. package/dist/secrets/types.d.ts +7 -0
  1063. package/dist/secrets/types.d.ts.map +1 -0
  1064. package/dist/secrets/types.js +2 -0
  1065. package/dist/secrets/types.js.map +1 -0
  1066. package/dist/services/apple-calendar/caldav-client.d.ts +48 -0
  1067. package/dist/services/apple-calendar/caldav-client.d.ts.map +1 -0
  1068. package/dist/services/apple-calendar/caldav-client.js +86 -0
  1069. package/dist/services/apple-calendar/caldav-client.js.map +1 -0
  1070. package/dist/services/apple-calendar/caldav-codec.d.ts +67 -0
  1071. package/dist/services/apple-calendar/caldav-codec.d.ts.map +1 -0
  1072. package/dist/services/apple-calendar/caldav-codec.js +341 -0
  1073. package/dist/services/apple-calendar/caldav-codec.js.map +1 -0
  1074. package/dist/services/apple-calendar/index.d.ts +3 -0
  1075. package/dist/services/apple-calendar/index.d.ts.map +1 -0
  1076. package/dist/services/apple-calendar/index.js +2 -0
  1077. package/dist/services/apple-calendar/index.js.map +1 -0
  1078. package/dist/services/apple-calendar/service.d.ts +75 -0
  1079. package/dist/services/apple-calendar/service.d.ts.map +1 -0
  1080. package/dist/services/apple-calendar/service.js +374 -0
  1081. package/dist/services/apple-calendar/service.js.map +1 -0
  1082. package/dist/services/apple-calendar/types.d.ts +78 -0
  1083. package/dist/services/apple-calendar/types.d.ts.map +1 -0
  1084. package/dist/services/apple-calendar/types.js +17 -0
  1085. package/dist/services/apple-calendar/types.js.map +1 -0
  1086. package/dist/services/attachments/hardlink.d.ts +11 -0
  1087. package/dist/services/attachments/hardlink.d.ts.map +1 -0
  1088. package/dist/services/attachments/hardlink.js +56 -0
  1089. package/dist/services/attachments/hardlink.js.map +1 -0
  1090. package/dist/services/attachments/sanitize.d.ts +21 -0
  1091. package/dist/services/attachments/sanitize.d.ts.map +1 -0
  1092. package/dist/services/attachments/sanitize.js +128 -0
  1093. package/dist/services/attachments/sanitize.js.map +1 -0
  1094. package/dist/services/attachments/store.d.ts +146 -0
  1095. package/dist/services/attachments/store.d.ts.map +1 -0
  1096. package/dist/services/attachments/store.js +477 -0
  1097. package/dist/services/attachments/store.js.map +1 -0
  1098. package/dist/services/calendar/outlook/graph-calendar-client.d.ts +114 -0
  1099. package/dist/services/calendar/outlook/graph-calendar-client.d.ts.map +1 -0
  1100. package/dist/services/calendar/outlook/graph-calendar-client.js +146 -0
  1101. package/dist/services/calendar/outlook/graph-calendar-client.js.map +1 -0
  1102. package/dist/services/calendar.d.ts +115 -0
  1103. package/dist/services/calendar.d.ts.map +1 -0
  1104. package/dist/services/calendar.js +281 -0
  1105. package/dist/services/calendar.js.map +1 -0
  1106. package/dist/services/delegated-backend-invoker.d.ts +414 -0
  1107. package/dist/services/delegated-backend-invoker.d.ts.map +1 -0
  1108. package/dist/services/delegated-backend-invoker.js +2372 -0
  1109. package/dist/services/delegated-backend-invoker.js.map +1 -0
  1110. package/dist/services/delegated-proxy-config.d.ts +93 -0
  1111. package/dist/services/delegated-proxy-config.d.ts.map +1 -0
  1112. package/dist/services/delegated-proxy-config.js +98 -0
  1113. package/dist/services/delegated-proxy-config.js.map +1 -0
  1114. package/dist/services/delegated-task-result-cache.d.ts +176 -0
  1115. package/dist/services/delegated-task-result-cache.d.ts.map +1 -0
  1116. package/dist/services/delegated-task-result-cache.js +0 -0
  1117. package/dist/services/delegated-task-result-cache.js.map +1 -0
  1118. package/dist/services/delegated-task-runtime.d.ts +346 -0
  1119. package/dist/services/delegated-task-runtime.d.ts.map +1 -0
  1120. package/dist/services/delegated-task-runtime.js +589 -0
  1121. package/dist/services/delegated-task-runtime.js.map +1 -0
  1122. package/dist/services/delegated-task-session-pool.d.ts +182 -0
  1123. package/dist/services/delegated-task-session-pool.d.ts.map +1 -0
  1124. package/dist/services/delegated-task-session-pool.js +292 -0
  1125. package/dist/services/delegated-task-session-pool.js.map +1 -0
  1126. package/dist/services/delegated-tool-runtime.d.ts +50 -0
  1127. package/dist/services/delegated-tool-runtime.d.ts.map +1 -0
  1128. package/dist/services/delegated-tool-runtime.js +120 -0
  1129. package/dist/services/delegated-tool-runtime.js.map +1 -0
  1130. package/dist/services/fts5.d.ts +40 -0
  1131. package/dist/services/fts5.d.ts.map +1 -0
  1132. package/dist/services/fts5.js +54 -0
  1133. package/dist/services/fts5.js.map +1 -0
  1134. package/dist/services/git-account-registry.d.ts +164 -0
  1135. package/dist/services/git-account-registry.d.ts.map +1 -0
  1136. package/dist/services/git-account-registry.js +297 -0
  1137. package/dist/services/git-account-registry.js.map +1 -0
  1138. package/dist/services/github.d.ts +49 -0
  1139. package/dist/services/github.d.ts.map +1 -0
  1140. package/dist/services/github.js +123 -0
  1141. package/dist/services/github.js.map +1 -0
  1142. package/dist/services/gmail-classifier.d.ts +62 -0
  1143. package/dist/services/gmail-classifier.d.ts.map +1 -0
  1144. package/dist/services/gmail-classifier.js +221 -0
  1145. package/dist/services/gmail-classifier.js.map +1 -0
  1146. package/dist/services/gmail.d.ts +192 -0
  1147. package/dist/services/gmail.d.ts.map +1 -0
  1148. package/dist/services/gmail.js +678 -0
  1149. package/dist/services/gmail.js.map +1 -0
  1150. package/dist/services/google-auth.d.ts +16 -0
  1151. package/dist/services/google-auth.d.ts.map +1 -0
  1152. package/dist/services/google-auth.js +37 -0
  1153. package/dist/services/google-auth.js.map +1 -0
  1154. package/dist/services/google-maps.d.ts +35 -0
  1155. package/dist/services/google-maps.d.ts.map +1 -0
  1156. package/dist/services/google-maps.js +82 -0
  1157. package/dist/services/google-maps.js.map +1 -0
  1158. package/dist/services/integrations/extract-write-item-id.d.ts +64 -0
  1159. package/dist/services/integrations/extract-write-item-id.d.ts.map +1 -0
  1160. package/dist/services/integrations/extract-write-item-id.js +188 -0
  1161. package/dist/services/integrations/extract-write-item-id.js.map +1 -0
  1162. package/dist/services/integrations/reconcile.d.ts +136 -0
  1163. package/dist/services/integrations/reconcile.d.ts.map +1 -0
  1164. package/dist/services/integrations/reconcile.js +218 -0
  1165. package/dist/services/integrations/reconcile.js.map +1 -0
  1166. package/dist/services/integrations/snapshot-partitions.d.ts +40 -0
  1167. package/dist/services/integrations/snapshot-partitions.d.ts.map +1 -0
  1168. package/dist/services/integrations/snapshot-partitions.js +113 -0
  1169. package/dist/services/integrations/snapshot-partitions.js.map +1 -0
  1170. package/dist/services/journal/render.d.ts +15 -0
  1171. package/dist/services/journal/render.d.ts.map +1 -0
  1172. package/dist/services/journal/render.js +17 -0
  1173. package/dist/services/journal/render.js.map +1 -0
  1174. package/dist/services/journal/writer.d.ts +26 -0
  1175. package/dist/services/journal/writer.d.ts.map +1 -0
  1176. package/dist/services/journal/writer.js +50 -0
  1177. package/dist/services/journal/writer.js.map +1 -0
  1178. package/dist/services/mail/account-registry.d.ts +208 -0
  1179. package/dist/services/mail/account-registry.d.ts.map +1 -0
  1180. package/dist/services/mail/account-registry.js +554 -0
  1181. package/dist/services/mail/account-registry.js.map +1 -0
  1182. package/dist/services/mail/gmail/auth-failure-classifier.d.ts +24 -0
  1183. package/dist/services/mail/gmail/auth-failure-classifier.d.ts.map +1 -0
  1184. package/dist/services/mail/gmail/auth-failure-classifier.js +67 -0
  1185. package/dist/services/mail/gmail/auth-failure-classifier.js.map +1 -0
  1186. package/dist/services/mail/gmail/gmail-provider.d.ts +58 -0
  1187. package/dist/services/mail/gmail/gmail-provider.d.ts.map +1 -0
  1188. package/dist/services/mail/gmail/gmail-provider.js +434 -0
  1189. package/dist/services/mail/gmail/gmail-provider.js.map +1 -0
  1190. package/dist/services/mail/gmail/legacy-row.d.ts +24 -0
  1191. package/dist/services/mail/gmail/legacy-row.d.ts.map +1 -0
  1192. package/dist/services/mail/gmail/legacy-row.js +71 -0
  1193. package/dist/services/mail/gmail/legacy-row.js.map +1 -0
  1194. package/dist/services/mail/gmail/poll-cursor.d.ts +12 -0
  1195. package/dist/services/mail/gmail/poll-cursor.d.ts.map +1 -0
  1196. package/dist/services/mail/gmail/poll-cursor.js +32 -0
  1197. package/dist/services/mail/gmail/poll-cursor.js.map +1 -0
  1198. package/dist/services/mail/html-to-plaintext.d.ts +27 -0
  1199. package/dist/services/mail/html-to-plaintext.d.ts.map +1 -0
  1200. package/dist/services/mail/html-to-plaintext.js +163 -0
  1201. package/dist/services/mail/html-to-plaintext.js.map +1 -0
  1202. package/dist/services/mail/imap/app-password.d.ts +27 -0
  1203. package/dist/services/mail/imap/app-password.d.ts.map +1 -0
  1204. package/dist/services/mail/imap/app-password.js +86 -0
  1205. package/dist/services/mail/imap/app-password.js.map +1 -0
  1206. package/dist/services/mail/imap/auth-failure-classifier.d.ts +21 -0
  1207. package/dist/services/mail/imap/auth-failure-classifier.d.ts.map +1 -0
  1208. package/dist/services/mail/imap/auth-failure-classifier.js +54 -0
  1209. package/dist/services/mail/imap/auth-failure-classifier.js.map +1 -0
  1210. package/dist/services/mail/imap/capabilities.d.ts +30 -0
  1211. package/dist/services/mail/imap/capabilities.d.ts.map +1 -0
  1212. package/dist/services/mail/imap/capabilities.js +70 -0
  1213. package/dist/services/mail/imap/capabilities.js.map +1 -0
  1214. package/dist/services/mail/imap/client.d.ts +15 -0
  1215. package/dist/services/mail/imap/client.d.ts.map +1 -0
  1216. package/dist/services/mail/imap/client.js +60 -0
  1217. package/dist/services/mail/imap/client.js.map +1 -0
  1218. package/dist/services/mail/imap/cursor.d.ts +19 -0
  1219. package/dist/services/mail/imap/cursor.d.ts.map +1 -0
  1220. package/dist/services/mail/imap/cursor.js +47 -0
  1221. package/dist/services/mail/imap/cursor.js.map +1 -0
  1222. package/dist/services/mail/imap/folder-resolver.d.ts +24 -0
  1223. package/dist/services/mail/imap/folder-resolver.d.ts.map +1 -0
  1224. package/dist/services/mail/imap/folder-resolver.js +58 -0
  1225. package/dist/services/mail/imap/folder-resolver.js.map +1 -0
  1226. package/dist/services/mail/imap/icloud-provider.d.ts +5 -0
  1227. package/dist/services/mail/imap/icloud-provider.d.ts.map +1 -0
  1228. package/dist/services/mail/imap/icloud-provider.js +5 -0
  1229. package/dist/services/mail/imap/icloud-provider.js.map +1 -0
  1230. package/dist/services/mail/imap/imap-provider-base.d.ts +173 -0
  1231. package/dist/services/mail/imap/imap-provider-base.d.ts.map +1 -0
  1232. package/dist/services/mail/imap/imap-provider-base.js +1004 -0
  1233. package/dist/services/mail/imap/imap-provider-base.js.map +1 -0
  1234. package/dist/services/mail/imap/query-translator.d.ts +13 -0
  1235. package/dist/services/mail/imap/query-translator.d.ts.map +1 -0
  1236. package/dist/services/mail/imap/query-translator.js +114 -0
  1237. package/dist/services/mail/imap/query-translator.js.map +1 -0
  1238. package/dist/services/mail/imap/reconcile-planner.d.ts +56 -0
  1239. package/dist/services/mail/imap/reconcile-planner.d.ts.map +1 -0
  1240. package/dist/services/mail/imap/reconcile-planner.js +52 -0
  1241. package/dist/services/mail/imap/reconcile-planner.js.map +1 -0
  1242. package/dist/services/mail/imap/reply-mime.d.ts +24 -0
  1243. package/dist/services/mail/imap/reply-mime.d.ts.map +1 -0
  1244. package/dist/services/mail/imap/reply-mime.js +77 -0
  1245. package/dist/services/mail/imap/reply-mime.js.map +1 -0
  1246. package/dist/services/mail/imap/yahoo-provider.d.ts +5 -0
  1247. package/dist/services/mail/imap/yahoo-provider.d.ts.map +1 -0
  1248. package/dist/services/mail/imap/yahoo-provider.js +5 -0
  1249. package/dist/services/mail/imap/yahoo-provider.js.map +1 -0
  1250. package/dist/services/mail/mail-search.d.ts +35 -0
  1251. package/dist/services/mail/mail-search.d.ts.map +1 -0
  1252. package/dist/services/mail/mail-search.js +59 -0
  1253. package/dist/services/mail/mail-search.js.map +1 -0
  1254. package/dist/services/mail/outlook/auth-failure-classifier.d.ts +38 -0
  1255. package/dist/services/mail/outlook/auth-failure-classifier.d.ts.map +1 -0
  1256. package/dist/services/mail/outlook/auth-failure-classifier.js +91 -0
  1257. package/dist/services/mail/outlook/auth-failure-classifier.js.map +1 -0
  1258. package/dist/services/mail/outlook/client-config.d.ts +34 -0
  1259. package/dist/services/mail/outlook/client-config.d.ts.map +1 -0
  1260. package/dist/services/mail/outlook/client-config.js +58 -0
  1261. package/dist/services/mail/outlook/client-config.js.map +1 -0
  1262. package/dist/services/mail/outlook/delta-cursor.d.ts +66 -0
  1263. package/dist/services/mail/outlook/delta-cursor.d.ts.map +1 -0
  1264. package/dist/services/mail/outlook/delta-cursor.js +85 -0
  1265. package/dist/services/mail/outlook/delta-cursor.js.map +1 -0
  1266. package/dist/services/mail/outlook/graph-client.d.ts +98 -0
  1267. package/dist/services/mail/outlook/graph-client.d.ts.map +1 -0
  1268. package/dist/services/mail/outlook/graph-client.js +198 -0
  1269. package/dist/services/mail/outlook/graph-client.js.map +1 -0
  1270. package/dist/services/mail/outlook/msal-app-factory.d.ts +20 -0
  1271. package/dist/services/mail/outlook/msal-app-factory.d.ts.map +1 -0
  1272. package/dist/services/mail/outlook/msal-app-factory.js +62 -0
  1273. package/dist/services/mail/outlook/msal-app-factory.js.map +1 -0
  1274. package/dist/services/mail/outlook/msal-cache-plugin.d.ts +19 -0
  1275. package/dist/services/mail/outlook/msal-cache-plugin.d.ts.map +1 -0
  1276. package/dist/services/mail/outlook/msal-cache-plugin.js +30 -0
  1277. package/dist/services/mail/outlook/msal-cache-plugin.js.map +1 -0
  1278. package/dist/services/mail/outlook/oauth-device-code.d.ts +26 -0
  1279. package/dist/services/mail/outlook/oauth-device-code.d.ts.map +1 -0
  1280. package/dist/services/mail/outlook/oauth-device-code.js +32 -0
  1281. package/dist/services/mail/outlook/oauth-device-code.js.map +1 -0
  1282. package/dist/services/mail/outlook/oauth-loopback.d.ts +41 -0
  1283. package/dist/services/mail/outlook/oauth-loopback.d.ts.map +1 -0
  1284. package/dist/services/mail/outlook/oauth-loopback.js +223 -0
  1285. package/dist/services/mail/outlook/oauth-loopback.js.map +1 -0
  1286. package/dist/services/mail/outlook/outlook-provider.d.ts +100 -0
  1287. package/dist/services/mail/outlook/outlook-provider.d.ts.map +1 -0
  1288. package/dist/services/mail/outlook/outlook-provider.js +619 -0
  1289. package/dist/services/mail/outlook/outlook-provider.js.map +1 -0
  1290. package/dist/services/mail/outlook/query-translator.d.ts +10 -0
  1291. package/dist/services/mail/outlook/query-translator.d.ts.map +1 -0
  1292. package/dist/services/mail/outlook/query-translator.js +103 -0
  1293. package/dist/services/mail/outlook/query-translator.js.map +1 -0
  1294. package/dist/services/mail/provider.d.ts +267 -0
  1295. package/dist/services/mail/provider.d.ts.map +1 -0
  1296. package/dist/services/mail/provider.js +34 -0
  1297. package/dist/services/mail/provider.js.map +1 -0
  1298. package/dist/services/mail/query-utils.d.ts +13 -0
  1299. package/dist/services/mail/query-utils.d.ts.map +1 -0
  1300. package/dist/services/mail/query-utils.js +18 -0
  1301. package/dist/services/mail/query-utils.js.map +1 -0
  1302. package/dist/services/mail-classifier.d.ts +25 -0
  1303. package/dist/services/mail-classifier.d.ts.map +1 -0
  1304. package/dist/services/mail-classifier.js +52 -0
  1305. package/dist/services/mail-classifier.js.map +1 -0
  1306. package/dist/services/mail-ingestion.d.ts +139 -0
  1307. package/dist/services/mail-ingestion.d.ts.map +1 -0
  1308. package/dist/services/mail-ingestion.js +223 -0
  1309. package/dist/services/mail-ingestion.js.map +1 -0
  1310. package/dist/services/mcp/auto-probe.d.ts +76 -0
  1311. package/dist/services/mcp/auto-probe.d.ts.map +1 -0
  1312. package/dist/services/mcp/auto-probe.js +147 -0
  1313. package/dist/services/mcp/auto-probe.js.map +1 -0
  1314. package/dist/services/mcp/generators/claude.d.ts +18 -0
  1315. package/dist/services/mcp/generators/claude.d.ts.map +1 -0
  1316. package/dist/services/mcp/generators/claude.js +90 -0
  1317. package/dist/services/mcp/generators/claude.js.map +1 -0
  1318. package/dist/services/mcp/generators/codex.d.ts +22 -0
  1319. package/dist/services/mcp/generators/codex.d.ts.map +1 -0
  1320. package/dist/services/mcp/generators/codex.js +102 -0
  1321. package/dist/services/mcp/generators/codex.js.map +1 -0
  1322. package/dist/services/mcp/generators/gemini.d.ts +20 -0
  1323. package/dist/services/mcp/generators/gemini.d.ts.map +1 -0
  1324. package/dist/services/mcp/generators/gemini.js +97 -0
  1325. package/dist/services/mcp/generators/gemini.js.map +1 -0
  1326. package/dist/services/mcp/generators/index.d.ts +20 -0
  1327. package/dist/services/mcp/generators/index.d.ts.map +1 -0
  1328. package/dist/services/mcp/generators/index.js +29 -0
  1329. package/dist/services/mcp/generators/index.js.map +1 -0
  1330. package/dist/services/mcp/generators/types.d.ts +47 -0
  1331. package/dist/services/mcp/generators/types.d.ts.map +1 -0
  1332. package/dist/services/mcp/generators/types.js +40 -0
  1333. package/dist/services/mcp/generators/types.js.map +1 -0
  1334. package/dist/services/mcp/probe.d.ts +31 -0
  1335. package/dist/services/mcp/probe.d.ts.map +1 -0
  1336. package/dist/services/mcp/probe.js +437 -0
  1337. package/dist/services/mcp/probe.js.map +1 -0
  1338. package/dist/services/mcp/registry.d.ts +84 -0
  1339. package/dist/services/mcp/registry.d.ts.map +1 -0
  1340. package/dist/services/mcp/registry.js +387 -0
  1341. package/dist/services/mcp/registry.js.map +1 -0
  1342. package/dist/services/mcp/risk.d.ts +82 -0
  1343. package/dist/services/mcp/risk.d.ts.map +1 -0
  1344. package/dist/services/mcp/risk.js +126 -0
  1345. package/dist/services/mcp/risk.js.map +1 -0
  1346. package/dist/services/mcp/session-materializer.d.ts +123 -0
  1347. package/dist/services/mcp/session-materializer.d.ts.map +1 -0
  1348. package/dist/services/mcp/session-materializer.js +361 -0
  1349. package/dist/services/mcp/session-materializer.js.map +1 -0
  1350. package/dist/services/mcp/tool-audit.d.ts +53 -0
  1351. package/dist/services/mcp/tool-audit.d.ts.map +1 -0
  1352. package/dist/services/mcp/tool-audit.js +74 -0
  1353. package/dist/services/mcp/tool-audit.js.map +1 -0
  1354. package/dist/services/mcp/types.d.ts +88 -0
  1355. package/dist/services/mcp/types.d.ts.map +1 -0
  1356. package/dist/services/mcp/types.js +94 -0
  1357. package/dist/services/mcp/types.js.map +1 -0
  1358. package/dist/services/notion.d.ts +134 -0
  1359. package/dist/services/notion.d.ts.map +1 -0
  1360. package/dist/services/notion.js +350 -0
  1361. package/dist/services/notion.js.map +1 -0
  1362. package/dist/services/obsidian.d.ts +116 -0
  1363. package/dist/services/obsidian.d.ts.map +1 -0
  1364. package/dist/services/obsidian.js +305 -0
  1365. package/dist/services/obsidian.js.map +1 -0
  1366. package/dist/services/service-registry.d.ts +31 -0
  1367. package/dist/services/service-registry.d.ts.map +1 -0
  1368. package/dist/services/service-registry.js +15 -0
  1369. package/dist/services/service-registry.js.map +1 -0
  1370. package/dist/services/voice/transcriber-impl.d.ts +15 -0
  1371. package/dist/services/voice/transcriber-impl.d.ts.map +1 -0
  1372. package/dist/services/voice/transcriber-impl.js +129 -0
  1373. package/dist/services/voice/transcriber-impl.js.map +1 -0
  1374. package/dist/services/voice/transcriber.d.ts +117 -0
  1375. package/dist/services/voice/transcriber.d.ts.map +1 -0
  1376. package/dist/services/voice/transcriber.js +201 -0
  1377. package/dist/services/voice/transcriber.js.map +1 -0
  1378. package/dist/settings/runtime-settings.d.ts +232 -0
  1379. package/dist/settings/runtime-settings.d.ts.map +1 -0
  1380. package/dist/settings/runtime-settings.js +769 -0
  1381. package/dist/settings/runtime-settings.js.map +1 -0
  1382. package/dist/settings/settings-store.d.ts +13 -0
  1383. package/dist/settings/settings-store.d.ts.map +1 -0
  1384. package/dist/settings/settings-store.js +87 -0
  1385. package/dist/settings/settings-store.js.map +1 -0
  1386. package/package.json +85 -0
@@ -0,0 +1,2541 @@
1
+ import { query, } from "@anthropic-ai/claude-agent-sdk";
2
+ import { collectSessionDeniedTools, INTEGRATION_DESCRIPTORS, INTEGRATION_KEYS, isAutonomousProcessKey, matchRunAllowedToolPattern, } from "@aitne/shared";
3
+ import { readIntegrations } from "../../db/integrations-store.js";
4
+ import { buildExecutionPrompt, buildSummaryPrompt, } from "./prompt-utils.js";
5
+ import { homedir } from "node:os";
6
+ import { resolve as resolvePath, isAbsolute } from "node:path";
7
+ import { getContextDir } from "../../config.js";
8
+ import { materializeMcpForSession } from "../../services/mcp/session-materializer.js";
9
+ import { parseMcpToolName } from "../../services/mcp/risk.js";
10
+ import { logMcpToolCall, updateMcpToolCallResult } from "../../services/mcp/tool-audit.js";
11
+ import { BackendQuotaError, BackendDecisiveFailure, DelegatedProxyTimeoutError, classifyAbortReason, } from "../agent-core.js";
12
+ import { IdleWatchdog } from "./idle-watchdog.js";
13
+ import { DELEGATED_PROXY_DEFAULTS } from "../../services/delegated-proxy-config.js";
14
+ import { buildDelegatedToolPrompt, emptyCost, flattenToolResultContent, tryParseToolResult, withDurationMs, } from "../../services/delegated-tool-runtime.js";
15
+ import { createSessionWorkdir, cleanupSessionWorkdir } from "../workdir.js";
16
+ import { buildDaemonApiCliEnv } from "../daemon-api-cli.js";
17
+ import { createLogger } from "../../logging.js";
18
+ import { DEFAULT_CLAUDE_HIGH_MODEL, DEFAULT_CLAUDE_MEDIUM_MODEL, findRegisteredModel, getModelsForBackend, } from "./model-registry.js";
19
+ import { readClaudeCredentials } from "./claude-credentials-store.js";
20
+ import { ALWAYS_DISALLOWED_TOOLS, classifyAbsoluteBlock, } from "../../safety/always-disallowed.js";
21
+ import { recordAbsoluteBlockAudit } from "../../safety/absolute-block-audit.js";
22
+ import { isPathInsideOrEqual, shellPathForms, } from "../path-compat.js";
23
+ import { CliPathCache, isPlausibleAnthropicApiKey } from "./cli-utils.js";
24
+ import { probeApiKeyServerSide } from "./api-key-probe.js";
25
+ import { extractSilentApiErrors, logSilentApiErrors, } from "./silent-api-error-detector.js";
26
+ const logger = createLogger("claude-code-core");
27
+ /**
28
+ * Detect which cloud-provider mode the Claude Code SDK is currently
29
+ * configured for, based on the documented `CLAUDE_CODE_USE_*` env flags.
30
+ * Returns null when running in the default direct-API-key / OAuth mode.
31
+ *
32
+ * Required-env spec follows the official Claude Code docs (verified
33
+ * 2026-05):
34
+ * - **Bedrock** — only `AWS_REGION` is required by Claude Code itself
35
+ * (the docs explicitly call this out). AWS credentials flow through
36
+ * the SDK's default credential chain, which can come from any of
37
+ * AWS_ACCESS_KEY_ID/SECRET, AWS_BEARER_TOKEN_BEDROCK, AWS_PROFILE, or
38
+ * `~/.aws/`. Requiring access-key + secret here would falsely fail
39
+ * bearer-token / profile setups.
40
+ * - **Vertex** — `ANTHROPIC_VERTEX_PROJECT_ID` + `CLOUD_ML_REGION`.
41
+ * GCP credentials flow through ADC, which can be `gcloud auth
42
+ * application-default login` or a `GOOGLE_APPLICATION_CREDENTIALS`
43
+ * file path; we don't require either at this layer.
44
+ * - **Foundry** — `ANTHROPIC_FOUNDRY_RESOURCE` OR
45
+ * `ANTHROPIC_FOUNDRY_BASE_URL`. The API key is optional; without it,
46
+ * Claude Code uses the Azure DefaultAzureCredential chain.
47
+ *
48
+ * The SDK reads these flags itself; the daemon only inspects them so
49
+ * the auth probes (`checkAuth` / `checkAuthDetailed`) can return the
50
+ * right `method` and skip the Anthropic-API probe (which would 401
51
+ * against a Bedrock / Vertex / Foundry deployment).
52
+ */
53
+ function detectCloudProviderEnv() {
54
+ if (process.env.CLAUDE_CODE_USE_BEDROCK?.trim() === "1") {
55
+ const missing = [];
56
+ if (!process.env.AWS_REGION?.trim())
57
+ missing.push("AWS_REGION");
58
+ return {
59
+ method: "bedrock",
60
+ flagEnvVar: "CLAUDE_CODE_USE_BEDROCK",
61
+ label: "Amazon Bedrock",
62
+ missing,
63
+ };
64
+ }
65
+ if (process.env.CLAUDE_CODE_USE_VERTEX?.trim() === "1") {
66
+ const required = [
67
+ "ANTHROPIC_VERTEX_PROJECT_ID",
68
+ "CLOUD_ML_REGION",
69
+ ];
70
+ return {
71
+ method: "vertex",
72
+ flagEnvVar: "CLAUDE_CODE_USE_VERTEX",
73
+ label: "Google Vertex AI",
74
+ missing: required.filter((name) => !process.env[name]?.trim()),
75
+ };
76
+ }
77
+ if (process.env.CLAUDE_CODE_USE_FOUNDRY?.trim() === "1") {
78
+ const hasResource = Boolean(process.env.ANTHROPIC_FOUNDRY_RESOURCE?.trim());
79
+ const hasBaseUrl = Boolean(process.env.ANTHROPIC_FOUNDRY_BASE_URL?.trim());
80
+ return {
81
+ method: "foundry",
82
+ flagEnvVar: "CLAUDE_CODE_USE_FOUNDRY",
83
+ label: "Microsoft Foundry",
84
+ missing: hasResource || hasBaseUrl
85
+ ? []
86
+ : ["ANTHROPIC_FOUNDRY_RESOURCE or ANTHROPIC_FOUNDRY_BASE_URL"],
87
+ };
88
+ }
89
+ return null;
90
+ }
91
+ // Probe data is derived from `INTEGRATION_DESCRIPTORS.backendConnectors.claude`
92
+ // at module init, so adding a new delegated integration only requires the
93
+ // registry update — the prompt, prefix list, and tool-name regex follow
94
+ // automatically. Before this was registry-driven, every new integration
95
+ // silently broke its own probe (`present` permanently false) until someone
96
+ // remembered to edit four constants in lockstep. See
97
+ // `docs/design/17-delegated-mode-v2.md` §7.1.
98
+ //
99
+ // Tool names span two character classes:
100
+ // - Gmail / Calendar: `search_threads`, `list_events` (snake_case only)
101
+ // - Notion: `notion-search`, `notion-create-pages` (kebab-case)
102
+ // The trailing `[A-Za-z0-9_-]+` class covers both. Namespace strings are
103
+ // regex-escaped because Codex (`._`) and Gemini (`.`) namespaces contain
104
+ // metacharacters.
105
+ function buildClaudeProbeData() {
106
+ const meta = [];
107
+ for (const key of INTEGRATION_KEYS) {
108
+ const descriptor = INTEGRATION_DESCRIPTORS[key];
109
+ const connector = descriptor.backendConnectors.claude;
110
+ if (!connector)
111
+ continue;
112
+ const seen = new Set();
113
+ for (const tools of Object.values(connector.capabilityTools)) {
114
+ for (const t of tools)
115
+ seen.add(t);
116
+ }
117
+ meta.push({
118
+ displayName: descriptor.displayName,
119
+ toolNamespace: connector.toolNamespace,
120
+ requiredCapabilities: connector.requiredCapabilities,
121
+ capabilityToolNames: Array.from(seen),
122
+ });
123
+ }
124
+ const prefixes = meta.map((m) => m.toolNamespace);
125
+ const lines = ["Use `ToolSearch` only."];
126
+ for (const m of meta) {
127
+ // Keyword query: display name + required capability words split on
128
+ // `_` / `-`. Mirrors the pre-registry-driven prompts (Gmail used
129
+ // `'Gmail search read draft label'`, Calendar used `'Google Calendar
130
+ // list get create update delete event'`) — both are display name +
131
+ // requiredCapabilities expanded into word tokens. Using the
132
+ // capability set (semantic) rather than every capability tool name
133
+ // (mechanical) keeps ToolSearch's token-overlap ranking sharp; a
134
+ // bag-of-tool-name-fragments query dilutes the signal across
135
+ // ~15-30 tokens per integration and demotes the actually-relevant
136
+ // hits.
137
+ const queryWords = [
138
+ m.displayName,
139
+ ...m.requiredCapabilities.flatMap((c) => c.split(/[-_]/)),
140
+ ]
141
+ .join(" ")
142
+ .replace(/\s+/g, " ")
143
+ .trim();
144
+ lines.push(`Search for ${m.displayName} connector tools with query '${queryWords}' and max_results 20.`);
145
+ }
146
+ lines.push("Do not call any of the searched MCP tools.");
147
+ lines.push(`After the searches, print every full tool name returned that starts with one of: ${prefixes
148
+ .map((p) => `'${p}'`)
149
+ .join(", ")}.`);
150
+ // Per-integration "must include" hints: ToolSearch caps results at
151
+ // max_results, so lower-ranked tools (e.g. Gmail's label_* family) can
152
+ // be missed by keyword search. Listing them explicitly nudges the agent
153
+ // to print them when they do appear in any of the searches above.
154
+ for (const m of meta) {
155
+ if (m.capabilityToolNames.length === 0)
156
+ continue;
157
+ const fullNames = m.capabilityToolNames
158
+ .map((n) => m.toolNamespace + n)
159
+ .join(", ");
160
+ lines.push(`Include these ${m.displayName} tools if present: ${fullNames}.`);
161
+ }
162
+ lines.push("One tool name per line. No markdown fences. No explanation. If no such tools are available, print NONE.");
163
+ // Defense: an empty prefix list would compile to `\b(?:)[A-Za-z0-9_-]+\b`,
164
+ // which matches any word — every connector probe would falsely "succeed".
165
+ // Realistically `INTEGRATION_DESCRIPTORS` is non-empty, but the guard
166
+ // keeps a future registry rollback from corrupting probe semantics.
167
+ const escapedPrefixes = prefixes.map((p) => p.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
168
+ const regex = escapedPrefixes.length === 0
169
+ ? /(?!)/g
170
+ : new RegExp(`\\b(?:${escapedPrefixes.join("|")})[A-Za-z0-9_-]+\\b`, "g");
171
+ return { prompt: lines.join(" "), prefixes, regex };
172
+ }
173
+ const CLAUDE_PROBE_DATA = buildClaudeProbeData();
174
+ export const CLAUDE_PROBE_TOOLS_PROMPT = CLAUDE_PROBE_DATA.prompt;
175
+ const CLAUDE_PROBE_TOOL_PREFIXES = CLAUDE_PROBE_DATA.prefixes;
176
+ const CLAUDE_CONNECTOR_TOOL_RE = CLAUDE_PROBE_DATA.regex;
177
+ /**
178
+ * The built-in Claude Code tool that loads schemas for deferred MCP tools.
179
+ * When a session inherits many MCP servers from the user's global config,
180
+ * the CLI defers a portion of the tool schemas; the model must call
181
+ * `ToolSearch` to bring a specific tool's schema into the working set
182
+ * before invoking it. The proxy explicitly allows it (see runDelegatedTool)
183
+ * and the stream parser excludes it from `wrongToolName` capture so a
184
+ * partial-trace failure (`ToolSearch` + max_turns before the connector
185
+ * call) classifies as `no_tool_call` rather than the misleading
186
+ * `wrong_tool=ToolSearch`.
187
+ */
188
+ const DEFERRED_TOOL_DISCOVERY_TOOL_NAME = "ToolSearch";
189
+ /**
190
+ * Registry-driven allowlist entries for integrations currently delegated to
191
+ * Claude. Under `permissionMode: "dontAsk"`, any tool not in the SDK's
192
+ * `allowedTools` is silently denied — so a delegated Gmail / Calendar
193
+ * integration whose skill instructs the agent to call
194
+ * `mcp__claude_ai_Gmail__search_threads` will fail with "permission denied"
195
+ * unless that exact tool name is pre-authorized here.
196
+ *
197
+ * Pure over `(integrations)` — callers pass the record read from
198
+ * `db/integrations-store.ts#readIntegrations`. The SDK's MCP tool matcher is
199
+ * literal (`mcp__<server>__<tool>` — see `services/mcp/risk.ts`), so we
200
+ * enumerate every capability tool the registry declares rather than using a
201
+ * wildcard. This guarantees the allowlist only widens by what the registry
202
+ * explicitly advertises; adding a new connector tool demands a registry
203
+ * update first.
204
+ *
205
+ * Only integrations whose `delegatedBackend === "claude"` contribute — a
206
+ * Codex-delegated Gmail integration must not widen Claude's surface.
207
+ */
208
+ export function computeDelegatedClaudeTools(integrations) {
209
+ const out = new Set();
210
+ for (const key of INTEGRATION_KEYS) {
211
+ const state = integrations[key];
212
+ if (!state || state.mode !== "delegated")
213
+ continue;
214
+ if (state.delegatedBackend !== "claude")
215
+ continue;
216
+ const connector = INTEGRATION_DESCRIPTORS[key].backendConnectors.claude;
217
+ if (!connector)
218
+ continue;
219
+ for (const toolNames of Object.values(connector.capabilityTools)) {
220
+ for (const toolName of toolNames) {
221
+ out.add(connector.toolNamespace + toolName);
222
+ }
223
+ }
224
+ }
225
+ return Array.from(out);
226
+ }
227
+ export class AgentTimeoutError extends Error {
228
+ timeoutMs;
229
+ constructor(timeoutMs) {
230
+ super(`Agent execution exceeded timeout of ${timeoutMs}ms`);
231
+ this.timeoutMs = timeoutMs;
232
+ this.name = "AgentTimeoutError";
233
+ }
234
+ }
235
+ export function isClaudeCodeQuotaError(error) {
236
+ if (!(error instanceof Error)) {
237
+ return false;
238
+ }
239
+ const maybeRecord = error;
240
+ const message = error.message.toLowerCase();
241
+ const code = typeof maybeRecord.code === "string" ? maybeRecord.code.toLowerCase() : "";
242
+ const type = typeof maybeRecord.type === "string" ? maybeRecord.type.toLowerCase() : "";
243
+ if (maybeRecord.status === 429) {
244
+ return true;
245
+ }
246
+ if (code.includes("rate") || code.includes("quota")) {
247
+ return true;
248
+ }
249
+ if (type.includes("rate") || type.includes("quota")) {
250
+ return true;
251
+ }
252
+ return /rate.?limit|quota|too many requests|you['']?\s*ve hit your limit/.test(message);
253
+ }
254
+ export function isClaudeCodeMaxBudgetError(error) {
255
+ const message = error instanceof Error
256
+ ? error.message
257
+ : typeof error === "string"
258
+ ? error
259
+ : "";
260
+ const code = typeof error === "object" && error !== null && typeof error.code === "string"
261
+ ? error.code
262
+ : "";
263
+ const type = typeof error === "object" && error !== null && typeof error.type === "string"
264
+ ? error.type
265
+ : "";
266
+ return /max(?:imum)? budget|max_budget_usd|budget limit|per-turn budget/i.test(`${message} ${code} ${type}`);
267
+ }
268
+ export function extractClaudeCodeQuotaResetHint(error) {
269
+ if (!(error instanceof Error)) {
270
+ return null;
271
+ }
272
+ const match = /resets?\s+(\d{1,2})(?::(\d{2}))?\s*(am|pm)\s*(?:\(([^)]+)\))?/i.exec(error.message);
273
+ if (!match) {
274
+ return null;
275
+ }
276
+ const rawHour = Number(match[1]);
277
+ const meridiem = match[3].toLowerCase();
278
+ let hour = rawHour % 12;
279
+ if (meridiem === "pm") {
280
+ hour += 12;
281
+ }
282
+ return {
283
+ hour,
284
+ minute: match[2] ? Number(match[2]) : 0,
285
+ timeZone: match[4]?.trim() || undefined,
286
+ rawLabel: error.message.slice(match.index).replace(/^resets?\s+/i, "").trim(),
287
+ };
288
+ }
289
+ /**
290
+ * ClaudeCodeCore intentionally does NOT run a pre-flight `checkAuth()`
291
+ * gate inside `execute()` / `runTurn()`. Codex and Gemini each call
292
+ * `await this.checkAuth()` at the top of `runTurn()` as a cheap way
293
+ * to surface an early `BackendDecisiveFailure("auth")` before paying
294
+ * the latency of spawning the CLI subprocess; Claude uses the
295
+ * `@anthropic-ai/claude-agent-sdk` stream consumer instead, and the
296
+ * SDK's first HTTP round-trip already returns a decisive 401 on its
297
+ * own. A pre-flight here would duplicate work (two credential reads
298
+ * per execute) and isn't needed to prevent accidental token use —
299
+ * the reactive path in `BackendRouter` catches the SDK's 401, maps
300
+ * it to `BackendDecisiveFailure("auth")`, and calls
301
+ * `recordReactiveAuthFailure` exactly as if a pre-flight had run.
302
+ *
303
+ * This asymmetry is deliberate and matched by the corresponding
304
+ * explanatory comments at `codex-core.ts` / `gemini-cli-core.ts`'s
305
+ * `runTurn` pre-flight and at `IAgentCore.checkAuth` in
306
+ * `agent-core.ts`. If you add a new backend, decide the pre-flight
307
+ * question based on the CLI / SDK's own startup cost, not on
308
+ * pattern-matching against one of the existing three.
309
+ */
310
+ export class ClaudeCodeCore {
311
+ config;
312
+ writeTracker;
313
+ backendId = "claude";
314
+ static RETRY_DELAY_MS = 5 * 60 * 1000;
315
+ static MAX_RETRIES = 1;
316
+ // Lazily re-resolved with a 60 s TTL so CLI install/uninstall is
317
+ // detected without a daemon restart (roadmap §9.4). Constructor does an
318
+ // eager PATH scan so the first checkAuth() call has no extra latency.
319
+ cliPathCache;
320
+ /** Legacy shared read token injected into the Claude subprocess env. */
321
+ readToken;
322
+ /** Scoped token manager preferred over the legacy shared read token. */
323
+ readTokenManager;
324
+ /** B-003 Phase 3 — DB + blob store for per-session MCP materialization. */
325
+ mcpContext;
326
+ /** Transparent getter — all existing `this.cliPath` references keep working. */
327
+ get cliPath() {
328
+ return this.cliPathCache.get();
329
+ }
330
+ constructor(config,
331
+ /**
332
+ * Shared AgentWriteTracker. When present, the Write/Edit PreToolUse hook
333
+ * pre-marks vault-scoped writes so the ObsidianWatcher attributes the
334
+ * resulting chokidar event to `actor='agent'` instead of `'user'`. Without
335
+ * this wiring, the hourly_check dispatcher would re-discover the agent's
336
+ * own vault writes every cycle and loop.
337
+ */
338
+ writeTracker) {
339
+ this.config = config;
340
+ this.writeTracker = writeTracker;
341
+ this.warnOnMissingCriticalTools();
342
+ this.cliPathCache = new CliPathCache("claude");
343
+ }
344
+ /** Set the per-daemon-boot read token for subprocess-local daemon API auth. */
345
+ setReadToken(token) {
346
+ this.readToken = token;
347
+ }
348
+ setReadTokenManager(manager) {
349
+ this.readTokenManager = manager;
350
+ }
351
+ setMcpContext(context) {
352
+ this.mcpContext = context;
353
+ logger.info({ backendId: this.backendId }, "MCP context wired — delegated-integration allowlist resolution enabled");
354
+ }
355
+ /**
356
+ * Load the per-session MCP materialization. When the core hasn't been
357
+ * wired with a context (tests, startup ordering) we return an empty
358
+ * result rather than throwing — equivalent to "no enabled servers".
359
+ */
360
+ async materializeMcp(sessionDir, processKey) {
361
+ if (!this.mcpContext) {
362
+ return {
363
+ servers: [],
364
+ env: {},
365
+ configPath: null,
366
+ claudeMcpServers: null,
367
+ disallowedTools: [],
368
+ };
369
+ }
370
+ // Allow mode bypasses the approve-tier MCP strip that autonomous
371
+ // process keys normally trigger — "strong permission mode" means every
372
+ // MCP is reachable, including routines that would otherwise have
373
+ // `slack_send_message` et al stripped.
374
+ const allowMode = this.config.claudeExecutionPermissionMode === "allow";
375
+ const autonomous = !allowMode && (processKey ? isAutonomousProcessKey(processKey) : false);
376
+ return materializeMcpForSession({
377
+ db: this.mcpContext.db,
378
+ blobStore: this.mcpContext.blobStore,
379
+ sessionDir,
380
+ backendId: this.backendId,
381
+ autonomous,
382
+ contextDir: getContextDir(this.config),
383
+ });
384
+ }
385
+ /**
386
+ * Tools the reactive DM path depends on. If `allowedToolsOverride` is set
387
+ * but drops any of these, sessions will silently deny them under
388
+ * `permissionMode: "dontAsk"` and the owner will see a misleading
389
+ * "restricted" error. See BUG-DM-BACKEND-PERMISSIONS.md §9 (Fix 1a).
390
+ */
391
+ static CRITICAL_OVERRIDE_TOOLS = ["Skill", "Bash(jq *)"];
392
+ /**
393
+ * Pure computation: which of the CRITICAL_OVERRIDE_TOOLS are missing from
394
+ * the current `allowedToolsOverride`. Returns `[]` when the override is
395
+ * unset (the default allowlist already contains all critical tools).
396
+ */
397
+ getMissingCriticalOverrideTools() {
398
+ const override = this.config.allowedToolsOverride;
399
+ if (!override)
400
+ return [];
401
+ return ClaudeCodeCore.CRITICAL_OVERRIDE_TOOLS.filter((tool) => !override.includes(tool));
402
+ }
403
+ /**
404
+ * `allowedToolsOverride` REPLACES the default allowlist (it does not merge).
405
+ * Emit a one-shot warning at construction so a mis-configuration surfaces
406
+ * in the daemon log instead of a confusing DM reply.
407
+ */
408
+ warnOnMissingCriticalTools() {
409
+ // In allow mode neither the override nor the default allowlist applies —
410
+ // the SDK runs under bypassPermissions, so a missing Skill / Bash(jq *)
411
+ // entry in the override is cosmetic. Suppress the warning.
412
+ if (this.config.claudeExecutionPermissionMode === "allow")
413
+ return;
414
+ const missing = this.getMissingCriticalOverrideTools();
415
+ if (missing.length === 0)
416
+ return;
417
+ logger.warn({
418
+ missing,
419
+ overrideSize: this.config.allowedToolsOverride?.length ?? 0,
420
+ }, "allowedToolsOverride is set but missing critical tools. " +
421
+ "The reactive DM path calls user skills and jq pipelines; without these " +
422
+ "the session will deny them with 'dontAsk' and respond to the owner with " +
423
+ "a misleading 'restricted' message. Either append the missing entries to " +
424
+ "the override, or clear the override to fall back to the default allowlist.");
425
+ }
426
+ /**
427
+ * Translate the Aitne advisor config into the SDK `options.settings`
428
+ * shape. `advisorModel` is a field on `Settings`, not on `Options` — the
429
+ * query() parameter must be passed inside a `settings` object.
430
+ *
431
+ * Returns an empty object when advisor is disabled so we don't clobber any
432
+ * settings source that would otherwise load.
433
+ */
434
+ buildAdvisorSettings() {
435
+ if (!this.config.advisorEnabled || !this.config.advisorModel) {
436
+ return {};
437
+ }
438
+ return {
439
+ settings: {
440
+ advisorModel: this.config.advisorModel,
441
+ },
442
+ };
443
+ }
444
+ buildSystemPrompt() {
445
+ // Character is NOT appended here — Phase 2 of the Character feature
446
+ // (see docs/design/15-character.md §15.4.3) moved the injection into
447
+ // the rendered CLAUDE.md so Claude / Codex / Gemini see a byte-
448
+ // identical block. The remaining append is the WhatsApp-prefix
449
+ // operational note, which is byte-stable per-session and therefore
450
+ // cache-friendly.
451
+ const appendParts = [
452
+ "WhatsApp outbound messages are prefixed by the daemon. Do not add that prefix yourself unless the user explicitly asks.",
453
+ ];
454
+ return {
455
+ type: "preset",
456
+ preset: "claude_code",
457
+ append: appendParts.join("\n"),
458
+ // Strip per-session dynamic sections (cwd, auto-memory path, git
459
+ // status) from the cached system prompt prefix. The content is
460
+ // re-injected as the first user message so the model still sees it,
461
+ // but the system prompt becomes byte-identical across sessions —
462
+ // enabling inter-session prompt cache hits within the 5-minute TTL.
463
+ // Biggest wins: back-to-back routines (morning_routine + roadmap_refresh
464
+ // + post-morning catchups) and retry chains where the second session
465
+ // starts within minutes of the first.
466
+ //
467
+ // Limitation: the SDK still reads CLAUDE.md and .claude/skills/ from
468
+ // cwd at session init. Different event types use different profiles
469
+ // (routine.md vs conversational.md) and skill subsets, so the file
470
+ // layer differs across event types → no cross-event-type cache hit.
471
+ // This flag only helps same-type back-to-back sessions.
472
+ excludeDynamicSections: true,
473
+ };
474
+ }
475
+ /**
476
+ * Expand CLI-style aliases ("opus", "sonnet") to their current canonical
477
+ * API IDs. Unrecognised strings pass through unchanged so custom or
478
+ * fine-tuned model IDs reach the SDK verbatim.
479
+ *
480
+ * NOTE: `"opus"` now resolves to Opus 4.7 (previously 4.6). Legacy
481
+ * `agent_schedule.model = 'opus'` rows will silently route to 4.7 on the
482
+ * next dispatch — intentional, since the alias means "latest Opus".
483
+ */
484
+ resolveActualModelId(modelId) {
485
+ if (modelId === "opus") {
486
+ return DEFAULT_CLAUDE_HIGH_MODEL;
487
+ }
488
+ if (modelId === "sonnet") {
489
+ return DEFAULT_CLAUDE_MEDIUM_MODEL;
490
+ }
491
+ return modelId;
492
+ }
493
+ async execute(params, streamCallbacks) {
494
+ return await this.runWithRetry(() => this.executeOnce(params, streamCallbacks), { eventType: params.event.type, modelId: params.modelId });
495
+ }
496
+ async executeOnce(params, streamCallbacks) {
497
+ const { prompt, context, event, modelId, maxTurns, maxBudgetUsd, sessionDir, persistSession = false, conversationHistory, webSearchEnabled = false, } = params;
498
+ const fullPrompt = buildExecutionPrompt(prompt, context, event, conversationHistory);
499
+ const startMs = Date.now();
500
+ const actualModelId = this.resolveActualModelId(modelId);
501
+ // If caller provided a persistent sessionDir, use it (non-DM Opus sessions
502
+ // that may be resumed later). Otherwise create a disposable temp dir.
503
+ // The disposable path also receives user skills so agent DMs that don't
504
+ // take the persistent-workdir path can still discover user-authored skills.
505
+ const useSessionDir = sessionDir ?? createSessionWorkdir(this.config.workspaceDir, event.type, `${this.config.dataDir}/skills`, {
506
+ backendId: this.backendId,
507
+ processKey: params.processKey,
508
+ character: this.config.character,
509
+ });
510
+ const isOwnedTempDir = !sessionDir;
511
+ const daemonReadToken = this.readTokenManager?.issue(useSessionDir) ?? this.readToken;
512
+ const mcp = await this.materializeMcp(useSessionDir, params.processKey);
513
+ const delegatedTools = this.getDelegatedClaudeTools();
514
+ const sessionDeniedTools = this.getSessionDeniedTools();
515
+ logger.info({
516
+ eventType: event.type,
517
+ model: actualModelId,
518
+ maxTurns,
519
+ promptLen: fullPrompt.length,
520
+ mcpServers: mcp.servers.map((s) => s.id),
521
+ delegatedToolCount: delegatedTools.length,
522
+ sessionDeniedToolCount: sessionDeniedTools.length,
523
+ }, "Agent execute started");
524
+ try {
525
+ const allowMode = this.config.claudeExecutionPermissionMode === "allow";
526
+ // P22 §3.4 step 4 — when the dispatcher pins a per-execute
527
+ // `allowedToolsOverride`, suspend Allow mode for this run: the
528
+ // optimizer agent must NOT receive `bypassPermissions`, regardless
529
+ // of the operator's per-backend Execution Mode setting. We swap
530
+ // back to strict `dontAsk` + the explicit allowedTools list. The
531
+ // ALWAYS_DISALLOWED_TOOLS layer still applies.
532
+ const optimizerClampActive = Array.isArray(params.allowedToolsOverride) && params.allowedToolsOverride.length > 0;
533
+ const stream = query({
534
+ prompt: fullPrompt,
535
+ options: {
536
+ model: actualModelId,
537
+ maxTurns,
538
+ maxBudgetUsd,
539
+ effort: actualModelId.includes("opus") ? "high" : "medium",
540
+ cwd: useSessionDir,
541
+ env: {
542
+ ...buildDaemonApiCliEnv(useSessionDir, this.config.apiPort, {
543
+ readToken: daemonReadToken,
544
+ sessionBackend: "claude",
545
+ sessionId: params.sessionDbId,
546
+ eventCorrelationId: event.correlationId,
547
+ }),
548
+ ...mcp.env,
549
+ ...(params.turnToken ? { PA_TURN_TOKEN: params.turnToken } : {}),
550
+ },
551
+ systemPrompt: this.buildSystemPrompt(),
552
+ ...(optimizerClampActive
553
+ ? {
554
+ permissionMode: "dontAsk",
555
+ allowedTools: [...params.allowedToolsOverride],
556
+ disallowedTools: [
557
+ ...ALWAYS_DISALLOWED_TOOLS,
558
+ ...this.config.disallowedTools,
559
+ ...mcp.disallowedTools,
560
+ ...sessionDeniedTools,
561
+ ],
562
+ }
563
+ : allowMode
564
+ ? {
565
+ permissionMode: "bypassPermissions",
566
+ allowDangerouslySkipPermissions: true,
567
+ disallowedTools: [
568
+ ...ALWAYS_DISALLOWED_TOOLS,
569
+ ...mcp.disallowedTools,
570
+ ...sessionDeniedTools,
571
+ ],
572
+ }
573
+ : {
574
+ permissionMode: "dontAsk",
575
+ allowedTools: this.getAllowedTools(webSearchEnabled, delegatedTools),
576
+ disallowedTools: [
577
+ ...ALWAYS_DISALLOWED_TOOLS,
578
+ ...this.config.disallowedTools,
579
+ ...mcp.disallowedTools,
580
+ ...sessionDeniedTools,
581
+ ],
582
+ }),
583
+ ...(mcp.claudeMcpServers
584
+ ? {
585
+ mcpServers: mcp.claudeMcpServers,
586
+ }
587
+ : {}),
588
+ hooks: this.getSecurityHooks(allowMode),
589
+ persistSession,
590
+ includePartialMessages: !!streamCallbacks,
591
+ ...this.buildAdvisorSettings(),
592
+ },
593
+ });
594
+ const result = await this.withTimeout(stream, () => this.consumeStream(stream, actualModelId, startMs, streamCallbacks, event.type), this.config.executeTimeoutMinutes);
595
+ logger.info({ eventType: event.type, model: actualModelId, durationMs: result.durationMs, costUsd: result.costUsd, numTurns: result.numTurns, isError: result.isError }, "Agent execute completed");
596
+ return result;
597
+ }
598
+ catch (err) {
599
+ logger.error({ err, eventType: event.type, model: actualModelId, durationMs: Date.now() - startMs }, "Agent execute failed");
600
+ throw err;
601
+ }
602
+ finally {
603
+ if (isOwnedTempDir) {
604
+ this.readTokenManager?.revoke(useSessionDir);
605
+ }
606
+ // Only clean up temp dirs we created; caller-owned dirs have their own lifecycle
607
+ if (isOwnedTempDir) {
608
+ cleanupSessionWorkdir(useSessionDir);
609
+ }
610
+ }
611
+ }
612
+ async executeResume(params, streamCallbacks) {
613
+ return await this.runWithRetry(() => this.executeResumeOnce(params, streamCallbacks), { sessionId: params.sessionId, modelId: params.modelId });
614
+ }
615
+ async executeResumeOnce(params, streamCallbacks) {
616
+ const { sessionId, message, modelId, sessionDir, webSearchEnabled = false } = params;
617
+ const startMs = Date.now();
618
+ const actualModelId = this.resolveActualModelId(modelId);
619
+ const isOpusTier = actualModelId.includes("opus");
620
+ const maxTurns = params.maxTurns ?? (isOpusTier ? 300 : 50);
621
+ const maxBudgetUsd = params.maxBudgetUsd ?? (isOpusTier ? 5.0 : 1.0);
622
+ if (!sessionDir) {
623
+ throw new Error("sessionDir is required for executeResume — SDK stores session history per-cwd");
624
+ }
625
+ const daemonReadToken = this.readTokenManager?.issue(sessionDir) ?? this.readToken;
626
+ // Resume is always a reactive DM continuation (owner in the loop), so the
627
+ // approve-tier MCP strip stays off even for otherwise-autonomous process
628
+ // keys. `materializeMcp` short-circuits on no context / no servers.
629
+ const mcp = await this.materializeMcp(sessionDir, undefined);
630
+ const delegatedTools = this.getDelegatedClaudeTools();
631
+ const sessionDeniedTools = this.getSessionDeniedTools();
632
+ logger.info({
633
+ sessionId,
634
+ model: actualModelId,
635
+ maxTurns,
636
+ mcpServers: mcp.servers.map((s) => s.id),
637
+ delegatedToolCount: delegatedTools.length,
638
+ sessionDeniedToolCount: sessionDeniedTools.length,
639
+ }, "Agent resume started");
640
+ // Use the same cwd as the original execute() so the SDK can find
641
+ // the session history (stored per-cwd in ~/.claude/projects/).
642
+ const allowMode = this.config.claudeExecutionPermissionMode === "allow";
643
+ const stream = query({
644
+ prompt: message,
645
+ options: {
646
+ resume: sessionId,
647
+ maxTurns,
648
+ maxBudgetUsd,
649
+ cwd: sessionDir,
650
+ env: {
651
+ ...buildDaemonApiCliEnv(sessionDir, this.config.apiPort, {
652
+ readToken: daemonReadToken,
653
+ sessionBackend: "claude",
654
+ sessionId: params.sessionDbId,
655
+ eventCorrelationId: params.eventCorrelationId,
656
+ }),
657
+ ...mcp.env,
658
+ ...(params.turnToken ? { PA_TURN_TOKEN: params.turnToken } : {}),
659
+ },
660
+ systemPrompt: this.buildSystemPrompt(),
661
+ ...(allowMode
662
+ ? {
663
+ permissionMode: "bypassPermissions",
664
+ allowDangerouslySkipPermissions: true,
665
+ disallowedTools: [
666
+ ...ALWAYS_DISALLOWED_TOOLS,
667
+ ...mcp.disallowedTools,
668
+ ...sessionDeniedTools,
669
+ ],
670
+ }
671
+ : {
672
+ permissionMode: "dontAsk",
673
+ allowedTools: this.getAllowedTools(webSearchEnabled, delegatedTools),
674
+ disallowedTools: [
675
+ ...ALWAYS_DISALLOWED_TOOLS,
676
+ ...this.config.disallowedTools,
677
+ ...mcp.disallowedTools,
678
+ ...sessionDeniedTools,
679
+ ],
680
+ }),
681
+ ...(mcp.claudeMcpServers
682
+ ? { mcpServers: mcp.claudeMcpServers }
683
+ : {}),
684
+ hooks: this.getSecurityHooks(allowMode),
685
+ includePartialMessages: !!streamCallbacks,
686
+ ...this.buildAdvisorSettings(),
687
+ },
688
+ });
689
+ return await this.withTimeout(stream, () => this.consumeStream(stream, actualModelId, startMs, streamCallbacks, "message.received"), this.config.executeTimeoutMinutes);
690
+ }
691
+ async runWithRetry(fn, context) {
692
+ let lastError;
693
+ for (let attempt = 0; attempt <= ClaudeCodeCore.MAX_RETRIES; attempt++) {
694
+ try {
695
+ return await fn();
696
+ }
697
+ catch (error) {
698
+ lastError = error;
699
+ if (attempt < ClaudeCodeCore.MAX_RETRIES &&
700
+ this.isRetryableExecutionError(error)) {
701
+ logger.warn({
702
+ ...context,
703
+ attempt: attempt + 1,
704
+ maxRetries: ClaudeCodeCore.MAX_RETRIES,
705
+ error: this.getErrorMessage(error),
706
+ }, "Retrying Claude backend after transient failure");
707
+ await this.sleep(ClaudeCodeCore.RETRY_DELAY_MS);
708
+ continue;
709
+ }
710
+ throw this.classifyExecutionError(error);
711
+ }
712
+ }
713
+ throw this.classifyExecutionError(lastError);
714
+ }
715
+ isRetryableExecutionError(error) {
716
+ if (error instanceof BackendQuotaError ||
717
+ error instanceof BackendDecisiveFailure) {
718
+ return false;
719
+ }
720
+ if (error instanceof AgentTimeoutError) {
721
+ return true;
722
+ }
723
+ if (isClaudeCodeQuotaError(error)) {
724
+ return false;
725
+ }
726
+ const status = this.getErrorStatus(error);
727
+ if (typeof status === "number" && status >= 500) {
728
+ return true;
729
+ }
730
+ const code = this.getErrorCode(error)?.toUpperCase();
731
+ if (code &&
732
+ ["ECONNRESET", "ECONNREFUSED", "ETIMEDOUT", "EPIPE", "ECONNABORTED", "ENOTFOUND"].includes(code)) {
733
+ return true;
734
+ }
735
+ return /network error|fetch failed|socket hang up|connection reset|timed out/i.test(this.getErrorMessage(error));
736
+ }
737
+ /** Visible for testing. */
738
+ classifyExecutionError(error) {
739
+ if (error instanceof BackendQuotaError ||
740
+ error instanceof BackendDecisiveFailure) {
741
+ return error;
742
+ }
743
+ const quotaError = this.toBackendQuotaError(error);
744
+ if (quotaError) {
745
+ return quotaError;
746
+ }
747
+ if (error instanceof AgentTimeoutError) {
748
+ return new BackendDecisiveFailure(this.backendId, "timeout", error);
749
+ }
750
+ if (this.isAuthError(error)) {
751
+ return new BackendDecisiveFailure(this.backendId, "auth", error);
752
+ }
753
+ return new BackendDecisiveFailure(this.backendId, "other_non_retryable", error);
754
+ }
755
+ toBackendQuotaError(error) {
756
+ if (isClaudeCodeMaxBudgetError(error)) {
757
+ return new BackendQuotaError(this.backendId, "max_budget_usd", null, this.getErrorMessage(error));
758
+ }
759
+ if (!isClaudeCodeQuotaError(error)) {
760
+ return null;
761
+ }
762
+ const hint = extractClaudeCodeQuotaResetHint(error);
763
+ return new BackendQuotaError(this.backendId, this.getErrorCode(error) ?? "rate_limited", hint ? this.toBackendQuotaResetHint(hint) : null, this.getErrorMessage(error));
764
+ }
765
+ toBackendQuotaResetHint(hint) {
766
+ return {
767
+ hour: hint.hour,
768
+ minute: hint.minute,
769
+ timeZone: hint.timeZone,
770
+ rawLabel: hint.rawLabel,
771
+ };
772
+ }
773
+ isAuthError(error) {
774
+ const status = this.getErrorStatus(error);
775
+ if (status === 401 || status === 403) {
776
+ return true;
777
+ }
778
+ const code = this.getErrorCode(error)?.toLowerCase() ?? "";
779
+ const type = this.getErrorType(error)?.toLowerCase() ?? "";
780
+ if (code.includes("auth") ||
781
+ code.includes("forbidden") ||
782
+ code.includes("unauthorized") ||
783
+ type.includes("auth") ||
784
+ type.includes("forbidden") ||
785
+ type.includes("unauthorized")) {
786
+ return true;
787
+ }
788
+ return /unauthorized|forbidden|authentication|invalid api key|login required/i.test(this.getErrorMessage(error));
789
+ }
790
+ getErrorStatus(error) {
791
+ return typeof error === "object" && error !== null && "status" in error
792
+ ? error.status
793
+ : undefined;
794
+ }
795
+ getErrorCode(error) {
796
+ return typeof error === "object" && error !== null && typeof error.code === "string"
797
+ ? error.code
798
+ : undefined;
799
+ }
800
+ getErrorType(error) {
801
+ return typeof error === "object" && error !== null && typeof error.type === "string"
802
+ ? error.type
803
+ : undefined;
804
+ }
805
+ getErrorMessage(error) {
806
+ if (error instanceof Error) {
807
+ return error.message;
808
+ }
809
+ if (typeof error === "string") {
810
+ return error;
811
+ }
812
+ return "Claude backend execution failed";
813
+ }
814
+ async sleep(ms) {
815
+ await new Promise((resolve) => {
816
+ const timer = setTimeout(resolve, ms);
817
+ timer.unref?.();
818
+ });
819
+ }
820
+ async summarize(conversationText) {
821
+ const prompt = buildSummaryPrompt(conversationText);
822
+ const startMs = Date.now();
823
+ const sessionDir = createSessionWorkdir(this.config.workspaceDir, "message.received", undefined, { backendId: this.backendId, character: this.config.character });
824
+ const daemonReadToken = this.readTokenManager?.issue(sessionDir) ?? this.readToken;
825
+ try {
826
+ // Light-tier model for cheap conversation summarization. Tracks the
827
+ // canonical default in MODEL_REGISTRY so a Sonnet generation bump
828
+ // propagates here for free, mirroring how Codex/Gemini do it via
829
+ // their own `pickSummaryModel()` helpers.
830
+ const summaryModel = DEFAULT_CLAUDE_MEDIUM_MODEL;
831
+ const stream = query({
832
+ prompt,
833
+ options: {
834
+ model: summaryModel,
835
+ maxTurns: 1,
836
+ maxBudgetUsd: 0.25,
837
+ cwd: sessionDir,
838
+ env: buildDaemonApiCliEnv(sessionDir, this.config.apiPort, { readToken: daemonReadToken, sessionBackend: "claude" }),
839
+ systemPrompt: { type: "preset", preset: "claude_code" },
840
+ permissionMode: "dontAsk",
841
+ allowedTools: [],
842
+ },
843
+ });
844
+ const result = await this.withTimeout(stream, () => this.consumeStream(stream, summaryModel, startMs), this.config.executeTimeoutMinutes);
845
+ return result.output || "";
846
+ }
847
+ finally {
848
+ this.readTokenManager?.revoke(sessionDir);
849
+ cleanupSessionWorkdir(sessionDir);
850
+ }
851
+ }
852
+ async checkAuth() {
853
+ // Presence check only — this is the cheap gate used from the reactive
854
+ // execute path. Detailed probe lives in checkAuthDetailed().
855
+ const cloud = detectCloudProviderEnv();
856
+ if (cloud) {
857
+ if (cloud.missing.length > 0) {
858
+ return {
859
+ ok: false,
860
+ reason: `${cloud.flagEnvVar}=1 but missing required env vars: ${cloud.missing.join(", ")}`,
861
+ };
862
+ }
863
+ return { ok: true, method: cloud.method };
864
+ }
865
+ const rawApiKey = process.env.ANTHROPIC_API_KEY?.trim();
866
+ if (rawApiKey) {
867
+ if (!isPlausibleAnthropicApiKey(rawApiKey)) {
868
+ return {
869
+ ok: false,
870
+ reason: "ANTHROPIC_API_KEY is set but does not look like an Anthropic key (expected `sk-ant-…`).",
871
+ };
872
+ }
873
+ return { ok: true, method: "api_key" };
874
+ }
875
+ if (!this.cliPath) {
876
+ return {
877
+ ok: false,
878
+ reason: "Claude Code CLI is not installed or not on PATH. Run `npm install -g @anthropic-ai/claude-code`.",
879
+ };
880
+ }
881
+ return { ok: true, method: "cli_login" };
882
+ }
883
+ /**
884
+ * Detailed auth probe used by AuthHealthMonitor and the dashboard setup
885
+ * wizard. Two modes:
886
+ * - **API key** (`ANTHROPIC_API_KEY`): format check + server-side probe
887
+ * via `probeApiKeyServerSide("anthropic", ...)` (roadmap §9.1).
888
+ * Throws on network/timeout so `checkAll()` records `probe_network_error`.
889
+ * - **CLI login**: reads `~/.claude/credentials.json` for `refreshToken`.
890
+ * Never writes to the Keychain or credentials file — refresh is left
891
+ * to the CLI (Phase 0 confirmed rotating refresh_tokens; daemon-driven
892
+ * refresh would race and corrupt state).
893
+ */
894
+ async checkAuthDetailed() {
895
+ const cloud = detectCloudProviderEnv();
896
+ if (cloud) {
897
+ if (cloud.missing.length > 0) {
898
+ return {
899
+ ok: false,
900
+ status: "missing",
901
+ method: cloud.method,
902
+ detail: `${cloud.flagEnvVar}=1 but missing: ${cloud.missing.join(", ")}`,
903
+ recoveryCommand: `Set the missing env vars or unset ${cloud.flagEnvVar}`,
904
+ };
905
+ }
906
+ // Real auth happens inside the SDK against AWS / GCP / Azure. The
907
+ // daemon does not run a server-side probe for cloud providers — the
908
+ // first execution will surface any credential failure. Mark the
909
+ // status as `ok` here so the dashboard reports "Configured (cloud)";
910
+ // AuthHealthMonitor still re-runs this check hourly so a malformed
911
+ // env (env vars cleared after launch) flips the cache to `missing`.
912
+ return {
913
+ ok: true,
914
+ status: "ok",
915
+ method: cloud.method,
916
+ detail: `Configured via ${cloud.label} — runtime auth verified by Claude Code SDK`,
917
+ };
918
+ }
919
+ const rawApiKey = process.env.ANTHROPIC_API_KEY?.trim();
920
+ if (rawApiKey) {
921
+ if (!isPlausibleAnthropicApiKey(rawApiKey)) {
922
+ return {
923
+ ok: false,
924
+ status: "expired",
925
+ method: "api_key",
926
+ detail: "ANTHROPIC_API_KEY does not match Anthropic key format (expected `sk-ant-…`).",
927
+ recoveryCommand: "Unset ANTHROPIC_API_KEY or replace it with a valid Anthropic API key",
928
+ };
929
+ }
930
+ // Format is plausible — attempt a server-side probe to detect
931
+ // revoked keys within 1 hourly cycle (roadmap §9.1). On network
932
+ // failure, the probe throws and the caller (checkAll or check-auth
933
+ // route) records `probe_network_error` without flipping DB cache.
934
+ const probe = await probeApiKeyServerSide("anthropic", rawApiKey);
935
+ return {
936
+ ok: probe.ok,
937
+ status: probe.ok ? "ok" : "expired",
938
+ method: "api_key",
939
+ detail: probe.detail,
940
+ ...(!probe.ok && {
941
+ recoveryCommand: "Unset ANTHROPIC_API_KEY or replace it with a valid Anthropic API key",
942
+ }),
943
+ };
944
+ }
945
+ if (!this.cliPath) {
946
+ return {
947
+ ok: false,
948
+ status: "missing",
949
+ method: "cli_login",
950
+ detail: "Claude Code CLI not found on PATH",
951
+ recoveryCommand: "npm install -g @anthropic-ai/claude-code",
952
+ };
953
+ }
954
+ const bundle = await readClaudeCredentials();
955
+ if (!bundle) {
956
+ return {
957
+ ok: false,
958
+ status: "expired",
959
+ method: "cli_login",
960
+ detail: "No Claude credentials found",
961
+ recoveryCommand: "claude auth login",
962
+ };
963
+ }
964
+ if (!bundle.refreshToken) {
965
+ return {
966
+ ok: false,
967
+ status: "expired",
968
+ method: "cli_login",
969
+ detail: "Credentials lack refresh_token — run `claude auth login`",
970
+ recoveryCommand: "claude auth login",
971
+ };
972
+ }
973
+ return { ok: true, status: "ok", method: "oauth" };
974
+ }
975
+ /**
976
+ * Phase 5 §4.11 live probe. Claude Code 2.1+ may defer large MCP tool
977
+ * manifests behind `ToolSearch`, so the old zero-turn `system.init.tools`
978
+ * capture is no longer sufficient for hosted claude.ai connectors like
979
+ * Gmail and Google Calendar. Run a tightly-scoped turn that can only use
980
+ * the read-only ToolSearch catalog, then extract connector names from
981
+ * both returned `tool_reference` blocks and the final printed answer.
982
+ */
983
+ async probeTools() {
984
+ const sessionDir = createSessionWorkdir(this.config.workspaceDir, "message.received", undefined, { backendId: this.backendId, character: this.config.character });
985
+ const daemonReadToken = this.readTokenManager?.issue(sessionDir) ?? this.readToken;
986
+ try {
987
+ const stream = query({
988
+ prompt: CLAUDE_PROBE_TOOLS_PROMPT,
989
+ options: {
990
+ model: DEFAULT_CLAUDE_MEDIUM_MODEL,
991
+ maxTurns: 3,
992
+ maxBudgetUsd: 0.25,
993
+ cwd: sessionDir,
994
+ env: buildDaemonApiCliEnv(sessionDir, this.config.apiPort, { readToken: daemonReadToken, sessionBackend: "claude" }),
995
+ systemPrompt: { type: "preset", preset: "claude_code" },
996
+ permissionMode: "dontAsk",
997
+ allowedTools: ["ToolSearch"],
998
+ },
999
+ });
1000
+ const tools = await new Promise((resolve, reject) => {
1001
+ const timer = setTimeout(() => {
1002
+ void (async () => {
1003
+ try {
1004
+ await stream.return?.(undefined);
1005
+ }
1006
+ catch {
1007
+ /* stream already closed */
1008
+ }
1009
+ })();
1010
+ reject(new Error("probeTools: timeout waiting for ToolSearch probe"));
1011
+ }, 60_000);
1012
+ timer.unref?.();
1013
+ void (async () => {
1014
+ const collected = [];
1015
+ let terminalError = null;
1016
+ try {
1017
+ for await (const message of stream) {
1018
+ collected.push(...extractClaudeProbeTools(message));
1019
+ if (message.type === "result") {
1020
+ const result = message;
1021
+ if (result.is_error) {
1022
+ terminalError = describeClaudeProbeResultError(result);
1023
+ }
1024
+ }
1025
+ }
1026
+ clearTimeout(timer);
1027
+ const deduped = Array.from(new Set(collected));
1028
+ if (terminalError && deduped.length === 0) {
1029
+ reject(new Error(`probeTools: ${terminalError}`));
1030
+ return;
1031
+ }
1032
+ resolve(deduped);
1033
+ }
1034
+ catch (err) {
1035
+ clearTimeout(timer);
1036
+ reject(err instanceof Error ? err : new Error(String(err)));
1037
+ }
1038
+ })();
1039
+ });
1040
+ logger.info({ toolCount: tools.length }, "Live probe collected tool manifest");
1041
+ return tools;
1042
+ }
1043
+ finally {
1044
+ this.readTokenManager?.revoke(sessionDir);
1045
+ cleanupSessionWorkdir(sessionDir);
1046
+ }
1047
+ }
1048
+ listModels() {
1049
+ const defaultMediumModel = DEFAULT_CLAUDE_MEDIUM_MODEL;
1050
+ const defaultHighModel = DEFAULT_CLAUDE_HIGH_MODEL;
1051
+ const configuredModels = [
1052
+ {
1053
+ ...(findRegisteredModel(this.backendId, defaultMediumModel) ?? {
1054
+ backendId: this.backendId,
1055
+ modelId: defaultMediumModel,
1056
+ label: defaultMediumModel,
1057
+ tier: "medium",
1058
+ available: true,
1059
+ }),
1060
+ },
1061
+ {
1062
+ ...(findRegisteredModel(this.backendId, defaultHighModel) ?? {
1063
+ backendId: this.backendId,
1064
+ modelId: defaultHighModel,
1065
+ label: defaultHighModel,
1066
+ tier: "high",
1067
+ available: true,
1068
+ }),
1069
+ },
1070
+ ];
1071
+ const models = [...configuredModels, ...getModelsForBackend(this.backendId)];
1072
+ return models.filter((model, index, list) => list.findIndex((candidate) => candidate.modelId === model.modelId) === index);
1073
+ }
1074
+ async consumeStream(stream, model, startMs, streamCallbacks, eventType) {
1075
+ let output = "";
1076
+ let streamedOutput = "";
1077
+ let sessionId = null;
1078
+ let costUsd = 0;
1079
+ let usage = {
1080
+ inputTokens: 0,
1081
+ outputTokens: 0,
1082
+ cacheCreationInputTokens: 0,
1083
+ cacheReadInputTokens: 0,
1084
+ };
1085
+ const modelUsage = {};
1086
+ let numTurns = 0;
1087
+ let durationApiMs = 0;
1088
+ let isError = false;
1089
+ let stopReason = null;
1090
+ // Context-update tracking (Phase 6 + H2 refinement).
1091
+ const contextUpdateCalls = new Set();
1092
+ const failedContextUpdates = new Set();
1093
+ // Advisor tool invocation count — incremented each time the SDK stream
1094
+ // emits a `server_tool_use` content block with `name: "advisor"`. This is
1095
+ // the `advisor_20260301` Anthropic-hosted tool. See `docs/advisor.md`.
1096
+ let advisorCallCount = 0;
1097
+ // B-003 Phase 4.4 — MCP tool result matching.
1098
+ // Maps tool_use_id → { rowId, startMs } so that when the SDK delivers the
1099
+ // matching tool_result block we can backfill ok/error/duration_ms.
1100
+ // startMs is set when the assistant message containing the tool_use block is
1101
+ // processed. The resulting duration_ms therefore covers SDK dispatch latency
1102
+ // (model → executor → result delivery) rather than pure tool execution time.
1103
+ const mcpPendingResults = new Map();
1104
+ try {
1105
+ for await (const message of stream) {
1106
+ if (message.type === "system" && message.subtype === "init") {
1107
+ const sysMsg = message;
1108
+ sessionId = sysMsg.session_id;
1109
+ logger.debug({ sessionId, model: sysMsg.model }, "Session initialized");
1110
+ }
1111
+ else if (message.type === "stream_event") {
1112
+ // Forward streaming text deltas to the caller (e.g., dashboard SSE)
1113
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- SDK stream_event lacks typed .event
1114
+ const event = message.event;
1115
+ if (event?.type === "content_block_delta" && event?.delta?.type === "text_delta") {
1116
+ streamedOutput += event.delta.text;
1117
+ streamCallbacks?.onText?.(event.delta.text);
1118
+ }
1119
+ }
1120
+ else if (message.type === "assistant") {
1121
+ // Track Bash tool_use blocks that hit the context API + server-side
1122
+ // advisor tool invocations.
1123
+ const assistantMsg = message;
1124
+ const blocks = assistantMsg.message?.content;
1125
+ if (Array.isArray(blocks)) {
1126
+ for (const block of blocks) {
1127
+ if (!block || typeof block !== "object")
1128
+ continue;
1129
+ const blockType = block.type;
1130
+ const blockName = block.name;
1131
+ if (blockType === "tool_use" && blockName === "Bash") {
1132
+ const toolUseId = block.id;
1133
+ const cmd = (block.input?.command ?? "");
1134
+ if (typeof toolUseId === "string" &&
1135
+ typeof cmd === "string" &&
1136
+ ClaudeCodeCore.isContextUpdateCommand(cmd)) {
1137
+ contextUpdateCalls.add(toolUseId);
1138
+ }
1139
+ }
1140
+ else if (blockType === "tool_use" &&
1141
+ typeof blockName === "string" &&
1142
+ blockName.startsWith("mcp__")) {
1143
+ // B-003 Phase 4.4 — persist MCP tool call to `mcp_tool_calls`.
1144
+ // Capture tool_use_id + start time so we can match the result
1145
+ // block that arrives later in a `user` message.
1146
+ const parsed = parseMcpToolName(blockName);
1147
+ if (parsed) {
1148
+ logger.debug({
1149
+ serverId: parsed.serverId,
1150
+ toolName: parsed.toolName,
1151
+ sessionId,
1152
+ eventType,
1153
+ }, "mcp.tool_call");
1154
+ if (this.mcpContext?.db) {
1155
+ try {
1156
+ const rowId = logMcpToolCall(this.mcpContext.db, {
1157
+ serverId: parsed.serverId,
1158
+ toolName: parsed.toolName,
1159
+ eventType,
1160
+ sessionId: sessionId ?? undefined,
1161
+ });
1162
+ const toolUseId = block.id;
1163
+ if (typeof toolUseId === "string") {
1164
+ mcpPendingResults.set(toolUseId, { rowId, startMs: Date.now() });
1165
+ }
1166
+ }
1167
+ catch (err) {
1168
+ logger.warn({ err, serverId: parsed.serverId }, "mcp.tool_call audit insert failed");
1169
+ }
1170
+ }
1171
+ }
1172
+ }
1173
+ else if (blockType === "server_tool_use" &&
1174
+ blockName === "advisor") {
1175
+ // The advisor_20260301 server-side tool. The SDK emits one
1176
+ // server_tool_use per invocation; we count them here.
1177
+ advisorCallCount += 1;
1178
+ }
1179
+ }
1180
+ }
1181
+ }
1182
+ else if (message.type === "user") {
1183
+ // The SDK emits the tool_result that feeds back to the model
1184
+ // as a 'user' message whose content array contains
1185
+ // tool_result blocks. Check is_error on each result matched
1186
+ // against our pending context tool_use ids, and scan the
1187
+ // merged tool output for PA_API_ERROR markers emitted by the
1188
+ // daemon API wrappers.
1189
+ const userMsg = message;
1190
+ const content = userMsg.message?.content;
1191
+ if (Array.isArray(content)) {
1192
+ for (const block of content) {
1193
+ if (block &&
1194
+ block.type === "tool_result") {
1195
+ const toolUseId = block.tool_use_id;
1196
+ const isError = block.is_error === true;
1197
+ if (typeof toolUseId === "string") {
1198
+ // Context-update error tracking.
1199
+ if (contextUpdateCalls.has(toolUseId) && isError) {
1200
+ failedContextUpdates.add(toolUseId);
1201
+ }
1202
+ // B-003 Phase 4.4 — backfill ok/error/duration_ms for MCP tool calls.
1203
+ const pending = mcpPendingResults.get(toolUseId);
1204
+ if (pending && this.mcpContext?.db) {
1205
+ const ok = !isError;
1206
+ const errorText = isError
1207
+ ? flattenToolResultContent(block.content).slice(0, 1000) || null
1208
+ : null;
1209
+ const durationMs = Date.now() - pending.startMs;
1210
+ try {
1211
+ updateMcpToolCallResult(this.mcpContext.db, pending.rowId, ok, errorText, durationMs);
1212
+ }
1213
+ catch (err) {
1214
+ logger.warn({ err, rowId: pending.rowId }, "mcp.tool_call result update failed");
1215
+ }
1216
+ mcpPendingResults.delete(toolUseId);
1217
+ }
1218
+ }
1219
+ const resultText = flattenToolResultContent(block.content);
1220
+ const apiErrors = extractSilentApiErrors(resultText);
1221
+ if (apiErrors.length > 0) {
1222
+ logSilentApiErrors(logger, apiErrors, {
1223
+ backendId: this.backendId,
1224
+ sessionId,
1225
+ eventType,
1226
+ });
1227
+ }
1228
+ }
1229
+ }
1230
+ }
1231
+ }
1232
+ else if (message.type === "result") {
1233
+ const r = message;
1234
+ if (r.subtype === "success") {
1235
+ const resultOutput = typeof r.result === "string" ? r.result : "";
1236
+ // Claude SDK can stream assistant text and still report an empty
1237
+ // final result when the turn ends after a tool-only message.
1238
+ output =
1239
+ resultOutput.trim().length > 0
1240
+ ? resultOutput
1241
+ : streamedOutput.trim().length > 0
1242
+ ? streamedOutput
1243
+ : resultOutput;
1244
+ }
1245
+ sessionId = r.session_id;
1246
+ costUsd = r.total_cost_usd;
1247
+ usage = {
1248
+ inputTokens: r.usage.input_tokens,
1249
+ outputTokens: r.usage.output_tokens,
1250
+ cacheCreationInputTokens: r.usage.cache_creation_input_tokens ?? 0,
1251
+ cacheReadInputTokens: r.usage.cache_read_input_tokens ?? 0,
1252
+ };
1253
+ // Convert SDK modelUsage to our format
1254
+ for (const [modelName, mu] of Object.entries(r.modelUsage)) {
1255
+ modelUsage[modelName] = {
1256
+ inputTokens: mu.inputTokens,
1257
+ outputTokens: mu.outputTokens,
1258
+ costUsd: mu.costUSD,
1259
+ };
1260
+ }
1261
+ numTurns = r.num_turns;
1262
+ durationApiMs = r.duration_api_ms;
1263
+ isError = r.is_error;
1264
+ stopReason = r.stop_reason;
1265
+ if (r.subtype !== "success") {
1266
+ logger.warn({ subtype: r.subtype, errors: "errors" in r ? r.errors : [] }, "Agent session ended with error");
1267
+ }
1268
+ }
1269
+ }
1270
+ }
1271
+ finally {
1272
+ // Always signal stream completion — even on error — so the client's
1273
+ // streaming state is reset (prevents stuck "streaming = true").
1274
+ streamCallbacks?.onEnd?.();
1275
+ }
1276
+ const contextUpdated = contextUpdateCalls.size > failedContextUpdates.size;
1277
+ return {
1278
+ output,
1279
+ sessionId,
1280
+ backendId: this.backendId,
1281
+ modelId: model,
1282
+ costSource: "sdk",
1283
+ costUsd,
1284
+ usage,
1285
+ modelUsage,
1286
+ numTurns,
1287
+ durationMs: Date.now() - startMs,
1288
+ durationApiMs,
1289
+ model,
1290
+ isError,
1291
+ stopReason,
1292
+ contextUpdated,
1293
+ advisorCallCount,
1294
+ };
1295
+ }
1296
+ /**
1297
+ * Race `fn()` against an `executeTimeoutMinutes` wall-clock timer.
1298
+ *
1299
+ * On timeout we must terminate the underlying SDK stream too — otherwise
1300
+ * `Promise.race` just rejects while `query()` keeps running in the
1301
+ * background, which in retry scenarios would produce two concurrent
1302
+ * Claude Code sessions for the same event and double quota consumption.
1303
+ */
1304
+ async withTimeout(stream, fn, timeoutMinutes) {
1305
+ const timeoutMs = timeoutMinutes * 60 * 1000;
1306
+ let timer;
1307
+ let timedOut = false;
1308
+ const fnPromise = fn();
1309
+ // Attach a no-op catch so post-timeout rejections from fn() don't
1310
+ // surface as unhandledRejection once Promise.race has already resolved.
1311
+ fnPromise.catch(() => undefined);
1312
+ try {
1313
+ return await Promise.race([
1314
+ fnPromise,
1315
+ new Promise((_, reject) => {
1316
+ timer = setTimeout(() => {
1317
+ timedOut = true;
1318
+ reject(new AgentTimeoutError(timeoutMs));
1319
+ // Cancel the SDK stream asynchronously.
1320
+ void (async () => {
1321
+ try {
1322
+ const iterable = stream;
1323
+ const iterator = typeof iterable[Symbol.asyncIterator] === "function"
1324
+ ? iterable[Symbol.asyncIterator]()
1325
+ : null;
1326
+ await iterator?.return?.(undefined);
1327
+ }
1328
+ catch {
1329
+ // ignore — cancellation is best-effort
1330
+ }
1331
+ })();
1332
+ }, timeoutMs);
1333
+ timer.unref?.();
1334
+ }),
1335
+ ]);
1336
+ }
1337
+ finally {
1338
+ if (timer) {
1339
+ clearTimeout(timer);
1340
+ }
1341
+ void timedOut; // reference to avoid unused-variable if optimizer drops it
1342
+ }
1343
+ }
1344
+ /**
1345
+ * Detect whether a Bash command invokes a write against the Context
1346
+ * File API (`PUT|PATCH /api/context/*` via curl).
1347
+ */
1348
+ static isContextUpdateCommand(command) {
1349
+ if (!/\bcurl\b/.test(command))
1350
+ return false;
1351
+ if (!/\/api\/context\//.test(command))
1352
+ return false;
1353
+ const segments = command.split(/[;&|\n]+/);
1354
+ for (const seg of segments) {
1355
+ if (!/\bcurl\b/.test(seg))
1356
+ continue;
1357
+ if (!/\/api\/context\//.test(seg))
1358
+ continue;
1359
+ if (/(?:-X|--request)\s+(?:PUT|PATCH)\b/.test(seg)) {
1360
+ return true;
1361
+ }
1362
+ }
1363
+ return false;
1364
+ }
1365
+ // Template resolution and event data extraction are shared with Codex/Gemini
1366
+ // backends via prompt-utils.ts (buildExecutionPrompt, extractEventData).
1367
+ /**
1368
+ * Allowed tools whitelist for dontAsk permission mode.
1369
+ *
1370
+ * `delegatedTools` is UNION'd onto the returned list — even when
1371
+ * `allowedToolsOverride` is set. This is a deliberate deviation from the
1372
+ * override's otherwise-absolute "replace everything" contract (see
1373
+ * `CRITICAL_OVERRIDE_TOOLS` at line 293, which warns but does not union).
1374
+ * Rationale: delegated mode is a runtime-configurable axis orthogonal to
1375
+ * the dashboard's tool-customization override. If a user set the override
1376
+ * before flipping an integration to delegated, silently dropping the
1377
+ * registry-declared connector tools would break mail/calendar with a
1378
+ * misleading "permission denied" DM. Union semantics keep the override's
1379
+ * curation intent while letting delegated mode widen the surface to
1380
+ * whatever the registry already advertised.
1381
+ */
1382
+ getAllowedTools(webSearchEnabled, delegatedTools = []) {
1383
+ const base = this.config.allowedToolsOverride ?? [
1384
+ "Read",
1385
+ "Glob",
1386
+ "Grep",
1387
+ "Write",
1388
+ "Edit",
1389
+ "Skill", // user skills (external-services, obsidian-*, observations, ...)
1390
+ "Bash(curl *)", // curl broadly allowed; hooks restrict to localhost
1391
+ "Bash(git *)", // Git operations
1392
+ "Bash(jq *)", // safe JSON post-processor for curl pipelines
1393
+ ];
1394
+ const merged = new Set(base);
1395
+ if (!this.config.allowedToolsOverride && webSearchEnabled) {
1396
+ merged.add("WebSearch");
1397
+ }
1398
+ for (const tool of delegatedTools)
1399
+ merged.add(tool);
1400
+ return Array.from(merged);
1401
+ }
1402
+ /**
1403
+ * Thin wrapper around the pure `computeDelegatedClaudeTools` helper that
1404
+ * pulls the integrations record from the wired mcp context. Returns `[]`
1405
+ * when the context is not yet wired (tests, startup ordering) — which
1406
+ * matches the pre-fix behavior for sessions that ran before the daemon
1407
+ * finished composing. A one-shot warning is emitted in `setMcpContext`
1408
+ * confirming wiring.
1409
+ */
1410
+ getDelegatedClaudeTools() {
1411
+ if (!this.mcpContext)
1412
+ return [];
1413
+ try {
1414
+ const integrations = readIntegrations(this.mcpContext.db);
1415
+ return computeDelegatedClaudeTools(integrations);
1416
+ }
1417
+ catch (err) {
1418
+ logger.warn({ err }, "Failed to read integrations for delegated-tool allowlist — proceeding without delegated tools");
1419
+ return [];
1420
+ }
1421
+ }
1422
+ /**
1423
+ * DELEGATED-MODE-V2-DESIGN.md §4.3.3 — same-backend deny enforcement at
1424
+ * the SDK boundary. For every integration whose `delegatedBackend === "claude"`,
1425
+ * expand `state.deniedTools` against the connector's known tools and emit
1426
+ * the namespaced names (`mcp__claude_ai_<X>__<tool>`). The SDK refuses any
1427
+ * tool listed in `disallowedTools` regardless of `allowedTools` — hard
1428
+ * enforcement.
1429
+ *
1430
+ * Returns `[]` when context isn't wired (tests / pre-startup) and on read
1431
+ * failures, matching the conservative pattern used by
1432
+ * `getDelegatedClaudeTools`.
1433
+ */
1434
+ getSessionDeniedTools() {
1435
+ if (!this.mcpContext)
1436
+ return [];
1437
+ try {
1438
+ const integrations = readIntegrations(this.mcpContext.db);
1439
+ const map = collectSessionDeniedTools(integrations, "claude");
1440
+ const out = [];
1441
+ for (const names of map.values()) {
1442
+ for (const n of names)
1443
+ out.push(n);
1444
+ }
1445
+ return out;
1446
+ }
1447
+ catch (err) {
1448
+ logger.warn({ err }, "Failed to read integrations for same-backend denied-tools — proceeding without per-integration deny");
1449
+ return [];
1450
+ }
1451
+ }
1452
+ /**
1453
+ * Security hooks:
1454
+ * 1. Bash(curl *) — restrict to localhost Daemon API, block connection-override flags. (strict only)
1455
+ * 2. Bash(jq *) — block file-access flags and the `env` filter (process env exfiltration). (strict only)
1456
+ * 3. Write/Edit — block writes into the session helper dir and context dir, mark vault writes.
1457
+ *
1458
+ * In allow mode the curl and jq hooks are dropped, but the Write/Edit hook
1459
+ * stays: the context-dir chokepoint exists for memory integrity (today-write
1460
+ * lock, md_file_snapshots, CONTEXT_WRITE_PERMISSIONS), not permissions.
1461
+ */
1462
+ getSecurityHooks(allowMode = false) {
1463
+ const bashCurlHook = async (input) => {
1464
+ const toolInput = input.tool_input;
1465
+ const cmd = toolInput?.command ?? "";
1466
+ if (/\bcurl\b/.test(cmd)) {
1467
+ const urls = cmd.match(/https?:\/\/[^\s'"]+/g) ?? [];
1468
+ if (urls.length === 0) {
1469
+ return {
1470
+ decision: "block",
1471
+ reason: "curl command must contain an explicit localhost URL",
1472
+ };
1473
+ }
1474
+ for (const url of urls) {
1475
+ try {
1476
+ const parsed = new URL(url);
1477
+ if (parsed.hostname !== "localhost" && parsed.hostname !== "127.0.0.1") {
1478
+ return {
1479
+ decision: "block",
1480
+ reason: `curl target not allowed: ${url} (host: ${parsed.hostname})`,
1481
+ };
1482
+ }
1483
+ const effectivePort = parsed.port || (parsed.protocol === "https:" ? "443" : "80");
1484
+ if (effectivePort !== String(this.config.apiPort)) {
1485
+ return {
1486
+ decision: "block",
1487
+ reason: `curl target port not allowed: ${effectivePort}`,
1488
+ };
1489
+ }
1490
+ }
1491
+ catch {
1492
+ return {
1493
+ decision: "block",
1494
+ reason: `curl target URL is malformed: ${url}`,
1495
+ };
1496
+ }
1497
+ }
1498
+ if (/--connect-to|--resolve|--config\b|(?:^|\s)-[a-zA-Z]*K|--proxy\b|(?:^|\s)-[a-zA-Z]*x|--socks/.test(cmd)) {
1499
+ return {
1500
+ decision: "block",
1501
+ reason: "curl connection override flags not allowed (--connect-to, --resolve, --config, --proxy)",
1502
+ };
1503
+ }
1504
+ }
1505
+ return { continue: true };
1506
+ };
1507
+ const bashJqHook = async (input) => {
1508
+ const toolInput = input.tool_input;
1509
+ const cmd = toolInput?.command ?? "";
1510
+ if (!/\bjq\b/.test(cmd))
1511
+ return { continue: true };
1512
+ // Narrow to THIS jq invocation's own args (up to the next pipe / chain op)
1513
+ // so that later pipeline stages are not inspected by the jq rules.
1514
+ //
1515
+ // Known approximation: `[^|;&]*` does not respect shell quoting, so a
1516
+ // jq filter with a `|` INSIDE a quoted expression (e.g. `jq 'env | keys'`)
1517
+ // will truncate `jqPart` at the first `|` regardless of whether that `|`
1518
+ // is a jq pipe inside quotes or an actual shell pipeline break. This is
1519
+ // intentionally conservative on the safe side: the env-filter check
1520
+ // below still fires on the truncated left half (`jq 'env `), so attack
1521
+ // payloads are still blocked. The downside is slightly reduced precision
1522
+ // on benign expressions containing the jq `|` operator — those get
1523
+ // scanned only up to the first pipe, not their full extent.
1524
+ const jqMatch = cmd.match(/\bjq\b([^|;&]*)/);
1525
+ if (!jqMatch)
1526
+ return { continue: true };
1527
+ const jqPart = jqMatch[0];
1528
+ // (a) Block file-access flags — --slurpfile / --rawfile read arbitrary
1529
+ // files, which would bypass the Read deny list (~/.ssh/**, .env, etc.).
1530
+ if (/(?:^|\s)--slurpfile\b/.test(jqPart) || /(?:^|\s)--rawfile\b/.test(jqPart)) {
1531
+ return {
1532
+ decision: "block",
1533
+ reason: "jq --slurpfile and --rawfile are not allowed " +
1534
+ "(would bypass Read(.env) / Read(~/.ssh/**) disallow rules).",
1535
+ };
1536
+ }
1537
+ // (b) Block module loading — -L <dir> + import can load filter code from
1538
+ // the filesystem, effectively RCE inside the jq process.
1539
+ if (/(?:^|\s)-L(?:\s|=|$)/.test(jqPart)) {
1540
+ return {
1541
+ decision: "block",
1542
+ reason: "jq -L (module load path) is not allowed.",
1543
+ };
1544
+ }
1545
+ // (c) Block the `env` filter. `jq env`, `jq -n env`, `jq 'env.FOO'`,
1546
+ // `jq '. , env'` all dump the daemon's process.env to stdout. Process.env
1547
+ // on this daemon is expected to be clean (secrets live in the keychain),
1548
+ // but defense-in-depth: if OPENAI_API_KEY or similar is ever exported at
1549
+ // launch, the env filter is the shortest exfil path.
1550
+ //
1551
+ // Heuristic: match bare `env` NOT preceded by a field-access dot or word
1552
+ // char, and NOT followed by a word char. This matches jq's env filter
1553
+ // (`env`, `env.HOME`, `(env)`, `env|keys`) while leaving field access
1554
+ // like `.env`, `.env_var`, `.data.environments` untouched.
1555
+ if (/(?:^|[^\w.])env(?!\w)/.test(jqPart)) {
1556
+ return {
1557
+ decision: "block",
1558
+ reason: "jq env filter is not allowed — it dumps the daemon process " +
1559
+ "environment, which is a known exfiltration vector for any " +
1560
+ "secrets loaded via .env at startup.",
1561
+ };
1562
+ }
1563
+ return { continue: true };
1564
+ };
1565
+ /**
1566
+ * Block any Bash command that references the context-directory path.
1567
+ *
1568
+ * Rationale: the daemon API is the ONLY sanctioned write channel for
1569
+ * context files — it enforces today-write-lock, md_file_snapshots,
1570
+ * CONTEXT_WRITE_PERMISSIONS, and onPromptContextChanged. In strict mode,
1571
+ * the allowlist (Bash narrowed to curl/git/jq) + fileWriteHook keeps
1572
+ * this chokepoint intact. In allow mode Bash is unrestricted, so an
1573
+ * agent could bypass via `echo > today.md`, `tee`, `python -c 'open…'`,
1574
+ * `git log … > context/…`, etc.
1575
+ *
1576
+ * This hook runs in BOTH modes (defense-in-depth). The heuristic is
1577
+ * deliberately conservative: we block the command if its raw text
1578
+ * contains any of the well-known path representations of the context
1579
+ * dir. This has false positives for read-only uses (`cat context/*.md`),
1580
+ * but the agent always has the Read tool and the daemon GET endpoint
1581
+ * available, so a blocked shell-read is an error message, not a
1582
+ * capability loss. Obfuscation beyond the handled variants (dynamic
1583
+ * path construction inside a subshell) is out of scope — the threat
1584
+ * model is "the model picks a shell workaround", not adversarial
1585
+ * prompt injection.
1586
+ */
1587
+ const bashContextWriteHook = async (input) => {
1588
+ const toolInput = input.tool_input;
1589
+ const cmd = toolInput?.command ?? "";
1590
+ if (typeof cmd !== "string" || cmd.length === 0)
1591
+ return { continue: true };
1592
+ const absContextDir = resolvePath(getContextDir(this.config));
1593
+ const home = homedir();
1594
+ const pathForms = shellPathForms(absContextDir, home);
1595
+ for (const form of pathForms) {
1596
+ if (cmd.includes(form)) {
1597
+ return {
1598
+ decision: "block",
1599
+ reason: `Bash commands that reference the context directory (${absContextDir}) are ` +
1600
+ `not allowed. Use the daemon API: ` +
1601
+ `GET/PUT/PATCH http://localhost:${this.config.apiPort}/api/context/<path>. ` +
1602
+ `The API enforces today-write-lock, md_file_snapshots, CONTEXT_WRITE_PERMISSIONS, ` +
1603
+ `and onPromptContextChanged — bypassing it via shell redirects or script ` +
1604
+ `engines leaves the memory layer inconsistent. Matched path form: ${form}.`,
1605
+ };
1606
+ }
1607
+ }
1608
+ return { continue: true };
1609
+ };
1610
+ const fileWriteHook = async (input) => {
1611
+ const hookInput = input;
1612
+ const toolInput = hookInput.tool_input;
1613
+ const rawFilePath = toolInput?.file_path;
1614
+ if (typeof rawFilePath !== "string" || rawFilePath.length === 0) {
1615
+ return { continue: true };
1616
+ }
1617
+ const filePath = rawFilePath;
1618
+ const cwd = hookInput.cwd;
1619
+ if (!cwd && !isAbsolute(filePath))
1620
+ return { continue: true };
1621
+ const absFile = resolvePath(cwd ?? "/", filePath);
1622
+ // (a) Block writes into the session-local helper dir. The `curl` shim in
1623
+ // `.pa/bin/` carries daemon-auth env at execution time; letting the model
1624
+ // rewrite it would turn the helper into a secret exfiltration vector.
1625
+ const absHelperDir = resolvePath(cwd ?? "/", ".pa");
1626
+ const withinHelperDir = isPathInsideOrEqual(absHelperDir, absFile);
1627
+ if (withinHelperDir) {
1628
+ return {
1629
+ decision: "block",
1630
+ reason: "Direct Write/Edit to .pa is forbidden. " +
1631
+ "Session helper binaries are managed by the daemon.",
1632
+ };
1633
+ }
1634
+ // (b) Block writes into the context dir.
1635
+ const contextDir = getContextDir(this.config);
1636
+ const absContextDir = resolvePath(contextDir);
1637
+ const withinContext = isPathInsideOrEqual(absContextDir, absFile);
1638
+ if (withinContext) {
1639
+ return {
1640
+ decision: "block",
1641
+ reason: `Direct Write/Edit to context dir is forbidden. ` +
1642
+ `Use the daemon API instead: ` +
1643
+ `PUT http://localhost:${this.config.apiPort}/api/context/<path> (full replace) or ` +
1644
+ `PATCH http://localhost:${this.config.apiPort}/api/context/<path> (section op). ` +
1645
+ `The API enforces CONTEXT_WRITE_PERMISSIONS, morningRoutineLock, md_file_snapshots, ` +
1646
+ `onPromptContextChanged, and expectedMtime concurrency. Path: ${absFile}`,
1647
+ };
1648
+ }
1649
+ // (c) Mark vault-scoped writes for observer attribution.
1650
+ // Targets the EXTERNAL Obsidian vault; the ObsidianWatcher observer
1651
+ // watches that path and would otherwise misattribute agent writes
1652
+ // as user writes.
1653
+ if (!this.writeTracker)
1654
+ return { continue: true };
1655
+ const vaultPath = this.config.externalObsidianVaultPath;
1656
+ if (!vaultPath)
1657
+ return { continue: true };
1658
+ const absVault = resolvePath(vaultPath);
1659
+ const withinVault = isPathInsideOrEqual(absVault, absFile);
1660
+ if (!withinVault)
1661
+ return { continue: true };
1662
+ this.writeTracker.markWriting(absFile);
1663
+ logger.debug({ filePath: absFile }, "vault write pre-marked for observer attribution");
1664
+ return { continue: true };
1665
+ };
1666
+ // EXECUTION-MODE-DESIGN.md §6 — absolute-block audit hook. Runs ahead
1667
+ // of every other Bash/Read/Write/Edit hook in both modes. The SDK-level
1668
+ // `disallowedTools` rejection is the authoritative block; this hook is
1669
+ // redundant defense-in-depth that also writes the `blocked_absolute`
1670
+ // audit row so the owner can see the layer is active.
1671
+ const makeAbsoluteBlockHook = (toolName, argField) => async (input) => {
1672
+ const toolInput = input.tool_input;
1673
+ const raw = toolInput?.[argField];
1674
+ if (typeof raw !== "string")
1675
+ return { continue: true };
1676
+ const match = classifyAbsoluteBlock(toolName, raw);
1677
+ if (!match)
1678
+ return { continue: true };
1679
+ recordAbsoluteBlockAudit({
1680
+ db: this.mcpContext?.db,
1681
+ backend: "claude",
1682
+ mode: this.config.claudeExecutionPermissionMode,
1683
+ match,
1684
+ toolName,
1685
+ });
1686
+ return {
1687
+ decision: "block",
1688
+ reason: `Absolute-block layer denied this ${toolName} call ` +
1689
+ `(category: ${match.category}). This rule holds in both Safe ` +
1690
+ `and Allow modes — see EXECUTION-MODE-DESIGN.md §6.`,
1691
+ };
1692
+ };
1693
+ const bashAbsoluteBlockHook = makeAbsoluteBlockHook("Bash", "command");
1694
+ const readAbsoluteBlockHook = makeAbsoluteBlockHook("Read", "file_path");
1695
+ const writeAbsoluteBlockHook = makeAbsoluteBlockHook("Write", "file_path");
1696
+ const editAbsoluteBlockHook = makeAbsoluteBlockHook("Edit", "file_path");
1697
+ // The context-write hook is always attached to Bash — it is the only
1698
+ // guarantee that the daemon-API chokepoint for memory files survives
1699
+ // allow mode (where curl/jq restrictions are dropped and Bash can
1700
+ // otherwise redirect into context/*.md freely).
1701
+ //
1702
+ // The absolute-block audit hook is appended LAST on every matcher
1703
+ // (§6.3). Appended rather than prepended so existing per-index hook
1704
+ // tests keep pointing at the same functions; semantically it is a
1705
+ // fallback defense whose practical effect is duplicating the SDK's
1706
+ // `disallowedTools` rejection into an `agent_actions` row.
1707
+ return {
1708
+ PreToolUse: [
1709
+ {
1710
+ matcher: "Bash",
1711
+ hooks: allowMode
1712
+ ? [bashContextWriteHook, bashAbsoluteBlockHook]
1713
+ : [
1714
+ bashCurlHook,
1715
+ bashJqHook,
1716
+ bashContextWriteHook,
1717
+ bashAbsoluteBlockHook,
1718
+ ],
1719
+ },
1720
+ { matcher: "Write", hooks: [fileWriteHook, writeAbsoluteBlockHook] },
1721
+ { matcher: "Edit", hooks: [fileWriteHook, editAbsoluteBlockHook] },
1722
+ { matcher: "Read", hooks: [readAbsoluteBlockHook] },
1723
+ ],
1724
+ };
1725
+ }
1726
+ /**
1727
+ * Delegated proxy invocation — Claude SDK path.
1728
+ *
1729
+ * Spawns a one-shot SDK `query()` constrained to a single `allowedTools`
1730
+ * entry (the requested connector tool), parses the structured stream
1731
+ * for the matching `tool_use` → `tool_result` pair, and returns the raw
1732
+ * tool result. The model's surrounding text is discarded — the route
1733
+ * handler only sees the connector's structured payload.
1734
+ *
1735
+ * Error classes (DelegatedToolErrorClass):
1736
+ * - `wrong_tool` — model called a tool we did not request (anti-prompt-injection).
1737
+ * - `no_tool_call` — model never invoked the tool within `maxTurns`.
1738
+ * - `tool_error` — connector returned `is_error: true`.
1739
+ * - `parse_error` — stream produced no terminal `result` event.
1740
+ * - `auth_error` — SDK reported `authentication_failed`.
1741
+ * - `timeout` — invoker's wall-clock signal aborted the stream.
1742
+ * - `subprocess_crashed` — exception thrown out of the iterator.
1743
+ *
1744
+ * Cost is captured from the terminal `SDKResultMessage` regardless of
1745
+ * subtype so the invoker can attribute partial spend on the failure
1746
+ * paths (no_tool_call, wrong_tool, tool_error).
1747
+ */
1748
+ async runDelegatedTool(params) {
1749
+ const startMs = Date.now();
1750
+ const { toolName, toolArgs, modelId, maxTurns, maxBudgetUsd, sessionDir } = params;
1751
+ const prompt = buildDelegatedToolPrompt(toolName, toolArgs);
1752
+ const daemonReadToken = this.readTokenManager?.issue(sessionDir) ?? this.readToken;
1753
+ let stream = null;
1754
+ const aborted = { value: false };
1755
+ // `abortReason` carries the reason that caused `aborted.value=true`
1756
+ // so the post-loop classifier can map idle-watchdog aborts to
1757
+ // `errorClass="timeout"`. Falls back to the caller's signal reason
1758
+ // when only the caller initiated the abort.
1759
+ let abortReason = null;
1760
+ const closeStream = () => {
1761
+ void (async () => {
1762
+ try {
1763
+ await stream?.return?.(undefined);
1764
+ }
1765
+ catch {
1766
+ /* stream already closed */
1767
+ }
1768
+ })();
1769
+ };
1770
+ const onAbort = () => {
1771
+ aborted.value = true;
1772
+ abortReason = params.abortSignal?.reason ?? null;
1773
+ closeStream();
1774
+ };
1775
+ if (params.abortSignal) {
1776
+ if (params.abortSignal.aborted) {
1777
+ aborted.value = true;
1778
+ abortReason = params.abortSignal.reason ?? null;
1779
+ }
1780
+ else {
1781
+ params.abortSignal.addEventListener("abort", onAbort, { once: true });
1782
+ }
1783
+ }
1784
+ // Idle watchdog. Claude SDK runs in-process; cold-start is
1785
+ // negligible (no MCP/CLI load) so the typical first message lands
1786
+ // within 1-3 s. A 30 s idle threshold catches a stuck SDK iterator
1787
+ // (network stall, server-side hang) without false-tripping a slow
1788
+ // tool. On trip we close the stream the same way `onAbort` does and
1789
+ // record the trip in `abortReason` so the classifier returns
1790
+ // `errorClass="timeout"` (uniform with CLI backends).
1791
+ const idleTimeoutMs = DELEGATED_PROXY_DEFAULTS.idleTimeoutMsByBackend.claude
1792
+ ?? DELEGATED_PROXY_DEFAULTS.idleTimeoutMs;
1793
+ const idleWatchdog = new IdleWatchdog({
1794
+ idleTimeoutMs,
1795
+ onTimeout: (idleMs) => {
1796
+ if (aborted.value)
1797
+ return;
1798
+ aborted.value = true;
1799
+ abortReason = new DelegatedProxyTimeoutError(`claude SDK stream idle for ${idleMs}ms (limit ${idleTimeoutMs}ms)`);
1800
+ logger.warn({ idleMs, idleTimeoutMs, toolName }, "claude delegated proxy idle watchdog tripped");
1801
+ closeStream();
1802
+ },
1803
+ });
1804
+ try {
1805
+ stream = query({
1806
+ prompt,
1807
+ options: {
1808
+ model: modelId,
1809
+ maxTurns,
1810
+ maxBudgetUsd,
1811
+ cwd: sessionDir,
1812
+ env: buildDaemonApiCliEnv(sessionDir, this.config.apiPort, { readToken: daemonReadToken, sessionBackend: "claude" }),
1813
+ systemPrompt: { type: "preset", preset: "claude_code" },
1814
+ permissionMode: "dontAsk",
1815
+ // The connector tool must be pre-authorized — Claude SDK with
1816
+ // permissionMode="dontAsk" silently denies anything not in
1817
+ // allowedTools.
1818
+ //
1819
+ // ToolSearch is Claude Code's deferred-tool discovery mechanism:
1820
+ // when many MCP servers are registered in the user's global
1821
+ // config (~/.claude.json: Notion, Gmail, GCal, Drive, Figma,
1822
+ // Canva, Hugging Face, …) the CLI ships only a working set of
1823
+ // tool schemas and defers the rest. To call a deferred tool, the
1824
+ // model must first call ToolSearch to load its schema. Without
1825
+ // ToolSearch allowed, the proxy's first turn was wasted on a
1826
+ // denied ToolSearch call (audit log 2026-04-29: 1 Notion failure
1827
+ // logged as `wrong_tool=ToolSearch`, 5 logged as
1828
+ // `subprocess_crashed: Reached maximum number of turns (2)` —
1829
+ // the model retried other approaches and exhausted the budget).
1830
+ //
1831
+ // Allowing ToolSearch is safe: allowedTools enforcement still
1832
+ // gates which tools can be CALLED, and ToolSearch only loads
1833
+ // schemas into context. The proxy parser below also skips
1834
+ // ToolSearch when capturing `wrongToolName` so a ToolSearch+
1835
+ // partial-result trace classifies as `no_tool_call` rather than
1836
+ // misleading `wrong_tool=ToolSearch`.
1837
+ //
1838
+ // TODO(future): a cleaner architectural fix is to materialize a
1839
+ // session-local `.mcp.json` containing only the relevant
1840
+ // connector's MCP server and pass `strictMcpConfig: true` —
1841
+ // that prevents deferral entirely (one MCP server → schemas fit
1842
+ // in the working set). Punted because it requires extracting
1843
+ // server configs from the user's global file per integration.
1844
+ allowedTools: [toolName, DEFERRED_TOOL_DISCOVERY_TOOL_NAME],
1845
+ // Defense-in-depth: even with allowedTools restricted to a tight
1846
+ // set, keep the absolute-block layer (rm -rf, sudo, secret file
1847
+ // reads) merged so a future relaxation of allowedTools can't
1848
+ // accidentally drop these guarantees.
1849
+ disallowedTools: [...ALWAYS_DISALLOWED_TOOLS],
1850
+ // Adaptive thinking is the SDK default for thinking-capable
1851
+ // models (Haiku 4.5+ / Sonnet 4.6+). Per Anthropic's docs
1852
+ // thinking happens within a single API call so it does not
1853
+ // typically burn an extra turn — but for a proxy that issues
1854
+ // one named tool call with explicit args, thinking adds latency
1855
+ // and tokens for no benefit. The proxy.md profile says "no
1856
+ // narration"; disabling thinking aligns runtime behavior with
1857
+ // that intent.
1858
+ thinking: { type: "disabled" },
1859
+ },
1860
+ });
1861
+ let capturedToolUseId = null;
1862
+ let capturedToolResult = undefined;
1863
+ let capturedToolErrorMessage = null;
1864
+ let wrongToolName = null;
1865
+ let cost = emptyCost();
1866
+ let terminalSubtype = null;
1867
+ let terminalIsError = false;
1868
+ let terminalErrors = [];
1869
+ try {
1870
+ idleWatchdog.start();
1871
+ for await (const message of stream) {
1872
+ idleWatchdog.beat();
1873
+ if (aborted.value) {
1874
+ break;
1875
+ }
1876
+ if (message.type === "assistant") {
1877
+ const assistantMsg = message;
1878
+ const blocks = assistantMsg.message?.content;
1879
+ if (!Array.isArray(blocks))
1880
+ continue;
1881
+ for (const block of blocks) {
1882
+ if (!block || typeof block !== "object")
1883
+ continue;
1884
+ const blockType = block.type;
1885
+ if (blockType !== "tool_use")
1886
+ continue;
1887
+ const blockName = block.name;
1888
+ const blockId = block.id;
1889
+ if (typeof blockName !== "string" || typeof blockId !== "string") {
1890
+ continue;
1891
+ }
1892
+ if (blockName === toolName) {
1893
+ if (capturedToolUseId === null) {
1894
+ capturedToolUseId = blockId;
1895
+ }
1896
+ }
1897
+ else if (blockName === DEFERRED_TOOL_DISCOVERY_TOOL_NAME) {
1898
+ // Expected intermediate step for loading the connector's
1899
+ // deferred MCP schema — not a violation. Do not capture as
1900
+ // wrongToolName so a partial trace (ToolSearch + max_turns
1901
+ // before the connector call) classifies as `no_tool_call`
1902
+ // instead of misleading `wrong_tool=ToolSearch`.
1903
+ }
1904
+ else if (wrongToolName === null) {
1905
+ wrongToolName = blockName;
1906
+ // Early abort: bound the wall-clock spend on a wrong_tool
1907
+ // failure to ~5s. Set `aborted` so the next loop iteration
1908
+ // breaks; close the SDK stream so any pending tool_use
1909
+ // doesn't continue. The post-loop classifier checks
1910
+ // `wrongToolName` BEFORE the abort branch, so the failure
1911
+ // is correctly attributed.
1912
+ aborted.value = true;
1913
+ closeStream();
1914
+ }
1915
+ }
1916
+ }
1917
+ else if (message.type === "user") {
1918
+ const userMsg = message;
1919
+ const content = userMsg.message?.content;
1920
+ if (!Array.isArray(content))
1921
+ continue;
1922
+ for (const block of content) {
1923
+ if (!block || typeof block !== "object")
1924
+ continue;
1925
+ if (block.type !== "tool_result")
1926
+ continue;
1927
+ const tuid = block.tool_use_id;
1928
+ if (tuid !== capturedToolUseId)
1929
+ continue;
1930
+ const isToolError = block.is_error === true;
1931
+ const rawContent = block.content;
1932
+ const flat = flattenToolResultContent(rawContent);
1933
+ if (isToolError) {
1934
+ capturedToolErrorMessage =
1935
+ flat.trim().length > 0 ? flat : "tool returned is_error";
1936
+ }
1937
+ else if (capturedToolResult === undefined) {
1938
+ capturedToolResult = tryParseToolResult(flat);
1939
+ }
1940
+ }
1941
+ }
1942
+ else if (message.type === "result") {
1943
+ const r = message;
1944
+ terminalSubtype = r.subtype;
1945
+ terminalIsError = r.is_error;
1946
+ cost = {
1947
+ tokensInput: r.usage.input_tokens ?? 0,
1948
+ tokensOutput: r.usage.output_tokens ?? 0,
1949
+ cacheCreationTokens: r.usage.cache_creation_input_tokens ?? 0,
1950
+ cacheReadTokens: r.usage.cache_read_input_tokens ?? 0,
1951
+ costUsd: r.total_cost_usd ?? 0,
1952
+ durationMs: r.duration_ms ?? Date.now() - startMs,
1953
+ numTurns: r.num_turns ?? 0,
1954
+ };
1955
+ if (r.subtype !== "success" && "errors" in r && Array.isArray(r.errors)) {
1956
+ terminalErrors = r.errors;
1957
+ }
1958
+ // The result message is terminal per SDK semantics. Break out
1959
+ // before the next iterator step. When `r.is_error` is true, the
1960
+ // SDK's transport sets `lastErrorResultText` and throws on the
1961
+ // next `readMessages` iteration — wrapping it as
1962
+ // `Error("Claude Code returned an error result: <text>")`. That
1963
+ // throw would land in the outer catch and misclassify as
1964
+ // `subprocess_crashed`, discarding the captured cost. Audit log
1965
+ // (2026-04-29) showed 5 such failures with num_turns=0,
1966
+ // tokens=0, masking that this was actually `error_max_turns`.
1967
+ // Breaking here lets the post-loop classifier run with the
1968
+ // captured terminalSubtype, terminalErrors, wrongToolName, and
1969
+ // cost intact.
1970
+ break;
1971
+ }
1972
+ }
1973
+ }
1974
+ finally {
1975
+ idleWatchdog.stop();
1976
+ try {
1977
+ await stream?.return?.(undefined);
1978
+ }
1979
+ catch {
1980
+ /* stream already closed */
1981
+ }
1982
+ }
1983
+ cost = withDurationMs(cost, startMs);
1984
+ // wrong_tool check hoisted above the abort branch because the
1985
+ // early-abort path sets `aborted.value` AND `wrongToolName`.
1986
+ // Without this ordering the failure would surface as `cancelled`
1987
+ // instead of the actual upstream cause. The `abortReason` field
1988
+ // distinguishes idle-watchdog aborts (errorClass="timeout") from
1989
+ // caller-initiated cancels (errorClass="cancelled" unless the
1990
+ // caller's reason was itself a `DelegatedProxyTimeoutError`).
1991
+ if (wrongToolName !== null) {
1992
+ return {
1993
+ ok: false,
1994
+ errorClass: "wrong_tool",
1995
+ message: `model called '${wrongToolName}' instead of requested '${toolName}'`,
1996
+ cost,
1997
+ };
1998
+ }
1999
+ if (aborted.value) {
2000
+ const reason = abortReason ?? params.abortSignal?.reason;
2001
+ const errorClass = classifyAbortReason(reason);
2002
+ const idleAbort = reason instanceof DelegatedProxyTimeoutError
2003
+ && /idle/.test(reason.message);
2004
+ return {
2005
+ ok: false,
2006
+ errorClass,
2007
+ message: errorClass === "timeout"
2008
+ ? (idleAbort
2009
+ ? `delegated proxy stream went idle (no claude SDK events for ${idleTimeoutMs}ms)`
2010
+ : "delegated proxy timed out (wall-clock)")
2011
+ : "delegated proxy cancelled by caller",
2012
+ cost,
2013
+ };
2014
+ }
2015
+ if (capturedToolResult !== undefined) {
2016
+ return { ok: true, toolResult: capturedToolResult, cost };
2017
+ }
2018
+ if (capturedToolErrorMessage !== null) {
2019
+ return {
2020
+ ok: false,
2021
+ errorClass: "tool_error",
2022
+ message: capturedToolErrorMessage,
2023
+ cost,
2024
+ };
2025
+ }
2026
+ // Map specific terminal subtypes before falling through to
2027
+ // no_tool_call. The model can fail for auth or budget reasons
2028
+ // before ever emitting a tool_use block.
2029
+ if (terminalSubtype === "error_during_execution" && terminalErrors.length > 0) {
2030
+ const joined = terminalErrors.join("; ");
2031
+ if (/auth|unauthorized|authentication_failed|invalid api key/i.test(joined)) {
2032
+ return {
2033
+ ok: false,
2034
+ errorClass: "auth_error",
2035
+ message: joined,
2036
+ cost,
2037
+ };
2038
+ }
2039
+ return {
2040
+ ok: false,
2041
+ errorClass: "tool_error",
2042
+ message: joined,
2043
+ cost,
2044
+ };
2045
+ }
2046
+ if (terminalSubtype === null && !terminalIsError) {
2047
+ // Stream ended before any terminal `result` arrived — abnormal
2048
+ // termination not classified as an abort. Treat as parse_error
2049
+ // so the route handler can surface the bug rather than retrying.
2050
+ return {
2051
+ ok: false,
2052
+ errorClass: "parse_error",
2053
+ message: "Claude SDK stream ended without a terminal result message",
2054
+ cost,
2055
+ };
2056
+ }
2057
+ return {
2058
+ ok: false,
2059
+ errorClass: "no_tool_call",
2060
+ message: `model did not invoke '${toolName}' within ${maxTurns} turns (subtype=${terminalSubtype ?? "unknown"})`,
2061
+ cost,
2062
+ };
2063
+ }
2064
+ catch (err) {
2065
+ const message = err instanceof Error ? err.message : String(err);
2066
+ const cost = withDurationMs(emptyCost(), startMs);
2067
+ // Map auth-shape exceptions before the catch-all subprocess_crashed.
2068
+ if (/authentication_failed|unauthorized|invalid api key|sk-ant-/i.test(message)) {
2069
+ return { ok: false, errorClass: "auth_error", message, cost };
2070
+ }
2071
+ if (aborted.value) {
2072
+ return {
2073
+ ok: false,
2074
+ errorClass: classifyAbortReason(abortReason ?? params.abortSignal?.reason),
2075
+ message,
2076
+ cost,
2077
+ };
2078
+ }
2079
+ return { ok: false, errorClass: "subprocess_crashed", message, cost };
2080
+ }
2081
+ finally {
2082
+ params.abortSignal?.removeEventListener("abort", onAbort);
2083
+ this.readTokenManager?.revoke(sessionDir);
2084
+ }
2085
+ }
2086
+ /**
2087
+ * DELEGATED-TASK-MODE-DESIGN.md §9.1 — Claude SDK task mode. The
2088
+ * subprocess plans + executes 1..N MCP calls within `allowedTools` and
2089
+ * emits a final assistant message that the runtime helper validates
2090
+ * against the caller's `outputSchema`.
2091
+ *
2092
+ * Stream parsing differences from `runDelegatedTool`:
2093
+ * - We accept multiple `tool_use` blocks (counted against `maxToolCalls`).
2094
+ * - We track per-tool durations to feed `onToolStep`.
2095
+ * - We capture the *final* assistant text (after the last tool turn)
2096
+ * as the validation target, not a single tool's `tool_result`.
2097
+ *
2098
+ * Safety:
2099
+ * - `allowedTools` already excludes the destructive set when
2100
+ * `allowDestructive: false`; the SDK will not surface those tools.
2101
+ * - `disallowedTools` is the absolute-block layer + the destructive
2102
+ * set as defense-in-depth (so a future relaxation of allowedTools
2103
+ * can't accidentally widen the surface).
2104
+ *
2105
+ * The §6.2 "no retry after write" rule is enforced at the invoker
2106
+ * layer; this method just signals via `writeClassToolFired` whether
2107
+ * any destructive tool ran during the task.
2108
+ */
2109
+ async runDelegatedTask(params) {
2110
+ const startMs = Date.now();
2111
+ const { systemPrompt, allowedTools, destructiveTools, writeClassTools, modelId, maxToolCalls, maxBudgetUsd, sessionDir, onToolStep, } = params;
2112
+ const daemonReadToken = this.readTokenManager?.issue(sessionDir) ?? this.readToken;
2113
+ const trace = [];
2114
+ // §6.2 / §7.4 — match against the *write-class* set (destructive ∪
2115
+ // reversible writes), not just destructive. Otherwise reversible
2116
+ // write tools like `create_draft` slip past the retry guard and the
2117
+ // single retry creates a duplicate side effect.
2118
+ //
2119
+ // Phase 1 (`/exec`) entries are fully-qualified exact names — the
2120
+ // exact-equality fast path inside `matchRunAllowedToolPattern` covers
2121
+ // them at one comparison. Phase 2 (`/api/delegated/run`) may pass
2122
+ // `*`-suffixed glob patterns derived from the caller's allowedTools
2123
+ // (DELEGATED-TASK-MODE-DESIGN.md §4.2); the shared helper handles both.
2124
+ const writeClassMatcher = (name) => writeClassTools.some((pattern) => matchRunAllowedToolPattern(pattern, name));
2125
+ let writeClassToolFired = false;
2126
+ // DELEGATED-TASK-MODE-DESIGN.md §13 Phase 3.1 — Claude SDK
2127
+ // structured-output. When the invoker passed `structuredOutputEnabled:
2128
+ // true` AND a `wrappedSchema`, configure `outputFormat` so the SDK
2129
+ // validates the model's final emission against the schema (with its
2130
+ // own internal retries) and surfaces it on `SDKResultSuccess.structured_output`.
2131
+ // We still capture the assistant text as a fallback — if the SDK
2132
+ // returns success without `structured_output` (older subtype, future
2133
+ // shape change, kill-switch flips off mid-call), the existing text
2134
+ // path takes over.
2135
+ const useStructuredOutput = params.structuredOutputEnabled === true
2136
+ && !!params.wrappedSchema;
2137
+ let capturedStructured;
2138
+ let sawStructuredOutputRetryError = false;
2139
+ let stream = null;
2140
+ const aborted = { value: false };
2141
+ const onAbort = () => {
2142
+ aborted.value = true;
2143
+ void (async () => {
2144
+ try {
2145
+ await stream?.return?.(undefined);
2146
+ }
2147
+ catch {
2148
+ /* stream already closed */
2149
+ }
2150
+ })();
2151
+ };
2152
+ if (params.abortSignal) {
2153
+ if (params.abortSignal.aborted) {
2154
+ aborted.value = true;
2155
+ }
2156
+ else {
2157
+ params.abortSignal.addEventListener("abort", onAbort, { once: true });
2158
+ }
2159
+ }
2160
+ const pendingByUseId = new Map();
2161
+ let toolCallCount = 0;
2162
+ let loopAborted = false;
2163
+ let assistantTextChunks = [];
2164
+ /** The "final" assistant message is the most recent assistant message
2165
+ * that contained NO `tool_use` block. The SDK emits one assistant
2166
+ * message per turn; the planning turns mix text + tool_use, the
2167
+ * closing turn is text-only. */
2168
+ let lastAssistantTextOnlyChunks = [];
2169
+ try {
2170
+ stream = query({
2171
+ prompt: systemPrompt,
2172
+ options: {
2173
+ model: modelId,
2174
+ maxTurns: Math.max(2, maxToolCalls + 1),
2175
+ maxBudgetUsd,
2176
+ cwd: sessionDir,
2177
+ env: buildDaemonApiCliEnv(sessionDir, this.config.apiPort, { readToken: daemonReadToken, sessionBackend: "claude" }),
2178
+ systemPrompt: { type: "preset", preset: "claude_code" },
2179
+ permissionMode: "dontAsk",
2180
+ allowedTools: [...allowedTools],
2181
+ // Defense-in-depth: absolute-block layer + destructive denies.
2182
+ // Destructive entries are redundant with the allowedTools
2183
+ // subtraction (when allowDestructive=false) but kept so a
2184
+ // future allowedTools widening doesn't drop the guarantee.
2185
+ disallowedTools: [
2186
+ ...ALWAYS_DISALLOWED_TOOLS,
2187
+ ...(params.allowDestructive ? [] : destructiveTools),
2188
+ ],
2189
+ // §13 Phase 3.1 — bind the wrapped schema (user schema OR
2190
+ // confirmation envelope OR error envelope) to SDK 0.2.98's
2191
+ // `outputFormat`. Result message carries `structured_output`
2192
+ // which we read below. Off when the kill switch is false or
2193
+ // the invoker omitted the wrapped schema.
2194
+ ...(useStructuredOutput && params.wrappedSchema
2195
+ ? {
2196
+ outputFormat: {
2197
+ type: "json_schema",
2198
+ schema: params.wrappedSchema,
2199
+ },
2200
+ }
2201
+ : {}),
2202
+ },
2203
+ });
2204
+ let cost = emptyCost();
2205
+ try {
2206
+ for await (const message of stream) {
2207
+ if (aborted.value || loopAborted)
2208
+ break;
2209
+ if (message.type === "assistant") {
2210
+ const assistantMsg = message;
2211
+ const blocks = assistantMsg.message?.content;
2212
+ if (!Array.isArray(blocks))
2213
+ continue;
2214
+ const textChunks = [];
2215
+ let sawToolUse = false;
2216
+ for (const block of blocks) {
2217
+ if (!block || typeof block !== "object")
2218
+ continue;
2219
+ const blockType = block.type;
2220
+ if (blockType === "text") {
2221
+ const text = block.text;
2222
+ if (typeof text === "string")
2223
+ textChunks.push(text);
2224
+ continue;
2225
+ }
2226
+ if (blockType !== "tool_use")
2227
+ continue;
2228
+ sawToolUse = true;
2229
+ const blockName = block.name;
2230
+ const blockId = block.id;
2231
+ const blockArgs = block.input;
2232
+ if (typeof blockName !== "string" || typeof blockId !== "string") {
2233
+ continue;
2234
+ }
2235
+ toolCallCount += 1;
2236
+ if (toolCallCount > maxToolCalls) {
2237
+ // §7.5 — once the cap is exceeded, abort. The next
2238
+ // tool_use is treated as overrun.
2239
+ loopAborted = true;
2240
+ aborted.value = true;
2241
+ try {
2242
+ await stream?.return?.(undefined);
2243
+ }
2244
+ catch {
2245
+ /* already closed */
2246
+ }
2247
+ break;
2248
+ }
2249
+ if (writeClassMatcher(blockName)) {
2250
+ writeClassToolFired = true;
2251
+ }
2252
+ pendingByUseId.set(blockId, {
2253
+ name: blockName,
2254
+ args: blockArgs,
2255
+ startedAt: Date.now(),
2256
+ });
2257
+ }
2258
+ assistantTextChunks = assistantTextChunks.concat(textChunks);
2259
+ if (!sawToolUse && textChunks.length > 0) {
2260
+ lastAssistantTextOnlyChunks = textChunks;
2261
+ }
2262
+ }
2263
+ else if (message.type === "user") {
2264
+ const userMsg = message;
2265
+ const content = userMsg.message?.content;
2266
+ if (!Array.isArray(content))
2267
+ continue;
2268
+ for (const block of content) {
2269
+ if (!block || typeof block !== "object")
2270
+ continue;
2271
+ if (block.type !== "tool_result")
2272
+ continue;
2273
+ const tuid = block.tool_use_id;
2274
+ if (typeof tuid !== "string")
2275
+ continue;
2276
+ const pending = pendingByUseId.get(tuid);
2277
+ if (!pending)
2278
+ continue;
2279
+ pendingByUseId.delete(tuid);
2280
+ const isToolError = block.is_error === true;
2281
+ // `tool_result` content is either a string or an array of
2282
+ // content blocks (typically a single `{type:"text", text}`).
2283
+ // The MCP SDK wraps connector JSON responses by serializing
2284
+ // to that text body, so the response-shape walker
2285
+ // downstream wants the parsed object. Pull the first text
2286
+ // block, JSON-parse when possible, fallback to the raw
2287
+ // string so the field is always populated for ok steps.
2288
+ let parsedToolResult;
2289
+ const blockContent = block.content;
2290
+ if (typeof blockContent === "string") {
2291
+ try {
2292
+ parsedToolResult = JSON.parse(blockContent);
2293
+ }
2294
+ catch {
2295
+ parsedToolResult = blockContent;
2296
+ }
2297
+ }
2298
+ else if (Array.isArray(blockContent)) {
2299
+ const firstText = blockContent.find((b) => !!b
2300
+ && typeof b === "object"
2301
+ && b.type === "text"
2302
+ && typeof b.text === "string");
2303
+ if (firstText) {
2304
+ try {
2305
+ parsedToolResult = JSON.parse(firstText.text);
2306
+ }
2307
+ catch {
2308
+ parsedToolResult = firstText.text;
2309
+ }
2310
+ }
2311
+ else {
2312
+ parsedToolResult = blockContent;
2313
+ }
2314
+ }
2315
+ const step = {
2316
+ toolName: pending.name,
2317
+ toolArgs: pending.args,
2318
+ durationMs: Date.now() - pending.startedAt,
2319
+ status: isToolError ? "error" : "ok",
2320
+ costUsd: null,
2321
+ tokensInput: null,
2322
+ tokensOutput: null,
2323
+ toolResult: parsedToolResult,
2324
+ };
2325
+ trace.push(step);
2326
+ onToolStep?.(step);
2327
+ }
2328
+ }
2329
+ else if (message.type === "result") {
2330
+ const r = message;
2331
+ cost = {
2332
+ tokensInput: r.usage.input_tokens ?? 0,
2333
+ tokensOutput: r.usage.output_tokens ?? 0,
2334
+ cacheCreationTokens: r.usage.cache_creation_input_tokens ?? 0,
2335
+ cacheReadTokens: r.usage.cache_read_input_tokens ?? 0,
2336
+ costUsd: r.total_cost_usd ?? 0,
2337
+ durationMs: r.duration_ms ?? Date.now() - startMs,
2338
+ numTurns: r.num_turns ?? 0,
2339
+ };
2340
+ // §13 Phase 3.1 — capture structured output when present, and
2341
+ // map the SDK's structured-output-retry-exhausted subtype to
2342
+ // a parse_error so the invoker classifies it consistently
2343
+ // with the text-extract path.
2344
+ if (r.subtype === "success") {
2345
+ const success = r;
2346
+ if (success.structured_output !== undefined) {
2347
+ capturedStructured = success.structured_output;
2348
+ }
2349
+ }
2350
+ else if (r.subtype === "error_max_structured_output_retries") {
2351
+ sawStructuredOutputRetryError = true;
2352
+ }
2353
+ }
2354
+ }
2355
+ }
2356
+ finally {
2357
+ try {
2358
+ await stream?.return?.(undefined);
2359
+ }
2360
+ catch {
2361
+ /* already closed */
2362
+ }
2363
+ }
2364
+ cost = withDurationMs(cost, startMs);
2365
+ if (loopAborted) {
2366
+ return {
2367
+ ok: false,
2368
+ errorClass: "loop_aborted",
2369
+ message: `subprocess exceeded maxToolCalls=${maxToolCalls}`,
2370
+ cost,
2371
+ trace,
2372
+ writeClassToolFired,
2373
+ };
2374
+ }
2375
+ if (aborted.value) {
2376
+ const errorClass = classifyAbortReason(params.abortSignal?.reason);
2377
+ return {
2378
+ ok: false,
2379
+ errorClass,
2380
+ message: errorClass === "timeout"
2381
+ ? "delegated task timed out (wall-clock)"
2382
+ : "delegated task cancelled by caller",
2383
+ cost,
2384
+ trace,
2385
+ writeClassToolFired,
2386
+ };
2387
+ }
2388
+ const finalText = lastAssistantTextOnlyChunks.length > 0
2389
+ ? lastAssistantTextOnlyChunks.join("\n").trim()
2390
+ : assistantTextChunks.join("\n").trim();
2391
+ // §13 Phase 3.1 — `error_max_structured_output_retries` typically
2392
+ // fires when the model wanted to emit a §7.2 confirmation envelope
2393
+ // or §5.1 error envelope, neither of which satisfies the user's
2394
+ // narrow schema. The assistant text emissions captured during those
2395
+ // retries land in `assistantTextChunks` / `lastAssistantTextOnlyChunks`,
2396
+ // so the invoker's text-extract chain can route them via
2397
+ // `detectConfirmationEnvelope` / `detectErrorEnvelope`. Only return
2398
+ // `parse_error` if there is also no usable text — otherwise fall
2399
+ // through to the text-emission path (no `structuredOutput` field
2400
+ // set, so the invoker uses `rawAssistantText`).
2401
+ if (sawStructuredOutputRetryError
2402
+ && capturedStructured === undefined
2403
+ && finalText.length === 0) {
2404
+ return {
2405
+ ok: false,
2406
+ errorClass: "parse_error",
2407
+ message: "Claude SDK exhausted structured-output retries and emitted no text fallback.",
2408
+ cost,
2409
+ trace,
2410
+ writeClassToolFired,
2411
+ };
2412
+ }
2413
+ // §13 Phase 3.1 — when the SDK supplied `structured_output`, that
2414
+ // is the validated final emission; the assistant text may be empty
2415
+ // (the SDK consumes the JSON internally on success). Skip the
2416
+ // empty-text parse_error guard in that case.
2417
+ if (capturedStructured === undefined && finalText.length === 0) {
2418
+ return {
2419
+ ok: false,
2420
+ errorClass: "parse_error",
2421
+ message: "Claude SDK stream ended without a text-only assistant turn",
2422
+ cost,
2423
+ trace,
2424
+ writeClassToolFired,
2425
+ };
2426
+ }
2427
+ return {
2428
+ ok: true,
2429
+ // When structured output is present, `rawAssistantText` is purely
2430
+ // a fallback; the invoker prefers `structuredOutput`. Carry both
2431
+ // so a future kill-switch flip mid-restart still sees an
2432
+ // extractable text emission.
2433
+ rawAssistantText: finalText,
2434
+ cost,
2435
+ trace,
2436
+ writeClassToolFired,
2437
+ ...(capturedStructured !== undefined
2438
+ ? { structuredOutput: capturedStructured }
2439
+ : {}),
2440
+ };
2441
+ }
2442
+ catch (err) {
2443
+ const message = err instanceof Error ? err.message : String(err);
2444
+ const cost = withDurationMs(emptyCost(), startMs);
2445
+ if (/authentication_failed|unauthorized|invalid api key|sk-ant-/i.test(message)) {
2446
+ return {
2447
+ ok: false,
2448
+ errorClass: "auth_error",
2449
+ message,
2450
+ cost,
2451
+ trace,
2452
+ writeClassToolFired,
2453
+ };
2454
+ }
2455
+ if (aborted.value) {
2456
+ return {
2457
+ ok: false,
2458
+ errorClass: classifyAbortReason(params.abortSignal?.reason),
2459
+ message,
2460
+ cost,
2461
+ trace,
2462
+ writeClassToolFired,
2463
+ };
2464
+ }
2465
+ return {
2466
+ ok: false,
2467
+ errorClass: "subprocess_crashed",
2468
+ message,
2469
+ cost,
2470
+ trace,
2471
+ writeClassToolFired,
2472
+ };
2473
+ }
2474
+ finally {
2475
+ params.abortSignal?.removeEventListener("abort", onAbort);
2476
+ this.readTokenManager?.revoke(sessionDir);
2477
+ }
2478
+ }
2479
+ }
2480
+ function extractClaudeProbeTools(message) {
2481
+ if (!message || typeof message !== "object")
2482
+ return [];
2483
+ const out = [];
2484
+ const record = message;
2485
+ if (record.type === "system" && record.subtype === "init" && Array.isArray(record.tools)) {
2486
+ addClaudeProbeTools(record.tools, out);
2487
+ }
2488
+ if (record.type === "assistant" || record.type === "user") {
2489
+ addClaudeProbeTools(record.message, out);
2490
+ }
2491
+ if (record.type === "result") {
2492
+ addClaudeProbeTools(record.result, out);
2493
+ }
2494
+ return out;
2495
+ }
2496
+ function addClaudeProbeTools(value, out, depth = 0) {
2497
+ if (depth > 8 || value === null || value === undefined)
2498
+ return;
2499
+ if (typeof value === "string") {
2500
+ for (const match of value.matchAll(CLAUDE_CONNECTOR_TOOL_RE)) {
2501
+ out.push(match[0]);
2502
+ }
2503
+ if (isClaudeProbeToolName(value))
2504
+ out.push(value);
2505
+ return;
2506
+ }
2507
+ if (Array.isArray(value)) {
2508
+ for (const item of value)
2509
+ addClaudeProbeTools(item, out, depth + 1);
2510
+ return;
2511
+ }
2512
+ if (typeof value !== "object")
2513
+ return;
2514
+ const record = value;
2515
+ addClaudeProbeTools(record.tool_name, out, depth + 1);
2516
+ addClaudeProbeTools(record.text, out, depth + 1);
2517
+ addClaudeProbeTools(record.content, out, depth + 1);
2518
+ addClaudeProbeTools(record.message, out, depth + 1);
2519
+ addClaudeProbeTools(record.result, out, depth + 1);
2520
+ addClaudeProbeTools(record.tools, out, depth + 1);
2521
+ }
2522
+ function isClaudeProbeToolName(value) {
2523
+ return CLAUDE_PROBE_TOOL_PREFIXES.some((prefix) => {
2524
+ if (!value.startsWith(prefix))
2525
+ return false;
2526
+ // Hyphen is part of the alphabet for kebab-case connectors (Notion's
2527
+ // `notion-search` etc.). Snake-case connectors keep working because
2528
+ // `_` is still in the class.
2529
+ return /^[A-Za-z0-9_-]+$/.test(value.slice(prefix.length));
2530
+ });
2531
+ }
2532
+ function describeClaudeProbeResultError(result) {
2533
+ if ("result" in result && typeof result.result === "string" && result.result.trim()) {
2534
+ return result.result.trim();
2535
+ }
2536
+ if ("errors" in result && Array.isArray(result.errors) && result.errors.length > 0) {
2537
+ return result.errors.join("; ");
2538
+ }
2539
+ return result.subtype;
2540
+ }
2541
+ //# sourceMappingURL=claude-code-core.js.map