@xingular/harness 0.1.6 → 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 (593) hide show
  1. package/CHANGELOG.md +107 -0
  2. package/LICENSE +202 -0
  3. package/NOTICE.md +60 -0
  4. package/README.md +265 -71
  5. package/THIRD_PARTY_LICENSES.md +942 -0
  6. package/dist/cli.js +14842 -9445
  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 +1170 -62
  373. package/docs/README.md +34 -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-0001-owned-terminal.md +87 -0
  403. package/docs/decisions/ADR-0002-native-subagent-lifecycle.md +49 -0
  404. package/docs/decisions/ADR-0003-shared-asynchronous-subagents.md +70 -0
  405. package/docs/decisions/ADR-0004-fullscreen-terminal-layout.md +50 -0
  406. package/docs/decisions/ADR-0005-app-provided-oauth-clients.md +54 -0
  407. package/docs/decisions/ADR-0006-opentui-only-terminal.md +47 -0
  408. package/docs/decisions/ADR-0007-reporting-section.md +33 -0
  409. package/docs/decisions/ADR-0008-flexible-reporting-guidance.md +38 -0
  410. package/docs/decisions/ADR-0009-xharness-command.md +38 -0
  411. package/docs/decisions/ADR-0010-lessons-in-the-wiki.md +31 -0
  412. package/docs/decisions/ADR-0011-foundation-and-variants.md +28 -0
  413. package/docs/decisions/ADR-0012-native-session-names.md +34 -0
  414. package/docs/decisions/ADR-0013-doctor.md +27 -0
  415. package/docs/decisions/ADR-0014-public-release-baseline.md +21 -0
  416. package/docs/doctor.md +74 -0
  417. package/docs/experiments/EXP-0001-terminal-input-latency/plan.md +81 -0
  418. package/docs/experiments/EXP-0001-terminal-input-latency/results.md +46 -0
  419. package/docs/experiments/EXP-0002-opentui-typing-latency/plan.md +70 -0
  420. package/docs/experiments/EXP-0002-opentui-typing-latency/results.md +92 -0
  421. package/docs/features/README.md +20 -0
  422. package/docs/features/automations/README.md +41 -0
  423. package/docs/features/cores/README.md +39 -0
  424. package/docs/features/google-harness2/README.md +52 -0
  425. package/docs/features/integrations/README.md +40 -0
  426. package/docs/features/interfaces/README.md +29 -0
  427. package/docs/features/memory/README.md +28 -0
  428. package/docs/releases/1.0.0.md +40 -0
  429. package/docs/releases/README.md +36 -0
  430. package/docs/study/00-index.md +78 -0
  431. package/docs/study/arms/00-matrix.md +20 -0
  432. package/docs/study/arms/01-system-prompt.md +211 -0
  433. package/docs/study/arms/02-tools.md +79 -0
  434. package/docs/study/arms/03-subagents.md +90 -0
  435. package/docs/study/arms/04-skills.md +75 -0
  436. package/docs/study/arms/05-context-management.md +90 -0
  437. package/docs/study/arms/06-memory.md +90 -0
  438. package/docs/study/arms/07-governance.md +71 -0
  439. package/docs/study/arms/08-execution.md +69 -0
  440. package/docs/study/arms/09-observability.md +60 -0
  441. package/docs/study/arms/10-refinement.md +110 -0
  442. package/docs/study/btw-comparison.md +37 -0
  443. package/docs/study/feature-gap-review.md +42 -0
  444. package/docs/study/insights.md +123 -0
  445. package/docs/study/roadmap.md +72 -0
  446. package/docs/study/sources/claude-code.md +44 -0
  447. package/docs/study/sources/deepseek-harness.md +102 -0
  448. package/docs/study/sources/harness2.md +50 -0
  449. package/docs/study/sources/kimi-cli.md +42 -0
  450. package/docs/study/sources/omp.md +93 -0
  451. package/docs/study/sources/opencode.md +43 -0
  452. package/docs/study/sources/openhands.md +46 -0
  453. package/docs/study/sources/smolagents.md +40 -0
  454. package/docs/study/sources/swe-agent.md +34 -0
  455. package/docs/system-prompt-design.md +196 -0
  456. package/docs/terminal-tui.md +671 -0
  457. package/package.json +48 -12
  458. package/src/accounts/accounts.test.ts +0 -223
  459. package/src/accounts/accounts.ts +0 -522
  460. package/src/accounts/env.test.ts +0 -95
  461. package/src/accounts/env.ts +0 -338
  462. package/src/accounts/secrets.ts +0 -50
  463. package/src/accounts/store.ts +0 -338
  464. package/src/capabilities/api.ts +0 -75
  465. package/src/capabilities/runSnapshot.ts +0 -59
  466. package/src/capabilities/types.ts +0 -34
  467. package/src/cli.ts +0 -114
  468. package/src/core/bus.ts +0 -34
  469. package/src/core/changes.ts +0 -33
  470. package/src/core/env.ts +0 -27
  471. package/src/core/errors.ts +0 -32
  472. package/src/core/frontmatter.ts +0 -47
  473. package/src/core/fs.test.ts +0 -38
  474. package/src/core/fs.ts +0 -92
  475. package/src/core/index.ts +0 -193
  476. package/src/core/path.test.ts +0 -14
  477. package/src/core/path.ts +0 -79
  478. package/src/core/projects.ts +0 -90
  479. package/src/core/text.ts +0 -39
  480. package/src/harness.ts +0 -299
  481. package/src/index.ts +0 -70
  482. package/src/mcp/connections.ts +0 -614
  483. package/src/mcp/manager.ts +0 -130
  484. package/src/mcp/oauth.ts +0 -195
  485. package/src/mcp/scopeMigration.test.ts +0 -79
  486. package/src/mcp/scopeMigration.ts +0 -204
  487. package/src/mcp/service.test.ts +0 -376
  488. package/src/mcp/service.ts +0 -549
  489. package/src/mcp/types.ts +0 -108
  490. package/src/memory/api.test.ts +0 -82
  491. package/src/memory/api.ts +0 -289
  492. package/src/memory/blocks.test.ts +0 -78
  493. package/src/memory/blocks.ts +0 -406
  494. package/src/memory/caller.ts +0 -57
  495. package/src/memory/dispatch.ts +0 -59
  496. package/src/memory/facts.test.ts +0 -41
  497. package/src/memory/facts.ts +0 -248
  498. package/src/memory/graph.ts +0 -103
  499. package/src/memory/health.test.ts +0 -130
  500. package/src/memory/health.ts +0 -74
  501. package/src/memory/maintainer.ts +0 -272
  502. package/src/memory/maintenance.test.ts +0 -176
  503. package/src/memory/maintenance.ts +0 -330
  504. package/src/memory/migrate.ts +0 -79
  505. package/src/memory/operations.ts +0 -138
  506. package/src/memory/proposals.test.ts +0 -168
  507. package/src/memory/proposals.ts +0 -576
  508. package/src/memory/recall.test.ts +0 -104
  509. package/src/memory/recall.ts +0 -271
  510. package/src/memory/references.ts +0 -77
  511. package/src/memory/runContext.ts +0 -93
  512. package/src/memory/secrets.ts +0 -6
  513. package/src/memory/store.test.ts +0 -66
  514. package/src/memory/store.ts +0 -385
  515. package/src/memory/wiki.test.ts +0 -47
  516. package/src/memory/wiki.ts +0 -422
  517. package/src/memory/wikiIndex.test.ts +0 -88
  518. package/src/memory/wikiIndex.ts +0 -116
  519. package/src/plugins/api.ts +0 -181
  520. package/src/plugins/attachments.test.ts +0 -84
  521. package/src/plugins/attachments.ts +0 -141
  522. package/src/plugins/builtin.ts +0 -82
  523. package/src/plugins/catalogue.test.ts +0 -254
  524. package/src/plugins/catalogue.ts +0 -251
  525. package/src/plugins/cli.ts +0 -184
  526. package/src/plugins/discover.ts +0 -151
  527. package/src/plugins/firstParty.test.ts +0 -143
  528. package/src/plugins/firstParty.ts +0 -129
  529. package/src/plugins/hooks.test.ts +0 -250
  530. package/src/plugins/hooks.ts +0 -239
  531. package/src/plugins/identity.ts +0 -37
  532. package/src/plugins/install.test.ts +0 -107
  533. package/src/plugins/install.ts +0 -106
  534. package/src/plugins/inventory.ts +0 -123
  535. package/src/plugins/manifest.ts +0 -76
  536. package/src/plugins/plugins.test.ts +0 -205
  537. package/src/plugins/plugins.ts +0 -189
  538. package/src/plugins/proposal.ts +0 -121
  539. package/src/plugins/runtime.test.ts +0 -40
  540. package/src/plugins/runtime.ts +0 -82
  541. package/src/plugins/trust.ts +0 -142
  542. package/src/plugins/types.ts +0 -149
  543. package/src/prompt/compile.test.ts +0 -261
  544. package/src/prompt/compile.ts +0 -732
  545. package/src/server/methods.ts +0 -314
  546. package/src/server/remote.ts +0 -77
  547. package/src/server/rpc.ts +0 -116
  548. package/src/server/serve.ts +0 -28
  549. package/src/server/server.test.ts +0 -174
  550. package/src/sessions/approvals.ts +0 -118
  551. package/src/sessions/contracts.ts +0 -310
  552. package/src/sessions/conversation.test.ts +0 -150
  553. package/src/sessions/extensionSession.test.ts +0 -74
  554. package/src/sessions/extensionUi.test.ts +0 -65
  555. package/src/sessions/extensionUi.ts +0 -102
  556. package/src/sessions/history.ts +0 -51
  557. package/src/sessions/lineageJoin.ts +0 -75
  558. package/src/sessions/policy.ts +0 -32
  559. package/src/sessions/pricing.ts +0 -60
  560. package/src/sessions/reasoningSummaries.ts +0 -59
  561. package/src/sessions/registry.ts +0 -294
  562. package/src/sessions/runIndex.ts +0 -99
  563. package/src/sessions/runStore.test.ts +0 -152
  564. package/src/sessions/runStore.ts +0 -332
  565. package/src/sessions/runner.ts +0 -569
  566. package/src/sessions/runtimeResources.test.ts +0 -61
  567. package/src/sessions/sessions.test.ts +0 -455
  568. package/src/sessions/sessions.ts +0 -295
  569. package/src/skills/registry.test.ts +0 -104
  570. package/src/skills/registry.ts +0 -407
  571. package/src/terminal/cli.ts +0 -149
  572. package/src/terminal/client.ts +0 -74
  573. package/src/terminal/controller.ts +0 -227
  574. package/src/terminal/launch.test.ts +0 -34
  575. package/src/terminal/launch.ts +0 -88
  576. package/src/terminal/piExtension.ts +0 -210
  577. package/src/terminal/pluginControl.test.ts +0 -146
  578. package/src/terminal/pluginMenu.ts +0 -112
  579. package/src/terminal/socket.test.ts +0 -71
  580. package/src/terminal/socket.ts +0 -221
  581. package/src/terminal/standalone.test.ts +0 -130
  582. package/src/terminal/standalone.ts +0 -144
  583. package/src/terminal/terminal.test.ts +0 -330
  584. package/src/terminal/terminals.ts +0 -443
  585. package/src/tools/askUser.ts +0 -45
  586. package/src/tools/definitions.ts +0 -187
  587. package/src/tools/memoryTools.ts +0 -22
  588. package/src/tools/pluginPropose.ts +0 -41
  589. package/src/tools/types.ts +0 -39
  590. package/src/web/safeRequest.ts +0 -171
  591. package/src/web/text.ts +0 -53
  592. package/src/web/tools.ts +0 -134
  593. package/src/web/web.test.ts +0 -141
@@ -1,422 +0,0 @@
1
- // The global Wiki. One corpus under `<data root>/wiki/`; skills, prompts, and rules are the
2
- // registry's items (`registry/`), shown and searched as Wiki objects without being copied.
3
- // Projects are path namespaces (`/projects/<slug>/…`), never access boundaries: everything may
4
- // be read, and the current project only makes its namespace more relevant.
5
- import { readdirSync, readFileSync } from 'node:fs'
6
- import { join } from 'node:path'
7
-
8
- import { noteChange } from '../core/changes'
9
- import { HarnessError, notFound } from '../core/errors'
10
- import * as frontmatter from '../core/frontmatter'
11
- import { atomicWrite, now } from '../core/fs'
12
- import { findProject, projectsOrNone } from '../core/projects'
13
- import { compareText, lines, takeChars } from '../core/text'
14
- import * as registry from '../skills/registry'
15
- import * as blocks from './blocks'
16
- import * as facts from './facts'
17
- import * as store from './store'
18
- import { firstParagraph, type ParsedPage, type WikiLink } from './store'
19
- import * as wikiIndex from './wikiIndex'
20
-
21
- export interface WikiPageSummary {
22
- id: string
23
- title: string
24
- type: string
25
- path: string
26
- namespace: string
27
- updatedAt: string
28
- sourceIds: string[]
29
- links: WikiLink[]
30
- }
31
-
32
- export interface WikiPage extends WikiPageSummary {
33
- body: string
34
- revisionId: string | null
35
- file: string
36
- }
37
-
38
- export function summary(page: ParsedPage): WikiPageSummary {
39
- return {
40
- id: page.frontmatter.id,
41
- title: page.frontmatter.title,
42
- type: page.frontmatter.type,
43
- path: page.location.path,
44
- namespace: page.location.namespace,
45
- updatedAt: page.frontmatter.updatedAt,
46
- sourceIds: page.frontmatter.sourceIds,
47
- links: page.frontmatter.links
48
- }
49
- }
50
-
51
- // ---- Index feed ----------------------------------------------------------------------
52
-
53
- export type EntryKind = 'page' | 'memory' | 'block' | 'skill' | 'rule' | 'prompt'
54
-
55
- /** One searchable entry as the index stores it. */
56
- export interface IndexedEntry {
57
- id: string
58
- kind: EntryKind
59
- title: string
60
- entryType: string
61
- path: string
62
- namespace: string
63
- file: string
64
- updatedAt: string
65
- body: string
66
- sourceIds: string[]
67
- /** `[to id, link type]`. */
68
- links: [string, string][]
69
- /** `[revision id, created at, actor]`. */
70
- revisions: [string, string, string][]
71
- }
72
-
73
- export interface IndexedSource {
74
- id: string
75
- name: string
76
- importedAt: string
77
- version: number
78
- }
79
-
80
- function revisionsOf(wiki: string, id: string): [string, string, string][] {
81
- try {
82
- return store.readManifest(wiki, id).map((revision) => [revision.id, revision.createdAt, revision.actor])
83
- } catch {
84
- return []
85
- }
86
- }
87
-
88
- /** Registry kind (`skills`) → entry kind (`skill`). */
89
- export function registryEntryKind(kind: string): 'skill' | 'rule' | 'prompt' | null {
90
- return kind === 'skills' ? 'skill' : kind === 'rules' ? 'rule' : kind === 'prompts' ? 'prompt' : null
91
- }
92
-
93
- const linkPairs = (links: readonly WikiLink[]): [string, string][] => links.map((link) => [link.toId, link.type])
94
-
95
- /** Everything the index holds: pages, facts, blocks, and registry skills/prompts/rules. */
96
- export function scan(root: string): { entries: IndexedEntry[]; sources: IndexedSource[] } {
97
- const wiki = store.wikiDir(root)
98
- const entries: IndexedEntry[] = store.loadPages(wiki).map((page) => ({
99
- id: page.frontmatter.id,
100
- kind: 'page',
101
- title: page.frontmatter.title,
102
- entryType: page.frontmatter.type,
103
- path: page.location.path,
104
- namespace: page.location.namespace,
105
- file: page.path,
106
- updatedAt: page.frontmatter.updatedAt,
107
- body: page.body,
108
- sourceIds: page.frontmatter.sourceIds,
109
- links: linkPairs(page.frontmatter.links),
110
- revisions: revisionsOf(wiki, page.frontmatter.id)
111
- }))
112
- for (const memory of facts.loadMemories(wiki)) {
113
- entries.push({
114
- id: memory.front.id,
115
- kind: 'memory',
116
- title: memory.front.title,
117
- entryType: memory.front.kind,
118
- path: `/facts/${memory.front.id}`,
119
- namespace: memory.front.namespace,
120
- file: memory.path,
121
- updatedAt: memory.front.updatedAt,
122
- body: memory.body,
123
- sourceIds: memory.front.sourceIds,
124
- links: linkPairs(memory.front.links),
125
- revisions: revisionsOf(wiki, memory.front.id)
126
- })
127
- }
128
- for (const block of blocks.loadAll(wiki)) {
129
- entries.push({
130
- id: block.id,
131
- kind: 'block',
132
- title: block.front.label,
133
- // The scope (`shared`, `agent`, `project`) decides who may see the block in a search.
134
- entryType: block.scope,
135
- path: `/${block.id}`,
136
- namespace: block.scope === 'project' && block.owner ? `/projects/${block.owner}` : store.ROOT_NAMESPACE,
137
- file: block.path,
138
- updatedAt: block.front.updatedAt,
139
- body: `${block.front.description}\n\n${block.body}`,
140
- sourceIds: [],
141
- links: [],
142
- revisions: revisionsOf(wiki, block.id)
143
- })
144
- }
145
- for (const item of registry.list(root)) {
146
- const kind = registryEntryKind(item.kind)
147
- if (!kind) continue
148
- entries.push({
149
- id: item.id,
150
- kind,
151
- title: item.name,
152
- entryType: kind,
153
- path: `/${item.id}`,
154
- namespace: store.ROOT_NAMESPACE,
155
- file: item.path,
156
- updatedAt: '',
157
- body: `${item.description}\n\n${registry.itemBody(item)}`,
158
- sourceIds: [],
159
- links: [],
160
- revisions: revisionsOf(wiki, item.id)
161
- })
162
- }
163
- const sources = store.listSources(wiki).map((source) => ({ id: source.id, name: source.name, importedAt: source.importedAt, version: source.version }))
164
- return { entries, sources }
165
- }
166
-
167
- export function countPages(root: string): number {
168
- return store.pageFiles(store.wikiDir(root)).length
169
- }
170
-
171
- // ---- Search ---------------------------------------------------------------------------
172
-
173
- export interface WikiSearchHit {
174
- id: string
175
- kind: string
176
- title: string
177
- type: string
178
- path: string
179
- namespace: string
180
- snippet: string
181
- }
182
-
183
- export interface SearchOptions {
184
- kinds?: string[]
185
- /** Only entries in this namespace (or below it). */
186
- namespace?: string | null
187
- /** Ranks this project's namespace higher; never filters. */
188
- projectId?: string | null
189
- limit?: number | null
190
- }
191
-
192
- export function inNamespace(namespace: string, filter: string | null | undefined): boolean {
193
- const prefix = filter?.replace(/\/+$/, '')
194
- return !prefix || namespace === prefix || namespace.startsWith(`${prefix}/`)
195
- }
196
-
197
- function snippet(body: string, needle: string): string {
198
- const line = lines(body).map((entry) => entry.trim()).find((entry) => needle && entry.toLowerCase().includes(needle)) ?? firstParagraph(body)
199
- return takeChars(line, 240)
200
- }
201
-
202
- /** Ranked hits across the whole Wiki. Falls back to scanning files when the index is unavailable. */
203
- export function searchEntries(root: string, query: string, options: SearchOptions = {}): WikiSearchHit[] {
204
- const limit = Math.min(Math.max(options.limit ?? 20, 1), 100)
205
- let boost: string | null = null
206
- if (options.projectId) {
207
- try {
208
- boost = findProject(root, options.projectId).wikiNamespace
209
- } catch {
210
- boost = null
211
- }
212
- }
213
- const { entries } = scan(root)
214
- const kinds = options.kinds ?? []
215
- let ranked: string[]
216
- try {
217
- ranked = wikiIndex.search(root, query, limit * 4, boost)
218
- } catch (error) {
219
- process.stderr.write(`[index] search fell back to files: ${error instanceof Error ? error.message : String(error)}\n`)
220
- const needle = query.trim().toLowerCase()
221
- if (!needle) return []
222
- const rank = (entry: IndexedEntry): number => (entry.namespace === boost ? 0 : 2) + (entry.title.toLowerCase().includes(needle) ? 0 : 1)
223
- ranked = entries
224
- .filter((entry) => entry.title.toLowerCase().includes(needle) || entry.body.toLowerCase().includes(needle))
225
- .map((entry, index) => ({ entry, index }))
226
- .sort((left, right) => rank(left.entry) - rank(right.entry) || left.index - right.index)
227
- .map(({ entry }) => entry.id)
228
- }
229
- // A volatile fact that has gone stale may no longer be true, so it ranks after everything else.
230
- const stale = new Set(facts.loadMemories(store.wikiDir(root)).filter((fact) => facts.isStale(fact.front)).map((fact) => fact.front.id))
231
- ranked = [...ranked.filter((id) => !stale.has(id)), ...ranked.filter((id) => stale.has(id))]
232
- const needle = (query.split(/\s+/).find(Boolean) ?? '').toLowerCase()
233
- const hits: WikiSearchHit[] = []
234
- for (const id of ranked) {
235
- if (hits.length >= limit) break
236
- const entry = entries.find((candidate) => candidate.id === id)
237
- if (!entry || (kinds.length && !kinds.includes(entry.kind)) || !inNamespace(entry.namespace, options.namespace)) continue
238
- hits.push({ id: entry.id, kind: entry.kind, title: entry.title, type: entry.entryType, path: entry.path, namespace: entry.namespace, snippet: snippet(entry.body, needle) })
239
- }
240
- return hits
241
- }
242
-
243
- // ---- Entries (pages, facts, blocks, registry items) ------------------------------------------
244
-
245
- export type EntryFile =
246
- | { kind: 'page'; page: ParsedPage }
247
- | { kind: 'memory'; memory: facts.ParsedMemory }
248
- | { kind: 'block'; block: blocks.Block }
249
- | { kind: 'registry'; item: registry.RegistryItem }
250
-
251
- /** Resolves a page id, fact id, registry id (`skills/<name>`), block id, or Wiki path (`/library/x`). */
252
- export function resolveEntry(root: string, rawKey: string): EntryFile {
253
- const wiki = store.wikiDir(root)
254
- const key = rawKey.trim()
255
- const registryKey = key.replace(/^\/+/, '')
256
- if (registryKey.startsWith('blocks/')) return { kind: 'block', block: blocks.find(wiki, registryKey) }
257
- const item = registry.list(root).find((entry) => entry.id === registryKey)
258
- if (item) return { kind: 'registry', item }
259
- const factId = key.startsWith('/facts/') ? key.slice('/facts/'.length) : key.startsWith('/memory/') ? key.slice('/memory/'.length) : null
260
- if (factId !== null) return { kind: 'memory', memory: facts.findMemory(wiki, factId) }
261
- const page = store.loadPages(wiki).find((entry) => entry.frontmatter.id === key || entry.location.path === key)
262
- if (page) return { kind: 'page', page }
263
- try {
264
- return { kind: 'memory', memory: facts.findMemory(wiki, key) }
265
- } catch {
266
- throw notFound('Wiki entry')
267
- }
268
- }
269
-
270
- export function entryId(entry: EntryFile): string {
271
- return entry.kind === 'page' ? entry.page.frontmatter.id : entry.kind === 'memory' ? entry.memory.front.id : entry.kind === 'block' ? entry.block.id : entry.item.id
272
- }
273
-
274
- export function entryFile(entry: EntryFile): string {
275
- return entry.kind === 'page' ? entry.page.path : entry.kind === 'memory' ? entry.memory.path : entry.kind === 'block' ? entry.block.path : entry.item.path
276
- }
277
-
278
- // ---- Reads for a person ------------------------------------------------------------------------
279
-
280
- export function listPages(root: string, namespace?: string | null): WikiPageSummary[] {
281
- return store.loadPages(store.wikiDir(root)).filter((page) => inNamespace(page.location.namespace, namespace)).map(summary)
282
- }
283
-
284
- export function loadPage(root: string, pageId: string): WikiPage {
285
- const wiki = store.wikiDir(root)
286
- const page = store.loadPages(wiki).find((entry) => entry.frontmatter.id === pageId || entry.location.path === pageId)
287
- if (!page) throw notFound('Page')
288
- return { ...summary(page), body: page.body, revisionId: store.currentRevision(wiki, page.frontmatter.id), file: page.path }
289
- }
290
-
291
- /** Revisions of an entry, newest first. */
292
- export function listRevisions(root: string, id: string): store.WikiRevision[] {
293
- return store.readManifest(store.wikiDir(root), id).reverse()
294
- }
295
-
296
- /** A revision's body without its frontmatter. */
297
- export function loadRevision(root: string, id: string, revisionId: string): string {
298
- const text = store.revisionText(store.wikiDir(root), id, revisionId)
299
- return frontmatter.split(text)?.body ?? text
300
- }
301
-
302
- /**
303
- * Restore never erases history: the current content is snapshotted, then the chosen revision
304
- * becomes the content and is itself recorded as a new revision. Works for every kind of entry.
305
- */
306
- export function restore(root: string, id: string, revisionId: string): void {
307
- const wiki = store.wikiDir(root)
308
- const entry = resolveEntry(root, id)
309
- const resolved = entryId(entry)
310
- const file = entryFile(entry)
311
- const revisionText = store.revisionText(wiki, resolved, revisionId)
312
- let nextText = revisionText
313
- if (entry.kind === 'page') {
314
- const restored = store.parsePage(revisionText, wiki, entry.page.path)
315
- if (!restored) throw new HarnessError('invalid_data', 'The revision could not be read as a Wiki page.')
316
- nextText = store.serializePage({ ...restored.frontmatter, id: entry.page.frontmatter.id, updatedAt: now() }, restored.body)
317
- } else if (entry.kind === 'memory') {
318
- if (!facts.parse(revisionText, file)) throw new HarnessError('invalid_data', 'The revision could not be read as a memory.')
319
- } else if (entry.kind === 'block') {
320
- const parsed = frontmatter.parse(revisionText)
321
- if (!parsed || !blocks.parseFront(parsed.front)) throw new HarnessError('invalid_data', 'The revision could not be read as a memory block.')
322
- }
323
- let currentText = ''
324
- try {
325
- currentText = readFileSync(file, 'utf8')
326
- } catch {
327
- currentText = ''
328
- }
329
- store.snapshot(wiki, resolved, currentText, 'user', 'Before restore')
330
- atomicWrite(file, nextText)
331
- const revision = store.snapshot(wiki, resolved, nextText, 'user', `Restored revision ${revisionId.slice(0, 8)}`)
332
- noteChange({ wiki, id: resolved, path: file, text: nextText, actor: 'user', reason: 'Restored an earlier revision' })
333
- store.log(wiki, `- ${now()} · user · restore · \`${resolved}\` · revision \`${revision.id}\``)
334
- }
335
-
336
- /** Any entry's content in one shape. */
337
- export interface WikiEntry {
338
- id: string
339
- kind: EntryKind
340
- title: string
341
- description: string
342
- body: string
343
- file: string
344
- revisionId: string | null
345
- }
346
-
347
- export function loadEntry(root: string, id: string): WikiEntry {
348
- const entry = resolveEntry(root, id)
349
- const shared = { file: entryFile(entry), revisionId: store.currentRevision(store.wikiDir(root), entryId(entry)) }
350
- if (entry.kind === 'page') return { id: entry.page.frontmatter.id, kind: 'page', title: entry.page.frontmatter.title, description: firstParagraph(entry.page.body), body: entry.page.body, ...shared }
351
- if (entry.kind === 'memory') return { id: entry.memory.front.id, kind: 'memory', title: entry.memory.front.title, description: entry.memory.front.kind, body: entry.memory.body, ...shared }
352
- if (entry.kind === 'block') return { id: entry.block.id, kind: 'block', title: entry.block.front.label, description: entry.block.front.description, body: entry.block.body, ...shared }
353
- return { id: entry.item.id, kind: registryEntryKind(entry.item.kind) ?? 'skill', title: entry.item.name, description: entry.item.description, body: registry.itemBody(entry.item), ...shared }
354
- }
355
-
356
- export interface Backlink {
357
- fromId: string
358
- kind: string
359
- title: string
360
- type: string
361
- }
362
-
363
- /** Entries that link to `id`, from the index's link table (files when it is unavailable). */
364
- export function backlinks(root: string, id: string): Backlink[] {
365
- const { entries } = scan(root)
366
- let pairs: [string, string][]
367
- try {
368
- pairs = wikiIndex.backlinks(root, id)
369
- } catch {
370
- pairs = entries.flatMap((entry) => entry.links.filter(([to]) => to === id).map(([, type]): [string, string] => [entry.id, type]))
371
- }
372
- return pairs.flatMap(([from, type]) => {
373
- const entry = entries.find((candidate) => candidate.id === from)
374
- return entry ? [{ fromId: from, kind: entry.kind, title: entry.title, type }] : []
375
- })
376
- }
377
-
378
- export interface WikiNamespace {
379
- namespace: string
380
- label: string
381
- projectId: string | null
382
- pageCount: number
383
- memoryCount: number
384
- }
385
-
386
- /** Project namespaces (registered projects first, then folders left by removed projects). */
387
- export function namespaces(root: string): WikiNamespace[] {
388
- const wiki = store.wikiDir(root)
389
- const pages = store.loadPages(wiki)
390
- const memories = facts.loadMemories(wiki)
391
- const counts = (namespace: string) => ({
392
- pageCount: pages.filter((page) => page.location.namespace === namespace).length,
393
- memoryCount: memories.filter((memory) => memory.front.namespace === namespace).length
394
- })
395
- const seen = new Set<string>()
396
- const result: WikiNamespace[] = []
397
- for (const project of projectsOrNone(root)) {
398
- seen.add(project.wikiNamespace)
399
- result.push({ namespace: project.wikiNamespace, label: project.name, projectId: project.id, ...counts(project.wikiNamespace) })
400
- }
401
- let folders: string[] = []
402
- try {
403
- folders = readdirSync(join(wiki, 'projects')).filter((name) => store.isDir(join(wiki, 'projects', name)))
404
- } catch {
405
- folders = []
406
- }
407
- for (const namespace of folders.map((name) => `/projects/${name}`).sort(compareText)) {
408
- if (!seen.has(namespace)) result.push({ namespace, label: namespace.slice('/projects/'.length), projectId: null, ...counts(namespace) })
409
- }
410
- return result
411
- }
412
-
413
- /** The newest 500 entries of `log.md`, newest first. */
414
- export function recentLog(root: string): string[] {
415
- let text = ''
416
- try {
417
- text = readFileSync(join(store.wikiDir(root), 'log.md'), 'utf8')
418
- } catch {
419
- text = ''
420
- }
421
- return lines(text).filter((line) => line.startsWith('- ')).map((line) => line.slice(2)).reverse().slice(0, 500)
422
- }
@@ -1,88 +0,0 @@
1
- import { mkdtempSync, rmSync, writeFileSync } from 'node:fs'
2
- import { tmpdir } from 'node:os'
3
- import { join } from 'node:path'
4
- import { DatabaseSync } from 'node:sqlite'
5
- import { expect, test } from 'vitest'
6
-
7
- import { writeFile } from '../../tests/helpers'
8
- import { writeJson } from '../core/fs'
9
- import { all, closeIndex, dbPath, migrate, withIndex } from '../core/index'
10
- import { runRecordSchema, type RunRecord } from '../sessions/contracts'
11
- import { recordRun, runsSince, syncRuns } from '../sessions/runIndex'
12
- import { ensure, rebuild, search } from './wikiIndex'
13
-
14
- const temp = () => mkdtempSync(join(tmpdir(), 'harness-index-'))
15
- const page = (root: string, relative: string, text: string) => writeFile(join(root, 'wiki', relative), text)
16
- const record = (fields: Partial<RunRecord> & { id: string }): RunRecord => runRecordSchema.parse({ projectId: null, mode: 'chat', harness: 'pi', sessionType: 'structured', sessionId: 'agent-1', nativeSessionId: null, workingDirectory: null, worktreeId: null, goal: null, startedAt: new Date().toISOString(), endedAt: null, status: 'completed', ...fields })
17
-
18
- test('rebuild indexes the whole wiki and boosts the current project', () => {
19
- const root = temp()
20
- page(root, 'library/a.md', '---\nid: tauri\ntitle: Use Tauri for the desktop shell\ntype: decision\n---\n\nRust host and React renderer.\n')
21
- page(root, 'projects/app/b.md', '---\nid: notes\ntitle: Meeting notes\ntype: summary\n---\n\nWe mentioned tauri once.\n')
22
- page(root, 'facts/m.md', '---\nid: shell\ntitle: Shell choice\nkind: decision\n---\n\nTauri stays.\n')
23
- expect(rebuild(root)).toBe(2)
24
- const first = search(root, 'tauri', 10, null)
25
- expect(first[0]).toBe('tauri')
26
- expect(first).toHaveLength(3)
27
- expect(search(root, 'rend', 10, null)).toEqual(['tauri'])
28
- // The current project's namespace ranks higher but nothing else is hidden.
29
- const boosted = search(root, 'tauri', 10, '/projects/app')
30
- expect(boosted.indexOf('notes')).toBeLessThanOrEqual(first.indexOf('notes'))
31
- expect(boosted).toHaveLength(3)
32
- // Rebuilding from files after deleting the index gives the same results.
33
- closeIndex(root)
34
- rmSync(dbPath(root))
35
- expect(ensure(root)).toBe(2)
36
- expect(search(root, 'tauri', 10, null)).toEqual(first)
37
- closeIndex(root)
38
- })
39
-
40
- test('runs are listed per account and agent and survive a rebuild', () => {
41
- const root = temp()
42
- const run = record({ id: 'run1', mode: 'code', harness: 'codex', sessionId: 's1', agentId: 'agent-7', accountId: 'acc1' })
43
- writeJson(join(root, 'runs/run1/run.json'), run)
44
- writeFileSync(join(root, 'runs/run1/events.jsonl'), '{"type":"usage.updated","payload":{"inputTokens":7,"outputTokens":3,"model":"gpt"}}\n')
45
- recordRun(root, run)
46
- expect(runsSince(root, { account: 'acc1' }, null)).toEqual(['run1'])
47
- expect(runsSince(root, { agent: 'agent-7' }, null)).toEqual(['run1'])
48
- rebuild(root)
49
- expect(runsSince(root, { account: 'acc1' }, null)).toEqual(['run1'])
50
- expect(runsSince(root, { agent: 'agent-7' }, null)).toEqual(['run1'])
51
- expect(runsSince(root, { agent: 'agent-8' }, null)).toEqual([])
52
- expect(withIndex(root, (database) => all<{ count: number }>(database, "SELECT COUNT(*) AS count FROM sqlite_master WHERE name = 'usage'")[0].count)).toBe(0)
53
- closeIndex(root)
54
- })
55
-
56
- test('runs the index never saw are picked up from their files', () => {
57
- const root = temp()
58
- const run = (id: string, status: string) => record({ id, status, startedAt: `2026-10-01T10:00:0${id.length}.000Z`, accountId: 'acc1' })
59
- // The index file exists with one run before the others are noticed, so `ensure` does not rebuild.
60
- writeJson(join(root, 'runs/a/run.json'), run('a', 'running'))
61
- recordRun(root, run('a', 'running'))
62
- writeJson(join(root, 'runs/a/run.json'), run('a', 'completed'))
63
- writeJson(join(root, 'runs/bb/run.json'), run('bb', 'completed'))
64
-
65
- ensure(root)
66
- expect(runsSince(root, { session: 'agent-1' }, null)).toEqual(['a', 'bb'])
67
- expect(runsSince(root, { session: 'agent-1' }, '2026-10-01T10:00:02.000Z')).toEqual(['bb'])
68
- // Chat runs from before the agent column count for the agent whose conversation they ran in.
69
- expect(runsSince(root, { agent: 'agent-1' }, null)).toHaveLength(2)
70
- expect(runsSince(root, { account: 'acc1' }, null)).toEqual(['a', 'bb'])
71
- expect(runsSince(root, { account: 'other' }, null)).toEqual([])
72
- expect(withIndex(root, (database) => all<{ status: string }>(database, "SELECT status FROM runs WHERE id = 'a'")[0].status)).toBe('completed')
73
- // Nothing is rewritten once the tables match the files.
74
- expect(syncRuns(root)).toBe(0)
75
- closeIndex(root)
76
- })
77
-
78
- test('failed migration restores the backup', () => {
79
- const path = join(temp(), 'index.sqlite')
80
- const good = ["CREATE TABLE kept (value TEXT); INSERT INTO kept VALUES ('before');"]
81
- migrate(path, good).close()
82
- expect(() => migrate(path, [good[0], 'CREATE TABLE extra (value TEXT); THIS IS NOT SQL;'])).toThrow('Index migration 2 failed')
83
- const database = new DatabaseSync(path)
84
- expect((database.prepare("SELECT value FROM meta WHERE key = 'schema_version'").get() as { value: string }).value).toBe('1')
85
- expect((database.prepare('SELECT value FROM kept').get() as { value: string }).value).toBe('before')
86
- expect(() => database.prepare('SELECT COUNT(*) FROM extra').get()).toThrow()
87
- database.close()
88
- })
@@ -1,116 +0,0 @@
1
- // The Wiki's rows in the index: full-text entries, links, sources, and revisions, all derived
2
- // from the canonical files.
3
- import { existsSync } from 'node:fs'
4
- import type { DatabaseSync } from 'node:sqlite'
5
-
6
- import { all, dbPath, deleteIndex, ftsQuery, run, transaction, withIndex } from '../core/index'
7
- import { readAllRuns, syncRuns, upsertRun } from '../sessions/runIndex'
8
- import { scan } from './wiki'
9
-
10
- /** Replaces every Wiki row from canonical files. Returns the number of pages indexed. */
11
- export function indexWiki(database: DatabaseSync, root: string): number {
12
- const { entries, sources } = scan(root)
13
- transaction(database, () => {
14
- for (const table of ['entries', 'entries_fts', 'links', 'sources', 'revisions']) database.exec(`DELETE FROM ${table}`)
15
- for (const entry of entries) {
16
- run(
17
- database,
18
- 'INSERT OR REPLACE INTO entries (id, kind, title, type, path, namespace, file, updated_at, source_ids) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9)',
19
- entry.id,
20
- entry.kind,
21
- entry.title,
22
- entry.entryType,
23
- entry.path,
24
- entry.namespace,
25
- entry.file,
26
- entry.updatedAt,
27
- JSON.stringify(entry.sourceIds)
28
- )
29
- const sourceNames = entry.sourceIds.flatMap((id) => sources.find((source) => source.id === id)?.name ?? [])
30
- run(
31
- database,
32
- 'INSERT INTO entries_fts (id, kind, namespace, title, body, links, sources) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)',
33
- entry.id,
34
- entry.kind,
35
- entry.namespace,
36
- entry.title,
37
- entry.body,
38
- entry.links.map(([to]) => to).join(' '),
39
- `${entry.path.replaceAll('/', ' ')} ${entry.sourceIds.join(' ')} ${sourceNames.join(' ')}`
40
- )
41
- for (const [to, type] of entry.links) run(database, 'INSERT INTO links (from_id, to_id, type) VALUES (?1, ?2, ?3)', entry.id, to, type)
42
- for (const [id, createdAt, actor] of entry.revisions) run(database, 'INSERT OR REPLACE INTO revisions (entry_id, id, created_at, actor) VALUES (?1, ?2, ?3, ?4)', entry.id, id, createdAt, actor)
43
- }
44
- for (const source of sources) run(database, 'INSERT OR REPLACE INTO sources (id, name, imported_at, version) VALUES (?1, ?2, ?3, ?4)', source.id, source.name, source.importedAt, source.version)
45
- })
46
- return entries.filter((entry) => entry.kind === 'page').length
47
- }
48
-
49
- export function reindexWiki(root: string): number {
50
- return withIndex(root, (database) => indexWiki(database, root))
51
- }
52
-
53
- /** `reindexWiki` for callers that must not fail because the index is unavailable. */
54
- export function reindexQuietly(root: string): void {
55
- try {
56
- reindexWiki(root)
57
- } catch (error) {
58
- process.stderr.write(`[index] reindex failed: ${error instanceof Error ? error.message : String(error)}\n`)
59
- }
60
- }
61
-
62
- /** Deletes the index and rebuilds it from canonical files. Returns pages indexed. */
63
- export function rebuild(root: string): number {
64
- deleteIndex(root)
65
- return withIndex(root, (database) => {
66
- const pages = indexWiki(database, root)
67
- const records = readAllRuns(root)
68
- transaction(database, () => records.forEach((record) => upsertRun(database, record)))
69
- return pages
70
- })
71
- }
72
-
73
- /**
74
- * Builds the index when it is missing and otherwise refreshes the Wiki rows, which also
75
- * catches edits made while nothing was running. `after` runs last, whatever happened before it.
76
- */
77
- export function ensure(root: string, after?: () => void): number {
78
- let pages: number
79
- if (existsSync(dbPath(root))) {
80
- pages = reindexWiki(root)
81
- try {
82
- syncRuns(root)
83
- } catch (error) {
84
- process.stderr.write(`[index] ${error instanceof Error ? error.message : String(error)}\n`)
85
- }
86
- } else {
87
- pages = rebuild(root)
88
- }
89
- after?.()
90
- return pages
91
- }
92
-
93
- /**
94
- * Ranked entry ids across the whole Wiki (best match first). Entries in `boostNamespace`
95
- * rank higher; nothing is filtered out by namespace here.
96
- */
97
- export function search(root: string, query: string, limit: number, boostNamespace: string | null): string[] {
98
- const fts = ftsQuery(query)
99
- if (!fts) return []
100
- return withIndex(root, (database) =>
101
- all<{ id: string }>(
102
- database,
103
- `SELECT id FROM entries_fts WHERE entries_fts MATCH ?1
104
- ORDER BY bm25(entries_fts, 0, 0, 0, 10.0, 1.0, 2.0, 2.0) * (CASE WHEN ?2 IS NOT NULL AND namespace = ?2 THEN 1.5 ELSE 1.0 END)
105
- LIMIT ?3`,
106
- fts,
107
- boostNamespace,
108
- limit
109
- ).map((row) => row.id)
110
- )
111
- }
112
-
113
- /** (from id, link type) for every entry linking to `entryId`. */
114
- export function backlinks(root: string, entryId: string): [string, string][] {
115
- return withIndex(root, (database) => all<{ from_id: string; type: string }>(database, 'SELECT from_id, type FROM links WHERE to_id = ?1 ORDER BY from_id', entryId).map((row) => [row.from_id, row.type]))
116
- }