@askdkc/kiokuko 0.1.16 → 0.1.19

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 (549) hide show
  1. package/README.ja.md +91 -112
  2. package/README.ko.md +90 -102
  3. package/README.md +103 -260
  4. package/README.zh-CN.md +88 -102
  5. package/dist/agent-file/atomic-write.d.ts +90 -3
  6. package/dist/agent-file/atomic-write.d.ts.map +1 -1
  7. package/dist/agent-file/atomic-write.js +990 -14
  8. package/dist/agent-file/atomic-write.js.map +1 -1
  9. package/dist/agent-file/managed-block.d.ts +12 -1
  10. package/dist/agent-file/managed-block.d.ts.map +1 -1
  11. package/dist/agent-file/managed-block.js +49 -4
  12. package/dist/agent-file/managed-block.js.map +1 -1
  13. package/dist/agent-file/render.d.ts +1 -1
  14. package/dist/agent-file/render.d.ts.map +1 -1
  15. package/dist/agent-file/render.js +10 -7
  16. package/dist/agent-file/render.js.map +1 -1
  17. package/dist/akinator/agent-task.d.ts +14 -24
  18. package/dist/akinator/agent-task.d.ts.map +1 -1
  19. package/dist/akinator/agent-task.js +460 -103
  20. package/dist/akinator/agent-task.js.map +1 -1
  21. package/dist/akinator/capabilities.d.ts +52 -7
  22. package/dist/akinator/capabilities.d.ts.map +1 -1
  23. package/dist/akinator/capabilities.js +226 -28
  24. package/dist/akinator/capabilities.js.map +1 -1
  25. package/dist/akinator/capability-binding.d.ts +11 -0
  26. package/dist/akinator/capability-binding.d.ts.map +1 -0
  27. package/dist/akinator/capability-binding.js +56 -0
  28. package/dist/akinator/capability-binding.js.map +1 -0
  29. package/dist/akinator/domain.js +2 -2
  30. package/dist/akinator/domain.js.map +1 -1
  31. package/dist/akinator/knowledge-path.d.ts.map +1 -1
  32. package/dist/akinator/knowledge-path.js +409 -39
  33. package/dist/akinator/knowledge-path.js.map +1 -1
  34. package/dist/akinator/orchestrator.d.ts +3 -4
  35. package/dist/akinator/orchestrator.d.ts.map +1 -1
  36. package/dist/akinator/orchestrator.js +1 -4
  37. package/dist/akinator/orchestrator.js.map +1 -1
  38. package/dist/akinator/service.d.ts +0 -4
  39. package/dist/akinator/service.d.ts.map +1 -1
  40. package/dist/akinator/service.js +19 -35
  41. package/dist/akinator/service.js.map +1 -1
  42. package/dist/akinator/skill-discovery-attempt.d.ts +20 -0
  43. package/dist/akinator/skill-discovery-attempt.d.ts.map +1 -0
  44. package/dist/akinator/skill-discovery-attempt.js +390 -0
  45. package/dist/akinator/skill-discovery-attempt.js.map +1 -0
  46. package/dist/akinator/store.d.ts.map +1 -1
  47. package/dist/akinator/store.js +107 -52
  48. package/dist/akinator/store.js.map +1 -1
  49. package/dist/akinator/types.d.ts +0 -12
  50. package/dist/akinator/types.d.ts.map +1 -1
  51. package/dist/bin/kiokuko.js +0 -0
  52. package/dist/cli.d.ts +2 -0
  53. package/dist/cli.d.ts.map +1 -1
  54. package/dist/cli.js +561 -144
  55. package/dist/cli.js.map +1 -1
  56. package/dist/client/server-client.d.ts +5 -3
  57. package/dist/client/server-client.d.ts.map +1 -1
  58. package/dist/client/server-client.js +486 -181
  59. package/dist/client/server-client.js.map +1 -1
  60. package/dist/commands/agent.d.ts +2 -0
  61. package/dist/commands/agent.d.ts.map +1 -1
  62. package/dist/commands/agent.js +861 -86
  63. package/dist/commands/agent.js.map +1 -1
  64. package/dist/commands/backup.d.ts +2 -1
  65. package/dist/commands/backup.d.ts.map +1 -1
  66. package/dist/commands/backup.js +64 -8
  67. package/dist/commands/backup.js.map +1 -1
  68. package/dist/commands/doctor.d.ts +5 -1
  69. package/dist/commands/doctor.d.ts.map +1 -1
  70. package/dist/commands/doctor.js +70 -26
  71. package/dist/commands/doctor.js.map +1 -1
  72. package/dist/commands/export.d.ts +0 -4
  73. package/dist/commands/export.d.ts.map +1 -1
  74. package/dist/commands/export.js +191 -32
  75. package/dist/commands/export.js.map +1 -1
  76. package/dist/commands/import.d.ts +10 -1
  77. package/dist/commands/import.d.ts.map +1 -1
  78. package/dist/commands/import.js +592 -113
  79. package/dist/commands/import.js.map +1 -1
  80. package/dist/commands/init.d.ts +19 -1
  81. package/dist/commands/init.d.ts.map +1 -1
  82. package/dist/commands/init.js +569 -22
  83. package/dist/commands/init.js.map +1 -1
  84. package/dist/commands/purge.d.ts.map +1 -1
  85. package/dist/commands/purge.js +3 -0
  86. package/dist/commands/purge.js.map +1 -1
  87. package/dist/commands/setup.d.ts +34 -8
  88. package/dist/commands/setup.d.ts.map +1 -1
  89. package/dist/commands/setup.js +418 -86
  90. package/dist/commands/setup.js.map +1 -1
  91. package/dist/commands/skills.d.ts +9 -0
  92. package/dist/commands/skills.d.ts.map +1 -0
  93. package/dist/commands/skills.js +317 -0
  94. package/dist/commands/skills.js.map +1 -0
  95. package/dist/commands/use.d.ts +10 -2
  96. package/dist/commands/use.d.ts.map +1 -1
  97. package/dist/commands/use.js +851 -73
  98. package/dist/commands/use.js.map +1 -1
  99. package/dist/config/paths.d.ts +11 -1
  100. package/dist/config/paths.d.ts.map +1 -1
  101. package/dist/config/paths.js +64 -29
  102. package/dist/config/paths.js.map +1 -1
  103. package/dist/config/project-config.d.ts +1 -0
  104. package/dist/config/project-config.d.ts.map +1 -1
  105. package/dist/config/project-config.js +70 -32
  106. package/dist/config/project-config.js.map +1 -1
  107. package/dist/context/broker.d.ts +30 -14
  108. package/dist/context/broker.d.ts.map +1 -1
  109. package/dist/context/broker.js +628 -150
  110. package/dist/context/broker.js.map +1 -1
  111. package/dist/context/delivery.d.ts +8 -22
  112. package/dist/context/delivery.d.ts.map +1 -1
  113. package/dist/context/delivery.js +204 -152
  114. package/dist/context/delivery.js.map +1 -1
  115. package/dist/context/feedback.d.ts +11 -12
  116. package/dist/context/feedback.d.ts.map +1 -1
  117. package/dist/context/feedback.js +250 -268
  118. package/dist/context/feedback.js.map +1 -1
  119. package/dist/context/origin.d.ts +9 -0
  120. package/dist/context/origin.d.ts.map +1 -0
  121. package/dist/context/origin.js +15 -0
  122. package/dist/context/origin.js.map +1 -0
  123. package/dist/context/ranking.d.ts +4 -13
  124. package/dist/context/ranking.d.ts.map +1 -1
  125. package/dist/context/ranking.js +21 -5
  126. package/dist/context/ranking.js.map +1 -1
  127. package/dist/context/recommendations.d.ts +0 -5
  128. package/dist/context/recommendations.d.ts.map +1 -1
  129. package/dist/context/recommendations.js +0 -1
  130. package/dist/context/recommendations.js.map +1 -1
  131. package/dist/context/run-state.d.ts +26 -0
  132. package/dist/context/run-state.d.ts.map +1 -0
  133. package/dist/context/run-state.js +399 -0
  134. package/dist/context/run-state.js.map +1 -0
  135. package/dist/context/scoped-broker.d.ts +19 -6
  136. package/dist/context/scoped-broker.d.ts.map +1 -1
  137. package/dist/context/scoped-broker.js +530 -131
  138. package/dist/context/scoped-broker.js.map +1 -1
  139. package/dist/context/selection-state.d.ts +19 -0
  140. package/dist/context/selection-state.d.ts.map +1 -0
  141. package/dist/context/selection-state.js +250 -0
  142. package/dist/context/selection-state.js.map +1 -0
  143. package/dist/db/adapter.d.ts +5 -3
  144. package/dist/db/adapter.d.ts.map +1 -1
  145. package/dist/db/adapter.js +6 -3
  146. package/dist/db/adapter.js.map +1 -1
  147. package/dist/db/capabilities.d.ts.map +1 -1
  148. package/dist/db/capabilities.js +34 -16
  149. package/dist/db/capabilities.js.map +1 -1
  150. package/dist/db/connection.d.ts +8 -0
  151. package/dist/db/connection.d.ts.map +1 -1
  152. package/dist/db/connection.js +55 -26
  153. package/dist/db/connection.js.map +1 -1
  154. package/dist/db/migrate.d.ts +28 -7
  155. package/dist/db/migrate.d.ts.map +1 -1
  156. package/dist/db/migrate.js +106 -78
  157. package/dist/db/migrate.js.map +1 -1
  158. package/dist/db/sqlite-retry.d.ts +11 -0
  159. package/dist/db/sqlite-retry.d.ts.map +1 -0
  160. package/dist/db/sqlite-retry.js +66 -0
  161. package/dist/db/sqlite-retry.js.map +1 -0
  162. package/dist/db/transaction.d.ts +13 -0
  163. package/dist/db/transaction.d.ts.map +1 -1
  164. package/dist/db/transaction.js +53 -24
  165. package/dist/db/transaction.js.map +1 -1
  166. package/dist/db/upgrade-backup.d.ts +58 -2
  167. package/dist/db/upgrade-backup.d.ts.map +1 -1
  168. package/dist/db/upgrade-backup.js +757 -28
  169. package/dist/db/upgrade-backup.js.map +1 -1
  170. package/dist/errors.js +1 -1
  171. package/dist/errors.js.map +1 -1
  172. package/dist/gateway/agent-service.d.ts +4 -1
  173. package/dist/gateway/agent-service.d.ts.map +1 -1
  174. package/dist/gateway/agent-service.js +71 -58
  175. package/dist/gateway/agent-service.js.map +1 -1
  176. package/dist/gateway/checkpoint-service.d.ts +1 -0
  177. package/dist/gateway/checkpoint-service.d.ts.map +1 -1
  178. package/dist/gateway/checkpoint-service.js +47 -24
  179. package/dist/gateway/checkpoint-service.js.map +1 -1
  180. package/dist/ledger/archive.d.ts +1 -4
  181. package/dist/ledger/archive.d.ts.map +1 -1
  182. package/dist/ledger/archive.js +134 -54
  183. package/dist/ledger/archive.js.map +1 -1
  184. package/dist/ledger/maintenance.d.ts +0 -11
  185. package/dist/ledger/maintenance.d.ts.map +1 -1
  186. package/dist/ledger/maintenance.js +41 -44
  187. package/dist/ledger/maintenance.js.map +1 -1
  188. package/dist/ledger/projection.d.ts +0 -1
  189. package/dist/ledger/projection.d.ts.map +1 -1
  190. package/dist/ledger/projection.js.map +1 -1
  191. package/dist/ledger/promotion.d.ts +0 -9
  192. package/dist/ledger/promotion.d.ts.map +1 -1
  193. package/dist/ledger/promotion.js.map +1 -1
  194. package/dist/ledger/query.d.ts +1 -15
  195. package/dist/ledger/query.d.ts.map +1 -1
  196. package/dist/ledger/query.js.map +1 -1
  197. package/dist/ledger/store.d.ts +0 -1
  198. package/dist/ledger/store.d.ts.map +1 -1
  199. package/dist/ledger/store.js +11 -8
  200. package/dist/ledger/store.js.map +1 -1
  201. package/dist/ledger/types.d.ts +0 -4
  202. package/dist/ledger/types.d.ts.map +1 -1
  203. package/dist/ledger/types.js.map +1 -1
  204. package/dist/ledger/validate.d.ts.map +1 -1
  205. package/dist/ledger/validate.js +0 -5
  206. package/dist/ledger/validate.js.map +1 -1
  207. package/dist/mcp/bounded-stdio-transport.d.ts +23 -0
  208. package/dist/mcp/bounded-stdio-transport.d.ts.map +1 -0
  209. package/dist/mcp/bounded-stdio-transport.js +109 -0
  210. package/dist/mcp/bounded-stdio-transport.js.map +1 -0
  211. package/dist/mcp/server.d.ts +4 -0
  212. package/dist/mcp/server.d.ts.map +1 -1
  213. package/dist/mcp/server.js +111 -75
  214. package/dist/mcp/server.js.map +1 -1
  215. package/dist/memory/audit.d.ts +0 -1
  216. package/dist/memory/audit.d.ts.map +1 -1
  217. package/dist/memory/audit.js +0 -1
  218. package/dist/memory/audit.js.map +1 -1
  219. package/dist/memory/curator.d.ts +45 -1
  220. package/dist/memory/curator.d.ts.map +1 -1
  221. package/dist/memory/curator.js +290 -68
  222. package/dist/memory/curator.js.map +1 -1
  223. package/dist/memory/entries.d.ts +12 -2
  224. package/dist/memory/entries.d.ts.map +1 -1
  225. package/dist/memory/entries.js +198 -114
  226. package/dist/memory/entries.js.map +1 -1
  227. package/dist/memory/federated-retrieval.d.ts +78 -0
  228. package/dist/memory/federated-retrieval.d.ts.map +1 -0
  229. package/dist/memory/federated-retrieval.js +441 -0
  230. package/dist/memory/federated-retrieval.js.map +1 -0
  231. package/dist/memory/hybrid-retrieval.d.ts +5 -11
  232. package/dist/memory/hybrid-retrieval.d.ts.map +1 -1
  233. package/dist/memory/hybrid-retrieval.js +78 -58
  234. package/dist/memory/hybrid-retrieval.js.map +1 -1
  235. package/dist/memory/lifecycle.d.ts.map +1 -1
  236. package/dist/memory/lifecycle.js +17 -13
  237. package/dist/memory/lifecycle.js.map +1 -1
  238. package/dist/memory/portability.d.ts +10 -0
  239. package/dist/memory/portability.d.ts.map +1 -0
  240. package/dist/memory/portability.js +44 -0
  241. package/dist/memory/portability.js.map +1 -0
  242. package/dist/memory/rebuild-search.d.ts +5 -0
  243. package/dist/memory/rebuild-search.d.ts.map +1 -1
  244. package/dist/memory/rebuild-search.js +101 -76
  245. package/dist/memory/rebuild-search.js.map +1 -1
  246. package/dist/memory/retrieval-query.d.ts +0 -5
  247. package/dist/memory/retrieval-query.d.ts.map +1 -1
  248. package/dist/memory/retrieval-query.js +0 -5
  249. package/dist/memory/retrieval-query.js.map +1 -1
  250. package/dist/memory/retrieval.d.ts +11 -0
  251. package/dist/memory/retrieval.d.ts.map +1 -1
  252. package/dist/memory/retrieval.js +34 -120
  253. package/dist/memory/retrieval.js.map +1 -1
  254. package/dist/memory/revisions.d.ts +76 -1
  255. package/dist/memory/revisions.d.ts.map +1 -1
  256. package/dist/memory/revisions.js +539 -35
  257. package/dist/memory/revisions.js.map +1 -1
  258. package/dist/memory/scoped-memory.d.ts +22 -13
  259. package/dist/memory/scoped-memory.d.ts.map +1 -1
  260. package/dist/memory/scoped-memory.js +248 -139
  261. package/dist/memory/scoped-memory.js.map +1 -1
  262. package/dist/memory/secrets.d.ts +2 -0
  263. package/dist/memory/secrets.d.ts.map +1 -1
  264. package/dist/memory/secrets.js +36 -0
  265. package/dist/memory/secrets.js.map +1 -1
  266. package/dist/memory/structured-memory.d.ts +8 -1
  267. package/dist/memory/structured-memory.d.ts.map +1 -1
  268. package/dist/memory/structured-memory.js +74 -20
  269. package/dist/memory/structured-memory.js.map +1 -1
  270. package/dist/memory/workspaces.d.ts +9 -0
  271. package/dist/memory/workspaces.d.ts.map +1 -1
  272. package/dist/memory/workspaces.js +67 -0
  273. package/dist/memory/workspaces.js.map +1 -1
  274. package/dist/package-version.d.ts +2 -0
  275. package/dist/package-version.d.ts.map +1 -0
  276. package/dist/package-version.js +7 -0
  277. package/dist/package-version.js.map +1 -0
  278. package/dist/repository/binding.d.ts +5 -0
  279. package/dist/repository/binding.d.ts.map +1 -1
  280. package/dist/repository/binding.js +117 -17
  281. package/dist/repository/binding.js.map +1 -1
  282. package/dist/repository/framework-version.d.ts +8 -0
  283. package/dist/repository/framework-version.d.ts.map +1 -0
  284. package/dist/repository/framework-version.js +29 -0
  285. package/dist/repository/framework-version.js.map +1 -0
  286. package/dist/repository/identity-value.d.ts +4 -0
  287. package/dist/repository/identity-value.d.ts.map +1 -0
  288. package/dist/repository/identity-value.js +24 -0
  289. package/dist/repository/identity-value.js.map +1 -0
  290. package/dist/repository/identity.d.ts.map +1 -1
  291. package/dist/repository/identity.js +2 -0
  292. package/dist/repository/identity.js.map +1 -1
  293. package/dist/repository/project-fingerprint.d.ts +33 -0
  294. package/dist/repository/project-fingerprint.d.ts.map +1 -0
  295. package/dist/repository/project-fingerprint.js +429 -0
  296. package/dist/repository/project-fingerprint.js.map +1 -0
  297. package/dist/repository/remote-url.d.ts +0 -1
  298. package/dist/repository/remote-url.d.ts.map +1 -1
  299. package/dist/repository/remote-url.js +0 -1
  300. package/dist/repository/remote-url.js.map +1 -1
  301. package/dist/runtime-version.d.ts +2 -1
  302. package/dist/runtime-version.d.ts.map +1 -1
  303. package/dist/runtime-version.js +21 -4
  304. package/dist/runtime-version.js.map +1 -1
  305. package/dist/serialization/boundary-json.d.ts +20 -0
  306. package/dist/serialization/boundary-json.d.ts.map +1 -0
  307. package/dist/serialization/boundary-json.js +129 -0
  308. package/dist/serialization/boundary-json.js.map +1 -0
  309. package/dist/serialization/envelope.js +1 -1
  310. package/dist/serialization/envelope.js.map +1 -1
  311. package/dist/serialization/validate.d.ts +7 -0
  312. package/dist/serialization/validate.d.ts.map +1 -1
  313. package/dist/serialization/validate.js +53 -13
  314. package/dist/serialization/validate.js.map +1 -1
  315. package/dist/server/app.js +1 -1
  316. package/dist/server/app.js.map +1 -1
  317. package/dist/server/http.d.ts +4 -3
  318. package/dist/server/http.d.ts.map +1 -1
  319. package/dist/server/http.js +90 -50
  320. package/dist/server/http.js.map +1 -1
  321. package/dist/server/idempotency.d.ts +0 -6
  322. package/dist/server/idempotency.d.ts.map +1 -1
  323. package/dist/server/idempotency.js.map +1 -1
  324. package/dist/server/router.d.ts.map +1 -1
  325. package/dist/server/router.js +21 -4
  326. package/dist/server/router.js.map +1 -1
  327. package/dist/server/routes/agent-capability-gate.d.ts +40 -0
  328. package/dist/server/routes/agent-capability-gate.d.ts.map +1 -0
  329. package/dist/server/routes/agent-capability-gate.js +182 -0
  330. package/dist/server/routes/agent-capability-gate.js.map +1 -0
  331. package/dist/server/routes/agent-events.d.ts.map +1 -1
  332. package/dist/server/routes/agent-events.js +8 -1
  333. package/dist/server/routes/agent-events.js.map +1 -1
  334. package/dist/server/routes/agent-intake.d.ts.map +1 -1
  335. package/dist/server/routes/agent-intake.js +10 -2
  336. package/dist/server/routes/agent-intake.js.map +1 -1
  337. package/dist/server/routes/agent-promotions.d.ts.map +1 -1
  338. package/dist/server/routes/agent-promotions.js +5 -2
  339. package/dist/server/routes/agent-promotions.js.map +1 -1
  340. package/dist/server/routes/agent-runs.d.ts.map +1 -1
  341. package/dist/server/routes/agent-runs.js +18 -4
  342. package/dist/server/routes/agent-runs.js.map +1 -1
  343. package/dist/server/routes/request-binding.d.ts +5 -0
  344. package/dist/server/routes/request-binding.d.ts.map +1 -0
  345. package/dist/server/routes/request-binding.js +49 -0
  346. package/dist/server/routes/request-binding.js.map +1 -0
  347. package/dist/server/routes/task5-support.d.ts +1 -8
  348. package/dist/server/routes/task5-support.d.ts.map +1 -1
  349. package/dist/server/routes/task5-support.js +1 -17
  350. package/dist/server/routes/task5-support.js.map +1 -1
  351. package/dist/server/routes/task5.d.ts.map +1 -1
  352. package/dist/server/routes/task5.js +106 -36
  353. package/dist/server/routes/task5.js.map +1 -1
  354. package/dist/server/write-queue.js +2 -2
  355. package/dist/server/write-queue.js.map +1 -1
  356. package/dist/setup/claude-config.d.ts +2 -1
  357. package/dist/setup/claude-config.d.ts.map +1 -1
  358. package/dist/setup/claude-config.js +54 -4
  359. package/dist/setup/claude-config.js.map +1 -1
  360. package/dist/setup/client-detection.d.ts +7 -2
  361. package/dist/setup/client-detection.d.ts.map +1 -1
  362. package/dist/setup/client-detection.js +27 -9
  363. package/dist/setup/client-detection.js.map +1 -1
  364. package/dist/setup/hermes-config.d.ts +2 -1
  365. package/dist/setup/hermes-config.d.ts.map +1 -1
  366. package/dist/setup/hermes-config.js +53 -12
  367. package/dist/setup/hermes-config.js.map +1 -1
  368. package/dist/setup/legacy-client-cleanup.d.ts +6 -0
  369. package/dist/setup/legacy-client-cleanup.d.ts.map +1 -0
  370. package/dist/setup/legacy-client-cleanup.js +152 -0
  371. package/dist/setup/legacy-client-cleanup.js.map +1 -0
  372. package/dist/setup/managed-text.d.ts.map +1 -1
  373. package/dist/setup/managed-text.js +11 -1
  374. package/dist/setup/managed-text.js.map +1 -1
  375. package/dist/setup/opencode-config.d.ts +2 -1
  376. package/dist/setup/opencode-config.d.ts.map +1 -1
  377. package/dist/setup/opencode-config.js +57 -5
  378. package/dist/setup/opencode-config.js.map +1 -1
  379. package/dist/setup/render.d.ts +2 -1
  380. package/dist/setup/render.d.ts.map +1 -1
  381. package/dist/setup/render.js +91 -17
  382. package/dist/setup/render.js.map +1 -1
  383. package/dist/setup/standard-skills.d.ts +16 -2
  384. package/dist/setup/standard-skills.d.ts.map +1 -1
  385. package/dist/setup/standard-skills.js +37 -13
  386. package/dist/setup/standard-skills.js.map +1 -1
  387. package/dist/setup/strict-json.d.ts +7 -0
  388. package/dist/setup/strict-json.d.ts.map +1 -0
  389. package/dist/setup/strict-json.js +98 -0
  390. package/dist/setup/strict-json.js.map +1 -0
  391. package/dist/setup/strict-toml.d.ts +7 -0
  392. package/dist/setup/strict-toml.d.ts.map +1 -0
  393. package/dist/setup/strict-toml.js +470 -0
  394. package/dist/setup/strict-toml.js.map +1 -0
  395. package/dist/skills/cache.d.ts +15 -0
  396. package/dist/skills/cache.d.ts.map +1 -0
  397. package/dist/skills/cache.js +19 -0
  398. package/dist/skills/cache.js.map +1 -0
  399. package/dist/skills/candidate-ranking.d.ts +15 -0
  400. package/dist/skills/candidate-ranking.d.ts.map +1 -0
  401. package/dist/skills/candidate-ranking.js +52 -0
  402. package/dist/skills/candidate-ranking.js.map +1 -0
  403. package/dist/skills/chunking.d.ts +11 -0
  404. package/dist/skills/chunking.d.ts.map +1 -0
  405. package/dist/skills/chunking.js +291 -0
  406. package/dist/skills/chunking.js.map +1 -0
  407. package/dist/skills/config.d.ts +19 -0
  408. package/dist/skills/config.d.ts.map +1 -0
  409. package/dist/skills/config.js +103 -0
  410. package/dist/skills/config.js.map +1 -0
  411. package/dist/skills/discovery-service.d.ts +26 -0
  412. package/dist/skills/discovery-service.d.ts.map +1 -0
  413. package/dist/skills/discovery-service.js +921 -0
  414. package/dist/skills/discovery-service.js.map +1 -0
  415. package/dist/skills/external-transport.d.ts +2 -0
  416. package/dist/skills/external-transport.d.ts.map +1 -0
  417. package/dist/skills/external-transport.js +30 -0
  418. package/dist/skills/external-transport.js.map +1 -0
  419. package/dist/skills/find.d.ts +16 -0
  420. package/dist/skills/find.d.ts.map +1 -0
  421. package/dist/skills/find.js +58 -0
  422. package/dist/skills/find.js.map +1 -0
  423. package/dist/skills/gap-detection.d.ts +23 -0
  424. package/dist/skills/gap-detection.d.ts.map +1 -0
  425. package/dist/skills/gap-detection.js +62 -0
  426. package/dist/skills/gap-detection.js.map +1 -0
  427. package/dist/skills/import-preparation.d.ts +4 -0
  428. package/dist/skills/import-preparation.d.ts.map +1 -0
  429. package/dist/skills/import-preparation.js +20 -0
  430. package/dist/skills/import-preparation.js.map +1 -0
  431. package/dist/skills/materialization-authority.d.ts +11 -0
  432. package/dist/skills/materialization-authority.d.ts.map +1 -0
  433. package/dist/skills/materialization-authority.js +92 -0
  434. package/dist/skills/materialization-authority.js.map +1 -0
  435. package/dist/skills/materialization-service.d.ts +22 -0
  436. package/dist/skills/materialization-service.d.ts.map +1 -0
  437. package/dist/skills/materialization-service.js +101 -0
  438. package/dist/skills/materialization-service.js.map +1 -0
  439. package/dist/skills/official-catalog.d.ts +31 -0
  440. package/dist/skills/official-catalog.d.ts.map +1 -0
  441. package/dist/skills/official-catalog.js +110 -0
  442. package/dist/skills/official-catalog.js.map +1 -0
  443. package/dist/skills/providers/schema.d.ts +30 -0
  444. package/dist/skills/providers/schema.d.ts.map +1 -0
  445. package/dist/skills/providers/schema.js +354 -0
  446. package/dist/skills/providers/schema.js.map +1 -0
  447. package/dist/skills/providers/skills-sh-compat.d.ts +17 -0
  448. package/dist/skills/providers/skills-sh-compat.d.ts.map +1 -0
  449. package/dist/skills/providers/skills-sh-compat.js +71 -0
  450. package/dist/skills/providers/skills-sh-compat.js.map +1 -0
  451. package/dist/skills/providers/skills-sh-v1.d.ts +23 -0
  452. package/dist/skills/providers/skills-sh-v1.d.ts.map +1 -0
  453. package/dist/skills/providers/skills-sh-v1.js +134 -0
  454. package/dist/skills/providers/skills-sh-v1.js.map +1 -0
  455. package/dist/skills/query-builder.d.ts +18 -0
  456. package/dist/skills/query-builder.d.ts.map +1 -0
  457. package/dist/skills/query-builder.js +93 -0
  458. package/dist/skills/query-builder.js.map +1 -0
  459. package/dist/skills/source/errors.d.ts +9 -0
  460. package/dist/skills/source/errors.d.ts.map +1 -0
  461. package/dist/skills/source/errors.js +15 -0
  462. package/dist/skills/source/errors.js.map +1 -0
  463. package/dist/skills/source/frontmatter.d.ts +9 -0
  464. package/dist/skills/source/frontmatter.d.ts.map +1 -0
  465. package/dist/skills/source/frontmatter.js +77 -0
  466. package/dist/skills/source/frontmatter.js.map +1 -0
  467. package/dist/skills/source/github-fetcher.d.ts +20 -0
  468. package/dist/skills/source/github-fetcher.d.ts.map +1 -0
  469. package/dist/skills/source/github-fetcher.js +292 -0
  470. package/dist/skills/source/github-fetcher.js.map +1 -0
  471. package/dist/skills/source/snapshot-validator.d.ts +28 -0
  472. package/dist/skills/source/snapshot-validator.d.ts.map +1 -0
  473. package/dist/skills/source/snapshot-validator.js +186 -0
  474. package/dist/skills/source/snapshot-validator.js.map +1 -0
  475. package/dist/skills/store.d.ts +181 -0
  476. package/dist/skills/store.d.ts.map +1 -0
  477. package/dist/skills/store.js +1710 -0
  478. package/dist/skills/store.js.map +1 -0
  479. package/dist/skills/types.d.ts +169 -0
  480. package/dist/skills/types.d.ts.map +1 -0
  481. package/dist/skills/types.js +2 -0
  482. package/dist/skills/types.js.map +1 -0
  483. package/dist/web/i18n.d.ts +56 -8
  484. package/dist/web/i18n.d.ts.map +1 -1
  485. package/dist/web/i18n.js +224 -32
  486. package/dist/web/i18n.js.map +1 -1
  487. package/dist/web/server.d.ts.map +1 -1
  488. package/dist/web/server.js +458 -42
  489. package/dist/web/server.js.map +1 -1
  490. package/dist/web/ui.d.ts +4 -0
  491. package/dist/web/ui.d.ts.map +1 -1
  492. package/dist/web/ui.js +697 -61
  493. package/dist/web/ui.js.map +1 -1
  494. package/migrations/008_federated_memory.sql +46 -0
  495. package/migrations/009_external_skill_discovery.sql +126 -0
  496. package/package.json +6 -3
  497. package/skills/kiokuko-single-purpose-functions/SKILL.md +288 -0
  498. package/skills/kiokuko-single-purpose-functions/references/kiokuko-patterns.md +344 -0
  499. package/skills/kiokuko-single-purpose-functions/references/review-checklist.md +97 -0
  500. package/skills/kiokuko-ui-design-soul/SKILL.md +1186 -28
  501. package/templates/AGENTS.md +8 -7
  502. package/dist/client/runtime-discovery.d.ts +0 -15
  503. package/dist/client/runtime-discovery.d.ts.map +0 -1
  504. package/dist/client/runtime-discovery.js +0 -45
  505. package/dist/client/runtime-discovery.js.map +0 -1
  506. package/dist/commands/call.d.ts +0 -7
  507. package/dist/commands/call.d.ts.map +0 -1
  508. package/dist/commands/call.js +0 -10
  509. package/dist/commands/call.js.map +0 -1
  510. package/dist/commands/link.d.ts +0 -6
  511. package/dist/commands/link.d.ts.map +0 -1
  512. package/dist/commands/link.js +0 -6
  513. package/dist/commands/link.js.map +0 -1
  514. package/dist/commands/promote.d.ts +0 -6
  515. package/dist/commands/promote.d.ts.map +0 -1
  516. package/dist/commands/promote.js +0 -6
  517. package/dist/commands/promote.js.map +0 -1
  518. package/dist/commands/read.d.ts +0 -6
  519. package/dist/commands/read.d.ts.map +0 -1
  520. package/dist/commands/read.js +0 -4
  521. package/dist/commands/read.js.map +0 -1
  522. package/dist/commands/recall.d.ts +0 -6
  523. package/dist/commands/recall.d.ts.map +0 -1
  524. package/dist/commands/recall.js +0 -4
  525. package/dist/commands/recall.js.map +0 -1
  526. package/dist/commands/record.d.ts +0 -6
  527. package/dist/commands/record.d.ts.map +0 -1
  528. package/dist/commands/record.js +0 -4
  529. package/dist/commands/record.js.map +0 -1
  530. package/dist/commands/search.d.ts +0 -6
  531. package/dist/commands/search.d.ts.map +0 -1
  532. package/dist/commands/search.js +0 -4
  533. package/dist/commands/search.js.map +0 -1
  534. package/dist/commands/supersede.d.ts +0 -6
  535. package/dist/commands/supersede.d.ts.map +0 -1
  536. package/dist/commands/supersede.js +0 -6
  537. package/dist/commands/supersede.js.map +0 -1
  538. package/dist/knowledge/sources.d.ts +0 -72
  539. package/dist/knowledge/sources.d.ts.map +0 -1
  540. package/dist/knowledge/sources.js +0 -388
  541. package/dist/knowledge/sources.js.map +0 -1
  542. package/dist/setup/opencode-evidence.d.ts +0 -37
  543. package/dist/setup/opencode-evidence.d.ts.map +0 -1
  544. package/dist/setup/opencode-evidence.js +0 -58
  545. package/dist/setup/opencode-evidence.js.map +0 -1
  546. package/dist/setup/opencode-loop-guard.d.ts +0 -9
  547. package/dist/setup/opencode-loop-guard.d.ts.map +0 -1
  548. package/dist/setup/opencode-loop-guard.js +0 -248
  549. package/dist/setup/opencode-loop-guard.js.map +0 -1
@@ -1,12 +1,39 @@
1
1
  import { createHash } from 'node:crypto';
2
+ import { isProxy } from 'node:util/types';
2
3
  import { withImmediateTransaction } from '../db/transaction.js';
3
4
  import { KiokukoError } from '../errors.js';
4
5
  import { sanitizeJson } from '../security/sanitize.js';
5
6
  import { canonicalContentHash } from '../serialization/validate.js';
7
+ import { entryOriginMatchesWorkspace, isContextEntryOrigin } from './origin.js';
6
8
  export const MAX_FEEDBACK_COMMENT_BYTES = 4 * 1024;
9
+ export const MAX_FEEDBACK_OUTCOME_BYTES = 4 * 1024;
7
10
  export const MAX_FEEDBACK_IDENTIFIER_LENGTH = 256;
8
11
  export const CONTEXT_FEEDBACK_VERDICTS = ['helpful', 'irrelevant', 'stale', 'conflicting'];
9
12
  export const RUN_FEEDBACK_RECOMMENDATION_VERDICTS = ['accepted', 'dismissed', 'resolved'];
13
+ /** Shared cross-run feedback evidence for retrieval policy consumers. */
14
+ export function contextFeedbackSignals(database, entryId) {
15
+ const rows = database.prepare(`
16
+ SELECT verdict, COUNT(DISTINCT run_id) AS distinctRuns
17
+ FROM context_feedback
18
+ WHERE entry_id = ?
19
+ GROUP BY verdict
20
+ `).all(entryId);
21
+ const byVerdict = new Map();
22
+ for (const row of rows) {
23
+ if (typeof row.verdict !== 'string'
24
+ || !CONTEXT_FEEDBACK_VERDICTS.includes(row.verdict)
25
+ || typeof row.distinctRuns !== 'number'
26
+ || !Number.isSafeInteger(row.distinctRuns)
27
+ || row.distinctRuns < 1) {
28
+ throw new KiokukoError('INTEGRITY_ERROR', 'Stored context feedback aggregate is invalid');
29
+ }
30
+ byVerdict.set(row.verdict, row.distinctRuns);
31
+ }
32
+ return CONTEXT_FEEDBACK_VERDICTS.flatMap((verdict) => {
33
+ const distinctRuns = byVerdict.get(verdict);
34
+ return distinctRuns === undefined ? [] : [{ verdict, distinctRuns, boundedInfluence: Math.min(2, distinctRuns) }];
35
+ });
36
+ }
10
37
  const CONTEXT_INPUT_FIELDS = new Set([
11
38
  'workspace', 'feedbackId', 'deliveryId', 'entryId', 'entryRevision', 'runId', 'verdict',
12
39
  'comment', 'actor', 'idempotencyKey', 'createdAt',
@@ -41,20 +68,75 @@ function databaseFailure() {
41
68
  return fail('DATABASE_ERROR', DATABASE_MESSAGE);
42
69
  }
43
70
  function isPlainObject(value) {
44
- if (typeof value !== 'object' || value === null || Array.isArray(value))
71
+ if (typeof value !== 'object' || value === null || Array.isArray(value) || isProxy(value))
45
72
  return false;
46
73
  const prototype = Object.getPrototypeOf(value);
47
74
  return prototype === Object.prototype || prototype === null;
48
75
  }
76
+ function inputFields(value, allowed, exact = false) {
77
+ if (!isPlainObject(value))
78
+ validation();
79
+ const keys = Reflect.ownKeys(value);
80
+ if (exact && keys.length !== allowed.size)
81
+ validation();
82
+ const descriptors = Object.getOwnPropertyDescriptors(value);
83
+ const result = Object.create(null);
84
+ for (const key of keys) {
85
+ if (typeof key !== 'string' || !allowed.has(key))
86
+ validation();
87
+ const descriptor = descriptors[key];
88
+ if (!descriptor || !('value' in descriptor) || descriptor.enumerable !== true)
89
+ validation();
90
+ result[key] = descriptor.value;
91
+ }
92
+ return result;
93
+ }
49
94
  function isKiokukoError(error) {
50
95
  return error instanceof KiokukoError;
51
96
  }
52
- function normalizeDatabaseError(error) {
97
+ const SQLITE_CONSTRAINT_PRIMARY_KEY = 1_555;
98
+ const SQLITE_CONSTRAINT_UNIQUE = 2_067;
99
+ const NO_UNIQUENESS_FAILURES = new Set();
100
+ const SQLITE_OPERATIONAL_PRIMARY_CODES = new Set([5, 6, 7, 8, 9, 10, 13, 14, 15, 22, 23]);
101
+ const SQLITE_INTEGRITY_PRIMARY_CODES = new Set([11, 24, 26]);
102
+ const CONTEXT_FEEDBACK_UNIQUENESS_FAILURES = new Set([
103
+ 'UNIQUE constraint failed: context_feedback.feedback_id',
104
+ 'UNIQUE constraint failed: context_feedback.run_id, context_feedback.actor, context_feedback.idempotency_key',
105
+ ]);
106
+ const RUN_FEEDBACK_UNIQUENESS_FAILURES = new Set([
107
+ 'UNIQUE constraint failed: run_feedback.feedback_id',
108
+ 'UNIQUE constraint failed: run_feedback.run_id, run_feedback.actor, run_feedback.idempotency_key',
109
+ ]);
110
+ const INTAKE_FEEDBACK_UNIQUENESS_FAILURES = new Set([
111
+ 'UNIQUE constraint failed: intake_feedback.feedback_id',
112
+ 'UNIQUE constraint failed: intake_feedback.run_id, intake_feedback.actor, intake_feedback.idempotency_key',
113
+ ]);
114
+ function nodeSqliteFailure(error) {
115
+ if (!(error instanceof Error))
116
+ return null;
117
+ const failure = error;
118
+ if (failure.code !== 'ERR_SQLITE_ERROR'
119
+ || typeof failure.errcode !== 'number'
120
+ || !Number.isSafeInteger(failure.errcode)
121
+ || failure.errcode < 0)
122
+ return null;
123
+ return failure;
124
+ }
125
+ function normalizeDatabaseError(error, uniquenessFailures = NO_UNIQUENESS_FAILURES) {
53
126
  if (isKiokukoError(error))
54
127
  throw error;
55
- if (error instanceof Error && /unique|constraint/i.test(error.message))
128
+ const failure = nodeSqliteFailure(error);
129
+ if (failure === null)
130
+ throw error;
131
+ if ((failure.errcode === SQLITE_CONSTRAINT_PRIMARY_KEY || failure.errcode === SQLITE_CONSTRAINT_UNIQUE)
132
+ && uniquenessFailures.has(failure.message))
56
133
  conflict();
57
- databaseFailure();
134
+ const primaryResultCode = failure.errcode & 0xff;
135
+ if (SQLITE_INTEGRITY_PRIMARY_CODES.has(primaryResultCode))
136
+ integrity();
137
+ if (SQLITE_OPERATIONAL_PRIMARY_CODES.has(primaryResultCode))
138
+ databaseFailure();
139
+ throw error;
58
140
  }
59
141
  function requiredString(value) {
60
142
  if (typeof value !== 'string' || value.length === 0 || value.length > MAX_FEEDBACK_IDENTIFIER_LENGTH)
@@ -68,13 +150,23 @@ function optionalText(value, maximum) {
68
150
  validation();
69
151
  return value;
70
152
  }
71
- function normalizeTimestamp(value) {
72
- if (typeof value !== 'string' || value.length === 0)
153
+ function optionalUtf8Text(value, maximumBytes) {
154
+ if (value === undefined || value === null)
155
+ return null;
156
+ if (typeof value !== 'string' || value.length === 0 || Buffer.byteLength(value, 'utf8') > maximumBytes)
73
157
  validation();
74
- const date = new Date(value);
75
- if (Number.isNaN(date.getTime()))
158
+ return value;
159
+ }
160
+ function isCanonicalFeedbackTimestamp(value) {
161
+ if (typeof value !== 'string' || !/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(value))
162
+ return false;
163
+ const parsed = Date.parse(value);
164
+ return Number.isFinite(parsed) && new Date(parsed).toISOString() === value;
165
+ }
166
+ export function validateFeedbackTimestamp(value) {
167
+ if (!isCanonicalFeedbackTimestamp(value))
76
168
  validation();
77
- return date.toISOString();
169
+ return value;
78
170
  }
79
171
  function normalizeComment(value, workspace) {
80
172
  if (value === undefined || value === null)
@@ -83,13 +175,7 @@ function normalizeComment(value, workspace) {
83
175
  validation();
84
176
  if (value.trim().length === 0)
85
177
  return null;
86
- let sanitized;
87
- try {
88
- sanitized = sanitizeJson(value, { workspace }).value;
89
- }
90
- catch {
91
- validation();
92
- }
178
+ const sanitized = sanitizeJson(value, { workspace }).value;
93
179
  if (typeof sanitized !== 'string')
94
180
  validation();
95
181
  if (sanitized.trim().length === 0)
@@ -129,168 +215,127 @@ function runBodyHash(input) {
129
215
  });
130
216
  }
131
217
  function validateContextFeedbackInput(value) {
132
- try {
133
- if (!isPlainObject(value))
134
- validation();
135
- for (const field of Object.keys(value)) {
136
- if (!CONTEXT_INPUT_FIELDS.has(field))
137
- validation();
138
- }
139
- const workspace = requiredString(value.workspace);
140
- const feedbackId = requiredString(value.feedbackId);
141
- const deliveryId = requiredString(value.deliveryId);
142
- const entryId = requiredString(value.entryId);
143
- const entryRevision = value.entryRevision === undefined
144
- ? undefined
145
- : typeof value.entryRevision === 'number' && Number.isSafeInteger(value.entryRevision) && value.entryRevision > 0
146
- ? value.entryRevision
147
- : validation();
148
- const runId = requiredString(value.runId);
149
- if (typeof value.verdict !== 'string' || !CONTEXT_FEEDBACK_VERDICTS.includes(value.verdict))
150
- validation();
151
- const verdict = value.verdict;
152
- const actor = requiredString(value.actor);
153
- const idempotencyKey = requiredString(value.idempotencyKey);
154
- const createdAt = normalizeTimestamp(value.createdAt);
155
- const comment = normalizeComment(value.comment, workspace);
156
- return {
157
- feedbackId,
158
- workspace,
159
- deliveryId,
160
- entryId,
161
- ...(entryRevision === undefined ? {} : { entryRevision }),
162
- runId,
163
- verdict,
164
- comment,
165
- actor,
166
- idempotencyKeyHash: hashIdempotencyKey(idempotencyKey),
167
- createdAt,
168
- };
169
- }
170
- catch (error) {
171
- if (isKiokukoError(error) && error.code === 'VALIDATION_ERROR')
172
- validation();
218
+ const fields = inputFields(value, CONTEXT_INPUT_FIELDS);
219
+ const workspace = requiredString(fields.workspace);
220
+ const feedbackId = requiredString(fields.feedbackId);
221
+ const deliveryId = requiredString(fields.deliveryId);
222
+ const entryId = requiredString(fields.entryId);
223
+ const entryRevision = fields.entryRevision === undefined
224
+ ? undefined
225
+ : typeof fields.entryRevision === 'number' && Number.isSafeInteger(fields.entryRevision) && fields.entryRevision > 0
226
+ ? fields.entryRevision
227
+ : validation();
228
+ const runId = requiredString(fields.runId);
229
+ if (typeof fields.verdict !== 'string' || !CONTEXT_FEEDBACK_VERDICTS.includes(fields.verdict))
173
230
  validation();
174
- }
231
+ const verdict = fields.verdict;
232
+ const actor = requiredString(fields.actor);
233
+ const idempotencyKey = requiredString(fields.idempotencyKey);
234
+ const createdAt = validateFeedbackTimestamp(fields.createdAt);
235
+ const comment = normalizeComment(fields.comment, workspace);
236
+ return {
237
+ feedbackId,
238
+ workspace,
239
+ deliveryId,
240
+ entryId,
241
+ ...(entryRevision === undefined ? {} : { entryRevision }),
242
+ runId,
243
+ verdict,
244
+ comment,
245
+ actor,
246
+ idempotencyKeyHash: hashIdempotencyKey(idempotencyKey),
247
+ createdAt,
248
+ };
175
249
  }
176
250
  function validateContextFeedbackListInput(value) {
177
- try {
178
- if (!isPlainObject(value))
179
- validation();
180
- for (const field of Object.keys(value)) {
181
- if (!CONTEXT_LIST_FIELDS.has(field))
182
- validation();
183
- }
184
- const workspace = requiredString(value.workspace);
185
- const runId = value.runId === undefined ? undefined : requiredString(value.runId);
186
- const deliveryId = value.deliveryId === undefined ? undefined : requiredString(value.deliveryId);
187
- const entryId = value.entryId === undefined ? undefined : requiredString(value.entryId);
188
- const limit = value.limit === undefined ? 100 : value.limit;
189
- if (typeof limit !== 'number' || !Number.isInteger(limit) || limit < 1 || limit > 100)
190
- validation();
191
- return {
192
- workspace,
193
- ...(runId === undefined ? {} : { runId }),
194
- ...(deliveryId === undefined ? {} : { deliveryId }),
195
- ...(entryId === undefined ? {} : { entryId }),
196
- limit,
197
- };
198
- }
199
- catch (error) {
200
- if (isKiokukoError(error) && error.code === 'VALIDATION_ERROR')
201
- validation();
251
+ const fields = inputFields(value, CONTEXT_LIST_FIELDS);
252
+ const workspace = requiredString(fields.workspace);
253
+ const runId = fields.runId === undefined ? undefined : requiredString(fields.runId);
254
+ const deliveryId = fields.deliveryId === undefined ? undefined : requiredString(fields.deliveryId);
255
+ const entryId = fields.entryId === undefined ? undefined : requiredString(fields.entryId);
256
+ const limit = fields.limit === undefined ? 100 : fields.limit;
257
+ if (typeof limit !== 'number' || !Number.isInteger(limit) || limit < 1 || limit > 100)
202
258
  validation();
203
- }
259
+ return {
260
+ workspace,
261
+ ...(runId === undefined ? {} : { runId }),
262
+ ...(deliveryId === undefined ? {} : { deliveryId }),
263
+ ...(entryId === undefined ? {} : { entryId }),
264
+ limit,
265
+ };
204
266
  }
205
267
  function validateRunFeedbackListInput(value) {
206
- try {
207
- if (!isPlainObject(value))
208
- validation();
209
- for (const field of Object.keys(value)) {
210
- if (!RUN_LIST_FIELDS.has(field))
211
- validation();
212
- }
213
- const workspace = requiredString(value.workspace);
214
- const runId = value.runId === undefined ? undefined : requiredString(value.runId);
215
- const limit = value.limit === undefined ? 100 : value.limit;
216
- if (typeof limit !== 'number' || !Number.isInteger(limit) || limit < 1 || limit > 100)
217
- validation();
218
- return { workspace, ...(runId === undefined ? {} : { runId }), limit };
219
- }
220
- catch (error) {
221
- if (isKiokukoError(error) && error.code === 'VALIDATION_ERROR')
222
- validation();
268
+ const fields = inputFields(value, RUN_LIST_FIELDS);
269
+ const workspace = requiredString(fields.workspace);
270
+ const runId = fields.runId === undefined ? undefined : requiredString(fields.runId);
271
+ const limit = fields.limit === undefined ? 100 : fields.limit;
272
+ if (typeof limit !== 'number' || !Number.isInteger(limit) || limit < 1 || limit > 100)
223
273
  validation();
224
- }
274
+ return { workspace, ...(runId === undefined ? {} : { runId }), limit };
225
275
  }
226
276
  function validateRunFeedbackInput(value) {
227
- try {
228
- if (!isPlainObject(value))
229
- validation();
230
- for (const field of Object.keys(value)) {
231
- if (!RUN_INPUT_FIELDS.has(field))
232
- validation();
233
- }
234
- const workspace = requiredString(value.workspace);
235
- const feedbackId = requiredString(value.feedbackId);
236
- const runId = requiredString(value.runId);
237
- const outcome = optionalText(value.outcome, MAX_FEEDBACK_COMMENT_BYTES);
238
- const recommendationCode = optionalText(value.recommendationCode, MAX_FEEDBACK_IDENTIFIER_LENGTH);
239
- const rawRecommendationVerdict = value.recommendationVerdict;
240
- const recommendationVerdict = rawRecommendationVerdict === undefined || rawRecommendationVerdict === null
241
- ? null
242
- : typeof rawRecommendationVerdict === 'string' && RUN_FEEDBACK_RECOMMENDATION_VERDICTS.includes(rawRecommendationVerdict)
243
- ? rawRecommendationVerdict
244
- : validation();
245
- if ((recommendationCode === null) !== (recommendationVerdict === null))
246
- validation();
247
- const rawRating = value.rating;
248
- const rating = rawRating === undefined || rawRating === null
249
- ? null
250
- : typeof rawRating === 'number' && Number.isInteger(rawRating) && rawRating >= 1 && rawRating <= 5
251
- ? rawRating
252
- : validation();
253
- if (outcome === null && recommendationCode === null && rating === null)
254
- validation();
255
- const actor = requiredString(value.actor);
256
- const idempotencyKey = requiredString(value.idempotencyKey);
257
- const createdAt = normalizeTimestamp(value.createdAt);
258
- const comment = normalizeComment(value.comment, workspace);
259
- return {
260
- feedbackId,
261
- workspace,
262
- runId,
263
- outcome,
264
- recommendationCode,
265
- recommendationVerdict,
266
- rating,
267
- comment,
268
- actor,
269
- idempotencyKeyHash: hashIdempotencyKey(idempotencyKey),
270
- createdAt,
271
- };
272
- }
273
- catch (error) {
274
- if (isKiokukoError(error) && error.code === 'VALIDATION_ERROR')
275
- validation();
277
+ const fields = inputFields(value, RUN_INPUT_FIELDS);
278
+ const workspace = requiredString(fields.workspace);
279
+ const feedbackId = requiredString(fields.feedbackId);
280
+ const runId = requiredString(fields.runId);
281
+ const outcome = optionalUtf8Text(fields.outcome, MAX_FEEDBACK_OUTCOME_BYTES);
282
+ const recommendationCode = optionalText(fields.recommendationCode, MAX_FEEDBACK_IDENTIFIER_LENGTH);
283
+ const rawRecommendationVerdict = fields.recommendationVerdict;
284
+ const recommendationVerdict = rawRecommendationVerdict === undefined || rawRecommendationVerdict === null
285
+ ? null
286
+ : typeof rawRecommendationVerdict === 'string' && RUN_FEEDBACK_RECOMMENDATION_VERDICTS.includes(rawRecommendationVerdict)
287
+ ? rawRecommendationVerdict
288
+ : validation();
289
+ if ((recommendationCode === null) !== (recommendationVerdict === null))
276
290
  validation();
277
- }
291
+ const rawRating = fields.rating;
292
+ const rating = rawRating === undefined || rawRating === null
293
+ ? null
294
+ : typeof rawRating === 'number' && Number.isInteger(rawRating) && rawRating >= 1 && rawRating <= 5
295
+ ? rawRating
296
+ : validation();
297
+ if (outcome === null && recommendationCode === null && rating === null)
298
+ validation();
299
+ const actor = requiredString(fields.actor);
300
+ const idempotencyKey = requiredString(fields.idempotencyKey);
301
+ const createdAt = validateFeedbackTimestamp(fields.createdAt);
302
+ const comment = normalizeComment(fields.comment, workspace);
303
+ return {
304
+ feedbackId,
305
+ workspace,
306
+ runId,
307
+ outcome,
308
+ recommendationCode,
309
+ recommendationVerdict,
310
+ rating,
311
+ comment,
312
+ actor,
313
+ idempotencyKeyHash: hashIdempotencyKey(idempotencyKey),
314
+ createdAt,
315
+ };
278
316
  }
279
317
  function assertContextTarget(database, input) {
280
318
  const target = database.prepare(`
281
- SELECT cde.entry_revision AS entry_revision
319
+ SELECT cde.entry_revision AS entry_revision, cde.origin_scope AS origin_scope,
320
+ e.workspace AS entry_workspace, er.workspace AS revision_workspace
282
321
  FROM context_deliveries AS cd
283
322
  JOIN ledger_runs AS lr ON lr.run_id = cd.run_id
284
323
  JOIN context_delivery_entries AS cde
285
324
  ON cde.delivery_id = cd.delivery_id AND cde.entry_id = ?
286
325
  JOIN entries AS e ON e.id = cde.entry_id
326
+ JOIN entry_revisions AS er
327
+ ON er.entry_id = cde.entry_id AND er.revision = cde.entry_revision
287
328
  WHERE cd.delivery_id = ?
288
329
  AND cd.run_id = ?
289
330
  AND lr.workspace = ?
290
- AND ((cde.origin_scope = 'global' AND e.workspace = 'global') OR (cde.origin_scope = 'project' AND e.workspace = ?))
291
- `).get(input.entryId, input.deliveryId, input.runId, input.workspace, input.workspace);
331
+ `).get(input.entryId, input.deliveryId, input.runId, input.workspace);
292
332
  if (!target)
293
333
  notFound();
334
+ if (!isContextEntryOrigin(target.origin_scope)
335
+ || typeof target.entry_workspace !== 'string'
336
+ || target.revision_workspace !== target.entry_workspace
337
+ || !entryOriginMatchesWorkspace({ origin: target.origin_scope, runWorkspace: input.workspace, entryWorkspace: target.entry_workspace }))
338
+ notFound();
294
339
  if (input.entryRevision !== undefined && target.entry_revision !== input.entryRevision)
295
340
  conflict();
296
341
  }
@@ -306,6 +351,7 @@ function selectContextByKey(database, input) {
306
351
  cde.entry_id AS linked_entry_id,
307
352
  cde.entry_revision AS entry_revision,
308
353
  e.workspace AS entry_workspace,
354
+ er.workspace AS revision_workspace,
309
355
  cde.origin_scope AS origin_scope
310
356
  FROM context_feedback AS cf
311
357
  LEFT JOIN ledger_runs AS lr ON lr.run_id = cf.run_id
@@ -313,6 +359,8 @@ function selectContextByKey(database, input) {
313
359
  LEFT JOIN context_delivery_entries AS cde
314
360
  ON cde.delivery_id = cf.delivery_id AND cde.entry_id = cf.entry_id
315
361
  LEFT JOIN entries AS e ON e.id = cf.entry_id
362
+ LEFT JOIN entry_revisions AS er
363
+ ON er.entry_id = cde.entry_id AND er.revision = cde.entry_revision
316
364
  WHERE cf.run_id = ? AND cf.actor = ? AND cf.idempotency_key = ?
317
365
  `).get(input.runId, input.actor, input.idempotencyKeyHash);
318
366
  }
@@ -330,13 +378,7 @@ function storedHash(value) {
330
378
  return value;
331
379
  }
332
380
  function storedTimestamp(value) {
333
- if (typeof value !== 'string')
334
- integrity();
335
- const date = new Date(value);
336
- if (Number.isNaN(date.getTime()))
337
- integrity();
338
- const normalized = date.toISOString();
339
- if (normalized !== value)
381
+ if (!isCanonicalFeedbackTimestamp(value))
340
382
  integrity();
341
383
  return value;
342
384
  }
@@ -357,10 +399,10 @@ function rowToContextFeedback(row, workspace) {
357
399
  integrity();
358
400
  if (storedString(row.linked_entry_id) !== entryId)
359
401
  integrity();
360
- const origin = row.origin_scope === 'global' ? 'global' : row.origin_scope === 'project' ? 'project' : integrity();
361
- if (origin === 'project' && storedString(row.entry_workspace) !== workspace)
362
- integrity();
363
- if (origin === 'global' && storedString(row.entry_workspace) !== 'global')
402
+ const origin = isContextEntryOrigin(row.origin_scope) ? row.origin_scope : integrity();
403
+ const entryWorkspace = storedString(row.entry_workspace);
404
+ if (storedString(row.revision_workspace) !== entryWorkspace
405
+ || !entryOriginMatchesWorkspace({ origin, runWorkspace: workspace, entryWorkspace }))
364
406
  integrity();
365
407
  if (typeof row.verdict !== 'string' || !CONTEXT_FEEDBACK_VERDICTS.includes(row.verdict))
366
408
  integrity();
@@ -372,13 +414,7 @@ function rowToContextFeedback(row, workspace) {
372
414
  else if (typeof row.comment === 'string') {
373
415
  if (row.comment.length === 0 || Buffer.byteLength(row.comment, 'utf8') > MAX_FEEDBACK_COMMENT_BYTES)
374
416
  integrity();
375
- let sanitized;
376
- try {
377
- sanitized = normalizeComment(row.comment, workspace);
378
- }
379
- catch {
380
- integrity();
381
- }
417
+ const sanitized = normalizeComment(row.comment, workspace);
382
418
  if (sanitized !== row.comment)
383
419
  integrity();
384
420
  comment = row.comment;
@@ -399,7 +435,7 @@ function rowToContextFeedback(row, workspace) {
399
435
  createdAt: storedTimestamp(row.created_at),
400
436
  };
401
437
  }
402
- function writeContextFeedback(database, input) {
438
+ function preflightContextFeedbackWrite(database, input) {
403
439
  assertContextTarget(database, input);
404
440
  const existingByKey = selectContextByKey(database, input);
405
441
  if (existingByKey) {
@@ -410,6 +446,22 @@ function writeContextFeedback(database, input) {
410
446
  }
411
447
  if (hasContextFeedbackId(database, input.feedbackId))
412
448
  conflict();
449
+ return undefined;
450
+ }
451
+ /** Validate a context-feedback write and its exact persisted target without mutating state. */
452
+ export function assertContextFeedbackRecordable(database, input) {
453
+ const validated = validateContextFeedbackInput(input);
454
+ try {
455
+ preflightContextFeedbackWrite(database, validated);
456
+ }
457
+ catch (error) {
458
+ normalizeDatabaseError(error, CONTEXT_FEEDBACK_UNIQUENESS_FAILURES);
459
+ }
460
+ }
461
+ function writeContextFeedback(database, input) {
462
+ const existing = preflightContextFeedbackWrite(database, input);
463
+ if (existing !== undefined)
464
+ return existing;
413
465
  database.prepare(`
414
466
  INSERT INTO context_feedback (
415
467
  feedback_id, delivery_id, entry_id, run_id, verdict, comment, actor, idempotency_key, created_at
@@ -426,7 +478,7 @@ export function recordContextFeedbackInTransaction(database, input) {
426
478
  return writeContextFeedback(database, validated);
427
479
  }
428
480
  catch (error) {
429
- normalizeDatabaseError(error);
481
+ normalizeDatabaseError(error, CONTEXT_FEEDBACK_UNIQUENESS_FAILURES);
430
482
  }
431
483
  }
432
484
  export function recordContextFeedback(database, input) {
@@ -435,7 +487,7 @@ export function recordContextFeedback(database, input) {
435
487
  return withImmediateTransaction(database, () => writeContextFeedback(database, validated));
436
488
  }
437
489
  catch (error) {
438
- normalizeDatabaseError(error);
490
+ normalizeDatabaseError(error, CONTEXT_FEEDBACK_UNIQUENESS_FAILURES);
439
491
  }
440
492
  }
441
493
  function runOptionalStoredText(value, maximum) {
@@ -445,18 +497,19 @@ function runOptionalStoredText(value, maximum) {
445
497
  integrity();
446
498
  return value;
447
499
  }
500
+ function runOptionalStoredUtf8Text(value, maximumBytes) {
501
+ if (value === null)
502
+ return null;
503
+ if (typeof value !== 'string' || value.length === 0 || Buffer.byteLength(value, 'utf8') > maximumBytes)
504
+ integrity();
505
+ return value;
506
+ }
448
507
  function runStoredComment(value, workspace) {
449
508
  if (value === null)
450
509
  return null;
451
510
  if (typeof value !== 'string' || value.length === 0 || Buffer.byteLength(value, 'utf8') > MAX_FEEDBACK_COMMENT_BYTES)
452
511
  integrity();
453
- let sanitized;
454
- try {
455
- sanitized = normalizeComment(value, workspace);
456
- }
457
- catch {
458
- integrity();
459
- }
512
+ const sanitized = normalizeComment(value, workspace);
460
513
  if (sanitized !== value)
461
514
  integrity();
462
515
  return value;
@@ -489,7 +542,7 @@ function rowToRunFeedback(row, workspace) {
489
542
  const runWorkspace = storedString(row.run_workspace);
490
543
  if (runWorkspace !== workspace)
491
544
  integrity();
492
- const outcome = runOptionalStoredText(row.outcome, MAX_FEEDBACK_COMMENT_BYTES);
545
+ const outcome = runOptionalStoredUtf8Text(row.outcome, MAX_FEEDBACK_OUTCOME_BYTES);
493
546
  const recommendationCode = runOptionalStoredText(row.recommendation_code, MAX_FEEDBACK_IDENTIFIER_LENGTH);
494
547
  let recommendationVerdict;
495
548
  if (row.recommendation_verdict === null) {
@@ -554,7 +607,7 @@ export function recordRunFeedbackInTransaction(database, input) {
554
607
  return writeRunFeedback(database, validated);
555
608
  }
556
609
  catch (error) {
557
- normalizeDatabaseError(error);
610
+ normalizeDatabaseError(error, RUN_FEEDBACK_UNIQUENESS_FAILURES);
558
611
  }
559
612
  }
560
613
  export function recordRunFeedback(database, input) {
@@ -563,7 +616,7 @@ export function recordRunFeedback(database, input) {
563
616
  return withImmediateTransaction(database, () => writeRunFeedback(database, validated));
564
617
  }
565
618
  catch (error) {
566
- normalizeDatabaseError(error);
619
+ normalizeDatabaseError(error, RUN_FEEDBACK_UNIQUENESS_FAILURES);
567
620
  }
568
621
  }
569
622
  export function listRunFeedback(database, input) {
@@ -621,6 +674,7 @@ export function listContextFeedback(database, input) {
621
674
  cde.entry_id AS linked_entry_id,
622
675
  cde.entry_revision AS entry_revision,
623
676
  e.workspace AS entry_workspace,
677
+ er.workspace AS revision_workspace,
624
678
  cde.origin_scope AS origin_scope
625
679
  FROM context_feedback AS cf
626
680
  LEFT JOIN ledger_runs AS lr ON lr.run_id = cf.run_id
@@ -628,6 +682,8 @@ export function listContextFeedback(database, input) {
628
682
  LEFT JOIN context_delivery_entries AS cde
629
683
  ON cde.delivery_id = cf.delivery_id AND cde.entry_id = cf.entry_id
630
684
  LEFT JOIN entries AS e ON e.id = cf.entry_id
685
+ LEFT JOIN entry_revisions AS er
686
+ ON er.entry_id = cde.entry_id AND er.revision = cde.entry_revision
631
687
  WHERE ${conditions.join(' AND ')}
632
688
  ORDER BY cf.created_at ASC, cf.feedback_id ASC
633
689
  LIMIT ?
@@ -645,59 +701,23 @@ const INTAKE_FEEDBACK_FIELDS = new Set([
645
701
  'verdict', 'comment', 'actor', 'idempotencyKey', 'createdAt',
646
702
  ]);
647
703
  const INTAKE_PROFILE_FIELDS = new Set(['taskType', 'target', 'expected', 'constraints']);
648
- function initialInputFields(value) {
649
- try {
650
- if (!isPlainObject(value))
651
- validation();
652
- const keys = Reflect.ownKeys(value);
653
- if (keys.length !== INTAKE_FEEDBACK_FIELDS.size || keys.some((key) => typeof key !== 'string' || !INTAKE_FEEDBACK_FIELDS.has(key)))
654
- validation();
655
- const descriptors = Object.getOwnPropertyDescriptors(value);
656
- const result = {};
657
- for (const field of INTAKE_FEEDBACK_FIELDS) {
658
- const descriptor = descriptors[field];
659
- if (!descriptor || !('value' in descriptor) || descriptor.enumerable !== true)
660
- validation();
661
- result[field] = descriptor.value;
662
- }
663
- structuredClone(value);
664
- return result;
665
- }
666
- catch {
667
- validation();
668
- }
669
- }
670
704
  function initialInputIdentifier(value) {
671
705
  if (typeof value !== 'string' || value.length === 0 || Buffer.byteLength(value, 'utf8') > MAX_FEEDBACK_IDENTIFIER_LENGTH || /\p{Cc}/u.test(value))
672
706
  validation();
673
707
  return value;
674
708
  }
675
- function initialInputTimestamp(value) {
676
- if (typeof value !== 'string' || !/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(value))
677
- validation();
678
- const date = new Date(value);
679
- if (Number.isNaN(date.getTime()) || date.toISOString() !== value)
680
- validation();
681
- return value;
682
- }
683
709
  function initialInputComment(value, workspace) {
684
710
  if (value === null)
685
711
  return null;
686
712
  if (typeof value !== 'string' || value.length === 0)
687
713
  validation();
688
- let sanitized;
689
- try {
690
- sanitized = sanitizeJson(value, { workspace }).value;
691
- }
692
- catch {
693
- validation();
694
- }
714
+ const sanitized = sanitizeJson(value, { workspace }).value;
695
715
  if (typeof sanitized !== 'string' || sanitized.length === 0 || Buffer.byteLength(sanitized, 'utf8') > MAX_FEEDBACK_COMMENT_BYTES)
696
716
  validation();
697
717
  return sanitized;
698
718
  }
699
719
  function validateInitialIntakeFeedbackInput(value) {
700
- const fields = initialInputFields(value);
720
+ const fields = inputFields(value, INTAKE_FEEDBACK_FIELDS, true);
701
721
  const workspace = initialInputIdentifier(fields.workspace);
702
722
  const feedbackId = initialInputIdentifier(fields.feedbackId);
703
723
  const runId = initialInputIdentifier(fields.runId);
@@ -729,7 +749,7 @@ function validateInitialIntakeFeedbackInput(value) {
729
749
  comment: initialInputComment(fields.comment, workspace),
730
750
  actor,
731
751
  idempotencyKeyHash: hashIdempotencyKey(idempotencyKey),
732
- createdAt: initialInputTimestamp(fields.createdAt),
752
+ createdAt: validateFeedbackTimestamp(fields.createdAt),
733
753
  };
734
754
  }
735
755
  function initialIntakeTarget(database, input) {
@@ -813,26 +833,12 @@ function initialStoredHash(value) {
813
833
  integrity();
814
834
  return value;
815
835
  }
816
- function initialStoredTimestamp(value) {
817
- if (typeof value !== 'string' || !/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(value))
818
- integrity();
819
- const date = new Date(value);
820
- if (Number.isNaN(date.getTime()) || date.toISOString() !== value)
821
- integrity();
822
- return value;
823
- }
824
836
  function initialStoredComment(value, workspace) {
825
837
  if (value === null)
826
838
  return null;
827
839
  if (typeof value !== 'string' || value.length === 0 || Buffer.byteLength(value, 'utf8') > MAX_FEEDBACK_COMMENT_BYTES)
828
840
  integrity();
829
- let sanitized;
830
- try {
831
- sanitized = normalizeComment(value, workspace);
832
- }
833
- catch {
834
- integrity();
835
- }
841
+ const sanitized = initialInputComment(value, workspace);
836
842
  if (sanitized !== value)
837
843
  integrity();
838
844
  return value;
@@ -875,7 +881,7 @@ function rowToInitialIntakeFeedback(row, workspace) {
875
881
  comment: initialStoredComment(row.comment, workspace),
876
882
  actor,
877
883
  idempotencyKeyHash: initialStoredHash(row.idempotency_key),
878
- createdAt: initialStoredTimestamp(row.created_at),
884
+ createdAt: storedTimestamp(row.created_at),
879
885
  };
880
886
  }
881
887
  function recordInitialIntakeFeedback(database, input) {
@@ -905,7 +911,7 @@ export function recordIntakeFeedback(database, input) {
905
911
  return withImmediateTransaction(database, () => recordInitialIntakeFeedback(database, validated));
906
912
  }
907
913
  catch (error) {
908
- normalizeDatabaseError(error);
914
+ normalizeDatabaseError(error, INTAKE_FEEDBACK_UNIQUENESS_FAILURES);
909
915
  }
910
916
  }
911
917
  export function recordIntakeFeedbackInTransaction(database, input) {
@@ -914,36 +920,12 @@ export function recordIntakeFeedbackInTransaction(database, input) {
914
920
  return recordInitialIntakeFeedback(database, validated);
915
921
  }
916
922
  catch (error) {
917
- normalizeDatabaseError(error);
923
+ normalizeDatabaseError(error, INTAKE_FEEDBACK_UNIQUENESS_FAILURES);
918
924
  }
919
925
  }
920
926
  const INTAKE_FEEDBACK_LIST_FIELDS = new Set(['workspace', 'runId', 'sessionId', 'questionId', 'profileField', 'limit']);
921
- function initialListInputFields(value) {
922
- try {
923
- if (!isPlainObject(value))
924
- validation();
925
- const keys = Reflect.ownKeys(value);
926
- if (keys.some((key) => typeof key !== 'string' || !INTAKE_FEEDBACK_LIST_FIELDS.has(key)))
927
- validation();
928
- const descriptors = Object.getOwnPropertyDescriptors(value);
929
- const result = {};
930
- for (const key of keys) {
931
- if (typeof key !== 'string')
932
- validation();
933
- const descriptor = descriptors[key];
934
- if (!descriptor || !('value' in descriptor) || descriptor.enumerable !== true)
935
- validation();
936
- result[key] = descriptor.value;
937
- }
938
- structuredClone(value);
939
- return result;
940
- }
941
- catch {
942
- validation();
943
- }
944
- }
945
927
  function validateInitialIntakeFeedbackListInput(value) {
946
- const fields = initialListInputFields(value);
928
+ const fields = inputFields(value, INTAKE_FEEDBACK_LIST_FIELDS);
947
929
  const workspace = initialInputIdentifier(fields.workspace);
948
930
  const runId = fields.runId === undefined ? undefined : initialInputIdentifier(fields.runId);
949
931
  const sessionId = fields.sessionId === undefined ? undefined : initialInputIdentifier(fields.sessionId);