@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,64 +0,0 @@
1
- import { readdirSync } from 'node:fs'
2
- import { join } from 'node:path'
3
- import { createHash } from 'node:crypto'
4
-
5
- import { invalid, notFound } from '../core/errors'
6
- import { newId, now, readJson, safeId, writeJson } from '../core/fs'
7
- import type { CallerContext } from './caller'
8
- import type { Job } from './maintenance'
9
- import type { MaintenanceRequest } from './maintainer'
10
- import { captureHashes, parseProposalSet, type ProposalSet, type RegistryProposal, type Evidence, type Trigger } from './proposals'
11
- import { looksSecret } from './secrets'
12
- import * as store from './store'
13
-
14
- export type CurationInput = Job
15
- | { kind: 'proposal'; namespace: string; proposals: ProposalSet; caller: CallerContext }
16
- | { kind: 'registry'; proposal: RegistryProposal; caller: CallerContext }
17
- | { kind: 'plugin'; proposal: unknown; caller: CallerContext }
18
- export interface CurationJob {
19
- id: string
20
- key: string
21
- input: CurationInput
22
- status: 'queued' | 'running' | 'completed' | 'failed' | 'rejected' | 'needs_user'
23
- createdAt: string
24
- updatedAt: string
25
- runId: string | null
26
- reason: string
27
- hashes: [string, string][]
28
- prepared?: { request: MaintenanceRequest; evidence: Evidence; namespace: string; trigger: Trigger }
29
- receipt: { operationId: string | null; notes: string[]; parked: number; flagged: number } | null
30
- }
31
-
32
- const directory = (root: string): string => join(store.wikiDir(root), 'maintenance-jobs')
33
- export function listCuration(root: string): CurationJob[] {
34
- let names: string[] = []
35
- try { names = readdirSync(directory(root)) } catch { return [] }
36
- return names.filter((name) => name.endsWith('.json')).flatMap((name) => {
37
- const job = readJson<CurationJob>(join(directory(root), name))
38
- return job && typeof job.id === 'string' && job.input && typeof job.input.kind === 'string' ? [job] : []
39
- }).sort((a, b) => a.createdAt.localeCompare(b.createdAt))
40
- }
41
- export function curationJob(root: string, id: string): CurationJob {
42
- const job = readJson<CurationJob>(join(directory(root), `${safeId(id)}.json`))
43
- if (!job) throw notFound('Maintenance job')
44
- return job
45
- }
46
- export function saveCuration(root: string, job: CurationJob): CurationJob {
47
- writeJson(join(directory(root), `${safeId(job.id)}.json`), { ...job, updatedAt: now() })
48
- return job
49
- }
50
- export function enqueueCuration(root: string, input: CurationInput): CurationJob {
51
- if (input.kind === 'proposal') input = { ...input, proposals: parseProposalSet(input.proposals) }
52
- if (Buffer.byteLength(JSON.stringify(input)) > 256 * 1024) throw invalid('The proposal is larger than 256 KiB.')
53
- if (looksSecret(JSON.stringify(input))) throw invalid('The proposal contains text that looks like a credential.')
54
- const captured = captureHashes(store.wikiDir(root))
55
- const revisions = input.kind === 'consolidate' ? input.blockIds.map(id => [id, captured.get(id)]) : undefined
56
- const key = createHash('sha256').update(JSON.stringify({ input, revisions })).digest('hex')
57
- const existing = listCuration(root).find((job) => job.key === key)
58
- if (existing) return existing
59
- const timestamp = now()
60
- return saveCuration(root, { id: newId(), key, input, status: 'queued', createdAt: timestamp, updatedAt: timestamp, runId: null, reason: '', hashes: [...captured], receipt: null })
61
- }
62
- export function requireCurator(context: CallerContext): void {
63
- if (context.vaultAccess !== 'curator' || !context.runId) throw invalid('This operation needs a curator capability issued by the host for this run.')
64
- }
@@ -1,59 +0,0 @@
1
- // One entry point for every memory, recall, and Wiki call a session makes, whichever way it
2
- // reaches the harness (a Pi tool, the `xagent-wiki` command, the bundled MCP server).
3
- import type { Bus } from '../core/bus'
4
- import type { HarnessEnv } from '../core/env'
5
- import { HarnessError } from '../core/errors'
6
- import { launchText, load, render } from '../prompt/compile'
7
- import * as api from './api'
8
- import type { CallerContext } from './caller'
9
- import * as recall from './recall'
10
- import { reindexQuietly } from './wikiIndex'
11
-
12
- export type DispatchEnv = HarnessEnv & { bus?: Bus }
13
-
14
- /** Runs one call and returns its reply as text for a model. */
15
- export function dispatch(env: DispatchEnv, context: CallerContext, call: string, params: api.Params, contributions?: readonly string[]): string {
16
- switch (call) {
17
- case 'wiki.entrypoint': {
18
- const recorded = context.runId ? safely(() => load(env.root, context.runId!)) : null
19
- return recorded ? render(env, recorded) : launchText(env, context)
20
- }
21
- case 'recall.search':
22
- return recall.searchTool(env, context, params)
23
- case 'recall.read':
24
- return recall.readTool(env, context, params)
25
- case 'memory.append':
26
- case 'memory.replace':
27
- case 'memory.rethink': {
28
- const text = api.memoryEdit(env, context, call, params)
29
- env.bus?.emit({ type: 'wiki.changed' })
30
- return text
31
- }
32
- case 'wiki.search':
33
- return api.search(env, context, params)
34
- case 'wiki.read':
35
- return api.read(env, context, params)
36
- case 'wiki.list':
37
- return api.list(env, params)
38
- case 'wiki.skill':
39
- return api.skill(env, context, params, contributions)
40
- case 'wiki.memory':
41
- return api.memories(env, context, params)
42
- case 'wiki.propose': {
43
- const text = api.propose(env, context, params)
44
- reindexQuietly(env.root)
45
- env.bus?.emit({ type: 'wiki.changed' })
46
- return text
47
- }
48
- default:
49
- throw new HarnessError('unknown_method', call.startsWith('memory.') ? `Unknown memory call ${call}.` : `Unknown Wiki call ${call}.`)
50
- }
51
- }
52
-
53
- function safely<T>(read: () => T): T | null {
54
- try {
55
- return read()
56
- } catch {
57
- return null
58
- }
59
- }
@@ -1,41 +0,0 @@
1
- import { expect, test } from 'vitest'
2
-
3
- import { dataRoot } from '../../tests/helpers'
4
- import { now } from '../core/fs'
5
- import { appliesTo, isStale, loadMemories, parse, response, saveAsUser, type MemoryFront, type MemoryInput } from './facts'
6
- import { readManifest, wikiDir } from './store'
7
-
8
- test('reads legacy procedures as facts without changing their content', () => {
9
- const parsed = parse('---\nid: legacy\ntitle: Legacy procedure\nkind: procedure\n---\n\nFollow these steps.\n', '/tmp/legacy.md')!
10
- expect(parsed.front.kind).toBe('fact')
11
- expect(parsed.body).toBe('Follow these steps.\n')
12
- const value = response(dataRoot(), parsed)
13
- expect(value.kind).toBe('fact')
14
- expect(value.body).toBe('Follow these steps.\n')
15
- })
16
-
17
- const input = (title: string, kind: string): MemoryInput => ({ title, kind, namespace: '/', body: 'Use pnpm, not npm.', confidence: 'high', status: 'active' })
18
-
19
- test('saves, validates and revisions memories', () => {
20
- const wiki = wikiDir(dataRoot())
21
- const saved = saveAsUser(wiki, input('Package manager', 'preference'))
22
- expect(saved.id).toBe('package-manager')
23
- expect(saved.sourceIds).toEqual(['user'])
24
- saveAsUser(wiki, { ...input('Package manager', 'preference'), id: 'package-manager', body: 'Use pnpm everywhere.' })
25
- expect(readManifest(wiki, 'package-manager')).toHaveLength(3)
26
- expect(() => saveAsUser(wiki, input('Bad', 'opinion'))).toThrow()
27
- expect(() => saveAsUser(wiki, input('Steps', 'procedure'))).toThrow()
28
- expect(() => saveAsUser(wiki, { ...input('Scoped', 'fact'), namespace: '/elsewhere' })).toThrow()
29
- expect(loadMemories(wiki)).toHaveLength(1)
30
- })
31
-
32
- test('applies by namespace and status', () => {
33
- const front: MemoryFront = { id: 'm', title: 'M', kind: 'fact', namespace: '/projects/a', sourceIds: [], confidence: 'high', status: 'active', supersedes: null, links: [], createdAt: '', updatedAt: '', observedAt: '', volatile: false }
34
- expect(isStale(front)).toBe(false)
35
- expect(isStale({ ...front, volatile: true, observedAt: '2020-01-01T00:00:00Z' })).toBe(true)
36
- expect(isStale({ ...front, volatile: true, observedAt: now() })).toBe(false)
37
- expect(appliesTo(front, '/projects/a')).toBe(true)
38
- expect(appliesTo(front, '/projects/b')).toBe(false)
39
- expect(appliesTo({ ...front, namespace: '/' }, null)).toBe(true)
40
- expect(appliesTo({ ...front, namespace: '/', status: 'archived' }, null)).toBe(false)
41
- })
@@ -1,248 +0,0 @@
1
- // Facts: short, typed things to carry between runs (a preference, a decision). Each is a file,
2
- // `wiki/facts/<id>.md`, with frontmatter and a few lines of body, has sources and revisions like
3
- // a page, and changes only through the user or a validated proposal.
4
- import { readFileSync } from 'node:fs'
5
- import { join } from 'node:path'
6
-
7
- import { noteChange } from '../core/changes'
8
- import { HarnessError, invalid, notFound } from '../core/errors'
9
- import * as frontmatter from '../core/frontmatter'
10
- import { atomicWrite, now, safeId } from '../core/fs'
11
- import { comparePaths } from '../core/text'
12
- import { looksSecret } from './secrets'
13
- import * as store from './store'
14
- import { LIBRARY_NAMESPACE, ROOT_NAMESPACE, type WikiLink } from './store'
15
-
16
- /** A procedure is a skill, not a fact. */
17
- export const MEMORY_KINDS = ['preference', 'fact', 'decision', 'feedback'] as const
18
- /** A volatile fact older than this loses rank in search and is reported by Health. */
19
- export const STALE_DAYS = 30
20
- export const CONFIDENCE = ['high', 'medium', 'low'] as const
21
- export const STATUSES = ['active', 'superseded', 'archived'] as const
22
- /** A fact is short, not a document. Measured in bytes. */
23
- export const MAX_BODY = 2000
24
-
25
- export interface MemoryFront {
26
- id: string
27
- title: string
28
- kind: string
29
- /** `/` for everything, or a project namespace such as `/projects/xagent`. */
30
- namespace: string
31
- sourceIds: string[]
32
- confidence: string
33
- status: string
34
- supersedes: string | null
35
- links: WikiLink[]
36
- createdAt: string
37
- updatedAt: string
38
- /** When the fact was observed to be true. */
39
- observedAt: string
40
- /** Current state that will change. Never put in a compiled prompt; loses rank as it ages. */
41
- volatile: boolean
42
- }
43
-
44
- export interface ParsedMemory {
45
- front: MemoryFront
46
- body: string
47
- path: string
48
- }
49
-
50
- /** Days since the fact was observed (or last updated), when that can be read. */
51
- export function ageDays(front: MemoryFront): number | null {
52
- const at = Date.parse(front.observedAt || front.updatedAt)
53
- return Number.isNaN(at) ? null : Math.trunc((Date.now() - at) / 86_400_000)
54
- }
55
-
56
- export function isStale(front: MemoryFront): boolean {
57
- const days = ageDays(front)
58
- return front.volatile && front.status === 'active' && days !== null && days >= STALE_DAYS
59
- }
60
-
61
- export function memoryDir(wiki: string): string {
62
- return join(wiki, 'facts')
63
- }
64
-
65
- /** The reason a fact is not valid, or `null`. */
66
- export function validate(front: MemoryFront, body: string): string | null {
67
- try {
68
- safeId(front.id)
69
- } catch {
70
- return 'The fact id must be letters, numbers, - or _.'
71
- }
72
- if (!front.title.trim() || !body.trim()) return 'A fact needs a title and a body.'
73
- if (Buffer.byteLength(body) > MAX_BODY) return `A memory is a short fact; keep the body under ${MAX_BODY} characters and put longer material in a Wiki page.`
74
- if (!(MEMORY_KINDS as readonly string[]).includes(front.kind)) return `A fact must be one of ${MEMORY_KINDS.join(', ')}.`
75
- if (!(CONFIDENCE as readonly string[]).includes(front.confidence) || !(STATUSES as readonly string[]).includes(front.status)) return 'Unknown confidence or status.'
76
- if (front.namespace !== ROOT_NAMESPACE && store.projectNamespaceOf(front.namespace) !== front.namespace && front.namespace !== LIBRARY_NAMESPACE) {
77
- return "A memory's namespace is / or a project namespace (/projects/<slug>)."
78
- }
79
- return null
80
- }
81
-
82
- const optionalText = (value: unknown, fallback: string): string | null => (value === undefined ? fallback : typeof value === 'string' ? value : null)
83
-
84
- export function parse(text: string, path: string): ParsedMemory | null {
85
- const parsed = frontmatter.parse(text)
86
- if (!parsed) return null
87
- const { id, title, kind, supersedes, volatile } = parsed.front
88
- if (typeof id !== 'string' || typeof title !== 'string' || typeof kind !== 'string') return null
89
- const namespace = optionalText(parsed.front.namespace, ROOT_NAMESPACE)
90
- const confidence = optionalText(parsed.front.confidence, 'medium')
91
- const status = optionalText(parsed.front.status, 'active')
92
- const createdAt = optionalText(parsed.front.createdAt, '')
93
- const updatedAt = optionalText(parsed.front.updatedAt, '')
94
- const observedAt = optionalText(parsed.front.observedAt, '')
95
- const sourceIds = store.stringList(parsed.front.sourceIds)
96
- const links = store.linkList(parsed.front.links, id)
97
- if (namespace === null || confidence === null || status === null || createdAt === null || updatedAt === null || observedAt === null || !sourceIds || !links) return null
98
- if (supersedes !== undefined && supersedes !== null && typeof supersedes !== 'string') return null
99
- if (volatile !== undefined && typeof volatile !== 'boolean') return null
100
- return {
101
- front: {
102
- id,
103
- title,
104
- // Historical procedures read as facts without rewriting files or creating registry skills.
105
- kind: kind === 'procedure' ? 'fact' : kind,
106
- namespace,
107
- sourceIds,
108
- confidence,
109
- status,
110
- supersedes: supersedes ?? null,
111
- links,
112
- createdAt,
113
- updatedAt,
114
- observedAt,
115
- volatile: volatile ?? false
116
- },
117
- body: parsed.body,
118
- path
119
- }
120
- }
121
-
122
- export function loadMemories(wiki: string): ParsedMemory[] {
123
- const files: string[] = []
124
- store.markdownFiles(memoryDir(wiki), files)
125
- const memories: ParsedMemory[] = []
126
- for (const path of files.sort(comparePaths)) {
127
- try {
128
- const memory = parse(readFileSync(path, 'utf8'), path)
129
- if (memory) memories.push(memory)
130
- } catch {
131
- // An unreadable file is not a fact.
132
- }
133
- }
134
- return memories
135
- }
136
-
137
- export function findMemory(wiki: string, id: string): ParsedMemory {
138
- const memory = loadMemories(wiki).find((entry) => entry.front.id === id)
139
- if (!memory) throw notFound('Memory')
140
- return memory
141
- }
142
-
143
- export function serialize(front: MemoryFront, body: string): string {
144
- return frontmatter.serialize(
145
- {
146
- id: front.id,
147
- title: front.title,
148
- kind: front.kind,
149
- namespace: front.namespace,
150
- sourceIds: front.sourceIds,
151
- confidence: front.confidence,
152
- status: front.status,
153
- ...(front.supersedes === null ? {} : { supersedes: front.supersedes }),
154
- links: front.links,
155
- createdAt: front.createdAt,
156
- updatedAt: front.updatedAt,
157
- observedAt: front.observedAt,
158
- ...(front.volatile ? { volatile: true } : {})
159
- },
160
- body
161
- )
162
- }
163
-
164
- export function pathFor(wiki: string, id: string): string {
165
- return join(memoryDir(wiki), `${safeId(id)}.md`)
166
- }
167
-
168
- /**
169
- * Facts that apply in a project namespace (or everywhere): active ones in `/`, `/library`,
170
- * or that namespace. Others stay retrievable by search.
171
- */
172
- export function appliesTo(front: MemoryFront, projectNamespace: string | null): boolean {
173
- return front.status === 'active' && (front.namespace === ROOT_NAMESPACE || front.namespace === LIBRARY_NAMESPACE || front.namespace === projectNamespace)
174
- }
175
-
176
- export type WikiMemory = Omit<MemoryFront, 'supersedes' | 'volatile'> & { supersedes?: string; volatile?: true; body: string; path: string; revisionId: string | null }
177
-
178
- export function response(wiki: string, memory: ParsedMemory): WikiMemory {
179
- const { supersedes, volatile, ...front } = memory.front
180
- return {
181
- ...front,
182
- ...(supersedes === null ? {} : { supersedes }),
183
- ...(volatile ? { volatile: true as const } : {}),
184
- body: memory.body,
185
- path: memory.path,
186
- revisionId: store.currentRevision(wiki, memory.front.id)
187
- }
188
- }
189
-
190
- export interface MemoryInput {
191
- id?: string | null
192
- title: string
193
- kind: string
194
- namespace?: string
195
- body: string
196
- confidence?: string
197
- status?: string
198
- supersedes?: string | null
199
- volatile?: boolean
200
- }
201
-
202
- /** A user's create or edit. Writes a revision before and after, like every other change. */
203
- export function saveAsUser(wiki: string, input: MemoryInput): WikiMemory {
204
- const id = input.id ?? store.slug(input.title)
205
- let existing: ParsedMemory | null = null
206
- try {
207
- existing = findMemory(wiki, id)
208
- } catch {
209
- existing = null
210
- }
211
- const sourceIds = existing ? [...existing.front.sourceIds] : []
212
- if (!sourceIds.length) sourceIds.push('user')
213
- const front: MemoryFront = {
214
- id,
215
- title: input.title.trim(),
216
- kind: input.kind,
217
- namespace: (input.namespace ?? ROOT_NAMESPACE).trim(),
218
- sourceIds,
219
- confidence: input.confidence ?? 'medium',
220
- status: input.status ?? 'active',
221
- supersedes: input.supersedes || null,
222
- links: existing ? existing.front.links : [],
223
- createdAt: existing?.front.createdAt || now(),
224
- updatedAt: now(),
225
- // Saving a fact again says it is still true now.
226
- observedAt: now(),
227
- volatile: input.volatile ?? false
228
- }
229
- const problem = validate(front, input.body)
230
- if (problem) throw invalid(problem)
231
- if (looksSecret(input.body)) throw invalid('The fact contains text that looks like a credential.')
232
- const path = existing?.path ?? pathFor(wiki, id)
233
- if (existing) {
234
- let before: string
235
- try {
236
- before = readFileSync(existing.path, 'utf8')
237
- } catch (error) {
238
- throw new HarnessError('io_error', error instanceof Error ? error.message : String(error))
239
- }
240
- store.snapshot(wiki, id, before, 'user', 'Before edit')
241
- }
242
- const text = serialize(front, input.body)
243
- atomicWrite(path, text)
244
- store.snapshot(wiki, id, text, 'user', existing ? 'Edited' : 'Created')
245
- noteChange({ wiki, id, path, text, actor: 'user', reason: existing ? 'Edited' : 'Created' })
246
- store.log(wiki, `- ${now()} · user · memory · \`${id}\` ${existing ? 'edited' : 'created'}`)
247
- return response(wiki, findMemory(wiki, id))
248
- }
@@ -1,103 +0,0 @@
1
- // One graph of the Wiki: pages, facts, memory blocks, registry skills/prompts/rules, and sources
2
- // as nodes; frontmatter links, citations, and namespace membership as edges.
3
- import type { HarnessEnv } from '../core/env'
4
- import { charCount } from '../core/text'
5
- import * as registry from '../skills/registry'
6
- import * as blocks from './blocks'
7
- import * as facts from './facts'
8
- import * as store from './store'
9
- import { registryEntryKind } from './wiki'
10
-
11
- export interface GraphNode {
12
- id: string
13
- label: string
14
- type: 'project' | 'page' | 'memory' | 'skill' | 'prompt' | 'rule' | 'block' | 'source'
15
- pageType: string | null
16
- namespace: string
17
- summary: string
18
- status: 'unresolved' | 'established' | 'stale'
19
- provenance: string
20
- }
21
-
22
- export interface GraphEdge {
23
- id: string
24
- source: string
25
- target: string
26
- type: string
27
- evidence: string | null
28
- }
29
-
30
- export interface GraphResponse {
31
- nodes: GraphNode[]
32
- edges: GraphEdge[]
33
- }
34
-
35
- const statusOf = (sourceIds: readonly string[]): 'unresolved' | 'established' => (sourceIds.length ? 'established' : 'unresolved')
36
-
37
- export function build(env: HarnessEnv): GraphResponse {
38
- const wiki = store.wikiDir(env.root)
39
- const pages = store.loadPages(wiki)
40
- const memories = facts.loadMemories(wiki)
41
- const nodes: GraphNode[] = pages.map((page) => ({
42
- id: page.frontmatter.id,
43
- label: page.frontmatter.title,
44
- type: page.frontmatter.type === 'project' ? 'project' : 'page',
45
- pageType: page.frontmatter.type,
46
- namespace: page.location.namespace,
47
- summary: store.firstParagraph(page.body),
48
- status: statusOf(page.frontmatter.sourceIds),
49
- provenance: `Wiki page ${page.location.path} · ${page.frontmatter.sourceIds.length} source(s)`
50
- }))
51
- for (const memory of memories) {
52
- nodes.push({
53
- id: memory.front.id,
54
- label: memory.front.title,
55
- type: 'memory',
56
- pageType: memory.front.kind,
57
- namespace: memory.front.namespace,
58
- summary: store.firstParagraph(memory.body),
59
- status: memory.front.status !== 'active' ? 'stale' : statusOf(memory.front.sourceIds),
60
- provenance: `Memory · ${memory.front.confidence} confidence · ${memory.front.sourceIds.length} source(s)`
61
- })
62
- }
63
- for (const item of registry.list(env.root)) {
64
- const type = registryEntryKind(item.kind)
65
- if (type) nodes.push({ id: item.id, label: item.name, type, pageType: null, namespace: store.ROOT_NAMESPACE, summary: item.description, status: 'established', provenance: `Registry item ${item.id}` })
66
- }
67
- for (const block of blocks.loadAll(wiki)) {
68
- nodes.push({
69
- id: block.id,
70
- label: block.scope === 'agent' && block.owner ? `${env.directory.agentName(block.owner) ?? 'Removed agent'} · ${block.front.label}` : block.front.label,
71
- type: 'block',
72
- pageType: block.scope,
73
- namespace: block.scope === 'project' && block.owner ? `/projects/${block.owner}` : store.ROOT_NAMESPACE,
74
- summary: block.body.trim() ? store.firstParagraph(block.body) : block.front.description,
75
- status: 'established',
76
- provenance: `Memory block · ${charCount(block.body)} of ${block.front.limit} characters`
77
- })
78
- }
79
- for (const source of store.listSources(wiki)) {
80
- nodes.push({ id: source.id, label: source.name, type: 'source', pageType: null, namespace: store.ROOT_NAMESPACE, summary: `Imported source, version ${source.version}`, status: 'established', provenance: `Imported ${source.importedAt}` })
81
- }
82
-
83
- const ids = new Set(nodes.map((node) => node.id))
84
- const edges: GraphEdge[] = []
85
- const pushLinks = (from: string, links: readonly store.WikiLink[], sourceIds: readonly string[]): void => {
86
- for (const link of links) if (ids.has(link.toId)) edges.push({ id: `${from}->${link.toId}:${link.type}`, source: from, target: link.toId, type: link.type, evidence: null })
87
- for (const sourceId of sourceIds) if (ids.has(sourceId)) edges.push({ id: `${from}->${sourceId}:cites`, source: from, target: sourceId, type: 'references', evidence: sourceId })
88
- }
89
- for (const page of pages) pushLinks(page.frontmatter.id, page.frontmatter.links, page.frontmatter.sourceIds)
90
- for (const memory of memories) pushLinks(memory.front.id, memory.front.links, memory.front.sourceIds)
91
- // Namespace membership: entries in a project namespace attach to that project's overview page.
92
- const projectPages = pages.filter((page) => page.frontmatter.type === 'project' && page.location.namespace.startsWith('/projects/')).map((page) => ({ namespace: page.location.namespace, id: page.frontmatter.id }))
93
- const members = [
94
- ...pages.map((page) => ({ id: page.frontmatter.id, namespace: page.location.namespace })),
95
- ...memories.map((memory) => ({ id: memory.front.id, namespace: memory.front.namespace })),
96
- ...nodes.filter((node) => node.type === 'block').map((node) => ({ id: node.id, namespace: node.namespace }))
97
- ]
98
- for (const member of members) {
99
- const project = projectPages.find((entry) => entry.namespace === member.namespace && entry.id !== member.id)
100
- if (project) edges.push({ id: `${member.id}->${project.id}:part_of`, source: member.id, target: project.id, type: 'part_of', evidence: null })
101
- }
102
- return { nodes, edges }
103
- }
@@ -1,130 +0,0 @@
1
- import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
2
- import { tmpdir } from 'node:os'
3
- import { join } from 'node:path'
4
- import { expect, test } from 'vitest'
5
-
6
- import { dataRoot, writeFile } from '../../tests/helpers'
7
- import { createEnv } from '../core/env'
8
- import { now, readJson, writeJson } from '../core/fs'
9
- import * as blocks from './blocks'
10
- import { loadMemories } from './facts'
11
- import { build } from './graph'
12
- import { check } from './health'
13
- import { run, version, WIKI_VERSION } from './migrate'
14
- import { ensureProjectNamespace, isDir, isFile, loadPages, wikiDir } from './store'
15
-
16
- test('reports problems across the wiki', () => {
17
- const root = dataRoot()
18
- const wiki = wikiDir(root)
19
- writeFileSync(join(wiki, 'library/tauri.md'), '---\nid: tauri\ntitle: Use Tauri\ntype: decision\nsourceIds: []\nlinks:\n - toId: xingular-agent\n type: references\n - toId: electron\n type: contradicts\n---\n\nWe use Tauri 2.\n')
20
- writeFile(join(wiki, 'projects/xingular-agent/xingular-agent.md'), '---\nid: xingular-agent\ntitle: Xingular Agent\ntype: concept\n---\n\nThe app.\n')
21
- writeFileSync(join(wiki, 'library/lonely.md'), '---\nid: lonely\ntitle: Lonely\ntype: concept\nsourceIds: [run:r1]\n---\n\nAlone.\n')
22
- writeFileSync(join(wiki, 'facts/m.md'), '---\nid: m\ntitle: M\nkind: fact\nsourceIds: [src-missing]\n---\n\nFact.\n')
23
- const report = check(root)
24
- expect(report.brokenLinks).toHaveLength(1)
25
- expect(report.contradictions).toHaveLength(1)
26
- expect(report.orphanPages).toEqual(['lonely'])
27
- expect([...report.missingEvidence].sort()).toEqual(['m', 'tauri', 'xingular-agent'])
28
- expect([report.staleFacts, report.similarTitles, report.fullBlocks]).toEqual([[], [], []])
29
- })
30
-
31
- test('reports stale facts, near-duplicate titles and full blocks', () => {
32
- const root = dataRoot()
33
- ensureProjectNamespace(root, 'app', 'App')
34
- const wiki = wikiDir(root)
35
- for (const [file, title] of [['a', 'Linear MCP availability observed in run a3695ebe'], ['b', 'Linear MCP availability observed in run c54c128a'], ['c', 'Release plan']]) {
36
- writeFileSync(join(wiki, `library/${file}.md`), `---\nid: ${file}\ntitle: ${title}\ntype: reference\nsourceIds: [user]\n---\n\nText.\n`)
37
- }
38
- writeFileSync(join(wiki, 'facts/old.md'), '---\nid: old\ntitle: Open issues\nkind: fact\nvolatile: true\nobservedAt: 2020-01-01T00:00:00Z\nsourceIds: [user]\n---\n\nThree open.\n')
39
- writeFileSync(join(wiki, 'facts/new.md'), `---\nid: new\ntitle: On call\nkind: fact\nvolatile: true\nobservedAt: ${now()}\nsourceIds: [user]\n---\n\nNora.\n`)
40
- const user = blocks.ensureUser(wiki)
41
- writeFileSync(user.path, blocks.serializeBlock({ ...user.front, limit: 20 }, 'Nineteen characters'))
42
- const report = check(root)
43
- expect(report.staleFacts).toEqual(['old'])
44
- expect(report.similarTitles).toEqual([['a', 'b']])
45
- expect(report.fullBlocks).toEqual(['blocks/shared/user'])
46
- // A project's skeleton pages start empty and unlinked without being reported.
47
- expect(report.orphanPages).toEqual(['a', 'b', 'c'])
48
- expect(report.missingEvidence).toEqual([])
49
- })
50
-
51
- test('graph spans namespaces, memories and registry', () => {
52
- const root = dataRoot()
53
- ensureProjectNamespace(root, 'app', 'App')
54
- const wiki = wikiDir(root)
55
- writeFileSync(join(wiki, 'projects/app/arch.md'), '---\nid: arch\ntitle: Arch\ntype: concept\nlinks:\n - toId: skills/review\n type: uses\n---\n\nBody.\n')
56
- writeFileSync(join(wiki, 'facts/m.md'), '---\nid: m\ntitle: M\nkind: fact\nnamespace: /projects/app\n---\n\nFact.\n')
57
- writeFile(join(root, 'registry/skills/review.md'), 'Review code.\n')
58
- const graph = build(createEnv(root))
59
- const types = new Set(graph.nodes.map((node) => node.type))
60
- for (const type of ['project', 'memory', 'skill'] as const) expect(types.has(type)).toBe(true)
61
- expect(graph.edges.some((edge) => edge.source === 'arch' && edge.target === 'skills/review')).toBe(true)
62
- expect(graph.edges.some((edge) => edge.source === 'm' && edge.target === 'project-app' && edge.type === 'part_of')).toBe(true)
63
- })
64
-
65
- function v2Layout(): string {
66
- const root = mkdtempSync(join(tmpdir(), 'harness-migrate-'))
67
- writeJson(join(root, 'projects.json'), [{ id: 'p1', name: 'Xingular Agent', slug: 'xingular-agent', rootPath: '/tmp/x', autoMaintenance: true, createdAt: '2026-01-01T00:00:00Z' }])
68
- writeFile(join(root, 'config/storage.json'), '{"wikiVersion":2}')
69
- writeFile(join(root, 'wiki/docs/observed.md'), '---\nid: observed\ntitle: Observed in run\ntype: reference\n---\n\nA run.\n')
70
- writeFile(join(root, 'wiki/memory/pnpm.md'), '---\nid: pnpm\ntitle: Use pnpm\nkind: preference\n---\n\nUse pnpm.\n')
71
- writeFile(join(root, 'wiki/log.md'), '# Maintenance log\n\n- t · user · ingest\n')
72
- writeFile(join(root, 'registry/rules/style.md'), 'Use spaces.\n')
73
- return root
74
- }
75
-
76
- test('version 3 starts clean and keeps the old wiki as a backup', () => {
77
- const root = v2Layout()
78
- expect(version(root)).toBe(2)
79
- expect(run(createEnv(root), ['a1'])).toBe(true)
80
- const wiki = wikiDir(root)
81
- expect(loadPages(wiki).every((page) => page.frontmatter.id !== 'observed')).toBe(true)
82
- expect(loadMemories(wiki)).toEqual([])
83
- for (const relative of ['blocks/shared/user.md', 'blocks/agents/a1/persona.md', 'blocks/agents/a1/notes.md', 'blocks/projects/xingular-agent/brief.md', 'projects/xingular-agent/overview.md']) expect(isFile(join(wiki, relative))).toBe(true)
84
- expect(isDir(join(wiki, 'library')) && isDir(join(wiki, 'facts'))).toBe(true)
85
- expect(isFile(join(root, 'wiki.pre-v3/docs/observed.md')) && isFile(join(root, 'wiki.pre-v3/memory/pnpm.md'))).toBe(true)
86
- expect(readFileSync(join(root, 'registry/rules/style.md'), 'utf8')).toBe('Use spaces.\n')
87
- expect(isDir(join(root, 'wiki.migrating'))).toBe(false)
88
- expect(version(root)).toBe(WIKI_VERSION)
89
- expect(run(createEnv(root))).toBe(false)
90
- })
91
-
92
- test('a version 2 wiki without a marker is still migrated', () => {
93
- const root = v2Layout()
94
- rmSync(join(root, 'config/storage.json'))
95
- expect(version(root)).toBe(2)
96
- expect(run(createEnv(root))).toBe(true)
97
- expect(isFile(join(root, 'wiki.pre-v3/docs/observed.md'))).toBe(true)
98
- })
99
-
100
- test('version 1 knowledge is kept as a backup and personal items become global', () => {
101
- const root = mkdtempSync(join(tmpdir(), 'harness-migrate-'))
102
- writeJson(join(root, 'projects.json'), [{ id: 'p1', name: 'Xingular Agent', rootPath: '/tmp/x', autoMaintenance: true, createdAt: '2026-01-01T00:00:00Z' }])
103
- writeFile(join(root, 'knowledge/personal/wiki/overview.md'), '---\nid: overview\ntitle: Mine\ntype: summary\n---\n\nMine.\n')
104
- writeFile(join(root, 'config/registry-enabled.json'), '{"personal":["skills/a"],"p1":["rules/b"]}')
105
- expect(version(root)).toBe(1)
106
- expect(run(createEnv(root))).toBe(true)
107
- expect(isDir(join(root, 'knowledge'))).toBe(false)
108
- expect(isFile(join(root, 'knowledge.pre-v2/personal/wiki/overview.md'))).toBe(true)
109
- expect(isFile(join(wikiDir(root), 'blocks/projects/xingular-agent/brief.md'))).toBe(true)
110
- const enablement = readJson<Record<string, string[]>>(join(root, 'config/registry-enabled.json'))!
111
- expect(enablement.global[0]).toBe('skills/a')
112
- expect('personal' in enablement).toBe(false)
113
- })
114
-
115
- test('a failed migration leaves the wiki untouched', () => {
116
- const root = v2Layout()
117
- // An unreadable project registry makes staging fail.
118
- writeFileSync(join(root, 'projects.json'), 'not json')
119
- expect(() => run(createEnv(root))).toThrow()
120
- expect(isFile(join(root, 'wiki/docs/observed.md'))).toBe(true)
121
- expect(isDir(join(root, 'wiki.migrating')) || isDir(join(root, 'wiki.pre-v3'))).toBe(false)
122
- expect(version(root)).toBe(2)
123
- })
124
-
125
- test('fresh data roots need no migration', () => {
126
- const root = mkdtempSync(join(tmpdir(), 'harness-migrate-'))
127
- mkdirSync(root, { recursive: true })
128
- expect(version(root)).toBe(WIKI_VERSION)
129
- expect(run(createEnv(root))).toBe(false)
130
- })