@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,18 +1,23 @@
1
1
  import { TextDecoder } from 'node:util';
2
+ import { isProxy } from 'node:util/types';
2
3
  import { getRuntimeDescriptorPath } from '../config/paths.js';
3
4
  import { KiokukoError } from '../errors.js';
5
+ import { cloneBoundaryJson, stringifyBoundaryJson, } from '../serialization/boundary-json.js';
4
6
  import { isPidAlive } from '../server/instance-lock.js';
5
7
  import { readRuntimeDescriptor } from '../server/runtime-descriptor.js';
8
+ import { MAX_STRICT_JSON_DEPTH, parseStrictJson } from '../setup/strict-json.js';
6
9
  const MAX_JSON_BYTES = 2 * 1024 * 1024;
7
10
  const MAX_PATH_BYTES = 16 * 1024;
8
11
  const MAX_QUERY_BYTES = 8 * 1024;
9
12
  const MAX_IDEMPOTENCY_KEY_BYTES = 256;
10
13
  const MAX_OPERATION_BYTES = 256;
11
- const MAX_ERROR_MESSAGE_BYTES = 1024;
14
+ const MAX_JSON_NODES = 262_144;
15
+ const MAX_RESPONSE_CHUNKS = 8_192;
16
+ const RESPONSE_CLEANUP_TIMEOUT_MS = 250;
12
17
  const HEALTH_READY_PATH = '/health/ready';
13
18
  const WRITE_METHODS = new Set(['POST', 'PUT', 'PATCH', 'DELETE']);
14
- const READ_METHODS = new Set(['GET', 'HEAD']);
15
- const SERVER_METHODS = new Set(['GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE']);
19
+ const READ_METHODS = new Set(['GET']);
20
+ const SERVER_METHODS = new Set(['GET', 'POST', 'PUT', 'PATCH', 'DELETE']);
16
21
  const ERROR_CODES = [
17
22
  'USAGE_ERROR',
18
23
  'VALIDATION_ERROR',
@@ -27,6 +32,20 @@ const ERROR_CODES = [
27
32
  'PARTIAL_FAILURE',
28
33
  'NOT_IMPLEMENTED',
29
34
  ];
35
+ const ERROR_STATUS = {
36
+ USAGE_ERROR: [400],
37
+ VALIDATION_ERROR: [400],
38
+ NOT_FOUND: [404],
39
+ CONFLICT: [409],
40
+ DATABASE_ERROR: [500, 503],
41
+ BACKPRESSURE: [429],
42
+ SERVICE_UNAVAILABLE: [503],
43
+ SECURITY_REJECTION: [422],
44
+ AUTHENTICATION_ERROR: [401],
45
+ INTEGRITY_ERROR: [500],
46
+ PARTIAL_FAILURE: [],
47
+ NOT_IMPLEMENTED: [],
48
+ };
30
49
  function validationError() {
31
50
  return new KiokukoError('VALIDATION_ERROR', 'Request is invalid');
32
51
  }
@@ -37,101 +56,75 @@ function unavailableError() {
37
56
  return new KiokukoError('SERVICE_UNAVAILABLE', 'Kiokuko server is unavailable');
38
57
  }
39
58
  async function readLiveRuntimeDescriptor(options) {
40
- let descriptorPath;
41
- try {
42
- descriptorPath = options.descriptorPath ?? getRuntimeDescriptorPath();
43
- }
44
- catch {
45
- throw unavailableError();
46
- }
47
- let descriptor;
48
- try {
49
- descriptor = await readRuntimeDescriptor(descriptorPath);
50
- }
51
- catch (error) {
52
- if (error instanceof KiokukoError)
53
- throw error;
54
- throw unavailableError();
55
- }
59
+ const descriptorPath = options.descriptorPath ?? getRuntimeDescriptorPath();
60
+ const descriptor = await readRuntimeDescriptor(descriptorPath);
56
61
  if (!descriptor)
57
62
  throw unavailableError();
58
- let live;
59
- try {
60
- live = await (options.isPidAlive ?? isPidAlive)(descriptor.pid);
61
- }
62
- catch {
63
- throw unavailableError();
64
- }
63
+ const live = await (options.isPidAlive ?? isPidAlive)(descriptor.pid);
65
64
  if (!live)
66
65
  throw unavailableError();
67
66
  return descriptor;
68
67
  }
69
68
  function isPlainObject(value) {
70
- if (typeof value !== 'object' || value === null || Array.isArray(value))
69
+ if (typeof value !== 'object' || value === null || isProxy(value) || Array.isArray(value))
71
70
  return false;
72
71
  const prototype = Object.getPrototypeOf(value);
73
72
  return prototype === Object.prototype || prototype === null;
74
73
  }
74
+ function directPrototype(value) {
75
+ if ((typeof value !== 'object' || value === null) && typeof value !== 'function')
76
+ return undefined;
77
+ if (isProxy(value))
78
+ return undefined;
79
+ return Object.getPrototypeOf(value);
80
+ }
81
+ const BUILTIN_ERROR_PROTOTYPES = new Set([
82
+ Error.prototype,
83
+ EvalError.prototype,
84
+ RangeError.prototype,
85
+ ReferenceError.prototype,
86
+ SyntaxError.prototype,
87
+ TypeError.prototype,
88
+ URIError.prototype,
89
+ ]);
90
+ function isExactErrorObject(value) {
91
+ const prototype = directPrototype(value);
92
+ return prototype !== undefined && prototype !== null && BUILTIN_ERROR_PROTOTYPES.has(prototype);
93
+ }
94
+ function isExactKiokukoError(value) {
95
+ return directPrototype(value) === KiokukoError.prototype;
96
+ }
75
97
  function hasControlCharacters(value) {
76
- return /[\u0000-\u001f\u007f]/.test(value);
98
+ return /\p{Cc}/u.test(value);
77
99
  }
78
- function isCanonicalArrayIndex(value) {
79
- if (value === '0')
80
- return true;
81
- if (!/^[1-9]\d*$/.test(value))
82
- return false;
83
- const index = Number(value);
84
- return Number.isSafeInteger(index) && index < 4_294_967_295 && String(index) === value;
85
- }
86
- function cloneJson(value, seen) {
87
- if (value === null || typeof value === 'boolean' || typeof value === 'string')
88
- return value;
89
- if (typeof value === 'number') {
90
- if (Number.isFinite(value))
91
- return value;
92
- throw validationError();
100
+ function isByteString(value) {
101
+ for (let index = 0; index < value.length; index += 1) {
102
+ if (value.charCodeAt(index) > 0xff)
103
+ return false;
93
104
  }
94
- if (typeof value !== 'object')
105
+ return true;
106
+ }
107
+ function ownDataDescriptors(value) {
108
+ if (isProxy(value))
95
109
  throw validationError();
96
- if (seen.has(value))
110
+ const keys = Reflect.ownKeys(value);
111
+ if (keys.some((key) => typeof key !== 'string'))
97
112
  throw validationError();
98
- seen.add(value);
99
- try {
100
- if (Array.isArray(value)) {
101
- const keys = Reflect.ownKeys(value);
102
- if (keys.some((key) => typeof key === 'symbol'
103
- || (typeof key === 'string' && key !== 'length' && !isCanonicalArrayIndex(key)))) {
104
- throw validationError();
105
- }
106
- const result = [];
107
- for (let index = 0; index < value.length; index += 1) {
108
- if (!Object.prototype.hasOwnProperty.call(value, index))
109
- throw validationError();
110
- result.push(cloneJson(value[index], seen));
111
- }
112
- return result;
113
- }
114
- if (!isPlainObject(value) || Object.getOwnPropertySymbols(value).length > 0)
113
+ const result = new Map();
114
+ for (const key of keys) {
115
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
116
+ if (descriptor === undefined || !('value' in descriptor))
115
117
  throw validationError();
116
- const result = {};
117
- for (const key of Object.keys(value).sort())
118
- result[key] = cloneJson(value[key], seen);
119
- return result;
120
- }
121
- finally {
122
- seen.delete(value);
118
+ result.set(key, descriptor);
123
119
  }
120
+ return result;
124
121
  }
125
122
  function jsonSnapshot(value) {
126
- let snapshot;
127
- try {
128
- snapshot = JSON.stringify(cloneJson(value, new Set()));
129
- }
130
- catch (error) {
131
- if (error instanceof KiokukoError)
132
- throw error;
133
- throw validationError();
134
- }
123
+ const snapshot = stringifyBoundaryJson(cloneBoundaryJson(value, {
124
+ failure: validationError,
125
+ maximumDepth: MAX_STRICT_JSON_DEPTH,
126
+ maximumNodes: MAX_JSON_NODES,
127
+ }));
135
128
  if (Buffer.byteLength(snapshot, 'utf8') > MAX_JSON_BYTES)
136
129
  throw validationError();
137
130
  return snapshot;
@@ -176,10 +169,13 @@ function validatePath(value, method, baseUrl) {
176
169
  const target = new URL(value, `${baseUrl}/`);
177
170
  if (target.origin !== base.origin || target.username !== '' || target.password !== '')
178
171
  throw validationError();
172
+ if (Buffer.byteLength(`${target.pathname}${target.search}`, 'utf8') > MAX_PATH_BYTES
173
+ || Buffer.byteLength(target.search.slice(1), 'utf8') > MAX_QUERY_BYTES)
174
+ throw validationError();
179
175
  return target.toString();
180
176
  }
181
177
  catch (error) {
182
- if (error instanceof KiokukoError)
178
+ if (isExactKiokukoError(error))
183
179
  throw error;
184
180
  throw validationError();
185
181
  }
@@ -191,10 +187,99 @@ function validateIdempotencyKey(method, value) {
191
187
  return undefined;
192
188
  }
193
189
  if (typeof value !== 'string' || value.length === 0 || Buffer.byteLength(value, 'utf8') > MAX_IDEMPOTENCY_KEY_BYTES
194
- || hasControlCharacters(value))
190
+ || value.trim() !== value || hasControlCharacters(value) || !isByteString(value))
195
191
  throw validationError();
196
192
  return value;
197
193
  }
194
+ function signalAborted(signal) {
195
+ return signal?.aborted === true;
196
+ }
197
+ function signalReason(signal) {
198
+ return signal.reason;
199
+ }
200
+ function throwIfSignalAborted(signal) {
201
+ if (signalAborted(signal))
202
+ throw signalReason(signal);
203
+ }
204
+ function awaitWithSignal(operation, signal) {
205
+ const guarded = Promise.resolve(operation);
206
+ if (signal === undefined)
207
+ return guarded;
208
+ if (signalAborted(signal)) {
209
+ guarded.then(() => undefined, () => undefined);
210
+ return Promise.reject(signalReason(signal));
211
+ }
212
+ return new Promise((resolve, reject) => {
213
+ let settled = false;
214
+ const cleanup = () => {
215
+ signal.removeEventListener('abort', onAbort);
216
+ };
217
+ const onAbort = () => {
218
+ if (settled)
219
+ return;
220
+ settled = true;
221
+ cleanup();
222
+ reject(signalReason(signal));
223
+ };
224
+ signal.addEventListener('abort', onAbort, { once: true });
225
+ guarded.then((value) => {
226
+ if (settled)
227
+ return;
228
+ settled = true;
229
+ cleanup();
230
+ if (signalAborted(signal))
231
+ reject(signalReason(signal));
232
+ else
233
+ resolve(value);
234
+ }, (error) => {
235
+ if (settled)
236
+ return;
237
+ settled = true;
238
+ cleanup();
239
+ if (signalAborted(signal))
240
+ reject(signalReason(signal));
241
+ else
242
+ reject(error);
243
+ });
244
+ });
245
+ }
246
+ function normalizeRequestInput(input) {
247
+ if (!isPlainObject(input))
248
+ throw validationError();
249
+ const descriptors = ownDataDescriptors(input);
250
+ const allowed = new Set(['method', 'path', 'operation', 'body', 'idempotencyKey', 'signal']);
251
+ if ([...descriptors.keys()].some((key) => !allowed.has(key)))
252
+ throw validationError();
253
+ for (const field of ['method', 'path', 'operation']) {
254
+ const descriptor = descriptors.get(field);
255
+ if (descriptor === undefined || descriptor.enumerable !== true)
256
+ throw validationError();
257
+ }
258
+ for (const descriptor of descriptors.values()) {
259
+ if (descriptor.enumerable !== true)
260
+ throw validationError();
261
+ }
262
+ const signal = descriptors.get('signal')?.value;
263
+ if (signal !== undefined && directPrototype(signal) !== AbortSignal.prototype) {
264
+ throw validationError();
265
+ }
266
+ if (signal !== undefined) {
267
+ try {
268
+ void signal.aborted;
269
+ }
270
+ catch {
271
+ throw validationError();
272
+ }
273
+ }
274
+ return {
275
+ method: descriptors.get('method')?.value,
276
+ path: descriptors.get('path')?.value,
277
+ operation: descriptors.get('operation')?.value,
278
+ body: descriptors.get('body')?.value,
279
+ idempotencyKey: descriptors.get('idempotencyKey')?.value,
280
+ signal,
281
+ };
282
+ }
198
283
  function assertExactKeys(value, keys) {
199
284
  const allowed = new Set(keys);
200
285
  if (Object.keys(value).some((key) => !allowed.has(key)))
@@ -203,107 +288,278 @@ function assertExactKeys(value, keys) {
203
288
  function isErrorCode(value) {
204
289
  return typeof value === 'string' && ERROR_CODES.includes(value);
205
290
  }
206
- function safeMessage(value, forbidden) {
207
- if (typeof value !== 'string' || value.length === 0 || Buffer.byteLength(value, 'utf8') > MAX_ERROR_MESSAGE_BYTES
208
- || hasControlCharacters(value) || forbidden.some((fragment) => fragment.length > 0 && value.includes(fragment))) {
209
- throw integrityError();
210
- }
211
- return value;
291
+ const TRANSPORT_ERROR_CODES = new Set([
292
+ 'EAI_AGAIN',
293
+ 'ECONNABORTED',
294
+ 'ECONNREFUSED',
295
+ 'ECONNRESET',
296
+ 'EHOSTUNREACH',
297
+ 'ENETDOWN',
298
+ 'ENETUNREACH',
299
+ 'ENOTFOUND',
300
+ 'EPIPE',
301
+ 'ETIMEDOUT',
302
+ 'UND_ERR_BODY_TIMEOUT',
303
+ 'UND_ERR_CONNECT_TIMEOUT',
304
+ 'UND_ERR_HEADERS_TIMEOUT',
305
+ 'UND_ERR_SOCKET',
306
+ ]);
307
+ function ownErrorField(value, field) {
308
+ if (isProxy(value))
309
+ return undefined;
310
+ const descriptor = Object.getOwnPropertyDescriptor(value, field);
311
+ return descriptor !== undefined && 'value' in descriptor ? descriptor.value : undefined;
212
312
  }
213
- function collectBodyFragments(value, fragments) {
214
- if (typeof value === 'string' || typeof value === 'number') {
215
- const fragment = String(value);
216
- if (fragment.length >= 4)
217
- fragments.add(fragment);
218
- return;
219
- }
220
- if (Array.isArray(value)) {
221
- for (const item of value)
222
- collectBodyFragments(item, fragments);
223
- return;
313
+ function hasExactOwnKeys(value, expected) {
314
+ const keys = Reflect.ownKeys(value);
315
+ const allowed = new Set(expected);
316
+ return keys.length === allowed.size
317
+ && keys.every((key) => typeof key === 'string' && allowed.has(key));
318
+ }
319
+ function isExactSystemTransportCause(cause, code) {
320
+ if (directPrototype(cause) !== Error.prototype
321
+ || typeof ownErrorField(cause, 'message') !== 'string'
322
+ || typeof ownErrorField(cause, 'errno') !== 'number'
323
+ || ownErrorField(cause, 'code') !== code
324
+ || typeof ownErrorField(cause, 'syscall') !== 'string')
325
+ return false;
326
+ if (code === 'EAI_AGAIN' || code === 'ENOTFOUND') {
327
+ return typeof ownErrorField(cause, 'hostname') === 'string'
328
+ && hasExactOwnKeys(cause, ['stack', 'message', 'errno', 'code', 'syscall', 'hostname']);
224
329
  }
225
- if (isPlainObject(value)) {
226
- for (const [key, child] of Object.entries(value)) {
227
- if (key.length >= 4)
228
- fragments.add(key);
229
- collectBodyFragments(child, fragments);
230
- }
330
+ return typeof ownErrorField(cause, 'address') === 'string'
331
+ && typeof ownErrorField(cause, 'port') === 'number'
332
+ && hasExactOwnKeys(cause, ['stack', 'message', 'errno', 'code', 'syscall', 'address', 'port']);
333
+ }
334
+ function isExactUndiciTransportCause(cause, code) {
335
+ const expectedName = {
336
+ UND_ERR_BODY_TIMEOUT: 'BodyTimeoutError',
337
+ UND_ERR_CONNECT_TIMEOUT: 'ConnectTimeoutError',
338
+ UND_ERR_HEADERS_TIMEOUT: 'HeadersTimeoutError',
339
+ };
340
+ return cause instanceof Error
341
+ && expectedName[code] !== undefined
342
+ && ownErrorField(cause, 'name') === expectedName[code]
343
+ && ownErrorField(cause, 'code') === code
344
+ && typeof ownErrorField(cause, 'message') === 'string'
345
+ && hasExactOwnKeys(cause, ['stack', 'message', 'name', 'code']);
346
+ }
347
+ function isExactTransportFailure(error) {
348
+ if (!isExactErrorObject(error))
349
+ return false;
350
+ const cause = ownErrorField(error, 'cause');
351
+ const message = ownErrorField(error, 'message');
352
+ if (directPrototype(error) !== TypeError.prototype || (message !== 'fetch failed' && message !== 'terminated')
353
+ || (typeof cause !== 'object' && typeof cause !== 'function') || cause === null
354
+ || isProxy(cause) || cause === error
355
+ || !hasExactOwnKeys(error, ['stack', 'message', 'cause']))
356
+ return false;
357
+ const causeCode = ownErrorField(cause, 'code');
358
+ if (message === 'fetch failed') {
359
+ return typeof causeCode === 'string'
360
+ && TRANSPORT_ERROR_CODES.has(causeCode)
361
+ && (isExactSystemTransportCause(cause, causeCode) || isExactUndiciTransportCause(cause, causeCode));
231
362
  }
363
+ return cause instanceof Error
364
+ && causeCode === 'UND_ERR_SOCKET'
365
+ && ownErrorField(cause, 'name') === 'SocketError'
366
+ && typeof ownErrorField(cause, 'message') === 'string'
367
+ && hasExactOwnKeys(cause, ['stack', 'message', 'name', 'code', 'socket']);
368
+ }
369
+ function throwTransportOrOriginal(error) {
370
+ throw normalizedTransportOrOriginal(error);
371
+ }
372
+ function normalizedTransportOrOriginal(error) {
373
+ return isExactTransportFailure(error) ? unavailableError() : error;
232
374
  }
233
- function bodyForbiddenFragments(snapshot) {
234
- if (snapshot === undefined)
235
- return [];
236
- const fragments = new Set();
375
+ function invalidFetchResponse() {
376
+ throw new TypeError('Fetch implementation returned a non-Response value');
377
+ }
378
+ function validateFetchResponse(value) {
379
+ if (directPrototype(value) !== Response.prototype || Reflect.ownKeys(value).length !== 0) {
380
+ invalidFetchResponse();
381
+ }
382
+ let status;
383
+ let headers;
384
+ let body;
385
+ let bodyUsed;
237
386
  try {
238
- collectBodyFragments(JSON.parse(snapshot), fragments);
387
+ const response = value;
388
+ status = response.status;
389
+ headers = response.headers;
390
+ body = response.body;
391
+ bodyUsed = response.bodyUsed;
392
+ if (directPrototype(headers) !== Headers.prototype
393
+ || Reflect.ownKeys(headers).some((key) => typeof key === 'string')
394
+ || (body !== null && (directPrototype(body) !== ReadableStream.prototype
395
+ || Reflect.ownKeys(body).some((key) => typeof key === 'string'))))
396
+ invalidFetchResponse();
239
397
  }
240
398
  catch {
241
- return [];
399
+ invalidFetchResponse();
242
400
  }
243
- return [...fragments];
401
+ if (bodyUsed || body?.locked === true) {
402
+ throw integrityError();
403
+ }
404
+ return { status, headers, body };
244
405
  }
245
- function containsUnsafeErrorKey(key) {
246
- return /^(?:key|body)$/i.test(key)
247
- || /authorization|bearer|token|secret|password|cookie|credential|api[-_]?key|idempotency|request[-_]?body|requestbody|payload/i.test(key);
406
+ function header(response, name) {
407
+ return response.headers.get(name);
248
408
  }
249
- function safeDetails(value, forbidden) {
250
- if (!isPlainObject(value))
409
+ function hasHeader(response, name) {
410
+ return response.headers.has(name);
411
+ }
412
+ async function settleResponseCleanup(operation, signal) {
413
+ let timer;
414
+ const settled = Promise.resolve(operation).then(() => true, () => false);
415
+ const timed = new Promise((resolve) => {
416
+ timer = setTimeout(() => resolve(false), RESPONSE_CLEANUP_TIMEOUT_MS);
417
+ });
418
+ let cleaned;
419
+ try {
420
+ cleaned = await awaitWithSignal(Promise.race([settled, timed]), signal);
421
+ }
422
+ finally {
423
+ if (timer !== undefined)
424
+ clearTimeout(timer);
425
+ }
426
+ if (!cleaned)
251
427
  throw integrityError();
252
- if (Object.keys(value).some(containsUnsafeErrorKey))
428
+ }
429
+ async function discardResponseBody(response, signal) {
430
+ if (response.body === null)
431
+ return;
432
+ try {
433
+ await settleResponseCleanup(response.body.cancel(), signal);
434
+ }
435
+ catch (error) {
436
+ throwIfSignalAborted(signal);
437
+ if (isExactKiokukoError(error))
438
+ throw error;
253
439
  throw integrityError();
254
- const cloned = cloneJson(value, new Set());
255
- if (typeof cloned !== 'object' || cloned === null || Array.isArray(cloned))
440
+ }
441
+ }
442
+ function exactResponseChunk(value) {
443
+ if (directPrototype(value) !== Uint8Array.prototype)
256
444
  throw integrityError();
257
- const text = JSON.stringify(cloned);
258
- if (forbidden.some((fragment) => fragment.length > 0 && text.includes(fragment)))
445
+ try {
446
+ const ownKeys = Reflect.ownKeys(value);
447
+ if (ownKeys.some((key) => typeof key !== 'string' || !/^(?:0|[1-9]\d*)$/u.test(key))) {
448
+ throw integrityError();
449
+ }
450
+ const byteLength = value.byteLength;
451
+ if (!Number.isSafeInteger(byteLength) || byteLength < 0
452
+ || ownKeys.some((key) => Number(key) >= byteLength))
453
+ throw integrityError();
454
+ return { value: value, byteLength };
455
+ }
456
+ catch (error) {
457
+ if (isExactKiokukoError(error))
458
+ throw error;
259
459
  throw integrityError();
260
- if (Buffer.byteLength(text, 'utf8') > MAX_JSON_BYTES)
460
+ }
461
+ }
462
+ function copyResponseChunk(value, byteLength) {
463
+ try {
464
+ const copy = new Uint8Array(byteLength);
465
+ copy.set(value);
466
+ return Buffer.from(copy.buffer, copy.byteOffset, copy.byteLength);
467
+ }
468
+ catch {
261
469
  throw integrityError();
262
- return cloned;
470
+ }
263
471
  }
264
- async function readBoundedBody(response) {
265
- const contentLength = response.headers.get('content-length');
472
+ async function readBoundedBody(response, signal) {
473
+ const contentLength = header(response, 'content-length');
266
474
  if (contentLength !== null && /^\d+$/.test(contentLength) && Number(contentLength) > MAX_JSON_BYTES) {
475
+ await discardResponseBody(response, signal);
267
476
  throw integrityError();
268
477
  }
269
- if (response.body === null)
478
+ if (response.body === null) {
479
+ throwIfSignalAborted(signal);
270
480
  return '';
271
- const reader = response.body.getReader();
481
+ }
482
+ let reader;
483
+ try {
484
+ reader = response.body.getReader();
485
+ }
486
+ catch {
487
+ throw integrityError();
488
+ }
272
489
  const chunks = [];
273
490
  let size = 0;
491
+ let chunkCount = 0;
492
+ let failed = false;
493
+ let primaryFailure;
494
+ const cleanupFailures = [];
274
495
  try {
275
496
  while (true) {
276
- const item = await reader.read();
497
+ const item = await awaitWithSignal(reader.read(), signal);
498
+ throwIfSignalAborted(signal);
277
499
  if (item.done)
278
500
  break;
279
- size += item.value.byteLength;
280
- if (size > MAX_JSON_BYTES) {
281
- await reader.cancel().catch(() => undefined);
501
+ chunkCount += 1;
502
+ if (chunkCount > MAX_RESPONSE_CHUNKS)
282
503
  throw integrityError();
283
- }
284
- chunks.push(Buffer.from(item.value));
504
+ const chunk = exactResponseChunk(item.value);
505
+ size += chunk.byteLength;
506
+ if (size > MAX_JSON_BYTES)
507
+ throw integrityError();
508
+ chunks.push(copyResponseChunk(chunk.value, chunk.byteLength));
285
509
  }
286
510
  }
287
511
  catch (error) {
288
- if (error instanceof KiokukoError)
289
- throw error;
290
- throw unavailableError();
512
+ failed = true;
513
+ primaryFailure = signal !== undefined && signalAborted(signal)
514
+ ? signalReason(signal)
515
+ : isExactKiokukoError(error)
516
+ ? error
517
+ : normalizedTransportOrOriginal(error);
518
+ try {
519
+ await settleResponseCleanup(reader.cancel());
520
+ }
521
+ catch {
522
+ cleanupFailures.push(integrityError());
523
+ }
291
524
  }
292
525
  try {
293
- return new TextDecoder('utf-8', { fatal: true }).decode(Buffer.concat(chunks));
526
+ reader.releaseLock();
527
+ }
528
+ catch {
529
+ cleanupFailures.push(integrityError());
530
+ }
531
+ if (!failed && signal !== undefined && signalAborted(signal)) {
532
+ failed = true;
533
+ primaryFailure = signalReason(signal);
534
+ }
535
+ if (failed) {
536
+ if (cleanupFailures.length > 0) {
537
+ throw new AggregateError([primaryFailure, ...cleanupFailures], signal !== undefined && signalAborted(signal)
538
+ ? 'Response cleanup failed after caller abort'
539
+ : 'Response body read failed and cleanup also failed');
540
+ }
541
+ throw primaryFailure;
542
+ }
543
+ if (cleanupFailures.length === 1)
544
+ throw cleanupFailures[0];
545
+ if (cleanupFailures.length > 1)
546
+ throw new AggregateError(cleanupFailures, 'Response body cleanup failed');
547
+ throwIfSignalAborted(signal);
548
+ try {
549
+ return new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(Buffer.concat(chunks));
294
550
  }
295
551
  catch {
296
552
  throw integrityError();
297
553
  }
298
554
  }
299
555
  function parseJson(text) {
300
- if (text.length === 0)
301
- throw integrityError();
302
556
  try {
303
- return JSON.parse(text);
557
+ return parseStrictJson(text, { allowTrailingComma: false, disallowComments: true, allowEmptyContent: false }, 'Server response is not valid JSON with unique keys');
304
558
  }
305
- catch {
306
- throw integrityError();
559
+ catch (error) {
560
+ if (isExactKiokukoError(error) && error.code === 'VALIDATION_ERROR')
561
+ throw integrityError();
562
+ throw error;
307
563
  }
308
564
  }
309
565
  function validateHealthResponse(value) {
@@ -325,7 +581,23 @@ function validateSuccessResponse(value, operation) {
325
581
  throw integrityError();
326
582
  return value.data;
327
583
  }
328
- function validateErrorResponse(value, operation, forbidden) {
584
+ function expectedErrorMessage(code, status) {
585
+ switch (code) {
586
+ case 'AUTHENTICATION_ERROR': return 'Authorization is invalid';
587
+ case 'NOT_FOUND': return 'Endpoint not found';
588
+ case 'USAGE_ERROR':
589
+ case 'VALIDATION_ERROR': return 'Request is invalid';
590
+ case 'CONFLICT': return 'Request conflicts with current state';
591
+ case 'BACKPRESSURE': return 'Service is busy';
592
+ case 'SERVICE_UNAVAILABLE': return 'Service unavailable';
593
+ case 'DATABASE_ERROR': return status === 503 ? 'Database unavailable' : 'Unexpected server error';
594
+ case 'SECURITY_REJECTION': return 'Request rejected';
595
+ case 'INTEGRITY_ERROR': return 'Internal integrity error';
596
+ case 'PARTIAL_FAILURE':
597
+ case 'NOT_IMPLEMENTED': throw integrityError();
598
+ }
599
+ }
600
+ function validateErrorResponse(value, operation, status) {
329
601
  if (!isPlainObject(value))
330
602
  throw integrityError();
331
603
  assertExactKeys(value, ['apiVersion', 'ok', 'operation', 'error']);
@@ -335,44 +607,67 @@ function validateErrorResponse(value, operation, forbidden) {
335
607
  assertExactKeys(value.error, ['code', 'message', 'details']);
336
608
  if (!isErrorCode(value.error.code))
337
609
  throw integrityError();
610
+ if (!ERROR_STATUS[value.error.code].includes(status) || !isPlainObject(value.error.details))
611
+ throw integrityError();
612
+ const message = expectedErrorMessage(value.error.code, status);
613
+ if (value.error.message !== message)
614
+ throw integrityError();
615
+ if (value.error.code === 'BACKPRESSURE') {
616
+ assertExactKeys(value.error.details, ['retryAfterSeconds']);
617
+ if (typeof value.error.details.retryAfterSeconds !== 'number'
618
+ || !Number.isSafeInteger(value.error.details.retryAfterSeconds)
619
+ || value.error.details.retryAfterSeconds < 1 || value.error.details.retryAfterSeconds > 60)
620
+ throw integrityError();
621
+ }
622
+ else {
623
+ assertExactKeys(value.error.details, []);
624
+ }
338
625
  return {
339
626
  code: value.error.code,
340
- message: safeMessage(value.error.message, forbidden),
341
- details: safeDetails(value.error.details, forbidden),
627
+ message,
628
+ details: value.error.details,
342
629
  };
343
630
  }
344
631
  function safeRetryAfter(response) {
345
- const value = response.headers.get('retry-after');
346
- if (value === null || !/^\d{1,5}$/.test(value))
632
+ const value = header(response, 'retry-after');
633
+ if (value === null || !/^\d{1,2}$/.test(value))
347
634
  return undefined;
348
635
  const seconds = Number(value);
349
- return Number.isSafeInteger(seconds) && seconds <= 86_400 ? seconds : undefined;
350
- }
351
- async function parseResponse(response, requestPath, operation, authorizationHeader, baseUrl, idempotencyKey, bodySnapshot) {
352
- const forbidden = [
353
- authorizationHeader.startsWith('Bearer ') ? authorizationHeader.slice('Bearer '.length) : authorizationHeader,
354
- baseUrl,
355
- idempotencyKey ?? '',
356
- bodySnapshot ?? '',
357
- ...bodyForbiddenFragments(bodySnapshot),
358
- ];
359
- if (response.status === 204) {
360
- if (requestPath === HEALTH_READY_PATH)
361
- return undefined;
636
+ return Number.isSafeInteger(seconds) && seconds >= 1 && seconds <= 60 ? seconds : undefined;
637
+ }
638
+ async function parseResponse(response, requestPath, operation, signal) {
639
+ if (response.status >= 200 && response.status < 300 && response.status !== 200) {
640
+ await discardResponseBody(response, signal);
362
641
  throw integrityError();
363
642
  }
364
- const contentType = response.headers.get('content-type') ?? '';
365
- if (!/^application\/json(?:\s*;|\s*$)/i.test(contentType))
643
+ const contentType = header(response, 'content-type') ?? '';
644
+ if (!/^application\/json(?:\s*;|\s*$)/i.test(contentType)) {
645
+ await discardResponseBody(response, signal);
366
646
  throw integrityError();
367
- const parsed = parseJson(await readBoundedBody(response));
368
- const isSuccess = response.status >= 200 && response.status < 300;
369
- if (requestPath === HEALTH_READY_PATH && isSuccess)
647
+ }
648
+ const parsed = parseJson(await readBoundedBody(response, signal));
649
+ const isSuccess = response.status === 200;
650
+ if (requestPath === HEALTH_READY_PATH && response.status === 200)
370
651
  return validateHealthResponse(parsed);
652
+ if (requestPath === HEALTH_READY_PATH && response.status === 503) {
653
+ if (!isPlainObject(parsed))
654
+ throw integrityError();
655
+ assertExactKeys(parsed, ['ok']);
656
+ if (parsed.ok !== false || hasHeader(response, 'retry-after'))
657
+ throw integrityError();
658
+ throw new KiokukoError('SERVICE_UNAVAILABLE', 'Kiokuko server is unavailable');
659
+ }
371
660
  if (!isSuccess) {
372
- const error = validateErrorResponse(parsed, operation, forbidden);
373
- const retryAfter = safeRetryAfter(response);
374
- if (retryAfter !== undefined && error.details.retryAfterSeconds === undefined) {
375
- error.details.retryAfterSeconds = retryAfter;
661
+ const error = validateErrorResponse(parsed, operation, response.status);
662
+ const retryAfterHeader = header(response, 'retry-after');
663
+ if (error.code === 'BACKPRESSURE') {
664
+ const retryAfter = safeRetryAfter(response);
665
+ if (retryAfter === undefined || error.details.retryAfterSeconds !== retryAfter) {
666
+ throw integrityError();
667
+ }
668
+ }
669
+ else if (retryAfterHeader !== null) {
670
+ throw integrityError();
376
671
  }
377
672
  throw new KiokukoError(error.code, error.message, error.details);
378
673
  }
@@ -384,16 +679,20 @@ export async function createServerClient(options = {}) {
384
679
  const authorizationHeader = `Bearer ${descriptor.capabilityToken}`;
385
680
  const fetchImplementation = options.fetchImplementation ?? options.fetch ?? globalThis.fetch;
386
681
  const request = async (input) => {
387
- if (typeof input !== 'object' || input === null)
388
- throw validationError();
389
- const method = input.method;
682
+ const normalized = normalizeRequestInput(input);
683
+ const method = normalized.method;
390
684
  if (typeof method !== 'string' || !SERVER_METHODS.has(method))
391
685
  throw validationError();
392
686
  const typedMethod = method;
393
- const operation = validateOperation(input.operation);
394
- const url = validatePath(input.path, typedMethod, baseUrl);
395
- const idempotencyKey = validateIdempotencyKey(typedMethod, input.idempotencyKey);
396
- const bodySnapshot = input.body === undefined ? undefined : jsonSnapshot(input.body);
687
+ const operation = validateOperation(normalized.operation);
688
+ const url = validatePath(normalized.path, typedMethod, baseUrl);
689
+ const requestPath = normalized.path.split('?')[0] ?? normalized.path;
690
+ if ((READ_METHODS.has(typedMethod) && normalized.body !== undefined)
691
+ || (requestPath === HEALTH_READY_PATH && typedMethod !== 'GET')
692
+ || ((requestPath === HEALTH_READY_PATH) !== (operation === 'health.ready')))
693
+ throw validationError();
694
+ const idempotencyKey = validateIdempotencyKey(typedMethod, normalized.idempotencyKey);
695
+ const bodySnapshot = normalized.body === undefined ? undefined : jsonSnapshot(normalized.body);
397
696
  if (typeof fetchImplementation !== 'function')
398
697
  throw unavailableError();
399
698
  const headers = {
@@ -408,16 +707,22 @@ export async function createServerClient(options = {}) {
408
707
  method: typedMethod,
409
708
  headers,
410
709
  ...(bodySnapshot === undefined ? {} : { body: bodySnapshot }),
411
- ...(input.signal === undefined ? {} : { signal: input.signal }),
710
+ ...(normalized.signal === undefined ? {} : { signal: normalized.signal }),
412
711
  };
413
- let response;
712
+ throwIfSignalAborted(normalized.signal);
713
+ let rawResponse;
414
714
  try {
415
- response = await fetchImplementation(url, init);
715
+ rawResponse = await awaitWithSignal(fetchImplementation(url, init), normalized.signal);
416
716
  }
417
- catch {
418
- throw unavailableError();
717
+ catch (error) {
718
+ throwIfSignalAborted(normalized.signal);
719
+ throwTransportOrOriginal(error);
419
720
  }
420
- return await parseResponse(response, input.path.split('?')[0] ?? input.path, operation, authorizationHeader, baseUrl, idempotencyKey, bodySnapshot);
721
+ throwIfSignalAborted(normalized.signal);
722
+ const response = validateFetchResponse(rawResponse);
723
+ const result = await parseResponse(response, requestPath, operation, normalized.signal);
724
+ throwIfSignalAborted(normalized.signal);
725
+ return result;
421
726
  };
422
727
  return Object.freeze({ request });
423
728
  }