@xingular/harness 0.1.7 → 1.0.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 (683) hide show
  1. package/CHANGELOG.md +97 -1
  2. package/LICENSE +202 -0
  3. package/NOTICE.md +22 -0
  4. package/README.md +187 -85
  5. package/THIRD_PARTY_LICENSES.md +942 -0
  6. package/dist/cli.js +13701 -13498
  7. package/dist/sdk/accounts/accounts.d.ts +165 -0
  8. package/dist/sdk/accounts/accounts.js +730 -0
  9. package/dist/sdk/accounts/choices.d.ts +23 -0
  10. package/dist/sdk/accounts/choices.js +62 -0
  11. package/dist/sdk/accounts/env.d.ts +78 -0
  12. package/dist/sdk/accounts/env.js +294 -0
  13. package/dist/sdk/accounts/secrets.d.ts +16 -0
  14. package/dist/sdk/accounts/secrets.js +40 -0
  15. package/dist/sdk/accounts/store.d.ts +114 -0
  16. package/dist/sdk/accounts/store.js +255 -0
  17. package/dist/sdk/browser/config.d.ts +16 -0
  18. package/dist/sdk/browser/config.js +22 -0
  19. package/dist/sdk/browser/diagnostics.d.ts +4 -0
  20. package/dist/sdk/browser/diagnostics.js +38 -0
  21. package/dist/sdk/browser/index.d.ts +17 -0
  22. package/dist/sdk/browser/index.js +65 -0
  23. package/dist/sdk/browser/network.d.ts +10 -0
  24. package/dist/sdk/browser/network.js +59 -0
  25. package/dist/sdk/browser/session.d.ts +84 -0
  26. package/dist/sdk/browser/session.js +192 -0
  27. package/dist/sdk/browser/tools.d.ts +8 -0
  28. package/dist/sdk/browser/tools.js +329 -0
  29. package/dist/sdk/capabilities/api.d.ts +22 -0
  30. package/dist/sdk/capabilities/api.js +54 -0
  31. package/dist/sdk/capabilities/runSnapshot.d.ts +18 -0
  32. package/dist/sdk/capabilities/runSnapshot.js +47 -0
  33. package/dist/sdk/capabilities/types.d.ts +29 -0
  34. package/dist/sdk/capabilities/types.js +1 -0
  35. package/dist/sdk/cli.d.ts +2 -0
  36. package/dist/sdk/cli.js +142 -0
  37. package/dist/sdk/core/bus.d.ts +23 -0
  38. package/dist/sdk/core/bus.js +76 -0
  39. package/dist/sdk/core/caller.d.ts +22 -0
  40. package/dist/sdk/core/caller.js +16 -0
  41. package/dist/sdk/core/changes.d.ts +15 -0
  42. package/dist/sdk/core/changes.js +15 -0
  43. package/dist/sdk/core/effort.d.ts +2 -0
  44. package/dist/sdk/core/effort.js +1 -0
  45. package/dist/sdk/core/env.d.ts +18 -0
  46. package/dist/sdk/core/env.js +8 -0
  47. package/dist/sdk/core/errors.d.ts +15 -0
  48. package/dist/sdk/core/errors.js +24 -0
  49. package/dist/sdk/core/frontmatter.d.ts +12 -0
  50. package/dist/sdk/core/frontmatter.js +50 -0
  51. package/dist/sdk/core/fs.d.ts +18 -0
  52. package/dist/sdk/core/fs.js +106 -0
  53. package/dist/sdk/core/index.d.ts +24 -0
  54. package/dist/sdk/core/index.js +187 -0
  55. package/dist/sdk/core/path.d.ts +7 -0
  56. package/dist/sdk/core/path.js +79 -0
  57. package/dist/sdk/core/projects.d.ts +18 -0
  58. package/dist/sdk/core/projects.js +67 -0
  59. package/dist/sdk/core/secrets.d.ts +2 -0
  60. package/dist/sdk/core/secrets.js +5 -0
  61. package/dist/sdk/core/text.d.ts +7 -0
  62. package/dist/sdk/core/text.js +40 -0
  63. package/dist/sdk/doctor/checks.d.ts +5 -0
  64. package/dist/sdk/doctor/checks.js +208 -0
  65. package/dist/sdk/doctor/probe.d.ts +4 -0
  66. package/dist/sdk/doctor/probe.js +92 -0
  67. package/dist/sdk/doctor/service.d.ts +23 -0
  68. package/dist/sdk/doctor/service.js +144 -0
  69. package/dist/sdk/doctor/types.d.ts +141 -0
  70. package/dist/sdk/doctor/types.js +29 -0
  71. package/dist/sdk/harness.d.ts +133 -0
  72. package/dist/sdk/harness.js +299 -0
  73. package/dist/sdk/history/lessonPrompt.d.ts +2 -0
  74. package/dist/sdk/history/lessonPrompt.js +15 -0
  75. package/dist/sdk/history/lessons.d.ts +52 -0
  76. package/dist/sdk/history/lessons.js +173 -0
  77. package/dist/sdk/history/recall.d.ts +68 -0
  78. package/dist/sdk/history/recall.js +199 -0
  79. package/dist/sdk/history/trajectory.d.ts +7 -0
  80. package/dist/sdk/history/trajectory.js +216 -0
  81. package/dist/sdk/hub/catalog.json +123 -0
  82. package/dist/sdk/hub/cli.d.ts +7 -0
  83. package/dist/sdk/hub/cli.js +81 -0
  84. package/dist/sdk/hub/hub.d.ts +74 -0
  85. package/dist/sdk/hub/hub.js +474 -0
  86. package/dist/sdk/hub/schema.d.ts +280 -0
  87. package/dist/sdk/hub/schema.js +78 -0
  88. package/dist/sdk/index.d.ts +63 -0
  89. package/dist/sdk/index.js +48 -0
  90. package/dist/sdk/mcp/connections.d.ts +83 -0
  91. package/dist/sdk/mcp/connections.js +669 -0
  92. package/dist/sdk/mcp/manager.d.ts +26 -0
  93. package/dist/sdk/mcp/manager.js +124 -0
  94. package/dist/sdk/mcp/oauth.d.ts +35 -0
  95. package/dist/sdk/mcp/oauth.js +171 -0
  96. package/dist/sdk/mcp/scopeMigration.d.ts +19 -0
  97. package/dist/sdk/mcp/scopeMigration.js +198 -0
  98. package/dist/sdk/mcp/service.d.ts +160 -0
  99. package/dist/sdk/mcp/service.js +510 -0
  100. package/dist/sdk/mcp/types.d.ts +131 -0
  101. package/dist/sdk/mcp/types.js +49 -0
  102. package/dist/sdk/pi/runtime.d.ts +13 -0
  103. package/dist/sdk/pi/runtime.js +31 -0
  104. package/dist/sdk/plugins/api.d.ts +66 -0
  105. package/dist/sdk/plugins/api.js +155 -0
  106. package/dist/sdk/plugins/attachments.d.ts +46 -0
  107. package/dist/sdk/plugins/attachments.js +111 -0
  108. package/dist/sdk/plugins/builtin.d.ts +6 -0
  109. package/dist/sdk/plugins/builtin.js +68 -0
  110. package/dist/sdk/plugins/catalogue.d.ts +29 -0
  111. package/dist/sdk/plugins/catalogue.js +196 -0
  112. package/dist/sdk/plugins/cli.d.ts +13 -0
  113. package/dist/sdk/plugins/cli.js +187 -0
  114. package/dist/sdk/plugins/discover.d.ts +42 -0
  115. package/dist/sdk/plugins/discover.js +115 -0
  116. package/dist/sdk/plugins/firstParty.d.ts +50 -0
  117. package/dist/sdk/plugins/firstParty.js +113 -0
  118. package/dist/sdk/plugins/hooks.d.ts +94 -0
  119. package/dist/sdk/plugins/hooks.js +162 -0
  120. package/dist/sdk/plugins/identity.d.ts +19 -0
  121. package/dist/sdk/plugins/identity.js +48 -0
  122. package/dist/sdk/plugins/install.d.ts +20 -0
  123. package/dist/sdk/plugins/install.js +110 -0
  124. package/dist/sdk/plugins/inventory.d.ts +22 -0
  125. package/dist/sdk/plugins/inventory.js +110 -0
  126. package/dist/sdk/plugins/manifest.d.ts +13 -0
  127. package/dist/sdk/plugins/manifest.js +56 -0
  128. package/dist/sdk/plugins/plugins.d.ts +104 -0
  129. package/dist/sdk/plugins/plugins.js +164 -0
  130. package/dist/sdk/plugins/runtime.d.ts +9 -0
  131. package/dist/sdk/plugins/runtime.js +95 -0
  132. package/dist/sdk/plugins/trust.d.ts +44 -0
  133. package/dist/sdk/plugins/trust.js +120 -0
  134. package/dist/sdk/plugins/types.d.ts +159 -0
  135. package/dist/sdk/plugins/types.js +7 -0
  136. package/dist/sdk/prompt/compile.d.ts +174 -0
  137. package/dist/sdk/prompt/compile.js +396 -0
  138. package/dist/sdk/refine/cli.d.ts +4 -0
  139. package/dist/sdk/refine/cli.js +186 -0
  140. package/dist/sdk/refine/demo.d.ts +21 -0
  141. package/dist/sdk/refine/demo.js +114 -0
  142. package/dist/sdk/refine/evidence.d.ts +55 -0
  143. package/dist/sdk/refine/evidence.js +330 -0
  144. package/dist/sdk/refine/host.d.ts +51 -0
  145. package/dist/sdk/refine/host.js +76 -0
  146. package/dist/sdk/refine/ledger.d.ts +48 -0
  147. package/dist/sdk/refine/ledger.js +76 -0
  148. package/dist/sdk/refine/library.d.ts +55 -0
  149. package/dist/sdk/refine/library.js +177 -0
  150. package/dist/sdk/refine/pi.d.ts +72 -0
  151. package/dist/sdk/refine/pi.js +248 -0
  152. package/dist/sdk/refine/prompts.d.ts +45 -0
  153. package/dist/sdk/refine/prompts.js +390 -0
  154. package/dist/sdk/refine/recursion.d.ts +113 -0
  155. package/dist/sdk/refine/recursion.js +258 -0
  156. package/dist/sdk/refine/runner.d.ts +81 -0
  157. package/dist/sdk/refine/runner.js +150 -0
  158. package/dist/sdk/refine/selection.d.ts +57 -0
  159. package/dist/sdk/refine/selection.js +251 -0
  160. package/dist/sdk/refine/service.d.ts +84 -0
  161. package/dist/sdk/refine/service.js +165 -0
  162. package/dist/sdk/refine/suite.d.ts +67 -0
  163. package/dist/sdk/refine/suite.js +174 -0
  164. package/dist/sdk/refine/trajectory.d.ts +9 -0
  165. package/dist/sdk/refine/trajectory.js +68 -0
  166. package/dist/sdk/refine/types.d.ts +77 -0
  167. package/dist/sdk/refine/types.js +10 -0
  168. package/dist/sdk/server/methods.d.ts +3 -0
  169. package/dist/sdk/server/methods.js +370 -0
  170. package/dist/sdk/server/remote.d.ts +19 -0
  171. package/dist/sdk/server/remote.js +84 -0
  172. package/dist/sdk/server/rpc.d.ts +20 -0
  173. package/dist/sdk/server/rpc.js +102 -0
  174. package/dist/sdk/server/serve.d.ts +10 -0
  175. package/dist/sdk/server/serve.js +18 -0
  176. package/dist/sdk/sessions/approvals.d.ts +47 -0
  177. package/dist/sdk/sessions/approvals.js +119 -0
  178. package/dist/sdk/sessions/continuation.d.ts +48 -0
  179. package/dist/sdk/sessions/continuation.js +85 -0
  180. package/dist/sdk/sessions/contracts.d.ts +534 -0
  181. package/dist/sdk/sessions/contracts.js +299 -0
  182. package/dist/sdk/sessions/extensionUi.d.ts +19 -0
  183. package/dist/sdk/sessions/extensionUi.js +64 -0
  184. package/dist/sdk/sessions/history.d.ts +16 -0
  185. package/dist/sdk/sessions/history.js +68 -0
  186. package/dist/sdk/sessions/lineageJoin.d.ts +2 -0
  187. package/dist/sdk/sessions/lineageJoin.js +61 -0
  188. package/dist/sdk/sessions/planMode.d.ts +36 -0
  189. package/dist/sdk/sessions/planMode.js +84 -0
  190. package/dist/sdk/sessions/policy.d.ts +43 -0
  191. package/dist/sdk/sessions/policy.js +1 -0
  192. package/dist/sdk/sessions/pricing.d.ts +34 -0
  193. package/dist/sdk/sessions/pricing.js +40 -0
  194. package/dist/sdk/sessions/reasoningSummaries.d.ts +11 -0
  195. package/dist/sdk/sessions/reasoningSummaries.js +61 -0
  196. package/dist/sdk/sessions/registry.d.ts +102 -0
  197. package/dist/sdk/sessions/registry.js +383 -0
  198. package/dist/sdk/sessions/runIndex.d.ts +21 -0
  199. package/dist/sdk/sessions/runIndex.js +65 -0
  200. package/dist/sdk/sessions/runStore.d.ts +66 -0
  201. package/dist/sdk/sessions/runStore.js +335 -0
  202. package/dist/sdk/sessions/runner.d.ts +213 -0
  203. package/dist/sdk/sessions/runner.js +589 -0
  204. package/dist/sdk/sessions/sessions.d.ts +140 -0
  205. package/dist/sdk/sessions/sessions.js +394 -0
  206. package/dist/sdk/sessions/subagentService.d.ts +41 -0
  207. package/dist/sdk/sessions/subagentService.js +247 -0
  208. package/dist/sdk/sessions/subagents.d.ts +50 -0
  209. package/dist/sdk/sessions/subagents.js +68 -0
  210. package/dist/sdk/terminal/accountsMenu.d.ts +46 -0
  211. package/dist/sdk/terminal/accountsMenu.js +392 -0
  212. package/dist/sdk/terminal/cli.d.ts +20 -0
  213. package/dist/sdk/terminal/cli.js +121 -0
  214. package/dist/sdk/terminal/client.d.ts +15 -0
  215. package/dist/sdk/terminal/client.js +126 -0
  216. package/dist/sdk/terminal/control.d.ts +4 -0
  217. package/dist/sdk/terminal/control.js +25 -0
  218. package/dist/sdk/terminal/controller.d.ts +72 -0
  219. package/dist/sdk/terminal/controller.js +351 -0
  220. package/dist/sdk/terminal/hubMenu.d.ts +10 -0
  221. package/dist/sdk/terminal/hubMenu.js +34 -0
  222. package/dist/sdk/terminal/launch.d.ts +5 -0
  223. package/dist/sdk/terminal/launch.js +27 -0
  224. package/dist/sdk/terminal/logs.d.ts +14 -0
  225. package/dist/sdk/terminal/logs.js +59 -0
  226. package/dist/sdk/terminal/piExtension.d.ts +6 -0
  227. package/dist/sdk/terminal/piExtension.js +392 -0
  228. package/dist/sdk/terminal/pluginMenu.d.ts +34 -0
  229. package/dist/sdk/terminal/pluginMenu.js +101 -0
  230. package/dist/sdk/terminal/socket.d.ts +70 -0
  231. package/dist/sdk/terminal/socket.js +256 -0
  232. package/dist/sdk/terminal/standalone.d.ts +18 -0
  233. package/dist/sdk/terminal/standalone.js +146 -0
  234. package/dist/sdk/terminal/terminals.d.ts +176 -0
  235. package/dist/sdk/terminal/terminals.js +767 -0
  236. package/dist/sdk/terminal/trajectory.d.ts +10 -0
  237. package/dist/sdk/terminal/trajectory.js +30 -0
  238. package/dist/sdk/terminal/tui/chrome.d.ts +64 -0
  239. package/dist/sdk/terminal/tui/chrome.js +169 -0
  240. package/dist/sdk/terminal/tui/clipboardFiles.d.ts +11 -0
  241. package/dist/sdk/terminal/tui/clipboardFiles.js +74 -0
  242. package/dist/sdk/terminal/tui/commandPages.d.ts +7 -0
  243. package/dist/sdk/terminal/tui/commandPages.js +63 -0
  244. package/dist/sdk/terminal/tui/commands.d.ts +42 -0
  245. package/dist/sdk/terminal/tui/commands.js +276 -0
  246. package/dist/sdk/terminal/tui/dialogGeometry.d.ts +27 -0
  247. package/dist/sdk/terminal/tui/dialogGeometry.js +50 -0
  248. package/dist/sdk/terminal/tui/dialogs.d.ts +75 -0
  249. package/dist/sdk/terminal/tui/dialogs.js +363 -0
  250. package/dist/sdk/terminal/tui/keybindings.d.ts +11 -0
  251. package/dist/sdk/terminal/tui/keybindings.js +49 -0
  252. package/dist/sdk/terminal/tui/list.d.ts +73 -0
  253. package/dist/sdk/terminal/tui/list.js +196 -0
  254. package/dist/sdk/terminal/tui/modeChoices.d.ts +42 -0
  255. package/dist/sdk/terminal/tui/modeChoices.js +70 -0
  256. package/dist/sdk/terminal/tui/modelPicker.d.ts +55 -0
  257. package/dist/sdk/terminal/tui/modelPicker.js +155 -0
  258. package/dist/sdk/terminal/tui/mouse.d.ts +3 -0
  259. package/dist/sdk/terminal/tui/mouse.js +3 -0
  260. package/dist/sdk/terminal/tui/page.d.ts +14 -0
  261. package/dist/sdk/terminal/tui/page.js +1 -0
  262. package/dist/sdk/terminal/tui/pageOverlay.d.ts +27 -0
  263. package/dist/sdk/terminal/tui/pageOverlay.js +145 -0
  264. package/dist/sdk/terminal/tui/pages/accountsPage.d.ts +54 -0
  265. package/dist/sdk/terminal/tui/pages/accountsPage.js +181 -0
  266. package/dist/sdk/terminal/tui/pages/componentsPage.d.ts +47 -0
  267. package/dist/sdk/terminal/tui/pages/componentsPage.js +119 -0
  268. package/dist/sdk/terminal/tui/pages/doctorPage.d.ts +37 -0
  269. package/dist/sdk/terminal/tui/pages/doctorPage.js +145 -0
  270. package/dist/sdk/terminal/tui/pages/hubPage.d.ts +39 -0
  271. package/dist/sdk/terminal/tui/pages/hubPage.js +128 -0
  272. package/dist/sdk/terminal/tui/pages/logPage.d.ts +38 -0
  273. package/dist/sdk/terminal/tui/pages/logPage.js +189 -0
  274. package/dist/sdk/terminal/tui/pages/permissionsPage.d.ts +44 -0
  275. package/dist/sdk/terminal/tui/pages/permissionsPage.js +124 -0
  276. package/dist/sdk/terminal/tui/pages/pluginsPage.d.ts +57 -0
  277. package/dist/sdk/terminal/tui/pages/pluginsPage.js +243 -0
  278. package/dist/sdk/terminal/tui/pages/settingsPage.d.ts +55 -0
  279. package/dist/sdk/terminal/tui/pages/settingsPage.js +88 -0
  280. package/dist/sdk/terminal/tui/pages/trajectoryPage.d.ts +58 -0
  281. package/dist/sdk/terminal/tui/pages/trajectoryPage.js +377 -0
  282. package/dist/sdk/terminal/tui/piAdapter.d.ts +18 -0
  283. package/dist/sdk/terminal/tui/piAdapter.js +48 -0
  284. package/dist/sdk/terminal/tui/planMode.d.ts +2 -0
  285. package/dist/sdk/terminal/tui/planMode.js +2 -0
  286. package/dist/sdk/terminal/tui/questionPicker.d.ts +20 -0
  287. package/dist/sdk/terminal/tui/questionPicker.js +150 -0
  288. package/dist/sdk/terminal/tui/questions.d.ts +19 -0
  289. package/dist/sdk/terminal/tui/questions.js +42 -0
  290. package/dist/sdk/terminal/tui/runtime.d.ts +114 -0
  291. package/dist/sdk/terminal/tui/runtime.js +441 -0
  292. package/dist/sdk/terminal/tui/search.d.ts +22 -0
  293. package/dist/sdk/terminal/tui/search.js +60 -0
  294. package/dist/sdk/terminal/tui/selection.d.ts +16 -0
  295. package/dist/sdk/terminal/tui/selection.js +16 -0
  296. package/dist/sdk/terminal/tui/sessionUi.d.ts +3 -0
  297. package/dist/sdk/terminal/tui/sessionUi.js +30 -0
  298. package/dist/sdk/terminal/tui/settingsModel.d.ts +12 -0
  299. package/dist/sdk/terminal/tui/settingsModel.js +84 -0
  300. package/dist/sdk/terminal/tui/sideQuestion.d.ts +53 -0
  301. package/dist/sdk/terminal/tui/sideQuestion.js +197 -0
  302. package/dist/sdk/terminal/tui/skillInvocation.d.ts +9 -0
  303. package/dist/sdk/terminal/tui/skillInvocation.js +43 -0
  304. package/dist/sdk/terminal/tui/status.d.ts +18 -0
  305. package/dist/sdk/terminal/tui/status.js +67 -0
  306. package/dist/sdk/terminal/tui/theme.d.ts +45 -0
  307. package/dist/sdk/terminal/tui/theme.js +176 -0
  308. package/dist/sdk/terminal/tui/treeModel.d.ts +79 -0
  309. package/dist/sdk/terminal/tui/treeModel.js +483 -0
  310. package/dist/sdk/terminal/tui/treePicker.d.ts +49 -0
  311. package/dist/sdk/terminal/tui/treePicker.js +251 -0
  312. package/dist/sdk/terminal/tui/ui.d.ts +47 -0
  313. package/dist/sdk/terminal/tui/ui.js +148 -0
  314. package/dist/sdk/terminal/tui/workingStatus.d.ts +9 -0
  315. package/dist/sdk/terminal/tui/workingStatus.js +229 -0
  316. package/dist/sdk/tools/askUser.d.ts +6 -0
  317. package/dist/sdk/tools/askUser.js +74 -0
  318. package/dist/sdk/tools/checklist.d.ts +9 -0
  319. package/dist/sdk/tools/checklist.js +54 -0
  320. package/dist/sdk/tools/definitions.d.ts +30 -0
  321. package/dist/sdk/tools/definitions.js +117 -0
  322. package/dist/sdk/tools/dispatch.d.ts +16 -0
  323. package/dist/sdk/tools/dispatch.js +67 -0
  324. package/dist/sdk/tools/harnessTools.d.ts +6 -0
  325. package/dist/sdk/tools/harnessTools.js +20 -0
  326. package/dist/sdk/tools/sessionName.d.ts +7 -0
  327. package/dist/sdk/tools/sessionName.js +31 -0
  328. package/dist/sdk/tools/spawnSubagent.d.ts +4 -0
  329. package/dist/sdk/tools/spawnSubagent.js +49 -0
  330. package/dist/sdk/tools/types.d.ts +48 -0
  331. package/dist/sdk/tools/types.js +1 -0
  332. package/dist/sdk/variant/components.d.ts +34 -0
  333. package/dist/sdk/variant/components.js +230 -0
  334. package/dist/sdk/variant/materialise.d.ts +66 -0
  335. package/dist/sdk/variant/materialise.js +81 -0
  336. package/dist/sdk/variant/migrate.d.ts +4 -0
  337. package/dist/sdk/variant/migrate.js +41 -0
  338. package/dist/sdk/variant/seed.d.ts +20 -0
  339. package/dist/sdk/variant/seed.js +116 -0
  340. package/dist/sdk/variant/store.d.ts +82 -0
  341. package/dist/sdk/variant/store.js +151 -0
  342. package/dist/sdk/variant/surface.d.ts +56 -0
  343. package/dist/sdk/variant/surface.js +81 -0
  344. package/dist/sdk/variant/trust.d.ts +27 -0
  345. package/dist/sdk/variant/trust.js +64 -0
  346. package/dist/sdk/variant/variant.d.ts +71 -0
  347. package/dist/sdk/variant/variant.js +331 -0
  348. package/dist/sdk/web/markdown.d.ts +10 -0
  349. package/dist/sdk/web/markdown.js +66 -0
  350. package/dist/sdk/web/safeRequest.d.ts +34 -0
  351. package/dist/sdk/web/safeRequest.js +175 -0
  352. package/dist/sdk/web/search.d.ts +53 -0
  353. package/dist/sdk/web/search.js +168 -0
  354. package/dist/sdk/web/text.d.ts +2 -0
  355. package/dist/sdk/web/text.js +7 -0
  356. package/dist/sdk/web/tools.d.ts +22 -0
  357. package/dist/sdk/web/tools.js +195 -0
  358. package/dist/sdk/web/turndown-plugin-gfm.d.ts +4 -0
  359. package/dist/sdk/wiki/notes.d.ts +68 -0
  360. package/dist/sdk/wiki/notes.js +297 -0
  361. package/dist/sdk/world/actions.d.ts +23 -0
  362. package/dist/sdk/world/actions.js +31 -0
  363. package/dist/sdk/world/cli.d.ts +12 -0
  364. package/dist/sdk/world/cli.js +166 -0
  365. package/dist/sdk/world/images.d.ts +20 -0
  366. package/dist/sdk/world/images.js +48 -0
  367. package/dist/sdk/world/untrusted.d.ts +12 -0
  368. package/dist/sdk/world/untrusted.js +20 -0
  369. package/dist/sdk/world/world.d.ts +65 -0
  370. package/dist/sdk/world/world.js +80 -0
  371. package/dist/terminal-opentui.js +13612 -0
  372. package/dist/terminal-pi.js +808 -151
  373. package/docs/README.md +22 -0
  374. package/docs/architecture/00-overview.md +159 -0
  375. package/docs/architecture/01-extension-points.md +78 -0
  376. package/docs/architecture/02-sessions-and-runs.md +146 -0
  377. package/docs/architecture/03-variants.md +95 -0
  378. package/docs/architecture/04-prompt.md +102 -0
  379. package/docs/architecture/05-refinement.md +107 -0
  380. package/docs/architecture/06-plugins-and-capabilities.md +93 -0
  381. package/docs/architecture/07-tools-and-gate.md +88 -0
  382. package/docs/architecture/08-memory-and-history.md +94 -0
  383. package/docs/architecture/09-accounts-and-connectors.md +90 -0
  384. package/docs/architecture/10-server-protocol.md +84 -0
  385. package/docs/architecture/11-terminal.md +81 -0
  386. package/docs/architecture/12-storage.md +61 -0
  387. package/docs/architecture/13-world-tools.md +23 -0
  388. package/docs/architecture/README.md +114 -0
  389. package/docs/architecture/proposals/PROP-0001-reporting-section.md +106 -0
  390. package/docs/architecture/proposals/PROP-0002-retain-rollout-workspaces.md +104 -0
  391. package/docs/architecture/proposals/PROP-0003-executor-settings.md +81 -0
  392. package/docs/architecture/proposals/PROP-0004-flexible-reporting-guidance.md +71 -0
  393. package/docs/architecture/proposals/PROP-0005-xharness-cli-name.md +78 -0
  394. package/docs/architecture/proposals/PROP-0006-run-checklist.md +68 -0
  395. package/docs/architecture/proposals/PROP-0007-run-continuation.md +80 -0
  396. package/docs/architecture/proposals/PROP-0008-lessons-from-runs.md +80 -0
  397. package/docs/architecture/proposals/PROP-0009-foundation-and-variants.md +78 -0
  398. package/docs/architecture/proposals/PROP-0010-session-names.md +73 -0
  399. package/docs/architecture/proposals/PROP-0011-doctor.md +63 -0
  400. package/docs/architecture/proposals/PROP-0012-release-baseline.md +56 -0
  401. package/docs/architecture/proposals/README.md +76 -0
  402. package/docs/decisions/ADR-0002-native-subagent-lifecycle.md +49 -0
  403. package/docs/decisions/ADR-0003-shared-asynchronous-subagents.md +70 -0
  404. package/docs/decisions/ADR-0004-fullscreen-terminal-layout.md +50 -0
  405. package/docs/decisions/ADR-0005-app-provided-oauth-clients.md +54 -0
  406. package/docs/decisions/ADR-0006-opentui-only-terminal.md +47 -0
  407. package/docs/decisions/ADR-0007-reporting-section.md +33 -0
  408. package/docs/decisions/ADR-0008-flexible-reporting-guidance.md +38 -0
  409. package/docs/decisions/ADR-0009-xharness-command.md +38 -0
  410. package/docs/decisions/ADR-0010-lessons-in-the-wiki.md +31 -0
  411. package/docs/decisions/ADR-0011-foundation-and-variants.md +28 -0
  412. package/docs/decisions/ADR-0012-native-session-names.md +34 -0
  413. package/docs/decisions/ADR-0013-doctor.md +27 -0
  414. package/docs/decisions/ADR-0014-public-release-baseline.md +21 -0
  415. package/docs/doctor.md +74 -0
  416. package/docs/experiments/EXP-0001-terminal-input-latency/plan.md +81 -0
  417. package/docs/experiments/EXP-0001-terminal-input-latency/results.md +46 -0
  418. package/docs/experiments/EXP-0002-opentui-typing-latency/plan.md +70 -0
  419. package/docs/experiments/EXP-0002-opentui-typing-latency/results.md +92 -0
  420. package/docs/features/README.md +20 -0
  421. package/docs/features/automations/README.md +41 -0
  422. package/docs/features/cores/README.md +39 -0
  423. package/docs/features/google-harness2/README.md +52 -0
  424. package/docs/features/integrations/README.md +40 -0
  425. package/docs/features/interfaces/README.md +29 -0
  426. package/docs/features/memory/README.md +28 -0
  427. package/docs/releases/1.0.0.md +40 -0
  428. package/docs/releases/README.md +36 -0
  429. package/docs/study/00-index.md +78 -0
  430. package/docs/study/arms/00-matrix.md +20 -0
  431. package/docs/study/arms/01-system-prompt.md +211 -0
  432. package/docs/study/arms/02-tools.md +79 -0
  433. package/docs/study/arms/03-subagents.md +90 -0
  434. package/docs/study/arms/04-skills.md +75 -0
  435. package/docs/study/arms/05-context-management.md +90 -0
  436. package/docs/study/arms/06-memory.md +90 -0
  437. package/docs/study/arms/07-governance.md +71 -0
  438. package/docs/study/arms/08-execution.md +69 -0
  439. package/docs/study/arms/09-observability.md +60 -0
  440. package/docs/study/arms/10-refinement.md +110 -0
  441. package/docs/study/btw-comparison.md +37 -0
  442. package/docs/study/feature-gap-review.md +42 -0
  443. package/docs/study/insights.md +123 -0
  444. package/docs/study/roadmap.md +72 -0
  445. package/docs/study/sources/claude-code.md +44 -0
  446. package/docs/study/sources/deepseek-harness.md +102 -0
  447. package/docs/study/sources/harness2.md +50 -0
  448. package/docs/study/sources/kimi-cli.md +42 -0
  449. package/docs/study/sources/omp.md +93 -0
  450. package/docs/study/sources/opencode.md +43 -0
  451. package/docs/study/sources/openhands.md +46 -0
  452. package/docs/study/sources/smolagents.md +40 -0
  453. package/docs/study/sources/swe-agent.md +34 -0
  454. package/docs/system-prompt-design.md +196 -0
  455. package/docs/terminal-tui.md +473 -56
  456. package/package.json +43 -13
  457. package/docs/evidence/terminal-2026-10-17/120x40-completed-transcript.ansi.gz +0 -0
  458. package/docs/evidence/terminal-2026-10-17/40x20-settings-interaction.ansi.gz +0 -0
  459. package/docs/evidence/terminal-2026-10-17/40x20-settings-keyboard.ansi.gz +0 -0
  460. package/docs/evidence/terminal-2026-10-17/40x20-welcome.ansi.gz +0 -0
  461. package/docs/evidence/terminal-2026-10-17/80x24-approval-0.ansi.gz +0 -0
  462. package/docs/evidence/terminal-2026-10-17/80x24-question.ansi.gz +0 -0
  463. package/docs/evidence/terminal-2026-10-17/verification.json +0 -130
  464. package/docs/evidence/terminal-2026-10-17-followup/120x40-completed-transcript.ansi.gz +0 -0
  465. package/docs/evidence/terminal-2026-10-17-followup/40x20-settings-interaction.ansi.gz +0 -0
  466. package/docs/evidence/terminal-2026-10-17-followup/40x20-settings-keyboard.ansi.gz +0 -0
  467. package/docs/evidence/terminal-2026-10-17-followup/40x20-welcome.ansi.gz +0 -0
  468. package/docs/evidence/terminal-2026-10-17-followup/80x24-approval-0.ansi.gz +0 -0
  469. package/docs/evidence/terminal-2026-10-17-followup/80x24-plugin-light.ansi.gz +0 -0
  470. package/docs/evidence/terminal-2026-10-17-followup/80x24-question-batch.ansi.gz +0 -0
  471. package/docs/evidence/terminal-2026-10-17-followup/80x24-question.ansi.gz +0 -0
  472. package/docs/evidence/terminal-2026-10-17-followup/app-bundle/80x24-approval-0.ansi.gz +0 -0
  473. package/docs/evidence/terminal-2026-10-17-followup/app-bundle/80x24-plugin-light.ansi.gz +0 -0
  474. package/docs/evidence/terminal-2026-10-17-followup/app-bundle/80x24-question-batch.ansi.gz +0 -0
  475. package/docs/evidence/terminal-2026-10-17-followup/app-bundle/80x24-question.ansi.gz +0 -0
  476. package/docs/evidence/terminal-2026-10-17-followup/app-bundle/verification.json +0 -95
  477. package/docs/evidence/terminal-2026-10-17-followup/global-install/80x24-approval-0.ansi.gz +0 -0
  478. package/docs/evidence/terminal-2026-10-17-followup/global-install/80x24-plugin-light.ansi.gz +0 -0
  479. package/docs/evidence/terminal-2026-10-17-followup/global-install/80x24-question-batch.ansi.gz +0 -0
  480. package/docs/evidence/terminal-2026-10-17-followup/global-install/80x24-question.ansi.gz +0 -0
  481. package/docs/evidence/terminal-2026-10-17-followup/global-install/README.md +0 -27
  482. package/docs/evidence/terminal-2026-10-17-followup/global-install/shell-command-80x24.ansi.gz +0 -0
  483. package/docs/evidence/terminal-2026-10-17-followup/global-install/shell-command.json +0 -18
  484. package/docs/evidence/terminal-2026-10-17-followup/global-install/verification.json +0 -95
  485. package/docs/evidence/terminal-2026-10-17-followup/harness-reference-80x24.json.gz +0 -0
  486. package/docs/evidence/terminal-2026-10-17-followup/harness-reference-final-80x24.json.gz +0 -0
  487. package/docs/evidence/terminal-2026-10-17-followup/harness-reference-scenario.json +0 -60
  488. package/docs/evidence/terminal-2026-10-17-followup/live-codex/README.md +0 -24
  489. package/docs/evidence/terminal-2026-10-17-followup/live-codex/complete-80x24.ansi.gz +0 -0
  490. package/docs/evidence/terminal-2026-10-17-followup/live-codex/verification.json +0 -57
  491. package/docs/evidence/terminal-2026-10-17-followup/omp-reference-80x24-early.json.gz +0 -0
  492. package/docs/evidence/terminal-2026-10-17-followup/omp-reference-80x24.json.gz +0 -0
  493. package/docs/evidence/terminal-2026-10-17-followup/omp-reference-scenario.json +0 -58
  494. package/docs/evidence/terminal-2026-10-17-followup/omp-supplemental-static.json.gz +0 -0
  495. package/docs/evidence/terminal-2026-10-17-followup/rea-artifacts.json +0 -320
  496. package/docs/evidence/terminal-2026-10-17-followup/reference-comparison.json +0 -30
  497. package/docs/evidence/terminal-2026-10-17-followup/reference-comparison.md +0 -133
  498. package/docs/evidence/terminal-2026-10-17-followup/reference-source-observations.json +0 -20
  499. package/docs/evidence/terminal-2026-10-17-followup/verification.json +0 -207
  500. package/src/accounts/accounts.test.ts +0 -333
  501. package/src/accounts/accounts.ts +0 -658
  502. package/src/accounts/env.test.ts +0 -95
  503. package/src/accounts/env.ts +0 -338
  504. package/src/accounts/secrets.ts +0 -50
  505. package/src/accounts/store.ts +0 -338
  506. package/src/capabilities/api.ts +0 -75
  507. package/src/capabilities/runSnapshot.ts +0 -59
  508. package/src/capabilities/types.ts +0 -34
  509. package/src/cli.ts +0 -118
  510. package/src/core/bus.ts +0 -34
  511. package/src/core/changes.ts +0 -33
  512. package/src/core/env.ts +0 -27
  513. package/src/core/errors.ts +0 -32
  514. package/src/core/frontmatter.ts +0 -47
  515. package/src/core/fs.test.ts +0 -38
  516. package/src/core/fs.ts +0 -92
  517. package/src/core/index.ts +0 -193
  518. package/src/core/path.test.ts +0 -14
  519. package/src/core/path.ts +0 -79
  520. package/src/core/projects.ts +0 -90
  521. package/src/core/text.ts +0 -39
  522. package/src/harness.ts +0 -312
  523. package/src/hub/catalog.json +0 -123
  524. package/src/hub/cli.ts +0 -59
  525. package/src/hub/hub.test.ts +0 -205
  526. package/src/hub/hub.ts +0 -256
  527. package/src/hub/schema.ts +0 -81
  528. package/src/index.ts +0 -75
  529. package/src/mcp/connections.ts +0 -614
  530. package/src/mcp/manager.ts +0 -130
  531. package/src/mcp/oauth.ts +0 -195
  532. package/src/mcp/scopeMigration.test.ts +0 -79
  533. package/src/mcp/scopeMigration.ts +0 -204
  534. package/src/mcp/service.test.ts +0 -376
  535. package/src/mcp/service.ts +0 -549
  536. package/src/mcp/types.ts +0 -108
  537. package/src/memory/api.test.ts +0 -82
  538. package/src/memory/api.ts +0 -303
  539. package/src/memory/blocks.test.ts +0 -78
  540. package/src/memory/blocks.ts +0 -408
  541. package/src/memory/caller.ts +0 -69
  542. package/src/memory/curation.test.ts +0 -163
  543. package/src/memory/curation.ts +0 -64
  544. package/src/memory/dispatch.ts +0 -59
  545. package/src/memory/facts.test.ts +0 -41
  546. package/src/memory/facts.ts +0 -248
  547. package/src/memory/graph.ts +0 -103
  548. package/src/memory/health.test.ts +0 -130
  549. package/src/memory/health.ts +0 -74
  550. package/src/memory/maintainer.ts +0 -272
  551. package/src/memory/maintenance.test.ts +0 -176
  552. package/src/memory/maintenance.ts +0 -518
  553. package/src/memory/migrate.ts +0 -79
  554. package/src/memory/operations.ts +0 -150
  555. package/src/memory/proposals.test.ts +0 -168
  556. package/src/memory/proposals.ts +0 -584
  557. package/src/memory/recall.test.ts +0 -115
  558. package/src/memory/recall.ts +0 -278
  559. package/src/memory/references.ts +0 -77
  560. package/src/memory/runContext.ts +0 -93
  561. package/src/memory/secrets.ts +0 -6
  562. package/src/memory/store.test.ts +0 -66
  563. package/src/memory/store.ts +0 -385
  564. package/src/memory/wiki.test.ts +0 -47
  565. package/src/memory/wiki.ts +0 -422
  566. package/src/memory/wikiIndex.test.ts +0 -88
  567. package/src/memory/wikiIndex.ts +0 -116
  568. package/src/plugins/api.ts +0 -181
  569. package/src/plugins/attachments.test.ts +0 -84
  570. package/src/plugins/attachments.ts +0 -141
  571. package/src/plugins/builtin.ts +0 -82
  572. package/src/plugins/catalogue.test.ts +0 -254
  573. package/src/plugins/catalogue.ts +0 -251
  574. package/src/plugins/cli.ts +0 -184
  575. package/src/plugins/discover.ts +0 -151
  576. package/src/plugins/firstParty.test.ts +0 -143
  577. package/src/plugins/firstParty.ts +0 -129
  578. package/src/plugins/hooks.test.ts +0 -250
  579. package/src/plugins/hooks.ts +0 -239
  580. package/src/plugins/identity.ts +0 -37
  581. package/src/plugins/install.test.ts +0 -107
  582. package/src/plugins/install.ts +0 -106
  583. package/src/plugins/inventory.ts +0 -123
  584. package/src/plugins/manifest.ts +0 -76
  585. package/src/plugins/plugins.test.ts +0 -205
  586. package/src/plugins/plugins.ts +0 -189
  587. package/src/plugins/proposal.ts +0 -121
  588. package/src/plugins/runtime.test.ts +0 -40
  589. package/src/plugins/runtime.ts +0 -82
  590. package/src/plugins/trust.ts +0 -142
  591. package/src/plugins/types.ts +0 -149
  592. package/src/prompt/compile.test.ts +0 -261
  593. package/src/prompt/compile.ts +0 -732
  594. package/src/server/methods.ts +0 -349
  595. package/src/server/remote.ts +0 -77
  596. package/src/server/rpc.ts +0 -116
  597. package/src/server/serve.ts +0 -28
  598. package/src/server/server.test.ts +0 -174
  599. package/src/sessions/approvals.ts +0 -118
  600. package/src/sessions/contracts.ts +0 -336
  601. package/src/sessions/conversation.test.ts +0 -177
  602. package/src/sessions/extensionSession.test.ts +0 -74
  603. package/src/sessions/extensionUi.test.ts +0 -65
  604. package/src/sessions/extensionUi.ts +0 -102
  605. package/src/sessions/history.ts +0 -51
  606. package/src/sessions/lineageJoin.ts +0 -75
  607. package/src/sessions/policy.ts +0 -36
  608. package/src/sessions/pricing.ts +0 -60
  609. package/src/sessions/questionBatches.test.ts +0 -110
  610. package/src/sessions/reasoningSummaries.ts +0 -59
  611. package/src/sessions/registry.ts +0 -381
  612. package/src/sessions/runIndex.ts +0 -99
  613. package/src/sessions/runStore.test.ts +0 -152
  614. package/src/sessions/runStore.ts +0 -332
  615. package/src/sessions/runner.ts +0 -604
  616. package/src/sessions/runtimeResources.test.ts +0 -61
  617. package/src/sessions/sessions.test.ts +0 -549
  618. package/src/sessions/sessions.ts +0 -339
  619. package/src/skills/registry.test.ts +0 -104
  620. package/src/skills/registry.ts +0 -413
  621. package/src/terminal/accountsMenu.test.ts +0 -225
  622. package/src/terminal/accountsMenu.ts +0 -382
  623. package/src/terminal/cli.ts +0 -149
  624. package/src/terminal/client.ts +0 -74
  625. package/src/terminal/control.test.ts +0 -23
  626. package/src/terminal/control.ts +0 -23
  627. package/src/terminal/controller.ts +0 -291
  628. package/src/terminal/hubMenu.ts +0 -24
  629. package/src/terminal/launch.test.ts +0 -25
  630. package/src/terminal/launch.ts +0 -48
  631. package/src/terminal/piExtension.lifecycle.test.ts +0 -55
  632. package/src/terminal/piExtension.ts +0 -259
  633. package/src/terminal/pluginControl.test.ts +0 -146
  634. package/src/terminal/pluginMenu.ts +0 -112
  635. package/src/terminal/socket.test.ts +0 -71
  636. package/src/terminal/socket.ts +0 -232
  637. package/src/terminal/standalone.test.ts +0 -167
  638. package/src/terminal/standalone.ts +0 -153
  639. package/src/terminal/terminal.test.ts +0 -399
  640. package/src/terminal/terminals.ts +0 -553
  641. package/src/terminal/tui/application.test.ts +0 -114
  642. package/src/terminal/tui/application.ts +0 -491
  643. package/src/terminal/tui/commands.test.ts +0 -218
  644. package/src/terminal/tui/commands.ts +0 -361
  645. package/src/terminal/tui/dialogs.ts +0 -301
  646. package/src/terminal/tui/editor.test.ts +0 -84
  647. package/src/terminal/tui/editor.ts +0 -79
  648. package/src/terminal/tui/keybindings.test.ts +0 -22
  649. package/src/terminal/tui/keybindings.ts +0 -50
  650. package/src/terminal/tui/piAdapter.ts +0 -62
  651. package/src/terminal/tui/presentation.test.ts +0 -79
  652. package/src/terminal/tui/questions.test.ts +0 -41
  653. package/src/terminal/tui/questions.ts +0 -47
  654. package/src/terminal/tui/runtime.socket.test.ts +0 -104
  655. package/src/terminal/tui/runtime.test.ts +0 -215
  656. package/src/terminal/tui/runtime.ts +0 -388
  657. package/src/terminal/tui/sessionUi.ts +0 -24
  658. package/src/terminal/tui/settings.test.ts +0 -150
  659. package/src/terminal/tui/settings.ts +0 -188
  660. package/src/terminal/tui/status.test.ts +0 -70
  661. package/src/terminal/tui/status.ts +0 -109
  662. package/src/terminal/tui/theme.ts +0 -174
  663. package/src/terminal/tui/tools.test.ts +0 -145
  664. package/src/terminal/tui/tools.ts +0 -142
  665. package/src/terminal/tui/transcript.test.ts +0 -25
  666. package/src/terminal/tui/transcript.ts +0 -124
  667. package/src/terminal/tui/ui.test.ts +0 -313
  668. package/src/terminal/tui/ui.ts +0 -166
  669. package/src/terminal/tui/welcome.ts +0 -102
  670. package/src/tools/askUser.test.ts +0 -69
  671. package/src/tools/askUser.ts +0 -59
  672. package/src/tools/definitions.ts +0 -187
  673. package/src/tools/maintenance.ts +0 -24
  674. package/src/tools/memoryTools.ts +0 -22
  675. package/src/tools/pluginPropose.ts +0 -41
  676. package/src/tools/registryWrite.test.ts +0 -101
  677. package/src/tools/registryWrite.ts +0 -182
  678. package/src/tools/spawnSubagent.ts +0 -92
  679. package/src/tools/types.ts +0 -39
  680. package/src/web/safeRequest.ts +0 -171
  681. package/src/web/text.ts +0 -53
  682. package/src/web/tools.ts +0 -134
  683. package/src/web/web.test.ts +0 -141
@@ -1,584 +0,0 @@
1
- // Validated Wiki updates.
2
- //
3
- // Agents and the sleep-time maintainer only *propose* pages, facts, and block rewrites. This
4
- // module validates every proposal (type, links, evidence, confidence, secrets, concurrent
5
- // edits), applies the valid ones as one atomic operation with revisions, and sends the rest to
6
- // the Inbox, where the user can accept them. Proposals to change skills, prompts, or rules
7
- // always wait in the Inbox.
8
- import { createHash } from 'node:crypto'
9
- import { mkdirSync, readFileSync, renameSync, rmSync } from 'node:fs'
10
- import { dirname, join, relative } from 'node:path'
11
- import { z } from 'zod'
12
-
13
- import { noteChange } from '../core/changes'
14
- import { HarnessError, invalid, notFound } from '../core/errors'
15
- import { atomicWrite, newId, now, readJson, safeId, writeJson } from '../core/fs'
16
- import { charCount, compareText, takeChars } from '../core/text'
17
- import { acceptPluginProposal, pluginProposalSchema } from '../plugins/proposal'
18
- import * as registry from '../skills/registry'
19
- import * as blocks from './blocks'
20
- import * as facts from './facts'
21
- import { inbox, operationsDir, type InboxItem, type Operation, type OperationPage } from './operations'
22
- import { looksSecret } from './secrets'
23
- import * as store from './store'
24
- import { LINK_TYPES, PAGE_TYPES, type WikiLink } from './store'
25
-
26
- // ---- Proposals ------------------------------------------------------------------------------
27
-
28
- const optionalText = z.string().nullish().transform((value) => value ?? null)
29
-
30
- const sourceRefSchema = z.object({
31
- kind: z.string(),
32
- ref: z.string(),
33
- /** A passage quoted from the evidence. A run or source reference counts only when this passage is found in it. */
34
- excerpt: z.string().nullish().transform((value) => value ?? undefined)
35
- })
36
- export type SourceRef = z.infer<typeof sourceRefSchema>
37
-
38
- const linkProposalSchema = z.object({ toId: z.string(), type: z.string() })
39
- export type LinkProposal = z.infer<typeof linkProposalSchema>
40
-
41
- export const pageProposalSchema = z.object({
42
- id: optionalText,
43
- title: z.string(),
44
- type: z.string(),
45
- body: z.string(),
46
- /** Where a new page is filed (`/library`, `/projects/<slug>`); the job's namespace by default. */
47
- namespace: optionalText,
48
- confidence: optionalText,
49
- sourceRefs: z.array(sourceRefSchema).default([]),
50
- links: z.array(linkProposalSchema).default([])
51
- })
52
- export type PageProposal = z.infer<typeof pageProposalSchema>
53
-
54
- export const memoryProposalSchema = z.object({
55
- id: optionalText,
56
- title: z.string(),
57
- kind: z.string(),
58
- body: z.string(),
59
- /** `/` for everything, or a project namespace. The job's project namespace by default. */
60
- namespace: optionalText,
61
- confidence: optionalText,
62
- supersedes: optionalText,
63
- volatile: z.boolean().nullish().transform((value) => value ?? null),
64
- sourceRefs: z.array(sourceRefSchema).default([]),
65
- links: z.array(linkProposalSchema).default([])
66
- })
67
- export type MemoryProposal = z.infer<typeof memoryProposalSchema>
68
-
69
- /** A rewritten memory block from sleep-time consolidation. */
70
- const blockProposalSchema = z.object({ block: z.string(), body: z.string(), sourceRefs: z.array(sourceRefSchema).default([]) })
71
- export type BlockProposal = z.infer<typeof blockProposalSchema>
72
-
73
- const claimFlagSchema = z.object({ claim: z.string(), kind: z.string(), reason: z.string() })
74
- export type ClaimFlag = z.infer<typeof claimFlagSchema>
75
-
76
- export const proposalSetSchema = z.object({
77
- pages: z.array(pageProposalSchema).default([]),
78
- memories: z.array(memoryProposalSchema).default([]),
79
- blocks: z.array(blockProposalSchema).default([]),
80
- flags: z.array(claimFlagSchema).default([])
81
- })
82
- export type ProposalSet = z.infer<typeof proposalSetSchema>
83
-
84
- export function parseProposalSet(value: unknown): ProposalSet {
85
- const parsed = proposalSetSchema.safeParse(value ?? {})
86
- if (!parsed.success) throw new HarnessError('invalid_data', `Stored data could not be read: ${parsed.error.issues[0]?.message ?? 'invalid proposals'}`)
87
- return parsed.data
88
- }
89
-
90
- /** The text proposals are checked against, and the blocks a job may rewrite. */
91
- export interface Evidence {
92
- /** The triggering run's request, assistant messages, and tool summaries. */
93
- runText?: string | null
94
- /** The imported source's text. */
95
- sourceText?: string | null
96
- /** Ids of the blocks attached to the run. */
97
- blocks?: string[]
98
- runs?: Record<string, string>
99
- sources?: Record<string, string>
100
- }
101
-
102
- const MIN_EXCERPT = 12
103
-
104
- function squash(text: string): string {
105
- return text.split(/\s+/).filter(Boolean).join(' ').toLowerCase()
106
- }
107
-
108
- /**
109
- * Whether `excerpt` occurs in `text`, ignoring case and runs of whitespace. Short excerpts
110
- * prove nothing, so they never count.
111
- */
112
- export function quotedIn(text: string | null | undefined, excerpt: string | null | undefined): boolean {
113
- if (typeof text !== 'string' || typeof excerpt !== 'string') return false
114
- const wanted = squash(excerpt)
115
- return charCount(wanted) >= MIN_EXCERPT && squash(text).includes(wanted)
116
- }
117
-
118
- /** What caused the change; decides which evidence references are valid and who the actor is. */
119
- export type Trigger =
120
- | { kind: 'ingest'; sourceId: string; sourceName: string }
121
- | { kind: 'run'; runId: string }
122
- /** An agent's `wiki_propose` during a run. */
123
- | { kind: 'agent'; runId: string | null; actor: string }
124
- /** The user accepted an Inbox item. */
125
- | { kind: 'user'; itemId: string }
126
- /** Idle consolidation of memory blocks that are close to their limit. */
127
- | { kind: 'consolidate' }
128
-
129
- export function describeTrigger(trigger: Trigger): string {
130
- switch (trigger.kind) {
131
- case 'ingest':
132
- return `ingest of ${trigger.sourceName} (${trigger.sourceId})`
133
- case 'run':
134
- return `run ${trigger.runId}`
135
- case 'agent':
136
- return trigger.runId ? `${trigger.actor} agent in run ${trigger.runId}` : `${trigger.actor} agent`
137
- case 'user':
138
- return `Inbox item ${trigger.itemId.slice(0, 8)}`
139
- case 'consolidate':
140
- return 'consolidation of full memory blocks'
141
- }
142
- }
143
-
144
- function triggerActor(trigger: Trigger): string {
145
- return trigger.kind === 'agent' ? trigger.actor : trigger.kind === 'user' ? 'user' : 'Sleep-time'
146
- }
147
-
148
- function triggerRunId(trigger: Trigger): string | null {
149
- return trigger.kind === 'run' ? trigger.runId : trigger.kind === 'agent' ? trigger.runId : null
150
- }
151
-
152
- // ---- Applying ---------------------------------------------------------------------------------
153
-
154
- function fileHash(path: string): string | null {
155
- try {
156
- return createHash('sha256').update(readFileSync(path)).digest('hex')
157
- } catch {
158
- return null
159
- }
160
- }
161
-
162
- function readOrNull(path: string): string | null {
163
- try {
164
- return readFileSync(path, 'utf8')
165
- } catch {
166
- return null
167
- }
168
- }
169
-
170
- /** Captures page, fact, and block file hashes when a job starts, to detect edits made while it ran. */
171
- export function captureHashes(wiki: string): Map<string, string> {
172
- const hashes = new Map<string, string>()
173
- const add = (id: string, path: string) => {
174
- const hash = fileHash(path)
175
- if (hash) hashes.set(id, hash)
176
- }
177
- for (const page of store.loadPages(wiki)) add(page.frontmatter.id, page.path)
178
- for (const memory of facts.loadMemories(wiki)) add(memory.front.id, memory.path)
179
- for (const block of blocks.loadAll(wiki)) add(block.id, block.path)
180
- for (const item of registry.list(dirname(wiki))) add(item.id, item.path)
181
- return hashes
182
- }
183
-
184
- /**
185
- * Rewrites the generated indexes: the root `index.md` lists the namespaces, and each namespace
186
- * has its own `index.md` listing its pages with one line each. Any page is two steps away.
187
- */
188
- export function writeIndex(wiki: string): void {
189
- const pages = store.loadPages(wiki)
190
- const memories = facts.loadMemories(wiki)
191
- const namespaces = [...new Set(pages.map((page) => page.location.namespace).filter((namespace) => namespace !== store.ROOT_NAMESPACE))].sort(compareText)
192
- let root = '# Wiki index\n\nEach namespace has its own index of pages.\n\n'
193
- if (!namespaces.length) root += 'No pages yet.\n'
194
- for (const namespace of namespaces) {
195
- const own = pages.filter((page) => page.location.namespace === namespace).sort((left, right) => compareText(left.location.path, right.location.path))
196
- const folder = namespace.replace(/^\/+/, '')
197
- root += `- [${namespace}](${folder}/index.md) — ${own.length} page${own.length === 1 ? '' : 's'}\n`
198
- let text = `# Index of ${namespace}\n\n`
199
- for (const page of own) {
200
- const inside = relative(join(wiki, folder), page.path)
201
- text += `- [${page.frontmatter.title}](${inside.startsWith('..') ? page.path : inside}) (${page.frontmatter.type}, \`${page.frontmatter.id}\`) — ${store.firstParagraph(page.body)}\n`
202
- }
203
- atomicWrite(join(wiki, folder, 'index.md'), text)
204
- }
205
- const active = memories.filter((memory) => memory.front.status === 'active')
206
- if (active.length) {
207
- root += '\n## Facts\n\n'
208
- for (const memory of active) root += `- [${memory.front.title}](facts/${memory.front.id}.md) (${memory.front.kind}, ${memory.front.namespace}${memory.front.volatile ? ', volatile' : ''})\n`
209
- }
210
- atomicWrite(join(wiki, 'index.md'), root)
211
- }
212
-
213
- export interface ApplyOutcome {
214
- operation: Operation | null
215
- parked: number
216
- flagged: number
217
- /** One line per proposal: what happened to it. */
218
- notes: string[]
219
- }
220
-
221
- interface Write {
222
- entryId: string
223
- path: string
224
- oldText: string | null
225
- newText: string
226
- }
227
-
228
- /** Validates proposals and applies the valid ones as one operation. Pure file logic. */
229
- export function apply(wiki: string, defaultNamespace: string, trigger: Trigger, proposals: ProposalSet, captured: ReadonlyMap<string, string>, evidence: Evidence, operationKey?: string, appliedBy?: string): ApplyOutcome {
230
- if (operationKey) {
231
- const committed = readJson<Operation>(join(operationsDir(wiki), `${safeId(operationKey)}.json`))
232
- if (committed) return { operation: committed, parked: 0, flagged: 0, notes: ['This request was already applied.'] }
233
- }
234
- const existing = store.loadPages(wiki)
235
- const existingMemories = facts.loadMemories(wiki)
236
- const root = dirname(wiki)
237
- const sourceIds = new Set(store.listSources(wiki).map((source) => source.id))
238
- const knownIds = new Set<string>([
239
- ...existing.map((page) => page.frontmatter.id),
240
- ...existingMemories.map((memory) => memory.front.id),
241
- ...registry.list(root).map((item) => item.id),
242
- ...sourceIds
243
- ])
244
- const proposedIds = new Set<string>([
245
- ...proposals.pages.map((page) => store.slug(page.id ?? page.title)),
246
- ...proposals.memories.map((memory) => store.slug(memory.id ?? memory.title))
247
- ])
248
- const outcome: ApplyOutcome = { operation: null, parked: 0, flagged: 0, notes: [] }
249
- const writes: Write[] = []
250
- const actor = appliedBy ?? triggerActor(trigger)
251
- const described = describeTrigger(trigger)
252
- const fromUser = trigger.kind === 'user'
253
-
254
- // Sends one proposal to the Inbox with its payload, so the user can accept it later.
255
- const park = (kind: string, title: string, label: string, reason: string, body: string, entryId: string, payload: unknown): void => {
256
- outcome.parked += 1
257
- outcome.notes.push(`${label} went to the Inbox: ${reason}`)
258
- inbox(wiki, kind, title, `${reason}\n\n${takeChars(body, 600)}`, [entryId], null, operationKey && payload && typeof payload === 'object' ? { ...payload, curationJobId: operationKey } : payload)
259
- }
260
-
261
- // Evidence: a source in the Wiki, the triggering run, a URL, or the user's acceptance. A run
262
- // or an imported source counts only with an excerpt found in its text; a bare reference to
263
- // the caller's own run proves nothing.
264
- const evidenceFor = (refs: readonly SourceRef[]): string[] => {
265
- const found: string[] = []
266
- for (const reference of refs) {
267
- let id: string | null = null
268
- if (reference.kind === 'source') {
269
- const source = evidence.sources?.[reference.ref] ?? (trigger.kind === 'ingest' && trigger.sourceId === reference.ref ? evidence.sourceText : null)
270
- if (sourceIds.has(reference.ref) && (operationKey ? quotedIn(source, reference.excerpt) : (evidence.sourceText == null || quotedIn(evidence.sourceText, reference.excerpt)))) id = reference.ref
271
- } else if (reference.kind === 'run') {
272
- if (quotedIn(evidence.runs?.[reference.ref] ?? (triggerRunId(trigger) === reference.ref ? evidence.runText : null), reference.excerpt)) id = `run:${reference.ref}`
273
- } else if (reference.kind === 'url') {
274
- if (!operationKey && (reference.ref.startsWith('https://') || reference.ref.startsWith('http://'))) id = `url:${reference.ref}`
275
- } else if (reference.kind === 'user') {
276
- if (fromUser) id = 'user:accepted'
277
- }
278
- if (id && !found.includes(id)) found.push(id)
279
- }
280
- return found
281
- }
282
- const filterLinks = (links: readonly LinkProposal[], ownId: string): WikiLink[] =>
283
- links
284
- .filter((link) => (LINK_TYPES as readonly string[]).includes(link.type))
285
- .filter((link) => knownIds.has(link.toId) || proposedIds.has(link.toId))
286
- .filter((link) => link.toId !== ownId)
287
- .map((link) => ({ fromId: ownId, toId: link.toId, type: link.type }))
288
- const changedSince = (id: string, path: string): boolean => (captured.has(id) || Boolean(operationKey)) && captured.get(id) !== fileHash(path)
289
-
290
- for (const proposal of proposals.pages) {
291
- const pageId = store.slug(proposal.id ?? proposal.title)
292
- const current = existing.find((page) => page.frontmatter.id === pageId)
293
- const namespace = current?.location.namespace ?? proposal.namespace ?? defaultNamespace
294
- const payload = { kind: 'page', namespace, proposal, trigger: described }
295
- const label = `Page "${proposal.title}"`
296
- const blocked = `Proposed page "${proposal.title}" was not applied`
297
-
298
- if (!(PAGE_TYPES as readonly string[]).includes(proposal.type) || !proposal.title.trim() || !proposal.body.trim()) {
299
- park('blocked', blocked, label, 'The proposal was incomplete (type, title, or body).', proposal.body, pageId, payload)
300
- continue
301
- }
302
- if (looksSecret(proposal.body) || looksSecret(proposal.title)) {
303
- // Never stored, not even in the Inbox payload.
304
- outcome.parked += 1
305
- outcome.notes.push(`Page "${proposal.title}" was rejected: it contains text that looks like a credential.`)
306
- inbox(wiki, 'blocked', blocked, 'The proposal contained text that looks like a credential, so it was not written.', [pageId])
307
- continue
308
- }
309
- let targetDir: string | null = null
310
- if (!current) {
311
- try {
312
- targetDir = store.namespaceDir(wiki, namespace)
313
- } catch (error) {
314
- park('blocked', blocked, label, error instanceof Error ? error.message : String(error), proposal.body, pageId, payload)
315
- continue
316
- }
317
- }
318
- // Consolidating a run never creates a page: one run is an episode, not an entity.
319
- if (!current && (trigger.kind === 'run' || trigger.kind === 'consolidate')) {
320
- park('unresolved', `"${proposal.title}" would be a new page`, label, 'Sleep-time consolidation updates existing pages only. Accept this to create the page.', proposal.body, pageId, payload)
321
- continue
322
- }
323
- const found = evidenceFor(proposal.sourceRefs)
324
- if (!found.length) {
325
- park('unresolved', `"${proposal.title}" has no verifiable evidence`, label, 'The proposal quotes nothing the host could find in its source or run, so it was not written.', proposal.body, pageId, payload)
326
- continue
327
- }
328
- if (proposal.confidence === 'low' && !fromUser) {
329
- park('unresolved', `"${proposal.title}" is low confidence`, label, 'Low-confidence proposals wait for review.', proposal.body, pageId, payload)
330
- continue
331
- }
332
- // An entry edited while the job ran is never overwritten.
333
- if (current && changedSince(pageId, current.path)) {
334
- park('blocked', blocked, label, 'The page changed while the update was running, so the proposal was parked instead of overwriting the edit.', proposal.body, pageId, payload)
335
- continue
336
- }
337
-
338
- const links = filterLinks(proposal.links, pageId)
339
- const contradicted = links.filter((link) => link.type === 'contradicts')
340
- if (contradicted.length) {
341
- inbox(wiki, 'unresolved', `"${proposal.title}" contradicts another entry`, 'The page was written with an explicit contradicts link. Review both claims and their sources.', [pageId, ...contradicted.map((link) => link.toId)])
342
- outcome.flagged += 1
343
- }
344
- const sourceList = current ? [...current.frontmatter.sourceIds] : []
345
- for (const id of found) if (!sourceList.includes(id)) sourceList.push(id)
346
- const front = { id: pageId, title: proposal.title.trim(), type: proposal.type, updatedAt: now(), sourceIds: sourceList, links }
347
- const path = current?.path ?? join(targetDir!, `${pageId}.md`)
348
- outcome.notes.push(`Page "${proposal.title}" (${pageId}) ${current ? 'updated' : 'created'} in ${namespace}.`)
349
- writes.push({ entryId: pageId, oldText: current ? readOrNull(current.path) : null, newText: store.serializePage(front, proposal.body), path })
350
- }
351
-
352
- const projectDefault = store.projectNamespaceOf(defaultNamespace) ?? store.ROOT_NAMESPACE
353
- for (const proposal of proposals.memories) {
354
- const memoryId = store.slug(proposal.id ?? proposal.title)
355
- const current = existingMemories.find((memory) => memory.front.id === memoryId)
356
- const payload = { kind: 'memory', proposal, trigger: described }
357
- const label = `Fact "${proposal.title}"`
358
- const title = `Fact "${proposal.title}" needs review`
359
- if (looksSecret(proposal.body) || looksSecret(proposal.title)) {
360
- outcome.parked += 1
361
- outcome.notes.push(`Fact "${proposal.title}" was rejected: it contains text that looks like a credential.`)
362
- inbox(wiki, 'blocked', `Fact "${proposal.title}" was not saved`, 'The proposal contained text that looks like a credential, so it was not written.', [])
363
- continue
364
- }
365
- const front: facts.MemoryFront = {
366
- id: memoryId,
367
- title: proposal.title.trim(),
368
- kind: proposal.kind,
369
- namespace: current?.front.namespace ?? proposal.namespace ?? projectDefault,
370
- sourceIds: current ? [...current.front.sourceIds] : [],
371
- confidence: proposal.confidence ?? 'medium',
372
- status: 'active',
373
- supersedes: proposal.supersedes && existingMemories.some((memory) => memory.front.id === proposal.supersedes) ? proposal.supersedes : null,
374
- links: filterLinks(proposal.links, memoryId),
375
- createdAt: current?.front.createdAt || now(),
376
- updatedAt: now(),
377
- observedAt: now(),
378
- volatile: proposal.volatile ?? current?.front.volatile ?? false
379
- }
380
- const problem = facts.validate(front, proposal.body)
381
- if (problem) {
382
- park('blocked', title, label, problem, proposal.body, memoryId, payload)
383
- continue
384
- }
385
- const found = evidenceFor(proposal.sourceRefs)
386
- if (!found.length) {
387
- park('unresolved', title, label, 'The fact quotes nothing the host could find in its source or run, so it was not saved.', proposal.body, memoryId, payload)
388
- continue
389
- }
390
- if (front.confidence === 'low' && !fromUser) {
391
- park('unresolved', title, label, 'Low-confidence facts wait for review.', proposal.body, memoryId, payload)
392
- continue
393
- }
394
- if (current && changedSince(memoryId, current.path)) {
395
- park('blocked', title, label, 'The fact changed while the update was running, so the proposal was parked.', proposal.body, memoryId, payload)
396
- continue
397
- }
398
- for (const id of found) if (!front.sourceIds.includes(id)) front.sourceIds.push(id)
399
- // A superseding fact retires the one it replaces in the same operation.
400
- const old = front.supersedes ? existingMemories.find((memory) => memory.front.id === front.supersedes) : undefined
401
- if (old) {
402
- writes.push({ entryId: old.front.id, path: old.path, oldText: readOrNull(old.path), newText: facts.serialize({ ...old.front, status: 'superseded', updatedAt: now() }, old.body) })
403
- }
404
- const path = current?.path ?? facts.pathFor(wiki, memoryId)
405
- outcome.notes.push(`Fact "${proposal.title}" (${memoryId}) ${current ? 'updated' : 'saved'}.`)
406
- writes.push({ entryId: memoryId, oldText: current ? readOrNull(current.path) : null, newText: facts.serialize(front, proposal.body), path })
407
- }
408
-
409
- const attachedBlocks = evidence.blocks ?? []
410
- for (const proposal of proposals.blocks) {
411
- const refuse = (reason: string): void => {
412
- outcome.parked += 1
413
- outcome.notes.push(`Block ${proposal.block} was not rewritten: ${reason}`)
414
- inbox(wiki, 'unresolved', `A rewrite of ${proposal.block} was not applied`, `${reason}\n\n${takeChars(proposal.body, 600)}`, [proposal.block])
415
- }
416
- let block: blocks.Block
417
- try {
418
- block = blocks.find(wiki, proposal.block)
419
- } catch {
420
- refuse('there is no such memory block.')
421
- continue
422
- }
423
- const body = proposal.body.trim()
424
- if (!attachedBlocks.includes(block.id) || block.front.readOnly) {
425
- refuse('the block is not attached to this run, or it is read-only.')
426
- continue
427
- }
428
- const problem = blocks.check(block.front, body)
429
- if (problem) {
430
- refuse(problem)
431
- continue
432
- }
433
- // A full block is only condensed: the rewrite must be shorter and add no evidence.
434
- const grounded = trigger.kind === 'consolidate' ? body !== '' && charCount(body) < charCount(block.body) : evidenceFor(proposal.sourceRefs).length > 0
435
- if (!grounded) {
436
- refuse(trigger.kind === 'consolidate' ? 'a consolidated block must be shorter than it was.' : 'it quotes nothing the host could find in the run.')
437
- continue
438
- }
439
- if (changedSince(block.id, block.path)) {
440
- refuse('the block changed while the update was running.')
441
- continue
442
- }
443
- if (body === block.body.trim()) continue
444
- outcome.notes.push(`Block ${block.front.label} rewritten.`)
445
- writes.push({ entryId: block.id, oldText: readOrNull(block.path), newText: blocks.serializeBlock({ ...block.front, updatedAt: now() }, body), path: block.path })
446
- }
447
-
448
- for (const flag of proposals.flags) {
449
- inbox(wiki, flag.kind === 'contradiction' ? 'blocked' : 'unresolved', `Flagged claim: ${takeChars(flag.claim, 120)}`, `${flag.reason} (${flag.kind})`, [])
450
- outcome.flagged += 1
451
- }
452
-
453
- if (!writes.length) {
454
- store.log(wiki, `- ${now()} · ${actor} · ${described} · nothing changed · ${outcome.parked} parked · ${outcome.flagged} flagged`)
455
- return outcome
456
- }
457
-
458
- // Apply everything or nothing: on any failure, restore what was already written.
459
- writes.forEach((write, index) => {
460
- try {
461
- atomicWrite(write.path, write.newText)
462
- } catch (error) {
463
- for (const done of writes.slice(0, index)) {
464
- try {
465
- if (done.oldText === null) rmSync(done.path, { force: true })
466
- else atomicWrite(done.path, done.oldText)
467
- } catch {
468
- // Best effort: the original failure is what the caller needs to see.
469
- }
470
- }
471
- throw error
472
- }
473
- })
474
-
475
- const operationId = operationKey ?? newId()
476
- const short = operationId.slice(0, 8)
477
- const pages: OperationPage[] = writes.map((write) => ({
478
- pageId: write.entryId,
479
- path: write.path,
480
- beforeRevisionId: write.oldText === null ? null : store.snapshot(wiki, write.entryId, write.oldText, actor, `Before update ${short}`).id,
481
- afterRevisionId: store.snapshot(wiki, write.entryId, write.newText, actor, `Update ${short} (${described})`).id
482
- }))
483
- const operation: Operation = { id: operationId, createdAt: now(), trigger: described, pages, undone: false }
484
- writeJson(join(operationsDir(wiki), `${operationId}.json`), operation)
485
- for (const write of writes) noteChange({ wiki, id: write.entryId, path: write.path, text: write.newText, actor, reason: described })
486
- writeIndex(wiki)
487
- store.log(
488
- wiki,
489
- `- ${now()} · ${actor} · ${described} · entries ${pages.map((page) => `\`${page.pageId}\``).join(', ')} · revisions ${pages.map((page) => `\`${page.afterRevisionId.slice(0, 8)}\``).join(', ')} · op \`${operationId}\` · ${outcome.parked} parked · ${outcome.flagged} flagged`
490
- )
491
- inbox(
492
- wiki,
493
- 'applied',
494
- `Updated ${pages.length} entr${pages.length === 1 ? 'y' : 'ies'}`,
495
- `From ${described}. Undo restores the previous content as new revisions.`,
496
- pages.map((page) => page.pageId),
497
- operationId
498
- )
499
- outcome.operation = operation
500
- return outcome
501
- }
502
-
503
- // ---- Registry proposals (skills, prompts, rules) -------------------------------------------
504
-
505
- export const registryProposalSchema = z.object({
506
- /** `skill`, `prompt`, or `rule`. */
507
- kind: z.string(),
508
- name: z.string(),
509
- description: z.string().default(''),
510
- body: z.string(),
511
- reason: z.string().default('')
512
- })
513
- export type RegistryProposal = z.infer<typeof registryProposalSchema>
514
-
515
- /**
516
- * Skills, prompts, and rules change how every agent behaves, so proposals never apply on
517
- * their own: they wait in the Inbox until the user accepts them.
518
- */
519
- export function parkRegistryProposal(wiki: string, trigger: Trigger, proposal: RegistryProposal): string {
520
- if (!['skill', 'prompt', 'rule'].includes(proposal.kind) || !proposal.name.trim() || !proposal.body.trim()) {
521
- throw invalid('A skill, prompt, or rule proposal needs a kind, name, and body.')
522
- }
523
- if (looksSecret(proposal.body)) throw invalid('The proposal contains text that looks like a credential.')
524
- const id = `${proposal.kind}s/${store.slug(proposal.name)}`
525
- inbox(
526
- wiki,
527
- 'proposed',
528
- `Proposed ${proposal.kind} "${proposal.name.trim()}"`,
529
- `${proposal.reason.trim() || 'Review the change before it applies to every agent.'}\n\nFrom ${describeTrigger(trigger)}.`,
530
- [id],
531
- null,
532
- { kind: proposal.kind, proposal, trigger: describeTrigger(trigger) }
533
- )
534
- store.log(wiki, `- ${now()} · ${triggerActor(trigger)} · proposed \`${id}\` · waiting in Inbox`)
535
- return id
536
- }
537
-
538
- function parsed<T>(schema: z.ZodType<T>, value: unknown): T {
539
- const result = schema.safeParse(value)
540
- if (!result.success) throw new HarnessError('invalid_data', `Stored data could not be read: ${result.error.issues[0]?.message ?? 'invalid proposal'}`)
541
- return result.data
542
- }
543
-
544
- /**
545
- * Accepts a parked proposal: pages and facts go through `apply` with the user as the
546
- * authority; registry items are written with a revision before and after.
547
- */
548
- export function accept(root: string, itemId: string): string {
549
- const wiki = store.wikiDir(root)
550
- const path = join(wiki, 'inbox', `${safeId(itemId)}.json`)
551
- const item = readJson<InboxItem>(path)
552
- if (!item) throw notFound('Inbox item')
553
- const payload = item.payload as { kind?: unknown; proposal?: unknown; namespace?: unknown } | undefined | null
554
- if (!payload) throw invalid('This Inbox item has nothing to accept.')
555
- const kind = typeof payload.kind === 'string' ? payload.kind : ''
556
- const trigger: Trigger = { kind: 'user', itemId: item.id }
557
- const userRef: SourceRef = { kind: 'user', ref: 'accepted', excerpt: undefined }
558
- let message: string
559
- if (kind === 'page' || kind === 'memory') {
560
- const set: ProposalSet = { pages: [], memories: [], blocks: [], flags: [] }
561
- if (kind === 'page') {
562
- const proposal = parsed(pageProposalSchema, payload.proposal)
563
- set.pages.push({ ...proposal, sourceRefs: [...proposal.sourceRefs, userRef] })
564
- } else {
565
- const proposal = parsed(memoryProposalSchema, payload.proposal)
566
- set.memories.push({ ...proposal, sourceRefs: [...proposal.sourceRefs, userRef] })
567
- }
568
- const namespace = typeof payload.namespace === 'string' ? payload.namespace : store.LIBRARY_NAMESPACE
569
- const outcome = apply(wiki, namespace, trigger, set, new Map(), {})
570
- if (!outcome.operation) throw invalid(outcome.notes.join(' '))
571
- message = outcome.notes.join(' ')
572
- } else if (kind === 'skill' || kind === 'prompt' || kind === 'rule') {
573
- const proposal = parsed(registryProposalSchema, payload.proposal)
574
- message = `Saved ${registry.writeItem(root, proposal.kind, proposal.name, proposal.description, proposal.body, `Accepted ${describeTrigger(trigger)}`)}.`
575
- } else if (kind === 'plugin') {
576
- message = acceptPluginProposal(root, parsed(pluginProposalSchema, payload.proposal))
577
- } else {
578
- throw invalid('Unknown proposal kind.')
579
- }
580
- const target = join(wiki, 'inbox', 'dismissed')
581
- mkdirSync(target, { recursive: true })
582
- renameSync(path, join(target, `${item.id}.json`))
583
- return message
584
- }