@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,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
- }