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