@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,1765 @@
1
+ import { Hono } from "hono";
2
+ import { readFileSync, existsSync, statSync, readdirSync, unlinkSync, realpathSync, lstatSync, readlinkSync, } from "node:fs";
3
+ import { basename, join, dirname, resolve, relative, isAbsolute } from "node:path";
4
+ import { writeFileAtomically } from "../../core/atomic-write.js";
5
+ import { contextPutSchema, contextPatchSchema, getAgentDayDateStr, localDateStr, nowInTimezone, } from "@aitne/shared";
6
+ import { getContextDir } from "../../config.js";
7
+ import { getDegradedMode } from "../../db/runtime-state.js";
8
+ import { InMemoryTodayWriteLockManager, getTodayWriteLockTimeoutMs, } from "../../core/today-write-lock.js";
9
+ import { InMemoryRoadmapWriteLockManager, getRoadmapWriteLockTimeoutMs, } from "../../core/roadmap-write-lock.js";
10
+ import { CONTEXT_BASE_FILE_STEMS, CONTEXT_FILE_EXTENSIONS, } from "../../core/context-paths.js";
11
+ import { REPAIRABLE_STUB_TARGETS, buildContextHealthReport, normalizeRepairStubPath, } from "../../core/context-health.js";
12
+ import { validateContextFileFrontmatter } from "../../core/context-frontmatter.js";
13
+ import { classifyContextWriteStaleness } from "../../core/context-staleness.js";
14
+ import { resolveTemplatesRoot } from "../../core/skeleton.js";
15
+ import { parseCustomRoutineSpec, } from "../../core/custom-routine-scheduler.js";
16
+ import { normalizeRoadmapForWrite, validateRoadmap, validateRoadmapTransition, } from "../../core/roadmap-validate.js";
17
+ import { isValidYmd, } from "../../core/roadmap-horizon.js";
18
+ import { extractRoadmapIds, generateRoadmapId, RoadmapIdGenerationError, } from "../../core/roadmap-ids.js";
19
+ import { buildTodayAgentPlanMetadata, extractTodayAgentPlanRows, extractTodayDate, readTodayAgentPlanMetadata, } from "../../core/today-agent-plan.js";
20
+ import { createLogger } from "../../logging.js";
21
+ import { readJsonBody } from "../json-body.js";
22
+ const logger = createLogger("context-api");
23
+ const CONTEXT_BASE_FILE_STEM_SET = new Set(CONTEXT_BASE_FILE_STEMS);
24
+ function resolveContextTarget(userPath) {
25
+ for (const ext of CONTEXT_FILE_EXTENSIONS) {
26
+ if (userPath.endsWith(ext)) {
27
+ return { base: userPath.slice(0, -ext.length), ext };
28
+ }
29
+ }
30
+ if (CONTEXT_BASE_FILE_STEM_SET.has(userPath)) {
31
+ return { base: userPath, ext: ".base" };
32
+ }
33
+ return { base: userPath, ext: ".md" };
34
+ }
35
+ function normalizeContextPath(userPath) {
36
+ return resolveContextTarget(userPath).base;
37
+ }
38
+ /**
39
+ * Subpath prefixes inside contextDir that the API never exposes.
40
+ * Relative paths from `path.relative` never contain a trailing slash for
41
+ * the leaf element, so we match on "<name>" exactly OR "<name>/" prefix.
42
+ *
43
+ * - `.git` — local repo artifacts the daemon must not touch
44
+ * - `.DS_Store` — macOS filesystem cruft
45
+ * - `.obsidian` — Obsidian's own state directory
46
+ *
47
+ * `.obsidian` stays denied in every mode. `vaultMode="obsidian"` means the
48
+ * directory may exist on disk and should be preserved by the daemon, not that
49
+ * the agent may read or edit Obsidian's workspace state through this API.
50
+ */
51
+ const DENIED_SUBPATH_ROOTS = [".git", ".DS_Store", ".obsidian"];
52
+ function isDeniedPath(relativePath) {
53
+ for (const root of DENIED_SUBPATH_ROOTS) {
54
+ if (relativePath === root || relativePath.startsWith(`${root}/`)) {
55
+ return true;
56
+ }
57
+ }
58
+ return false;
59
+ }
60
+ function escapesBase(base, candidate) {
61
+ const rel = relative(base, candidate);
62
+ return rel.startsWith("..") || isAbsolute(rel);
63
+ }
64
+ function resolveRealPathBestEffort(path, seen = new Set()) {
65
+ const abs = resolve(path);
66
+ try {
67
+ const stat = lstatSync(abs);
68
+ if (stat.isSymbolicLink()) {
69
+ if (seen.has(abs))
70
+ return null;
71
+ seen.add(abs);
72
+ const target = readlinkSync(abs);
73
+ return resolveRealPathBestEffort(isAbsolute(target) ? target : resolve(dirname(abs), target), seen);
74
+ }
75
+ return realpathSync(abs);
76
+ }
77
+ catch {
78
+ const parent = dirname(abs);
79
+ if (parent === abs)
80
+ return abs;
81
+ const parentReal = resolveRealPathBestEffort(parent, seen);
82
+ return parentReal ? resolve(parentReal, basename(abs)) : null;
83
+ }
84
+ }
85
+ /**
86
+ * Resolve a user-supplied path safely within contextDir.
87
+ * Accepts paths with or without the trailing `.md` / `.base` extension.
88
+ * Returns null if the resolved path escapes contextDir (path traversal),
89
+ * targets a reserved `.base` stem with the wrong extension, or is on the
90
+ * deny list.
91
+ */
92
+ function safePath(contextDir, userPath) {
93
+ const { base, ext } = resolveContextTarget(userPath);
94
+ if (base === "projects/_active" && ext !== ".base") {
95
+ logger.warn({ userPath, base, ext }, "Base file requested with wrong extension");
96
+ return null;
97
+ }
98
+ const resolved = resolve(contextDir, `${base}${ext}`);
99
+ const rel = relative(contextDir, resolved);
100
+ // Reject if path escapes contextDir (starts with .. or is absolute)
101
+ if (escapesBase(contextDir, resolved)) {
102
+ logger.warn({ userPath, resolved }, "Path traversal rejected");
103
+ return null;
104
+ }
105
+ if (isDeniedPath(rel)) {
106
+ logger.warn({ userPath, resolved }, "Denied subpath rejected");
107
+ return null;
108
+ }
109
+ const contextReal = resolveRealPathBestEffort(contextDir);
110
+ const resolvedReal = resolveRealPathBestEffort(resolved);
111
+ if (!contextReal || !resolvedReal) {
112
+ logger.warn({ userPath, resolved }, "Realpath resolution rejected");
113
+ return null;
114
+ }
115
+ if (escapesBase(contextReal, resolvedReal)) {
116
+ logger.warn({ userPath, resolved, resolvedReal }, "Symlink traversal rejected");
117
+ return null;
118
+ }
119
+ const realRel = relative(contextReal, resolvedReal);
120
+ if (isDeniedPath(realRel)) {
121
+ logger.warn({ userPath, resolved, resolvedReal }, "Denied realpath rejected");
122
+ return null;
123
+ }
124
+ return resolved;
125
+ }
126
+ // B-007 §5.1 — write-permission whitelist for the new layout.
127
+ const CONTEXT_WRITE_PERMISSIONS = {
128
+ // Top-level survivors.
129
+ today: ["PUT", "PATCH"],
130
+ yesterday: ["PUT", "PATCH"],
131
+ roadmap: ["PUT", "PATCH"],
132
+ _index: ["PUT", "PATCH"],
133
+ "context-index": ["PUT", "PATCH"],
134
+ // user/* covers fixed area files AND the §5.5 growth pattern
135
+ // (e.g. `user/health/sleep-log.md` after an area promotion).
136
+ "user/*": ["PUT", "PATCH"],
137
+ // Natural-language rulebooks — §5.8.
138
+ "rules/_index": ["PUT", "PATCH"],
139
+ // DELETE intentionally omitted. Policy files under `rules/policies/`
140
+ // use `status: removed` in lieu of physical deletion so the captured
141
+ // history (origin DM, why, linked routine) survives. See
142
+ // MANAGEMENT-POLICY-CAPTURE-PLAN.md §4.6 / §5.1.
143
+ "rules/*": ["PUT", "PATCH"],
144
+ "routines/_index": ["PUT", "PATCH"],
145
+ "routines/*": ["PUT", "PATCH"],
146
+ // B-007 §5.8 Q3 — custom routines support DELETE so the agent can
147
+ // retire a routine when the user asks via DM. The scheduler re-reads
148
+ // the directory via `onCustomRoutinesChanged` and unregisters the
149
+ // cron job on the next reload pass.
150
+ "routines/custom/*": ["PUT", "PATCH", "DELETE"],
151
+ // Projects (`.base` permitted via CONTEXT_FILE_EXTENSIONS).
152
+ "projects/_index": ["PUT", "PATCH"],
153
+ "projects/_active": ["PUT"],
154
+ "projects/*": ["PUT", "PATCH"],
155
+ // Lightweight registry for watched git repos that are not promoted to a
156
+ // full project page.
157
+ // @deprecated Pre-cutover layout (see docs/design/appendices/unified-repositories.md);
158
+ // retained for transitional reads of legacy files. New writes route to
159
+ // `git/<slug>/{overview,journal/<YYYY-MM-DD>}`.
160
+ "git-repos/*": ["PUT", "PATCH"],
161
+ // Unified repositories — per-repo project overview + per-day journal.
162
+ // The two specific patterns below carry write permission; arbitrary
163
+ // paths under `git/` are NOT writable to keep the layout disciplined.
164
+ // See docs/design/appendices/unified-repositories.md §4.5.
165
+ "git/{slug}/overview": ["PUT", "PATCH"],
166
+ "git/{slug}/journal/{date}": ["PUT", "PATCH"],
167
+ // Journal & reviews.
168
+ "daily/*": ["PUT", "PATCH"],
169
+ "weekly/*": ["PUT", "PATCH"],
170
+ "monthly/*": ["PUT", "PATCH"],
171
+ // Dossiers + inbox + agent self-areas.
172
+ "dossiers/_index": ["PUT", "PATCH"],
173
+ "dossiers/*": ["PUT", "PATCH"],
174
+ // B-007 §5.9 Step 4 / §5.3 — morning routine triages each inbox file and
175
+ // moves the original to `agent/scratch/inbox-YYYY-MM-DD-*.md`. Both sides
176
+ // of the move need DELETE: inbox for the post-triage cleanup, scratch for
177
+ // the eventual 48h TTL retention sweep (§6.5).
178
+ "inbox/*": ["PUT", "PATCH", "DELETE"],
179
+ "agent/journal": ["PUT", "PATCH"],
180
+ "agent/scratch/*": ["PUT", "PATCH", "DELETE"],
181
+ };
182
+ /**
183
+ * Paths where PUT is only allowed when the file does not yet exist.
184
+ * Subsequent writes must go through PATCH (append). This enforces the
185
+ * append-only contract at the API level rather than relying on prompt
186
+ * compliance alone.
187
+ */
188
+ const CREATE_ONLY_PUT = new Set(["agent/journal"]);
189
+ /**
190
+ * Slug regex shared by `{slug}` and `{date}` placeholders. Matches the
191
+ * sanitized output of `deriveSlug` (a-z, 0-9, dot, underscore, dash) and
192
+ * `YYYY-MM-DD` date strings without further validation — the route
193
+ * handler does the canonical date validation when it parses the URL.
194
+ */
195
+ const PLACEHOLDER_SEGMENT_RE = /^[a-z0-9._-]+$/;
196
+ function patternToRegex(pattern) {
197
+ // Escape regex metachars except the placeholder syntax we control.
198
+ const escaped = pattern.replace(/[.+^$()|\\]/g, "\\$&");
199
+ // `{name}` → one allowed segment.
200
+ const withSegments = escaped.replace(/\\?\{[^}]+\\?\}/g, "[a-z0-9._-]+");
201
+ // `/*` at end → exactly one trailing segment.
202
+ const withTail = withSegments.replace(/\/\*$/, "/[^/]+");
203
+ return new RegExp("^" + withTail + "$");
204
+ }
205
+ function isWriteAllowed(path, method) {
206
+ // Check exact match first
207
+ if (CONTEXT_WRITE_PERMISSIONS[path]?.includes(method))
208
+ return true;
209
+ // Check wildcard patterns
210
+ for (const [pattern, methods] of Object.entries(CONTEXT_WRITE_PERMISSIONS)) {
211
+ if (!methods.includes(method))
212
+ continue;
213
+ if (pattern.endsWith("/*")) {
214
+ const prefix = pattern.slice(0, -2);
215
+ if (path.startsWith(prefix + "/")) {
216
+ return true;
217
+ }
218
+ }
219
+ if (pattern.includes("{")) {
220
+ if (patternToRegex(pattern).test(path)) {
221
+ // Defense-in-depth: each replaced placeholder must match the
222
+ // sanitized form. The regex already enforces that, but we
223
+ // double-check the character set explicitly so a future
224
+ // pattern with `{slug}` mid-string can't drift.
225
+ const segments = path.split("/");
226
+ const patternSegments = pattern.split("/");
227
+ if (segments.length !== patternSegments.length)
228
+ continue;
229
+ let allValid = true;
230
+ for (let i = 0; i < segments.length; i++) {
231
+ const lit = patternSegments[i];
232
+ if (lit.startsWith("{") && lit.endsWith("}")) {
233
+ if (!PLACEHOLDER_SEGMENT_RE.test(segments[i])) {
234
+ allValid = false;
235
+ break;
236
+ }
237
+ }
238
+ else if (lit !== segments[i]) {
239
+ allValid = false;
240
+ break;
241
+ }
242
+ }
243
+ if (allValid)
244
+ return true;
245
+ }
246
+ }
247
+ }
248
+ return false;
249
+ }
250
+ /**
251
+ * Determine if a context file change should trigger a prompt context
252
+ * refresh consideration. The staleness classifier decides whether the
253
+ * matching write is loud enough to invalidate active DM sessions.
254
+ *
255
+ * B-007 §5.1 — user/profile.md is refreshed on PUT only (setup writes
256
+ * the full file) but NOT on PATCH (SignalDetector appends to Raw Signals
257
+ * frequently — refreshing on every append would thrash the owner session).
258
+ *
259
+ * The setup.initial PUT fires this, but it does NOT destroy the in-flight
260
+ * setup conversation — the `onPromptContextChanged` handler in index.ts
261
+ * skips `markActiveDmSessionsStale` while `currentSetupMode` is active.
262
+ */
263
+ function shouldRefreshPromptContext(path, method) {
264
+ if (path === "today" ||
265
+ path === "roadmap" ||
266
+ path === "context-index") {
267
+ return true;
268
+ }
269
+ // B-007 — any rules/*.md file feeds the policy-files injection hub, so
270
+ // edits to any of them should invalidate the owner-session prompt cache.
271
+ // Routine rulebooks (`routines/*.md`) similarly drive task-flow prompts.
272
+ if (path.startsWith("rules/") || path.startsWith("routines/")) {
273
+ return true;
274
+ }
275
+ if (path.startsWith("dossiers/")) {
276
+ return true;
277
+ }
278
+ if (path === "user/profile" && method === "PUT") {
279
+ return true;
280
+ }
281
+ return false;
282
+ }
283
+ function notifyPromptContextChanged(deps, path, reason, input) {
284
+ const classification = classifyContextWriteStaleness(input);
285
+ deps.onPromptContextChanged?.(path, reason, classification.tier, {
286
+ tierReason: classification.tierReason,
287
+ });
288
+ // STAGE-C-DM-FRESHNESS-PLAN §Task 4 — record the staleness tier in
289
+ // `agent_actions` so the dashboard's `dm_freshness_metrics` view can
290
+ // count loud vs. quiet writes that landed within a DM session's
291
+ // lifetime. Best-effort: a failure here must not break the write.
292
+ try {
293
+ deps.db
294
+ .prepare(`INSERT INTO agent_actions (action_type, trigger, result, detail, started_at, completed_at)
295
+ VALUES ('context_write', 'reactive', 'success', json(?), datetime('now'), datetime('now'))`)
296
+ .run(JSON.stringify({
297
+ path,
298
+ method: input.method,
299
+ tier: classification.tier,
300
+ tierReason: classification.tierReason,
301
+ reason,
302
+ }));
303
+ }
304
+ catch (err) {
305
+ logger.warn({ err, path, method: input.method }, "Failed to record context_write agent_actions row (Stage C metrics)");
306
+ }
307
+ }
308
+ /**
309
+ * Normalize a section name for matching:
310
+ * lowercase, spaces → underscores, strip leading ##
311
+ */
312
+ function normalizeSection(name) {
313
+ return name
314
+ .replace(/^#+\s*/, "")
315
+ .toLowerCase()
316
+ .replace(/\s+/g, "_");
317
+ }
318
+ /**
319
+ * Find a section in markdown content and return its boundaries.
320
+ * Returns [startOfBody, endOfBody] where body is between this ## and next ##.
321
+ */
322
+ function findSection(content, sectionName) {
323
+ const normalized = normalizeSection(sectionName);
324
+ const lines = content.split("\n");
325
+ let sectionStart = -1;
326
+ let headerEnd = -1;
327
+ for (let i = 0; i < lines.length; i++) {
328
+ if (lines[i].startsWith("## ")) {
329
+ const lineNormalized = normalizeSection(lines[i]);
330
+ if (lineNormalized === normalized) {
331
+ sectionStart = i;
332
+ const lineStart = sumLength(lines, i);
333
+ const nlPos = content.indexOf("\n", lineStart);
334
+ // Handle file ending without trailing newline
335
+ headerEnd = nlPos === -1 ? content.length : nlPos + 1;
336
+ break;
337
+ }
338
+ }
339
+ }
340
+ if (sectionStart === -1)
341
+ return null;
342
+ // Find end: next ## header or EOF
343
+ let sectionEnd = content.length;
344
+ for (let i = sectionStart + 1; i < lines.length; i++) {
345
+ if (lines[i].startsWith("## ")) {
346
+ sectionEnd = sumLength(lines, i);
347
+ break;
348
+ }
349
+ }
350
+ return { start: headerEnd, end: sectionEnd, headerEnd };
351
+ }
352
+ function sumLength(lines, upToIndex) {
353
+ let len = 0;
354
+ for (let i = 0; i < upToIndex; i++) {
355
+ len += lines[i].length + 1; // +1 for \n
356
+ }
357
+ return len;
358
+ }
359
+ function getAvailableSections(content) {
360
+ return content
361
+ .split("\n")
362
+ .filter((l) => l.startsWith("## "))
363
+ .map((l) => normalizeSection(l));
364
+ }
365
+ /**
366
+ * Parse a timestamp from a bullet entry like `- [2026-04-10 02:32:59] ...`
367
+ * Returns the timestamp string or null if the line doesn't match.
368
+ */
369
+ const ENTRY_TIMESTAMP_RE = /^- \[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\]/;
370
+ function parseEntryTimestamp(line) {
371
+ const match = ENTRY_TIMESTAMP_RE.exec(line);
372
+ return match ? match[1] : null;
373
+ }
374
+ /**
375
+ * Remove entries whose `- [YYYY-MM-DD HH:MM:SS]` timestamp is ≤ cutoff.
376
+ * Non-matching lines (blank lines, continuation lines) are preserved.
377
+ * Returns the remaining section body and the count of removed entries.
378
+ */
379
+ function clearEntriesBefore(sectionBody, cutoff) {
380
+ const lines = sectionBody.split("\n");
381
+ const kept = [];
382
+ let removedCount = 0;
383
+ let skipContinuation = false;
384
+ for (const line of lines) {
385
+ const ts = parseEntryTimestamp(line);
386
+ if (ts !== null) {
387
+ // This is a timestamped entry
388
+ if (ts <= cutoff) {
389
+ removedCount++;
390
+ skipContinuation = true;
391
+ continue;
392
+ }
393
+ skipContinuation = false;
394
+ kept.push(line);
395
+ }
396
+ else if (skipContinuation && (line.startsWith(" ") || line.trim() === "")) {
397
+ // Continuation or trailing blank line of a removed entry
398
+ continue;
399
+ }
400
+ else {
401
+ skipContinuation = false;
402
+ kept.push(line);
403
+ }
404
+ }
405
+ return { remaining: kept.join("\n"), removedCount };
406
+ }
407
+ /**
408
+ * Trim oldest bullet entries (`- ...` lines) from the top of a section
409
+ * body to keep at most `maxEntries` entries. Non-bullet lines (blank
410
+ * lines, non-`- ` prefixed lines) are preserved.
411
+ */
412
+ function trimBulletEntries(body, maxEntries) {
413
+ const lines = body.split("\n");
414
+ // Collect indices of bullet entry start lines
415
+ const bulletIndices = [];
416
+ for (let i = 0; i < lines.length; i++) {
417
+ if (lines[i].startsWith("- ")) {
418
+ bulletIndices.push(i);
419
+ }
420
+ }
421
+ const excess = bulletIndices.length - maxEntries;
422
+ if (excess <= 0) {
423
+ return { body, trimmed: 0 };
424
+ }
425
+ // Remove the oldest (topmost) `excess` entries and their continuations.
426
+ // Also remove blank lines between consecutive removed entries to avoid
427
+ // orphaned whitespace accumulating over many trim cycles.
428
+ const removeSet = new Set();
429
+ for (let i = 0; i < excess; i++) {
430
+ const start = bulletIndices[i];
431
+ const end = i + 1 < bulletIndices.length ? bulletIndices[i + 1] : lines.length;
432
+ for (let j = start; j < end; j++) {
433
+ if (j === start || lines[j].startsWith(" ") || lines[j].trim() === "") {
434
+ removeSet.add(j);
435
+ }
436
+ }
437
+ }
438
+ const kept = lines.filter((_, i) => !removeSet.has(i));
439
+ return { body: kept.join("\n"), trimmed: excess };
440
+ }
441
+ const SNAPSHOT_DEBOUNCE_MS = 5 * 60 * 1000; // 5 minutes
442
+ /**
443
+ * Cap on the JSON body accepted by the Context PUT/PATCH endpoints.
444
+ *
445
+ * Real context files are well under this — `today.md` is typically
446
+ * ~10 KB at the busiest point of the day, `roadmap.md` runs ~50 KB,
447
+ * project pages ~50 KB, and `agent/journal.md` is bounded by the
448
+ * retention rollup. 1 MB leaves >10x headroom for legitimate writes
449
+ * while preventing a runaway-payload denial-of-service:
450
+ *
451
+ * - The agent could otherwise be tricked (prompt injection from a
452
+ * poisoned email or Obsidian note) into PATCHing a multi-megabyte
453
+ * payload, and each PATCH writes a snapshot row in
454
+ * `md_file_snapshots`. Snapshots are pruned at 30 days, so a
455
+ * burst of large writes can balloon the DB before retention
456
+ * catches up.
457
+ *
458
+ * - 1 MB is an order of magnitude smaller than the attachment route's
459
+ * 25 MB cap; context files have no legitimate need to be that big.
460
+ *
461
+ * Only PUT/PATCH against the wildcard route apply this cap. Smaller
462
+ * structured endpoints (lock, archive-today, repair/stub) use
463
+ * `readOptionalJsonBody` whose payloads are tiny by construction.
464
+ */
465
+ const CONTEXT_BODY_MAX_BYTES = 1024 * 1024;
466
+ export function createContextRoutes(deps) {
467
+ const app = new Hono();
468
+ const { db, config, writeTracker } = deps;
469
+ // Resolve the context directory at request time rather than closing over
470
+ // the startup value. `/api/setup/migrate-context` mutates `config` in
471
+ // memory after a successful move, and the Context API must immediately
472
+ // follow the new primary-vault path without requiring a daemon restart.
473
+ //
474
+ // Intentionally omit `db` here: degraded mode is handled by the 503
475
+ // middleware below, so once a request reaches a handler we want the
476
+ // actual current target path, never the legacy fallback.
477
+ const getCurrentContextDir = () => getContextDir(config);
478
+ /**
479
+ * Management Mode degraded-mode gate (plan §5.4).
480
+ * When the primary vault is unreachable, refuse BOTH reads and writes
481
+ * with 503 so the agent does not read or write a stale fallback
482
+ * location. Checked per-request so lifting degraded mode in the health
483
+ * probe takes effect without restart. The lock endpoints under
484
+ * `/context/lock/*` also participate: acquiring a lock during degraded
485
+ * mode would leave the lock held with no way to write, so we gate them
486
+ * too.
487
+ */
488
+ app.use("/context/*", async (c, next) => {
489
+ const state = getDegradedMode(db);
490
+ if (state) {
491
+ return c.json({
492
+ error: "primary_vault_unreachable",
493
+ reason: state.reason,
494
+ path: state.path,
495
+ since: state.since,
496
+ }, 503);
497
+ }
498
+ // Phase 2 — global context-write gate engaged during a
499
+ // /api/setup/migrate-context run. Refuses WRITES (not reads)
500
+ // because reads against the still-intact source are safe; the
501
+ // migration endpoint blocks writes so no handler races the move.
502
+ const writeMethods = new Set(["POST", "PUT", "PATCH", "DELETE"]);
503
+ if (deps.contextWriteGate?.isEngaged() && writeMethods.has(c.req.method)) {
504
+ const gateState = deps.contextWriteGate.getState();
505
+ return c.json({
506
+ error: "migration_in_progress",
507
+ reason: gateState.reason,
508
+ since: gateState.since,
509
+ }, 503);
510
+ }
511
+ await next();
512
+ });
513
+ const morningRoutineLock = deps.morningRoutineLock ??
514
+ new InMemoryTodayWriteLockManager(getTodayWriteLockTimeoutMs(config.executeTimeoutMinutes));
515
+ const roadmapWriteLock = deps.roadmapWriteLock ??
516
+ new InMemoryRoadmapWriteLockManager(getRoadmapWriteLockTimeoutMs(config.executeTimeoutMinutes));
517
+ // Per-instance state (not shared across tests)
518
+ const lastSnapshotTimes = new Map();
519
+ // Mutex for serialized writes
520
+ let writeLock = Promise.resolve();
521
+ function withWriteLock(fn) {
522
+ const prev = writeLock;
523
+ let resolve;
524
+ writeLock = new Promise((r) => {
525
+ resolve = r;
526
+ });
527
+ return prev.then(() => {
528
+ try {
529
+ return fn();
530
+ }
531
+ finally {
532
+ resolve();
533
+ }
534
+ });
535
+ }
536
+ function saveSnapshot(filePath, content, trigger, force = false, sessionId) {
537
+ const now = Date.now();
538
+ const lastTime = lastSnapshotTimes.get(filePath) ?? 0;
539
+ if (!force && now - lastTime < SNAPSHOT_DEBOUNCE_MS) {
540
+ return null;
541
+ }
542
+ const result = db
543
+ .prepare("INSERT INTO md_file_snapshots (file_path, content, trigger, session_id) VALUES (?, ?, ?, ?)")
544
+ .run(filePath, content, trigger, sessionId ?? null);
545
+ lastSnapshotTimes.set(filePath, now);
546
+ return Number(result.lastInsertRowid);
547
+ }
548
+ function isRoadmapValidationDisabled(path, headerValue) {
549
+ return path === "roadmap" && headerValue?.toLowerCase() === "off";
550
+ }
551
+ function logRoadmapValidationBypass(c, method, path) {
552
+ logger.warn({
553
+ path,
554
+ method,
555
+ sessionId: c.req.header("X-Session-Id") ?? null,
556
+ caller: c.req.header("X-Caller") ??
557
+ c.req.header("X-Agent-Caller") ??
558
+ c.req.header("User-Agent") ??
559
+ null,
560
+ route: c.req.path,
561
+ }, "Roadmap validation bypassed by X-Roadmap-Validation: off");
562
+ }
563
+ function roadmapDefaultLongTermPlanSource(c) {
564
+ const caller = (c.req.header("X-Caller") ??
565
+ c.req.header("X-Agent-Caller") ??
566
+ "").toLowerCase();
567
+ return caller.includes("dashboard") ? "dashboard" : "manual";
568
+ }
569
+ async function readOptionalJsonBody(c) {
570
+ const raw = await c.req.text();
571
+ if (raw.trim() === "")
572
+ return { ok: true, body: {} };
573
+ try {
574
+ const parsed = JSON.parse(raw);
575
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
576
+ return {
577
+ ok: false,
578
+ response: c.json({
579
+ error: "validation_error",
580
+ message: "JSON body must be an object.",
581
+ }, 400),
582
+ };
583
+ }
584
+ return { ok: true, body: parsed };
585
+ }
586
+ catch (err) {
587
+ const detail = err instanceof Error ? err.message : String(err);
588
+ logger.warn({ path: c.req.path, method: c.req.method, detail }, "Request rejected — body is not valid JSON");
589
+ return {
590
+ ok: false,
591
+ response: c.json({ error: "invalid_json_body", message: detail }, 400),
592
+ };
593
+ }
594
+ }
595
+ // === Routes registered BEFORE wildcards (Hono matches in registration order) ===
596
+ // POST /context/lock/morning-routine — Acquire exclusive lock
597
+ app.post("/context/lock/morning-routine", (c) => {
598
+ const result = morningRoutineLock.acquire();
599
+ if (!result.ok) {
600
+ return c.json({ error: "lock_held", holder: result.holder }, 409);
601
+ }
602
+ return c.json({ status: "acquired", lockId: result.lockId });
603
+ });
604
+ // DELETE /context/lock/morning-routine — Release exclusive lock
605
+ app.delete("/context/lock/morning-routine", async (c) => {
606
+ const body = await c.req.json().catch(() => ({}));
607
+ const lockId = body.lockId;
608
+ if (lockId && morningRoutineLock.release(lockId)) {
609
+ return c.json({ status: "released" });
610
+ }
611
+ return c.json({ error: "lock_not_held" }, 400);
612
+ });
613
+ // POST /context/lock/roadmap — Acquire exclusive roadmap write lock
614
+ // Dispatcher auto-acquires this for `routine.roadmap_refresh`; other
615
+ // flows (DM handler via the roadmap skill, evening sweeper) may
616
+ // acquire it manually. See ROADMAP-REDESIGN.md §3.6.
617
+ app.post("/context/lock/roadmap", (c) => {
618
+ const result = roadmapWriteLock.acquire();
619
+ if (!result.ok) {
620
+ return c.json({ error: "roadmap_write_lock_held", holder: result.holder }, 409);
621
+ }
622
+ return c.json({ status: "acquired", lockId: result.lockId });
623
+ });
624
+ // DELETE /context/lock/roadmap — Release the roadmap write lock
625
+ app.delete("/context/lock/roadmap", async (c) => {
626
+ const body = await c.req.json().catch(() => ({}));
627
+ const lockId = body.lockId;
628
+ if (lockId && roadmapWriteLock.release(lockId)) {
629
+ return c.json({ status: "released" });
630
+ }
631
+ return c.json({ error: "lock_not_held" }, 400);
632
+ });
633
+ // POST /context/roadmap/id — Mint a stable daemon-owned roadmap entry id.
634
+ app.post("/context/roadmap/id", async (c) => {
635
+ if (roadmapWriteLock.getHolder()) {
636
+ const lockId = c.req.header("X-Lock-Id");
637
+ if (!roadmapWriteLock.isHeldBy(lockId)) {
638
+ logger.info({ path: "roadmap" }, "Roadmap id mint rejected — roadmap write lock held");
639
+ return c.json({ error: "roadmap_write_lock_held" }, 409);
640
+ }
641
+ }
642
+ const parsedBody = await readOptionalJsonBody(c);
643
+ if (!parsedBody.ok)
644
+ return parsedBody.response;
645
+ const requestedDate = parsedBody.body.creationDate ?? parsedBody.body.sourceDate;
646
+ const creationDate = typeof requestedDate === "string"
647
+ ? requestedDate
648
+ : localDateStr(new Date(), config.timezone || undefined);
649
+ if (!isValidYmd(creationDate)) {
650
+ return c.json({
651
+ error: "validation_error",
652
+ message: "creationDate must be YYYY-MM-DD.",
653
+ }, 400);
654
+ }
655
+ return withWriteLock(() => {
656
+ const contextDir = getCurrentContextDir();
657
+ const fullPath = safePath(contextDir, "roadmap");
658
+ if (!fullPath) {
659
+ return c.json({ error: "invalid_path", path: "roadmap" }, 400);
660
+ }
661
+ const content = existsSync(fullPath)
662
+ ? readFileSync(fullPath, "utf-8")
663
+ : "";
664
+ const existingIds = extractRoadmapIds(content).map((ref) => ref.id);
665
+ try {
666
+ return c.json({
667
+ id: generateRoadmapId({
668
+ creationDate,
669
+ existingIds,
670
+ randomBytes: deps.roadmapIdRandomBytes,
671
+ }),
672
+ });
673
+ }
674
+ catch (err) {
675
+ if (err instanceof RoadmapIdGenerationError) {
676
+ return c.json({ error: "roadmap_id_generation_failed" }, 503);
677
+ }
678
+ throw err;
679
+ }
680
+ });
681
+ });
682
+ // POST /context/archive-today — B-007 §5.9 day rotation.
683
+ // Before Phase 1 this copied today.md to `schedule/YYYY-MM-DD.md`; that
684
+ // mechanical archive has been retired (the synthesized `daily/YYYY-MM-DD.md`
685
+ // is now written by the morning routine). The endpoint is kept as the
686
+ // agent-triggered rotation that renames `today.md → yesterday.md` and
687
+ // returns the previous date so the agent can write the new `today.md`
688
+ // in the same flow.
689
+ app.post("/context/archive-today", (c) => {
690
+ return withWriteLock(() => {
691
+ const contextDir = getCurrentContextDir();
692
+ const todayPath = join(contextDir, "today.md");
693
+ if (!existsSync(todayPath)) {
694
+ return c.json({ error: "not_found", path: "today" }, 404);
695
+ }
696
+ const content = readFileSync(todayPath, "utf-8");
697
+ const dateStr = content.match(/^#.*(\d{4}-\d{2}-\d{2})/)?.[1] ??
698
+ localDateStr(new Date());
699
+ const yesterdayPath = join(contextDir, "yesterday.md");
700
+ // Atomic write through O_NOFOLLOW + rename so a symlink swap at
701
+ // `yesterday.md` between request validation and the write cannot
702
+ // redirect the rotation into an attacker-controlled path. The
703
+ // legacy `copyFileSync` would silently follow such a symlink.
704
+ writeFileAtomically(yesterdayPath, content);
705
+ saveSnapshot("today", content, "rotate-to-yesterday", true);
706
+ return c.json({
707
+ status: "archived",
708
+ archivePath: "yesterday.md",
709
+ rotatedFrom: dateStr,
710
+ });
711
+ });
712
+ });
713
+ // POST /context/restore-snapshot/:id — restore a prior md_file_snapshots
714
+ // row back onto disk. The current on-disk file (if any) is snapshotted
715
+ // first so the restore itself is reversible from the Knowledge page.
716
+ app.post("/context/restore-snapshot/:id", (c) => {
717
+ const id = Number(c.req.param("id"));
718
+ if (!Number.isSafeInteger(id) || id <= 0) {
719
+ return c.json({ error: "invalid_id" }, 400);
720
+ }
721
+ const row = db
722
+ .prepare("SELECT id, file_path, content FROM md_file_snapshots WHERE id = ?")
723
+ .get(id);
724
+ if (!row) {
725
+ return c.json({ error: "not_found" }, 404);
726
+ }
727
+ const target = resolveContextTarget(row.file_path);
728
+ const path = target.base;
729
+ const contextDir = getCurrentContextDir();
730
+ const fullPath = safePath(contextDir, row.file_path);
731
+ if (!fullPath) {
732
+ return c.json({ error: "invalid_path", path }, 400);
733
+ }
734
+ if (!isWriteAllowed(path, "PUT") && !isWriteAllowed(path, "PATCH")) {
735
+ logger.warn({ path, method: "RESTORE" }, "Snapshot restore forbidden");
736
+ return c.json({ error: "forbidden", path, method: "RESTORE" }, 403);
737
+ }
738
+ if (morningRoutineLock.getHolder() && path === "today") {
739
+ const lockId = c.req.header("X-Lock-Id");
740
+ if (!morningRoutineLock.isHeldBy(lockId)) {
741
+ logger.info({ path }, "Snapshot restore rejected — morning routine lock held");
742
+ return c.json({ error: "morning_routine_lock_held" }, 409);
743
+ }
744
+ }
745
+ if (roadmapWriteLock.getHolder() && path === "roadmap") {
746
+ const lockId = c.req.header("X-Lock-Id");
747
+ if (!roadmapWriteLock.isHeldBy(lockId)) {
748
+ logger.info({ path }, "Snapshot restore rejected — roadmap write lock held");
749
+ return c.json({ error: "roadmap_write_lock_held" }, 409);
750
+ }
751
+ }
752
+ const contentError = validateContextContent(target, row.content, {
753
+ skipFrontmatterValidation: true,
754
+ });
755
+ if (contentError) {
756
+ return c.json({ error: "validation_error", message: contentError.message }, contentError.status);
757
+ }
758
+ return withWriteLock(() => {
759
+ let backupSnapshotId = null;
760
+ if (existsSync(fullPath)) {
761
+ const current = readFileSync(fullPath, "utf-8");
762
+ backupSnapshotId = saveSnapshot(path, current, "api_restore_snapshot", true);
763
+ }
764
+ // writeFileAtomically handles parent-dir creation, refuses to
765
+ // follow a symlink at the destination, and renames into place.
766
+ writeFileAtomically(fullPath, row.content);
767
+ writeTracker?.markWriting(fullPath, row.content);
768
+ if (shouldRefreshPromptContext(path, "PUT")) {
769
+ notifyPromptContextChanged(deps, path, `context_restore_snapshot:${path}`, { path, method: "RESTORE" });
770
+ }
771
+ if (path.startsWith("routines/custom/")) {
772
+ deps.onCustomRoutinesChanged?.();
773
+ }
774
+ const writtenStat = statSync(fullPath);
775
+ logger.info({
776
+ path,
777
+ method: "RESTORE",
778
+ restoredFromSnapshotId: id,
779
+ backupSnapshotId: backupSnapshotId ?? undefined,
780
+ }, "Context snapshot restored");
781
+ return c.json({
782
+ status: "restored",
783
+ path,
784
+ restoredFromSnapshotId: id,
785
+ backupSnapshotId,
786
+ lastModified: writtenStat.mtime.toISOString(),
787
+ });
788
+ });
789
+ });
790
+ // GET /context/list/:dir — List files in directory
791
+ app.get("/context/list/:dir", (c) => {
792
+ const dir = c.req.param("dir");
793
+ // B-007 §5.1 — canonical listable directories.
794
+ const allowedDirs = [
795
+ "projects",
796
+ "weekly",
797
+ "monthly",
798
+ "daily",
799
+ "user",
800
+ "rules",
801
+ "routines",
802
+ "dossiers",
803
+ "git",
804
+ "git-repos",
805
+ "inbox",
806
+ ];
807
+ if (!allowedDirs.includes(dir)) {
808
+ return c.json({ error: "invalid_directory", allowed: allowedDirs }, 400);
809
+ }
810
+ const contextDir = getCurrentContextDir();
811
+ const dirPath = join(contextDir, dir);
812
+ if (!existsSync(dirPath)) {
813
+ return c.json({ files: [] });
814
+ }
815
+ const files = readdirSync(dirPath)
816
+ .filter((f) => CONTEXT_FILE_EXTENSIONS.some((ext) => f.endsWith(ext)))
817
+ .map((f) => {
818
+ const stat = statSync(join(dirPath, f));
819
+ return { name: f, lastModified: stat.mtime.toISOString() };
820
+ });
821
+ // B-007 §5.8 Q3 — surface custom routines so the dashboard routines
822
+ // editor sees them alongside the built-ins. `routines/custom/` is the
823
+ // only nested directory we need to flatten; other listable dirs are
824
+ // flat by design (§5.1).
825
+ if (dir === "routines") {
826
+ const customDir = join(dirPath, "custom");
827
+ if (existsSync(customDir)) {
828
+ for (const f of readdirSync(customDir)) {
829
+ if (!CONTEXT_FILE_EXTENSIONS.some((ext) => f.endsWith(ext)))
830
+ continue;
831
+ const stat = statSync(join(customDir, f));
832
+ files.push({
833
+ name: `custom/${f}`,
834
+ lastModified: stat.mtime.toISOString(),
835
+ });
836
+ }
837
+ }
838
+ }
839
+ // Unified repositories layout (`git/<slug>/overview.md` +
840
+ // `git/<slug>/journal/<YYYY-MM-DD>.md`) — surface every per-repo file
841
+ // under the `git` listing so the Knowledge page tree shows them.
842
+ // Without this the listing only contains files directly under `git/`,
843
+ // and the per-slug subdirectories silently drop off the dashboard.
844
+ // Mirrors the `routines/custom/` flatten above.
845
+ if (dir === "git") {
846
+ for (const entry of readdirSync(dirPath, { withFileTypes: true })) {
847
+ if (!entry.isDirectory())
848
+ continue;
849
+ const slug = entry.name;
850
+ const slugDir = join(dirPath, slug);
851
+ for (const f of readdirSync(slugDir)) {
852
+ if (!CONTEXT_FILE_EXTENSIONS.some((ext) => f.endsWith(ext)))
853
+ continue;
854
+ const stat = statSync(join(slugDir, f));
855
+ files.push({
856
+ name: `${slug}/${f}`,
857
+ lastModified: stat.mtime.toISOString(),
858
+ });
859
+ }
860
+ const journalDir = join(slugDir, "journal");
861
+ if (existsSync(journalDir)) {
862
+ for (const f of readdirSync(journalDir)) {
863
+ if (!CONTEXT_FILE_EXTENSIONS.some((ext) => f.endsWith(ext)))
864
+ continue;
865
+ const stat = statSync(join(journalDir, f));
866
+ files.push({
867
+ name: `${slug}/journal/${f}`,
868
+ lastModified: stat.mtime.toISOString(),
869
+ });
870
+ }
871
+ }
872
+ }
873
+ }
874
+ // MANAGEMENT-POLICY-CAPTURE-PLAN §4.4.1 step 1 — surface policy files
875
+ // under `rules/policies/` flattened into the `rules` listing so the
876
+ // `management-policy` skill can use the directory listing as its
877
+ // source-of-truth (the agent-maintained `_index.md` is only the
878
+ // convenience snapshot). Mirrors the `routines/custom/` flatten above.
879
+ if (dir === "rules") {
880
+ const policiesDir = join(dirPath, "policies");
881
+ if (existsSync(policiesDir)) {
882
+ for (const f of readdirSync(policiesDir)) {
883
+ if (!CONTEXT_FILE_EXTENSIONS.some((ext) => f.endsWith(ext)))
884
+ continue;
885
+ const stat = statSync(join(policiesDir, f));
886
+ files.push({
887
+ name: `policies/${f}`,
888
+ lastModified: stat.mtime.toISOString(),
889
+ });
890
+ }
891
+ }
892
+ }
893
+ return c.json({ files });
894
+ });
895
+ // GET /context/today/reconciliation — compare open Agent Plan rows with
896
+ // pending/running schedules for the same local day. This is intentionally
897
+ // diagnostic only: morning routine may write today.md and register schedules
898
+ // in separate API calls, so write-time hard failure would create false
899
+ // conflicts. The endpoint gives operators and future jobs a server-side
900
+ // reconciliation surface.
901
+ app.get("/context/today/reconciliation", (c) => {
902
+ const contextDir = getCurrentContextDir();
903
+ const fullPath = safePath(contextDir, "today");
904
+ if (!fullPath) {
905
+ return c.json({ error: "invalid_path", path: "today" }, 400);
906
+ }
907
+ if (!existsSync(fullPath)) {
908
+ return c.json({ error: "not_found", path: "today" }, 404);
909
+ }
910
+ const content = readFileSync(fullPath, "utf-8");
911
+ const validationError = validateTodayContent(content);
912
+ const todayDate = extractTodayDate(content) ??
913
+ localDateStr(new Date(), config.timezone || undefined);
914
+ const openRows = extractTodayAgentPlanRows(content).rows.filter((row) => !row.checked);
915
+ const openRowsWithMetadata = openRows.map((row) => ({
916
+ row,
917
+ agentPlan: buildTodayAgentPlanMetadata(todayDate, row),
918
+ }));
919
+ const pendingRows = db
920
+ .prepare(`SELECT id, scheduled_for, task_type, task_description, task_context, status
921
+ FROM agent_schedule
922
+ WHERE status IN ('pending', 'running')`)
923
+ .all();
924
+ const schedules = pendingRows
925
+ .map((row) => toTodayScheduleCandidate(row, config.timezone || undefined))
926
+ .filter((row) => row !== null)
927
+ .map((row) => ({
928
+ ...row,
929
+ agentPlan: readTodayAgentPlanMetadata(row.taskContext),
930
+ }))
931
+ .filter((row) => row.agentPlan !== null && row.agentPlan.date === todayDate);
932
+ const rowMatches = openRowsWithMetadata.map(({ row, agentPlan }) => {
933
+ const matches = schedules.filter((schedule) => schedule.localDate === todayDate &&
934
+ schedule.localTime === row.time &&
935
+ schedule.agentPlan.ref === agentPlan.ref &&
936
+ schedule.agentPlan.fingerprint === agentPlan.fingerprint &&
937
+ schedule.agentPlan.category === row.category &&
938
+ schedule.agentPlan.trigger === row.trigger);
939
+ return { row, agentPlan, matches };
940
+ });
941
+ const rowsWithoutSchedule = rowMatches.filter(({ matches }) => matches.length === 0);
942
+ const duplicateAgentPlanSchedules = rowMatches.filter(({ matches }) => matches.length > 1);
943
+ const matchedScheduleIds = new Set();
944
+ for (const { matches } of rowMatches) {
945
+ for (const schedule of matches)
946
+ matchedScheduleIds.add(schedule.id);
947
+ }
948
+ const schedulesWithoutRow = schedules.filter((row) => !matchedScheduleIds.has(row.id));
949
+ const mismatchCount = (rowsWithoutSchedule.length +
950
+ duplicateAgentPlanSchedules.length +
951
+ schedulesWithoutRow.length);
952
+ return c.json({
953
+ status: validationError
954
+ ? "invalid_today"
955
+ : mismatchCount > 0
956
+ ? "mismatch"
957
+ : "ok",
958
+ validationError,
959
+ todayDate,
960
+ openAgentPlanRows: openRows.length,
961
+ pendingSchedules: schedules.length,
962
+ rowsWithoutSchedule: rowsWithoutSchedule.map(({ row, agentPlan }) => ({
963
+ line: row.line,
964
+ ref: agentPlan.ref,
965
+ time: row.time,
966
+ action: row.action,
967
+ category: row.category,
968
+ trigger: row.trigger,
969
+ })),
970
+ schedulesWithoutRow: schedulesWithoutRow.map((row) => ({
971
+ id: row.id,
972
+ ref: row.agentPlan.ref,
973
+ localTime: row.localTime,
974
+ scheduledFor: row.scheduledFor,
975
+ taskType: row.taskType,
976
+ status: row.status,
977
+ description: row.description,
978
+ })),
979
+ duplicateAgentPlanSchedules: duplicateAgentPlanSchedules.map(({ row, agentPlan, matches }) => ({
980
+ line: row.line,
981
+ ref: agentPlan.ref,
982
+ time: row.time,
983
+ action: row.action,
984
+ scheduleIds: matches.map((match) => match.id),
985
+ })),
986
+ });
987
+ });
988
+ // GET /context/health — schema drift and missing-file report for the
989
+ // primary context vault. Registered before the wildcard read route.
990
+ app.get("/context/health", (c) => {
991
+ const contextDir = getCurrentContextDir();
992
+ return c.json(buildContextHealthReport(contextDir));
993
+ });
994
+ // POST /context/repair/stub — create a known missing stub from the
995
+ // templates tree. This is intentionally guarded to a small allow-list;
996
+ // it is not an arbitrary file creation endpoint.
997
+ app.post("/context/repair/stub", async (c) => {
998
+ const parsedBody = await readOptionalJsonBody(c);
999
+ if (!parsedBody.ok)
1000
+ return parsedBody.response;
1001
+ const rawPath = parsedBody.body.path;
1002
+ if (typeof rawPath !== "string") {
1003
+ return c.json({
1004
+ error: "validation_error",
1005
+ message: "path must be a string.",
1006
+ }, 400);
1007
+ }
1008
+ const normalizedPath = normalizeRepairStubPath(rawPath);
1009
+ if (!normalizedPath || !REPAIRABLE_STUB_TARGETS.has(normalizedPath)) {
1010
+ return c.json({
1011
+ error: "unsupported_stub_target",
1012
+ message: "Only known context stub targets can be repaired.",
1013
+ path: rawPath,
1014
+ }, 400);
1015
+ }
1016
+ const templatesRoot = resolveTemplatesRoot(config.workspaceDir);
1017
+ if (!templatesRoot) {
1018
+ return c.json({
1019
+ error: "templates_unavailable",
1020
+ message: "agent-assets/templates could not be located.",
1021
+ }, 503);
1022
+ }
1023
+ const templatePath = join(templatesRoot, normalizedPath);
1024
+ if (!existsSync(templatePath)) {
1025
+ return c.json({
1026
+ error: "template_not_found",
1027
+ message: `No template exists for ${normalizedPath}.`,
1028
+ path: normalizedPath,
1029
+ }, 404);
1030
+ }
1031
+ const contextDir = getCurrentContextDir();
1032
+ const fullPath = safePath(contextDir, normalizedPath);
1033
+ if (!fullPath) {
1034
+ return c.json({ error: "invalid_path", path: normalizedPath }, 400);
1035
+ }
1036
+ return withWriteLock(() => {
1037
+ if (existsSync(fullPath)) {
1038
+ const existingStat = statSync(fullPath);
1039
+ return c.json({
1040
+ status: "exists",
1041
+ path: normalizedPath,
1042
+ lastModified: existingStat.mtime.toISOString(),
1043
+ });
1044
+ }
1045
+ // Read the template once and write atomically; replaces the
1046
+ // previous copyFileSync, which would have silently followed a
1047
+ // symlink planted at `fullPath` during the TOCTOU window between
1048
+ // safePath validation and the write.
1049
+ const content = readFileSync(templatePath, "utf-8");
1050
+ writeFileAtomically(fullPath, content);
1051
+ writeTracker?.markWriting(fullPath, content);
1052
+ const normalizedBase = normalizeContextPath(normalizedPath);
1053
+ if (shouldRefreshPromptContext(normalizedBase, "PUT")) {
1054
+ notifyPromptContextChanged(deps, normalizedBase, `context_repair_stub:${normalizedBase}`, { path: normalizedBase, method: "REPAIR" });
1055
+ }
1056
+ deps.onIndexableContextChange?.(normalizedPath);
1057
+ const writtenStat = statSync(fullPath);
1058
+ logger.info({ path: normalizedPath, templatePath }, "Context stub repaired from template");
1059
+ return c.json({
1060
+ status: "created",
1061
+ path: normalizedPath,
1062
+ lastModified: writtenStat.mtime.toISOString(),
1063
+ });
1064
+ });
1065
+ });
1066
+ // === Wildcard routes ===
1067
+ // GET /context/* — Read context file
1068
+ app.get("/context/*", (c) => {
1069
+ const rawPath = c.req.path.replace("/api/context/", "");
1070
+ if (!rawPath || rawPath === "list") {
1071
+ return c.json({ error: "path_required" }, 400);
1072
+ }
1073
+ const path = normalizeContextPath(rawPath);
1074
+ const contextDir = getCurrentContextDir();
1075
+ const fullPath = safePath(contextDir, rawPath);
1076
+ if (!fullPath) {
1077
+ return c.json({ error: "invalid_path", path }, 400);
1078
+ }
1079
+ if (!existsSync(fullPath)) {
1080
+ return c.json({ error: "not_found", path }, 404);
1081
+ }
1082
+ const content = readFileSync(fullPath, "utf-8");
1083
+ const stat = statSync(fullPath);
1084
+ // STAGE-C-DM-FRESHNESS-PLAN §Task 4 — record reads of `today` so the
1085
+ // dashboard refetch-hit metric can detect when the agent invokes the
1086
+ // Task 3 directive on a resumed turn. Bounded to `today` reads only
1087
+ // so the agent_actions volume stays small. Best-effort: any logging
1088
+ // failure must not break the read.
1089
+ if (path === "today") {
1090
+ try {
1091
+ deps.db
1092
+ .prepare(`INSERT INTO agent_actions (action_type, trigger, result, detail, started_at, completed_at)
1093
+ VALUES ('context_read', 'reactive', 'success', json(?), datetime('now'), datetime('now'))`)
1094
+ .run(JSON.stringify({ path }));
1095
+ }
1096
+ catch (err) {
1097
+ logger.warn({ err, path }, "Failed to record context_read agent_actions row (Stage C metrics)");
1098
+ }
1099
+ }
1100
+ return c.json({
1101
+ content,
1102
+ lastModified: stat.mtime.toISOString(),
1103
+ editable: isWriteAllowed(path, "PUT"),
1104
+ });
1105
+ });
1106
+ // PUT /context/* — Full replace
1107
+ app.put("/context/*", async (c) => {
1108
+ const rawPath = c.req.path.replace("/api/context/", "");
1109
+ const target = resolveContextTarget(rawPath);
1110
+ const path = target.base;
1111
+ const contextDir = getCurrentContextDir();
1112
+ const fullPath = safePath(contextDir, rawPath);
1113
+ if (!fullPath) {
1114
+ return c.json({ error: "invalid_path", path }, 400);
1115
+ }
1116
+ if (!isWriteAllowed(path, "PUT")) {
1117
+ logger.warn({ path, method: "PUT" }, "Context write forbidden");
1118
+ return c.json({ error: "forbidden", path, method: "PUT" }, 403);
1119
+ }
1120
+ // Morning Routine lock: reject writes to today while lock is held
1121
+ if (morningRoutineLock.getHolder() && path === "today") {
1122
+ const lockId = c.req.header("X-Lock-Id");
1123
+ if (!morningRoutineLock.isHeldBy(lockId)) {
1124
+ logger.info({ path }, "Context PUT rejected — morning routine lock held");
1125
+ return c.json({ error: "morning_routine_lock_held" }, 409);
1126
+ }
1127
+ }
1128
+ // Roadmap write lock: reject writes to roadmap while another session holds it
1129
+ if (roadmapWriteLock.getHolder() && path === "roadmap") {
1130
+ const lockId = c.req.header("X-Lock-Id");
1131
+ if (!roadmapWriteLock.isHeldBy(lockId)) {
1132
+ logger.info({ path }, "Context PUT rejected — roadmap write lock held");
1133
+ return c.json({ error: "roadmap_write_lock_held" }, 409);
1134
+ }
1135
+ }
1136
+ const parsedBody = await readJsonBody(c, { maxBytes: CONTEXT_BODY_MAX_BYTES });
1137
+ if (!parsedBody.ok)
1138
+ return parsedBody.response;
1139
+ const body = parsedBody.body;
1140
+ const parsed = contextPutSchema.safeParse(body);
1141
+ if (!parsed.success) {
1142
+ return c.json({ error: "validation_error", details: parsed.error }, 400);
1143
+ }
1144
+ const roadmapValidationOff = isRoadmapValidationDisabled(path, c.req.header("X-Roadmap-Validation"));
1145
+ if (roadmapValidationOff) {
1146
+ logRoadmapValidationBypass(c, "PUT", path);
1147
+ }
1148
+ const expectedAgentDay = path === "today"
1149
+ ? getAgentDayDateStr(config.timezone || undefined, config.dayBoundaryHour ?? 4)
1150
+ : undefined;
1151
+ const preflight = prepareContextContentForWrite(target, parsed.data.content, {
1152
+ timezone: config.timezone || undefined,
1153
+ disableRoadmapValidation: roadmapValidationOff,
1154
+ defaultLongTermPlanSource: roadmapDefaultLongTermPlanSource(c),
1155
+ expectedAgentDay,
1156
+ });
1157
+ if (!preflight.ok) {
1158
+ return c.json({
1159
+ error: "validation_error",
1160
+ message: preflight.message,
1161
+ path: preflight.path,
1162
+ }, preflight.status);
1163
+ }
1164
+ const sessionId = c.req.header("X-Session-Id");
1165
+ return withWriteLock(() => {
1166
+ // Append-only files: PUT is only allowed for initial creation.
1167
+ // Once the file exists, all writes must go through PATCH to preserve
1168
+ // the append-only contract. This check MUST be inside withWriteLock
1169
+ // to prevent TOCTOU races where two concurrent PUTs both pass an
1170
+ // outer existsSync check and then sequentially overwrite.
1171
+ if (CREATE_ONLY_PUT.has(path) && existsSync(fullPath)) {
1172
+ logger.warn({ path }, "Context PUT rejected — file exists, use PATCH to append");
1173
+ return c.json({
1174
+ error: "append_only",
1175
+ message: `${path} already exists. Use PATCH to append new sections.`,
1176
+ path,
1177
+ }, 409);
1178
+ }
1179
+ // Optimistic concurrency check: if client supplied expectedMtime,
1180
+ // compare against the current file. On mismatch, return 409 with
1181
+ // the current state so the UI can surface a conflict dialog without
1182
+ // a second round-trip.
1183
+ let snapshotId = null;
1184
+ let contentToWrite = preflight.content;
1185
+ if (existsSync(fullPath)) {
1186
+ const currentStat = statSync(fullPath);
1187
+ const currentMtime = currentStat.mtime.toISOString();
1188
+ const existing = readFileSync(fullPath, "utf-8");
1189
+ if (parsed.data.expectedMtime !== undefined &&
1190
+ parsed.data.expectedMtime !== currentMtime) {
1191
+ logger.info({ path, expectedMtime: parsed.data.expectedMtime, currentMtime }, "Context PUT conflict");
1192
+ return c.json({
1193
+ error: "conflict",
1194
+ currentMtime,
1195
+ currentContent: existing,
1196
+ }, 409);
1197
+ }
1198
+ const prepared = prepareContextContentForWrite(target, parsed.data.content, {
1199
+ timezone: config.timezone || undefined,
1200
+ disableRoadmapValidation: roadmapValidationOff,
1201
+ previousRoadmapContent: existing,
1202
+ today: localDateStr(new Date(), config.timezone || undefined),
1203
+ defaultLongTermPlanSource: roadmapDefaultLongTermPlanSource(c),
1204
+ expectedAgentDay,
1205
+ });
1206
+ if (!prepared.ok) {
1207
+ return c.json({
1208
+ error: "validation_error",
1209
+ message: prepared.message,
1210
+ path: prepared.path,
1211
+ }, prepared.status);
1212
+ }
1213
+ contentToWrite = prepared.content;
1214
+ snapshotId = saveSnapshot(path, existing, "api_put", true, sessionId);
1215
+ }
1216
+ else if (parsed.data.expectedMtime !== undefined) {
1217
+ // Client expected a specific mtime but the file is gone
1218
+ return c.json({
1219
+ error: "conflict",
1220
+ currentMtime: "",
1221
+ currentContent: "",
1222
+ }, 409);
1223
+ }
1224
+ // Symlink-safe atomic write — protects against a TOCTOU swap of
1225
+ // `fullPath` to a symlink between safePath validation and the write.
1226
+ writeFileAtomically(fullPath, contentToWrite);
1227
+ writeTracker?.markWriting(fullPath, contentToWrite);
1228
+ if (shouldRefreshPromptContext(path, "PUT")) {
1229
+ notifyPromptContextChanged(deps, path, `context_put:${path}`, { path, method: "PUT" });
1230
+ }
1231
+ if (path.startsWith("routines/custom/")) {
1232
+ deps.onCustomRoutinesChanged?.();
1233
+ }
1234
+ deps.onIndexableContextChange?.(`${path}${target.ext}`);
1235
+ const writtenStat = statSync(fullPath);
1236
+ logger.info({ path, method: "PUT", bytesWritten: writtenStat.size, snapshotId: snapshotId ?? undefined }, "Context file updated");
1237
+ return c.json({
1238
+ status: "updated",
1239
+ snapshotId: snapshotId ?? 0,
1240
+ lastModified: writtenStat.mtime.toISOString(),
1241
+ });
1242
+ });
1243
+ });
1244
+ // PATCH /context/* — Section operation
1245
+ app.patch("/context/*", async (c) => {
1246
+ const rawPath = c.req.path.replace("/api/context/", "");
1247
+ const target = resolveContextTarget(rawPath);
1248
+ const path = target.base;
1249
+ const contextDir = getCurrentContextDir();
1250
+ const fullPath = safePath(contextDir, rawPath);
1251
+ if (!fullPath) {
1252
+ return c.json({ error: "invalid_path", path }, 400);
1253
+ }
1254
+ if (!isWriteAllowed(path, "PATCH")) {
1255
+ logger.warn({ path, method: "PATCH" }, "Context write forbidden");
1256
+ return c.json({ error: "forbidden", path, method: "PATCH" }, 403);
1257
+ }
1258
+ // Morning Routine lock: reject writes to today while lock is held
1259
+ if (morningRoutineLock.getHolder() && path === "today") {
1260
+ const lockId = c.req.header("X-Lock-Id");
1261
+ if (!morningRoutineLock.isHeldBy(lockId)) {
1262
+ logger.info({ path }, "Context PATCH rejected — morning routine lock held");
1263
+ return c.json({ error: "morning_routine_lock_held" }, 409);
1264
+ }
1265
+ }
1266
+ // Roadmap write lock: reject writes to roadmap while another session holds it
1267
+ if (roadmapWriteLock.getHolder() && path === "roadmap") {
1268
+ const lockId = c.req.header("X-Lock-Id");
1269
+ if (!roadmapWriteLock.isHeldBy(lockId)) {
1270
+ logger.info({ path }, "Context PATCH rejected — roadmap write lock held");
1271
+ return c.json({ error: "roadmap_write_lock_held" }, 409);
1272
+ }
1273
+ }
1274
+ const parsedBody = await readJsonBody(c, { maxBytes: CONTEXT_BODY_MAX_BYTES });
1275
+ if (!parsedBody.ok)
1276
+ return parsedBody.response;
1277
+ const body = parsedBody.body;
1278
+ const parsed = contextPatchSchema.safeParse(body);
1279
+ if (!parsed.success) {
1280
+ return c.json({ error: "validation_error", details: parsed.error }, 400);
1281
+ }
1282
+ if (target.ext === ".base") {
1283
+ return c.json({
1284
+ error: "unsupported_operation",
1285
+ message: "PATCH is not supported for .base files; use PUT to replace the file.",
1286
+ }, 400);
1287
+ }
1288
+ const { section, mode, content: newContent, cutoff, maxEntries } = parsed.data;
1289
+ const sessionId = c.req.header("X-Session-Id");
1290
+ const roadmapValidationOff = isRoadmapValidationDisabled(path, c.req.header("X-Roadmap-Validation"));
1291
+ if (roadmapValidationOff) {
1292
+ logRoadmapValidationBypass(c, "PATCH", path);
1293
+ }
1294
+ const expectedAgentDay = path === "today"
1295
+ ? getAgentDayDateStr(config.timezone || undefined, config.dayBoundaryHour ?? 4)
1296
+ : undefined;
1297
+ return withWriteLock(() => {
1298
+ if (!existsSync(fullPath)) {
1299
+ return c.json({ error: "not_found", path }, 404);
1300
+ }
1301
+ const fileContent = readFileSync(fullPath, "utf-8");
1302
+ // ── append_to_file: append content to end of file (no section lookup) ──
1303
+ // Designed for agent/journal.md and similar append-only files where
1304
+ // each write adds a new top-level ## section rather than modifying
1305
+ // an existing one. Avoids the hack of targeting the last section's
1306
+ // body and injecting H2 headers inside it.
1307
+ if (mode === "append_to_file") {
1308
+ const separator = fileContent.endsWith("\n") ? "" : "\n";
1309
+ const updated = fileContent + separator + (newContent ?? "") + "\n";
1310
+ const prepared = prepareContextContentForWrite(target, updated, {
1311
+ timezone: config.timezone || undefined,
1312
+ disableRoadmapValidation: roadmapValidationOff,
1313
+ previousRoadmapContent: fileContent,
1314
+ today: localDateStr(new Date(), config.timezone || undefined),
1315
+ defaultLongTermPlanSource: roadmapDefaultLongTermPlanSource(c),
1316
+ allowLegacyToday: path === "today" && isLegacyTodayContent(fileContent),
1317
+ expectedAgentDay,
1318
+ });
1319
+ if (!prepared.ok) {
1320
+ return c.json({
1321
+ error: "validation_error",
1322
+ message: prepared.message,
1323
+ path: prepared.path,
1324
+ }, prepared.status);
1325
+ }
1326
+ saveSnapshot(path, fileContent, "api_patch", false, sessionId);
1327
+ writeFileAtomically(fullPath, prepared.content);
1328
+ writeTracker?.markWriting(fullPath, prepared.content);
1329
+ if (shouldRefreshPromptContext(path, "PATCH")) {
1330
+ notifyPromptContextChanged(deps, path, `context_patch:${path}`, {
1331
+ path,
1332
+ method: "PATCH",
1333
+ mode,
1334
+ section,
1335
+ content: newContent,
1336
+ previousContent: fileContent,
1337
+ });
1338
+ }
1339
+ if (path.startsWith("routines/custom/")) {
1340
+ deps.onCustomRoutinesChanged?.();
1341
+ }
1342
+ deps.onIndexableContextChange?.(`${path}${target.ext}`);
1343
+ logger.info({ path, method: "PATCH", mode }, "Content appended to file");
1344
+ return c.json({ status: "appended" });
1345
+ }
1346
+ // ── Section-based modes: require section lookup ──
1347
+ const sectionBounds = findSection(fileContent, section);
1348
+ if (!sectionBounds) {
1349
+ return c.json({
1350
+ error: "section_not_found",
1351
+ section,
1352
+ availableSections: getAvailableSections(fileContent),
1353
+ }, 400);
1354
+ }
1355
+ let updated;
1356
+ const before = fileContent.slice(0, sectionBounds.start);
1357
+ const after = fileContent.slice(sectionBounds.end);
1358
+ const currentBody = fileContent.slice(sectionBounds.start, sectionBounds.end);
1359
+ let removedCount;
1360
+ let trimmedCount;
1361
+ switch (mode) {
1362
+ case "append": {
1363
+ // Ensure a single newline separator without destroying existing content
1364
+ const separator = currentBody.endsWith("\n") ? "" : "\n";
1365
+ let appendedBody = currentBody + separator + (newContent ?? "") + "\n";
1366
+ // maxEntries: trim oldest bullet entries from the top
1367
+ if (maxEntries !== undefined) {
1368
+ const trimResult = trimBulletEntries(appendedBody, maxEntries);
1369
+ appendedBody = trimResult.body;
1370
+ trimmedCount = trimResult.trimmed;
1371
+ }
1372
+ updated = before + appendedBody + after;
1373
+ break;
1374
+ }
1375
+ case "replace":
1376
+ updated = before + (newContent ?? "") + "\n" + after;
1377
+ break;
1378
+ case "clear":
1379
+ updated = before + "\n" + after;
1380
+ break;
1381
+ case "clear_before": {
1382
+ // Schema refinements validate format, but defense-in-depth for
1383
+ // direct API callers that bypass schema validation.
1384
+ if (!cutoff || !/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(cutoff)) {
1385
+ return c.json({
1386
+ error: "cutoff_required",
1387
+ message: "clear_before requires cutoff in 'YYYY-MM-DD HH:MM:SS' format (zero-padded)",
1388
+ }, 400);
1389
+ }
1390
+ const clearResult = clearEntriesBefore(currentBody, cutoff);
1391
+ updated = before + clearResult.remaining + after;
1392
+ removedCount = clearResult.removedCount;
1393
+ break;
1394
+ }
1395
+ }
1396
+ const prepared = prepareContextContentForWrite(target, updated, {
1397
+ timezone: config.timezone || undefined,
1398
+ disableRoadmapValidation: roadmapValidationOff,
1399
+ previousRoadmapContent: fileContent,
1400
+ today: localDateStr(new Date(), config.timezone || undefined),
1401
+ defaultLongTermPlanSource: roadmapDefaultLongTermPlanSource(c),
1402
+ allowLegacyToday: path === "today" && isLegacyTodayContent(fileContent),
1403
+ expectedAgentDay,
1404
+ });
1405
+ if (!prepared.ok) {
1406
+ return c.json({
1407
+ error: "validation_error",
1408
+ message: prepared.message,
1409
+ path: prepared.path,
1410
+ }, prepared.status);
1411
+ }
1412
+ // Force snapshot on replace (bypass debounce) to ensure recovery
1413
+ // from accidental overwrites. Other modes use normal debounce.
1414
+ const forceSnapshot = mode === "replace" || mode === "clear" || mode === "clear_before";
1415
+ saveSnapshot(path, fileContent, "api_patch", forceSnapshot, sessionId);
1416
+ writeFileAtomically(fullPath, prepared.content);
1417
+ writeTracker?.markWriting(fullPath, prepared.content);
1418
+ if (shouldRefreshPromptContext(path, "PATCH")) {
1419
+ notifyPromptContextChanged(deps, path, `context_patch:${path}`, {
1420
+ path,
1421
+ method: "PATCH",
1422
+ mode,
1423
+ section,
1424
+ content: newContent,
1425
+ previousContent: fileContent,
1426
+ });
1427
+ }
1428
+ if (path.startsWith("routines/custom/")) {
1429
+ deps.onCustomRoutinesChanged?.();
1430
+ }
1431
+ deps.onIndexableContextChange?.(`${path}${target.ext}`);
1432
+ const resultStatus = mode === "append" ? "appended" : mode === "replace" ? "replaced" : "cleared";
1433
+ logger.info({ path, method: "PATCH", section, mode, removedCount, trimmedCount }, "Context section " + resultStatus);
1434
+ return c.json({ status: resultStatus, removedCount, trimmedCount });
1435
+ });
1436
+ });
1437
+ // DELETE /context/* — File delete (currently limited to `routines/custom/*`
1438
+ // via the write-permission whitelist). B-007 §5.8 Q3: the agent retires a
1439
+ // custom routine after the user confirms. The scheduler listens via
1440
+ // `onCustomRoutinesChanged` and unregisters the cron job on reload.
1441
+ app.delete("/context/*", (c) => {
1442
+ const path = normalizeContextPath(c.req.path.replace("/api/context/", ""));
1443
+ const contextDir = getCurrentContextDir();
1444
+ const fullPath = safePath(contextDir, path);
1445
+ if (!fullPath) {
1446
+ return c.json({ error: "invalid_path", path }, 400);
1447
+ }
1448
+ if (!isWriteAllowed(path, "DELETE")) {
1449
+ logger.warn({ path, method: "DELETE" }, "Context delete forbidden");
1450
+ return c.json({ error: "forbidden", path, method: "DELETE" }, 403);
1451
+ }
1452
+ return withWriteLock(() => {
1453
+ if (!existsSync(fullPath)) {
1454
+ return c.json({ error: "not_found", path }, 404);
1455
+ }
1456
+ const existing = readFileSync(fullPath, "utf-8");
1457
+ const snapshotId = saveSnapshot(path, existing, "api_delete", true);
1458
+ unlinkSync(fullPath);
1459
+ if (path.startsWith("routines/custom/")) {
1460
+ deps.onCustomRoutinesChanged?.();
1461
+ }
1462
+ deps.onIndexableContextChange?.(path);
1463
+ logger.info({ path, method: "DELETE", snapshotId: snapshotId ?? undefined }, "Context file deleted");
1464
+ return c.json({ status: "deleted", snapshotId: snapshotId ?? 0 });
1465
+ });
1466
+ });
1467
+ return app;
1468
+ }
1469
+ function validateContextContent(target, content, options) {
1470
+ if (target.base === "today") {
1471
+ const message = validateTodayContent(content, {
1472
+ allowLegacyToday: options?.allowLegacyToday ?? false,
1473
+ expectedAgentDay: options?.expectedAgentDay,
1474
+ });
1475
+ return message ? { message, status: 400 } : null;
1476
+ }
1477
+ if (target.base === "roadmap") {
1478
+ const result = validateRoadmap(content);
1479
+ if (!result.ok && result.error) {
1480
+ return {
1481
+ message: formatRoadmapValidationError(result.error),
1482
+ status: 400,
1483
+ path: result.error.path,
1484
+ };
1485
+ }
1486
+ return null;
1487
+ }
1488
+ if (target.base.startsWith("routines/custom/")) {
1489
+ const slug = target.base.slice("routines/custom/".length);
1490
+ const result = parseCustomRoutineSpec(slug, content);
1491
+ if (!result.ok) {
1492
+ return {
1493
+ message: explainCustomRoutineValidationError(result.error),
1494
+ status: 400,
1495
+ };
1496
+ }
1497
+ return null;
1498
+ }
1499
+ if (target.base.startsWith("routines/") && target.base !== "routines/_index") {
1500
+ const message = validateBuiltInRoutineRulebook(target.base, content);
1501
+ return message ? { message, status: 400 } : null;
1502
+ }
1503
+ const relativePath = `${target.base}${target.ext}`;
1504
+ if (!options?.skipFrontmatterValidation) {
1505
+ const frontmatterError = validateContextFileFrontmatter(content, relativePath);
1506
+ if (frontmatterError) {
1507
+ return { message: frontmatterError.message, status: 422 };
1508
+ }
1509
+ }
1510
+ if (target.ext !== ".base")
1511
+ return null;
1512
+ const message = validateBaseYamlSyntax(content);
1513
+ return message ? { message, status: 400 } : null;
1514
+ }
1515
+ const TODAY_REQUIRED_SECTIONS = [
1516
+ "User Schedule",
1517
+ "User Tasks",
1518
+ "Agent Plan",
1519
+ "Agent Notes",
1520
+ "Agent Log",
1521
+ "Handoff",
1522
+ ];
1523
+ const TODAY_H1_RE = /^# \d{4}-\d{2}-\d{2}(?: \([^)]+\))?$/;
1524
+ const TODAY_DAY_TYPE_RE = /^> Day type: (Weekday|Weekend) \| Work focus: (on|off) \| Study focus: (on|off) \| Personal focus: (on|off)$/;
1525
+ function isLegacyTodayContent(content) {
1526
+ const lines = content.split(/\r?\n/);
1527
+ return (lines[0] ?? "").trim() === "# Today";
1528
+ }
1529
+ function validateTodayContent(content, options = {}) {
1530
+ if (options.allowLegacyToday && isLegacyTodayContent(content))
1531
+ return null;
1532
+ const lines = content.split(/\r?\n/);
1533
+ const firstLine = (lines[0] ?? "").trim();
1534
+ if (!TODAY_H1_RE.test(firstLine)) {
1535
+ return "today.md line 1 must be `# YYYY-MM-DD (day-of-week)`.";
1536
+ }
1537
+ if (!TODAY_DAY_TYPE_RE.test((lines[1] ?? "").trim())) {
1538
+ return "today.md line 2 must be `> Day type: Weekday|Weekend | Work focus: on|off | Study focus: on|off | Personal focus: on|off`.";
1539
+ }
1540
+ // Agent-day-date check — rejects wrong-date H1 with a clear error echoing
1541
+ // both values. Without this, a wrong-date PUT silently succeeds (regex
1542
+ // passes) and the dispatcher's post-run hasCurrentAgentDayTodayMd() check
1543
+ // schedules a retry while the same session still has the prompt context
1544
+ // loaded, wasting a heavy-tier turn cycle. With this guard the agent gets
1545
+ // immediate feedback and corrects in-session.
1546
+ if (options.expectedAgentDay) {
1547
+ // TODAY_H1_RE already matched, so the YYYY-MM-DD capture is guaranteed.
1548
+ // No optional-chain — the regex precondition guarantees `[1]` is set.
1549
+ const writtenDate = firstLine.match(/^# (\d{4}-\d{2}-\d{2})/)[1];
1550
+ if (writtenDate !== options.expectedAgentDay) {
1551
+ return (`today.md line 1 date '${writtenDate}' does not match the current ` +
1552
+ `agent-day date '${options.expectedAgentDay}'. ` +
1553
+ `Use the date from <current_agent_day date="..."> in your prompt context — ` +
1554
+ `the agent-day differs from calendar today before the day-boundary hour.`);
1555
+ }
1556
+ }
1557
+ let previousSectionIndex = 1;
1558
+ for (const section of TODAY_REQUIRED_SECTIONS) {
1559
+ const index = lines.findIndex((line, lineIndex) => lineIndex > previousSectionIndex && line.trim() === `## ${section}`);
1560
+ if (index < 0) {
1561
+ return `today.md requires \`## ${section}\` in canonical order.`;
1562
+ }
1563
+ previousSectionIndex = index;
1564
+ }
1565
+ const parsed = extractTodayAgentPlanRows(content);
1566
+ if (parsed.invalidRows.length > 0) {
1567
+ const first = parsed.invalidRows[0];
1568
+ return (`today.md Agent Plan line ${first.line} must match ` +
1569
+ `\`- [ ] HH:MM <action> [work|study|personal|home] →DM|→notify|→check-in|→wake\`. ` +
1570
+ `Got: ${JSON.stringify(first.raw)}`);
1571
+ }
1572
+ return null;
1573
+ }
1574
+ function toTodayScheduleCandidate(row, timezone) {
1575
+ const scheduledAt = parseScheduleDate(row.scheduled_for);
1576
+ if (Number.isNaN(scheduledAt.getTime()))
1577
+ return null;
1578
+ const local = nowInTimezone(timezone, scheduledAt);
1579
+ const localDate = `${local.year}-${String(local.month).padStart(2, "0")}-${String(local.day).padStart(2, "0")}`;
1580
+ const localTime = `${String(local.hours).padStart(2, "0")}:${String(local.minutes).padStart(2, "0")}`;
1581
+ return {
1582
+ id: row.id,
1583
+ scheduledFor: row.scheduled_for,
1584
+ localDate,
1585
+ localTime,
1586
+ taskType: row.task_type,
1587
+ status: row.status,
1588
+ description: row.task_description,
1589
+ taskContext: parseJsonObject(row.task_context),
1590
+ };
1591
+ }
1592
+ function parseScheduleDate(value) {
1593
+ return new Date(value.includes("T") ? value : value.replace(" ", "T") + "Z");
1594
+ }
1595
+ function parseJsonObject(raw) {
1596
+ if (!raw)
1597
+ return {};
1598
+ try {
1599
+ const parsed = JSON.parse(raw);
1600
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
1601
+ return parsed;
1602
+ }
1603
+ }
1604
+ catch {
1605
+ // Ignore corrupt metadata for reconciliation diagnostics.
1606
+ }
1607
+ return {};
1608
+ }
1609
+ function prepareContextContentForWrite(target, content, options) {
1610
+ if (target.base !== "roadmap") {
1611
+ const contentError = validateContextContent(target, content, {
1612
+ allowLegacyToday: options?.allowLegacyToday,
1613
+ expectedAgentDay: options?.expectedAgentDay,
1614
+ });
1615
+ if (contentError) {
1616
+ return {
1617
+ ok: false,
1618
+ message: contentError.message,
1619
+ status: contentError.status,
1620
+ path: contentError.path,
1621
+ };
1622
+ }
1623
+ return { ok: true, content };
1624
+ }
1625
+ if (options?.disableRoadmapValidation) {
1626
+ return { ok: true, content };
1627
+ }
1628
+ const normalized = normalizeRoadmapForWrite(content, {
1629
+ timezone: options?.timezone,
1630
+ defaultLongTermPlanSource: options?.defaultLongTermPlanSource ?? "manual",
1631
+ });
1632
+ const result = validateRoadmap(normalized.content);
1633
+ if (!result.ok && result.error) {
1634
+ return {
1635
+ ok: false,
1636
+ message: formatRoadmapValidationError(result.error),
1637
+ status: 400,
1638
+ path: result.error.path,
1639
+ };
1640
+ }
1641
+ if (options?.previousRoadmapContent !== undefined) {
1642
+ const transition = validateRoadmapTransition(options.previousRoadmapContent, normalized.content, {
1643
+ today: options.today,
1644
+ timezone: options.timezone,
1645
+ });
1646
+ if (!transition.ok && transition.error) {
1647
+ return {
1648
+ ok: false,
1649
+ message: formatRoadmapValidationError(transition.error),
1650
+ status: 400,
1651
+ path: transition.error.path,
1652
+ };
1653
+ }
1654
+ }
1655
+ return { ok: true, content: normalized.content };
1656
+ }
1657
+ function formatRoadmapValidationError(error) {
1658
+ const line = error.line ? `line ${error.line}: ` : "";
1659
+ return `${line}${error.message}`;
1660
+ }
1661
+ function validateBuiltInRoutineRulebook(path, content) {
1662
+ const frontmatter = extractRoutineFrontmatter(content);
1663
+ if (frontmatter === null) {
1664
+ return "Routine rulebooks require YAML frontmatter.";
1665
+ }
1666
+ const expectedSlug = path.slice("routines/".length);
1667
+ const typeRaw = readRoutineFrontmatterScalar(frontmatter, "type");
1668
+ if (!typeRaw) {
1669
+ return "Routine rulebooks require `type: rule` in frontmatter.";
1670
+ }
1671
+ if (typeRaw !== "rule") {
1672
+ return "Routine rulebooks must declare `type: rule`.";
1673
+ }
1674
+ const slugRaw = readRoutineFrontmatterScalar(frontmatter, "slug");
1675
+ if (!slugRaw) {
1676
+ return "Routine rulebooks require a `slug` frontmatter field.";
1677
+ }
1678
+ if (slugRaw !== expectedSlug) {
1679
+ return `Routine rulebook slug must match the filename (${expectedSlug}).`;
1680
+ }
1681
+ if (!/^##\s+Checks\s*$/m.test(content)) {
1682
+ return "Routine rulebooks require a `## Checks` section.";
1683
+ }
1684
+ return null;
1685
+ }
1686
+ function explainCustomRoutineValidationError(error) {
1687
+ switch (error.kind) {
1688
+ case "missing_field":
1689
+ return `Custom routine files require \`${error.field}\` in frontmatter.`;
1690
+ case "invalid_cron":
1691
+ return `Invalid cron expression: \`${error.value}\`.`;
1692
+ case "invalid_slug":
1693
+ return `Custom routine slug is invalid or does not match the filename: \`${error.value}\`.`;
1694
+ case "invalid_type":
1695
+ return `Custom routines must declare \`type: rule\`, got \`${error.value}\`.`;
1696
+ case "invalid_process_key":
1697
+ return `Custom routine \`process_key\` must match the filename-derived key, got \`${error.value}\`.`;
1698
+ case "invalid_enabled":
1699
+ return `Custom routine \`enabled\` must be \`true\` or \`false\`, got \`${error.value}\`.`;
1700
+ case "invalid_tier":
1701
+ return `Custom routine \`backend_tier\` must be \`light\` or \`heavy\`, got \`${error.value}\`.`;
1702
+ case "invalid_budget":
1703
+ return `Custom routine \`max_budget_usd\` must be a positive number, got \`${error.value}\`.`;
1704
+ case "missing_checks_section":
1705
+ return "Custom routines require a `## Checks` section.";
1706
+ case "no_frontmatter":
1707
+ return "Custom routines require YAML frontmatter.";
1708
+ }
1709
+ }
1710
+ function extractRoutineFrontmatter(content) {
1711
+ if (!content.startsWith("---\n") && !content.startsWith("---\r\n")) {
1712
+ return null;
1713
+ }
1714
+ const afterOpen = content.startsWith("---\r\n") ? 5 : 4;
1715
+ const endIdx = content.indexOf("\n---", afterOpen - 1);
1716
+ if (endIdx < 0)
1717
+ return null;
1718
+ return content.slice(afterOpen, endIdx);
1719
+ }
1720
+ function readRoutineFrontmatterScalar(frontmatter, field) {
1721
+ const re = new RegExp(`^${field}\\s*:\\s*(.+?)\\s*$`, "m");
1722
+ const match = frontmatter.match(re);
1723
+ if (!match)
1724
+ return null;
1725
+ let value = match[1].trim();
1726
+ if ((value.startsWith('"') && value.endsWith('"')) ||
1727
+ (value.startsWith("'") && value.endsWith("'"))) {
1728
+ value = value.slice(1, -1);
1729
+ }
1730
+ return value;
1731
+ }
1732
+ function validateBaseYamlSyntax(content) {
1733
+ if (content.trim().length === 0) {
1734
+ return ".base files must not be empty.";
1735
+ }
1736
+ const lines = content.split("\n");
1737
+ let sawMeaningfulLine = false;
1738
+ for (let index = 0; index < lines.length; index++) {
1739
+ const raw = lines[index];
1740
+ const lineNo = index + 1;
1741
+ if (raw.includes("\t")) {
1742
+ return `.base YAML may not contain tab indentation (line ${lineNo}).`;
1743
+ }
1744
+ const trimmed = raw.trim();
1745
+ if (!trimmed || trimmed.startsWith("#"))
1746
+ continue;
1747
+ sawMeaningfulLine = true;
1748
+ const indent = raw.length - raw.trimStart().length;
1749
+ if (indent % 2 !== 0) {
1750
+ return `.base YAML uses 2-space indentation (line ${lineNo}).`;
1751
+ }
1752
+ const isListItem = /^-\s+\S/.test(trimmed);
1753
+ const isMapping = /^[^:#][^:]*:\s*(?:.*)?$/.test(trimmed);
1754
+ if (!isListItem && !isMapping) {
1755
+ return `Invalid .base YAML structure on line ${lineNo}.`;
1756
+ }
1757
+ }
1758
+ if (!sawMeaningfulLine) {
1759
+ return ".base files must contain at least one mapping entry.";
1760
+ }
1761
+ return null;
1762
+ }
1763
+ // Export for testing
1764
+ export { normalizeSection, findSection, isWriteAllowed, safePath, resolveContextTarget, validateBaseYamlSyntax, validateTodayContent, clearEntriesBefore, trimBulletEntries, parseEntryTimestamp, };
1765
+ //# sourceMappingURL=context.js.map