@quickchatai/quickreview 0.0.0-stage → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1443) hide show
  1. package/LICENSE +23 -0
  2. package/README.md +385 -2
  3. package/THIRD-PARTY-NOTICES.md +134 -0
  4. package/agents/pass-abstraction.md +64 -0
  5. package/agents/pass-ask-human.md +134 -0
  6. package/agents/pass-backcompat.md +67 -0
  7. package/agents/pass-baseline.md +61 -0
  8. package/agents/pass-behaviour-delta.md +64 -0
  9. package/agents/pass-bounds.md +36 -0
  10. package/agents/pass-claims.md +31 -0
  11. package/agents/pass-concurrency.md +168 -0
  12. package/agents/pass-consistency.md +57 -0
  13. package/agents/pass-contracts.md +30 -0
  14. package/agents/pass-data-safety.md +54 -0
  15. package/agents/pass-deferred.md +35 -0
  16. package/agents/pass-delivery.md +37 -0
  17. package/agents/pass-duplication.md +60 -0
  18. package/agents/pass-intent.md +63 -0
  19. package/agents/pass-lint-conformance.md +46 -0
  20. package/agents/pass-maintainability.md +67 -0
  21. package/agents/pass-placement.md +68 -0
  22. package/agents/pass-prod-risk.md +24 -0
  23. package/agents/pass-rollout.md +32 -0
  24. package/agents/pass-roundtrip.md +46 -0
  25. package/agents/pass-security.md +31 -0
  26. package/agents/pass-simplicity.md +68 -0
  27. package/agents/pass-statelessness.md +27 -0
  28. package/agents/pass-style.md +37 -0
  29. package/agents/pass-sweep.md +57 -0
  30. package/agents/pass-tests.md +58 -0
  31. package/agents/pass-ui.md +23 -0
  32. package/agents/pass-validate.md +50 -0
  33. package/agents/pass-widened.md +46 -0
  34. package/agents/scan/pass-scan.md +86 -0
  35. package/bin/qcr.js +11 -0
  36. package/config.example.toml +1067 -0
  37. package/deploy/ansible/README.md +356 -0
  38. package/deploy/ansible/group_vars/all.yml +212 -0
  39. package/deploy/ansible/inventory.example.ini +25 -0
  40. package/deploy/ansible/playbook.yml +360 -0
  41. package/deploy/collect-secrets.sh +289 -0
  42. package/deploy/collect-slack-secrets.mjs +1190 -0
  43. package/deploy/github-app-manifest.json +31 -0
  44. package/deploy/manifest.schema.json +75 -0
  45. package/deploy/qcr-update.sh +803 -0
  46. package/deploy/reviewer/AGENTS.override.md +12 -0
  47. package/dist/extensions/cli/bash-guard-ambient.js +42 -0
  48. package/dist/extensions/cli/bash-guard-ambient.js.map +1 -0
  49. package/dist/extensions/cli/bash-guard.js +5 -0
  50. package/dist/extensions/cli/bash-guard.js.map +1 -0
  51. package/dist/extensions/cli/companion-guard.js +5 -0
  52. package/dist/extensions/cli/companion-guard.js.map +1 -0
  53. package/dist/extensions/cli/debug-round.js +8 -0
  54. package/dist/extensions/cli/debug-round.js.map +1 -0
  55. package/dist/extensions/cli/inject-bridge.js +5 -0
  56. package/dist/extensions/cli/inject-bridge.js.map +1 -0
  57. package/dist/extensions/cli/ledger-pin.js +5 -0
  58. package/dist/extensions/cli/ledger-pin.js.map +1 -0
  59. package/dist/extensions/cli/lens.js +13 -0
  60. package/dist/extensions/cli/lens.js.map +1 -0
  61. package/dist/extensions/cli/muted-theme.js +5 -0
  62. package/dist/extensions/cli/muted-theme.js.map +1 -0
  63. package/dist/extensions/cli/onboarding.js +5 -0
  64. package/dist/extensions/cli/onboarding.js.map +1 -0
  65. package/dist/extensions/cli/setup.js +5 -0
  66. package/dist/extensions/cli/setup.js.map +1 -0
  67. package/dist/extensions/cli/tui-view.js +5 -0
  68. package/dist/extensions/cli/tui-view.js.map +1 -0
  69. package/dist/extensions/companion-guard.js +361 -0
  70. package/dist/extensions/companion-guard.js.map +1 -0
  71. package/dist/extensions/debug-round.js +204 -0
  72. package/dist/extensions/debug-round.js.map +1 -0
  73. package/dist/extensions/inject-bridge.js +603 -0
  74. package/dist/extensions/inject-bridge.js.map +1 -0
  75. package/dist/extensions/muted-theme.js +12 -0
  76. package/dist/extensions/muted-theme.js.map +1 -0
  77. package/dist/extensions/onboarding.js +175 -0
  78. package/dist/extensions/onboarding.js.map +1 -0
  79. package/dist/extensions/setup-replay.js +269 -0
  80. package/dist/extensions/setup-replay.js.map +1 -0
  81. package/dist/extensions/setup-scan.js +998 -0
  82. package/dist/extensions/setup-scan.js.map +1 -0
  83. package/dist/extensions/setup-triage.js +175 -0
  84. package/dist/extensions/setup-triage.js.map +1 -0
  85. package/dist/extensions/setup.js +1160 -0
  86. package/dist/extensions/setup.js.map +1 -0
  87. package/dist/extensions/tui-view.js +389 -0
  88. package/dist/extensions/tui-view.js.map +1 -0
  89. package/dist/extensions/vendor/openviking-pi/client.js +376 -0
  90. package/dist/extensions/vendor/openviking-pi/client.js.map +1 -0
  91. package/dist/extensions/vendor/openviking-pi/config.js +189 -0
  92. package/dist/extensions/vendor/openviking-pi/config.js.map +1 -0
  93. package/dist/extensions/vendor/openviking-pi/index.js +421 -0
  94. package/dist/extensions/vendor/openviking-pi/index.js.map +1 -0
  95. package/dist/extensions/vendor/openviking-pi/lib/capture-adapter.mjs +86 -0
  96. package/dist/extensions/vendor/openviking-pi/lib/capture-adapter.mjs.map +1 -0
  97. package/dist/extensions/vendor/openviking-pi/lib/takeover-core.mjs +408 -0
  98. package/dist/extensions/vendor/openviking-pi/lib/takeover-core.mjs.map +1 -0
  99. package/dist/extensions/vendor/openviking-pi/lib/uri-guard-adapter.mjs +41 -0
  100. package/dist/extensions/vendor/openviking-pi/lib/uri-guard-adapter.mjs.map +1 -0
  101. package/dist/extensions/vendor/openviking-pi/qcr-hint.js +290 -0
  102. package/dist/extensions/vendor/openviking-pi/qcr-hint.js.map +1 -0
  103. package/dist/extensions/vendor/openviking-pi/qcr-honest.js +148 -0
  104. package/dist/extensions/vendor/openviking-pi/qcr-honest.js.map +1 -0
  105. package/dist/extensions/vendor/openviking-pi/qcr-hooks.js +68 -0
  106. package/dist/extensions/vendor/openviking-pi/qcr-hooks.js.map +1 -0
  107. package/dist/extensions/vendor/openviking-pi/qcr-leaf.js +77 -0
  108. package/dist/extensions/vendor/openviking-pi/qcr-leaf.js.map +1 -0
  109. package/dist/extensions/vendor/openviking-pi/qcr-lesson.js +216 -0
  110. package/dist/extensions/vendor/openviking-pi/qcr-lesson.js.map +1 -0
  111. package/dist/extensions/vendor/openviking-pi/qcr-namespaces.js +154 -0
  112. package/dist/extensions/vendor/openviking-pi/qcr-namespaces.js.map +1 -0
  113. package/dist/extensions/vendor/openviking-pi/qcr-recall.js +254 -0
  114. package/dist/extensions/vendor/openviking-pi/qcr-recall.js.map +1 -0
  115. package/dist/extensions/vendor/openviking-pi/qcr-shim.js +94 -0
  116. package/dist/extensions/vendor/openviking-pi/qcr-shim.js.map +1 -0
  117. package/dist/extensions/vendor/openviking-pi/qcr-write.js +333 -0
  118. package/dist/extensions/vendor/openviking-pi/qcr-write.js.map +1 -0
  119. package/dist/extensions/vendor/openviking-pi/recall.js +108 -0
  120. package/dist/extensions/vendor/openviking-pi/recall.js.map +1 -0
  121. package/dist/extensions/vendor/openviking-pi/shared/capture-utils.mjs +529 -0
  122. package/dist/extensions/vendor/openviking-pi/shared/capture-utils.mjs.map +1 -0
  123. package/dist/extensions/vendor/openviking-pi/shared/credentials.mjs +205 -0
  124. package/dist/extensions/vendor/openviking-pi/shared/credentials.mjs.map +1 -0
  125. package/dist/extensions/vendor/openviking-pi/shared/pending-queue.mjs +442 -0
  126. package/dist/extensions/vendor/openviking-pi/shared/pending-queue.mjs.map +1 -0
  127. package/dist/extensions/vendor/openviking-pi/shared/profile-inject.mjs +286 -0
  128. package/dist/extensions/vendor/openviking-pi/shared/profile-inject.mjs.map +1 -0
  129. package/dist/extensions/vendor/openviking-pi/shared/recall-compress-core.mjs +189 -0
  130. package/dist/extensions/vendor/openviking-pi/shared/recall-compress-core.mjs.map +1 -0
  131. package/dist/extensions/vendor/openviking-pi/shared/recall-core.mjs +580 -0
  132. package/dist/extensions/vendor/openviking-pi/shared/recall-core.mjs.map +1 -0
  133. package/dist/extensions/vendor/openviking-pi/shared/retryable.mjs +11 -0
  134. package/dist/extensions/vendor/openviking-pi/shared/retryable.mjs.map +1 -0
  135. package/dist/extensions/vendor/openviking-pi/shared/session-model.mjs +63 -0
  136. package/dist/extensions/vendor/openviking-pi/shared/session-model.mjs.map +1 -0
  137. package/dist/extensions/vendor/openviking-pi/shared/uri-guard.mjs +58 -0
  138. package/dist/extensions/vendor/openviking-pi/shared/uri-guard.mjs.map +1 -0
  139. package/dist/extensions/vendor/openviking-pi/shared/workspace-peer.mjs +16 -0
  140. package/dist/extensions/vendor/openviking-pi/shared/workspace-peer.mjs.map +1 -0
  141. package/dist/extensions/vendor/openviking-pi/sync.js +127 -0
  142. package/dist/extensions/vendor/openviking-pi/sync.js.map +1 -0
  143. package/dist/extensions/vendor/openviking-pi/takeover.js +25 -0
  144. package/dist/extensions/vendor/openviking-pi/takeover.js.map +1 -0
  145. package/dist/extensions/vendor/openviking-pi/tools.js +417 -0
  146. package/dist/extensions/vendor/openviking-pi/tools.js.map +1 -0
  147. package/dist/src/anomalies.js +483 -0
  148. package/dist/src/anomalies.js.map +1 -0
  149. package/dist/src/answerworker.js +180 -0
  150. package/dist/src/answerworker.js.map +1 -0
  151. package/dist/src/appstamp.js +68 -0
  152. package/dist/src/appstamp.js.map +1 -0
  153. package/dist/src/archive/admission.js +3 -0
  154. package/dist/src/archive/admission.js.map +1 -0
  155. package/dist/src/archive/archivedb.js +474 -0
  156. package/dist/src/archive/archivedb.js.map +1 -0
  157. package/dist/src/archive/archiver.js +1770 -0
  158. package/dist/src/archive/archiver.js.map +1 -0
  159. package/dist/src/archive/archivewrite.js +198 -0
  160. package/dist/src/archive/archivewrite.js.map +1 -0
  161. package/dist/src/archive/bundle.js +266 -0
  162. package/dist/src/archive/bundle.js.map +1 -0
  163. package/dist/src/archive/dbmove.js +638 -0
  164. package/dist/src/archive/dbmove.js.map +1 -0
  165. package/dist/src/archive/duplicatecounts.js +80 -0
  166. package/dist/src/archive/duplicatecounts.js.map +1 -0
  167. package/dist/src/archive/eligibility.js +113 -0
  168. package/dist/src/archive/eligibility.js.map +1 -0
  169. package/dist/src/archive/extract.js +288 -0
  170. package/dist/src/archive/extract.js.map +1 -0
  171. package/dist/src/archive/fsutil.js +330 -0
  172. package/dist/src/archive/fsutil.js.map +1 -0
  173. package/dist/src/archive/gzfile.js +277 -0
  174. package/dist/src/archive/gzfile.js.map +1 -0
  175. package/dist/src/archive/kinds.js +22 -0
  176. package/dist/src/archive/kinds.js.map +1 -0
  177. package/dist/src/archive/livecheckpoint.js +178 -0
  178. package/dist/src/archive/livecheckpoint.js.map +1 -0
  179. package/dist/src/archive/liveretention.js +145 -0
  180. package/dist/src/archive/liveretention.js.map +1 -0
  181. package/dist/src/archive/manifest.js +284 -0
  182. package/dist/src/archive/manifest.js.map +1 -0
  183. package/dist/src/archive/overseer.js +283 -0
  184. package/dist/src/archive/overseer.js.map +1 -0
  185. package/dist/src/archive/piglobal.js +129 -0
  186. package/dist/src/archive/piglobal.js.map +1 -0
  187. package/dist/src/archive/plan.js +398 -0
  188. package/dist/src/archive/plan.js.map +1 -0
  189. package/dist/src/archive/prarchive.js +831 -0
  190. package/dist/src/archive/prarchive.js.map +1 -0
  191. package/dist/src/archive/prfiles.js +303 -0
  192. package/dist/src/archive/prfiles.js.map +1 -0
  193. package/dist/src/archive/report.js +169 -0
  194. package/dist/src/archive/report.js.map +1 -0
  195. package/dist/src/archive/restore.js +276 -0
  196. package/dist/src/archive/restore.js.map +1 -0
  197. package/dist/src/archive/rows.js +106 -0
  198. package/dist/src/archive/rows.js.map +1 -0
  199. package/dist/src/archive/seal.js +480 -0
  200. package/dist/src/archive/seal.js.map +1 -0
  201. package/dist/src/archive/status.js +528 -0
  202. package/dist/src/archive/status.js.map +1 -0
  203. package/dist/src/archive/storepass.js +409 -0
  204. package/dist/src/archive/storepass.js.map +1 -0
  205. package/dist/src/backfill.js +217 -0
  206. package/dist/src/backfill.js.map +1 -0
  207. package/dist/src/bench/cost.js +87 -0
  208. package/dist/src/bench/exec.js +76 -0
  209. package/dist/src/bench/values.js +14 -0
  210. package/dist/src/botcontrol.js +127 -0
  211. package/dist/src/botcontrol.js.map +1 -0
  212. package/dist/src/botworker.js +805 -0
  213. package/dist/src/botworker.js.map +1 -0
  214. package/dist/src/capture.js +234 -0
  215. package/dist/src/capture.js.map +1 -0
  216. package/dist/src/cases.js +1491 -0
  217. package/dist/src/cases.js.map +1 -0
  218. package/dist/src/channelfs.js +27 -0
  219. package/dist/src/channelfs.js.map +1 -0
  220. package/dist/src/checklist.js +312 -0
  221. package/dist/src/checklist.js.map +1 -0
  222. package/dist/src/ciretry.js +91 -0
  223. package/dist/src/ciretry.js.map +1 -0
  224. package/dist/src/cli.js +1916 -0
  225. package/dist/src/cli.js.map +1 -0
  226. package/dist/src/cliops.js +333 -0
  227. package/dist/src/cliops.js.map +1 -0
  228. package/dist/src/clonedir.js +15 -0
  229. package/dist/src/clonedir.js.map +1 -0
  230. package/dist/src/commandeffects.js +43 -0
  231. package/dist/src/commandeffects.js.map +1 -0
  232. package/dist/src/commands.js +1312 -0
  233. package/dist/src/commands.js.map +1 -0
  234. package/dist/src/companioninbox.js +203 -0
  235. package/dist/src/companioninbox.js.map +1 -0
  236. package/dist/src/compare.js +673 -0
  237. package/dist/src/compare.js.map +1 -0
  238. package/dist/src/config.js +1027 -0
  239. package/dist/src/config.js.map +1 -0
  240. package/dist/src/configcheck.js +111 -0
  241. package/dist/src/configcheck.js.map +1 -0
  242. package/dist/src/coreext.js +43 -0
  243. package/dist/src/coreext.js.map +1 -0
  244. package/dist/src/daemon.js +929 -0
  245. package/dist/src/daemon.js.map +1 -0
  246. package/dist/src/debuground.js +731 -0
  247. package/dist/src/debuground.js.map +1 -0
  248. package/dist/src/debugroundpi.js +219 -0
  249. package/dist/src/debugroundpi.js.map +1 -0
  250. package/dist/src/diagnostics.js +14 -0
  251. package/dist/src/diagnostics.js.map +1 -0
  252. package/dist/src/digest.js +139 -0
  253. package/dist/src/digest.js.map +1 -0
  254. package/dist/src/dispatch.js +1726 -0
  255. package/dist/src/dispatch.js.map +1 -0
  256. package/dist/src/engine/answerguard.js +18 -0
  257. package/dist/src/engine/answerguard.js.map +1 -0
  258. package/dist/src/engine/botsdk.js +262 -0
  259. package/dist/src/engine/botsdk.js.map +1 -0
  260. package/dist/src/engine/caserunner-sdk.js +332 -0
  261. package/dist/src/engine/caserunner-sdk.js.map +1 -0
  262. package/dist/src/engine/debugpi.js +194 -0
  263. package/dist/src/engine/debugpi.js.map +1 -0
  264. package/dist/src/eod.js +473 -0
  265. package/dist/src/eod.js.map +1 -0
  266. package/dist/src/eodpinwatch.js +391 -0
  267. package/dist/src/eodpinwatch.js.map +1 -0
  268. package/dist/src/escalation.js +1009 -0
  269. package/dist/src/escalation.js.map +1 -0
  270. package/dist/src/eventloop.js +779 -0
  271. package/dist/src/eventloop.js.map +1 -0
  272. package/dist/src/execboundary.js +430 -0
  273. package/dist/src/execboundary.js.map +1 -0
  274. package/dist/src/feedback.js +915 -0
  275. package/dist/src/feedback.js.map +1 -0
  276. package/dist/src/findingscheck.js +200 -0
  277. package/dist/src/findingscheck.js.map +1 -0
  278. package/dist/src/fsdenied.js +26 -0
  279. package/dist/src/fsdenied.js.map +1 -0
  280. package/dist/src/ghread.js +181 -0
  281. package/dist/src/ghread.js.map +1 -0
  282. package/dist/src/github.js +1063 -0
  283. package/dist/src/github.js.map +1 -0
  284. package/dist/src/homes.js +103 -0
  285. package/dist/src/homes.js.map +1 -0
  286. package/dist/src/hostroute.js +24 -0
  287. package/dist/src/hostroute.js.map +1 -0
  288. package/dist/src/improvements.js +625 -0
  289. package/dist/src/improvements.js.map +1 -0
  290. package/dist/src/install.js +946 -0
  291. package/dist/src/install.js.map +1 -0
  292. package/dist/src/installkind.js +40 -0
  293. package/dist/src/installkind.js.map +1 -0
  294. package/dist/src/ipc/capability.js +286 -0
  295. package/dist/src/ipc/capability.js.map +1 -0
  296. package/dist/src/ipc/client.js +226 -0
  297. package/dist/src/ipc/client.js.map +1 -0
  298. package/dist/src/ipc/control.js +70 -0
  299. package/dist/src/ipc/control.js.map +1 -0
  300. package/dist/src/ipc/ghreadshim.js +77 -0
  301. package/dist/src/ipc/ghreadshim.js.map +1 -0
  302. package/dist/src/ipc/launcher.js +65 -0
  303. package/dist/src/ipc/launcher.js.map +1 -0
  304. package/dist/src/ipc/permits.js +293 -0
  305. package/dist/src/ipc/permits.js.map +1 -0
  306. package/dist/src/ipc/postshim.js +137 -0
  307. package/dist/src/ipc/postshim.js.map +1 -0
  308. package/dist/src/ipc/protocol.js +239 -0
  309. package/dist/src/ipc/protocol.js.map +1 -0
  310. package/dist/src/ipc/server.js +312 -0
  311. package/dist/src/ipc/server.js.map +1 -0
  312. package/dist/src/ipc/workerspec.js +148 -0
  313. package/dist/src/ipc/workerspec.js.map +1 -0
  314. package/dist/src/learner/learner.js +1272 -0
  315. package/dist/src/learner/learner.js.map +1 -0
  316. package/dist/src/learner/miner.js +948 -0
  317. package/dist/src/learner/miner.js.map +1 -0
  318. package/dist/src/learner/packet.js +216 -0
  319. package/dist/src/learner/packet.js.map +1 -0
  320. package/dist/src/learner/receipt.js +135 -0
  321. package/dist/src/learner/receipt.js.map +1 -0
  322. package/dist/src/learner/status.js +38 -0
  323. package/dist/src/learner/status.js.map +1 -0
  324. package/dist/src/ledgercheck.js +120 -0
  325. package/dist/src/ledgercheck.js.map +1 -0
  326. package/dist/src/lessonledger.js +451 -0
  327. package/dist/src/lessonledger.js.map +1 -0
  328. package/dist/src/lessonselect.js +639 -0
  329. package/dist/src/lessonselect.js.map +1 -0
  330. package/dist/src/lessonshadow.js +540 -0
  331. package/dist/src/lessonshadow.js.map +1 -0
  332. package/dist/src/levers.js +302 -0
  333. package/dist/src/levers.js.map +1 -0
  334. package/dist/src/live/projection.js +450 -0
  335. package/dist/src/live/projection.js.map +1 -0
  336. package/dist/src/live/publish.js +83 -0
  337. package/dist/src/live/publish.js.map +1 -0
  338. package/dist/src/live/read.js +60 -0
  339. package/dist/src/live/read.js.map +1 -0
  340. package/dist/src/livecli.js +288 -0
  341. package/dist/src/livecli.js.map +1 -0
  342. package/dist/src/loginhint.js +42 -0
  343. package/dist/src/loginhint.js.map +1 -0
  344. package/dist/src/loginrefresh/atomic.js +66 -0
  345. package/dist/src/loginrefresh/atomic.js.map +1 -0
  346. package/dist/src/loginrefresh/lock.js +93 -0
  347. package/dist/src/loginrefresh/lock.js.map +1 -0
  348. package/dist/src/loginrefresh/main.js +58 -0
  349. package/dist/src/loginrefresh/main.js.map +1 -0
  350. package/dist/src/loginrefresh/pirefresh.js +49 -0
  351. package/dist/src/loginrefresh/pirefresh.js.map +1 -0
  352. package/dist/src/loginrefresh/refresher.js +286 -0
  353. package/dist/src/loginrefresh/refresher.js.map +1 -0
  354. package/dist/src/loginrefresh/supervisor.js +253 -0
  355. package/dist/src/loginrefresh/supervisor.js.map +1 -0
  356. package/dist/src/loginrefresh/types.js +4 -0
  357. package/dist/src/loginrefresh/types.js.map +1 -0
  358. package/dist/src/memory/context.js +251 -0
  359. package/dist/src/memory/context.js.map +1 -0
  360. package/dist/src/memory/datafence.js +5 -0
  361. package/dist/src/memory/datafence.js.map +1 -0
  362. package/dist/src/memory/delivery.js +131 -0
  363. package/dist/src/memory/delivery.js.map +1 -0
  364. package/dist/src/memory/eventtags.js +81 -0
  365. package/dist/src/memory/eventtags.js.map +1 -0
  366. package/dist/src/memory/health.js +713 -0
  367. package/dist/src/memory/health.js.map +1 -0
  368. package/dist/src/memory/import.js +504 -0
  369. package/dist/src/memory/import.js.map +1 -0
  370. package/dist/src/memory/layout.js +252 -0
  371. package/dist/src/memory/layout.js.map +1 -0
  372. package/dist/src/memory/legacy-file.js +100 -0
  373. package/dist/src/memory/legacy-file.js.map +1 -0
  374. package/dist/src/memory/lessons.js +370 -0
  375. package/dist/src/memory/lessons.js.map +1 -0
  376. package/dist/src/memory/ovsession.js +449 -0
  377. package/dist/src/memory/ovsession.js.map +1 -0
  378. package/dist/src/memory/relayout.js +259 -0
  379. package/dist/src/memory/relayout.js.map +1 -0
  380. package/dist/src/memory/roundactivity.js +180 -0
  381. package/dist/src/memory/roundactivity.js.map +1 -0
  382. package/dist/src/memory/selection.js +690 -0
  383. package/dist/src/memory/selection.js.map +1 -0
  384. package/dist/src/memory/shadowstatus.js +69 -0
  385. package/dist/src/memory/shadowstatus.js.map +1 -0
  386. package/dist/src/memory/store.js +83 -0
  387. package/dist/src/memory/store.js.map +1 -0
  388. package/dist/src/memory/textidentity.js +8 -0
  389. package/dist/src/memory/textidentity.js.map +1 -0
  390. package/dist/src/metrics.js +773 -0
  391. package/dist/src/metrics.js.map +1 -0
  392. package/dist/src/missingconfig.js +8 -0
  393. package/dist/src/missingconfig.js.map +1 -0
  394. package/dist/src/npmverbs.js +226 -0
  395. package/dist/src/npmverbs.js.map +1 -0
  396. package/dist/src/onboard/choices.js +191 -0
  397. package/dist/src/onboard/choices.js.map +1 -0
  398. package/dist/src/onboard/engine.js +344 -0
  399. package/dist/src/onboard/engine.js.map +1 -0
  400. package/dist/src/onboard/launch.js +83 -0
  401. package/dist/src/onboard/launch.js.map +1 -0
  402. package/dist/src/onboard/steps/appslug.js +211 -0
  403. package/dist/src/onboard/steps/appslug.js.map +1 -0
  404. package/dist/src/onboard/steps/bringup.js +408 -0
  405. package/dist/src/onboard/steps/bringup.js.map +1 -0
  406. package/dist/src/onboard/steps/compose.js +343 -0
  407. package/dist/src/onboard/steps/compose.js.map +1 -0
  408. package/dist/src/onboard/steps/configdelivery.js +50 -0
  409. package/dist/src/onboard/steps/configdelivery.js.map +1 -0
  410. package/dist/src/onboard/steps/configfill.js +1148 -0
  411. package/dist/src/onboard/steps/configfill.js.map +1 -0
  412. package/dist/src/onboard/steps/deploysh.js +80 -0
  413. package/dist/src/onboard/steps/deploysh.js.map +1 -0
  414. package/dist/src/onboard/steps/embeddings.js +472 -0
  415. package/dist/src/onboard/steps/embeddings.js.map +1 -0
  416. package/dist/src/onboard/steps/escalation.js +571 -0
  417. package/dist/src/onboard/steps/escalation.js.map +1 -0
  418. package/dist/src/onboard/steps/githubapp.js +1092 -0
  419. package/dist/src/onboard/steps/githubapp.js.map +1 -0
  420. package/dist/src/onboard/steps/golive.js +506 -0
  421. package/dist/src/onboard/steps/golive.js.map +1 -0
  422. package/dist/src/onboard/steps/index.js +67 -0
  423. package/dist/src/onboard/steps/index.js.map +1 -0
  424. package/dist/src/onboard/steps/ingress.js +762 -0
  425. package/dist/src/onboard/steps/ingress.js.map +1 -0
  426. package/dist/src/onboard/steps/inventory.js +420 -0
  427. package/dist/src/onboard/steps/inventory.js.map +1 -0
  428. package/dist/src/onboard/steps/llmauth.js +893 -0
  429. package/dist/src/onboard/steps/llmauth.js.map +1 -0
  430. package/dist/src/onboard/steps/memory.js +1060 -0
  431. package/dist/src/onboard/steps/memory.js.map +1 -0
  432. package/dist/src/onboard/steps/memorykeys.js +43 -0
  433. package/dist/src/onboard/steps/memorykeys.js.map +1 -0
  434. package/dist/src/onboard/steps/preflight.js +172 -0
  435. package/dist/src/onboard/steps/preflight.js.map +1 -0
  436. package/dist/src/onboard/steps/proof.js +502 -0
  437. package/dist/src/onboard/steps/proof.js.map +1 -0
  438. package/dist/src/onboard/steps/ssh.js +300 -0
  439. package/dist/src/onboard/steps/ssh.js.map +1 -0
  440. package/dist/src/onboard/steps/topology.js +291 -0
  441. package/dist/src/onboard/steps/topology.js.map +1 -0
  442. package/dist/src/onboard/steps/transport.js +511 -0
  443. package/dist/src/onboard/steps/transport.js.map +1 -0
  444. package/dist/src/onboard/steps/verifyup.js +362 -0
  445. package/dist/src/onboard/steps/verifyup.js.map +1 -0
  446. package/dist/src/onboard/steps/vmdeploy.js +368 -0
  447. package/dist/src/onboard/steps/vmdeploy.js.map +1 -0
  448. package/dist/src/onboard/toml.js +53 -0
  449. package/dist/src/onboard/toml.js.map +1 -0
  450. package/dist/src/opencli.js +508 -0
  451. package/dist/src/opencli.js.map +1 -0
  452. package/dist/src/openpr.js +457 -0
  453. package/dist/src/openpr.js.map +1 -0
  454. package/dist/src/openviking/client.js +821 -0
  455. package/dist/src/openviking/client.js.map +1 -0
  456. package/dist/src/openviking/context.js +218 -0
  457. package/dist/src/openviking/context.js.map +1 -0
  458. package/dist/src/openviking/embedder.js +457 -0
  459. package/dist/src/openviking/embedder.js.map +1 -0
  460. package/dist/src/openviking/gapsink.js +38 -0
  461. package/dist/src/openviking/gapsink.js.map +1 -0
  462. package/dist/src/openviking/health.js +69 -0
  463. package/dist/src/openviking/health.js.map +1 -0
  464. package/dist/src/openviking/index.js +24 -0
  465. package/dist/src/openviking/index.js.map +1 -0
  466. package/dist/src/openviking/lessonfind.js +54 -0
  467. package/dist/src/openviking/lessonfind.js.map +1 -0
  468. package/dist/src/openviking/probe.js +89 -0
  469. package/dist/src/openviking/probe.js.map +1 -0
  470. package/dist/src/openviking/proc.js +95 -0
  471. package/dist/src/openviking/proc.js.map +1 -0
  472. package/dist/src/openviking/provisionreport.js +144 -0
  473. package/dist/src/openviking/provisionreport.js.map +1 -0
  474. package/dist/src/openviking/reembed.js +317 -0
  475. package/dist/src/openviking/reembed.js.map +1 -0
  476. package/dist/src/openviking/relayout.js +153 -0
  477. package/dist/src/openviking/relayout.js.map +1 -0
  478. package/dist/src/openviking/sidecar-main.js +39 -0
  479. package/dist/src/openviking/sidecar-main.js.map +1 -0
  480. package/dist/src/openviking/sidecar.js +79 -0
  481. package/dist/src/openviking/sidecar.js.map +1 -0
  482. package/dist/src/openviking/store.js +1758 -0
  483. package/dist/src/openviking/store.js.map +1 -0
  484. package/dist/src/openviking/supervisor.js +422 -0
  485. package/dist/src/openviking/supervisor.js.map +1 -0
  486. package/dist/src/openviking/types.js +5 -0
  487. package/dist/src/openviking/types.js.map +1 -0
  488. package/dist/src/operator-recovery.js +172 -0
  489. package/dist/src/operator-recovery.js.map +1 -0
  490. package/dist/src/operatormessage.js +44 -0
  491. package/dist/src/operatormessage.js.map +1 -0
  492. package/dist/src/outcomes.js +1361 -0
  493. package/dist/src/outcomes.js.map +1 -0
  494. package/dist/src/piauthcopy.js +5 -0
  495. package/dist/src/piauthcopy.js.map +1 -0
  496. package/dist/src/picli.js +45 -0
  497. package/dist/src/picli.js.map +1 -0
  498. package/dist/src/picwd.js +25 -0
  499. package/dist/src/picwd.js.map +1 -0
  500. package/dist/src/pilogin.js +35 -0
  501. package/dist/src/pilogin.js.map +1 -0
  502. package/dist/src/pingpong.js +1028 -0
  503. package/dist/src/pingpong.js.map +1 -0
  504. package/dist/src/posting-journal.js +441 -0
  505. package/dist/src/posting-journal.js.map +1 -0
  506. package/dist/src/posting-outbox.js +662 -0
  507. package/dist/src/posting-outbox.js.map +1 -0
  508. package/dist/src/posting-receipt.js +203 -0
  509. package/dist/src/posting-receipt.js.map +1 -0
  510. package/dist/src/posting.js +348 -0
  511. package/dist/src/posting.js.map +1 -0
  512. package/dist/src/postops.js +637 -0
  513. package/dist/src/postops.js.map +1 -0
  514. package/dist/src/pr-activity.js +11 -0
  515. package/dist/src/pr-activity.js.map +1 -0
  516. package/dist/src/pr-author.js +5 -0
  517. package/dist/src/pr-author.js.map +1 -0
  518. package/dist/src/pr-conversation.js +355 -0
  519. package/dist/src/pr-conversation.js.map +1 -0
  520. package/dist/src/pr-session-lifecycle.js +542 -0
  521. package/dist/src/pr-session-lifecycle.js.map +1 -0
  522. package/dist/src/preflight.js +341 -0
  523. package/dist/src/preflight.js.map +1 -0
  524. package/dist/src/priorresolve.js +275 -0
  525. package/dist/src/priorresolve.js.map +1 -0
  526. package/dist/src/qcrbin.js +180 -0
  527. package/dist/src/qcrbin.js.map +1 -0
  528. package/dist/src/recheck.js +1398 -0
  529. package/dist/src/recheck.js.map +1 -0
  530. package/dist/src/reconcile.js +820 -0
  531. package/dist/src/reconcile.js.map +1 -0
  532. package/dist/src/recordedfindings.js +15 -0
  533. package/dist/src/recordedfindings.js.map +1 -0
  534. package/dist/src/regression.js +546 -0
  535. package/dist/src/regression.js.map +1 -0
  536. package/dist/src/replay.js +598 -0
  537. package/dist/src/replay.js.map +1 -0
  538. package/dist/src/requiredpasses.js +113 -0
  539. package/dist/src/requiredpasses.js.map +1 -0
  540. package/dist/src/resumecheck.js +168 -0
  541. package/dist/src/resumecheck.js.map +1 -0
  542. package/dist/src/reviewcli.js +671 -0
  543. package/dist/src/reviewcli.js.map +1 -0
  544. package/dist/src/reviewcontext.js +22 -0
  545. package/dist/src/reviewcontext.js.map +1 -0
  546. package/dist/src/reviewdetach.js +574 -0
  547. package/dist/src/reviewdetach.js.map +1 -0
  548. package/dist/src/reviewhistory.js +284 -0
  549. package/dist/src/reviewhistory.js.map +1 -0
  550. package/dist/src/reviewhome.js +26 -0
  551. package/dist/src/reviewhome.js.map +1 -0
  552. package/dist/src/reviewmemory.js +110 -0
  553. package/dist/src/reviewmemory.js.map +1 -0
  554. package/dist/src/reviewrendercli.js +104 -0
  555. package/dist/src/reviewrendercli.js.map +1 -0
  556. package/dist/src/round-work.js +20 -0
  557. package/dist/src/round-work.js.map +1 -0
  558. package/dist/src/runhost.js +72 -0
  559. package/dist/src/runhost.js.map +1 -0
  560. package/dist/src/scanauth.js +25 -0
  561. package/dist/src/scanauth.js.map +1 -0
  562. package/dist/src/scanbox.js +846 -0
  563. package/dist/src/scanbox.js.map +1 -0
  564. package/dist/src/scancli.js +1074 -0
  565. package/dist/src/scancli.js.map +1 -0
  566. package/dist/src/scandriverlog.js +30 -0
  567. package/dist/src/scandriverlog.js.map +1 -0
  568. package/dist/src/session-bridge.js +75 -0
  569. package/dist/src/session-bridge.js.map +1 -0
  570. package/dist/src/session-command-payload.js +29 -0
  571. package/dist/src/session-command-payload.js.map +1 -0
  572. package/dist/src/session-command-supervisor.js +939 -0
  573. package/dist/src/session-command-supervisor.js.map +1 -0
  574. package/dist/src/sessionjsonl.js +85 -0
  575. package/dist/src/sessionjsonl.js.map +1 -0
  576. package/dist/src/sessions.js +541 -0
  577. package/dist/src/sessions.js.map +1 -0
  578. package/dist/src/setup/adapters.js +330 -0
  579. package/dist/src/setup/adapters.js.map +1 -0
  580. package/dist/src/setup/baselines.js +64 -0
  581. package/dist/src/setup/baselines.js.map +1 -0
  582. package/dist/src/setup/caserunner.js +554 -0
  583. package/dist/src/setup/caserunner.js.map +1 -0
  584. package/dist/src/setup/configcommit.js +358 -0
  585. package/dist/src/setup/configcommit.js.map +1 -0
  586. package/dist/src/setup/engine.js +672 -0
  587. package/dist/src/setup/engine.js.map +1 -0
  588. package/dist/src/setup/facts.js +593 -0
  589. package/dist/src/setup/facts.js.map +1 -0
  590. package/dist/src/setup/findings.js +948 -0
  591. package/dist/src/setup/findings.js.map +1 -0
  592. package/dist/src/setup/history.js +338 -0
  593. package/dist/src/setup/history.js.map +1 -0
  594. package/dist/src/setup/interview.js +185 -0
  595. package/dist/src/setup/interview.js.map +1 -0
  596. package/dist/src/setup/ledger.js +207 -0
  597. package/dist/src/setup/ledger.js.map +1 -0
  598. package/dist/src/setup/pins.js +43 -0
  599. package/dist/src/setup/pins.js.map +1 -0
  600. package/dist/src/setup/portrait.js +432 -0
  601. package/dist/src/setup/portrait.js.map +1 -0
  602. package/dist/src/setup/presentation.js +9 -0
  603. package/dist/src/setup/presentation.js.map +1 -0
  604. package/dist/src/setup/profile.js +417 -0
  605. package/dist/src/setup/profile.js.map +1 -0
  606. package/dist/src/setup/replay.js +240 -0
  607. package/dist/src/setup/replay.js.map +1 -0
  608. package/dist/src/setup/replaybuild.js +311 -0
  609. package/dist/src/setup/replaybuild.js.map +1 -0
  610. package/dist/src/setup/replayrun.js +806 -0
  611. package/dist/src/setup/replayrun.js.map +1 -0
  612. package/dist/src/setup/replaysource.js +169 -0
  613. package/dist/src/setup/replaysource.js.map +1 -0
  614. package/dist/src/setup/retune.js +333 -0
  615. package/dist/src/setup/retune.js.map +1 -0
  616. package/dist/src/setup/retunelog.js +51 -0
  617. package/dist/src/setup/retunelog.js.map +1 -0
  618. package/dist/src/setup/scan.js +725 -0
  619. package/dist/src/setup/scan.js.map +1 -0
  620. package/dist/src/setup/scanbuild.js +133 -0
  621. package/dist/src/setup/scanbuild.js.map +1 -0
  622. package/dist/src/setup/scanfacts.js +96 -0
  623. package/dist/src/setup/scanfacts.js.map +1 -0
  624. package/dist/src/setup/scanlease.js +251 -0
  625. package/dist/src/setup/scanlease.js.map +1 -0
  626. package/dist/src/setup/scanreport.js +289 -0
  627. package/dist/src/setup/scanreport.js.map +1 -0
  628. package/dist/src/setup/scanrun.js +1733 -0
  629. package/dist/src/setup/scanrun.js.map +1 -0
  630. package/dist/src/setup/scantree.js +257 -0
  631. package/dist/src/setup/scantree.js.map +1 -0
  632. package/dist/src/setup/stage2.js +617 -0
  633. package/dist/src/setup/stage2.js.map +1 -0
  634. package/dist/src/setup/stage2request.js +259 -0
  635. package/dist/src/setup/stage2request.js.map +1 -0
  636. package/dist/src/setup/survey.js +307 -0
  637. package/dist/src/setup/survey.js.map +1 -0
  638. package/dist/src/setup/surveyrun.js +549 -0
  639. package/dist/src/setup/surveyrun.js.map +1 -0
  640. package/dist/src/setup/textsniff.js +89 -0
  641. package/dist/src/setup/textsniff.js.map +1 -0
  642. package/dist/src/setup/trackersink.js +395 -0
  643. package/dist/src/setup/trackersink.js.map +1 -0
  644. package/dist/src/setup/triage.js +636 -0
  645. package/dist/src/setup/triage.js.map +1 -0
  646. package/dist/src/setup/tuning.js +585 -0
  647. package/dist/src/setup/tuning.js.map +1 -0
  648. package/dist/src/setup/unitcut.js +437 -0
  649. package/dist/src/setup/unitcut.js.map +1 -0
  650. package/dist/src/singleflight.js +72 -0
  651. package/dist/src/singleflight.js.map +1 -0
  652. package/dist/src/slack/announce.js +725 -0
  653. package/dist/src/slack/announce.js.map +1 -0
  654. package/dist/src/slack/api.js +227 -0
  655. package/dist/src/slack/api.js.map +1 -0
  656. package/dist/src/slack/messages.js +158 -0
  657. package/dist/src/slack/messages.js.map +1 -0
  658. package/dist/src/slack/origin.js +550 -0
  659. package/dist/src/slack/origin.js.map +1 -0
  660. package/dist/src/slack/policy.js +225 -0
  661. package/dist/src/slack/policy.js.map +1 -0
  662. package/dist/src/slack/reply.js +153 -0
  663. package/dist/src/slack/reply.js.map +1 -0
  664. package/dist/src/slack/router.js +189 -0
  665. package/dist/src/slack/router.js.map +1 -0
  666. package/dist/src/slack/socket.js +323 -0
  667. package/dist/src/slack/socket.js.map +1 -0
  668. package/dist/src/slack/types.js +11 -0
  669. package/dist/src/slack/types.js.map +1 -0
  670. package/dist/src/sqlitehint.js +30 -0
  671. package/dist/src/sqlitehint.js.map +1 -0
  672. package/dist/src/ssh-observation.js +25 -0
  673. package/dist/src/ssh-observation.js.map +1 -0
  674. package/dist/src/state.js +5869 -0
  675. package/dist/src/state.js.map +1 -0
  676. package/dist/src/statemachine.js +220 -0
  677. package/dist/src/statemachine.js.map +1 -0
  678. package/dist/src/stubs.js +52 -0
  679. package/dist/src/stubs.js.map +1 -0
  680. package/dist/src/takeover.js +506 -0
  681. package/dist/src/takeover.js.map +1 -0
  682. package/dist/src/takeoverpi.js +249 -0
  683. package/dist/src/takeoverpi.js.map +1 -0
  684. package/dist/src/terminal-failure.js +26 -0
  685. package/dist/src/terminal-failure.js.map +1 -0
  686. package/dist/src/thread-resolution-refusal.js +4 -0
  687. package/dist/src/thread-resolution-refusal.js.map +1 -0
  688. package/dist/src/tmux.js +126 -0
  689. package/dist/src/tmux.js.map +1 -0
  690. package/dist/src/trackerid.js +43 -0
  691. package/dist/src/trackerid.js.map +1 -0
  692. package/dist/src/transcriptindex.js +512 -0
  693. package/dist/src/transcriptindex.js.map +1 -0
  694. package/dist/src/tui/actions.js +404 -0
  695. package/dist/src/tui/actions.js.map +1 -0
  696. package/dist/src/tui/alerts.js +523 -0
  697. package/dist/src/tui/alerts.js.map +1 -0
  698. package/dist/src/tui/app.js +1835 -0
  699. package/dist/src/tui/app.js.map +1 -0
  700. package/dist/src/tui/archiveops.js +164 -0
  701. package/dist/src/tui/archiveops.js.map +1 -0
  702. package/dist/src/tui/autofile.js +191 -0
  703. package/dist/src/tui/autofile.js.map +1 -0
  704. package/dist/src/tui/board.js +1143 -0
  705. package/dist/src/tui/board.js.map +1 -0
  706. package/dist/src/tui/candidates.js +699 -0
  707. package/dist/src/tui/candidates.js.map +1 -0
  708. package/dist/src/tui/cellwidth.js +151 -0
  709. package/dist/src/tui/cellwidth.js.map +1 -0
  710. package/dist/src/tui/changelog-store.js +404 -0
  711. package/dist/src/tui/changelog-store.js.map +1 -0
  712. package/dist/src/tui/chord.js +26 -0
  713. package/dist/src/tui/chord.js.map +1 -0
  714. package/dist/src/tui/clipboard.js +81 -0
  715. package/dist/src/tui/clipboard.js.map +1 -0
  716. package/dist/src/tui/cmdbar.js +253 -0
  717. package/dist/src/tui/cmdbar.js.map +1 -0
  718. package/dist/src/tui/companion.js +1275 -0
  719. package/dist/src/tui/companion.js.map +1 -0
  720. package/dist/src/tui/companionplan.js +200 -0
  721. package/dist/src/tui/companionplan.js.map +1 -0
  722. package/dist/src/tui/companiontab.js +61 -0
  723. package/dist/src/tui/companiontab.js.map +1 -0
  724. package/dist/src/tui/confighome.js +105 -0
  725. package/dist/src/tui/confighome.js.map +1 -0
  726. package/dist/src/tui/connect.js +44 -0
  727. package/dist/src/tui/connect.js.map +1 -0
  728. package/dist/src/tui/deploy-ceremony.js +75 -0
  729. package/dist/src/tui/deploy-ceremony.js.map +1 -0
  730. package/dist/src/tui/deploy-drain.js +93 -0
  731. package/dist/src/tui/deploy-drain.js.map +1 -0
  732. package/dist/src/tui/deploy-process.js +234 -0
  733. package/dist/src/tui/deploy-process.js.map +1 -0
  734. package/dist/src/tui/deploytab.js +1263 -0
  735. package/dist/src/tui/deploytab.js.map +1 -0
  736. package/dist/src/tui/design.js +111 -0
  737. package/dist/src/tui/design.js.map +1 -0
  738. package/dist/src/tui/digesttab.js +148 -0
  739. package/dist/src/tui/digesttab.js.map +1 -0
  740. package/dist/src/tui/emptystate.js +32 -0
  741. package/dist/src/tui/emptystate.js.map +1 -0
  742. package/dist/src/tui/evidence.js +790 -0
  743. package/dist/src/tui/evidence.js.map +1 -0
  744. package/dist/src/tui/feed.js +415 -0
  745. package/dist/src/tui/feed.js.map +1 -0
  746. package/dist/src/tui/feedbacktab.js +907 -0
  747. package/dist/src/tui/feedbacktab.js.map +1 -0
  748. package/dist/src/tui/filters.js +72 -0
  749. package/dist/src/tui/filters.js.map +1 -0
  750. package/dist/src/tui/ghread.js +272 -0
  751. package/dist/src/tui/ghread.js.map +1 -0
  752. package/dist/src/tui/historypull.js +61 -0
  753. package/dist/src/tui/historypull.js.map +1 -0
  754. package/dist/src/tui/inboxpull.js +197 -0
  755. package/dist/src/tui/inboxpull.js.map +1 -0
  756. package/dist/src/tui/index.js +1425 -0
  757. package/dist/src/tui/index.js.map +1 -0
  758. package/dist/src/tui/issuesink.js +206 -0
  759. package/dist/src/tui/issuesink.js.map +1 -0
  760. package/dist/src/tui/jsonfile.js +32 -0
  761. package/dist/src/tui/jsonfile.js.map +1 -0
  762. package/dist/src/tui/keys.js +97 -0
  763. package/dist/src/tui/keys.js.map +1 -0
  764. package/dist/src/tui/layout.js +70 -0
  765. package/dist/src/tui/layout.js.map +1 -0
  766. package/dist/src/tui/learning.js +469 -0
  767. package/dist/src/tui/learning.js.map +1 -0
  768. package/dist/src/tui/lessonswitch.js +103 -0
  769. package/dist/src/tui/lessonswitch.js.map +1 -0
  770. package/dist/src/tui/livecontrol.js +167 -0
  771. package/dist/src/tui/livecontrol.js.map +1 -0
  772. package/dist/src/tui/memforward.js +310 -0
  773. package/dist/src/tui/memforward.js.map +1 -0
  774. package/dist/src/tui/memincident.js +287 -0
  775. package/dist/src/tui/memincident.js.map +1 -0
  776. package/dist/src/tui/memory.js +485 -0
  777. package/dist/src/tui/memory.js.map +1 -0
  778. package/dist/src/tui/memtab.js +513 -0
  779. package/dist/src/tui/memtab.js.map +1 -0
  780. package/dist/src/tui/metricstab.js +979 -0
  781. package/dist/src/tui/metricstab.js.map +1 -0
  782. package/dist/src/tui/model.js +104 -0
  783. package/dist/src/tui/model.js.map +1 -0
  784. package/dist/src/tui/mouse.js +83 -0
  785. package/dist/src/tui/mouse.js.map +1 -0
  786. package/dist/src/tui/msg.js +196 -0
  787. package/dist/src/tui/msg.js.map +1 -0
  788. package/dist/src/tui/nativecompanion.js +321 -0
  789. package/dist/src/tui/nativecompanion.js.map +1 -0
  790. package/dist/src/tui/openurl.js +17 -0
  791. package/dist/src/tui/openurl.js.map +1 -0
  792. package/dist/src/tui/paint.js +501 -0
  793. package/dist/src/tui/paint.js.map +1 -0
  794. package/dist/src/tui/panes.js +74 -0
  795. package/dist/src/tui/panes.js.map +1 -0
  796. package/dist/src/tui/pipane.js +166 -0
  797. package/dist/src/tui/pipane.js.map +1 -0
  798. package/dist/src/tui/poll-hooks.js +11 -0
  799. package/dist/src/tui/poll-hooks.js.map +1 -0
  800. package/dist/src/tui/poll.js +113 -0
  801. package/dist/src/tui/poll.js.map +1 -0
  802. package/dist/src/tui/proposals.js +715 -0
  803. package/dist/src/tui/proposals.js.map +1 -0
  804. package/dist/src/tui/prpause.js +132 -0
  805. package/dist/src/tui/prpause.js.map +1 -0
  806. package/dist/src/tui/reload.js +351 -0
  807. package/dist/src/tui/reload.js.map +1 -0
  808. package/dist/src/tui/remote.js +312 -0
  809. package/dist/src/tui/remote.js.map +1 -0
  810. package/dist/src/tui/rollover.js +767 -0
  811. package/dist/src/tui/rollover.js.map +1 -0
  812. package/dist/src/tui/scantab.js +1053 -0
  813. package/dist/src/tui/scantab.js.map +1 -0
  814. package/dist/src/tui/setupentry.js +81 -0
  815. package/dist/src/tui/setupentry.js.map +1 -0
  816. package/dist/src/tui/sidebar.js +602 -0
  817. package/dist/src/tui/sidebar.js.map +1 -0
  818. package/dist/src/tui/sshtriage.js +393 -0
  819. package/dist/src/tui/sshtriage.js.map +1 -0
  820. package/dist/src/tui/startup.js +172 -0
  821. package/dist/src/tui/startup.js.map +1 -0
  822. package/dist/src/tui/tabs.js +41 -0
  823. package/dist/src/tui/tabs.js.map +1 -0
  824. package/dist/src/tui/termmirror.js +217 -0
  825. package/dist/src/tui/termmirror.js.map +1 -0
  826. package/dist/src/tui/theme.js +95 -0
  827. package/dist/src/tui/theme.js.map +1 -0
  828. package/dist/src/tui/ticketstab.js +224 -0
  829. package/dist/src/tui/ticketstab.js.map +1 -0
  830. package/dist/src/tui/tmuxsocket.js +101 -0
  831. package/dist/src/tui/tmuxsocket.js.map +1 -0
  832. package/dist/src/tui/trackertickets.js +77 -0
  833. package/dist/src/tui/trackertickets.js.map +1 -0
  834. package/dist/src/tui/unwedge.js +245 -0
  835. package/dist/src/tui/unwedge.js.map +1 -0
  836. package/dist/src/tui/viewer.js +479 -0
  837. package/dist/src/tui/viewer.js.map +1 -0
  838. package/dist/src/tui/viewerinput.js +125 -0
  839. package/dist/src/tui/viewerinput.js.map +1 -0
  840. package/dist/src/updatenotice.js +143 -0
  841. package/dist/src/updatenotice.js.map +1 -0
  842. package/dist/src/usage.js +1007 -0
  843. package/dist/src/usage.js.map +1 -0
  844. package/dist/src/verdicts.js +3848 -0
  845. package/dist/src/verdicts.js.map +1 -0
  846. package/dist/src/version.js +58 -0
  847. package/dist/src/version.js.map +1 -0
  848. package/dist/src/wakes.js +411 -0
  849. package/dist/src/wakes.js.map +1 -0
  850. package/dist/src/webhook.js +725 -0
  851. package/dist/src/webhook.js.map +1 -0
  852. package/dist/src/webhookheal.js +238 -0
  853. package/dist/src/webhookheal.js.map +1 -0
  854. package/dist/src/wire.js +1801 -0
  855. package/dist/src/wire.js.map +1 -0
  856. package/dist/src/worker-session-host.js +531 -0
  857. package/dist/src/worker-session-host.js.map +1 -0
  858. package/dist/src/workerbreaker.js +112 -0
  859. package/dist/src/workerbreaker.js.map +1 -0
  860. package/dist/src/workercontrol.js +49 -0
  861. package/dist/src/workercontrol.js.map +1 -0
  862. package/dist/src/workerlease.js +351 -0
  863. package/dist/src/workerlease.js.map +1 -0
  864. package/dist/src/workerliveness.js +84 -0
  865. package/dist/src/workerliveness.js.map +1 -0
  866. package/dist/src/workerlog.js +65 -0
  867. package/dist/src/workerlog.js.map +1 -0
  868. package/dist/src/workerruntime.js +10 -0
  869. package/dist/src/workerruntime.js.map +1 -0
  870. package/dist/src/workersupervisor.js +1206 -0
  871. package/dist/src/workersupervisor.js.map +1 -0
  872. package/dist/src/workerusage.js +23 -0
  873. package/dist/src/workerusage.js.map +1 -0
  874. package/dist/src/workerworld.js +332 -0
  875. package/dist/src/workerworld.js.map +1 -0
  876. package/dist/src/worktrees.js +984 -0
  877. package/dist/src/worktrees.js.map +1 -0
  878. package/docker/Dockerfile +284 -0
  879. package/docker/Dockerfile.dockerignore +35 -0
  880. package/docker/README.md +221 -0
  881. package/docker/companion/Dockerfile +139 -0
  882. package/docker/companion/agents/evidence.md +34 -0
  883. package/docker/companion/agents/explore.md +26 -0
  884. package/docker/companion/agents/pass-survey.md +49 -0
  885. package/docker/companion/agents/study.md +26 -0
  886. package/docker/companion/entrypoint.sh +343 -0
  887. package/docker/companion/memory-health.mjs +269 -0
  888. package/docker/entrypoint.sh +782 -0
  889. package/docker/memory/Dockerfile +191 -0
  890. package/docker/memory/Dockerfile.dockerignore +20 -0
  891. package/docker/memory/README.md +60 -0
  892. package/docker/memory/entrypoint.sh +163 -0
  893. package/docker/setid/qcr-setid.c +109 -0
  894. package/docker/tunnel/Dockerfile.cloudflared +51 -0
  895. package/docker/tunnel/Dockerfile.ngrok +40 -0
  896. package/docker/tunnel/sidecar.mjs +411 -0
  897. package/docker/vm/tmux.conf +26 -0
  898. package/docker-compose.yml +348 -0
  899. package/extensions/cli/bash-guard-ambient.ts +71 -0
  900. package/extensions/cli/bash-guard.ts +12 -0
  901. package/extensions/cli/companion-guard.ts +8 -0
  902. package/extensions/cli/debug-round.ts +9 -0
  903. package/extensions/cli/inject-bridge.ts +8 -0
  904. package/extensions/cli/ledger-pin.ts +13 -0
  905. package/extensions/cli/lens.ts +22 -0
  906. package/extensions/cli/muted-theme.ts +9 -0
  907. package/extensions/cli/onboarding.ts +8 -0
  908. package/extensions/cli/setup.ts +8 -0
  909. package/extensions/cli/tui-view.ts +8 -0
  910. package/extensions/companion-guard.ts +411 -0
  911. package/extensions/debug-round.ts +281 -0
  912. package/extensions/inject-bridge.ts +630 -0
  913. package/extensions/inline-bash.ts +102 -0
  914. package/extensions/muted-theme.json +68 -0
  915. package/extensions/muted-theme.ts +23 -0
  916. package/extensions/onboarding.ts +233 -0
  917. package/extensions/setup-replay.ts +336 -0
  918. package/extensions/setup-scan.ts +1236 -0
  919. package/extensions/setup-triage.ts +190 -0
  920. package/extensions/setup.ts +1428 -0
  921. package/extensions/tui-view.ts +489 -0
  922. package/extensions/vendor/openviking-pi/LICENSE +201 -0
  923. package/extensions/vendor/openviking-pi/NOTICE +68 -0
  924. package/extensions/vendor/openviking-pi/README.md +550 -0
  925. package/extensions/vendor/openviking-pi/client.ts +588 -0
  926. package/extensions/vendor/openviking-pi/config.json +28 -0
  927. package/extensions/vendor/openviking-pi/config.ts +271 -0
  928. package/extensions/vendor/openviking-pi/index.ts +523 -0
  929. package/extensions/vendor/openviking-pi/lib/capture-adapter.d.mts +10 -0
  930. package/extensions/vendor/openviking-pi/lib/capture-adapter.mjs +88 -0
  931. package/extensions/vendor/openviking-pi/lib/takeover-core.d.mts +80 -0
  932. package/extensions/vendor/openviking-pi/lib/takeover-core.mjs +406 -0
  933. package/extensions/vendor/openviking-pi/lib/uri-guard-adapter.d.mts +1 -0
  934. package/extensions/vendor/openviking-pi/lib/uri-guard-adapter.mjs +42 -0
  935. package/extensions/vendor/openviking-pi/patches/0000-vendoring-and-build-conformance.patch +726 -0
  936. package/extensions/vendor/openviking-pi/patches/0001-remove-session-before-compact-handler.patch +101 -0
  937. package/extensions/vendor/openviking-pi/patches/0002-no-ambient-work-in-subagent-leaves.patch +202 -0
  938. package/extensions/vendor/openviking-pi/patches/0003-never-auto-create-openviking-sessions.patch +120 -0
  939. package/extensions/vendor/openviking-pi/patches/0004-viking-write-durable-batch-write.patch +521 -0
  940. package/extensions/vendor/openviking-pi/patches/0005-second-memory-namespace.patch +786 -0
  941. package/extensions/vendor/openviking-pi/patches/0006-writes-that-stick-and-honest-errors.patch +996 -0
  942. package/extensions/vendor/openviking-pi/patches/0007-bounded-recall-no-commit.patch +794 -0
  943. package/extensions/vendor/openviking-pi/patches/0008-pr-derived-recall.patch +379 -0
  944. package/extensions/vendor/openviking-pi/patches/0009-pr-session-tools-in-round-areas.patch +375 -0
  945. package/extensions/vendor/openviking-pi/patches/0010-typed-lessons.patch +448 -0
  946. package/extensions/vendor/openviking-pi/patches/0011-review-session-memory-boundary.patch +382 -0
  947. package/extensions/vendor/openviking-pi/patches/0012-typecheck-against-the-real-pi.patch +129 -0
  948. package/extensions/vendor/openviking-pi/patches/0013-createopenviking-factory.patch +1168 -0
  949. package/extensions/vendor/openviking-pi/qcr-hint.ts +313 -0
  950. package/extensions/vendor/openviking-pi/qcr-honest.ts +183 -0
  951. package/extensions/vendor/openviking-pi/qcr-hooks.ts +87 -0
  952. package/extensions/vendor/openviking-pi/qcr-leaf.ts +78 -0
  953. package/extensions/vendor/openviking-pi/qcr-lesson.ts +231 -0
  954. package/extensions/vendor/openviking-pi/qcr-namespaces.ts +198 -0
  955. package/extensions/vendor/openviking-pi/qcr-recall.ts +288 -0
  956. package/extensions/vendor/openviking-pi/qcr-shim.ts +142 -0
  957. package/extensions/vendor/openviking-pi/qcr-write.ts +427 -0
  958. package/extensions/vendor/openviking-pi/recall.ts +149 -0
  959. package/extensions/vendor/openviking-pi/shared/capture-utils.d.mts +9 -0
  960. package/extensions/vendor/openviking-pi/shared/capture-utils.mjs +515 -0
  961. package/extensions/vendor/openviking-pi/shared/credentials.d.mts +14 -0
  962. package/extensions/vendor/openviking-pi/shared/credentials.mjs +228 -0
  963. package/extensions/vendor/openviking-pi/shared/pending-queue.d.mts +19 -0
  964. package/extensions/vendor/openviking-pi/shared/pending-queue.mjs +458 -0
  965. package/extensions/vendor/openviking-pi/shared/profile-inject.d.mts +17 -0
  966. package/extensions/vendor/openviking-pi/shared/profile-inject.mjs +294 -0
  967. package/extensions/vendor/openviking-pi/shared/recall-compress-core.mjs +195 -0
  968. package/extensions/vendor/openviking-pi/shared/recall-core.d.mts +13 -0
  969. package/extensions/vendor/openviking-pi/shared/recall-core.mjs +609 -0
  970. package/extensions/vendor/openviking-pi/shared/retryable.mjs +9 -0
  971. package/extensions/vendor/openviking-pi/shared/session-model.d.mts +3 -0
  972. package/extensions/vendor/openviking-pi/shared/session-model.mjs +57 -0
  973. package/extensions/vendor/openviking-pi/shared/uri-guard.mjs +56 -0
  974. package/extensions/vendor/openviking-pi/shared/workspace-peer.d.mts +5 -0
  975. package/extensions/vendor/openviking-pi/shared/workspace-peer.mjs +16 -0
  976. package/extensions/vendor/openviking-pi/sync.ts +163 -0
  977. package/extensions/vendor/openviking-pi/takeover.ts +36 -0
  978. package/extensions/vendor/openviking-pi/tools.ts +479 -0
  979. package/extensions/vendor/openviking-pi/upstream.json +48 -0
  980. package/package.json +138 -4
  981. package/profiles/default/README.md +21 -0
  982. package/profiles/default/addenda/.gitkeep +0 -0
  983. package/profiles/default/profile.toml +17 -0
  984. package/profiles/example-django/README.md +21 -0
  985. package/profiles/example-django/addenda/10-migration-discipline.md +13 -0
  986. package/profiles/example-django/addenda/20-new-column-nullability.md +12 -0
  987. package/profiles/example-django/addenda/30-test-doctrine.md +12 -0
  988. package/profiles/example-django/addenda/40-orm-usage.md +19 -0
  989. package/profiles/example-django/addenda/50-declared-shape.md +10 -0
  990. package/profiles/example-django/addenda/60-config-placement.md +14 -0
  991. package/profiles/example-django/heuristics.toml +24 -0
  992. package/profiles/example-django/profile.toml +9 -0
  993. package/profiles/fast/README.md +24 -0
  994. package/profiles/fast/profile.toml +59 -0
  995. package/profiles/minimal/README.md +17 -0
  996. package/profiles/minimal/addenda/.gitkeep +0 -0
  997. package/profiles/minimal/profile.toml +8 -0
  998. package/profiles/snappy/README.md +24 -0
  999. package/profiles/snappy/addenda/10-race-as-question.md +6 -0
  1000. package/profiles/snappy/profile.toml +46 -0
  1001. package/prompts/companion-day-open.md +46 -0
  1002. package/prompts/companion-first-run.md +104 -0
  1003. package/prompts/companion.md +821 -0
  1004. package/prompts/conversation-system.md +117 -0
  1005. package/prompts/eod-sweep.md +120 -0
  1006. package/prompts/onboarding.md +74 -0
  1007. package/prompts/pass-common.md +52 -0
  1008. package/prompts/pass-quality-common.md +22 -0
  1009. package/prompts/round-first.md +874 -0
  1010. package/prompts/round-follow-up.md +991 -0
  1011. package/prompts/round-re-review.md +889 -0
  1012. package/prompts/round-recheck.md +196 -0
  1013. package/prompts/round-staleness.md +856 -0
  1014. package/schemas/review-result.v1.json +391 -0
  1015. package/schemas/scan-result.v1.json +421 -0
  1016. package/schemas/version.v1.json +57 -0
  1017. package/scripts/approve-pr.sh +16 -0
  1018. package/scripts/build-stamp.mjs +67 -0
  1019. package/scripts/commit-verdict.sh +155 -0
  1020. package/scripts/companion-e2e.sh +250 -0
  1021. package/scripts/companion-memory-forward.mjs +1966 -0
  1022. package/scripts/config-fingerprint.sh +28 -0
  1023. package/scripts/deploy-manifest.mjs +141 -0
  1024. package/scripts/deploy.sh +1435 -0
  1025. package/scripts/directory-lock.mjs +193 -0
  1026. package/scripts/heartbeat-fresh.mjs +54 -0
  1027. package/scripts/install-locator.sh +328 -0
  1028. package/scripts/install-wrapper.sh +76 -0
  1029. package/scripts/memory-search-check.mjs +98 -0
  1030. package/scripts/mint-token.sh +212 -0
  1031. package/scripts/openviking-embedder.py +392 -0
  1032. package/scripts/openviking-ov-conf.mjs +161 -0
  1033. package/scripts/openviking-provision.mjs +1122 -0
  1034. package/scripts/openviking-reembed.mjs +1154 -0
  1035. package/scripts/post-review.sh +16 -0
  1036. package/scripts/pr-checks.sh +256 -0
  1037. package/scripts/pr-context.py +174 -0
  1038. package/scripts/pr-context.sh +63 -0
  1039. package/scripts/pr-self.sh +144 -0
  1040. package/scripts/pr-threads.sh +145 -0
  1041. package/scripts/qcr +15 -0
  1042. package/scripts/qcr-host.sh +769 -0
  1043. package/scripts/render-review.sh +24 -0
  1044. package/scripts/reply-thread.sh +16 -0
  1045. package/scripts/required-passes.py +112 -0
  1046. package/scripts/smoke-companion.sh +211 -0
  1047. package/scripts/tui-deploy-runner.mjs +61 -0
  1048. package/scripts/verify-dist.mjs +201 -0
  1049. package/scripts/vm-ghcr-login.sh +188 -0
  1050. package/seeds/agents/pass-baseline.md +61 -0
  1051. package/seeds/agents/pass-contracts.md +30 -0
  1052. package/seeds/agents/pass-data-safety.md +54 -0
  1053. package/seeds/agents/pass-delivery.md +37 -0
  1054. package/seeds/agents/pass-prod-risk.md +24 -0
  1055. package/seeds/agents/pass-security.md +31 -0
  1056. package/seeds/agents/pass-statelessness.md +27 -0
  1057. package/seeds/agents/pass-ui.md +23 -0
  1058. package/seeds/agents/pass-validate.md +50 -0
  1059. package/seeds/prompts/conversation-system.md +117 -0
  1060. package/seeds/prompts/eod-sweep.md +120 -0
  1061. package/seeds/prompts/pass-common.md +52 -0
  1062. package/skills/companion/adjudicate/SKILL.md +247 -0
  1063. package/skills/companion/evidence/SKILL.md +150 -0
  1064. package/skills/companion/land/SKILL.md +200 -0
  1065. package/skills/companion/replay/SKILL.md +138 -0
  1066. package/skills/companion/setup/SKILL.md +167 -0
  1067. package/skills/companion/survey/SKILL.md +160 -0
  1068. package/skills/selfimprove/README.md +34 -0
  1069. package/skills/selfimprove/SKILL.md +127 -0
  1070. package/skills/selfimprove/agents/openai.yaml +2 -0
  1071. package/skills/selfimprove/commands/selfimprove.md +6 -0
  1072. package/skills/selfimprove/references/fix-loop.md +49 -0
  1073. package/skills/selfimprove/references/ledger.md +20 -0
  1074. package/skills/selfimprove/references/setup.md +40 -0
  1075. package/src/anomalies.ts +566 -0
  1076. package/src/answerworker.ts +251 -0
  1077. package/src/appstamp.ts +65 -0
  1078. package/src/archive/admission.ts +3 -0
  1079. package/src/archive/archivedb.ts +548 -0
  1080. package/src/archive/archiver.ts +1963 -0
  1081. package/src/archive/archivewrite.ts +279 -0
  1082. package/src/archive/bundle.ts +333 -0
  1083. package/src/archive/dbmove.ts +911 -0
  1084. package/src/archive/duplicatecounts.ts +98 -0
  1085. package/src/archive/eligibility.ts +181 -0
  1086. package/src/archive/extract.ts +342 -0
  1087. package/src/archive/fsutil.ts +415 -0
  1088. package/src/archive/gzfile.ts +370 -0
  1089. package/src/archive/kinds.ts +21 -0
  1090. package/src/archive/livecheckpoint.ts +217 -0
  1091. package/src/archive/liveretention.ts +180 -0
  1092. package/src/archive/manifest.ts +519 -0
  1093. package/src/archive/overseer.ts +336 -0
  1094. package/src/archive/piglobal.ts +174 -0
  1095. package/src/archive/plan.ts +612 -0
  1096. package/src/archive/prarchive.ts +984 -0
  1097. package/src/archive/prfiles.ts +406 -0
  1098. package/src/archive/report.ts +252 -0
  1099. package/src/archive/restore.ts +330 -0
  1100. package/src/archive/rows.ts +187 -0
  1101. package/src/archive/seal.ts +630 -0
  1102. package/src/archive/status.ts +719 -0
  1103. package/src/archive/storepass.ts +581 -0
  1104. package/src/backfill.ts +362 -0
  1105. package/src/bench/cost.ts +113 -0
  1106. package/src/bench/exec.ts +90 -0
  1107. package/src/bench/values.ts +13 -0
  1108. package/src/botcontrol.ts +176 -0
  1109. package/src/botworker.ts +953 -0
  1110. package/src/capture.ts +321 -0
  1111. package/src/cases.ts +1789 -0
  1112. package/src/channelfs.ts +26 -0
  1113. package/src/checklist.ts +506 -0
  1114. package/src/ciretry.ts +141 -0
  1115. package/src/cli.ts +2271 -0
  1116. package/src/cliops.ts +384 -0
  1117. package/src/clonedir.ts +15 -0
  1118. package/src/commandeffects.ts +57 -0
  1119. package/src/commands.ts +1678 -0
  1120. package/src/companioninbox.ts +239 -0
  1121. package/src/compare.ts +957 -0
  1122. package/src/config.ts +2050 -0
  1123. package/src/configcheck.ts +133 -0
  1124. package/src/coreext.ts +47 -0
  1125. package/src/daemon.ts +1302 -0
  1126. package/src/debuground.ts +927 -0
  1127. package/src/debugroundpi.ts +262 -0
  1128. package/src/diagnostics.ts +14 -0
  1129. package/src/digest.ts +183 -0
  1130. package/src/dispatch.ts +2250 -0
  1131. package/src/engine/answerguard.ts +27 -0
  1132. package/src/engine/botsdk.ts +336 -0
  1133. package/src/engine/caserunner-sdk.ts +423 -0
  1134. package/src/engine/debugpi.ts +235 -0
  1135. package/src/eod.ts +669 -0
  1136. package/src/eodpinwatch.ts +556 -0
  1137. package/src/escalation.ts +1253 -0
  1138. package/src/eventloop.ts +1045 -0
  1139. package/src/execboundary.ts +633 -0
  1140. package/src/feedback.ts +1162 -0
  1141. package/src/findingscheck.ts +298 -0
  1142. package/src/fsdenied.ts +24 -0
  1143. package/src/ghread.ts +242 -0
  1144. package/src/github.ts +1497 -0
  1145. package/src/homes.ts +175 -0
  1146. package/src/hostroute.ts +53 -0
  1147. package/src/improvements.ts +787 -0
  1148. package/src/install.ts +1103 -0
  1149. package/src/installkind.ts +50 -0
  1150. package/src/ipc/capability.ts +333 -0
  1151. package/src/ipc/client.ts +269 -0
  1152. package/src/ipc/control.ts +90 -0
  1153. package/src/ipc/ghreadshim.ts +94 -0
  1154. package/src/ipc/launcher.ts +65 -0
  1155. package/src/ipc/permits.ts +362 -0
  1156. package/src/ipc/postshim.ts +164 -0
  1157. package/src/ipc/protocol.ts +342 -0
  1158. package/src/ipc/server.ts +371 -0
  1159. package/src/ipc/workerspec.ts +218 -0
  1160. package/src/learner/learner.ts +1655 -0
  1161. package/src/learner/miner.ts +1290 -0
  1162. package/src/learner/packet.ts +340 -0
  1163. package/src/learner/receipt.ts +168 -0
  1164. package/src/learner/status.ts +107 -0
  1165. package/src/ledgercheck.ts +157 -0
  1166. package/src/lessonledger.ts +703 -0
  1167. package/src/lessonselect.ts +888 -0
  1168. package/src/lessonshadow.ts +810 -0
  1169. package/src/levers.ts +393 -0
  1170. package/src/live/projection.ts +491 -0
  1171. package/src/live/publish.ts +92 -0
  1172. package/src/live/read.ts +86 -0
  1173. package/src/livecli.ts +336 -0
  1174. package/src/loginhint.ts +56 -0
  1175. package/src/loginrefresh/atomic.ts +76 -0
  1176. package/src/loginrefresh/lock.ts +104 -0
  1177. package/src/loginrefresh/main.ts +59 -0
  1178. package/src/loginrefresh/pirefresh.ts +57 -0
  1179. package/src/loginrefresh/refresher.ts +326 -0
  1180. package/src/loginrefresh/supervisor.ts +273 -0
  1181. package/src/loginrefresh/types.ts +35 -0
  1182. package/src/memory/context.ts +385 -0
  1183. package/src/memory/datafence.ts +9 -0
  1184. package/src/memory/delivery.ts +171 -0
  1185. package/src/memory/eventtags.ts +80 -0
  1186. package/src/memory/health.ts +953 -0
  1187. package/src/memory/import.ts +664 -0
  1188. package/src/memory/layout.ts +261 -0
  1189. package/src/memory/legacy-file.ts +104 -0
  1190. package/src/memory/lessons.ts +447 -0
  1191. package/src/memory/ovsession.ts +601 -0
  1192. package/src/memory/relayout.ts +335 -0
  1193. package/src/memory/roundactivity.ts +209 -0
  1194. package/src/memory/selection.ts +989 -0
  1195. package/src/memory/shadowstatus.ts +125 -0
  1196. package/src/memory/store.ts +275 -0
  1197. package/src/memory/textidentity.ts +8 -0
  1198. package/src/metrics.ts +1056 -0
  1199. package/src/missingconfig.ts +7 -0
  1200. package/src/npmverbs.ts +264 -0
  1201. package/src/onboard/choices.ts +222 -0
  1202. package/src/onboard/engine.ts +518 -0
  1203. package/src/onboard/launch.ts +115 -0
  1204. package/src/onboard/steps/appslug.ts +265 -0
  1205. package/src/onboard/steps/bringup.ts +482 -0
  1206. package/src/onboard/steps/compose.ts +459 -0
  1207. package/src/onboard/steps/configdelivery.ts +58 -0
  1208. package/src/onboard/steps/configfill.ts +1352 -0
  1209. package/src/onboard/steps/deploysh.ts +105 -0
  1210. package/src/onboard/steps/embeddings.ts +550 -0
  1211. package/src/onboard/steps/escalation.ts +640 -0
  1212. package/src/onboard/steps/githubapp.ts +1414 -0
  1213. package/src/onboard/steps/golive.ts +577 -0
  1214. package/src/onboard/steps/index.ts +71 -0
  1215. package/src/onboard/steps/ingress.ts +907 -0
  1216. package/src/onboard/steps/inventory.ts +526 -0
  1217. package/src/onboard/steps/llmauth.ts +1095 -0
  1218. package/src/onboard/steps/memory.ts +1290 -0
  1219. package/src/onboard/steps/memorykeys.ts +85 -0
  1220. package/src/onboard/steps/preflight.ts +191 -0
  1221. package/src/onboard/steps/proof.ts +624 -0
  1222. package/src/onboard/steps/ssh.ts +377 -0
  1223. package/src/onboard/steps/topology.ts +337 -0
  1224. package/src/onboard/steps/transport.ts +665 -0
  1225. package/src/onboard/steps/verifyup.ts +448 -0
  1226. package/src/onboard/steps/vmdeploy.ts +442 -0
  1227. package/src/onboard/toml.ts +50 -0
  1228. package/src/opencli.ts +591 -0
  1229. package/src/openpr.ts +568 -0
  1230. package/src/openviking/client.ts +1131 -0
  1231. package/src/openviking/context.ts +263 -0
  1232. package/src/openviking/embedder.ts +516 -0
  1233. package/src/openviking/gapsink.ts +63 -0
  1234. package/src/openviking/health.ts +83 -0
  1235. package/src/openviking/index.ts +119 -0
  1236. package/src/openviking/lessonfind.ts +92 -0
  1237. package/src/openviking/probe.ts +129 -0
  1238. package/src/openviking/proc.ts +110 -0
  1239. package/src/openviking/provisionreport.ts +160 -0
  1240. package/src/openviking/reembed.ts +412 -0
  1241. package/src/openviking/relayout.ts +177 -0
  1242. package/src/openviking/sidecar-main.ts +38 -0
  1243. package/src/openviking/sidecar.ts +106 -0
  1244. package/src/openviking/store.ts +2025 -0
  1245. package/src/openviking/supervisor.ts +474 -0
  1246. package/src/openviking/types.ts +174 -0
  1247. package/src/operator-recovery.ts +237 -0
  1248. package/src/operatormessage.ts +52 -0
  1249. package/src/outcomes.ts +1670 -0
  1250. package/src/piauthcopy.ts +12 -0
  1251. package/src/picli.ts +49 -0
  1252. package/src/picwd.ts +25 -0
  1253. package/src/pilogin.ts +37 -0
  1254. package/src/pingpong.ts +1339 -0
  1255. package/src/posting-journal.ts +549 -0
  1256. package/src/posting-outbox.ts +802 -0
  1257. package/src/posting-receipt.ts +324 -0
  1258. package/src/posting.ts +603 -0
  1259. package/src/postops.ts +832 -0
  1260. package/src/pr-activity.ts +20 -0
  1261. package/src/pr-author.ts +6 -0
  1262. package/src/pr-conversation.ts +432 -0
  1263. package/src/pr-session-lifecycle.ts +631 -0
  1264. package/src/preflight.ts +391 -0
  1265. package/src/priorresolve.ts +343 -0
  1266. package/src/qcrbin.ts +186 -0
  1267. package/src/recheck.ts +1775 -0
  1268. package/src/reconcile.ts +1030 -0
  1269. package/src/recordedfindings.ts +27 -0
  1270. package/src/regression.ts +833 -0
  1271. package/src/replay.ts +816 -0
  1272. package/src/requiredpasses.ts +148 -0
  1273. package/src/resumecheck.ts +246 -0
  1274. package/src/reviewcli.ts +787 -0
  1275. package/src/reviewcontext.ts +35 -0
  1276. package/src/reviewdetach.ts +734 -0
  1277. package/src/reviewhistory.ts +427 -0
  1278. package/src/reviewhome.ts +36 -0
  1279. package/src/reviewmemory.ts +133 -0
  1280. package/src/reviewrendercli.ts +139 -0
  1281. package/src/round-work.ts +42 -0
  1282. package/src/runhost.ts +108 -0
  1283. package/src/scanauth.ts +36 -0
  1284. package/src/scanbox.ts +1081 -0
  1285. package/src/scancli.ts +1296 -0
  1286. package/src/scandriverlog.ts +32 -0
  1287. package/src/session-bridge.ts +139 -0
  1288. package/src/session-command-payload.ts +35 -0
  1289. package/src/session-command-supervisor.ts +1142 -0
  1290. package/src/sessionjsonl.ts +88 -0
  1291. package/src/sessions.ts +659 -0
  1292. package/src/setup/adapters.ts +335 -0
  1293. package/src/setup/baselines.ts +110 -0
  1294. package/src/setup/caserunner.ts +611 -0
  1295. package/src/setup/configcommit.ts +443 -0
  1296. package/src/setup/engine.ts +1001 -0
  1297. package/src/setup/facts.ts +627 -0
  1298. package/src/setup/findings.ts +1264 -0
  1299. package/src/setup/history.ts +443 -0
  1300. package/src/setup/interview.ts +243 -0
  1301. package/src/setup/ledger.ts +324 -0
  1302. package/src/setup/pins.ts +66 -0
  1303. package/src/setup/portrait.ts +635 -0
  1304. package/src/setup/presentation.ts +18 -0
  1305. package/src/setup/profile.ts +508 -0
  1306. package/src/setup/replay.ts +370 -0
  1307. package/src/setup/replaybuild.ts +392 -0
  1308. package/src/setup/replayrun.ts +1096 -0
  1309. package/src/setup/replaysource.ts +198 -0
  1310. package/src/setup/retune.ts +415 -0
  1311. package/src/setup/retunelog.ts +95 -0
  1312. package/src/setup/scan.ts +1033 -0
  1313. package/src/setup/scanbuild.ts +168 -0
  1314. package/src/setup/scanfacts.ts +107 -0
  1315. package/src/setup/scanlease.ts +297 -0
  1316. package/src/setup/scanreport.ts +373 -0
  1317. package/src/setup/scanrun.ts +2268 -0
  1318. package/src/setup/scantree.ts +259 -0
  1319. package/src/setup/stage2.ts +926 -0
  1320. package/src/setup/stage2request.ts +347 -0
  1321. package/src/setup/survey.ts +458 -0
  1322. package/src/setup/surveyrun.ts +758 -0
  1323. package/src/setup/textsniff.ts +95 -0
  1324. package/src/setup/trackersink.ts +433 -0
  1325. package/src/setup/triage.ts +768 -0
  1326. package/src/setup/tuning.ts +766 -0
  1327. package/src/setup/unitcut.ts +523 -0
  1328. package/src/singleflight.ts +86 -0
  1329. package/src/slack/announce.ts +911 -0
  1330. package/src/slack/api.ts +303 -0
  1331. package/src/slack/messages.ts +288 -0
  1332. package/src/slack/origin.ts +599 -0
  1333. package/src/slack/policy.ts +354 -0
  1334. package/src/slack/reply.ts +201 -0
  1335. package/src/slack/router.ts +285 -0
  1336. package/src/slack/socket.ts +384 -0
  1337. package/src/slack/types.ts +108 -0
  1338. package/src/sqlitehint.ts +32 -0
  1339. package/src/ssh-observation.ts +30 -0
  1340. package/src/state.ts +8243 -0
  1341. package/src/statemachine.ts +369 -0
  1342. package/src/stubs.ts +68 -0
  1343. package/src/takeover.ts +634 -0
  1344. package/src/takeoverpi.ts +293 -0
  1345. package/src/terminal-failure.ts +41 -0
  1346. package/src/thread-resolution-refusal.ts +2 -0
  1347. package/src/tmux.ts +153 -0
  1348. package/src/trackerid.ts +41 -0
  1349. package/src/transcriptindex.ts +665 -0
  1350. package/src/tui/actions.ts +484 -0
  1351. package/src/tui/alerts.ts +666 -0
  1352. package/src/tui/app.ts +1979 -0
  1353. package/src/tui/archiveops.ts +192 -0
  1354. package/src/tui/autofile.ts +233 -0
  1355. package/src/tui/board.ts +1432 -0
  1356. package/src/tui/candidates.ts +889 -0
  1357. package/src/tui/cellwidth.ts +148 -0
  1358. package/src/tui/changelog-store.ts +503 -0
  1359. package/src/tui/chord.ts +25 -0
  1360. package/src/tui/clipboard.ts +92 -0
  1361. package/src/tui/cmdbar.ts +296 -0
  1362. package/src/tui/companion.ts +1427 -0
  1363. package/src/tui/companionplan.ts +247 -0
  1364. package/src/tui/companiontab.ts +83 -0
  1365. package/src/tui/confighome.ts +155 -0
  1366. package/src/tui/connect.ts +68 -0
  1367. package/src/tui/deploy-ceremony.ts +104 -0
  1368. package/src/tui/deploy-drain.ts +129 -0
  1369. package/src/tui/deploy-process.ts +265 -0
  1370. package/src/tui/deploytab.ts +1523 -0
  1371. package/src/tui/design.ts +125 -0
  1372. package/src/tui/digesttab.ts +214 -0
  1373. package/src/tui/emptystate.ts +39 -0
  1374. package/src/tui/evidence.ts +999 -0
  1375. package/src/tui/feed.ts +604 -0
  1376. package/src/tui/feedbacktab.ts +1077 -0
  1377. package/src/tui/filters.ts +90 -0
  1378. package/src/tui/ghread.ts +321 -0
  1379. package/src/tui/historypull.ts +81 -0
  1380. package/src/tui/inboxpull.ts +236 -0
  1381. package/src/tui/index.ts +1565 -0
  1382. package/src/tui/issuesink.ts +238 -0
  1383. package/src/tui/jsonfile.ts +42 -0
  1384. package/src/tui/keys.ts +109 -0
  1385. package/src/tui/layout.ts +108 -0
  1386. package/src/tui/learning.ts +627 -0
  1387. package/src/tui/lessonswitch.ts +118 -0
  1388. package/src/tui/livecontrol.ts +228 -0
  1389. package/src/tui/memforward.ts +443 -0
  1390. package/src/tui/memincident.ts +363 -0
  1391. package/src/tui/memory.ts +620 -0
  1392. package/src/tui/memtab.ts +606 -0
  1393. package/src/tui/metricstab.ts +1177 -0
  1394. package/src/tui/model.ts +131 -0
  1395. package/src/tui/mouse.ts +98 -0
  1396. package/src/tui/msg.ts +268 -0
  1397. package/src/tui/nativecompanion.ts +417 -0
  1398. package/src/tui/openurl.ts +21 -0
  1399. package/src/tui/paint.ts +511 -0
  1400. package/src/tui/panes.ts +98 -0
  1401. package/src/tui/pipane.ts +219 -0
  1402. package/src/tui/poll-hooks.ts +12 -0
  1403. package/src/tui/poll.ts +147 -0
  1404. package/src/tui/proposals.ts +838 -0
  1405. package/src/tui/prpause.ts +150 -0
  1406. package/src/tui/reload.ts +436 -0
  1407. package/src/tui/remote.ts +413 -0
  1408. package/src/tui/rollover.ts +969 -0
  1409. package/src/tui/scantab.ts +1290 -0
  1410. package/src/tui/setupentry.ts +93 -0
  1411. package/src/tui/sidebar.ts +749 -0
  1412. package/src/tui/sshtriage.ts +510 -0
  1413. package/src/tui/startup.ts +231 -0
  1414. package/src/tui/tabs.ts +45 -0
  1415. package/src/tui/termmirror.ts +224 -0
  1416. package/src/tui/theme.ts +95 -0
  1417. package/src/tui/ticketstab.ts +310 -0
  1418. package/src/tui/tmuxsocket.ts +129 -0
  1419. package/src/tui/trackertickets.ts +84 -0
  1420. package/src/tui/unwedge.ts +286 -0
  1421. package/src/tui/viewer.ts +575 -0
  1422. package/src/tui/viewerinput.ts +173 -0
  1423. package/src/updatenotice.ts +178 -0
  1424. package/src/usage.ts +1154 -0
  1425. package/src/verdicts.ts +4689 -0
  1426. package/src/version.ts +80 -0
  1427. package/src/wakes.ts +476 -0
  1428. package/src/webhook.ts +942 -0
  1429. package/src/webhookheal.ts +276 -0
  1430. package/src/wire.ts +2153 -0
  1431. package/src/worker-session-host.ts +602 -0
  1432. package/src/workerbreaker.ts +156 -0
  1433. package/src/workercontrol.ts +104 -0
  1434. package/src/workerlease.ts +441 -0
  1435. package/src/workerliveness.ts +103 -0
  1436. package/src/workerlog.ts +79 -0
  1437. package/src/workerruntime.ts +30 -0
  1438. package/src/workersupervisor.ts +1538 -0
  1439. package/src/workerusage.ts +42 -0
  1440. package/src/workerworld.ts +427 -0
  1441. package/src/worktrees.ts +1138 -0
  1442. package/tests/fixtures/regression-cases.json +795 -0
  1443. package/tests/fixtures/seed-manifest.json +19 -0
@@ -0,0 +1,1131 @@
1
+ // The OpenViking HTTP client — the one place in the daemon that
2
+ // knows OpenViking speaks HTTP on loopback :1933.
3
+ //
4
+ // Everything above this file (the `MemoryStore` seam, the round's
5
+ // `ContextAssembler`) is engine-agnostic; everything below is the server. The
6
+ // client's whole job is to turn an HTTP surface that can be down, slow, or
7
+ // wrong into a TOTAL function: `OvOutcome<T>` for every call, never a
8
+ // rejection.
9
+ //
10
+ // Four facts about the running v0.4.15 server shape this module. They were
11
+ // verified against it and they contradict the published docs
12
+ // in places — do not "correct" them back:
13
+ //
14
+ // 1. WRITES GO THROUGH `content/batch-write`, EXCLUSIVELY. For memory-context
15
+ // targets, bare `content/write` appends a server-side `MEMORY_FIELDS`
16
+ // footer that `content/read` strips again, and no API returns the stored
17
+ // hash — so a read → sha256 → write cycle 409s FOREVER on any file that
18
+ // endpoint created. Files written by batch-write carry no footer and
19
+ // round-trip exactly. This client therefore has NO `content/write`
20
+ // wrapper at all: the footgun is removed by absence, not by a comment.
21
+ // 2. `replace_if_hash` with a stale `base_hash` returns 409 CONFLICT and
22
+ // leaves the file verifiably unchanged. That is a clean, ordinary answer
23
+ // ("someone edited this since you read it") — `conflict: true` on the
24
+ // outcome, never an exception. The SAME status and code also mean "the
25
+ // directory was locked by another writer" (`details.conflict_type =
26
+ // "path_busy"`: batch-write's root lock is a zero-timeout try-lock), and
27
+ // that one is NOT a refusal — nothing was checked. It is told apart by
28
+ // `details.conflict_type` alone and retried here.
29
+ // 3. SEARCH IS `POST /api/v1/search/search` with `mode: "context"`, and the
30
+ // determinism knobs are pinned OFF here rather than left to the caller:
31
+ // `rewrite` and `query_expansion` both invoke a server-side LLM, and the
32
+ // daemon has no LLM in its hot path. Note the wire spelling: `rewrite` is
33
+ // typed `bool | "auto"` server-side, so "off" IS `false` — sending the
34
+ // string "off" is a 422, i.e. a silent memory outage.
35
+ // 4. AUTH IS THE REVIEWER USER KEY, `Authorization: Bearer <key>`, and
36
+ // nothing else. The server confines that key to `user/reviewer/` (403
37
+ // across users — a real guarantee, not a convention), the identity
38
+ // headers are ignored in api_key mode, and an ADMIN/ROOT key must never
39
+ // appear here: ADMIN grants no cross-user data access anyway and can list
40
+ // every user key in plaintext. The key is supplied by the caller, read
41
+ // lazily, and NEVER logged — `redact()` scrubs it out of every failure
42
+ // message at construction, before any caller can log or render one.
43
+ import { readFileSync, statSync } from "node:fs";
44
+ import { normalizeTag } from "../memory/store.js";
45
+ import type { HealthRequest } from "../memory/health.js";
46
+
47
+ /** The `fetch` slice this client uses — the whole network seam. */
48
+ export interface HttpFetch {
49
+ (
50
+ url: string,
51
+ init: {
52
+ method: string;
53
+ headers: Record<string, string>;
54
+ body?: string;
55
+ signal?: AbortSignal;
56
+ },
57
+ ): Promise<HttpResponse>;
58
+ }
59
+
60
+ export interface HttpResponse {
61
+ ok: boolean;
62
+ status: number;
63
+ text(): Promise<string>;
64
+ }
65
+
66
+ /** A call that did not do what was asked — logged, and handed to `onGap` for
67
+ * the overseer anomaly. Never carries the key or a header map. */
68
+ export interface OvGap {
69
+ /** Short operation name: `batch_write`, `search`, `read`, … */
70
+ op: string;
71
+ /** HTTP status, or 0 for "never got an answer". */
72
+ status: number;
73
+ /** Server error code (`CONFLICT`, `PERMISSION_DENIED`, …) or `transport`. */
74
+ code: string;
75
+ message: string;
76
+ }
77
+
78
+ /**
79
+ * Every call's answer.
80
+ *
81
+ * `conflict` is broken out of the failure arm because it is the one refusal
82
+ * that is not a gap: a 409 means the optimistic-concurrency precondition did
83
+ * its job. Callers surface it to an operator; nothing alerts on it.
84
+ *
85
+ * `busy` is the other 409, and it is never a `conflict`. The
86
+ * server takes a zero-timeout try-lock on a batch-write's root directory, and
87
+ * a second writer into the same directory gets `409 CONFLICT` with
88
+ * `details.conflict_type = "path_busy"` and `retryable: true` — nothing was
89
+ * checked and nothing was written. Reading that as "the precondition refused"
90
+ * would send the caller to re-read a file nobody had touched and drop its
91
+ * write. The client retries a busy answer itself
92
+ * (bounded, jittered — see `BUSY_RETRY_DEFAULTS`); one that is still busy
93
+ * when the budget runs out comes back `busy: true, conflict: false`, an
94
+ * ordinary failure.
95
+ */
96
+ export interface OvFailure {
97
+ ok: false;
98
+ status: number;
99
+ code: string;
100
+ message: string;
101
+ conflict: boolean;
102
+ busy: boolean;
103
+ }
104
+
105
+ export type OvOutcome<T> = { ok: true; status: number; result: T } | OvFailure;
106
+
107
+ /** Returns the FAILURE arm, not the union: a caller that builds one wants to
108
+ * read `conflict` off it without re-narrowing. A busy answer is never a
109
+ * conflict, whatever its status says. */
110
+ export function ovFailed(status: number, code: string, message: string, busy = false): OvFailure {
111
+ return {
112
+ ok: false,
113
+ status,
114
+ code,
115
+ message,
116
+ conflict: !busy && (status === 409 || code === "CONFLICT"),
117
+ busy,
118
+ };
119
+ }
120
+
121
+ /** The `details.conflict_type` the server stamps on a lock it could not take
122
+ * (`server/error_mapping.py`, `ResourceBusyError` / `LockAcquisitionError`). */
123
+ export const BUSY_CONFLICT_TYPE = "path_busy";
124
+
125
+ /**
126
+ * Is this error envelope the server's "directory busy, try again" answer?
127
+ * Keyed on `details.conflict_type`, never on the message text
128
+ * and never on the status alone: a hash-precondition 409 carries the same
129
+ * status and code, and it must stay a refusal.
130
+ */
131
+ export function isBusyConflict(status: number, error: unknown): boolean {
132
+ if (status !== 409 || !error || typeof error !== "object") return false;
133
+ const details = (error as { details?: unknown }).details;
134
+ if (!details || typeof details !== "object") return false;
135
+ return (details as { conflict_type?: unknown }).conflict_type === BUSY_CONFLICT_TYPE;
136
+ }
137
+
138
+ /** How hard the client retries a busy answer: at most `retries` more
139
+ * attempts, the n-th after a jittered `min(capMs, baseMs·2ⁿ)` wait (half to
140
+ * all of it), and no retry is STARTED once its wait would carry it past
141
+ * `budgetMs` from the first attempt — so a lock held for longer comes back as
142
+ * a failure the caller can see rather than a request that hangs. A retry that
143
+ * does start runs under the request's own timeout, so the whole call can end
144
+ * up to one timeout past the budget: an attempt cut short mid-write would
145
+ * leave its outcome unknown, which is worse than the wait. */
146
+ export const BUSY_RETRY_DEFAULTS = Object.freeze({
147
+ retries: 4,
148
+ baseMs: 250,
149
+ capMs: 2000,
150
+ budgetMs: 10_000,
151
+ });
152
+
153
+ export interface BusyRetryOptions {
154
+ retries?: number;
155
+ baseMs?: number;
156
+ capMs?: number;
157
+ budgetMs?: number;
158
+ }
159
+
160
+ /** The wait before busy retry number `retry` (0-based): full exponential
161
+ * step, capped, then jittered into [½, 1] of it so writers that collided once
162
+ * do not collide again in lockstep. Pure — `random` is injected. */
163
+ export function busyRetryDelay(
164
+ retry: number,
165
+ random: () => number = Math.random,
166
+ opts: BusyRetryOptions = {},
167
+ ): number {
168
+ const base = opts.baseMs ?? BUSY_RETRY_DEFAULTS.baseMs;
169
+ const cap = opts.capMs ?? BUSY_RETRY_DEFAULTS.capMs;
170
+ const step = Math.min(cap, base * 2 ** Math.max(0, retry));
171
+ const r = Math.min(1, Math.max(0, random()));
172
+ return Math.round(step * (0.5 + r / 2));
173
+ }
174
+
175
+ /** Server error codes that mean "this key does not authenticate here". */
176
+ const AUTH_CODES = new Set([
177
+ "UNAUTHENTICATED",
178
+ "UNAUTHORIZED",
179
+ "PERMISSION_DENIED",
180
+ "FORBIDDEN",
181
+ "INVALID_API_KEY",
182
+ ]);
183
+
184
+ /**
185
+ * Is this answer an authentication failure?
186
+ *
187
+ * A 401/403, an auth error code, or the message the 0.4.15 server actually
188
+ * sends on a bad key ("Invalid API Key"), which it has been seen to wrap in an
189
+ * HTTP-200 error envelope. Read as plain "memory unavailable", a refused key
190
+ * goes unreported; this predicate is what lets every reader call it what it
191
+ * is. `no_key` (nothing to send at all) is NOT this — callers
192
+ * that care treat it alongside, by code.
193
+ */
194
+ export function isAuthFailure(status: number, code: string, message = ""): boolean {
195
+ if (status === 401 || status === 403) return true;
196
+ if (AUTH_CODES.has(code.toUpperCase())) return true;
197
+ return /invalid api key|unauthenticated|unauthori[sz]ed/i.test(message);
198
+ }
199
+
200
+ /**
201
+ * Is this answer a NOT_FOUND? The server authenticates a key
202
+ * before it resolves a path, so a NOT_FOUND is an authenticated ANSWER — the
203
+ * path is not there — never an outage. The store already reads it as "absent,
204
+ * known-empty" and ovsession's delete as the desired end state; the probe and
205
+ * the request observer read it the same way through this one predicate.
206
+ */
207
+ export function isNotFound(_status: number, code: string): boolean {
208
+ return code === "NOT_FOUND";
209
+ }
210
+
211
+ /** One request, as the client's observer sees it: what was asked, how it
212
+ * ended, how long it took. Never the key, never a header, never a body — it is
213
+ * a counter's input, not a log line. It IS the health monitor's
214
+ * `HealthRequest` (one declaration): `ok` — answered; `absent` — a NOT_FOUND
215
+ * answer (authenticated; the path is not there — an answer, not a failure);
216
+ * `conflict` — a 409 precondition refusal (an answer, not a failure); `auth` —
217
+ * the key did not authenticate, or there was no key to send; `failed` —
218
+ * everything else (transport, 5xx, bad body). `ms` is wall-clock (0 when
219
+ * nothing was sent); `message` is already scrubbed of the key and absent on
220
+ * success. */
221
+ export type OvRequestRecord = HealthRequest;
222
+
223
+ // ---- request/response shapes ------------------------------------------------
224
+
225
+ /** batch-write's precondition. `create_if_absent` MUST NOT carry a hash and
226
+ * `replace_if_hash` MUST — the server rejects the other combinations. */
227
+ export type BatchWritePrecondition =
228
+ { kind: "create_if_absent" } | { kind: "replace_if_hash"; base_hash: string };
229
+
230
+ export interface BatchWriteOperation {
231
+ uri: string;
232
+ content: string;
233
+ precondition: BatchWritePrecondition;
234
+ }
235
+
236
+ export interface BatchWriteRequest {
237
+ root_uri: string;
238
+ operations: BatchWriteOperation[];
239
+ /** `wait` blocks on the semantic/vector refresh — ~1.6 CORE-seconds per
240
+ * ~500 B write on the 2-CPU container quota. The bytes are durable either
241
+ * way; only searchability lags. Default false: memory never delays a round. */
242
+ wait: boolean;
243
+ }
244
+
245
+ export interface BatchWriteResult {
246
+ root_uri: string;
247
+ created: string[];
248
+ updated: string[];
249
+ unchanged: string[];
250
+ }
251
+
252
+ export interface OvDirEntry {
253
+ uri: string;
254
+ name: string;
255
+ isDir: boolean;
256
+ size: number;
257
+ modTime: string;
258
+ }
259
+
260
+ /** One entry of a `mode: "context"` search. */
261
+ export interface ContextSearchEntry {
262
+ uri: string;
263
+ category: string;
264
+ score: number;
265
+ /** Which tier of the document was returned: `abstract` | `overview` | `full`. */
266
+ detail: string;
267
+ text: string;
268
+ origin: string;
269
+ }
270
+
271
+ /** What a context search produced: the server-rendered block the round pastes,
272
+ * the entries behind it, and the budget accounting. Both halves are exposed —
273
+ * the block is what a prompt carries, the stats are what tells us whether the
274
+ * budget was actually spent. */
275
+ export interface ContextSearchResult {
276
+ entries: ContextSearchEntry[];
277
+ rendered: string;
278
+ digest: string;
279
+ stats: Record<string, unknown>;
280
+ }
281
+
282
+ /**
283
+ * The quota buckets the server will accept (`CATEGORY_KEYS` in
284
+ * `retrieve/context_assembler/params.py`). An unknown key is a 422 for the
285
+ * WHOLE request, so unknown keys are dropped with a gap rather than sent.
286
+ */
287
+ export const QUOTA_CATEGORIES: readonly string[] = [
288
+ "events",
289
+ "entities",
290
+ "preferences",
291
+ "experiences",
292
+ "resources",
293
+ "skills",
294
+ ];
295
+
296
+ export type TimeField = "updated_at" | "created_at";
297
+
298
+ export interface ContextSearchOptions {
299
+ /** Token budget for the assembled block (server clamps to 64…32000). */
300
+ maxTokens?: number;
301
+ /** Per-category caps, keys from `QUOTA_CATEGORIES`. */
302
+ quotas?: Record<string, number>;
303
+ /** Retrieval-tag filter (the `fs/attrs/set_tags` list, not body text). */
304
+ tags?: string[];
305
+ /** ISO instants bounding `timeField` (default the server's `updated_at`). */
306
+ since?: string;
307
+ until?: string;
308
+ timeField?: TimeField;
309
+ scoreThreshold?: number;
310
+ limit?: number;
311
+ purpose?: "chat" | "coding";
312
+ excludeUris?: string[];
313
+ timeoutMs?: number;
314
+ }
315
+
316
+ /** The most exclusions one search request carries. A request-size bound, not
317
+ * a correctness one: past it the search can return an excluded entry, so a
318
+ * caller that must never see one (the round's context block) filters the
319
+ * result against its full list too. */
320
+ export const EXCLUDE_URIS_CAP = 200;
321
+
322
+ /**
323
+ * The exact body of a context search — pure, so the determinism guarantees are
324
+ * unit-testable without a server.
325
+ *
326
+ * `mode`, `rewrite` and `query_expansion` are NOT parameters. A round prompt
327
+ * must be reproducible from the round order, and both `rewrite: "auto"` and
328
+ * `query_expansion: "auto"` (the server's DEFAULT for the latter) put an LLM
329
+ * inside the daemon's hot path. They are pinned off here so no caller can ask
330
+ * for them by accident.
331
+ */
332
+ export function buildContextSearchBody(
333
+ query: string,
334
+ opts: ContextSearchOptions = {},
335
+ onGap?: (gap: OvGap) => void,
336
+ ): Record<string, unknown> {
337
+ const body: Record<string, unknown> = {
338
+ query,
339
+ mode: "context",
340
+ // `false`, not "off": the server types this `bool | "auto"`.
341
+ rewrite: false,
342
+ query_expansion: "off",
343
+ };
344
+ if (opts.maxTokens !== undefined)
345
+ body["max_tokens"] = Math.max(64, Math.min(32000, Math.floor(opts.maxTokens)));
346
+ if (opts.limit !== undefined) body["limit"] = Math.max(1, Math.floor(opts.limit));
347
+ if (opts.scoreThreshold !== undefined) body["score_threshold"] = opts.scoreThreshold;
348
+ if (opts.purpose !== undefined) body["purpose"] = opts.purpose;
349
+ if (opts.quotas) {
350
+ const quotas: Record<string, number> = {};
351
+ for (const [key, value] of Object.entries(opts.quotas)) {
352
+ if (!QUOTA_CATEGORIES.includes(key)) {
353
+ onGap?.({
354
+ op: "search",
355
+ status: 0,
356
+ code: "bad_quota",
357
+ message: `dropped unknown quota category '${key}'`,
358
+ });
359
+ continue;
360
+ }
361
+ quotas[key] = Math.max(0, Math.floor(value));
362
+ }
363
+ if (Object.keys(quotas).length > 0) body["quotas"] = quotas;
364
+ }
365
+ const tags = (opts.tags ?? []).map((tag) => normalizeTag(tag).trim()).filter((t) => t !== "");
366
+ if (tags.length > 0) body["tags"] = [...new Set(tags)];
367
+ if (opts.since) body["since"] = opts.since;
368
+ if (opts.until) body["until"] = opts.until;
369
+ if (opts.timeField) body["time_field"] = opts.timeField;
370
+ if (opts.excludeUris && opts.excludeUris.length > 0) {
371
+ body["exclude_uris"] = opts.excludeUris.slice(0, EXCLUDE_URIS_CAP);
372
+ if (opts.excludeUris.length > EXCLUDE_URIS_CAP)
373
+ onGap?.({
374
+ op: "search",
375
+ status: 0,
376
+ code: "exclude_truncated",
377
+ message: `sent ${EXCLUDE_URIS_CAP} of ${opts.excludeUris.length} exclusions; the rest are filtered from the result by the caller`,
378
+ });
379
+ }
380
+ return body;
381
+ }
382
+
383
+ /** Options of a `/search/find`. */
384
+ export interface FindOptions {
385
+ /** The area(s) searched — one directory URI, or a list (the server takes
386
+ * one; vendored patch 0011 sends a list the same way). */
387
+ targetUri: string | readonly string[];
388
+ /** Hits asked for (the server's `limit`). */
389
+ limit?: number;
390
+ timeoutMs?: number;
391
+ }
392
+
393
+ /** One `/search/find` hit from the memories bucket. */
394
+ export interface FindResultHit {
395
+ uri: string;
396
+ score: number;
397
+ text: string;
398
+ }
399
+
400
+ /**
401
+ * The exact body of a `/search/find` — pure, so its determinism is testable:
402
+ * the query, the area(s) and the limit, and NOTHING that turns a server-side
403
+ * LLM on. No `session_id` (the expansion stage keys on one) and no
404
+ * `score_threshold` (the caller's filters decide, not a similarity floor).
405
+ */
406
+ export function buildFindBody(query: string, opts: FindOptions): Record<string, unknown> {
407
+ const target = Array.isArray(opts.targetUri) ? [...opts.targetUri] : opts.targetUri;
408
+ const body: Record<string, unknown> = { query, target_uri: target };
409
+ if (opts.limit !== undefined) body["limit"] = Math.max(1, Math.floor(opts.limit));
410
+ return body;
411
+ }
412
+
413
+ /**
414
+ * The session memory policy every session this system creates MUST carry.
415
+ *
416
+ * Our deployment configures no `vlm` on purpose — memories are AUTHORED by
417
+ * sessions and the EOD curator, never extracted. A session created without
418
+ * this policy queues an extraction task on every single commit and every one
419
+ * of them FAILS (verified). Disabling all three at create time makes commit
420
+ * complete cleanly with `memories_extracted: {}` and zero LLM tokens.
421
+ */
422
+ export const DISABLED_MEMORY_POLICY = Object.freeze({
423
+ self: { enabled: false },
424
+ peer: { enabled: false },
425
+ working_memory: { enabled: false },
426
+ });
427
+
428
+ export interface OvSessionResult {
429
+ session_id: string;
430
+ uri?: string;
431
+ }
432
+
433
+ // ---- the client -------------------------------------------------------------
434
+
435
+ /** How the reviewer key is obtained. A function is read on every request (so a
436
+ * secret that appears later is picked up without a restart) — implementations
437
+ * are expected to memoize, see `keyFromFile`. */
438
+ export type KeySource = string | (() => string | null | undefined);
439
+
440
+ export interface OpenVikingClientOptions {
441
+ /** `http://127.0.0.1:1933` — from `openVikingBaseUrl(config.openviking)`. */
442
+ baseUrl: string;
443
+ /** The reviewer USER key. Absent ⇒ every call degrades exactly like a dead
444
+ * server, which is the correct behaviour on a dev PC with no secret. */
445
+ apiKey?: KeySource;
446
+ /** OpenViking user id — the tree the key is confined to. */
447
+ user?: string;
448
+ account?: string;
449
+ /** Sent as `X-OpenViking-Actor-Peer`. A peer is a retrieval hint, NEVER an
450
+ * ACL (verified: a peer header writes freely outside the peer dir). */
451
+ peerId?: string;
452
+ /** Per-request deadline. Memory is a soft dependency; this is its ceiling. */
453
+ timeoutMs?: number;
454
+ fetchFn?: HttpFetch;
455
+ log?: (msg: string, extra?: unknown) => void;
456
+ /** Called for every gap, so the daemon can raise an overseer anomaly. Must
457
+ * not throw; a throwing sink is swallowed rather than escaping a call. */
458
+ onGap?: (gap: OvGap) => void;
459
+ /** Called once per request with its outcome — successes too,
460
+ * which `onGap` never sees. The daemon counts its own requests per
461
+ * operation and feeds the memory health monitor from here; the TUI counts
462
+ * its own. Must not throw; a throwing observer is swallowed. */
463
+ onRequest?: (record: OvRequestRecord) => void;
464
+ /** Millisecond clock for `OvRequestRecord.ms`. Tests inject one. */
465
+ clock?: () => number;
466
+ /** The busy-retry bound — `BUSY_RETRY_DEFAULTS` when absent. */
467
+ busyRetry?: BusyRetryOptions;
468
+ /** The wait between busy retries. Tests inject an instant one. */
469
+ sleep?: (ms: number) => Promise<void>;
470
+ /** The jitter source for busy retries. Tests inject a fixed one. */
471
+ random?: () => number;
472
+ }
473
+
474
+ /** A key read lazily from a file: call it for the current key, and
475
+ * `invalidate()` it when the server says the key is wrong, so the next call
476
+ * re-reads the file instead of re-sending a key the server refused. */
477
+ export interface KeyFileSource {
478
+ (): string | null;
479
+ invalidate(): void;
480
+ }
481
+
482
+ /**
483
+ * Reads a key file and remembers the answer (including "not there"),
484
+ * re-checking at most every `ttlMs`.
485
+ *
486
+ * A secret that lands after boot is picked up without a restart, and a missing
487
+ * one does not stat the disk per request. A found key is not remembered
488
+ * forever: every `ttlMs` the file is re-stat'ed, and a file whose identity
489
+ * (inode, size or mtime) changed is re-read — so a rotated key reaches the
490
+ * daemon within one TTL, and a removed one stops being sent. A 401 from the
491
+ * server calls `invalidate()` (see `OpenVikingClient`), which makes the very
492
+ * next request re-read the file.
493
+ */
494
+ export function keyFromFile(
495
+ path: string,
496
+ ttlMs = 60_000,
497
+ now: () => number = Date.now,
498
+ ): KeyFileSource {
499
+ let cached: string | null = null;
500
+ let signature: string | null = null;
501
+ let checkedAt = -Infinity;
502
+ const read = (): string | null => {
503
+ if (now() - checkedAt < ttlMs) return cached;
504
+ checkedAt = now();
505
+ let sig: string;
506
+ try {
507
+ const st = statSync(path);
508
+ sig = `${st.ino}:${st.size}:${st.mtimeMs}`;
509
+ } catch {
510
+ // Gone (or unreadable): a key that is no longer on disk is no longer
511
+ // ours to send. A keyless client is loud (`no_key`), never silent.
512
+ cached = null;
513
+ signature = null;
514
+ return cached;
515
+ }
516
+ if (sig === signature && cached !== null) return cached;
517
+ try {
518
+ const value = readFileSync(path, "utf8").trim();
519
+ cached = value === "" ? null : value;
520
+ signature = sig;
521
+ } catch {
522
+ cached = null;
523
+ signature = null;
524
+ }
525
+ return cached;
526
+ };
527
+ const source = read as KeyFileSource;
528
+ source.invalidate = () => {
529
+ checkedAt = -Infinity;
530
+ signature = null;
531
+ };
532
+ return source;
533
+ }
534
+
535
+ const DEFAULT_TIMEOUT_MS = 10_000;
536
+
537
+ export class OpenVikingClient {
538
+ private readonly baseUrl: string;
539
+ private readonly key: () => string | null;
540
+ /** The key source's cache-drop, when it has one (`keyFromFile`). */
541
+ private readonly invalidateKey: (() => void) | undefined;
542
+ private readonly user: string;
543
+ private readonly account: string;
544
+ private readonly peerId: string;
545
+ private readonly timeoutMs: number;
546
+ private readonly fetchFn: HttpFetch;
547
+ private readonly log: (msg: string, extra?: unknown) => void;
548
+ private readonly onGap: ((gap: OvGap) => void) | undefined;
549
+ private readonly onRequest: ((record: OvRequestRecord) => void) | undefined;
550
+ private readonly clock: () => number;
551
+ private readonly busyRetry: Required<BusyRetryOptions>;
552
+ private readonly sleep: (ms: number) => Promise<void>;
553
+ private readonly random: () => number;
554
+ private keyGapReported = false;
555
+
556
+ constructor(opts: OpenVikingClientOptions) {
557
+ this.baseUrl = opts.baseUrl.replace(/\/+$/, "");
558
+ const source = opts.apiKey;
559
+ this.key = typeof source === "function" ? () => source() ?? null : () => source ?? null;
560
+ const invalidate =
561
+ typeof source === "function" ? (source as Partial<KeyFileSource>).invalidate : undefined;
562
+ this.invalidateKey = typeof invalidate === "function" ? () => invalidate() : undefined;
563
+ this.user = opts.user ?? "reviewer";
564
+ this.account = opts.account ?? "";
565
+ this.peerId = opts.peerId ?? "";
566
+ this.timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
567
+ this.fetchFn = opts.fetchFn ?? defaultFetch;
568
+ this.log = opts.log ?? (() => {});
569
+ this.onGap = opts.onGap;
570
+ this.onRequest = opts.onRequest;
571
+ this.clock = opts.clock ?? Date.now;
572
+ this.busyRetry = { ...BUSY_RETRY_DEFAULTS, ...(opts.busyRetry ?? {}) };
573
+ this.sleep = opts.sleep ?? defaultSleep;
574
+ this.random = opts.random ?? Math.random;
575
+ }
576
+
577
+ /** Hand one request's outcome to the observer — never throws. */
578
+ private observe(record: OvRequestRecord): void {
579
+ try {
580
+ this.onRequest?.(record);
581
+ } catch {
582
+ // A counter that throws must not become a memory outage.
583
+ }
584
+ }
585
+
586
+ /** The user tree this client's key is confined to — the root every memory
587
+ * URI is built under. */
588
+ memoriesRoot(): string {
589
+ return `viking://user/${this.user}/memories`;
590
+ }
591
+
592
+ /** Scrub the key out of a string before it can leave this class. The key is
593
+ * never deliberately logged; this is the belt to that braces, because server
594
+ * error bodies have been known to echo request material. It is applied where
595
+ * a failure is CONSTRUCTED (`request()`), so every consumer of an
596
+ * `OvFailure.message` or `OvGap.message` — the round prompt's unreadable
597
+ * note, the overseer anomaly, the daemon log, the `onGap` sink — receives the
598
+ * scrubbed text; `report()` scrubs its own line again as braces. */
599
+ private redact(text: string, sent?: string | null): string {
600
+ // The key the request CARRIED, when the caller has it: the source may
601
+ // have rotated while the request was out, and the echo is of the old one.
602
+ let out = text;
603
+ for (const key of new Set([sent, this.key()])) {
604
+ if (key && key.length >= 8) out = out.split(key).join("<redacted>");
605
+ }
606
+ return out;
607
+ }
608
+
609
+ private report(gap: OvGap): void {
610
+ this.log(
611
+ `openviking: ${gap.op} failed (${gap.status || "no answer"} ${gap.code}): ${this.redact(gap.message)}`,
612
+ );
613
+ try {
614
+ this.onGap?.(gap);
615
+ } catch {
616
+ // An alerting sink that throws must not become a memory outage, and
617
+ // certainly must not propagate into a review round.
618
+ }
619
+ }
620
+
621
+ /**
622
+ * One request, total. Every failure mode — no key, connection refused,
623
+ * timeout, non-JSON body, `{status:"error"}` envelope, a `fetch` seam that
624
+ * throws synchronously — comes back as the failure arm of `OvOutcome`.
625
+ *
626
+ * A BUSY answer (`409 path_busy`, see `OvFailure`) is retried here, for
627
+ * every operation: the server answers busy before it checks or writes
628
+ * anything, so a repeat can never double a write. Each retried busy answer
629
+ * is observed as an answer (`conflict` — the server is up and took the
630
+ * key); one still busy when `BUSY_RETRY_DEFAULTS` runs out is reported as
631
+ * the gap it is and returned `busy: true`. A hash-precondition 409 is never
632
+ * retried: it is the refusal it says it is.
633
+ */
634
+ async request<T>(
635
+ op: string,
636
+ path: string,
637
+ init: { method: string; body?: unknown; timeoutMs?: number },
638
+ ): Promise<OvOutcome<T>> {
639
+ const started = this.clock();
640
+ for (let retry = 0; ; retry += 1) {
641
+ const { res, ms } = await this.attempt<T>(op, path, init);
642
+ if (res.ok || !res.busy) return res;
643
+ const delay = busyRetryDelay(retry, this.random, this.busyRetry);
644
+ const elapsed = this.clock() - started;
645
+ if (retry >= this.busyRetry.retries || elapsed + delay > this.busyRetry.budgetMs) {
646
+ const message = `${res.message} — still busy after ${retry} ${retry === 1 ? "retry" : "retries"} (${elapsed} ms); nothing was written`;
647
+ this.report({ op, status: res.status, code: BUSY_CONFLICT_TYPE, message });
648
+ this.observe({
649
+ op,
650
+ outcome: "failed",
651
+ status: res.status,
652
+ code: BUSY_CONFLICT_TYPE,
653
+ ms,
654
+ message,
655
+ });
656
+ return ovFailed(res.status, res.code, message, true);
657
+ }
658
+ this.observe({
659
+ op,
660
+ outcome: "conflict",
661
+ status: res.status,
662
+ code: BUSY_CONFLICT_TYPE,
663
+ ms,
664
+ message: res.message,
665
+ });
666
+ this.log(
667
+ `openviking: ${op} answered busy (${BUSY_CONFLICT_TYPE}) — retry ${retry + 1} in ${delay} ms`,
668
+ );
669
+ await this.sleep(delay);
670
+ }
671
+ }
672
+
673
+ /** One attempt of `request()`. Observes and reports everything except a
674
+ * busy answer, which `request()` decides about (retry, or report once). */
675
+ private async attempt<T>(
676
+ op: string,
677
+ path: string,
678
+ init: { method: string; body?: unknown; timeoutMs?: number },
679
+ ): Promise<{ res: OvOutcome<T>; ms: number }> {
680
+ const key = this.key();
681
+ if (!key) {
682
+ // Reported ONCE per client: a keyless deployment is a standing condition
683
+ // (a dev PC with no secret), and every call would otherwise raise the
684
+ // same anomaly. It must still never look like success — and the
685
+ // observer hears EVERY one, because the health monitor counts it as an
686
+ // authentication failure rather than as quiet.
687
+ if (!this.keyGapReported) {
688
+ this.keyGapReported = true;
689
+ this.report({
690
+ op,
691
+ status: 0,
692
+ code: "no_key",
693
+ message:
694
+ "no OpenViking reviewer key configured — every memory call degrades until one is",
695
+ });
696
+ }
697
+ this.observe({
698
+ op,
699
+ outcome: "auth",
700
+ status: 0,
701
+ code: "no_key",
702
+ ms: 0,
703
+ message: "no OpenViking key configured",
704
+ });
705
+ return { res: ovFailed(0, "no_key", "no OpenViking reviewer key configured"), ms: 0 };
706
+ }
707
+ const started = this.clock();
708
+ const headers: Record<string, string> = {
709
+ "Content-Type": "application/json",
710
+ Authorization: `Bearer ${key}`,
711
+ };
712
+ // Ignored in api_key mode, load-bearing in trusted mode. Harmless either
713
+ // way, and it keeps the identity explicit in the request we send.
714
+ if (this.account) headers["X-OpenViking-Account"] = this.account;
715
+ if (this.user) headers["X-OpenViking-User"] = this.user;
716
+ if (this.peerId) headers["X-OpenViking-Actor-Peer"] = this.peerId;
717
+
718
+ let res: HttpResponse;
719
+ let raw: string;
720
+ try {
721
+ const signal = timeoutSignal(init.timeoutMs ?? this.timeoutMs);
722
+ res = await this.fetchFn(`${this.baseUrl}${path}`, {
723
+ method: init.method,
724
+ headers,
725
+ ...(init.body !== undefined ? { body: JSON.stringify(init.body) } : {}),
726
+ ...(signal ? { signal } : {}),
727
+ });
728
+ raw = await res.text();
729
+ } catch (err) {
730
+ const gap: OvGap = {
731
+ op,
732
+ status: 0,
733
+ code: "transport",
734
+ message: this.redact(errText(err), key),
735
+ };
736
+ this.report(gap);
737
+ this.observe({
738
+ op,
739
+ outcome: "failed",
740
+ status: 0,
741
+ code: gap.code,
742
+ ms: this.clock() - started,
743
+ message: gap.message,
744
+ });
745
+ return { res: ovFailed(gap.status, gap.code, gap.message), ms: this.clock() - started };
746
+ }
747
+ const ms = this.clock() - started;
748
+
749
+ // Every OpenViking answer is a `{status, result, error}` envelope. Anything
750
+ // else — an nginx error page, a bare `null`, an empty or truncated body, an
751
+ // object with no `status` — is NOT an answer, and a 200 carrying one must
752
+ // not be read as success: that is how a write that never happened gets
753
+ // reported as a write that did. A 200 succeeds only on `status: "ok"`.
754
+ let body: {
755
+ status?: unknown;
756
+ result?: unknown;
757
+ error?: { code?: unknown; message?: unknown };
758
+ } | null = null;
759
+ try {
760
+ const parsed: unknown = JSON.parse(raw);
761
+ if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) body = parsed;
762
+ } catch {
763
+ body = null;
764
+ }
765
+ if (res.ok && body !== null && body.status !== "ok" && body.status !== "error") body = null;
766
+ if (body === null) {
767
+ if (res.ok) {
768
+ const gap: OvGap = {
769
+ op,
770
+ status: res.status,
771
+ code: "bad_body",
772
+ message: `response was not an OpenViking envelope (${raw.length} bytes)`,
773
+ };
774
+ this.report(gap);
775
+ this.observe({
776
+ op,
777
+ outcome: "failed",
778
+ status: gap.status,
779
+ code: gap.code,
780
+ ms,
781
+ message: gap.message,
782
+ });
783
+ return { res: ovFailed(gap.status, gap.code, gap.message), ms };
784
+ }
785
+ body = {};
786
+ }
787
+
788
+ if (!res.ok || body.status === "error") {
789
+ const code = typeof body.error?.code === "string" ? body.error.code : `http_${res.status}`;
790
+ const message = this.redact(
791
+ typeof body.error?.message === "string" ? body.error.message : `HTTP ${res.status}`,
792
+ key,
793
+ );
794
+ // The directory lock was held: nothing was checked or
795
+ // written. `request()` retries it — not observed or reported here.
796
+ if (isBusyConflict(res.status, body.error)) {
797
+ return { res: ovFailed(res.status, code, message, true), ms };
798
+ }
799
+ const outcome = ovFailed(res.status, code, message);
800
+ const auth = isAuthFailure(res.status, code, message);
801
+ const absent = !auth && isNotFound(res.status, code);
802
+ // A 409 is the precondition working as designed, and the engine's own
803
+ // NOT_FOUND envelope is an authenticated answer (the path is not there —
804
+ // the store reads it as known-empty): neither is alerted on. A bare 404
805
+ // with no such code — a missing route, the wrong service behind the
806
+ // forward — is still reported: it is the one trace that says so.
807
+ const answered = outcome.conflict || (absent && code === "NOT_FOUND");
808
+ if (!answered) this.report({ op, status: res.status, code, message });
809
+ this.observe({
810
+ op,
811
+ outcome: outcome.conflict ? "conflict" : auth ? "auth" : absent ? "absent" : "failed",
812
+ status: res.status,
813
+ code,
814
+ ms,
815
+ message,
816
+ });
817
+ // The key we sent was refused: drop the source's cache so the NEXT
818
+ // request reads the file again — a rotated key must not wait out a TTL
819
+ // behind a 401. Last, deliberately: `report()` reads the
820
+ // key to redact with, and a read after the drop would re-cache the very
821
+ // key that was just refused for another full TTL.
822
+ if (auth) this.invalidateKey?.();
823
+ return { res: outcome, ms };
824
+ }
825
+
826
+ this.observe({ op, outcome: "ok", status: res.status, code: "", ms });
827
+ return { res: { ok: true, status: res.status, result: (body.result ?? body) as T }, ms };
828
+ }
829
+
830
+ // ---- content ---------------------------------------------------------------
831
+
832
+ /**
833
+ * The ONE write path. There is deliberately no `content/write` wrapper on
834
+ * this class — see the header. `conflict: true` on the outcome means a
835
+ * precondition refused (stale `base_hash`, or `create_if_absent` on a target
836
+ * that already exists), and the stored file is unchanged.
837
+ */
838
+ async batchWrite(
839
+ request: BatchWriteRequest,
840
+ timeoutMs?: number,
841
+ ): Promise<OvOutcome<BatchWriteResult>> {
842
+ const res = await this.request<unknown>("batch_write", "/api/v1/content/batch-write", {
843
+ method: "POST",
844
+ body: request,
845
+ ...(timeoutMs !== undefined ? { timeoutMs } : {}),
846
+ });
847
+ if (!res.ok) return res;
848
+ // The three URI lists are the only proof a write landed; normalizing them
849
+ // here means the caller checks membership rather than trusting a 200.
850
+ const raw = (res.result && typeof res.result === "object" ? res.result : {}) as Record<
851
+ string,
852
+ unknown
853
+ >;
854
+ return {
855
+ ok: true,
856
+ status: res.status,
857
+ result: {
858
+ root_uri: str(raw["root_uri"]),
859
+ created: strings(raw["created"]),
860
+ updated: strings(raw["updated"]),
861
+ unchanged: strings(raw["unchanged"]),
862
+ },
863
+ };
864
+ }
865
+
866
+ /** L2 full content. Safe as a hash source ONLY because every file this
867
+ * system writes was written by batch-write and so carries no `MEMORY_FIELDS`
868
+ * footer for `content/read` to strip. */
869
+ async readContent(uri: string): Promise<OvOutcome<string>> {
870
+ const res = await this.request<unknown>(
871
+ "read",
872
+ `/api/v1/content/read?uri=${encodeURIComponent(uri)}`,
873
+ { method: "GET" },
874
+ );
875
+ if (!res.ok) return res;
876
+ // A successful envelope whose result is not text is a malformed answer,
877
+ // not an empty file: an empty read would pass for a healthy empty entry.
878
+ if (typeof res.result !== "string") {
879
+ return ovFailed(res.status, "MALFORMED_RESULT", "content/read result is not a string");
880
+ }
881
+ return { ok: true, status: res.status, result: res.result };
882
+ }
883
+
884
+ async ls(uri: string): Promise<OvOutcome<OvDirEntry[]>> {
885
+ const res = await this.request<unknown>("ls", `/api/v1/fs/ls?uri=${encodeURIComponent(uri)}`, {
886
+ method: "GET",
887
+ });
888
+ if (!res.ok) return res;
889
+ // Likewise a non-array result is a malformed answer, not an empty directory.
890
+ if (!Array.isArray(res.result)) {
891
+ return ovFailed(res.status, "MALFORMED_RESULT", "fs/ls result is not a list");
892
+ }
893
+ const rows: unknown[] = res.result;
894
+ return {
895
+ ok: true,
896
+ status: res.status,
897
+ result: rows
898
+ .filter((r): r is Record<string, unknown> => !!r && typeof r === "object")
899
+ .map((r) => ({
900
+ uri: str(r["uri"]),
901
+ name: str(r["name"]) || basename(str(r["uri"])),
902
+ isDir: r["isDir"] === true,
903
+ size: typeof r["size"] === "number" ? r["size"] : 0,
904
+ modTime: str(r["modTime"]),
905
+ })),
906
+ };
907
+ }
908
+
909
+ remove(uri: string, recursive = false): Promise<OvOutcome<unknown>> {
910
+ return this.request<unknown>(
911
+ "delete",
912
+ `/api/v1/fs?uri=${encodeURIComponent(uri)}&recursive=${recursive}`,
913
+ { method: "DELETE" },
914
+ );
915
+ }
916
+
917
+ /**
918
+ * Create a directory (and its parents). A fresh server has ONLY
919
+ * `viking://user/default`, so the first write into `user/<us>/memories/<cat>`
920
+ * 404s on the missing root — nothing else provisions the tree, and making
921
+ * boot order responsible for it would put a network call in front of the
922
+ * daemon. The store calls this lazily on that failure, and eagerly from
923
+ * `ensureWritable`.
924
+ */
925
+ async mkdir(uri: string, parents = true): Promise<boolean> {
926
+ const res = await this.request<unknown>("mkdir", "/api/v1/fs/mkdir", {
927
+ method: "POST",
928
+ body: { uri, parents },
929
+ });
930
+ // `fs/mkdir` is NOT idempotent: an existing directory comes back CONFLICT
931
+ // ("already exists"), verified live against 0.4.15. Every caller here wants
932
+ // `mkdir -p` semantics — the directory is there afterwards either way — so
933
+ // the conflict is a success, not a failure to report upward.
934
+ return res.ok || res.conflict;
935
+ }
936
+
937
+ /**
938
+ * Set the retrieval tag list that search's `tags` filter reads. Best-effort
939
+ * by contract: the tags are already in the written body's header, which is
940
+ * what `content/read` returns and what the store parses, so a failure here
941
+ * narrows retrieval — it never loses the memory or its tags.
942
+ */
943
+ async setTags(
944
+ uri: string,
945
+ tags: string[],
946
+ mode: "append" | "replace" = "replace",
947
+ ): Promise<boolean> {
948
+ if (tags.length === 0 && mode === "append") return true;
949
+ const res = await this.request<unknown>("set_tags", "/api/v1/fs/attrs/set_tags", {
950
+ method: "POST",
951
+ body: { uri, tags, mode },
952
+ });
953
+ return res.ok;
954
+ }
955
+
956
+ // ---- search ----------------------------------------------------------------
957
+
958
+ /**
959
+ * A budgeted context search. Returns the rendered block AND the usage stats;
960
+ * callers that only want a prompt block take `.rendered`, callers that need
961
+ * to know what the budget bought read `.stats`.
962
+ */
963
+ async searchContext(
964
+ query: string,
965
+ opts: ContextSearchOptions = {},
966
+ ): Promise<OvOutcome<ContextSearchResult>> {
967
+ const body = buildContextSearchBody(query, opts, (gap) => this.report(gap));
968
+ const res = await this.request<unknown>("search", "/api/v1/search/search", {
969
+ method: "POST",
970
+ body,
971
+ ...(opts.timeoutMs !== undefined ? { timeoutMs: opts.timeoutMs } : {}),
972
+ });
973
+ if (!res.ok) return res;
974
+ const result = (res.result && typeof res.result === "object" ? res.result : {}) as Record<
975
+ string,
976
+ unknown
977
+ >;
978
+ const rawEntries = Array.isArray(result["entries"]) ? result["entries"] : [];
979
+ return {
980
+ ok: true,
981
+ status: res.status,
982
+ result: {
983
+ entries: rawEntries
984
+ .filter((e): e is Record<string, unknown> => !!e && typeof e === "object")
985
+ .map((e) => ({
986
+ uri: str(e["uri"]),
987
+ category: str(e["category"]) || "memories",
988
+ score: typeof e["score"] === "number" ? e["score"] : 0,
989
+ detail: str(e["detail"]),
990
+ text: str(e["text"]) || str(e["content"]) || str(e["abstract"]),
991
+ origin: str(e["origin"]),
992
+ })),
993
+ rendered: str(result["rendered"]).trim(),
994
+ digest: str(result["digest"]).trim(),
995
+ stats: (result["stats"] && typeof result["stats"] === "object"
996
+ ? result["stats"]
997
+ : {}) as Record<string, unknown>,
998
+ },
999
+ };
1000
+ }
1001
+
1002
+ /**
1003
+ * A plain vector search inside one or more areas (`POST /api/v1/search/find`):
1004
+ * the hits the server ranks by similarity under `target_uri`,
1005
+ * never a global top K filtered afterwards. The memories bucket only; each
1006
+ * hit's text is its abstract (the stored content itself in a deployment
1007
+ * without a VLM), else its overview.
1008
+ *
1009
+ * Deterministic by construction: no `session_id` is sent, so the server
1010
+ * runs no query expansion (that stage keys on a session), and there is no
1011
+ * rewrite stage on this route at all.
1012
+ */
1013
+ async find(query: string, opts: FindOptions): Promise<OvOutcome<FindResultHit[]>> {
1014
+ const res = await this.request<unknown>("find", "/api/v1/search/find", {
1015
+ method: "POST",
1016
+ body: buildFindBody(query, opts),
1017
+ ...(opts.timeoutMs !== undefined ? { timeoutMs: opts.timeoutMs } : {}),
1018
+ });
1019
+ if (!res.ok) return res;
1020
+ const result = (res.result && typeof res.result === "object" ? res.result : {}) as Record<
1021
+ string,
1022
+ unknown
1023
+ >;
1024
+ const memories = Array.isArray(result["memories"]) ? result["memories"] : [];
1025
+ return {
1026
+ ok: true,
1027
+ status: res.status,
1028
+ result: memories
1029
+ .filter((m): m is Record<string, unknown> => !!m && typeof m === "object")
1030
+ .map((m) => ({
1031
+ uri: str(m["uri"]),
1032
+ score: typeof m["score"] === "number" && Number.isFinite(m["score"]) ? m["score"] : 0,
1033
+ text: str(m["abstract"]) || str(m["overview"]),
1034
+ }))
1035
+ .filter((h) => h.uri !== ""),
1036
+ };
1037
+ }
1038
+
1039
+ // ---- sessions --------------------------------------------------------------
1040
+
1041
+ /** Create a per-PR session with extraction fully disabled. The policy is not
1042
+ * a parameter: a session without it rots (see `DISABLED_MEMORY_POLICY`). */
1043
+ createSession(sessionId: string): Promise<OvOutcome<OvSessionResult>> {
1044
+ return this.request<OvSessionResult>("session_create", "/api/v1/sessions", {
1045
+ method: "POST",
1046
+ body: { session_id: sessionId, memory_policy: DISABLED_MEMORY_POLICY },
1047
+ });
1048
+ }
1049
+
1050
+ /**
1051
+ * The ids of every session the key can see — what the
1052
+ * stale-session sweep lists. The server swallows its OWN listing failures
1053
+ * into an empty list (`session_service.py` `sessions()`), so `[]` means "none
1054
+ * listed", never proof that none exist.
1055
+ */
1056
+ async listSessions(): Promise<OvOutcome<string[]>> {
1057
+ const res = await this.request<unknown>("session_list", "/api/v1/sessions", {
1058
+ method: "GET",
1059
+ });
1060
+ if (!res.ok) return res;
1061
+ const rows = Array.isArray(res.result) ? res.result : [];
1062
+ const ids = rows
1063
+ .map((r) =>
1064
+ r && typeof r === "object" ? str((r as Record<string, unknown>)["session_id"]) : "",
1065
+ )
1066
+ .filter((id) => id !== "");
1067
+ return { ok: true, status: res.status, result: [...new Set(ids)] };
1068
+ }
1069
+
1070
+ /** Removes the session's messages and archives (verified: the tree is gone).
1071
+ * Sessions are absent from the search corpus, so this frees disk, not
1072
+ * recall. */
1073
+ deleteSession(sessionId: string): Promise<OvOutcome<unknown>> {
1074
+ return this.request<unknown>(
1075
+ "session_delete",
1076
+ `/api/v1/sessions/${encodeURIComponent(sessionId)}`,
1077
+ { method: "DELETE" },
1078
+ );
1079
+ }
1080
+ }
1081
+
1082
+ // ---- helpers ----------------------------------------------------------------
1083
+
1084
+ function str(value: unknown): string {
1085
+ return typeof value === "string" ? value : "";
1086
+ }
1087
+
1088
+ function strings(value: unknown): string[] {
1089
+ return Array.isArray(value) ? value.filter((v): v is string => typeof v === "string") : [];
1090
+ }
1091
+
1092
+ /** Did this URI actually land? A batch-write that returns 200 without naming
1093
+ * the target in any of its three lists did NOT write it, and reporting that as
1094
+ * a success is how a memory silently goes missing. */
1095
+ export function batchWriteLanded(result: BatchWriteResult, uri: string): boolean {
1096
+ return (
1097
+ result.created.includes(uri) || result.updated.includes(uri) || result.unchanged.includes(uri)
1098
+ );
1099
+ }
1100
+
1101
+ function basename(uri: string): string {
1102
+ const cleaned = uri.replace(/\/+$/, "");
1103
+ const cut = cleaned.lastIndexOf("/");
1104
+ return cut >= 0 ? cleaned.slice(cut + 1) : cleaned;
1105
+ }
1106
+
1107
+ /** A thrown request error as one line: a timeout or abort is "timeout",
1108
+ * anything else its message. Shared by every OpenViking probe. */
1109
+ export function errText(err: unknown): string {
1110
+ if (err instanceof Error)
1111
+ return err.name === "TimeoutError" || err.name === "AbortError" ? "timeout" : err.message;
1112
+ return String(err);
1113
+ }
1114
+
1115
+ /** `AbortSignal.timeout` where the runtime has it; undefined otherwise. Tests
1116
+ * inject their own fetch and never see it. */
1117
+ function timeoutSignal(ms: number): AbortSignal | undefined {
1118
+ try {
1119
+ return AbortSignal.timeout(ms);
1120
+ } catch {
1121
+ return undefined;
1122
+ }
1123
+ }
1124
+
1125
+ const defaultFetch: HttpFetch = (url, init) => fetch(url, init);
1126
+
1127
+ const defaultSleep = (ms: number): Promise<void> =>
1128
+ new Promise((resolve) => {
1129
+ const t = setTimeout(resolve, ms);
1130
+ t.unref?.();
1131
+ });