@askdkc/kiokuko 0.1.17 → 0.1.20

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 (539) 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/cli.d.ts +2 -0
  52. package/dist/cli.d.ts.map +1 -1
  53. package/dist/cli.js +560 -150
  54. package/dist/cli.js.map +1 -1
  55. package/dist/client/server-client.d.ts +5 -3
  56. package/dist/client/server-client.d.ts.map +1 -1
  57. package/dist/client/server-client.js +486 -181
  58. package/dist/client/server-client.js.map +1 -1
  59. package/dist/commands/agent.d.ts +2 -0
  60. package/dist/commands/agent.d.ts.map +1 -1
  61. package/dist/commands/agent.js +861 -86
  62. package/dist/commands/agent.js.map +1 -1
  63. package/dist/commands/backup.d.ts +2 -1
  64. package/dist/commands/backup.d.ts.map +1 -1
  65. package/dist/commands/backup.js +71 -8
  66. package/dist/commands/backup.js.map +1 -1
  67. package/dist/commands/doctor.d.ts +5 -1
  68. package/dist/commands/doctor.d.ts.map +1 -1
  69. package/dist/commands/doctor.js +70 -26
  70. package/dist/commands/doctor.js.map +1 -1
  71. package/dist/commands/export.d.ts +0 -4
  72. package/dist/commands/export.d.ts.map +1 -1
  73. package/dist/commands/export.js +191 -32
  74. package/dist/commands/export.js.map +1 -1
  75. package/dist/commands/import.d.ts +10 -1
  76. package/dist/commands/import.d.ts.map +1 -1
  77. package/dist/commands/import.js +592 -113
  78. package/dist/commands/import.js.map +1 -1
  79. package/dist/commands/init.d.ts +19 -1
  80. package/dist/commands/init.d.ts.map +1 -1
  81. package/dist/commands/init.js +569 -22
  82. package/dist/commands/init.js.map +1 -1
  83. package/dist/commands/purge.d.ts.map +1 -1
  84. package/dist/commands/purge.js +3 -0
  85. package/dist/commands/purge.js.map +1 -1
  86. package/dist/commands/setup.d.ts +37 -8
  87. package/dist/commands/setup.d.ts.map +1 -1
  88. package/dist/commands/setup.js +448 -86
  89. package/dist/commands/setup.js.map +1 -1
  90. package/dist/commands/skills.d.ts +9 -0
  91. package/dist/commands/skills.d.ts.map +1 -0
  92. package/dist/commands/skills.js +317 -0
  93. package/dist/commands/skills.js.map +1 -0
  94. package/dist/commands/use.d.ts +10 -2
  95. package/dist/commands/use.d.ts.map +1 -1
  96. package/dist/commands/use.js +851 -73
  97. package/dist/commands/use.js.map +1 -1
  98. package/dist/config/paths.d.ts +11 -1
  99. package/dist/config/paths.d.ts.map +1 -1
  100. package/dist/config/paths.js +64 -29
  101. package/dist/config/paths.js.map +1 -1
  102. package/dist/config/project-config.d.ts +1 -0
  103. package/dist/config/project-config.d.ts.map +1 -1
  104. package/dist/config/project-config.js +70 -32
  105. package/dist/config/project-config.js.map +1 -1
  106. package/dist/context/broker.d.ts +28 -14
  107. package/dist/context/broker.d.ts.map +1 -1
  108. package/dist/context/broker.js +604 -145
  109. package/dist/context/broker.js.map +1 -1
  110. package/dist/context/delivery.d.ts +6 -21
  111. package/dist/context/delivery.d.ts.map +1 -1
  112. package/dist/context/delivery.js +196 -147
  113. package/dist/context/delivery.js.map +1 -1
  114. package/dist/context/feedback.d.ts +11 -12
  115. package/dist/context/feedback.d.ts.map +1 -1
  116. package/dist/context/feedback.js +229 -261
  117. package/dist/context/feedback.js.map +1 -1
  118. package/dist/context/ranking.d.ts +1 -12
  119. package/dist/context/ranking.d.ts.map +1 -1
  120. package/dist/context/ranking.js +13 -4
  121. package/dist/context/ranking.js.map +1 -1
  122. package/dist/context/recommendations.d.ts +0 -5
  123. package/dist/context/recommendations.d.ts.map +1 -1
  124. package/dist/context/recommendations.js +0 -1
  125. package/dist/context/recommendations.js.map +1 -1
  126. package/dist/context/run-state.d.ts +26 -0
  127. package/dist/context/run-state.d.ts.map +1 -0
  128. package/dist/context/run-state.js +399 -0
  129. package/dist/context/run-state.js.map +1 -0
  130. package/dist/context/scoped-broker.d.ts +17 -5
  131. package/dist/context/scoped-broker.d.ts.map +1 -1
  132. package/dist/context/scoped-broker.js +512 -106
  133. package/dist/context/scoped-broker.js.map +1 -1
  134. package/dist/context/selection-state.d.ts +19 -0
  135. package/dist/context/selection-state.d.ts.map +1 -0
  136. package/dist/context/selection-state.js +250 -0
  137. package/dist/context/selection-state.js.map +1 -0
  138. package/dist/db/adapter.d.ts +5 -3
  139. package/dist/db/adapter.d.ts.map +1 -1
  140. package/dist/db/adapter.js +7 -3
  141. package/dist/db/adapter.js.map +1 -1
  142. package/dist/db/capabilities.d.ts.map +1 -1
  143. package/dist/db/capabilities.js +34 -16
  144. package/dist/db/capabilities.js.map +1 -1
  145. package/dist/db/connection.d.ts +8 -0
  146. package/dist/db/connection.d.ts.map +1 -1
  147. package/dist/db/connection.js +55 -26
  148. package/dist/db/connection.js.map +1 -1
  149. package/dist/db/migrate.d.ts +28 -7
  150. package/dist/db/migrate.d.ts.map +1 -1
  151. package/dist/db/migrate.js +106 -78
  152. package/dist/db/migrate.js.map +1 -1
  153. package/dist/db/sqlite-retry.d.ts +11 -0
  154. package/dist/db/sqlite-retry.d.ts.map +1 -0
  155. package/dist/db/sqlite-retry.js +66 -0
  156. package/dist/db/sqlite-retry.js.map +1 -0
  157. package/dist/db/transaction.d.ts +13 -0
  158. package/dist/db/transaction.d.ts.map +1 -1
  159. package/dist/db/transaction.js +53 -24
  160. package/dist/db/transaction.js.map +1 -1
  161. package/dist/db/upgrade-backup.d.ts +58 -2
  162. package/dist/db/upgrade-backup.d.ts.map +1 -1
  163. package/dist/db/upgrade-backup.js +758 -28
  164. package/dist/db/upgrade-backup.js.map +1 -1
  165. package/dist/errors.d.ts +4 -0
  166. package/dist/errors.d.ts.map +1 -1
  167. package/dist/errors.js +29 -1
  168. package/dist/errors.js.map +1 -1
  169. package/dist/gateway/agent-service.d.ts +4 -1
  170. package/dist/gateway/agent-service.d.ts.map +1 -1
  171. package/dist/gateway/agent-service.js +71 -58
  172. package/dist/gateway/agent-service.js.map +1 -1
  173. package/dist/gateway/checkpoint-service.d.ts +1 -0
  174. package/dist/gateway/checkpoint-service.d.ts.map +1 -1
  175. package/dist/gateway/checkpoint-service.js +47 -24
  176. package/dist/gateway/checkpoint-service.js.map +1 -1
  177. package/dist/ledger/archive.d.ts +1 -4
  178. package/dist/ledger/archive.d.ts.map +1 -1
  179. package/dist/ledger/archive.js +77 -39
  180. package/dist/ledger/archive.js.map +1 -1
  181. package/dist/ledger/maintenance.d.ts +0 -11
  182. package/dist/ledger/maintenance.d.ts.map +1 -1
  183. package/dist/ledger/maintenance.js +24 -40
  184. package/dist/ledger/maintenance.js.map +1 -1
  185. package/dist/ledger/projection.d.ts +0 -1
  186. package/dist/ledger/projection.d.ts.map +1 -1
  187. package/dist/ledger/projection.js.map +1 -1
  188. package/dist/ledger/promotion.d.ts +0 -9
  189. package/dist/ledger/promotion.d.ts.map +1 -1
  190. package/dist/ledger/promotion.js.map +1 -1
  191. package/dist/ledger/query.d.ts +1 -15
  192. package/dist/ledger/query.d.ts.map +1 -1
  193. package/dist/ledger/query.js.map +1 -1
  194. package/dist/ledger/store.d.ts +0 -1
  195. package/dist/ledger/store.d.ts.map +1 -1
  196. package/dist/ledger/store.js +11 -8
  197. package/dist/ledger/store.js.map +1 -1
  198. package/dist/ledger/types.d.ts +0 -4
  199. package/dist/ledger/types.d.ts.map +1 -1
  200. package/dist/ledger/types.js.map +1 -1
  201. package/dist/ledger/validate.d.ts.map +1 -1
  202. package/dist/ledger/validate.js +0 -5
  203. package/dist/ledger/validate.js.map +1 -1
  204. package/dist/mcp/server.d.ts +4 -0
  205. package/dist/mcp/server.d.ts.map +1 -1
  206. package/dist/mcp/server.js +105 -54
  207. package/dist/mcp/server.js.map +1 -1
  208. package/dist/memory/audit.d.ts +0 -1
  209. package/dist/memory/audit.d.ts.map +1 -1
  210. package/dist/memory/audit.js +0 -1
  211. package/dist/memory/audit.js.map +1 -1
  212. package/dist/memory/curator.d.ts.map +1 -1
  213. package/dist/memory/curator.js +172 -96
  214. package/dist/memory/curator.js.map +1 -1
  215. package/dist/memory/entries.d.ts +12 -2
  216. package/dist/memory/entries.d.ts.map +1 -1
  217. package/dist/memory/entries.js +199 -115
  218. package/dist/memory/entries.js.map +1 -1
  219. package/dist/memory/federated-retrieval.d.ts +12 -1
  220. package/dist/memory/federated-retrieval.d.ts.map +1 -1
  221. package/dist/memory/federated-retrieval.js +183 -70
  222. package/dist/memory/federated-retrieval.js.map +1 -1
  223. package/dist/memory/hybrid-retrieval.d.ts +5 -11
  224. package/dist/memory/hybrid-retrieval.d.ts.map +1 -1
  225. package/dist/memory/hybrid-retrieval.js +78 -58
  226. package/dist/memory/hybrid-retrieval.js.map +1 -1
  227. package/dist/memory/lifecycle.d.ts.map +1 -1
  228. package/dist/memory/lifecycle.js +17 -13
  229. package/dist/memory/lifecycle.js.map +1 -1
  230. package/dist/memory/rebuild-search.d.ts +5 -0
  231. package/dist/memory/rebuild-search.d.ts.map +1 -1
  232. package/dist/memory/rebuild-search.js +101 -76
  233. package/dist/memory/rebuild-search.js.map +1 -1
  234. package/dist/memory/retrieval-query.d.ts +0 -5
  235. package/dist/memory/retrieval-query.d.ts.map +1 -1
  236. package/dist/memory/retrieval-query.js +0 -5
  237. package/dist/memory/retrieval-query.js.map +1 -1
  238. package/dist/memory/retrieval.d.ts.map +1 -1
  239. package/dist/memory/retrieval.js +25 -131
  240. package/dist/memory/retrieval.js.map +1 -1
  241. package/dist/memory/revisions.d.ts +76 -1
  242. package/dist/memory/revisions.d.ts.map +1 -1
  243. package/dist/memory/revisions.js +540 -36
  244. package/dist/memory/revisions.js.map +1 -1
  245. package/dist/memory/scoped-memory.d.ts +16 -1
  246. package/dist/memory/scoped-memory.d.ts.map +1 -1
  247. package/dist/memory/scoped-memory.js +240 -107
  248. package/dist/memory/scoped-memory.js.map +1 -1
  249. package/dist/memory/secrets.d.ts +2 -0
  250. package/dist/memory/secrets.d.ts.map +1 -1
  251. package/dist/memory/secrets.js +36 -0
  252. package/dist/memory/secrets.js.map +1 -1
  253. package/dist/memory/structured-memory.d.ts +3 -2
  254. package/dist/memory/structured-memory.d.ts.map +1 -1
  255. package/dist/memory/structured-memory.js +54 -22
  256. package/dist/memory/structured-memory.js.map +1 -1
  257. package/dist/memory/workspaces.d.ts +9 -0
  258. package/dist/memory/workspaces.d.ts.map +1 -1
  259. package/dist/memory/workspaces.js +67 -0
  260. package/dist/memory/workspaces.js.map +1 -1
  261. package/dist/package-version.d.ts +2 -0
  262. package/dist/package-version.d.ts.map +1 -0
  263. package/dist/package-version.js +7 -0
  264. package/dist/package-version.js.map +1 -0
  265. package/dist/repository/binding.d.ts +5 -0
  266. package/dist/repository/binding.d.ts.map +1 -1
  267. package/dist/repository/binding.js +117 -17
  268. package/dist/repository/binding.js.map +1 -1
  269. package/dist/repository/framework-version.d.ts +8 -0
  270. package/dist/repository/framework-version.d.ts.map +1 -0
  271. package/dist/repository/framework-version.js +29 -0
  272. package/dist/repository/framework-version.js.map +1 -0
  273. package/dist/repository/identity-value.d.ts +4 -0
  274. package/dist/repository/identity-value.d.ts.map +1 -0
  275. package/dist/repository/identity-value.js +24 -0
  276. package/dist/repository/identity-value.js.map +1 -0
  277. package/dist/repository/identity.d.ts.map +1 -1
  278. package/dist/repository/identity.js +2 -0
  279. package/dist/repository/identity.js.map +1 -1
  280. package/dist/repository/project-fingerprint.d.ts +14 -2
  281. package/dist/repository/project-fingerprint.d.ts.map +1 -1
  282. package/dist/repository/project-fingerprint.js +312 -33
  283. package/dist/repository/project-fingerprint.js.map +1 -1
  284. package/dist/repository/remote-url.d.ts +0 -1
  285. package/dist/repository/remote-url.d.ts.map +1 -1
  286. package/dist/repository/remote-url.js +0 -1
  287. package/dist/repository/remote-url.js.map +1 -1
  288. package/dist/runtime-version.d.ts +2 -1
  289. package/dist/runtime-version.d.ts.map +1 -1
  290. package/dist/runtime-version.js +21 -4
  291. package/dist/runtime-version.js.map +1 -1
  292. package/dist/serialization/boundary-json.d.ts +20 -0
  293. package/dist/serialization/boundary-json.d.ts.map +1 -0
  294. package/dist/serialization/boundary-json.js +129 -0
  295. package/dist/serialization/boundary-json.js.map +1 -0
  296. package/dist/serialization/envelope.js +1 -1
  297. package/dist/serialization/envelope.js.map +1 -1
  298. package/dist/serialization/validate.d.ts +7 -0
  299. package/dist/serialization/validate.d.ts.map +1 -1
  300. package/dist/serialization/validate.js +53 -13
  301. package/dist/serialization/validate.js.map +1 -1
  302. package/dist/server/app.js +1 -1
  303. package/dist/server/app.js.map +1 -1
  304. package/dist/server/http.d.ts +4 -3
  305. package/dist/server/http.d.ts.map +1 -1
  306. package/dist/server/http.js +90 -50
  307. package/dist/server/http.js.map +1 -1
  308. package/dist/server/idempotency.d.ts +0 -6
  309. package/dist/server/idempotency.d.ts.map +1 -1
  310. package/dist/server/idempotency.js.map +1 -1
  311. package/dist/server/router.d.ts.map +1 -1
  312. package/dist/server/router.js +21 -4
  313. package/dist/server/router.js.map +1 -1
  314. package/dist/server/routes/agent-capability-gate.d.ts +40 -0
  315. package/dist/server/routes/agent-capability-gate.d.ts.map +1 -0
  316. package/dist/server/routes/agent-capability-gate.js +182 -0
  317. package/dist/server/routes/agent-capability-gate.js.map +1 -0
  318. package/dist/server/routes/agent-events.d.ts.map +1 -1
  319. package/dist/server/routes/agent-events.js +8 -1
  320. package/dist/server/routes/agent-events.js.map +1 -1
  321. package/dist/server/routes/agent-intake.d.ts.map +1 -1
  322. package/dist/server/routes/agent-intake.js +10 -2
  323. package/dist/server/routes/agent-intake.js.map +1 -1
  324. package/dist/server/routes/agent-promotions.d.ts.map +1 -1
  325. package/dist/server/routes/agent-promotions.js +5 -2
  326. package/dist/server/routes/agent-promotions.js.map +1 -1
  327. package/dist/server/routes/agent-runs.d.ts.map +1 -1
  328. package/dist/server/routes/agent-runs.js +18 -4
  329. package/dist/server/routes/agent-runs.js.map +1 -1
  330. package/dist/server/routes/request-binding.d.ts +5 -0
  331. package/dist/server/routes/request-binding.d.ts.map +1 -0
  332. package/dist/server/routes/request-binding.js +49 -0
  333. package/dist/server/routes/request-binding.js.map +1 -0
  334. package/dist/server/routes/task5-support.d.ts +1 -8
  335. package/dist/server/routes/task5-support.d.ts.map +1 -1
  336. package/dist/server/routes/task5-support.js +1 -17
  337. package/dist/server/routes/task5-support.js.map +1 -1
  338. package/dist/server/routes/task5.d.ts.map +1 -1
  339. package/dist/server/routes/task5.js +106 -36
  340. package/dist/server/routes/task5.js.map +1 -1
  341. package/dist/server/write-queue.js +2 -2
  342. package/dist/server/write-queue.js.map +1 -1
  343. package/dist/setup/claude-config.d.ts +4 -1
  344. package/dist/setup/claude-config.d.ts.map +1 -1
  345. package/dist/setup/claude-config.js +62 -4
  346. package/dist/setup/claude-config.js.map +1 -1
  347. package/dist/setup/client-detection.d.ts +7 -2
  348. package/dist/setup/client-detection.d.ts.map +1 -1
  349. package/dist/setup/client-detection.js +27 -9
  350. package/dist/setup/client-detection.js.map +1 -1
  351. package/dist/setup/hermes-config.d.ts +4 -1
  352. package/dist/setup/hermes-config.d.ts.map +1 -1
  353. package/dist/setup/hermes-config.js +71 -17
  354. package/dist/setup/hermes-config.js.map +1 -1
  355. package/dist/setup/legacy-client-cleanup.d.ts +6 -0
  356. package/dist/setup/legacy-client-cleanup.d.ts.map +1 -0
  357. package/dist/setup/legacy-client-cleanup.js +152 -0
  358. package/dist/setup/legacy-client-cleanup.js.map +1 -0
  359. package/dist/setup/managed-text.d.ts.map +1 -1
  360. package/dist/setup/managed-text.js +11 -1
  361. package/dist/setup/managed-text.js.map +1 -1
  362. package/dist/setup/mcp-conflict.d.ts +4 -0
  363. package/dist/setup/mcp-conflict.d.ts.map +1 -0
  364. package/dist/setup/mcp-conflict.js +15 -0
  365. package/dist/setup/mcp-conflict.js.map +1 -0
  366. package/dist/setup/opencode-config.d.ts +4 -1
  367. package/dist/setup/opencode-config.d.ts.map +1 -1
  368. package/dist/setup/opencode-config.js +65 -5
  369. package/dist/setup/opencode-config.js.map +1 -1
  370. package/dist/setup/render.d.ts +4 -1
  371. package/dist/setup/render.d.ts.map +1 -1
  372. package/dist/setup/render.js +168 -18
  373. package/dist/setup/render.js.map +1 -1
  374. package/dist/setup/standard-skills.d.ts +16 -2
  375. package/dist/setup/standard-skills.d.ts.map +1 -1
  376. package/dist/setup/standard-skills.js +37 -13
  377. package/dist/setup/standard-skills.js.map +1 -1
  378. package/dist/setup/strict-json.d.ts +7 -0
  379. package/dist/setup/strict-json.d.ts.map +1 -0
  380. package/dist/setup/strict-json.js +98 -0
  381. package/dist/setup/strict-json.js.map +1 -0
  382. package/dist/setup/strict-toml.d.ts +18 -0
  383. package/dist/setup/strict-toml.d.ts.map +1 -0
  384. package/dist/setup/strict-toml.js +491 -0
  385. package/dist/setup/strict-toml.js.map +1 -0
  386. package/dist/skills/cache.d.ts +15 -0
  387. package/dist/skills/cache.d.ts.map +1 -0
  388. package/dist/skills/cache.js +19 -0
  389. package/dist/skills/cache.js.map +1 -0
  390. package/dist/skills/candidate-ranking.d.ts +15 -0
  391. package/dist/skills/candidate-ranking.d.ts.map +1 -0
  392. package/dist/skills/candidate-ranking.js +52 -0
  393. package/dist/skills/candidate-ranking.js.map +1 -0
  394. package/dist/skills/chunking.d.ts +11 -0
  395. package/dist/skills/chunking.d.ts.map +1 -0
  396. package/dist/skills/chunking.js +291 -0
  397. package/dist/skills/chunking.js.map +1 -0
  398. package/dist/skills/config.d.ts +19 -0
  399. package/dist/skills/config.d.ts.map +1 -0
  400. package/dist/skills/config.js +103 -0
  401. package/dist/skills/config.js.map +1 -0
  402. package/dist/skills/discovery-service.d.ts +26 -0
  403. package/dist/skills/discovery-service.d.ts.map +1 -0
  404. package/dist/skills/discovery-service.js +921 -0
  405. package/dist/skills/discovery-service.js.map +1 -0
  406. package/dist/skills/external-transport.d.ts +2 -0
  407. package/dist/skills/external-transport.d.ts.map +1 -0
  408. package/dist/skills/external-transport.js +30 -0
  409. package/dist/skills/external-transport.js.map +1 -0
  410. package/dist/skills/find.d.ts +16 -0
  411. package/dist/skills/find.d.ts.map +1 -0
  412. package/dist/skills/find.js +58 -0
  413. package/dist/skills/find.js.map +1 -0
  414. package/dist/skills/gap-detection.d.ts +23 -0
  415. package/dist/skills/gap-detection.d.ts.map +1 -0
  416. package/dist/skills/gap-detection.js +62 -0
  417. package/dist/skills/gap-detection.js.map +1 -0
  418. package/dist/skills/import-preparation.d.ts +4 -0
  419. package/dist/skills/import-preparation.d.ts.map +1 -0
  420. package/dist/skills/import-preparation.js +20 -0
  421. package/dist/skills/import-preparation.js.map +1 -0
  422. package/dist/skills/materialization-authority.d.ts +11 -0
  423. package/dist/skills/materialization-authority.d.ts.map +1 -0
  424. package/dist/skills/materialization-authority.js +92 -0
  425. package/dist/skills/materialization-authority.js.map +1 -0
  426. package/dist/skills/materialization-service.d.ts +22 -0
  427. package/dist/skills/materialization-service.d.ts.map +1 -0
  428. package/dist/skills/materialization-service.js +101 -0
  429. package/dist/skills/materialization-service.js.map +1 -0
  430. package/dist/skills/official-catalog.d.ts +31 -0
  431. package/dist/skills/official-catalog.d.ts.map +1 -0
  432. package/dist/skills/official-catalog.js +110 -0
  433. package/dist/skills/official-catalog.js.map +1 -0
  434. package/dist/skills/providers/schema.d.ts +30 -0
  435. package/dist/skills/providers/schema.d.ts.map +1 -0
  436. package/dist/skills/providers/schema.js +354 -0
  437. package/dist/skills/providers/schema.js.map +1 -0
  438. package/dist/skills/providers/skills-sh-compat.d.ts +17 -0
  439. package/dist/skills/providers/skills-sh-compat.d.ts.map +1 -0
  440. package/dist/skills/providers/skills-sh-compat.js +71 -0
  441. package/dist/skills/providers/skills-sh-compat.js.map +1 -0
  442. package/dist/skills/providers/skills-sh-v1.d.ts +23 -0
  443. package/dist/skills/providers/skills-sh-v1.d.ts.map +1 -0
  444. package/dist/skills/providers/skills-sh-v1.js +134 -0
  445. package/dist/skills/providers/skills-sh-v1.js.map +1 -0
  446. package/dist/skills/query-builder.d.ts +18 -0
  447. package/dist/skills/query-builder.d.ts.map +1 -0
  448. package/dist/skills/query-builder.js +93 -0
  449. package/dist/skills/query-builder.js.map +1 -0
  450. package/dist/skills/source/errors.d.ts +9 -0
  451. package/dist/skills/source/errors.d.ts.map +1 -0
  452. package/dist/skills/source/errors.js +15 -0
  453. package/dist/skills/source/errors.js.map +1 -0
  454. package/dist/skills/source/frontmatter.d.ts +9 -0
  455. package/dist/skills/source/frontmatter.d.ts.map +1 -0
  456. package/dist/skills/source/frontmatter.js +77 -0
  457. package/dist/skills/source/frontmatter.js.map +1 -0
  458. package/dist/skills/source/github-fetcher.d.ts +20 -0
  459. package/dist/skills/source/github-fetcher.d.ts.map +1 -0
  460. package/dist/skills/source/github-fetcher.js +292 -0
  461. package/dist/skills/source/github-fetcher.js.map +1 -0
  462. package/dist/skills/source/snapshot-validator.d.ts +28 -0
  463. package/dist/skills/source/snapshot-validator.d.ts.map +1 -0
  464. package/dist/skills/source/snapshot-validator.js +186 -0
  465. package/dist/skills/source/snapshot-validator.js.map +1 -0
  466. package/dist/skills/store.d.ts +181 -0
  467. package/dist/skills/store.d.ts.map +1 -0
  468. package/dist/skills/store.js +1710 -0
  469. package/dist/skills/store.js.map +1 -0
  470. package/dist/skills/types.d.ts +169 -0
  471. package/dist/skills/types.d.ts.map +1 -0
  472. package/dist/skills/types.js +2 -0
  473. package/dist/skills/types.js.map +1 -0
  474. package/dist/web/i18n.d.ts +32 -0
  475. package/dist/web/i18n.d.ts.map +1 -1
  476. package/dist/web/i18n.js +128 -0
  477. package/dist/web/i18n.js.map +1 -1
  478. package/dist/web/server.d.ts.map +1 -1
  479. package/dist/web/server.js +386 -38
  480. package/dist/web/server.js.map +1 -1
  481. package/dist/web/ui.d.ts +4 -0
  482. package/dist/web/ui.d.ts.map +1 -1
  483. package/dist/web/ui.js +382 -6
  484. package/dist/web/ui.js.map +1 -1
  485. package/migrations/009_external_skill_discovery.sql +126 -0
  486. package/package.json +6 -3
  487. package/skills/kiokuko-single-purpose-functions/SKILL.md +288 -0
  488. package/skills/kiokuko-single-purpose-functions/references/kiokuko-patterns.md +344 -0
  489. package/skills/kiokuko-single-purpose-functions/references/review-checklist.md +97 -0
  490. package/skills/kiokuko-ui-design-soul/SKILL.md +1186 -28
  491. package/templates/AGENTS.md +8 -7
  492. package/dist/client/runtime-discovery.d.ts +0 -15
  493. package/dist/client/runtime-discovery.d.ts.map +0 -1
  494. package/dist/client/runtime-discovery.js +0 -45
  495. package/dist/client/runtime-discovery.js.map +0 -1
  496. package/dist/commands/call.d.ts +0 -7
  497. package/dist/commands/call.d.ts.map +0 -1
  498. package/dist/commands/call.js +0 -10
  499. package/dist/commands/call.js.map +0 -1
  500. package/dist/commands/link.d.ts +0 -6
  501. package/dist/commands/link.d.ts.map +0 -1
  502. package/dist/commands/link.js +0 -6
  503. package/dist/commands/link.js.map +0 -1
  504. package/dist/commands/promote.d.ts +0 -6
  505. package/dist/commands/promote.d.ts.map +0 -1
  506. package/dist/commands/promote.js +0 -6
  507. package/dist/commands/promote.js.map +0 -1
  508. package/dist/commands/read.d.ts +0 -6
  509. package/dist/commands/read.d.ts.map +0 -1
  510. package/dist/commands/read.js +0 -4
  511. package/dist/commands/read.js.map +0 -1
  512. package/dist/commands/recall.d.ts +0 -6
  513. package/dist/commands/recall.d.ts.map +0 -1
  514. package/dist/commands/recall.js +0 -4
  515. package/dist/commands/recall.js.map +0 -1
  516. package/dist/commands/record.d.ts +0 -6
  517. package/dist/commands/record.d.ts.map +0 -1
  518. package/dist/commands/record.js +0 -4
  519. package/dist/commands/record.js.map +0 -1
  520. package/dist/commands/search.d.ts +0 -6
  521. package/dist/commands/search.d.ts.map +0 -1
  522. package/dist/commands/search.js +0 -4
  523. package/dist/commands/search.js.map +0 -1
  524. package/dist/commands/supersede.d.ts +0 -6
  525. package/dist/commands/supersede.d.ts.map +0 -1
  526. package/dist/commands/supersede.js +0 -6
  527. package/dist/commands/supersede.js.map +0 -1
  528. package/dist/knowledge/sources.d.ts +0 -72
  529. package/dist/knowledge/sources.d.ts.map +0 -1
  530. package/dist/knowledge/sources.js +0 -388
  531. package/dist/knowledge/sources.js.map +0 -1
  532. package/dist/setup/opencode-evidence.d.ts +0 -37
  533. package/dist/setup/opencode-evidence.d.ts.map +0 -1
  534. package/dist/setup/opencode-evidence.js +0 -58
  535. package/dist/setup/opencode-evidence.js.map +0 -1
  536. package/dist/setup/opencode-loop-guard.d.ts +0 -9
  537. package/dist/setup/opencode-loop-guard.d.ts.map +0 -1
  538. package/dist/setup/opencode-loop-guard.js +0 -248
  539. package/dist/setup/opencode-loop-guard.js.map +0 -1
package/dist/web/ui.js CHANGED
@@ -10,6 +10,93 @@ const WEB_I18N_CONFIG = JSON.stringify({
10
10
  .replaceAll('>', '\\u003e')
11
11
  .replaceAll('\u2028', '\\u2028')
12
12
  .replaceAll('\u2029', '\\u2029');
13
+ /** Strict client-boundary decoder for the bounded external-skill list shape. */
14
+ export function externalSkillListItemIsValid(value) {
15
+ if (typeof value !== 'object' || value === null || Array.isArray(value))
16
+ return false;
17
+ const skill = value;
18
+ const fields = new Set([
19
+ 'skillId', 'provider', 'sourceType', 'sourceLocator', 'slug', 'name', 'installUrl',
20
+ 'officialStatus', 'duplicate', 'installs', 'state', 'sourceWorkspace', 'sourceCommit',
21
+ 'snapshotHash', 'metadata', 'auditStatus', 'generation', 'firstSeenAt', 'lastSeenAt',
22
+ 'lastCheckedAt', 'disabledAt',
23
+ ]);
24
+ const text = (item, maximum) => typeof item === 'string'
25
+ && item.length >= 1 && item.length <= maximum && item === item.trim() && !/[\u0000-\u001f\u007f]/u.test(item);
26
+ const timestamp = (item) => {
27
+ if (typeof item !== 'string')
28
+ return false;
29
+ const parsed = Date.parse(item);
30
+ return Number.isFinite(parsed) && new Date(parsed).toISOString() === item;
31
+ };
32
+ const metadata = skill.metadata;
33
+ const sourceLocator = skill.sourceLocator;
34
+ const slug = skill.slug;
35
+ const sourceCommit = skill.sourceCommit;
36
+ const snapshotHash = skill.snapshotHash;
37
+ const disabledAt = skill.disabledAt;
38
+ const officialStatus = skill.officialStatus;
39
+ const state = skill.state;
40
+ const auditStatus = skill.auditStatus;
41
+ if (Object.keys(skill).length !== fields.size || Object.keys(skill).some((field) => !fields.has(field))
42
+ || !text(skill.skillId, 500) || !text(skill.provider, 50) || !/^[A-Za-z0-9_.-]+$/u.test(skill.provider)
43
+ || skill.sourceType !== 'github'
44
+ || typeof sourceLocator !== 'string' || !/^[a-z0-9_.-]{1,100}\/[a-z0-9_.-]{1,100}$/u.test(sourceLocator)
45
+ || typeof slug !== 'string' || !/^[A-Za-z0-9_.\-/]{1,240}$/u.test(slug)
46
+ || slug.split('/').some((part) => part === '' || part === '.' || part === '..')
47
+ || skill.skillId !== `github:${sourceLocator}:${slug}`
48
+ || !text(skill.name, 500)
49
+ || skill.installUrl !== null && skill.installUrl !== `https://github.com/${sourceLocator}`
50
+ || typeof officialStatus !== 'string'
51
+ || !['curated', 'catalog-verified', 'owner-verified', 'registry-only', 'unknown'].includes(officialStatus)
52
+ || typeof skill.duplicate !== 'boolean'
53
+ || typeof skill.installs !== 'number' || !Number.isSafeInteger(skill.installs) || skill.installs < 0
54
+ || typeof state !== 'string'
55
+ || !['discovered', 'imported', 'blocked', 'stale', 'disabled'].includes(state)
56
+ || !text(skill.sourceWorkspace, 240)
57
+ || sourceCommit !== null && (typeof sourceCommit !== 'string' || !/^(?:[0-9a-f]{40}|[0-9a-f]{64})$/u.test(sourceCommit))
58
+ || snapshotHash !== null && (typeof snapshotHash !== 'string' || !/^[0-9a-f]{64}$/u.test(snapshotHash))
59
+ || (sourceCommit === null) !== (snapshotHash === null)
60
+ || typeof metadata !== 'object' || metadata === null || Array.isArray(metadata)
61
+ || Object.keys(metadata).length !== 2 || !Object.hasOwn(metadata, 'documents') || !Object.hasOwn(metadata, 'technology')
62
+ || typeof metadata.documents !== 'number'
63
+ || !Number.isSafeInteger(metadata.documents)
64
+ || metadata.documents < 0
65
+ || metadata.documents > 64
66
+ || metadata.technology !== null && !text(metadata.technology, 500)
67
+ || typeof auditStatus !== 'string'
68
+ || !['not-required', 'passed', 'failed', 'unavailable'].includes(auditStatus)
69
+ || typeof skill.generation !== 'number' || !Number.isSafeInteger(skill.generation) || skill.generation < 1
70
+ || !timestamp(skill.firstSeenAt) || !timestamp(skill.lastSeenAt) || !timestamp(skill.lastCheckedAt)
71
+ || disabledAt !== null && !timestamp(disabledAt)
72
+ || skill.firstSeenAt > skill.lastSeenAt
73
+ || skill.firstSeenAt > skill.lastCheckedAt
74
+ || disabledAt !== null && disabledAt < skill.firstSeenAt
75
+ || sourceCommit === null && (['imported', 'disabled'].includes(state) || disabledAt !== null)
76
+ || sourceCommit !== null && !['imported', 'disabled', 'stale', 'blocked'].includes(state)
77
+ || state === 'imported' && disabledAt !== null
78
+ || state === 'disabled' && disabledAt === null
79
+ || sourceCommit === null && (metadata.documents !== 0 || metadata.technology !== null)
80
+ || sourceCommit !== null && (metadata.documents === 0 || !text(metadata.technology, 500)))
81
+ return false;
82
+ return true;
83
+ }
84
+ /** Strict client-boundary decoder for one external-skill mapping summary. */
85
+ export function externalSkillEntrySummaryIsValid(value) {
86
+ if (typeof value !== 'object' || value === null || Array.isArray(value))
87
+ return false;
88
+ const entry = value;
89
+ const fields = new Set(['entryId', 'revision', 'sourcePath', 'chunkIndex', 'primary', 'active']);
90
+ return Object.keys(entry).length === fields.size
91
+ && Object.keys(entry).every((field) => fields.has(field))
92
+ && typeof entry.entryId === 'string' && entry.entryId.length >= 1 && entry.entryId.length <= 500 && entry.entryId === entry.entryId.trim()
93
+ && typeof entry.revision === 'number' && Number.isSafeInteger(entry.revision) && entry.revision >= 1
94
+ && typeof entry.sourcePath === 'string' && entry.sourcePath.length >= 1 && entry.sourcePath.length <= 2_000
95
+ && /^[A-Za-z0-9_.\-/]+$/u.test(entry.sourcePath) && !entry.sourcePath.startsWith('/')
96
+ && !entry.sourcePath.split('/').some((part) => part === '' || part === '.' || part === '..')
97
+ && typeof entry.chunkIndex === 'number' && Number.isSafeInteger(entry.chunkIndex) && entry.chunkIndex >= 0
98
+ && typeof entry.primary === 'boolean' && typeof entry.active === 'boolean';
99
+ }
13
100
  export const WEB_HTML = String.raw `<!doctype html>
14
101
  <html lang="en">
15
102
  <head>
@@ -140,6 +227,17 @@ export const WEB_HTML = String.raw `<!doctype html>
140
227
  .curator-confirm-field dd { margin:0; overflow-wrap:anywhere; white-space:pre-wrap; }
141
228
  .curator-confirm-draft { max-height:280px; overflow:auto; margin:0; padding:12px; border:1px solid var(--line); border-radius:12px; background:var(--surface); white-space:pre-wrap; overflow-wrap:anywhere; font:inherit; font-size:13px; line-height:1.5; }
142
229
  .curator-confirm-actions { display:flex; justify-content:flex-end; gap:8px; margin-top:14px; }
230
+ .skill-dialog { width:min(1040px,calc(100vw - 32px)); max-height:min(860px,calc(100vh - 48px)); display:flex; flex-direction:column; min-height:0; background:rgba(255,255,255,.96); box-shadow:0 28px 90px rgba(15,23,42,.28); }
231
+ .skill-dialog .panel-body { min-height:0; overflow-y:auto; }
232
+ .skill-list { display:grid; gap:12px; }
233
+ .skill-card { border:1px solid var(--line); border-radius:14px; padding:16px; background:var(--panel); }
234
+ .skill-card h3 { margin:8px 0; font-size:17px; overflow-wrap:anywhere; }
235
+ .skill-card-grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(180px,1fr)); gap:8px; margin-top:12px; }
236
+ .skill-field { min-width:0; padding:10px 11px; border:1px solid var(--line); border-radius:10px; background:var(--surface); }
237
+ .skill-field dt { margin:0 0 4px; color:var(--muted); font-size:11px; font-weight:800; }
238
+ .skill-field dd { margin:0; overflow-wrap:anywhere; white-space:pre-wrap; font-size:13px; }
239
+ .skill-card-actions { display:flex; flex-wrap:wrap; gap:8px; margin-top:12px; }
240
+ .skill-source-link { color:var(--accent); overflow-wrap:anywhere; }
143
241
  @keyframes curator-backdrop-in { from { opacity:0; } to { opacity:1; } }
144
242
  @keyframes curator-backdrop-out { from { opacity:1; } to { opacity:0; } }
145
243
  @keyframes curator-dialog-in { from { opacity:0; transform:translateY(10px) scale(.98); } to { opacity:1; transform:translateY(0) scale(1); } }
@@ -171,6 +269,7 @@ export const WEB_HTML = String.raw `<!doctype html>
171
269
  <select id="workspace" class="control" aria-label="Workspace" data-i18n-aria-label="workspaceLabel"></select>
172
270
  <input id="search" class="search" type="search" placeholder="Search memory…" aria-label="Search memory…" data-i18n-placeholder="searchPlaceholder" data-i18n-aria-label="searchPlaceholder">
173
271
  <button id="curator-button" class="button" type="button" data-i18n="curator">Curator</button>
272
+ <button id="external-skills-button" class="button" type="button" data-i18n="openExternalSkills">External Skills</button>
174
273
  <button id="refresh" class="button" type="button" data-i18n="refresh">Refresh</button>
175
274
  </div>
176
275
  </div>
@@ -238,8 +337,23 @@ export const WEB_HTML = String.raw `<!doctype html>
238
337
  </section>
239
338
  </div>
240
339
  </div>
340
+ <div id="external-skills-modal" class="curator-modal" hidden>
341
+ <section id="external-skills-panel" class="panel skill-dialog" role="dialog" aria-modal="true" aria-labelledby="external-skills-title" aria-describedby="external-skills-description">
342
+ <div class="panel-head curator-dialog-head">
343
+ <div class="curator-heading"><h2 id="external-skills-title" data-i18n="externalSkills">External Skills</h2><span class="badge" data-i18n="trustBadge">stored data is untrusted / non-actionable</span></div>
344
+ <div class="curator-header-actions"><button id="external-skills-refresh" class="button" type="button" data-i18n="externalSkillsRefresh">Refresh</button><button id="external-skills-close" class="curator-close" type="button" aria-label="Close External Skills" data-i18n-aria-label="externalSkillsClose"><span aria-hidden="true">×</span></button></div>
345
+ </div>
346
+ <div class="panel-body">
347
+ <p id="external-skills-description" class="subtitle" data-i18n="externalSkillsDescription">Review fetched skills as untrusted reference data. Nothing here installs software or runs scripts.</p>
348
+ <div id="external-skills-status" class="status" role="status" aria-live="polite"></div>
349
+ <div id="external-skills-list" class="skill-list"></div>
350
+ </div>
351
+ </section>
352
+ </div>
241
353
  <script>
242
354
  const i18n = ${WEB_I18N_CONFIG};
355
+ const validExternalSkillListItem = (${externalSkillListItemIsValid.toString()});
356
+ const validExternalSkillEntrySummary = (${externalSkillEntrySummaryIsValid.toString()});
243
357
  const localeStorageKey = 'kiokuko.web.locale';
244
358
  const normalizeLocale = (value) => {
245
359
  if (typeof value !== 'string') return null;
@@ -251,7 +365,14 @@ export const WEB_HTML = String.raw `<!doctype html>
251
365
  if (language === 'zh' && (parts.length === 1 || parts.includes('hans') || parts.includes('cn') || parts.includes('sg'))) return 'zh-CN';
252
366
  return null;
253
367
  };
254
- const readStoredLocale = () => { try { return localStorage.getItem(localeStorageKey); } catch { return null; } };
368
+ const isStorageAccessError = (error) => typeof DOMException !== 'undefined' && error instanceof DOMException;
369
+ const readStoredLocale = () => {
370
+ try { return localStorage.getItem(localeStorageKey); }
371
+ catch (error) {
372
+ if (!isStorageAccessError(error)) throw error;
373
+ return null;
374
+ }
375
+ };
255
376
  const browserLocales = Array.isArray(navigator.languages) ? navigator.languages : [navigator.language];
256
377
  const localeCandidates = [new URLSearchParams(location.search).get('lang'), readStoredLocale(), ...browserLocales];
257
378
  const initialLocale = localeCandidates.map(normalizeLocale).find(Boolean) || i18n.defaultLocale;
@@ -262,7 +383,7 @@ export const WEB_HTML = String.raw `<!doctype html>
262
383
  ['bot:common', 'bot.common'], ['bot:researcher', 'bot.researcher'], ['bot:builder', 'bot.builder'], ['bot:reviewer', 'bot.reviewer'], ['bot:devops', 'bot.devops'], ['bot:writer', 'bot.writer'], ['bot:analyst', 'bot.analyst']
263
384
  ];
264
385
  const curatorUrl = new URLSearchParams(location.search);
265
- const state = { locale: initialLocale, workspace: '', kind: 'all', tag: '', query: '', entries: [], recallItems: [], tags: [], selected: null, selectedRecall: null, runs: [], selectedRun: null, curatorCandidates: [], curatorGlobalized: new Set(), curatorNextCursor: null, curatorTotalApproximate: 0, curatorOpen: false, curatorPreviousFocus: null, curatorPendingCandidate: null, curatorConfirmationTrigger: null, curatorGlobalizeBusy: false, localizedStatus: null, curatorSearch: curatorUrl.get('search') || '', curatorProject: curatorUrl.get('project') || '', curatorTags: new Set(curatorUrl.getAll('tag')), curatorFramework: curatorUrl.get('framework') || '', curatorLanguage: curatorUrl.get('language') || '', curatorMemoryClass: curatorUrl.get('memoryClass') || '', curatorTier: curatorUrl.get('tier') || '', curatorReady: curatorUrl.get('ready') === 'true', curatorIncludeGlobalized: curatorUrl.get('includeGlobalized') === 'true', curatorFacets: null };
386
+ const state = { locale: initialLocale, workspace: '', kind: 'all', tag: '', query: '', entries: [], recallItems: [], tags: [], selected: null, selectedRecall: null, runs: [], selectedRun: null, curatorCandidates: [], curatorGlobalized: new Set(), curatorNextCursor: null, curatorTotalApproximate: 0, curatorOpen: false, curatorPreviousFocus: null, curatorPendingCandidate: null, curatorConfirmationTrigger: null, curatorGlobalizeBusy: false, externalSkills: [], externalSkillsOpen: false, externalSkillsPreviousFocus: null, externalSkillsBusy: false, externalSkillsPendingDisable: null, localizedStatus: null, curatorSearch: curatorUrl.get('search') || '', curatorProject: curatorUrl.get('project') || '', curatorTags: new Set(curatorUrl.getAll('tag')), curatorFramework: curatorUrl.get('framework') || '', curatorLanguage: curatorUrl.get('language') || '', curatorMemoryClass: curatorUrl.get('memoryClass') || '', curatorTier: curatorUrl.get('tier') || '', curatorReady: curatorUrl.get('ready') === 'true', curatorIncludeGlobalized: curatorUrl.get('includeGlobalized') === 'true', curatorFacets: null };
266
387
  const $ = (id) => document.getElementById(id);
267
388
  const t = (key, parameters = {}) => {
268
389
  const template = i18n.messages[state.locale]?.[key] ?? i18n.messages[i18n.defaultLocale]?.[key] ?? key;
@@ -310,9 +431,10 @@ export const WEB_HTML = String.raw `<!doctype html>
310
431
  };
311
432
  const selectLocale = (value) => {
312
433
  state.locale = normalizeLocale(value) || i18n.defaultLocale;
313
- try { localStorage.setItem(localeStorageKey, state.locale); } catch {}
434
+ try { localStorage.setItem(localeStorageKey, state.locale); }
435
+ catch (error) { if (!isStorageAccessError(error)) throw error; }
314
436
  setLanguageMenuOpen(false, true);
315
- applyTranslations(); renderFilters(); renderEntries(); renderRuns(); renderRunDetail(); renderCurator(); updateEditorState();
437
+ applyTranslations(); renderFilters(); renderEntries(); renderRuns(); renderRunDetail(); renderCurator(); renderExternalSkills(); updateEditorState();
316
438
  };
317
439
  const applyTranslations = () => {
318
440
  document.documentElement.lang = state.locale;
@@ -326,10 +448,24 @@ export const WEB_HTML = String.raw `<!doctype html>
326
448
  renderLanguageMenu();
327
449
  if (state.localizedStatus) showStatus(state.localizedStatus.plural ? tp(state.localizedStatus.key, state.localizedStatus.count) : t(state.localizedStatus.key, state.localizedStatus.parameters), state.localizedStatus.error);
328
450
  };
451
+ const apiError = (value) => {
452
+ const rawCode = value?.error?.code;
453
+ const rawMessage = value?.error?.message;
454
+ const code = typeof rawCode === 'string' && /^[A-Z][A-Z0-9_]{0,63}$/.test(rawCode) ? rawCode : 'REQUEST_FAILED';
455
+ const normalizedMessage = typeof rawMessage === 'string' ? rawMessage.replace(/[\u0000-\u001f\u007f]+/g, ' ').trim().slice(0, 300) : '';
456
+ const error = new Error(normalizedMessage || t('requestFailed'));
457
+ error.code = code;
458
+ return error;
459
+ };
460
+ const apiErrorText = (error) => {
461
+ const code = error instanceof Error && typeof error.code === 'string' && /^[A-Z][A-Z0-9_]{0,63}$/.test(error.code) ? error.code : 'REQUEST_FAILED';
462
+ const normalizedMessage = error instanceof Error ? error.message.replace(/[\u0000-\u001f\u007f]+/g, ' ').trim().slice(0, 300) : '';
463
+ return '[' + code + '] ' + (normalizedMessage || t('requestFailed'));
464
+ };
329
465
  const api = async (path, options) => {
330
466
  const response = await fetch(path, options);
331
467
  const value = await response.json();
332
- if (!response.ok) throw new Error(value.error?.message || t('requestFailed'));
468
+ if (!response.ok) throw apiError(value);
333
469
  return value;
334
470
  };
335
471
  const escapeTags = (value) => value.split(',').map((item) => item.trim()).filter(Boolean);
@@ -437,6 +573,242 @@ export const WEB_HTML = String.raw `<!doctype html>
437
573
  else if (!event.shiftKey && document.activeElement === last) { event.preventDefault(); first.focus(); }
438
574
  }
439
575
 
576
+ const setExternalSkillsStatus = (message, error = false) => {
577
+ const element = $('external-skills-status');
578
+ element.textContent = message;
579
+ element.className = error ? 'status notice error curator-status' : 'status curator-status';
580
+ };
581
+ function openExternalSkills() {
582
+ if (state.externalSkillsOpen) { $('external-skills-close')?.focus(); return; }
583
+ state.externalSkillsPreviousFocus = document.activeElement instanceof HTMLElement ? document.activeElement : null;
584
+ state.externalSkillsOpen = true;
585
+ const modal = $('external-skills-modal');
586
+ modal.classList.remove('is-closing');
587
+ setCuratorBackgroundBlocked(true);
588
+ modal.hidden = false;
589
+ requestAnimationFrame(() => $('external-skills-close')?.focus());
590
+ }
591
+ function closeExternalSkills() {
592
+ if (state.externalSkillsBusy) return;
593
+ const modal = $('external-skills-modal');
594
+ if (modal.hidden) return;
595
+ state.externalSkillsOpen = false;
596
+ state.externalSkillsPendingDisable = null;
597
+ modal.classList.add('is-closing');
598
+ let finished = false;
599
+ const finish = () => {
600
+ if (finished) return;
601
+ finished = true;
602
+ modal.hidden = true;
603
+ modal.classList.remove('is-closing');
604
+ setCuratorBackgroundBlocked(false);
605
+ const previousFocus = state.externalSkillsPreviousFocus;
606
+ state.externalSkillsPreviousFocus = null;
607
+ if (previousFocus?.isConnected) previousFocus.focus(); else $('external-skills-button')?.focus();
608
+ };
609
+ modal.addEventListener('animationend', (event) => { if (event.target === modal) finish(); }, { once: true });
610
+ window.setTimeout(finish, 220);
611
+ }
612
+ function handleExternalSkillsKeydown(event) {
613
+ if (event.key === 'Escape') { event.preventDefault(); closeExternalSkills(); return; }
614
+ if (event.key !== 'Tab') return;
615
+ const modal = $('external-skills-modal');
616
+ const focusable = [...modal.querySelectorAll('button:not([disabled]), a[href], [tabindex]:not([tabindex="-1"])')];
617
+ if (!focusable.length) { event.preventDefault(); return; }
618
+ const first = focusable[0]; const last = focusable.at(-1);
619
+ if (event.shiftKey && document.activeElement === first) { event.preventDefault(); last.focus(); }
620
+ else if (!event.shiftKey && document.activeElement === last) { event.preventDefault(); first.focus(); }
621
+ }
622
+ function skillField(labelKey, value) {
623
+ const field = document.createElement('div'); field.className = 'skill-field';
624
+ const label = document.createElement('dt'); setI18nText(label, labelKey);
625
+ const content = document.createElement('dd'); content.textContent = value || t('unknown');
626
+ field.append(label, content); return field;
627
+ }
628
+ function externalSkillButton(attribute, skillId) {
629
+ return [...document.querySelectorAll('[' + attribute + ']')].find((element) => element.getAttribute(attribute) === skillId);
630
+ }
631
+ function externalSkillSourceUrl(skill) {
632
+ return /^[A-Za-z0-9_.-]{1,100}\/[A-Za-z0-9_.-]{1,100}$/.test(skill.sourceLocator) ? 'https://github.com/' + skill.sourceLocator : null;
633
+ }
634
+ function renderExternalSkills() {
635
+ if (!state.externalSkillsOpen) return;
636
+ const root = $('external-skills-list');
637
+ if (!state.externalSkills.length) { const empty = document.createElement('div'); empty.className = 'editor-empty'; setI18nText(empty, 'externalSkillsEmpty'); root.replaceChildren(empty); return; }
638
+ root.replaceChildren(...state.externalSkills.map((skill) => {
639
+ const card = document.createElement('article'); card.className = 'skill-card';
640
+ const meta = document.createElement('div'); meta.className = 'entry-meta';
641
+ const stateBadge = document.createElement('span'); stateBadge.className = 'badge ' + (skill.state === 'disabled' ? 'superseded' : skill.state === 'imported' ? 'verified' : 'candidate'); stateBadge.textContent = skill.state;
642
+ const official = document.createElement('span'); official.className = 'badge'; official.textContent = skill.officialStatus;
643
+ meta.append(stateBadge, official);
644
+ const heading = document.createElement('h3'); heading.textContent = skill.name;
645
+ const fields = document.createElement('dl'); fields.className = 'skill-card-grid';
646
+ fields.append(
647
+ skillField('externalSkillsSource', skill.sourceLocator + '/' + skill.slug),
648
+ skillField('externalSkillsCommit', skill.sourceCommit ? skill.sourceCommit.slice(0, 12) : null),
649
+ skillField('externalSkillsSnapshot', skill.snapshotHash ? skill.snapshotHash.slice(0, 12) : null),
650
+ skillField('externalSkillsDocuments', String(skill.metadata?.documents ?? 0)),
651
+ skillField('externalSkillsFirstSeen', skill.firstSeenAt),
652
+ skillField('externalSkillsLastChecked', skill.lastCheckedAt),
653
+ skillField('externalSkillsTechnology', skill.metadata?.technology ?? skill.name),
654
+ skillField('externalSkillsAudit', skill.auditStatus),
655
+ skillField('externalSkillsState', skill.state),
656
+ );
657
+ const notice = document.createElement('div'); notice.className = 'notice'; setI18nText(notice, 'externalSkillsUntrusted');
658
+ const actions = document.createElement('div'); actions.className = 'skill-card-actions';
659
+ const sourceUrl = externalSkillSourceUrl(skill);
660
+ if (sourceUrl) { const source = document.createElement('a'); source.className = 'button'; source.href = sourceUrl; source.target = '_blank'; source.rel = 'noopener noreferrer'; setI18nText(source, 'externalSkillsSourceUrl'); actions.append(source); }
661
+ const refresh = document.createElement('button'); refresh.type = 'button'; refresh.className = 'button'; refresh.setAttribute('data-external-skill-refresh', skill.skillId); setI18nText(refresh, 'externalSkillsRefresh'); refresh.disabled = state.externalSkillsBusy; refresh.addEventListener('click', () => externalSkillAction(skill.skillId, 'refresh')); actions.append(refresh);
662
+ const action = skill.state === 'disabled' ? 'enable' : skill.state === 'imported' ? 'disable' : null;
663
+ if (action === 'disable' && state.externalSkillsPendingDisable === skill.skillId) {
664
+ const confirmation = document.createElement('div'); confirmation.className = 'notice'; confirmation.textContent = t('externalSkillsDisableConfirm');
665
+ const confirm = document.createElement('button'); confirm.type = 'button'; confirm.className = 'button primary'; confirm.setAttribute('data-external-skill-confirm', skill.skillId); setI18nText(confirm, 'externalSkillsDisable'); confirm.disabled = state.externalSkillsBusy; confirm.addEventListener('click', () => externalSkillAction(skill.skillId, action, true));
666
+ const cancel = document.createElement('button'); cancel.type = 'button'; cancel.className = 'button'; setI18nText(cancel, 'curatorCancel'); cancel.disabled = state.externalSkillsBusy; cancel.addEventListener('click', () => { state.externalSkillsPendingDisable = null; renderExternalSkills(); requestAnimationFrame(() => externalSkillButton('data-external-skill-toggle', skill.skillId)?.focus()); });
667
+ actions.append(confirmation, confirm, cancel);
668
+ } else if (action !== null) {
669
+ const toggle = document.createElement('button'); toggle.type = 'button'; toggle.className = 'button primary'; toggle.setAttribute('data-external-skill-toggle', skill.skillId); setI18nText(toggle, action === 'enable' ? 'externalSkillsEnable' : 'externalSkillsDisable'); toggle.disabled = state.externalSkillsBusy; toggle.addEventListener('click', () => externalSkillAction(skill.skillId, action)); actions.append(toggle);
670
+ }
671
+ const mapping = document.createElement('div'); mapping.className = 'detail-text'; mapping.hidden = true;
672
+ const viewEntries = document.createElement('button'); viewEntries.type = 'button'; viewEntries.className = 'button'; viewEntries.setAttribute('aria-expanded', 'false'); setI18nText(viewEntries, 'externalSkillsViewEntries'); viewEntries.disabled = state.externalSkillsBusy; viewEntries.addEventListener('click', async () => {
673
+ viewEntries.disabled = true;
674
+ try {
675
+ const detail = externalSkillDetail(await api('/api/skills/' + encodeURIComponent(skill.skillId)), skill.skillId);
676
+ if (detail === null) throw apiError({ error: { code: 'INVALID_RESPONSE', message: t('requestFailed') } });
677
+ const entries = detail.entries;
678
+ mapping.textContent = entries.length ? entries.map((entry) => entry.sourcePath + '#' + entry.chunkIndex + ' → ' + entry.entryId + '@' + entry.revision + (entry.active ? '' : ' (inactive)')).join('\n') : t('externalSkillsNoEntries');
679
+ mapping.hidden = false;
680
+ viewEntries.setAttribute('aria-expanded', 'true');
681
+ } catch {
682
+ mapping.textContent = '';
683
+ mapping.hidden = true;
684
+ viewEntries.setAttribute('aria-expanded', 'false');
685
+ setExternalSkillsStatus(t('externalSkillsFailure'), true);
686
+ }
687
+ finally { viewEntries.disabled = state.externalSkillsBusy; }
688
+ });
689
+ actions.append(viewEntries);
690
+ card.append(meta, heading, fields, notice, actions, mapping); return card;
691
+ }));
692
+ }
693
+ async function reloadExternalSkills() {
694
+ const skills = [];
695
+ const skillIds = new Set();
696
+ const cursors = new Set();
697
+ let cursor = null;
698
+ for (let page = 0; page < 100; page += 1) {
699
+ const result = await api('/api/skills?limit=200' + (cursor === null ? '' : '&cursor=' + encodeURIComponent(cursor)));
700
+ if (!result || typeof result !== 'object' || Array.isArray(result)
701
+ || Object.keys(result).length !== 5
702
+ || result.untrusted !== true
703
+ || !Array.isArray(result.skills) || result.skills.length > 200
704
+ || !Number.isSafeInteger(result.count) || result.count !== result.skills.length
705
+ || typeof result.truncated !== 'boolean'
706
+ || result.nextCursor !== null && typeof result.nextCursor !== 'string') throw apiError({ error: { code: 'INVALID_RESPONSE', message: t('requestFailed') } });
707
+ if (skills.length + result.skills.length > 20_000) throw apiError({ error: { code: 'INVALID_RESPONSE', message: t('requestFailed') } });
708
+ for (const skill of result.skills) {
709
+ if (!validExternalSkillListItem(skill) || skillIds.has(skill.skillId)) throw apiError({ error: { code: 'INVALID_RESPONSE', message: t('requestFailed') } });
710
+ skillIds.add(skill.skillId); skills.push(skill);
711
+ }
712
+ if (!result.truncated) {
713
+ if (result.nextCursor !== null) throw apiError({ error: { code: 'INVALID_RESPONSE', message: t('requestFailed') } });
714
+ state.externalSkills = skills;
715
+ renderExternalSkills();
716
+ return;
717
+ }
718
+ if (result.skills.length === 0 || typeof result.nextCursor !== 'string' || result.nextCursor.length === 0 || cursors.has(result.nextCursor)) throw apiError({ error: { code: 'INVALID_RESPONSE', message: t('requestFailed') } });
719
+ cursors.add(result.nextCursor); cursor = result.nextCursor;
720
+ }
721
+ throw apiError({ error: { code: 'INVALID_RESPONSE', message: t('requestFailed') } });
722
+ }
723
+ function externalSkillDetail(result, expectedSkillId) {
724
+ if (!result || typeof result !== 'object' || Array.isArray(result)
725
+ || Object.keys(result).length !== 4 || result.untrusted !== true
726
+ || !validExternalSkillListItem(result.skill) || result.skill.skillId !== expectedSkillId
727
+ || !Array.isArray(result.entries) || result.entries.length > 200
728
+ || typeof result.entriesTruncated !== 'boolean'
729
+ || result.entriesTruncated && result.entries.length !== 200
730
+ || result.skill.sourceCommit === null && result.entries.length !== 0) return null;
731
+ const entryIds = new Set(); const mappingIds = new Set();
732
+ for (const entry of result.entries) {
733
+ const mappingId = validExternalSkillEntrySummary(entry) ? entry.sourcePath + '\u0000' + entry.chunkIndex : null;
734
+ if (mappingId === null || entryIds.has(entry.entryId) || mappingIds.has(mappingId)) return null;
735
+ entryIds.add(entry.entryId); mappingIds.add(mappingId);
736
+ }
737
+ return { skill: result.skill, entries: result.entries, entriesTruncated: result.entriesTruncated };
738
+ }
739
+ async function reloadExternalSkill(skillId) {
740
+ const detail = externalSkillDetail(await api('/api/skills/' + encodeURIComponent(skillId)), skillId);
741
+ if (detail === null) throw apiError({ error: { code: 'INVALID_RESPONSE', message: t('requestFailed') } });
742
+ const index = state.externalSkills.findIndex((skill) => skill.skillId === skillId);
743
+ if (index < 0) throw apiError({ error: { code: 'INVALID_RESPONSE', message: t('requestFailed') } });
744
+ state.externalSkills[index] = detail.skill;
745
+ renderExternalSkills();
746
+ }
747
+ async function externalSkillAction(skillId, action, confirmed = false) {
748
+ if (state.externalSkillsBusy) return;
749
+ if (action === 'disable' && !confirmed) { state.externalSkillsPendingDisable = skillId; renderExternalSkills(); requestAnimationFrame(() => externalSkillButton('data-external-skill-confirm', skillId)?.focus()); return; }
750
+ state.externalSkillsPendingDisable = null;
751
+ state.externalSkillsBusy = true;
752
+ $('external-skills-refresh').disabled = true;
753
+ $('external-skills-panel').setAttribute('aria-busy', 'true');
754
+ setExternalSkillsStatus(action === 'refresh' ? t('externalSkillsRefreshing') : t('externalSkillsLoading'));
755
+ renderExternalSkills();
756
+ try {
757
+ let actionError = null;
758
+ try {
759
+ await api('/api/skills/' + encodeURIComponent(skillId) + '/' + action, { method: 'POST' });
760
+ } catch (error) {
761
+ actionError = error;
762
+ }
763
+ let reloadError = null;
764
+ try {
765
+ await reloadExternalSkill(skillId);
766
+ } catch (error) {
767
+ reloadError = error;
768
+ }
769
+ if (reloadError) {
770
+ state.externalSkills = [];
771
+ state.externalSkillsPendingDisable = null;
772
+ }
773
+ if (actionError) {
774
+ const reloadFailure = reloadError ? ' / ' + apiErrorText(reloadError) : '';
775
+ setExternalSkillsStatus(apiErrorText(actionError) + reloadFailure, true);
776
+ } else if (reloadError) {
777
+ setExternalSkillsStatus(apiErrorText(reloadError), true);
778
+ } else {
779
+ setExternalSkillsStatus(t(action === 'disable' ? 'externalSkillsDisabled' : action === 'enable' ? 'externalSkillsEnabled' : 'externalSkillsRefreshed'));
780
+ }
781
+ } finally {
782
+ state.externalSkillsBusy = false;
783
+ $('external-skills-refresh').disabled = false;
784
+ $('external-skills-panel').removeAttribute('aria-busy');
785
+ renderExternalSkills();
786
+ requestAnimationFrame(() => externalSkillButton(action === 'refresh' ? 'data-external-skill-refresh' : 'data-external-skill-toggle', skillId)?.focus());
787
+ }
788
+ }
789
+ async function loadExternalSkills(open = true) {
790
+ if (state.externalSkillsBusy) return;
791
+ if (open) openExternalSkills();
792
+ state.externalSkills = [];
793
+ state.externalSkillsPendingDisable = null;
794
+ state.externalSkillsBusy = true;
795
+ $('external-skills-refresh').disabled = true;
796
+ renderExternalSkills();
797
+ setExternalSkillsStatus(t('externalSkillsLoading'));
798
+ $('external-skills-panel').setAttribute('aria-busy', 'true');
799
+ try {
800
+ await reloadExternalSkills();
801
+ setExternalSkillsStatus('');
802
+ } catch (error) {
803
+ setExternalSkillsStatus(t('externalSkillsOffline') + ' ' + apiErrorText(error), true);
804
+ } finally {
805
+ $('external-skills-panel').removeAttribute('aria-busy');
806
+ state.externalSkillsBusy = false;
807
+ $('external-skills-refresh').disabled = false;
808
+ renderExternalSkills();
809
+ }
810
+ }
811
+
440
812
  function filterButton(key, label, count, active, onClick) {
441
813
  const button = document.createElement('button');
442
814
  button.type = 'button';
@@ -862,13 +1234,17 @@ export const WEB_HTML = String.raw `<!doctype html>
862
1234
  });
863
1235
  document.addEventListener('click', (event) => { if (!$('language-picker')?.contains(event.target)) setLanguageMenuOpen(false); });
864
1236
  document.addEventListener('focusin', (event) => { if (!$('language-picker')?.contains(event.target)) setLanguageMenuOpen(false); });
865
- $('workspace').addEventListener('change', (event) => { if (state.curatorOpen) closeCurator(); state.workspace = event.target.value; state.selected = null; state.selectedRecall = null; state.selectedRun = null; state.runs = []; state.tag = ''; state.curatorCandidates = []; state.curatorGlobalized = new Set(); state.curatorNextCursor = null; state.curatorTotalApproximate = 0; state.curatorOpen = false; loadTags().then(loadEntries).then(loadRuns); });
1237
+ $('workspace').addEventListener('change', (event) => { if (state.curatorOpen) closeCurator(); if (state.externalSkillsOpen) closeExternalSkills(); state.workspace = event.target.value; state.selected = null; state.selectedRecall = null; state.selectedRun = null; state.runs = []; state.tag = ''; state.curatorCandidates = []; state.curatorGlobalized = new Set(); state.curatorNextCursor = null; state.curatorTotalApproximate = 0; state.curatorOpen = false; loadTags().then(loadEntries).then(loadRuns); });
866
1238
  $('curator-button').addEventListener('click', () => loadCurator());
867
1239
  $('curator-close').addEventListener('click', () => closeCurator());
1240
+ $('external-skills-button').addEventListener('click', () => loadExternalSkills());
1241
+ $('external-skills-close').addEventListener('click', () => closeExternalSkills());
1242
+ $('external-skills-refresh').addEventListener('click', () => loadExternalSkills(false));
868
1243
  $('curator-confirm-cancel').addEventListener('click', () => closeCuratorConfirmation());
869
1244
  $('curator-confirm-submit').addEventListener('click', () => globalizePendingCurator());
870
1245
  $('curator-confirm-modal').addEventListener('keydown', handleCuratorConfirmationKeydown);
871
1246
  $('curator-modal').addEventListener('keydown', handleCuratorKeydown);
1247
+ $('external-skills-modal').addEventListener('keydown', handleExternalSkillsKeydown);
872
1248
  window.addEventListener('popstate', () => { restoreCuratorUrl(); if (state.curatorOpen) loadCurator(); });
873
1249
  $('refresh').addEventListener('click', () => loadWorkspaces());
874
1250
  let searchTimer; $('search').addEventListener('input', (event) => { clearTimeout(searchTimer); state.query = event.target.value.trim(); searchTimer = setTimeout(() => loadEntries(), 180); });
@@ -1 +1 @@
1
- {"version":3,"file":"ui.js","sourceRoot":"","sources":["../../src/web/ui.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAE7F,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC;IACrC,aAAa,EAAE,kBAAkB;IACjC,YAAY,EAAE,iBAAiB;IAC/B,OAAO,EAAE,WAAW;IACpB,QAAQ,EAAE,YAAY;CACvB,CAAC;KACC,UAAU,CAAC,GAAG,EAAE,SAAS,CAAC;KAC1B,UAAU,CAAC,GAAG,EAAE,SAAS,CAAC;KAC1B,UAAU,CAAC,GAAG,EAAE,SAAS,CAAC;KAC1B,UAAU,CAAC,QAAQ,EAAE,SAAS,CAAC;KAC/B,UAAU,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;AAEnC,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAqOf,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA6nB1B,CAAC"}
1
+ {"version":3,"file":"ui.js","sourceRoot":"","sources":["../../src/web/ui.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAE7F,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC;IACrC,aAAa,EAAE,kBAAkB;IACjC,YAAY,EAAE,iBAAiB;IAC/B,OAAO,EAAE,WAAW;IACpB,QAAQ,EAAE,YAAY;CACvB,CAAC;KACC,UAAU,CAAC,GAAG,EAAE,SAAS,CAAC;KAC1B,UAAU,CAAC,GAAG,EAAE,SAAS,CAAC;KAC1B,UAAU,CAAC,GAAG,EAAE,SAAS,CAAC;KAC1B,UAAU,CAAC,QAAQ,EAAE,SAAS,CAAC;KAC/B,UAAU,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;AAEnC,gFAAgF;AAChF,MAAM,UAAU,4BAA4B,CAAC,KAAc;IACzD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACtF,MAAM,KAAK,GAAG,KAAgC,CAAC;IAC/C,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC;QACrB,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY;QAClF,gBAAgB,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,EAAE,iBAAiB,EAAE,cAAc;QACrF,cAAc,EAAE,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY;QACpF,eAAe,EAAE,YAAY;KAC9B,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,CAAC,IAAa,EAAE,OAAe,EAAkB,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ;WACpF,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,IAAI,OAAO,IAAI,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChH,MAAM,SAAS,GAAG,CAAC,IAAa,EAAkB,EAAE;QAClD,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAChC,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC;IAC5E,CAAC,CAAC;IACF,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;IAChC,MAAM,aAAa,GAAG,KAAK,CAAC,aAAa,CAAC;IAC1C,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;IACxB,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;IACxC,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;IACxC,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;IACpC,MAAM,cAAc,GAAG,KAAK,CAAC,cAAc,CAAC;IAC5C,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAC1B,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC;IACtC,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;WAClG,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;WACpG,KAAK,CAAC,UAAU,KAAK,QAAQ;WAC7B,OAAO,aAAa,KAAK,QAAQ,IAAI,CAAC,2CAA2C,CAAC,IAAI,CAAC,aAAa,CAAC;WACrG,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,4BAA4B,CAAC,IAAI,CAAC,IAAI,CAAC;WACpE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,EAAE,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,IAAI,CAAC;WAC5E,KAAK,CAAC,OAAO,KAAK,UAAU,aAAa,IAAI,IAAI,EAAE;WACnD,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC;WACtB,KAAK,CAAC,UAAU,KAAK,IAAI,IAAI,KAAK,CAAC,UAAU,KAAK,sBAAsB,aAAa,EAAE;WACvF,OAAO,cAAc,KAAK,QAAQ;WAClC,CAAC,CAAC,SAAS,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,eAAe,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC;WACvG,OAAO,KAAK,CAAC,SAAS,KAAK,SAAS;WACpC,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC;WACjG,OAAO,KAAK,KAAK,QAAQ;WACzB,CAAC,CAAC,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;WAC3E,CAAC,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,GAAG,CAAC;WACjC,YAAY,KAAK,IAAI,IAAI,CAAC,OAAO,YAAY,KAAK,QAAQ,IAAI,CAAC,kCAAkC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;WACrH,YAAY,KAAK,IAAI,IAAI,CAAC,OAAO,YAAY,KAAK,QAAQ,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;WACpG,CAAC,YAAY,KAAK,IAAI,CAAC,KAAK,CAAC,YAAY,KAAK,IAAI,CAAC;WACnD,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;WAC5E,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,YAAY,CAAC;WACrH,OAAQ,QAAoC,CAAC,SAAS,KAAK,QAAQ;WACnE,CAAC,MAAM,CAAC,aAAa,CAAE,QAAoC,CAAC,SAAS,CAAC;WACpE,QAAoC,CAAC,SAAoB,GAAG,CAAC;WAC7D,QAAoC,CAAC,SAAoB,GAAG,EAAE;WAC/D,QAAoC,CAAC,UAAU,KAAK,IAAI,IAAI,CAAC,IAAI,CAAE,QAAoC,CAAC,UAAU,EAAE,GAAG,CAAC;WACzH,OAAO,WAAW,KAAK,QAAQ;WAC/B,CAAC,CAAC,cAAc,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC;WAC1E,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,KAAK,CAAC,UAAU,GAAG,CAAC;WACvG,CAAC,SAAS,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,aAAa,CAAC;WAChG,UAAU,KAAK,IAAI,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC;WAC5C,KAAK,CAAC,WAAsB,GAAI,KAAK,CAAC,UAAqB;WAC3D,KAAK,CAAC,WAAsB,GAAI,KAAK,CAAC,aAAwB;WAC/D,UAAU,KAAK,IAAI,IAAI,UAAU,GAAI,KAAK,CAAC,WAAsB;WACjE,YAAY,KAAK,IAAI,IAAI,CAAC,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,UAAU,KAAK,IAAI,CAAC;WAC1F,YAAY,KAAK,IAAI,IAAI,CAAC,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;WACtF,KAAK,KAAK,UAAU,IAAI,UAAU,KAAK,IAAI;WAC3C,KAAK,KAAK,UAAU,IAAI,UAAU,KAAK,IAAI;WAC3C,YAAY,KAAK,IAAI,IAAI,CAAE,QAAoC,CAAC,SAAS,KAAK,CAAC,IAAK,QAAoC,CAAC,UAAU,KAAK,IAAI,CAAC;WAC7I,YAAY,KAAK,IAAI,IAAI,CAAE,QAAoC,CAAC,SAAS,KAAK,CAAC,IAAI,CAAC,IAAI,CAAE,QAAoC,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACpK,OAAO,IAAI,CAAC;AACd,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,gCAAgC,CAAC,KAAc;IAC7D,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACtF,MAAM,KAAK,GAAG,KAAgC,CAAC;IAC/C,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC;IACjG,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,IAAI;WAC3C,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;WACtD,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,IAAI,GAAG,IAAI,KAAK,CAAC,OAAO,KAAK,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE;WACvI,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ,IAAI,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,QAAQ,IAAI,CAAC;WACjG,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,IAAI,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,IAAI,KAAK;WACxG,sBAAsB,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC;WAClF,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,EAAE,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,IAAI,CAAC;WACzF,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ,IAAI,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,KAAK,CAAC,UAAU,IAAI,CAAC;WACvG,OAAO,KAAK,CAAC,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC;AAC/E,CAAC;AAED,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBA8Pf,eAAe;0CACQ,4BAA4B,CAAC,QAAQ,EAAE;8CACnC,gCAAgC,CAAC,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAm4BjF,CAAC"}
@@ -0,0 +1,126 @@
1
+ CREATE TABLE external_skill_generation_clock (
2
+ singleton INTEGER PRIMARY KEY CHECK (singleton = 1),
3
+ value INTEGER NOT NULL CHECK (typeof(value) = 'integer' AND value BETWEEN 0 AND 9007199254740991)
4
+ );
5
+
6
+ INSERT INTO external_skill_generation_clock (singleton, value) VALUES (1, 0);
7
+
8
+ CREATE TABLE external_skill_generation_tokens (
9
+ generation INTEGER PRIMARY KEY AUTOINCREMENT
10
+ CHECK (typeof(generation) = 'integer' AND generation BETWEEN 1 AND 9007199254740991)
11
+ );
12
+
13
+ CREATE TABLE external_skills (
14
+ skill_id TEXT PRIMARY KEY,
15
+ generation INTEGER NOT NULL REFERENCES external_skill_generation_tokens(generation)
16
+ CHECK (typeof(generation) = 'integer' AND generation BETWEEN 1 AND 9007199254740991),
17
+ provider TEXT NOT NULL,
18
+ source_type TEXT NOT NULL CHECK (source_type = 'github'),
19
+ source_locator TEXT NOT NULL,
20
+ slug TEXT NOT NULL,
21
+ name TEXT NOT NULL,
22
+ install_url TEXT,
23
+ official_status TEXT NOT NULL CHECK (official_status IN ('curated', 'catalog-verified', 'owner-verified', 'registry-only', 'unknown')),
24
+ duplicate INTEGER NOT NULL DEFAULT 0 CHECK (duplicate IN (0, 1)),
25
+ installs INTEGER NOT NULL DEFAULT 0 CHECK (installs >= 0),
26
+ state TEXT NOT NULL CHECK (state IN ('discovered', 'imported', 'blocked', 'stale', 'disabled')),
27
+ source_workspace TEXT NOT NULL,
28
+ source_commit TEXT,
29
+ snapshot_hash TEXT,
30
+ metadata_json TEXT NOT NULL DEFAULT '{}',
31
+ first_seen_at TEXT NOT NULL,
32
+ last_seen_at TEXT NOT NULL,
33
+ last_checked_at TEXT NOT NULL,
34
+ disabled_at TEXT,
35
+ UNIQUE(generation),
36
+ UNIQUE(source_type, source_locator, slug)
37
+ );
38
+
39
+ CREATE INDEX idx_external_skills_state_checked ON external_skills(state, last_checked_at DESC);
40
+ CREATE INDEX idx_external_skills_source ON external_skills(source_locator, slug);
41
+
42
+ CREATE TABLE external_skill_entries (
43
+ skill_id TEXT NOT NULL REFERENCES external_skills(skill_id) ON DELETE CASCADE,
44
+ source_path TEXT NOT NULL,
45
+ chunk_index INTEGER NOT NULL CHECK (chunk_index >= 0),
46
+ entry_id TEXT NOT NULL REFERENCES entries(id),
47
+ entry_revision INTEGER NOT NULL CHECK (entry_revision > 0),
48
+ content_hash TEXT NOT NULL,
49
+ primary_document INTEGER NOT NULL DEFAULT 0 CHECK (primary_document IN (0, 1)),
50
+ active INTEGER NOT NULL DEFAULT 1 CHECK (active IN (0, 1)),
51
+ imported_at TEXT NOT NULL,
52
+ PRIMARY KEY(skill_id, source_path, chunk_index),
53
+ FOREIGN KEY(entry_id, entry_revision) REFERENCES entry_revisions(entry_id, revision)
54
+ );
55
+
56
+ CREATE INDEX idx_external_skill_entries_entry ON external_skill_entries(entry_id, entry_revision);
57
+
58
+ CREATE TABLE skill_discovery_cache (
59
+ cache_key TEXT PRIMARY KEY,
60
+ provider TEXT NOT NULL,
61
+ query_text TEXT NOT NULL,
62
+ owner TEXT,
63
+ mode TEXT NOT NULL CHECK (mode IN ('official', 'community')),
64
+ outcome TEXT NOT NULL CHECK (outcome IN ('success', 'empty', 'rate_limited', 'unavailable')),
65
+ response_json TEXT NOT NULL,
66
+ fetched_at TEXT NOT NULL,
67
+ expires_at TEXT NOT NULL
68
+ );
69
+
70
+ CREATE INDEX idx_skill_discovery_cache_expiry ON skill_discovery_cache(expires_at);
71
+
72
+ CREATE TABLE skill_source_failure_cache (
73
+ cache_key TEXT PRIMARY KEY,
74
+ source_type TEXT NOT NULL CHECK (source_type = 'github'),
75
+ source_locator TEXT NOT NULL,
76
+ slug TEXT NOT NULL,
77
+ outcome TEXT NOT NULL CHECK (outcome IN ('source_rate_limited', 'source_unavailable')),
78
+ fetched_at TEXT NOT NULL,
79
+ expires_at TEXT NOT NULL
80
+ );
81
+
82
+ CREATE INDEX idx_skill_source_failure_cache_expiry ON skill_source_failure_cache(expires_at);
83
+
84
+ CREATE TABLE skill_audit_failure_cache (
85
+ cache_key TEXT PRIMARY KEY,
86
+ provider TEXT NOT NULL,
87
+ source_type TEXT NOT NULL CHECK (source_type = 'github'),
88
+ source_locator TEXT NOT NULL,
89
+ slug TEXT NOT NULL,
90
+ outcome TEXT NOT NULL CHECK (outcome IN ('registry_rate_limited', 'registry_unavailable')),
91
+ fetched_at TEXT NOT NULL,
92
+ expires_at TEXT NOT NULL
93
+ );
94
+
95
+ CREATE INDEX idx_skill_audit_failure_cache_expiry ON skill_audit_failure_cache(expires_at);
96
+
97
+ CREATE TABLE agent_task_skill_discovery_attempts (
98
+ run_id TEXT PRIMARY KEY REFERENCES ledger_runs(run_id) ON DELETE CASCADE,
99
+ request_digest TEXT NOT NULL CHECK (
100
+ typeof(request_digest) = 'text'
101
+ AND length(request_digest) = 64
102
+ AND request_digest NOT GLOB '*[^0-9a-f]*'
103
+ ),
104
+ state TEXT NOT NULL CHECK (state IN ('started', 'completed', 'failed')),
105
+ summary_json TEXT,
106
+ failure_json TEXT,
107
+ started_at TEXT NOT NULL CHECK (typeof(started_at) = 'text' AND length(started_at) > 0),
108
+ finished_at TEXT,
109
+ CHECK (
110
+ finished_at IS NULL
111
+ OR (typeof(finished_at) = 'text' AND length(finished_at) > 0 AND finished_at >= started_at)
112
+ ),
113
+ CHECK (
114
+ (state = 'started' AND summary_json IS NULL AND failure_json IS NULL AND finished_at IS NULL)
115
+ OR (state = 'completed' AND typeof(summary_json) = 'text' AND failure_json IS NULL AND finished_at IS NOT NULL)
116
+ OR (state = 'failed' AND summary_json IS NULL AND typeof(failure_json) = 'text' AND finished_at IS NOT NULL)
117
+ )
118
+ );
119
+
120
+ -- The application migration operation rewrites every revision preimage and
121
+ -- hash to the single locale-independent canonical representation before it
122
+ -- inserts this singleton. Leaving the row absent is never a supported state.
123
+ CREATE TABLE entry_revision_hash_format (
124
+ singleton INTEGER PRIMARY KEY CHECK (singleton = 1),
125
+ algorithm TEXT NOT NULL CHECK (algorithm = 'canonical-json-utf16-tags-v1')
126
+ );