kiokuko-dsh 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1032) hide show
  1. package/LICENSE +21 -0
  2. package/README.ja.md +50 -0
  3. package/README.ko.md +50 -0
  4. package/README.md +53 -0
  5. package/README.zh-CN.md +50 -0
  6. package/dist/agent-file/atomic-write.d.ts +93 -0
  7. package/dist/agent-file/atomic-write.d.ts.map +1 -0
  8. package/dist/agent-file/atomic-write.js +1026 -0
  9. package/dist/agent-file/atomic-write.js.map +1 -0
  10. package/dist/agent-file/managed-block.d.ts +23 -0
  11. package/dist/agent-file/managed-block.d.ts.map +1 -0
  12. package/dist/agent-file/managed-block.js +101 -0
  13. package/dist/agent-file/managed-block.js.map +1 -0
  14. package/dist/agent-file/render.d.ts +14 -0
  15. package/dist/agent-file/render.d.ts.map +1 -0
  16. package/dist/agent-file/render.js +63 -0
  17. package/dist/agent-file/render.js.map +1 -0
  18. package/dist/akinator/agent-task.d.ts +72 -0
  19. package/dist/akinator/agent-task.d.ts.map +1 -0
  20. package/dist/akinator/agent-task.js +684 -0
  21. package/dist/akinator/agent-task.js.map +1 -0
  22. package/dist/akinator/capabilities.d.ts +92 -0
  23. package/dist/akinator/capabilities.d.ts.map +1 -0
  24. package/dist/akinator/capabilities.js +364 -0
  25. package/dist/akinator/capabilities.js.map +1 -0
  26. package/dist/akinator/capability-binding.d.ts +11 -0
  27. package/dist/akinator/capability-binding.d.ts.map +1 -0
  28. package/dist/akinator/capability-binding.js +71 -0
  29. package/dist/akinator/capability-binding.js.map +1 -0
  30. package/dist/akinator/domain.d.ts +25 -0
  31. package/dist/akinator/domain.d.ts.map +1 -0
  32. package/dist/akinator/domain.js +266 -0
  33. package/dist/akinator/domain.js.map +1 -0
  34. package/dist/akinator/knowledge-path.d.ts +33 -0
  35. package/dist/akinator/knowledge-path.d.ts.map +1 -0
  36. package/dist/akinator/knowledge-path.js +474 -0
  37. package/dist/akinator/knowledge-path.js.map +1 -0
  38. package/dist/akinator/orchestrator.d.ts +7 -0
  39. package/dist/akinator/orchestrator.d.ts.map +1 -0
  40. package/dist/akinator/orchestrator.js +8 -0
  41. package/dist/akinator/orchestrator.js.map +1 -0
  42. package/dist/akinator/reasoning.d.ts +8 -0
  43. package/dist/akinator/reasoning.d.ts.map +1 -0
  44. package/dist/akinator/reasoning.js +118 -0
  45. package/dist/akinator/reasoning.js.map +1 -0
  46. package/dist/akinator/service.d.ts +32 -0
  47. package/dist/akinator/service.d.ts.map +1 -0
  48. package/dist/akinator/service.js +294 -0
  49. package/dist/akinator/service.js.map +1 -0
  50. package/dist/akinator/skill-discovery-attempt.d.ts +26 -0
  51. package/dist/akinator/skill-discovery-attempt.d.ts.map +1 -0
  52. package/dist/akinator/skill-discovery-attempt.js +469 -0
  53. package/dist/akinator/skill-discovery-attempt.js.map +1 -0
  54. package/dist/akinator/store.d.ts +96 -0
  55. package/dist/akinator/store.d.ts.map +1 -0
  56. package/dist/akinator/store.js +642 -0
  57. package/dist/akinator/store.js.map +1 -0
  58. package/dist/akinator/types.d.ts +70 -0
  59. package/dist/akinator/types.d.ts.map +1 -0
  60. package/dist/akinator/types.js +2 -0
  61. package/dist/akinator/types.js.map +1 -0
  62. package/dist/bin/kiokuko.d.ts +3 -0
  63. package/dist/bin/kiokuko.d.ts.map +1 -0
  64. package/dist/bin/kiokuko.js +13 -0
  65. package/dist/bin/kiokuko.js.map +1 -0
  66. package/dist/cli.d.ts +24 -0
  67. package/dist/cli.d.ts.map +1 -0
  68. package/dist/cli.js +962 -0
  69. package/dist/cli.js.map +1 -0
  70. package/dist/client/server-client.d.ts +22 -0
  71. package/dist/client/server-client.d.ts.map +1 -0
  72. package/dist/client/server-client.js +729 -0
  73. package/dist/client/server-client.js.map +1 -0
  74. package/dist/commands/agent.d.ts +12 -0
  75. package/dist/commands/agent.d.ts.map +1 -0
  76. package/dist/commands/agent.js +1138 -0
  77. package/dist/commands/agent.js.map +1 -0
  78. package/dist/commands/backup.d.ts +6 -0
  79. package/dist/commands/backup.d.ts.map +1 -0
  80. package/dist/commands/backup.js +77 -0
  81. package/dist/commands/backup.js.map +1 -0
  82. package/dist/commands/curator.d.ts +25 -0
  83. package/dist/commands/curator.d.ts.map +1 -0
  84. package/dist/commands/curator.js +58 -0
  85. package/dist/commands/curator.js.map +1 -0
  86. package/dist/commands/doctor.d.ts +61 -0
  87. package/dist/commands/doctor.d.ts.map +1 -0
  88. package/dist/commands/doctor.js +522 -0
  89. package/dist/commands/doctor.js.map +1 -0
  90. package/dist/commands/embeddings.d.ts +40 -0
  91. package/dist/commands/embeddings.d.ts.map +1 -0
  92. package/dist/commands/embeddings.js +317 -0
  93. package/dist/commands/embeddings.js.map +1 -0
  94. package/dist/commands/enno.d.ts +7 -0
  95. package/dist/commands/enno.d.ts.map +1 -0
  96. package/dist/commands/enno.js +76 -0
  97. package/dist/commands/enno.js.map +1 -0
  98. package/dist/commands/export.d.ts +17 -0
  99. package/dist/commands/export.d.ts.map +1 -0
  100. package/dist/commands/export.js +233 -0
  101. package/dist/commands/export.js.map +1 -0
  102. package/dist/commands/import.d.ts +24 -0
  103. package/dist/commands/import.d.ts.map +1 -0
  104. package/dist/commands/import.js +778 -0
  105. package/dist/commands/import.js.map +1 -0
  106. package/dist/commands/init.d.ts +34 -0
  107. package/dist/commands/init.d.ts.map +1 -0
  108. package/dist/commands/init.js +637 -0
  109. package/dist/commands/init.js.map +1 -0
  110. package/dist/commands/ledger.d.ts +7 -0
  111. package/dist/commands/ledger.d.ts.map +1 -0
  112. package/dist/commands/ledger.js +66 -0
  113. package/dist/commands/ledger.js.map +1 -0
  114. package/dist/commands/purge.d.ts +10 -0
  115. package/dist/commands/purge.d.ts.map +1 -0
  116. package/dist/commands/purge.js +29 -0
  117. package/dist/commands/purge.js.map +1 -0
  118. package/dist/commands/serve.d.ts +34 -0
  119. package/dist/commands/serve.d.ts.map +1 -0
  120. package/dist/commands/serve.js +120 -0
  121. package/dist/commands/serve.js.map +1 -0
  122. package/dist/commands/server-status.d.ts +20 -0
  123. package/dist/commands/server-status.d.ts.map +1 -0
  124. package/dist/commands/server-status.js +21 -0
  125. package/dist/commands/server-status.js.map +1 -0
  126. package/dist/commands/server.d.ts +13 -0
  127. package/dist/commands/server.d.ts.map +1 -0
  128. package/dist/commands/server.js +89 -0
  129. package/dist/commands/server.js.map +1 -0
  130. package/dist/commands/setup.d.ts +105 -0
  131. package/dist/commands/setup.d.ts.map +1 -0
  132. package/dist/commands/setup.js +793 -0
  133. package/dist/commands/setup.js.map +1 -0
  134. package/dist/commands/skills.d.ts +9 -0
  135. package/dist/commands/skills.d.ts.map +1 -0
  136. package/dist/commands/skills.js +317 -0
  137. package/dist/commands/skills.js.map +1 -0
  138. package/dist/commands/use.d.ts +40 -0
  139. package/dist/commands/use.d.ts.map +1 -0
  140. package/dist/commands/use.js +1090 -0
  141. package/dist/commands/use.js.map +1 -0
  142. package/dist/config/paths.d.ts +57 -0
  143. package/dist/config/paths.d.ts.map +1 -0
  144. package/dist/config/paths.js +352 -0
  145. package/dist/config/paths.js.map +1 -0
  146. package/dist/config/project-config.d.ts +11 -0
  147. package/dist/config/project-config.d.ts.map +1 -0
  148. package/dist/config/project-config.js +97 -0
  149. package/dist/config/project-config.js.map +1 -0
  150. package/dist/context/broker.d.ts +99 -0
  151. package/dist/context/broker.d.ts.map +1 -0
  152. package/dist/context/broker.js +923 -0
  153. package/dist/context/broker.js.map +1 -0
  154. package/dist/context/delivery-migration.d.ts +40 -0
  155. package/dist/context/delivery-migration.d.ts.map +1 -0
  156. package/dist/context/delivery-migration.js +367 -0
  157. package/dist/context/delivery-migration.js.map +1 -0
  158. package/dist/context/delivery.d.ts +61 -0
  159. package/dist/context/delivery.d.ts.map +1 -0
  160. package/dist/context/delivery.js +886 -0
  161. package/dist/context/delivery.js.map +1 -0
  162. package/dist/context/feedback.d.ts +73 -0
  163. package/dist/context/feedback.d.ts.map +1 -0
  164. package/dist/context/feedback.js +993 -0
  165. package/dist/context/feedback.js.map +1 -0
  166. package/dist/context/nudge-store.d.ts +57 -0
  167. package/dist/context/nudge-store.d.ts.map +1 -0
  168. package/dist/context/nudge-store.js +227 -0
  169. package/dist/context/nudge-store.js.map +1 -0
  170. package/dist/context/nudge-validation.d.ts +26 -0
  171. package/dist/context/nudge-validation.d.ts.map +1 -0
  172. package/dist/context/nudge-validation.js +122 -0
  173. package/dist/context/nudge-validation.js.map +1 -0
  174. package/dist/context/nudges.d.ts +38 -0
  175. package/dist/context/nudges.d.ts.map +1 -0
  176. package/dist/context/nudges.js +131 -0
  177. package/dist/context/nudges.js.map +1 -0
  178. package/dist/context/origin.d.ts +9 -0
  179. package/dist/context/origin.d.ts.map +1 -0
  180. package/dist/context/origin.js +15 -0
  181. package/dist/context/origin.js.map +1 -0
  182. package/dist/context/ranking.d.ts +92 -0
  183. package/dist/context/ranking.d.ts.map +1 -0
  184. package/dist/context/ranking.js +560 -0
  185. package/dist/context/ranking.js.map +1 -0
  186. package/dist/context/recommendations.d.ts +80 -0
  187. package/dist/context/recommendations.d.ts.map +1 -0
  188. package/dist/context/recommendations.js +341 -0
  189. package/dist/context/recommendations.js.map +1 -0
  190. package/dist/context/run-state.d.ts +26 -0
  191. package/dist/context/run-state.d.ts.map +1 -0
  192. package/dist/context/run-state.js +399 -0
  193. package/dist/context/run-state.js.map +1 -0
  194. package/dist/context/scoped-broker.d.ts +77 -0
  195. package/dist/context/scoped-broker.d.ts.map +1 -0
  196. package/dist/context/scoped-broker.js +690 -0
  197. package/dist/context/scoped-broker.js.map +1 -0
  198. package/dist/context/selection-state.d.ts +32 -0
  199. package/dist/context/selection-state.d.ts.map +1 -0
  200. package/dist/context/selection-state.js +369 -0
  201. package/dist/context/selection-state.js.map +1 -0
  202. package/dist/db/adapter.d.ts +27 -0
  203. package/dist/db/adapter.d.ts.map +1 -0
  204. package/dist/db/adapter.js +41 -0
  205. package/dist/db/adapter.js.map +1 -0
  206. package/dist/db/capabilities.d.ts +21 -0
  207. package/dist/db/capabilities.d.ts.map +1 -0
  208. package/dist/db/capabilities.js +57 -0
  209. package/dist/db/capabilities.js.map +1 -0
  210. package/dist/db/connection.d.ts +21 -0
  211. package/dist/db/connection.d.ts.map +1 -0
  212. package/dist/db/connection.js +129 -0
  213. package/dist/db/connection.js.map +1 -0
  214. package/dist/db/migrate.d.ts +40 -0
  215. package/dist/db/migrate.d.ts.map +1 -0
  216. package/dist/db/migrate.js +216 -0
  217. package/dist/db/migrate.js.map +1 -0
  218. package/dist/db/sqlite-retry.d.ts +11 -0
  219. package/dist/db/sqlite-retry.d.ts.map +1 -0
  220. package/dist/db/sqlite-retry.js +70 -0
  221. package/dist/db/sqlite-retry.js.map +1 -0
  222. package/dist/db/transaction.d.ts +17 -0
  223. package/dist/db/transaction.d.ts.map +1 -0
  224. package/dist/db/transaction.js +68 -0
  225. package/dist/db/transaction.js.map +1 -0
  226. package/dist/db/upgrade-backup.d.ts +59 -0
  227. package/dist/db/upgrade-backup.d.ts.map +1 -0
  228. package/dist/db/upgrade-backup.js +773 -0
  229. package/dist/db/upgrade-backup.js.map +1 -0
  230. package/dist/dsh/advisory-runner.d.ts +32 -0
  231. package/dist/dsh/advisory-runner.d.ts.map +1 -0
  232. package/dist/dsh/advisory-runner.js +111 -0
  233. package/dist/dsh/advisory-runner.js.map +1 -0
  234. package/dist/dsh/agent-state.d.ts +49 -0
  235. package/dist/dsh/agent-state.d.ts.map +1 -0
  236. package/dist/dsh/agent-state.js +103 -0
  237. package/dist/dsh/agent-state.js.map +1 -0
  238. package/dist/dsh/capability-catalog.d.ts +24 -0
  239. package/dist/dsh/capability-catalog.d.ts.map +1 -0
  240. package/dist/dsh/capability-catalog.js +108 -0
  241. package/dist/dsh/capability-catalog.js.map +1 -0
  242. package/dist/dsh/commands.d.ts +43 -0
  243. package/dist/dsh/commands.d.ts.map +1 -0
  244. package/dist/dsh/commands.js +83 -0
  245. package/dist/dsh/commands.js.map +1 -0
  246. package/dist/dsh/composition.d.ts +64 -0
  247. package/dist/dsh/composition.d.ts.map +1 -0
  248. package/dist/dsh/composition.js +104 -0
  249. package/dist/dsh/composition.js.map +1 -0
  250. package/dist/dsh/config.d.ts +7 -0
  251. package/dist/dsh/config.d.ts.map +1 -0
  252. package/dist/dsh/config.js +6 -0
  253. package/dist/dsh/config.js.map +1 -0
  254. package/dist/dsh/context-injection.d.ts +24 -0
  255. package/dist/dsh/context-injection.d.ts.map +1 -0
  256. package/dist/dsh/context-injection.js +61 -0
  257. package/dist/dsh/context-injection.js.map +1 -0
  258. package/dist/dsh/enno-controller.d.ts +94 -0
  259. package/dist/dsh/enno-controller.d.ts.map +1 -0
  260. package/dist/dsh/enno-controller.js +137 -0
  261. package/dist/dsh/enno-controller.js.map +1 -0
  262. package/dist/dsh/index.d.ts +31 -0
  263. package/dist/dsh/index.d.ts.map +1 -0
  264. package/dist/dsh/index.js +52 -0
  265. package/dist/dsh/index.js.map +1 -0
  266. package/dist/dsh/intake-gate.d.ts +50 -0
  267. package/dist/dsh/intake-gate.d.ts.map +1 -0
  268. package/dist/dsh/intake-gate.js +77 -0
  269. package/dist/dsh/intake-gate.js.map +1 -0
  270. package/dist/dsh/intake-profile-resolver.d.ts +22 -0
  271. package/dist/dsh/intake-profile-resolver.d.ts.map +1 -0
  272. package/dist/dsh/intake-profile-resolver.js +44 -0
  273. package/dist/dsh/intake-profile-resolver.js.map +1 -0
  274. package/dist/dsh/message-sources.d.ts +28 -0
  275. package/dist/dsh/message-sources.d.ts.map +1 -0
  276. package/dist/dsh/message-sources.js +62 -0
  277. package/dist/dsh/message-sources.js.map +1 -0
  278. package/dist/dsh/parity.d.ts +18 -0
  279. package/dist/dsh/parity.d.ts.map +1 -0
  280. package/dist/dsh/parity.js +105 -0
  281. package/dist/dsh/parity.js.map +1 -0
  282. package/dist/dsh/prompt-policy.d.ts +18 -0
  283. package/dist/dsh/prompt-policy.d.ts.map +1 -0
  284. package/dist/dsh/prompt-policy.js +16 -0
  285. package/dist/dsh/prompt-policy.js.map +1 -0
  286. package/dist/dsh/runtime.d.ts +40 -0
  287. package/dist/dsh/runtime.d.ts.map +1 -0
  288. package/dist/dsh/runtime.js +237 -0
  289. package/dist/dsh/runtime.js.map +1 -0
  290. package/dist/dsh/session-bridge.d.ts +98 -0
  291. package/dist/dsh/session-bridge.d.ts.map +1 -0
  292. package/dist/dsh/session-bridge.js +202 -0
  293. package/dist/dsh/session-bridge.js.map +1 -0
  294. package/dist/dsh/standard-skill-provider.d.ts +50 -0
  295. package/dist/dsh/standard-skill-provider.d.ts.map +1 -0
  296. package/dist/dsh/standard-skill-provider.js +71 -0
  297. package/dist/dsh/standard-skill-provider.js.map +1 -0
  298. package/dist/dsh/tool-policy.d.ts +40 -0
  299. package/dist/dsh/tool-policy.d.ts.map +1 -0
  300. package/dist/dsh/tool-policy.js +125 -0
  301. package/dist/dsh/tool-policy.js.map +1 -0
  302. package/dist/dsh/tools.d.ts +85 -0
  303. package/dist/dsh/tools.d.ts.map +1 -0
  304. package/dist/dsh/tools.js +156 -0
  305. package/dist/dsh/tools.js.map +1 -0
  306. package/dist/dsh/user-interaction.d.ts +51 -0
  307. package/dist/dsh/user-interaction.d.ts.map +1 -0
  308. package/dist/dsh/user-interaction.js +92 -0
  309. package/dist/dsh/user-interaction.js.map +1 -0
  310. package/dist/embedding/backend.d.ts +27 -0
  311. package/dist/embedding/backend.d.ts.map +1 -0
  312. package/dist/embedding/backend.js +67 -0
  313. package/dist/embedding/backend.js.map +1 -0
  314. package/dist/embedding/config.d.ts +10 -0
  315. package/dist/embedding/config.d.ts.map +1 -0
  316. package/dist/embedding/config.js +142 -0
  317. package/dist/embedding/config.js.map +1 -0
  318. package/dist/embedding/diagnostics.d.ts +34 -0
  319. package/dist/embedding/diagnostics.d.ts.map +1 -0
  320. package/dist/embedding/diagnostics.js +274 -0
  321. package/dist/embedding/diagnostics.js.map +1 -0
  322. package/dist/embedding/document.d.ts +20 -0
  323. package/dist/embedding/document.d.ts.map +1 -0
  324. package/dist/embedding/document.js +122 -0
  325. package/dist/embedding/document.js.map +1 -0
  326. package/dist/embedding/javascript-backend.d.ts +11 -0
  327. package/dist/embedding/javascript-backend.d.ts.map +1 -0
  328. package/dist/embedding/javascript-backend.js +164 -0
  329. package/dist/embedding/javascript-backend.js.map +1 -0
  330. package/dist/embedding/jobs.d.ts +67 -0
  331. package/dist/embedding/jobs.d.ts.map +1 -0
  332. package/dist/embedding/jobs.js +259 -0
  333. package/dist/embedding/jobs.js.map +1 -0
  334. package/dist/embedding/local-model-loader.d.ts +24 -0
  335. package/dist/embedding/local-model-loader.d.ts.map +1 -0
  336. package/dist/embedding/local-model-loader.js +64 -0
  337. package/dist/embedding/local-model-loader.js.map +1 -0
  338. package/dist/embedding/local-transformers-provider.d.ts +17 -0
  339. package/dist/embedding/local-transformers-provider.d.ts.map +1 -0
  340. package/dist/embedding/local-transformers-provider.js +54 -0
  341. package/dist/embedding/local-transformers-provider.js.map +1 -0
  342. package/dist/embedding/model-download.d.ts +32 -0
  343. package/dist/embedding/model-download.d.ts.map +1 -0
  344. package/dist/embedding/model-download.js +41 -0
  345. package/dist/embedding/model-download.js.map +1 -0
  346. package/dist/embedding/model-installation.d.ts +17 -0
  347. package/dist/embedding/model-installation.d.ts.map +1 -0
  348. package/dist/embedding/model-installation.js +71 -0
  349. package/dist/embedding/model-installation.js.map +1 -0
  350. package/dist/embedding/model-manifest.d.ts +18 -0
  351. package/dist/embedding/model-manifest.d.ts.map +1 -0
  352. package/dist/embedding/model-manifest.js +86 -0
  353. package/dist/embedding/model-manifest.js.map +1 -0
  354. package/dist/embedding/openai-compatible-provider.d.ts +24 -0
  355. package/dist/embedding/openai-compatible-provider.d.ts.map +1 -0
  356. package/dist/embedding/openai-compatible-provider.js +330 -0
  357. package/dist/embedding/openai-compatible-provider.js.map +1 -0
  358. package/dist/embedding/presets/local-small.d.ts +8 -0
  359. package/dist/embedding/presets/local-small.d.ts.map +1 -0
  360. package/dist/embedding/presets/local-small.js +67 -0
  361. package/dist/embedding/presets/local-small.js.map +1 -0
  362. package/dist/embedding/presets/manifest.d.ts +27 -0
  363. package/dist/embedding/presets/manifest.d.ts.map +1 -0
  364. package/dist/embedding/presets/manifest.js +5 -0
  365. package/dist/embedding/presets/manifest.js.map +1 -0
  366. package/dist/embedding/profile.d.ts +10 -0
  367. package/dist/embedding/profile.d.ts.map +1 -0
  368. package/dist/embedding/profile.js +67 -0
  369. package/dist/embedding/profile.js.map +1 -0
  370. package/dist/embedding/provider.d.ts +13 -0
  371. package/dist/embedding/provider.d.ts.map +1 -0
  372. package/dist/embedding/provider.js +17 -0
  373. package/dist/embedding/provider.js.map +1 -0
  374. package/dist/embedding/query-cache.d.ts +45 -0
  375. package/dist/embedding/query-cache.d.ts.map +1 -0
  376. package/dist/embedding/query-cache.js +181 -0
  377. package/dist/embedding/query-cache.js.map +1 -0
  378. package/dist/embedding/runtime.d.ts +14 -0
  379. package/dist/embedding/runtime.d.ts.map +1 -0
  380. package/dist/embedding/runtime.js +407 -0
  381. package/dist/embedding/runtime.js.map +1 -0
  382. package/dist/embedding/settings.d.ts +6 -0
  383. package/dist/embedding/settings.d.ts.map +1 -0
  384. package/dist/embedding/settings.js +69 -0
  385. package/dist/embedding/settings.js.map +1 -0
  386. package/dist/embedding/setup-lock.d.ts +7 -0
  387. package/dist/embedding/setup-lock.d.ts.map +1 -0
  388. package/dist/embedding/setup-lock.js +35 -0
  389. package/dist/embedding/setup-lock.js.map +1 -0
  390. package/dist/embedding/setup-service.d.ts +53 -0
  391. package/dist/embedding/setup-service.d.ts.map +1 -0
  392. package/dist/embedding/setup-service.js +184 -0
  393. package/dist/embedding/setup-service.js.map +1 -0
  394. package/dist/embedding/sqlite-vec-backend.d.ts +9 -0
  395. package/dist/embedding/sqlite-vec-backend.d.ts.map +1 -0
  396. package/dist/embedding/sqlite-vec-backend.js +106 -0
  397. package/dist/embedding/sqlite-vec-backend.js.map +1 -0
  398. package/dist/embedding/sqlite-vec-loader.d.ts +17 -0
  399. package/dist/embedding/sqlite-vec-loader.d.ts.map +1 -0
  400. package/dist/embedding/sqlite-vec-loader.js +51 -0
  401. package/dist/embedding/sqlite-vec-loader.js.map +1 -0
  402. package/dist/embedding/store.d.ts +66 -0
  403. package/dist/embedding/store.d.ts.map +1 -0
  404. package/dist/embedding/store.js +490 -0
  405. package/dist/embedding/store.js.map +1 -0
  406. package/dist/embedding/types.d.ts +126 -0
  407. package/dist/embedding/types.d.ts.map +1 -0
  408. package/dist/embedding/types.js +2 -0
  409. package/dist/embedding/types.js.map +1 -0
  410. package/dist/embedding/vector.d.ts +9 -0
  411. package/dist/embedding/vector.d.ts.map +1 -0
  412. package/dist/embedding/vector.js +90 -0
  413. package/dist/embedding/vector.js.map +1 -0
  414. package/dist/embedding/worker.d.ts +23 -0
  415. package/dist/embedding/worker.d.ts.map +1 -0
  416. package/dist/embedding/worker.js +84 -0
  417. package/dist/embedding/worker.js.map +1 -0
  418. package/dist/enno-oduno/adapters.d.ts +21 -0
  419. package/dist/enno-oduno/adapters.d.ts.map +1 -0
  420. package/dist/enno-oduno/adapters.js +253 -0
  421. package/dist/enno-oduno/adapters.js.map +1 -0
  422. package/dist/enno-oduno/advisory-store.d.ts +31 -0
  423. package/dist/enno-oduno/advisory-store.d.ts.map +1 -0
  424. package/dist/enno-oduno/advisory-store.js +105 -0
  425. package/dist/enno-oduno/advisory-store.js.map +1 -0
  426. package/dist/enno-oduno/advisory.d.ts +18 -0
  427. package/dist/enno-oduno/advisory.d.ts.map +1 -0
  428. package/dist/enno-oduno/advisory.js +310 -0
  429. package/dist/enno-oduno/advisory.js.map +1 -0
  430. package/dist/enno-oduno/confirmation.d.ts +4 -0
  431. package/dist/enno-oduno/confirmation.d.ts.map +1 -0
  432. package/dist/enno-oduno/confirmation.js +127 -0
  433. package/dist/enno-oduno/confirmation.js.map +1 -0
  434. package/dist/enno-oduno/directives.d.ts +12 -0
  435. package/dist/enno-oduno/directives.d.ts.map +1 -0
  436. package/dist/enno-oduno/directives.js +276 -0
  437. package/dist/enno-oduno/directives.js.map +1 -0
  438. package/dist/enno-oduno/enno-oduno.d.mts +2 -0
  439. package/dist/enno-oduno/enno-oduno.d.mts.map +1 -0
  440. package/dist/enno-oduno/enno-oduno.mjs +3 -0
  441. package/dist/enno-oduno/enno-oduno.mjs.map +1 -0
  442. package/dist/enno-oduno/experts.d.ts +6 -0
  443. package/dist/enno-oduno/experts.d.ts.map +1 -0
  444. package/dist/enno-oduno/experts.js +32 -0
  445. package/dist/enno-oduno/experts.js.map +1 -0
  446. package/dist/enno-oduno/goki.d.mts +2 -0
  447. package/dist/enno-oduno/goki.d.mts.map +1 -0
  448. package/dist/enno-oduno/goki.mjs +3 -0
  449. package/dist/enno-oduno/goki.mjs.map +1 -0
  450. package/dist/enno-oduno/handoff.d.ts +4 -0
  451. package/dist/enno-oduno/handoff.d.ts.map +1 -0
  452. package/dist/enno-oduno/handoff.js +18 -0
  453. package/dist/enno-oduno/handoff.js.map +1 -0
  454. package/dist/enno-oduno/harness.d.ts +20 -0
  455. package/dist/enno-oduno/harness.d.ts.map +1 -0
  456. package/dist/enno-oduno/harness.js +66 -0
  457. package/dist/enno-oduno/harness.js.map +1 -0
  458. package/dist/enno-oduno/instructions.d.ts +9 -0
  459. package/dist/enno-oduno/instructions.d.ts.map +1 -0
  460. package/dist/enno-oduno/instructions.js +12 -0
  461. package/dist/enno-oduno/instructions.js.map +1 -0
  462. package/dist/enno-oduno/plan-recovery.d.ts +44 -0
  463. package/dist/enno-oduno/plan-recovery.d.ts.map +1 -0
  464. package/dist/enno-oduno/plan-recovery.js +160 -0
  465. package/dist/enno-oduno/plan-recovery.js.map +1 -0
  466. package/dist/enno-oduno/repository-state.d.ts +8 -0
  467. package/dist/enno-oduno/repository-state.d.ts.map +1 -0
  468. package/dist/enno-oduno/repository-state.js +139 -0
  469. package/dist/enno-oduno/repository-state.js.map +1 -0
  470. package/dist/enno-oduno/role-runner.d.ts +9 -0
  471. package/dist/enno-oduno/role-runner.d.ts.map +1 -0
  472. package/dist/enno-oduno/role-runner.js +219 -0
  473. package/dist/enno-oduno/role-runner.js.map +1 -0
  474. package/dist/enno-oduno/sanitize.d.ts +17 -0
  475. package/dist/enno-oduno/sanitize.d.ts.map +1 -0
  476. package/dist/enno-oduno/sanitize.js +88 -0
  477. package/dist/enno-oduno/sanitize.js.map +1 -0
  478. package/dist/enno-oduno/schemas.d.ts +962 -0
  479. package/dist/enno-oduno/schemas.d.ts.map +1 -0
  480. package/dist/enno-oduno/schemas.js +609 -0
  481. package/dist/enno-oduno/schemas.js.map +1 -0
  482. package/dist/enno-oduno/service.d.ts +57 -0
  483. package/dist/enno-oduno/service.d.ts.map +1 -0
  484. package/dist/enno-oduno/service.js +1379 -0
  485. package/dist/enno-oduno/service.js.map +1 -0
  486. package/dist/enno-oduno/skills.d.ts +22 -0
  487. package/dist/enno-oduno/skills.d.ts.map +1 -0
  488. package/dist/enno-oduno/skills.js +127 -0
  489. package/dist/enno-oduno/skills.js.map +1 -0
  490. package/dist/enno-oduno/store.d.ts +106 -0
  491. package/dist/enno-oduno/store.d.ts.map +1 -0
  492. package/dist/enno-oduno/store.js +712 -0
  493. package/dist/enno-oduno/store.js.map +1 -0
  494. package/dist/enno-oduno/types.d.ts +457 -0
  495. package/dist/enno-oduno/types.d.ts.map +1 -0
  496. package/dist/enno-oduno/types.js +66 -0
  497. package/dist/enno-oduno/types.js.map +1 -0
  498. package/dist/enno-oduno/validation-errors.d.ts +93 -0
  499. package/dist/enno-oduno/validation-errors.d.ts.map +1 -0
  500. package/dist/enno-oduno/validation-errors.js +152 -0
  501. package/dist/enno-oduno/validation-errors.js.map +1 -0
  502. package/dist/enno-oduno/verifier.d.ts +10 -0
  503. package/dist/enno-oduno/verifier.d.ts.map +1 -0
  504. package/dist/enno-oduno/verifier.js +214 -0
  505. package/dist/enno-oduno/verifier.js.map +1 -0
  506. package/dist/enno-oduno/zenki.d.mts +2 -0
  507. package/dist/enno-oduno/zenki.d.mts.map +1 -0
  508. package/dist/enno-oduno/zenki.mjs +3 -0
  509. package/dist/enno-oduno/zenki.mjs.map +1 -0
  510. package/dist/errors.d.ts +13 -0
  511. package/dist/errors.d.ts.map +1 -0
  512. package/dist/errors.js +60 -0
  513. package/dist/errors.js.map +1 -0
  514. package/dist/gateway/agent-service.d.ts +72 -0
  515. package/dist/gateway/agent-service.d.ts.map +1 -0
  516. package/dist/gateway/agent-service.js +594 -0
  517. package/dist/gateway/agent-service.js.map +1 -0
  518. package/dist/gateway/checkpoint-mutation-service.d.ts +33 -0
  519. package/dist/gateway/checkpoint-mutation-service.d.ts.map +1 -0
  520. package/dist/gateway/checkpoint-mutation-service.js +513 -0
  521. package/dist/gateway/checkpoint-mutation-service.js.map +1 -0
  522. package/dist/gateway/checkpoint-service.d.ts +40 -0
  523. package/dist/gateway/checkpoint-service.d.ts.map +1 -0
  524. package/dist/gateway/checkpoint-service.js +149 -0
  525. package/dist/gateway/checkpoint-service.js.map +1 -0
  526. package/dist/gateway/nudge-delivery-service.d.ts +21 -0
  527. package/dist/gateway/nudge-delivery-service.d.ts.map +1 -0
  528. package/dist/gateway/nudge-delivery-service.js +67 -0
  529. package/dist/gateway/nudge-delivery-service.js.map +1 -0
  530. package/dist/ledger/archive.d.ts +48 -0
  531. package/dist/ledger/archive.d.ts.map +1 -0
  532. package/dist/ledger/archive.js +1261 -0
  533. package/dist/ledger/archive.js.map +1 -0
  534. package/dist/ledger/checkpoint-contract.d.ts +144 -0
  535. package/dist/ledger/checkpoint-contract.d.ts.map +1 -0
  536. package/dist/ledger/checkpoint-contract.js +91 -0
  537. package/dist/ledger/checkpoint-contract.js.map +1 -0
  538. package/dist/ledger/checkpoint-eligibility.d.ts +17 -0
  539. package/dist/ledger/checkpoint-eligibility.d.ts.map +1 -0
  540. package/dist/ledger/checkpoint-eligibility.js +19 -0
  541. package/dist/ledger/checkpoint-eligibility.js.map +1 -0
  542. package/dist/ledger/hash.d.ts +22 -0
  543. package/dist/ledger/hash.d.ts.map +1 -0
  544. package/dist/ledger/hash.js +25 -0
  545. package/dist/ledger/hash.js.map +1 -0
  546. package/dist/ledger/maintenance.d.ts +68 -0
  547. package/dist/ledger/maintenance.d.ts.map +1 -0
  548. package/dist/ledger/maintenance.js +767 -0
  549. package/dist/ledger/maintenance.js.map +1 -0
  550. package/dist/ledger/projection.d.ts +38 -0
  551. package/dist/ledger/projection.d.ts.map +1 -0
  552. package/dist/ledger/projection.js +315 -0
  553. package/dist/ledger/projection.js.map +1 -0
  554. package/dist/ledger/promotion.d.ts +19 -0
  555. package/dist/ledger/promotion.d.ts.map +1 -0
  556. package/dist/ledger/promotion.js +310 -0
  557. package/dist/ledger/promotion.js.map +1 -0
  558. package/dist/ledger/query.d.ts +41 -0
  559. package/dist/ledger/query.d.ts.map +1 -0
  560. package/dist/ledger/query.js +321 -0
  561. package/dist/ledger/query.js.map +1 -0
  562. package/dist/ledger/redaction.d.ts +8 -0
  563. package/dist/ledger/redaction.d.ts.map +1 -0
  564. package/dist/ledger/redaction.js +40 -0
  565. package/dist/ledger/redaction.js.map +1 -0
  566. package/dist/ledger/store.d.ts +45 -0
  567. package/dist/ledger/store.d.ts.map +1 -0
  568. package/dist/ledger/store.js +327 -0
  569. package/dist/ledger/store.js.map +1 -0
  570. package/dist/ledger/types.d.ts +115 -0
  571. package/dist/ledger/types.d.ts.map +1 -0
  572. package/dist/ledger/types.js +27 -0
  573. package/dist/ledger/types.js.map +1 -0
  574. package/dist/ledger/validate.d.ts +10 -0
  575. package/dist/ledger/validate.d.ts.map +1 -0
  576. package/dist/ledger/validate.js +178 -0
  577. package/dist/ledger/validate.js.map +1 -0
  578. package/dist/mcp/bounded-stdio-transport.d.ts +26 -0
  579. package/dist/mcp/bounded-stdio-transport.d.ts.map +1 -0
  580. package/dist/mcp/bounded-stdio-transport.js +121 -0
  581. package/dist/mcp/bounded-stdio-transport.js.map +1 -0
  582. package/dist/mcp/request-deadline.d.ts +51 -0
  583. package/dist/mcp/request-deadline.d.ts.map +1 -0
  584. package/dist/mcp/request-deadline.js +155 -0
  585. package/dist/mcp/request-deadline.js.map +1 -0
  586. package/dist/mcp/runtime-owner.d.ts +27 -0
  587. package/dist/mcp/runtime-owner.d.ts.map +1 -0
  588. package/dist/mcp/runtime-owner.js +129 -0
  589. package/dist/mcp/runtime-owner.js.map +1 -0
  590. package/dist/mcp/server.d.ts +24 -0
  591. package/dist/mcp/server.d.ts.map +1 -0
  592. package/dist/mcp/server.js +502 -0
  593. package/dist/mcp/server.js.map +1 -0
  594. package/dist/memory/audit.d.ts +13 -0
  595. package/dist/memory/audit.d.ts.map +1 -0
  596. package/dist/memory/audit.js +15 -0
  597. package/dist/memory/audit.js.map +1 -0
  598. package/dist/memory/checkpoint-contract.d.ts +490 -0
  599. package/dist/memory/checkpoint-contract.d.ts.map +1 -0
  600. package/dist/memory/checkpoint-contract.js +106 -0
  601. package/dist/memory/checkpoint-contract.js.map +1 -0
  602. package/dist/memory/curator-trust.d.ts +15 -0
  603. package/dist/memory/curator-trust.d.ts.map +1 -0
  604. package/dist/memory/curator-trust.js +58 -0
  605. package/dist/memory/curator-trust.js.map +1 -0
  606. package/dist/memory/curator.d.ts +115 -0
  607. package/dist/memory/curator.d.ts.map +1 -0
  608. package/dist/memory/curator.js +706 -0
  609. package/dist/memory/curator.js.map +1 -0
  610. package/dist/memory/entries.d.ts +75 -0
  611. package/dist/memory/entries.d.ts.map +1 -0
  612. package/dist/memory/entries.js +355 -0
  613. package/dist/memory/entries.js.map +1 -0
  614. package/dist/memory/federated-retrieval.d.ts +79 -0
  615. package/dist/memory/federated-retrieval.d.ts.map +1 -0
  616. package/dist/memory/federated-retrieval.js +515 -0
  617. package/dist/memory/federated-retrieval.js.map +1 -0
  618. package/dist/memory/hybrid-retrieval.d.ts +33 -0
  619. package/dist/memory/hybrid-retrieval.d.ts.map +1 -0
  620. package/dist/memory/hybrid-retrieval.js +398 -0
  621. package/dist/memory/hybrid-retrieval.js.map +1 -0
  622. package/dist/memory/lifecycle.d.ts +29 -0
  623. package/dist/memory/lifecycle.d.ts.map +1 -0
  624. package/dist/memory/lifecycle.js +65 -0
  625. package/dist/memory/lifecycle.js.map +1 -0
  626. package/dist/memory/portability.d.ts +10 -0
  627. package/dist/memory/portability.d.ts.map +1 -0
  628. package/dist/memory/portability.js +44 -0
  629. package/dist/memory/portability.js.map +1 -0
  630. package/dist/memory/rebuild-search.d.ts +24 -0
  631. package/dist/memory/rebuild-search.d.ts.map +1 -0
  632. package/dist/memory/rebuild-search.js +167 -0
  633. package/dist/memory/rebuild-search.js.map +1 -0
  634. package/dist/memory/retrieval-query.d.ts +16 -0
  635. package/dist/memory/retrieval-query.d.ts.map +1 -0
  636. package/dist/memory/retrieval-query.js +161 -0
  637. package/dist/memory/retrieval-query.js.map +1 -0
  638. package/dist/memory/retrieval.d.ts +56 -0
  639. package/dist/memory/retrieval.d.ts.map +1 -0
  640. package/dist/memory/retrieval.js +101 -0
  641. package/dist/memory/retrieval.js.map +1 -0
  642. package/dist/memory/revisions.d.ts +123 -0
  643. package/dist/memory/revisions.d.ts.map +1 -0
  644. package/dist/memory/revisions.js +759 -0
  645. package/dist/memory/revisions.js.map +1 -0
  646. package/dist/memory/scoped-memory.d.ts +76 -0
  647. package/dist/memory/scoped-memory.d.ts.map +1 -0
  648. package/dist/memory/scoped-memory.js +539 -0
  649. package/dist/memory/scoped-memory.js.map +1 -0
  650. package/dist/memory/secrets.d.ts +8 -0
  651. package/dist/memory/secrets.d.ts.map +1 -0
  652. package/dist/memory/secrets.js +54 -0
  653. package/dist/memory/secrets.js.map +1 -0
  654. package/dist/memory/structured-memory.d.ts +60 -0
  655. package/dist/memory/structured-memory.d.ts.map +1 -0
  656. package/dist/memory/structured-memory.js +341 -0
  657. package/dist/memory/structured-memory.js.map +1 -0
  658. package/dist/memory/workspaces.d.ts +26 -0
  659. package/dist/memory/workspaces.d.ts.map +1 -0
  660. package/dist/memory/workspaces.js +159 -0
  661. package/dist/memory/workspaces.js.map +1 -0
  662. package/dist/model-tools/contracts.d.ts +1297 -0
  663. package/dist/model-tools/contracts.d.ts.map +1 -0
  664. package/dist/model-tools/contracts.js +104 -0
  665. package/dist/model-tools/contracts.js.map +1 -0
  666. package/dist/model-tools/registry.d.ts +8 -0
  667. package/dist/model-tools/registry.d.ts.map +1 -0
  668. package/dist/model-tools/registry.js +59 -0
  669. package/dist/model-tools/registry.js.map +1 -0
  670. package/dist/package-version.d.ts +2 -0
  671. package/dist/package-version.d.ts.map +1 -0
  672. package/dist/package-version.js +7 -0
  673. package/dist/package-version.js.map +1 -0
  674. package/dist/repository/binding.d.ts +32 -0
  675. package/dist/repository/binding.d.ts.map +1 -0
  676. package/dist/repository/binding.js +208 -0
  677. package/dist/repository/binding.js.map +1 -0
  678. package/dist/repository/cwd-schema.d.ts +4 -0
  679. package/dist/repository/cwd-schema.d.ts.map +1 -0
  680. package/dist/repository/cwd-schema.js +8 -0
  681. package/dist/repository/cwd-schema.js.map +1 -0
  682. package/dist/repository/detect-root.d.ts +13 -0
  683. package/dist/repository/detect-root.d.ts.map +1 -0
  684. package/dist/repository/detect-root.js +77 -0
  685. package/dist/repository/detect-root.js.map +1 -0
  686. package/dist/repository/framework-version.d.ts +8 -0
  687. package/dist/repository/framework-version.d.ts.map +1 -0
  688. package/dist/repository/framework-version.js +29 -0
  689. package/dist/repository/framework-version.js.map +1 -0
  690. package/dist/repository/git-origin.d.ts +2 -0
  691. package/dist/repository/git-origin.d.ts.map +1 -0
  692. package/dist/repository/git-origin.js +15 -0
  693. package/dist/repository/git-origin.js.map +1 -0
  694. package/dist/repository/gitignore.d.ts +8 -0
  695. package/dist/repository/gitignore.d.ts.map +1 -0
  696. package/dist/repository/gitignore.js +21 -0
  697. package/dist/repository/gitignore.js.map +1 -0
  698. package/dist/repository/identity-value.d.ts +4 -0
  699. package/dist/repository/identity-value.d.ts.map +1 -0
  700. package/dist/repository/identity-value.js +24 -0
  701. package/dist/repository/identity-value.js.map +1 -0
  702. package/dist/repository/identity.d.ts +19 -0
  703. package/dist/repository/identity.d.ts.map +1 -0
  704. package/dist/repository/identity.js +25 -0
  705. package/dist/repository/identity.js.map +1 -0
  706. package/dist/repository/project-fingerprint.d.ts +33 -0
  707. package/dist/repository/project-fingerprint.d.ts.map +1 -0
  708. package/dist/repository/project-fingerprint.js +429 -0
  709. package/dist/repository/project-fingerprint.js.map +1 -0
  710. package/dist/repository/remote-url.d.ts +3 -0
  711. package/dist/repository/remote-url.d.ts.map +1 -0
  712. package/dist/repository/remote-url.js +35 -0
  713. package/dist/repository/remote-url.js.map +1 -0
  714. package/dist/runtime-version.d.ts +6 -0
  715. package/dist/runtime-version.d.ts.map +1 -0
  716. package/dist/runtime-version.js +33 -0
  717. package/dist/runtime-version.js.map +1 -0
  718. package/dist/security/sanitize.d.ts +4 -0
  719. package/dist/security/sanitize.d.ts.map +1 -0
  720. package/dist/security/sanitize.js +174 -0
  721. package/dist/security/sanitize.js.map +1 -0
  722. package/dist/serialization/boundary-json.d.ts +20 -0
  723. package/dist/serialization/boundary-json.d.ts.map +1 -0
  724. package/dist/serialization/boundary-json.js +129 -0
  725. package/dist/serialization/boundary-json.js.map +1 -0
  726. package/dist/serialization/envelope.d.ts +20 -0
  727. package/dist/serialization/envelope.d.ts.map +1 -0
  728. package/dist/serialization/envelope.js +11 -0
  729. package/dist/serialization/envelope.js.map +1 -0
  730. package/dist/serialization/validate.d.ts +38 -0
  731. package/dist/serialization/validate.d.ts.map +1 -0
  732. package/dist/serialization/validate.js +233 -0
  733. package/dist/serialization/validate.js.map +1 -0
  734. package/dist/server/agent-application.d.ts +6 -0
  735. package/dist/server/agent-application.d.ts.map +1 -0
  736. package/dist/server/agent-application.js +74 -0
  737. package/dist/server/agent-application.js.map +1 -0
  738. package/dist/server/agent-checkpoint-use-case.d.ts +41 -0
  739. package/dist/server/agent-checkpoint-use-case.d.ts.map +1 -0
  740. package/dist/server/agent-checkpoint-use-case.js +159 -0
  741. package/dist/server/agent-checkpoint-use-case.js.map +1 -0
  742. package/dist/server/app.d.ts +5 -0
  743. package/dist/server/app.d.ts.map +1 -0
  744. package/dist/server/app.js +87 -0
  745. package/dist/server/app.js.map +1 -0
  746. package/dist/server/auth.d.ts +2 -0
  747. package/dist/server/auth.d.ts.map +1 -0
  748. package/dist/server/auth.js +22 -0
  749. package/dist/server/auth.js.map +1 -0
  750. package/dist/server/http.d.ts +86 -0
  751. package/dist/server/http.d.ts.map +1 -0
  752. package/dist/server/http.js +455 -0
  753. package/dist/server/http.js.map +1 -0
  754. package/dist/server/idempotency.d.ts +6 -0
  755. package/dist/server/idempotency.d.ts.map +1 -0
  756. package/dist/server/idempotency.js +210 -0
  757. package/dist/server/idempotency.js.map +1 -0
  758. package/dist/server/instance-lock.d.ts +17 -0
  759. package/dist/server/instance-lock.d.ts.map +1 -0
  760. package/dist/server/instance-lock.js +118 -0
  761. package/dist/server/instance-lock.js.map +1 -0
  762. package/dist/server/router.d.ts +29 -0
  763. package/dist/server/router.d.ts.map +1 -0
  764. package/dist/server/router.js +129 -0
  765. package/dist/server/router.js.map +1 -0
  766. package/dist/server/routes/agent-capability-gate.d.ts +43 -0
  767. package/dist/server/routes/agent-capability-gate.d.ts.map +1 -0
  768. package/dist/server/routes/agent-capability-gate.js +202 -0
  769. package/dist/server/routes/agent-capability-gate.js.map +1 -0
  770. package/dist/server/routes/agent-events.d.ts +5 -0
  771. package/dist/server/routes/agent-events.d.ts.map +1 -0
  772. package/dist/server/routes/agent-events.js +53 -0
  773. package/dist/server/routes/agent-events.js.map +1 -0
  774. package/dist/server/routes/agent-intake.d.ts +5 -0
  775. package/dist/server/routes/agent-intake.d.ts.map +1 -0
  776. package/dist/server/routes/agent-intake.js +50 -0
  777. package/dist/server/routes/agent-intake.js.map +1 -0
  778. package/dist/server/routes/agent-promotions.d.ts +5 -0
  779. package/dist/server/routes/agent-promotions.d.ts.map +1 -0
  780. package/dist/server/routes/agent-promotions.js +55 -0
  781. package/dist/server/routes/agent-promotions.js.map +1 -0
  782. package/dist/server/routes/agent-runs.d.ts +32 -0
  783. package/dist/server/routes/agent-runs.d.ts.map +1 -0
  784. package/dist/server/routes/agent-runs.js +165 -0
  785. package/dist/server/routes/agent-runs.js.map +1 -0
  786. package/dist/server/routes/request-binding.d.ts +5 -0
  787. package/dist/server/routes/request-binding.d.ts.map +1 -0
  788. package/dist/server/routes/request-binding.js +49 -0
  789. package/dist/server/routes/request-binding.js.map +1 -0
  790. package/dist/server/routes/task5-support.d.ts +4 -0
  791. package/dist/server/routes/task5-support.d.ts.map +1 -0
  792. package/dist/server/routes/task5-support.js +6 -0
  793. package/dist/server/routes/task5-support.js.map +1 -0
  794. package/dist/server/routes/task5.d.ts +5 -0
  795. package/dist/server/routes/task5.d.ts.map +1 -0
  796. package/dist/server/routes/task5.js +85 -0
  797. package/dist/server/routes/task5.js.map +1 -0
  798. package/dist/server/runtime-descriptor.d.ts +24 -0
  799. package/dist/server/runtime-descriptor.d.ts.map +1 -0
  800. package/dist/server/runtime-descriptor.js +156 -0
  801. package/dist/server/runtime-descriptor.js.map +1 -0
  802. package/dist/server/write-queue.d.ts +20 -0
  803. package/dist/server/write-queue.d.ts.map +1 -0
  804. package/dist/server/write-queue.js +83 -0
  805. package/dist/server/write-queue.js.map +1 -0
  806. package/dist/setup/claude-config.d.ts +8 -0
  807. package/dist/setup/claude-config.d.ts.map +1 -0
  808. package/dist/setup/claude-config.js +95 -0
  809. package/dist/setup/claude-config.js.map +1 -0
  810. package/dist/setup/client-detection.d.ts +13 -0
  811. package/dist/setup/client-detection.d.ts.map +1 -0
  812. package/dist/setup/client-detection.js +64 -0
  813. package/dist/setup/client-detection.js.map +1 -0
  814. package/dist/setup/enno-client-config.d.ts +9 -0
  815. package/dist/setup/enno-client-config.d.ts.map +1 -0
  816. package/dist/setup/enno-client-config.js +172 -0
  817. package/dist/setup/enno-client-config.js.map +1 -0
  818. package/dist/setup/hermes-config.d.ts +7 -0
  819. package/dist/setup/hermes-config.d.ts.map +1 -0
  820. package/dist/setup/hermes-config.js +145 -0
  821. package/dist/setup/hermes-config.js.map +1 -0
  822. package/dist/setup/legacy-client-cleanup.d.ts +6 -0
  823. package/dist/setup/legacy-client-cleanup.d.ts.map +1 -0
  824. package/dist/setup/legacy-client-cleanup.js +152 -0
  825. package/dist/setup/legacy-client-cleanup.js.map +1 -0
  826. package/dist/setup/managed-text.d.ts +6 -0
  827. package/dist/setup/managed-text.d.ts.map +1 -0
  828. package/dist/setup/managed-text.js +52 -0
  829. package/dist/setup/managed-text.js.map +1 -0
  830. package/dist/setup/mcp-conflict.d.ts +4 -0
  831. package/dist/setup/mcp-conflict.d.ts.map +1 -0
  832. package/dist/setup/mcp-conflict.js +15 -0
  833. package/dist/setup/mcp-conflict.js.map +1 -0
  834. package/dist/setup/opencode-config.d.ts +8 -0
  835. package/dist/setup/opencode-config.d.ts.map +1 -0
  836. package/dist/setup/opencode-config.js +98 -0
  837. package/dist/setup/opencode-config.js.map +1 -0
  838. package/dist/setup/project-agent-refresh.d.ts +41 -0
  839. package/dist/setup/project-agent-refresh.d.ts.map +1 -0
  840. package/dist/setup/project-agent-refresh.js +158 -0
  841. package/dist/setup/project-agent-refresh.js.map +1 -0
  842. package/dist/setup/render.d.ts +13 -0
  843. package/dist/setup/render.d.ts.map +1 -0
  844. package/dist/setup/render.js +334 -0
  845. package/dist/setup/render.js.map +1 -0
  846. package/dist/setup/standard-skills.d.ts +60 -0
  847. package/dist/setup/standard-skills.d.ts.map +1 -0
  848. package/dist/setup/standard-skills.js +133 -0
  849. package/dist/setup/standard-skills.js.map +1 -0
  850. package/dist/setup/strict-json.d.ts +7 -0
  851. package/dist/setup/strict-json.d.ts.map +1 -0
  852. package/dist/setup/strict-json.js +98 -0
  853. package/dist/setup/strict-json.js.map +1 -0
  854. package/dist/setup/strict-toml.d.ts +18 -0
  855. package/dist/setup/strict-toml.d.ts.map +1 -0
  856. package/dist/setup/strict-toml.js +491 -0
  857. package/dist/setup/strict-toml.js.map +1 -0
  858. package/dist/skills/cache.d.ts +15 -0
  859. package/dist/skills/cache.d.ts.map +1 -0
  860. package/dist/skills/cache.js +19 -0
  861. package/dist/skills/cache.js.map +1 -0
  862. package/dist/skills/candidate-ranking.d.ts +15 -0
  863. package/dist/skills/candidate-ranking.d.ts.map +1 -0
  864. package/dist/skills/candidate-ranking.js +52 -0
  865. package/dist/skills/candidate-ranking.js.map +1 -0
  866. package/dist/skills/chunking.d.ts +11 -0
  867. package/dist/skills/chunking.d.ts.map +1 -0
  868. package/dist/skills/chunking.js +291 -0
  869. package/dist/skills/chunking.js.map +1 -0
  870. package/dist/skills/config.d.ts +19 -0
  871. package/dist/skills/config.d.ts.map +1 -0
  872. package/dist/skills/config.js +103 -0
  873. package/dist/skills/config.js.map +1 -0
  874. package/dist/skills/discovery-service.d.ts +26 -0
  875. package/dist/skills/discovery-service.d.ts.map +1 -0
  876. package/dist/skills/discovery-service.js +929 -0
  877. package/dist/skills/discovery-service.js.map +1 -0
  878. package/dist/skills/external-transport.d.ts +2 -0
  879. package/dist/skills/external-transport.d.ts.map +1 -0
  880. package/dist/skills/external-transport.js +30 -0
  881. package/dist/skills/external-transport.js.map +1 -0
  882. package/dist/skills/find.d.ts +17 -0
  883. package/dist/skills/find.d.ts.map +1 -0
  884. package/dist/skills/find.js +59 -0
  885. package/dist/skills/find.js.map +1 -0
  886. package/dist/skills/gap-detection.d.ts +23 -0
  887. package/dist/skills/gap-detection.d.ts.map +1 -0
  888. package/dist/skills/gap-detection.js +62 -0
  889. package/dist/skills/gap-detection.js.map +1 -0
  890. package/dist/skills/import-preparation.d.ts +4 -0
  891. package/dist/skills/import-preparation.d.ts.map +1 -0
  892. package/dist/skills/import-preparation.js +20 -0
  893. package/dist/skills/import-preparation.js.map +1 -0
  894. package/dist/skills/materialization-authority.d.ts +11 -0
  895. package/dist/skills/materialization-authority.d.ts.map +1 -0
  896. package/dist/skills/materialization-authority.js +92 -0
  897. package/dist/skills/materialization-authority.js.map +1 -0
  898. package/dist/skills/materialization-service.d.ts +22 -0
  899. package/dist/skills/materialization-service.d.ts.map +1 -0
  900. package/dist/skills/materialization-service.js +101 -0
  901. package/dist/skills/materialization-service.js.map +1 -0
  902. package/dist/skills/official-catalog.d.ts +31 -0
  903. package/dist/skills/official-catalog.d.ts.map +1 -0
  904. package/dist/skills/official-catalog.js +110 -0
  905. package/dist/skills/official-catalog.js.map +1 -0
  906. package/dist/skills/providers/schema.d.ts +30 -0
  907. package/dist/skills/providers/schema.d.ts.map +1 -0
  908. package/dist/skills/providers/schema.js +354 -0
  909. package/dist/skills/providers/schema.js.map +1 -0
  910. package/dist/skills/providers/skills-sh-compat.d.ts +17 -0
  911. package/dist/skills/providers/skills-sh-compat.d.ts.map +1 -0
  912. package/dist/skills/providers/skills-sh-compat.js +73 -0
  913. package/dist/skills/providers/skills-sh-compat.js.map +1 -0
  914. package/dist/skills/providers/skills-sh-v1.d.ts +23 -0
  915. package/dist/skills/providers/skills-sh-v1.d.ts.map +1 -0
  916. package/dist/skills/providers/skills-sh-v1.js +152 -0
  917. package/dist/skills/providers/skills-sh-v1.js.map +1 -0
  918. package/dist/skills/query-builder.d.ts +18 -0
  919. package/dist/skills/query-builder.d.ts.map +1 -0
  920. package/dist/skills/query-builder.js +93 -0
  921. package/dist/skills/query-builder.js.map +1 -0
  922. package/dist/skills/source/errors.d.ts +9 -0
  923. package/dist/skills/source/errors.d.ts.map +1 -0
  924. package/dist/skills/source/errors.js +15 -0
  925. package/dist/skills/source/errors.js.map +1 -0
  926. package/dist/skills/source/frontmatter.d.ts +9 -0
  927. package/dist/skills/source/frontmatter.d.ts.map +1 -0
  928. package/dist/skills/source/frontmatter.js +77 -0
  929. package/dist/skills/source/frontmatter.js.map +1 -0
  930. package/dist/skills/source/github-fetcher.d.ts +20 -0
  931. package/dist/skills/source/github-fetcher.d.ts.map +1 -0
  932. package/dist/skills/source/github-fetcher.js +296 -0
  933. package/dist/skills/source/github-fetcher.js.map +1 -0
  934. package/dist/skills/source/snapshot-validator.d.ts +28 -0
  935. package/dist/skills/source/snapshot-validator.d.ts.map +1 -0
  936. package/dist/skills/source/snapshot-validator.js +186 -0
  937. package/dist/skills/source/snapshot-validator.js.map +1 -0
  938. package/dist/skills/store.d.ts +180 -0
  939. package/dist/skills/store.d.ts.map +1 -0
  940. package/dist/skills/store.js +1712 -0
  941. package/dist/skills/store.js.map +1 -0
  942. package/dist/skills/types.d.ts +171 -0
  943. package/dist/skills/types.d.ts.map +1 -0
  944. package/dist/skills/types.js +2 -0
  945. package/dist/skills/types.js.map +1 -0
  946. package/dist/web/i18n.d.ts +184 -0
  947. package/dist/web/i18n.d.ts.map +1 -0
  948. package/dist/web/i18n.js +733 -0
  949. package/dist/web/i18n.js.map +1 -0
  950. package/dist/web/server.d.ts +16 -0
  951. package/dist/web/server.d.ts.map +1 -0
  952. package/dist/web/server.js +862 -0
  953. package/dist/web/server.js.map +1 -0
  954. package/dist/web/ui.d.ts +6 -0
  955. package/dist/web/ui.d.ts.map +1 -0
  956. package/dist/web/ui.js +1328 -0
  957. package/dist/web/ui.js.map +1 -0
  958. package/docs/README.ja.md +14 -0
  959. package/docs/README.md +16 -0
  960. package/docs/agent-file.md +72 -0
  961. package/docs/agent-gateway.md +104 -0
  962. package/docs/architecture.md +12 -0
  963. package/docs/cli-contract.md +39 -0
  964. package/docs/client-compatibility.md +299 -0
  965. package/docs/concepts.ja.md +25 -0
  966. package/docs/concepts.md +33 -0
  967. package/docs/database.md +11 -0
  968. package/docs/dsh-plugin.md +108 -0
  969. package/docs/enno-oduno.ja.md +22 -0
  970. package/docs/enno-oduno.md +35 -0
  971. package/docs/execution-ledger.md +89 -0
  972. package/docs/getting-started.ja.md +88 -0
  973. package/docs/getting-started.md +99 -0
  974. package/docs/release-notes-0.1.18.md +103 -0
  975. package/docs/retrieval-evaluation.md +10 -0
  976. package/docs/security-and-trust.ja.md +29 -0
  977. package/docs/security-and-trust.md +39 -0
  978. package/docs/security.md +11 -0
  979. package/docs/semantic-retrieval.ja.md +18 -0
  980. package/docs/semantic-retrieval.md +26 -0
  981. package/docs/sqlite-driver-adr.md +8 -0
  982. package/dsh/cordis.patch.yml +7 -0
  983. package/migrations/001_initial.sql +123 -0
  984. package/migrations/002_fts.sql +22 -0
  985. package/migrations/003_akinator.sql +30 -0
  986. package/migrations/004_agent_gateway.sql +261 -0
  987. package/migrations/005_hybrid_search.sql +40 -0
  988. package/migrations/006_context_v2.sql +4 -0
  989. package/migrations/007_akinator_reasoning.sql +59 -0
  990. package/migrations/008_federated_memory.sql +46 -0
  991. package/migrations/009_external_skill_discovery.sql +126 -0
  992. package/migrations/010_nudge_deliveries.sql +50 -0
  993. package/migrations/011_nudge_integrity.sql +52 -0
  994. package/migrations/012_context_delivery_v4.sql +3 -0
  995. package/migrations/013_enno_oduno.sql +176 -0
  996. package/migrations/014_oduno_reflection_phases.sql +40 -0
  997. package/migrations/015_skill_discovery_attempt_digests.sql +90 -0
  998. package/migrations/016_enno_advisory_rounds.sql +67 -0
  999. package/migrations/017_enno_advisory_protocol_v2.sql +101 -0
  1000. package/migrations/018_enno_repository_routing.sql +5 -0
  1001. package/migrations/019_enno_execution_integrity.sql +149 -0
  1002. package/migrations/020_cjk_fts.sql +80 -0
  1003. package/migrations/021_semantic_embeddings.sql +122 -0
  1004. package/migrations/022_embedding_setup_v2.sql +236 -0
  1005. package/migrations/023_enno_dsh_client.sql +291 -0
  1006. package/migrations/down/020_cjk_fts.sql +38 -0
  1007. package/migrations/down/021_semantic_embeddings.sql +17 -0
  1008. package/migrations/down/022_embedding_setup_v2.sql +133 -0
  1009. package/package.json +101 -0
  1010. package/skills/kiokuko-enno-oduno/SKILL.md +209 -0
  1011. package/skills/kiokuko-enno-oduno/enno-oduno.png +0 -0
  1012. package/skills/kiokuko-simple-work/SKILL.md +112 -0
  1013. package/skills/kiokuko-single-purpose-functions/SKILL.md +82 -0
  1014. package/skills/kiokuko-single-purpose-functions/references/boundaries-and-ownership.md +50 -0
  1015. package/skills/kiokuko-single-purpose-functions/references/domain-and-types.md +48 -0
  1016. package/skills/kiokuko-single-purpose-functions/references/effects-and-data.md +43 -0
  1017. package/skills/kiokuko-single-purpose-functions/references/kiokuko-patterns.md +344 -0
  1018. package/skills/kiokuko-single-purpose-functions/references/problem-shaping-and-language.md +84 -0
  1019. package/skills/kiokuko-single-purpose-functions/references/protocols-and-idempotency.md +42 -0
  1020. package/skills/kiokuko-single-purpose-functions/references/review-checklist.md +97 -0
  1021. package/skills/kiokuko-single-purpose-functions/references/verification.md +41 -0
  1022. package/skills/kiokuko-soul/SKILL.md +104 -0
  1023. package/skills/kiokuko-ui-design-soul/SKILL.md +73 -0
  1024. package/skills/kiokuko-ui-design-soul/references/accessibility-and-navigation.md +31 -0
  1025. package/skills/kiokuko-ui-design-soul/references/async-recovery.md +49 -0
  1026. package/skills/kiokuko-ui-design-soul/references/forms-and-controls.md +35 -0
  1027. package/skills/kiokuko-ui-design-soul/references/interaction-feedback.md +34 -0
  1028. package/skills/kiokuko-ui-design-soul/references/responsive-and-platform.md +38 -0
  1029. package/skills/kiokuko-ui-design-soul/references/safety-and-review.md +39 -0
  1030. package/skills/kiokuko-ui-design-soul/references/ui-checklist.md +71 -0
  1031. package/skills/memory-reasoning/SKILL.md +52 -0
  1032. package/templates/AGENTS.md +46 -0
package/dist/web/ui.js ADDED
@@ -0,0 +1,1328 @@
1
+ import { DEFAULT_WEB_LOCALE, WEB_LOCALE_LABELS, WEB_LOCALES, WEB_MESSAGES } from './i18n.js';
2
+ const WEB_I18N_CONFIG = JSON.stringify({
3
+ defaultLocale: DEFAULT_WEB_LOCALE,
4
+ localeLabels: WEB_LOCALE_LABELS,
5
+ locales: WEB_LOCALES,
6
+ messages: WEB_MESSAGES,
7
+ })
8
+ .replaceAll('&', '\\u0026')
9
+ .replaceAll('<', '\\u003c')
10
+ .replaceAll('>', '\\u003e')
11
+ .replaceAll('\u2028', '\\u2028')
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
+ }
100
+ export const WEB_HTML = String.raw `<!doctype html>
101
+ <html lang="en">
102
+ <head>
103
+ <meta charset="utf-8">
104
+ <meta name="viewport" content="width=device-width, initial-scale=1">
105
+ <title>Kiokuko Web</title>
106
+ <style>
107
+ :root { color-scheme: light; --ink:#1e293b; --muted:#64748b; --line:#e2e8f0; --panel:#ffffff; --surface:#f8fafc; --accent:#2563eb; --accent-soft:#eff6ff; --warn:#b45309; --danger:#b91c1c; }
108
+ * { box-sizing:border-box; }
109
+ [hidden] { display:none !important; }
110
+ body { margin:0; background:linear-gradient(135deg,#f8fafc,#eef2ff); color:var(--ink); font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif; }
111
+ button,input,select,textarea { font:inherit; }
112
+ button { cursor:pointer; }
113
+ .shell { max-width:1440px; margin:0 auto; padding:28px; }
114
+ .topbar { display:grid; grid-template-columns:minmax(0,1.1fr) minmax(420px,.9fr); gap:24px; align-items:start; margin-bottom:22px; }
115
+ .brand,.topbar-side { min-width:0; }
116
+ .topbar-side { display:flex; flex-direction:column; gap:10px; align-self:stretch; }
117
+ .eyebrow { color:var(--accent); font-size:12px; font-weight:800; letter-spacing:.16em; text-transform:uppercase; }
118
+ h1 { margin:4px 0 0; font-size:clamp(28px,4vw,44px); letter-spacing:-.04em; }
119
+ .subtitle { margin:8px 0 0; color:var(--muted); }
120
+ .language-picker { position:relative; align-self:flex-end; z-index:10; }
121
+ .language-toggle { display:grid; place-items:center; width:44px; height:44px; border:1px solid var(--line); border-radius:12px; background:var(--panel); color:var(--ink); box-shadow:0 6px 18px rgba(15,23,42,.06); }
122
+ .language-toggle:hover,.language-toggle[aria-expanded="true"] { border-color:#93c5fd; background:var(--accent-soft); color:var(--accent); }
123
+ .language-toggle:focus-visible,.language-option:focus-visible { outline:3px solid rgba(37,99,235,.25); outline-offset:2px; }
124
+ .language-toggle svg { width:22px; height:22px; }
125
+ .language-menu { position:absolute; top:calc(100% + 8px); right:0; display:grid; gap:2px; width:max-content; min-width:168px; padding:6px; border:1px solid var(--line); border-radius:14px; background:var(--panel); box-shadow:0 18px 48px rgba(15,23,42,.16); }
126
+ .language-option { display:flex; align-items:center; justify-content:space-between; gap:18px; width:100%; border:0; border-radius:9px; padding:9px 11px; background:transparent; color:var(--ink); text-align:left; }
127
+ .language-option:hover,.language-option:focus-visible,.language-option[aria-checked="true"] { background:var(--accent-soft); color:var(--accent); }
128
+ .language-option[aria-checked="true"]::after { content:"✓"; font-weight:800; }
129
+ .toolbar { display:flex; gap:10px; align-items:center; justify-content:flex-end; flex-wrap:wrap; margin-top:auto; }
130
+ .topbar-side .control { flex:1 1 210px; width:auto; min-width:0; }
131
+ .topbar-side .search { flex:1.4 1 240px; width:auto; min-width:0; }
132
+ .control, .search { border:1px solid var(--line); border-radius:12px; background:var(--panel); color:var(--ink); padding:10px 12px; }
133
+ .search { min-width:260px; }
134
+ .button { border:1px solid var(--line); border-radius:12px; background:var(--panel); color:var(--ink); padding:10px 14px; font-weight:700; }
135
+ .button.primary { background:var(--accent); color:#fff; border-color:var(--accent); }
136
+ .button:disabled { cursor:not-allowed; opacity:.45; }
137
+ .button:focus-visible,.curator-close:focus-visible { outline:3px solid rgba(37,99,235,.25); outline-offset:2px; }
138
+ .layout { display:grid; grid-template-columns:220px minmax(300px,1fr) minmax(360px,1.15fr); gap:16px; align-items:start; }
139
+ .panel { background:rgba(255,255,255,.88); border:1px solid rgba(226,232,240,.9); border-radius:20px; box-shadow:0 14px 44px rgba(15,23,42,.08); overflow:hidden; }
140
+ .panel-head { padding:18px 20px; border-bottom:1px solid var(--line); display:flex; justify-content:space-between; align-items:center; gap:12px; }
141
+ .panel-head h2 { margin:0; font-size:16px; }
142
+ .panel-body { padding:16px; }
143
+ .genres { padding:10px; }
144
+ .filter-group + .filter-group { border-top:1px solid var(--line); margin-top:8px; padding-top:8px; }
145
+ .filter-group-title { color:var(--muted); font-size:11px; font-weight:800; letter-spacing:.08em; padding:8px 12px 4px; text-transform:uppercase; }
146
+ .genre { display:flex; justify-content:space-between; align-items:center; width:100%; border:0; background:transparent; color:var(--muted); border-radius:12px; padding:11px 12px; text-align:left; }
147
+ .genre:hover,.genre.active { background:var(--accent-soft); color:var(--accent); }
148
+ .count { min-width:26px; padding:2px 7px; border-radius:999px; background:#e2e8f0; color:var(--muted); font-size:12px; text-align:center; }
149
+ .genre.active .count { background:#dbeafe; color:var(--accent); }
150
+ .entry-list { display:flex; flex-direction:column; gap:10px; max-height:calc(100vh - 220px); overflow:auto; }
151
+ .entry-card { border:1px solid var(--line); border-radius:14px; padding:14px; background:var(--panel); transition:.16s ease; }
152
+ .entry-card:hover,.entry-card.selected { border-color:#93c5fd; box-shadow:0 8px 20px rgba(37,99,235,.10); }
153
+ .entry-meta { display:flex; gap:7px; align-items:center; flex-wrap:wrap; color:var(--muted); font-size:12px; }
154
+ .badge { border-radius:999px; padding:3px 8px; background:#f1f5f9; color:#475569; font-weight:700; }
155
+ .badge.origin-project { background:#dbeafe; color:#1d4ed8; }
156
+ .badge.origin-ecosystem { background:#dcfce7; color:#166534; }
157
+ .badge.origin-global { background:#fef3c7; color:#92400e; }
158
+ .badge.verified { background:#dcfce7; color:#166534; }
159
+ .badge.candidate { background:#fef3c7; color:#92400e; }
160
+ .badge.superseded { background:#fee2e2; color:#991b1b; }
161
+ .entry-card h3 { margin:9px 0 6px; font-size:16px; }
162
+ .snippet { margin:0; color:var(--muted); display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical; overflow:hidden; white-space:pre-wrap; }
163
+ .federated-card { border-left:4px solid #22c55e; }
164
+ .federated-card.global { border-left-color:#f59e0b; }
165
+ .federated-source,.selection-reasons { margin-top:8px; color:var(--muted); font-size:12px; white-space:pre-wrap; overflow-wrap:anywhere; }
166
+ .federated-detail { display:grid; gap:12px; }
167
+ .tags { display:flex; gap:6px; flex-wrap:wrap; margin-top:10px; }
168
+ .tag { border:0; background:transparent; color:var(--accent); font-size:12px; padding:0; }
169
+ .tag:hover { text-decoration:underline; }
170
+ .form { display:grid; gap:12px; }
171
+ label { display:grid; gap:6px; color:var(--muted); font-size:12px; font-weight:800; letter-spacing:.04em; }
172
+ textarea,input,select { width:100%; border:1px solid var(--line); border-radius:10px; padding:10px 11px; background:#fff; color:var(--ink); }
173
+ textarea { min-height:120px; resize:vertical; line-height:1.55; }
174
+ textarea.body { min-height:260px; }
175
+ .form-row { display:grid; grid-template-columns:1fr 1fr; gap:10px; }
176
+ .editor-empty { color:var(--muted); padding:30px 10px; text-align:center; }
177
+ .notice { border-radius:12px; padding:11px 12px; background:#fffbeb; color:var(--warn); font-size:13px; }
178
+ .notice.error { background:#fef2f2; color:var(--danger); }
179
+ .status { color:var(--muted); font-size:12px; min-height:18px; }
180
+ .conflict-guide { display:grid; gap:10px; padding:16px; border:1px solid #fecaca; border-radius:14px; background:#fef2f2; color:#7f1d1d; font-size:14px; }
181
+ .conflict-guide h2,.conflict-guide p,.conflict-guide ol { margin:0; }
182
+ .conflict-guide h2 { font-size:16px; }
183
+ .conflict-guide ol { display:grid; gap:6px; padding-left:22px; line-height:1.5; }
184
+ .conflict-guide-actions { display:flex; flex-wrap:wrap; gap:8px; }
185
+ .conflict-guide-feedback { min-height:18px; font-size:13px; font-weight:700; }
186
+ .conflict-guide-feedback.error { color:var(--danger); }
187
+ .operator-panel { grid-column:1 / -1; margin-top:16px; }
188
+ .operator-grid { display:grid; grid-template-columns:minmax(240px,.7fr) minmax(420px,1.3fr); gap:16px; }
189
+ .run-list { display:flex; flex-direction:column; gap:8px; max-height:360px; overflow:auto; }
190
+ .run-card { border:1px solid var(--line); border-radius:12px; padding:11px; background:var(--panel); text-align:left; }
191
+ .run-card.selected { border-color:#93c5fd; background:var(--accent-soft); }
192
+ .detail-block { border-top:1px solid var(--line); padding-top:12px; margin-top:12px; }
193
+ .detail-block h3 { margin:0 0 8px; font-size:14px; }
194
+ .detail-text { white-space:pre-wrap; overflow-wrap:anywhere; color:var(--muted); font-size:13px; }
195
+ .curator-modal { position:fixed; inset:0; z-index:100; display:grid; place-items:center; padding:24px; background:rgba(15,23,42,.42); backdrop-filter:blur(6px); animation:curator-backdrop-in .18s ease-out both; }
196
+ .curator-modal.is-closing { animation:curator-backdrop-out .18s ease-in both; }
197
+ .curator-dialog { width:min(880px,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); animation:curator-dialog-in .22s cubic-bezier(.2,.8,.2,1) both; }
198
+ .curator-modal.is-closing .curator-dialog { animation:curator-dialog-out .18s ease-in both; }
199
+ .curator-dialog .panel-body { min-height:0; overflow-y:auto; }
200
+ .curator-dialog-head { align-items:flex-start; }
201
+ .curator-heading { display:flex; align-items:center; gap:10px; min-width:0; flex-wrap:wrap; }
202
+ .curator-header-actions { display:flex; align-items:center; justify-content:flex-end; gap:8px; min-width:0; margin-left:auto; }
203
+ .curator-actions { display:flex; align-items:center; gap:6px; flex-wrap:wrap; }
204
+ .curator-actions .button { padding:8px 10px; border-radius:10px; font-size:13px; white-space:nowrap; }
205
+ .curator-selection-count { color:var(--muted); font-size:12px; font-weight:700; white-space:nowrap; }
206
+ .curator-selection-summary { display:block; margin:0 0 10px; }
207
+ .curator-close { display:grid; place-items:center; flex:0 0 auto; width:44px; height:44px; border:1px solid var(--line); border-radius:12px; background:var(--panel); color:var(--muted); font-size:26px; line-height:1; }
208
+ .curator-close:hover { border-color:#93c5fd; background:var(--accent-soft); color:var(--accent); }
209
+ .curator-status { margin:0 0 12px; }
210
+ .curator-filters { display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:8px; margin:0 0 14px; padding:12px; border:1px solid var(--line); border-radius:12px; background:var(--surface); }
211
+ .curator-filter { display:grid; gap:4px; color:var(--muted); font-size:11px; font-weight:800; }
212
+ .curator-filter-check { display:flex; align-items:center; gap:6px; color:var(--muted); font-size:12px; font-weight:700; }
213
+ .curator-filter-check input { width:16px; height:16px; }
214
+ .curator-filter-tags { grid-column:1 / -1; display:flex; flex-wrap:wrap; gap:7px; padding-top:4px; }
215
+ .curator-filter-tags .tag.active { font-weight:800; text-decoration:underline; }
216
+ .curator-list { display:grid; gap:12px; }
217
+ .curator-card { border:1px solid var(--line); border-radius:14px; padding:16px; background:var(--panel); }
218
+ .curator-workspace { overflow-wrap:anywhere; }
219
+ .curator-card h3 { margin:8px 0; font-size:17px; }
220
+ .curator-overview { margin:8px 0 12px; color:var(--muted); white-space:pre-wrap; line-height:1.55; }
221
+ .curator-card-actions { display:flex; flex-wrap:wrap; gap:8px; margin:12px 0 0; }
222
+ .curator-review-details { margin-top:12px; }
223
+ .curator-draft { margin:12px 0; padding:12px; border:1px solid var(--line); border-radius:12px; background:var(--surface); }
224
+ .curator-draft h4 { margin:0 0 10px; font-size:14px; }
225
+ .curator-draft-label { margin:10px 0 4px; color:var(--muted); font-size:12px; font-weight:700; }
226
+ .curator-draft-value { margin:0; white-space:pre-wrap; overflow-wrap:anywhere; font:inherit; font-size:13px; line-height:1.5; }
227
+ .curator-reasons { color:var(--muted); font-size:12px; white-space:pre-wrap; }
228
+ .curator-confirm-modal { position:absolute; inset:0; z-index:2; display:grid; place-items:center; padding:24px; background:rgba(15,23,42,.58); }
229
+ .curator-confirm-dialog { width:min(680px,calc(100vw - 32px)); max-height:min(760px,calc(100vh - 48px)); display:flex; flex-direction:column; min-height:0; background:var(--panel); box-shadow:0 28px 90px rgba(15,23,42,.34); }
230
+ .curator-confirm-dialog .panel-body { min-height:0; overflow-y:auto; }
231
+ .curator-confirm-grid { display:grid; grid-template-columns:1fr 1fr; gap:10px; margin:0 0 14px; }
232
+ .curator-confirm-field { min-width:0; padding:11px 12px; border:1px solid var(--line); border-radius:12px; background:var(--surface); }
233
+ .curator-confirm-field dt { margin:0 0 5px; color:var(--muted); font-size:12px; font-weight:800; }
234
+ .curator-confirm-field dd { margin:0; overflow-wrap:anywhere; white-space:pre-wrap; }
235
+ .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; }
236
+ .curator-confirm-actions { display:flex; justify-content:flex-end; gap:8px; margin-top:14px; }
237
+ .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); }
238
+ .skill-dialog .panel-body { min-height:0; overflow-y:auto; }
239
+ .skill-list { display:grid; gap:12px; }
240
+ .skill-card { border:1px solid var(--line); border-radius:14px; padding:16px; background:var(--panel); }
241
+ .skill-card h3 { margin:8px 0; font-size:17px; overflow-wrap:anywhere; }
242
+ .skill-card-grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(180px,1fr)); gap:8px; margin-top:12px; }
243
+ .skill-field { min-width:0; padding:10px 11px; border:1px solid var(--line); border-radius:10px; background:var(--surface); }
244
+ .skill-field dt { margin:0 0 4px; color:var(--muted); font-size:11px; font-weight:800; }
245
+ .skill-field dd { margin:0; overflow-wrap:anywhere; white-space:pre-wrap; font-size:13px; }
246
+ .skill-card-actions { display:flex; flex-wrap:wrap; gap:8px; margin-top:12px; }
247
+ .skill-source-link { color:var(--accent); overflow-wrap:anywhere; }
248
+ @keyframes curator-backdrop-in { from { opacity:0; } to { opacity:1; } }
249
+ @keyframes curator-backdrop-out { from { opacity:1; } to { opacity:0; } }
250
+ @keyframes curator-dialog-in { from { opacity:0; transform:translateY(10px) scale(.98); } to { opacity:1; transform:translateY(0) scale(1); } }
251
+ @keyframes curator-dialog-out { from { opacity:1; transform:translateY(0) scale(1); } to { opacity:0; transform:translateY(6px) scale(.985); } }
252
+ @media (prefers-reduced-motion: reduce) {
253
+ .curator-modal,.curator-modal .curator-dialog,.curator-modal.is-closing,.curator-modal.is-closing .curator-dialog { animation-duration:.01ms; }
254
+ }
255
+ @media (max-width:680px) { .operator-grid { grid-template-columns:1fr; } }
256
+ @media (max-width:1050px) { .layout { grid-template-columns:180px minmax(280px,1fr); } .editor-panel { grid-column:1 / -1; } }
257
+ @media (max-width:680px) { .shell { padding:16px; } .topbar { display:block; position:relative; } .brand { padding-right:56px; } .topbar-side { margin-top:16px; align-self:auto; } .language-picker { position:absolute; top:0; right:0; } .toolbar { justify-content:stretch; margin-top:0; } .topbar-side .control,.topbar-side .search { flex:1 1 100%; width:100%; } .search { min-width:0; } .layout { grid-template-columns:1fr; } .genres-panel { order:0; } .list-panel { order:1; } .editor-panel { order:2; } .entry-list { max-height:none; } .curator-dialog-head { flex-wrap:wrap; } .curator-header-actions { flex:1 1 100%; width:100%; margin-left:0; } .curator-actions { justify-content:flex-end; } .curator-confirm-grid { grid-template-columns:1fr; } .curator-confirm-actions { flex-direction:column-reverse; } .curator-confirm-actions .button { width:100%; } }
258
+ </style>
259
+ </head>
260
+ <body>
261
+ <main id="app-main" class="shell">
262
+ <header class="topbar">
263
+ <div class="brand">
264
+ <div class="eyebrow" data-i18n="eyebrow">Local memory console</div>
265
+ <h1>Kiokuko Web</h1>
266
+ <p class="subtitle" data-i18n="subtitle">Browse SQLite memory by role and purpose, memory type, and cross-cutting tags, and safely edit candidate entries.</p>
267
+ </div>
268
+ <div class="topbar-side">
269
+ <div id="language-picker" class="language-picker">
270
+ <button id="language-toggle" class="language-toggle" type="button" aria-haspopup="menu" aria-expanded="false" aria-controls="language-menu" aria-label="Language" data-i18n-aria-label="languageLabel">
271
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="9"></circle><path d="M3 12h18M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18"></path></svg>
272
+ </button>
273
+ <div id="language-menu" class="language-menu" role="menu" aria-label="Language" data-i18n-aria-label="languageLabel" hidden></div>
274
+ </div>
275
+ <div class="toolbar">
276
+ <select id="workspace" class="control" aria-label="Workspace" data-i18n-aria-label="workspaceLabel"></select>
277
+ <input id="search" class="search" type="search" placeholder="Search memory…" aria-label="Search memory…" data-i18n-placeholder="searchPlaceholder" data-i18n-aria-label="searchPlaceholder">
278
+ <button id="curator-button" class="button" type="button" data-i18n="curator">Curator</button>
279
+ <button id="external-skills-button" class="button" type="button" data-i18n="openExternalSkills">External Skills</button>
280
+ <button id="refresh" class="button" type="button" data-i18n="refresh">Refresh</button>
281
+ </div>
282
+ </div>
283
+ </header>
284
+ <div id="status" class="status" role="status"></div>
285
+ <section class="layout">
286
+ <aside class="panel genres-panel">
287
+ <div class="panel-head"><h2 data-i18n="filtersPanelTitle">Role and purpose / tags</h2></div>
288
+ <nav id="genres" class="genres" aria-label="Filter by role and purpose, memory type, or tag" data-i18n-aria-label="filtersNavLabel"></nav>
289
+ </aside>
290
+ <section class="panel list-panel">
291
+ <div class="panel-head"><h2 id="list-title">Memory</h2><span id="result-count" class="badge">0 items</span></div>
292
+ <div class="panel-body"><div id="entry-list" class="entry-list"></div></div>
293
+ </section>
294
+ <section class="panel editor-panel">
295
+ <div class="panel-head"><h2 data-i18n="editorTitle">Details</h2><span id="editor-state" class="badge" data-i18n="unselected">Not selected</span></div>
296
+ <div class="panel-body"><div id="editor"></div></div>
297
+ </section>
298
+ </section>
299
+ <section class="panel operator-panel">
300
+ <div class="panel-head"><h2 data-i18n="operatorTitle">Agent run operator view</h2><span class="badge" data-i18n="trustBadge">stored data is untrusted / non-actionable</span></div>
301
+ <div class="panel-body operator-grid">
302
+ <div><div id="run-list" class="run-list"></div><div id="run-page" class="status"></div></div>
303
+ <div id="run-detail"><div class="editor-empty" data-i18n="runSelectFull">Select a run to view its intake, profile, timeline, delivery, feedback, and coverage.</div></div>
304
+ </div>
305
+ </section>
306
+ </main>
307
+ <div id="curator-modal" class="curator-modal" hidden>
308
+ <section id="curator-panel" class="panel curator-dialog" role="dialog" aria-modal="true" aria-labelledby="curator-title" aria-describedby="curator-description">
309
+ <div class="panel-head curator-dialog-head">
310
+ <div class="curator-heading"><h2 id="curator-title" data-i18n="curatorTitle">Curator</h2><span class="badge" data-i18n="curatorBadge">user confirmation required</span></div>
311
+ <div class="curator-header-actions">
312
+ <div id="curator-actions" class="curator-actions"></div>
313
+ <button id="curator-close" class="curator-close" type="button" aria-label="Close Curator" data-i18n-aria-label="curatorClose"><span aria-hidden="true">×</span></button>
314
+ </div>
315
+ </div>
316
+ <div class="panel-body">
317
+ <p id="curator-description" class="subtitle" data-i18n="curatorDescription">Review reusable knowledge candidates and add them to global memory.</p>
318
+ <div id="curator-filters" class="curator-filters" aria-label="Curator filters"></div>
319
+ <div class="curator-selection-summary"><span id="curator-result-count" class="curator-selection-count">0 candidates</span></div>
320
+ <div id="curator-status" class="status" role="status" aria-live="polite"></div>
321
+ <div id="curator-list" class="curator-list"></div>
322
+ </div>
323
+ </section>
324
+ <div id="curator-confirm-modal" class="curator-confirm-modal" hidden>
325
+ <section id="curator-confirm-panel" class="panel curator-confirm-dialog" role="alertdialog" aria-modal="true" aria-labelledby="curator-confirm-title" aria-describedby="curator-confirm-description">
326
+ <div class="panel-head">
327
+ <h2 id="curator-confirm-title" data-i18n="curatorConfirmTitle">Confirm Global memory addition</h2>
328
+ </div>
329
+ <div class="panel-body">
330
+ <p id="curator-confirm-description" class="subtitle" data-i18n="curatorConfirmDescription">Verify the source, applicability, and complete regenerated draft.</p>
331
+ <dl class="curator-confirm-grid">
332
+ <div class="curator-confirm-field"><dt data-i18n="curatorConfirmSource">Source project</dt><dd id="curator-confirm-source"></dd></div>
333
+ <div class="curator-confirm-field"><dt data-i18n="curatorConfirmSkill">Skill</dt><dd id="curator-confirm-skill"></dd></div>
334
+ <div class="curator-confirm-field"><dt data-i18n="curatorConfirmApplicability">Applicability</dt><dd id="curator-confirm-applicability"></dd></div>
335
+ </dl>
336
+ <h3 data-i18n="curatorConfirmDraft">Draft to add</h3>
337
+ <pre id="curator-confirm-draft" class="curator-confirm-draft"></pre>
338
+ <div id="curator-confirm-status" class="status curator-status" role="status" aria-live="polite"></div>
339
+ <div class="curator-confirm-actions">
340
+ <button id="curator-confirm-cancel" class="button" type="button" data-i18n="curatorCancel">Cancel</button>
341
+ <button id="curator-confirm-submit" class="button primary" type="button" data-i18n="curatorConfirmAction">Add this draft to Global</button>
342
+ </div>
343
+ </div>
344
+ </section>
345
+ </div>
346
+ </div>
347
+ <div id="external-skills-modal" class="curator-modal" hidden>
348
+ <section id="external-skills-panel" class="panel skill-dialog" role="dialog" aria-modal="true" aria-labelledby="external-skills-title" aria-describedby="external-skills-description">
349
+ <div class="panel-head curator-dialog-head">
350
+ <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>
351
+ <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>
352
+ </div>
353
+ <div class="panel-body">
354
+ <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>
355
+ <div id="external-skills-status" class="status" role="status" aria-live="polite"></div>
356
+ <div id="external-skills-list" class="skill-list"></div>
357
+ </div>
358
+ </section>
359
+ </div>
360
+ <script>
361
+ const i18n = ${WEB_I18N_CONFIG};
362
+ const validExternalSkillListItem = (${externalSkillListItemIsValid.toString()});
363
+ const validExternalSkillEntrySummary = (${externalSkillEntrySummaryIsValid.toString()});
364
+ const localeStorageKey = 'kiokuko.web.locale';
365
+ const normalizeLocale = (value) => {
366
+ if (typeof value !== 'string') return null;
367
+ const normalized = value.trim().replaceAll('_', '-').toLowerCase();
368
+ if (!normalized) return null;
369
+ const parts = normalized.split('-');
370
+ const language = parts[0];
371
+ if (language === 'en' || language === 'ja' || language === 'ko') return language;
372
+ if (language === 'zh' && (parts.length === 1 || parts.includes('hans') || parts.includes('cn') || parts.includes('sg'))) return 'zh-CN';
373
+ return null;
374
+ };
375
+ const isStorageAccessError = (error) => typeof DOMException !== 'undefined' && error instanceof DOMException;
376
+ const readStoredLocale = () => {
377
+ try { return localStorage.getItem(localeStorageKey); }
378
+ catch (error) {
379
+ if (!isStorageAccessError(error)) throw error;
380
+ return null;
381
+ }
382
+ };
383
+ const browserLocales = Array.isArray(navigator.languages) ? navigator.languages : [navigator.language];
384
+ const localeCandidates = [new URLSearchParams(location.search).get('lang'), readStoredLocale(), ...browserLocales];
385
+ const initialLocale = localeCandidates.map(normalizeLocale).find(Boolean) || i18n.defaultLocale;
386
+ const kinds = [
387
+ ['all', 'kind.all'], ['fact', 'kind.fact'], ['decision', 'kind.decision'], ['lesson', 'kind.lesson'], ['preference', 'kind.preference'], ['reference', 'kind.reference']
388
+ ];
389
+ const botModes = [
390
+ ['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']
391
+ ];
392
+ const curatorUrl = new URLSearchParams(location.search);
393
+ 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 };
394
+ const $ = (id) => document.getElementById(id);
395
+ const t = (key, parameters = {}) => {
396
+ const template = i18n.messages[state.locale]?.[key] ?? i18n.messages[i18n.defaultLocale]?.[key] ?? key;
397
+ return template.replace(/\{([^}]+)\}/g, (_match, name) => Object.prototype.hasOwnProperty.call(parameters, name) ? String(parameters[name]) : '');
398
+ };
399
+ const tp = (key, count) => {
400
+ const category = new Intl.PluralRules(state.locale).select(count) === 'one' ? 'one' : 'other';
401
+ return t(key + '.' + category, { count });
402
+ };
403
+ const setI18nText = (element, key) => { element.dataset.i18n = key; element.textContent = t(key); return element; };
404
+ const labelForKind = (kind) => { const item = kinds.find(([value]) => value === kind); return item ? t(item[1]) : kind; };
405
+ const labelForStatus = (status) => i18n.messages[state.locale]?.['status.' + status] ?? status;
406
+ const labelForOrigin = (origin) => t(origin === 'ecosystem' ? 'originEcosystem' : origin === 'global' ? 'originGlobal' : 'originProject');
407
+ const updateEditorState = () => {
408
+ const element = $('editor-state');
409
+ if (state.selected) { delete element.dataset.i18n; element.dataset.i18nStatus = state.selected.status; element.textContent = labelForStatus(state.selected.status); }
410
+ else { delete element.dataset.i18nStatus; setI18nText(element, 'unselected'); }
411
+ };
412
+ const showStatus = (message, error = false) => { const element = $('status'); element.textContent = message; element.className = error ? 'status notice error' : 'status'; element.setAttribute('role', error ? 'alert' : 'status'); element.setAttribute('aria-live', error ? 'assertive' : 'polite'); };
413
+ const setStatus = (message, error = false) => { state.localizedStatus = null; showStatus(message, error); };
414
+ const setLocalizedStatus = (key, parameters = {}, error = false) => { state.localizedStatus = { key, parameters, error }; showStatus(t(key, parameters), error); };
415
+ const setLocalizedCountStatus = (key, count, error = false) => { state.localizedStatus = { key, count, error, plural: true }; showStatus(tp(key, count), error); };
416
+ const renderLanguageMenu = () => {
417
+ const menu = $('language-menu');
418
+ menu.replaceChildren(...i18n.locales.map((locale) => {
419
+ const option = document.createElement('button');
420
+ option.type = 'button';
421
+ option.className = 'language-option';
422
+ option.lang = locale;
423
+ option.dataset.locale = locale;
424
+ option.setAttribute('role', 'menuitemradio');
425
+ option.setAttribute('aria-checked', String(locale === state.locale));
426
+ option.textContent = i18n.localeLabels[locale];
427
+ option.addEventListener('click', () => selectLocale(locale));
428
+ return option;
429
+ }));
430
+ };
431
+ const setLanguageMenuOpen = (open, restoreFocus = false) => {
432
+ const menu = $('language-menu');
433
+ const toggle = $('language-toggle');
434
+ menu.hidden = !open;
435
+ toggle.setAttribute('aria-expanded', String(open));
436
+ if (open) requestAnimationFrame(() => menu.querySelector('[aria-checked="true"]')?.focus());
437
+ else if (restoreFocus) toggle.focus();
438
+ };
439
+ const selectLocale = (value) => {
440
+ state.locale = normalizeLocale(value) || i18n.defaultLocale;
441
+ try { localStorage.setItem(localeStorageKey, state.locale); }
442
+ catch (error) { if (!isStorageAccessError(error)) throw error; }
443
+ setLanguageMenuOpen(false, true);
444
+ applyTranslations(); renderFilters(); renderEntries(); renderRuns(); renderRunDetail(); renderCurator(); renderExternalSkills(); updateEditorState();
445
+ };
446
+ const applyTranslations = () => {
447
+ document.documentElement.lang = state.locale;
448
+ document.querySelectorAll('[data-i18n]').forEach((element) => { element.textContent = t(element.dataset.i18n); });
449
+ document.querySelectorAll('[data-i18n-aria-label]').forEach((element) => { element.setAttribute('aria-label', t(element.dataset.i18nAriaLabel)); });
450
+ document.querySelectorAll('[data-i18n-placeholder]').forEach((element) => { element.setAttribute('placeholder', t(element.dataset.i18nPlaceholder)); });
451
+ document.querySelectorAll('[data-i18n-status]').forEach((element) => {
452
+ const value = labelForStatus(element.dataset.i18nStatus);
453
+ if ('value' in element) element.value = value; else element.textContent = value;
454
+ });
455
+ renderLanguageMenu();
456
+ if (state.localizedStatus) showStatus(state.localizedStatus.plural ? tp(state.localizedStatus.key, state.localizedStatus.count) : t(state.localizedStatus.key, state.localizedStatus.parameters), state.localizedStatus.error);
457
+ };
458
+ const apiError = (value) => {
459
+ const rawCode = value?.error?.code;
460
+ const rawMessage = value?.error?.message;
461
+ const code = typeof rawCode === 'string' && /^[A-Z][A-Z0-9_]{0,63}$/.test(rawCode) ? rawCode : 'REQUEST_FAILED';
462
+ const normalizedMessage = typeof rawMessage === 'string' ? rawMessage.replace(/[\u0000-\u001f\u007f]+/g, ' ').trim().slice(0, 300) : '';
463
+ const error = new Error(normalizedMessage || t('requestFailed'));
464
+ error.code = code;
465
+ return error;
466
+ };
467
+ const apiErrorText = (error) => {
468
+ const code = error instanceof Error && typeof error.code === 'string' && /^[A-Z][A-Z0-9_]{0,63}$/.test(error.code) ? error.code : 'REQUEST_FAILED';
469
+ const normalizedMessage = error instanceof Error ? error.message.replace(/[\u0000-\u001f\u007f]+/g, ' ').trim().slice(0, 300) : '';
470
+ return '[' + code + '] ' + (normalizedMessage || t('requestFailed'));
471
+ };
472
+ const api = async (path, options) => {
473
+ const response = await fetch(path, options);
474
+ const value = await response.json();
475
+ if (!response.ok) throw apiError(value);
476
+ return value;
477
+ };
478
+ async function loadEntrySelection(id) {
479
+ const result = await api('/api/entries/' + encodeURIComponent(id) + '?workspace=' + encodeURIComponent(state.workspace));
480
+ state.selectedRecall = null; state.selected = result.entry; renderEntries(); renderEditor();
481
+ }
482
+ async function copyTextToClipboard(text) {
483
+ if (!navigator.clipboard?.writeText) throw new Error('Clipboard API unavailable');
484
+ await navigator.clipboard.writeText(text);
485
+ }
486
+ function showEntryConflictGuide(entryId, draftText) {
487
+ state.localizedStatus = null;
488
+ const root = $('status'); root.className = 'status conflict-guide'; root.setAttribute('role', 'alert'); root.setAttribute('aria-live', 'assertive');
489
+ const heading = document.createElement('h2'); setI18nText(heading, 'entryConflictTitle');
490
+ const explanation = document.createElement('p'); setI18nText(explanation, 'entryConflictExplanation');
491
+ const steps = document.createElement('ol');
492
+ for (const key of ['entryConflictStepCopy', 'entryConflictStepReload', 'entryConflictStepCompare']) { const item = document.createElement('li'); setI18nText(item, key); steps.append(item); }
493
+ const applyHint = document.createElement('p'); applyHint.id = 'entry-conflict-apply-hint'; setI18nText(applyHint, 'entryConflictApplyHint');
494
+ const actions = document.createElement('div'); actions.className = 'conflict-guide-actions';
495
+ const apply = document.createElement('button'); apply.type = 'button'; apply.className = 'button primary'; apply.setAttribute('aria-describedby', applyHint.id); setI18nText(apply, 'entryConflictApply');
496
+ const copy = document.createElement('button'); copy.type = 'button'; copy.className = 'button'; setI18nText(copy, 'entryConflictCopy');
497
+ const reload = document.createElement('button'); reload.type = 'button'; reload.className = 'button'; setI18nText(reload, 'entryConflictReload');
498
+ const feedback = document.createElement('div'); feedback.className = 'conflict-guide-feedback'; feedback.setAttribute('role', 'status'); feedback.setAttribute('aria-live', 'polite');
499
+ const actionsDisabled = (disabled) => { for (const action of [apply, copy, reload]) action.disabled = disabled; };
500
+ apply.addEventListener('click', async () => {
501
+ actionsDisabled(true); setI18nText(apply, 'entryConflictApplying');
502
+ try {
503
+ await copyTextToClipboard(draftText());
504
+ } catch {
505
+ actionsDisabled(false); setI18nText(apply, 'entryConflictApply');
506
+ feedback.className = 'conflict-guide-feedback error'; setI18nText(feedback, 'entryConflictApplyCopyFailed');
507
+ return;
508
+ }
509
+ try {
510
+ await loadEntrySelection(entryId);
511
+ setLocalizedStatus('entryConflictApplied');
512
+ } catch (error) {
513
+ actionsDisabled(false); setI18nText(apply, 'entryConflictApply');
514
+ feedback.className = 'conflict-guide-feedback error'; feedback.textContent = t('entryConflictApplyReloadFailed') + ' ' + apiErrorText(error);
515
+ }
516
+ });
517
+ copy.addEventListener('click', async () => {
518
+ actionsDisabled(true); setI18nText(copy, 'entryConflictCopying');
519
+ try {
520
+ await copyTextToClipboard(draftText());
521
+ feedback.className = 'conflict-guide-feedback'; setI18nText(feedback, 'entryConflictCopied');
522
+ } catch {
523
+ feedback.className = 'conflict-guide-feedback error'; setI18nText(feedback, 'entryConflictCopyFailed');
524
+ } finally {
525
+ actionsDisabled(false); setI18nText(copy, 'entryConflictCopy');
526
+ }
527
+ });
528
+ reload.addEventListener('click', async () => {
529
+ actionsDisabled(true); setI18nText(reload, 'entryConflictReloading');
530
+ try {
531
+ await loadEntrySelection(entryId);
532
+ setLocalizedStatus('entryConflictReloaded');
533
+ } catch (error) {
534
+ actionsDisabled(false); setI18nText(reload, 'entryConflictReload');
535
+ feedback.className = 'conflict-guide-feedback error'; feedback.textContent = apiErrorText(error);
536
+ }
537
+ });
538
+ actions.append(apply, copy, reload); root.replaceChildren(heading, explanation, steps, applyHint, actions, feedback);
539
+ requestAnimationFrame(() => root.scrollIntoView({ block: 'nearest' }));
540
+ }
541
+ const escapeTags = (value) => value.split(',').map((item) => item.trim()).filter(Boolean);
542
+ const setCuratorStatus = (message, error = false) => {
543
+ const element = $('curator-status');
544
+ element.textContent = message;
545
+ element.className = error ? 'status notice error curator-status' : 'status curator-status';
546
+ };
547
+ const setCuratorBackgroundBlocked = (blocked) => {
548
+ const appMain = $('app-main');
549
+ appMain.inert = blocked;
550
+ if (blocked) appMain.setAttribute('aria-hidden', 'true');
551
+ else appMain.removeAttribute('aria-hidden');
552
+ };
553
+ function restoreCuratorUrl() {
554
+ const params = new URLSearchParams(location.search);
555
+ state.curatorSearch = params.get('search') || '';
556
+ state.curatorProject = params.get('project') || '';
557
+ state.curatorTags = new Set(params.getAll('tag'));
558
+ state.curatorFramework = params.get('framework') || '';
559
+ state.curatorLanguage = params.get('language') || '';
560
+ state.curatorMemoryClass = params.get('memoryClass') || '';
561
+ state.curatorTier = params.get('tier') || '';
562
+ state.curatorReady = params.get('ready') === 'true';
563
+ state.curatorIncludeGlobalized = params.get('includeGlobalized') === 'true';
564
+ }
565
+ function syncCuratorUrl(push = false) {
566
+ const params = new URLSearchParams(location.search);
567
+ for (const key of ['search', 'project', 'framework', 'language', 'memoryClass', 'tier', 'ready', 'includeGlobalized', 'tag']) params.delete(key);
568
+ if (state.curatorSearch) params.set('search', state.curatorSearch);
569
+ if (state.curatorProject) params.set('project', state.curatorProject);
570
+ if (state.curatorFramework) params.set('framework', state.curatorFramework);
571
+ if (state.curatorLanguage) params.set('language', state.curatorLanguage);
572
+ if (state.curatorMemoryClass) params.set('memoryClass', state.curatorMemoryClass);
573
+ if (state.curatorTier) params.set('tier', state.curatorTier);
574
+ if (state.curatorReady) params.set('ready', 'true');
575
+ if (state.curatorIncludeGlobalized) params.set('includeGlobalized', 'true');
576
+ for (const tag of state.curatorTags) params.append('tag', tag);
577
+ const nextUrl = location.pathname + (params.toString() ? '?' + params.toString() : '');
578
+ if (push) history.pushState(null, '', nextUrl); else history.replaceState(null, '', nextUrl);
579
+ }
580
+ function curatorFilterSelect(label, values, value, onChange) {
581
+ const wrapper = document.createElement('label'); wrapper.className = 'curator-filter';
582
+ const text = document.createElement('span'); text.textContent = label;
583
+ const select = document.createElement('select');
584
+ const all = document.createElement('option'); all.value = ''; all.textContent = 'All'; select.append(all);
585
+ for (const item of values || []) { const option = document.createElement('option'); option.value = item.value || item.workspace; option.textContent = item.name || item.value || item.workspace; select.append(option); }
586
+ select.value = value || ''; select.addEventListener('change', () => onChange(select.value)); wrapper.append(text, select); return wrapper;
587
+ }
588
+ function renderCuratorFilters() {
589
+ const root = $('curator-filters'); if (!root) return;
590
+ const facets = state.curatorFacets || {};
591
+ const search = document.createElement('input'); search.type = 'search'; search.placeholder = 'Search candidates'; search.value = state.curatorSearch; search.addEventListener('input', () => { state.curatorSearch = search.value.trim(); clearTimeout(state.curatorSearchTimer); state.curatorSearchTimer = setTimeout(() => { syncCuratorUrl(true); loadCurator(); }, 180); });
592
+ const project = curatorFilterSelect('Project', facets.projects, state.curatorProject, (value) => { state.curatorProject = value; syncCuratorUrl(true); loadCurator(); });
593
+ const framework = curatorFilterSelect('Framework', facets.frameworks, state.curatorFramework, (value) => { state.curatorFramework = value; syncCuratorUrl(true); loadCurator(); });
594
+ const language = curatorFilterSelect('Language', facets.languages, state.curatorLanguage, (value) => { state.curatorLanguage = value; syncCuratorUrl(true); loadCurator(); });
595
+ const memoryClass = curatorFilterSelect('Memory class', facets.memoryClasses, state.curatorMemoryClass, (value) => { state.curatorMemoryClass = value; syncCuratorUrl(true); loadCurator(); });
596
+ const readiness = curatorFilterSelect('Readiness', [{ value: 'portable', name: 'Portable' }, { value: 'repeated', name: 'Repeated' }, { value: 'observed', name: 'Observed' }], state.curatorTier, (value) => { state.curatorTier = value; syncCuratorUrl(true); loadCurator(); });
597
+ const ready = document.createElement('label'); ready.className = 'curator-filter-check'; const readyInput = document.createElement('input'); readyInput.type = 'checkbox'; readyInput.checked = state.curatorReady; readyInput.addEventListener('change', () => { state.curatorReady = readyInput.checked; syncCuratorUrl(true); loadCurator(); }); ready.append(readyInput, document.createTextNode('Skill-ready'));
598
+ const globalized = document.createElement('label'); globalized.className = 'curator-filter-check'; const globalizedInput = document.createElement('input'); globalizedInput.type = 'checkbox'; globalizedInput.checked = state.curatorIncludeGlobalized; globalizedInput.addEventListener('change', () => { state.curatorIncludeGlobalized = globalizedInput.checked; syncCuratorUrl(true); loadCurator(); }); globalized.append(globalizedInput, document.createTextNode('Show already globalized'));
599
+ const tags = document.createElement('div'); tags.className = 'curator-filter-tags'; for (const facet of facets.tags || []) { const button = document.createElement('button'); button.type = 'button'; button.className = 'tag' + (state.curatorTags.has(facet.value) ? ' active' : ''); button.textContent = '#' + facet.value + ' (' + facet.count + ')'; button.addEventListener('click', () => { if (state.curatorTags.has(facet.value)) state.curatorTags.delete(facet.value); else state.curatorTags.add(facet.value); syncCuratorUrl(true); loadCurator(); }); tags.append(button); }
600
+ root.replaceChildren(search, project, framework, language, memoryClass, readiness, ready, globalized, tags);
601
+ }
602
+ function openCurator() {
603
+ if (state.curatorOpen) { $('curator-close')?.focus(); return; }
604
+ state.curatorPreviousFocus = document.activeElement instanceof HTMLElement ? document.activeElement : null;
605
+ state.curatorOpen = true;
606
+ const modal = $('curator-modal');
607
+ modal.classList.remove('is-closing');
608
+ setCuratorBackgroundBlocked(true);
609
+ renderCurator();
610
+ requestAnimationFrame(() => $('curator-close')?.focus());
611
+ }
612
+ function closeCurator() {
613
+ if (state.curatorGlobalizeBusy) return;
614
+ if (state.curatorPendingCandidate) closeCuratorConfirmation(false);
615
+ const modal = $('curator-modal');
616
+ if (modal.hidden) return;
617
+ state.curatorOpen = false;
618
+ modal.classList.add('is-closing');
619
+ let finished = false;
620
+ const finish = () => {
621
+ if (finished) return;
622
+ finished = true;
623
+ modal.hidden = true;
624
+ modal.classList.remove('is-closing');
625
+ setCuratorBackgroundBlocked(false);
626
+ const previousFocus = state.curatorPreviousFocus;
627
+ state.curatorPreviousFocus = null;
628
+ if (previousFocus?.isConnected) previousFocus.focus();
629
+ else $('curator-button')?.focus();
630
+ };
631
+ modal.addEventListener('animationend', (event) => { if (event.target === modal) finish(); }, { once: true });
632
+ window.setTimeout(finish, 220);
633
+ }
634
+ function handleCuratorKeydown(event) {
635
+ if (event.key === 'Escape') { event.preventDefault(); closeCurator(); return; }
636
+ if (event.key !== 'Tab') return;
637
+ const modal = $('curator-modal');
638
+ const focusable = [...modal.querySelectorAll('button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])')];
639
+ if (!focusable.length) { event.preventDefault(); return; }
640
+ const first = focusable[0];
641
+ const last = focusable.at(-1);
642
+ if (event.shiftKey && document.activeElement === first) { event.preventDefault(); last.focus(); }
643
+ else if (!event.shiftKey && document.activeElement === last) { event.preventDefault(); first.focus(); }
644
+ }
645
+
646
+ const setExternalSkillsStatus = (message, error = false) => {
647
+ const element = $('external-skills-status');
648
+ element.textContent = message;
649
+ element.className = error ? 'status notice error curator-status' : 'status curator-status';
650
+ };
651
+ function openExternalSkills() {
652
+ if (state.externalSkillsOpen) { $('external-skills-close')?.focus(); return; }
653
+ state.externalSkillsPreviousFocus = document.activeElement instanceof HTMLElement ? document.activeElement : null;
654
+ state.externalSkillsOpen = true;
655
+ const modal = $('external-skills-modal');
656
+ modal.classList.remove('is-closing');
657
+ setCuratorBackgroundBlocked(true);
658
+ modal.hidden = false;
659
+ requestAnimationFrame(() => $('external-skills-close')?.focus());
660
+ }
661
+ function closeExternalSkills() {
662
+ if (state.externalSkillsBusy) return;
663
+ const modal = $('external-skills-modal');
664
+ if (modal.hidden) return;
665
+ state.externalSkillsOpen = false;
666
+ state.externalSkillsPendingDisable = null;
667
+ modal.classList.add('is-closing');
668
+ let finished = false;
669
+ const finish = () => {
670
+ if (finished) return;
671
+ finished = true;
672
+ modal.hidden = true;
673
+ modal.classList.remove('is-closing');
674
+ setCuratorBackgroundBlocked(false);
675
+ const previousFocus = state.externalSkillsPreviousFocus;
676
+ state.externalSkillsPreviousFocus = null;
677
+ if (previousFocus?.isConnected) previousFocus.focus(); else $('external-skills-button')?.focus();
678
+ };
679
+ modal.addEventListener('animationend', (event) => { if (event.target === modal) finish(); }, { once: true });
680
+ window.setTimeout(finish, 220);
681
+ }
682
+ function handleExternalSkillsKeydown(event) {
683
+ if (event.key === 'Escape') { event.preventDefault(); closeExternalSkills(); return; }
684
+ if (event.key !== 'Tab') return;
685
+ const modal = $('external-skills-modal');
686
+ const focusable = [...modal.querySelectorAll('button:not([disabled]), a[href], [tabindex]:not([tabindex="-1"])')];
687
+ if (!focusable.length) { event.preventDefault(); return; }
688
+ const first = focusable[0]; const last = focusable.at(-1);
689
+ if (event.shiftKey && document.activeElement === first) { event.preventDefault(); last.focus(); }
690
+ else if (!event.shiftKey && document.activeElement === last) { event.preventDefault(); first.focus(); }
691
+ }
692
+ function skillField(labelKey, value) {
693
+ const field = document.createElement('div'); field.className = 'skill-field';
694
+ const label = document.createElement('dt'); setI18nText(label, labelKey);
695
+ const content = document.createElement('dd'); content.textContent = value || t('unknown');
696
+ field.append(label, content); return field;
697
+ }
698
+ function externalSkillButton(attribute, skillId) {
699
+ return [...document.querySelectorAll('[' + attribute + ']')].find((element) => element.getAttribute(attribute) === skillId);
700
+ }
701
+ function externalSkillSourceUrl(skill) {
702
+ return /^[A-Za-z0-9_.-]{1,100}\/[A-Za-z0-9_.-]{1,100}$/.test(skill.sourceLocator) ? 'https://github.com/' + skill.sourceLocator : null;
703
+ }
704
+ function renderExternalSkills() {
705
+ if (!state.externalSkillsOpen) return;
706
+ const root = $('external-skills-list');
707
+ if (!state.externalSkills.length) { const empty = document.createElement('div'); empty.className = 'editor-empty'; setI18nText(empty, 'externalSkillsEmpty'); root.replaceChildren(empty); return; }
708
+ root.replaceChildren(...state.externalSkills.map((skill) => {
709
+ const card = document.createElement('article'); card.className = 'skill-card';
710
+ const meta = document.createElement('div'); meta.className = 'entry-meta';
711
+ const stateBadge = document.createElement('span'); stateBadge.className = 'badge ' + (skill.state === 'disabled' ? 'superseded' : skill.state === 'imported' ? 'verified' : 'candidate'); stateBadge.textContent = skill.state;
712
+ const official = document.createElement('span'); official.className = 'badge'; official.textContent = skill.officialStatus;
713
+ meta.append(stateBadge, official);
714
+ const heading = document.createElement('h3'); heading.textContent = skill.name;
715
+ const fields = document.createElement('dl'); fields.className = 'skill-card-grid';
716
+ fields.append(
717
+ skillField('externalSkillsSource', skill.sourceLocator + '/' + skill.slug),
718
+ skillField('externalSkillsCommit', skill.sourceCommit ? skill.sourceCommit.slice(0, 12) : null),
719
+ skillField('externalSkillsSnapshot', skill.snapshotHash ? skill.snapshotHash.slice(0, 12) : null),
720
+ skillField('externalSkillsDocuments', String(skill.metadata?.documents ?? 0)),
721
+ skillField('externalSkillsFirstSeen', skill.firstSeenAt),
722
+ skillField('externalSkillsLastChecked', skill.lastCheckedAt),
723
+ skillField('externalSkillsTechnology', skill.metadata?.technology ?? skill.name),
724
+ skillField('externalSkillsAudit', skill.auditStatus),
725
+ skillField('externalSkillsState', skill.state),
726
+ );
727
+ const notice = document.createElement('div'); notice.className = 'notice'; setI18nText(notice, 'externalSkillsUntrusted');
728
+ const actions = document.createElement('div'); actions.className = 'skill-card-actions';
729
+ const sourceUrl = externalSkillSourceUrl(skill);
730
+ 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); }
731
+ 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);
732
+ const action = skill.state === 'disabled' ? 'enable' : skill.state === 'imported' ? 'disable' : null;
733
+ if (action === 'disable' && state.externalSkillsPendingDisable === skill.skillId) {
734
+ const confirmation = document.createElement('div'); confirmation.className = 'notice'; confirmation.textContent = t('externalSkillsDisableConfirm');
735
+ 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));
736
+ 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()); });
737
+ actions.append(confirmation, confirm, cancel);
738
+ } else if (action !== null) {
739
+ 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);
740
+ }
741
+ const mapping = document.createElement('div'); mapping.className = 'detail-text'; mapping.hidden = true;
742
+ 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 () => {
743
+ viewEntries.disabled = true;
744
+ try {
745
+ const detail = externalSkillDetail(await api('/api/skills/' + encodeURIComponent(skill.skillId)), skill.skillId);
746
+ if (detail === null) throw apiError({ error: { code: 'INVALID_RESPONSE', message: t('requestFailed') } });
747
+ const entries = detail.entries;
748
+ mapping.textContent = entries.length ? entries.map((entry) => entry.sourcePath + '#' + entry.chunkIndex + ' → ' + entry.entryId + '@' + entry.revision + (entry.active ? '' : ' (inactive)')).join('\n') : t('externalSkillsNoEntries');
749
+ mapping.hidden = false;
750
+ viewEntries.setAttribute('aria-expanded', 'true');
751
+ } catch {
752
+ mapping.textContent = '';
753
+ mapping.hidden = true;
754
+ viewEntries.setAttribute('aria-expanded', 'false');
755
+ setExternalSkillsStatus(t('externalSkillsFailure'), true);
756
+ }
757
+ finally { viewEntries.disabled = state.externalSkillsBusy; }
758
+ });
759
+ actions.append(viewEntries);
760
+ card.append(meta, heading, fields, notice, actions, mapping); return card;
761
+ }));
762
+ }
763
+ async function reloadExternalSkills() {
764
+ const skills = [];
765
+ const skillIds = new Set();
766
+ const cursors = new Set();
767
+ let cursor = null;
768
+ for (let page = 0; page < 100; page += 1) {
769
+ const result = await api('/api/skills?limit=200' + (cursor === null ? '' : '&cursor=' + encodeURIComponent(cursor)));
770
+ if (!result || typeof result !== 'object' || Array.isArray(result)
771
+ || Object.keys(result).length !== 5
772
+ || result.untrusted !== true
773
+ || !Array.isArray(result.skills) || result.skills.length > 200
774
+ || !Number.isSafeInteger(result.count) || result.count !== result.skills.length
775
+ || typeof result.truncated !== 'boolean'
776
+ || result.nextCursor !== null && typeof result.nextCursor !== 'string') throw apiError({ error: { code: 'INVALID_RESPONSE', message: t('requestFailed') } });
777
+ if (skills.length + result.skills.length > 20_000) throw apiError({ error: { code: 'INVALID_RESPONSE', message: t('requestFailed') } });
778
+ for (const skill of result.skills) {
779
+ if (!validExternalSkillListItem(skill) || skillIds.has(skill.skillId)) throw apiError({ error: { code: 'INVALID_RESPONSE', message: t('requestFailed') } });
780
+ skillIds.add(skill.skillId); skills.push(skill);
781
+ }
782
+ if (!result.truncated) {
783
+ if (result.nextCursor !== null) throw apiError({ error: { code: 'INVALID_RESPONSE', message: t('requestFailed') } });
784
+ state.externalSkills = skills;
785
+ renderExternalSkills();
786
+ return;
787
+ }
788
+ 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') } });
789
+ cursors.add(result.nextCursor); cursor = result.nextCursor;
790
+ }
791
+ throw apiError({ error: { code: 'INVALID_RESPONSE', message: t('requestFailed') } });
792
+ }
793
+ function externalSkillDetail(result, expectedSkillId) {
794
+ if (!result || typeof result !== 'object' || Array.isArray(result)
795
+ || Object.keys(result).length !== 4 || result.untrusted !== true
796
+ || !validExternalSkillListItem(result.skill) || result.skill.skillId !== expectedSkillId
797
+ || !Array.isArray(result.entries) || result.entries.length > 200
798
+ || typeof result.entriesTruncated !== 'boolean'
799
+ || result.entriesTruncated && result.entries.length !== 200
800
+ || result.skill.sourceCommit === null && result.entries.length !== 0) return null;
801
+ const entryIds = new Set(); const mappingIds = new Set();
802
+ for (const entry of result.entries) {
803
+ const mappingId = validExternalSkillEntrySummary(entry) ? entry.sourcePath + '\u0000' + entry.chunkIndex : null;
804
+ if (mappingId === null || entryIds.has(entry.entryId) || mappingIds.has(mappingId)) return null;
805
+ entryIds.add(entry.entryId); mappingIds.add(mappingId);
806
+ }
807
+ return { skill: result.skill, entries: result.entries, entriesTruncated: result.entriesTruncated };
808
+ }
809
+ async function reloadExternalSkill(skillId) {
810
+ const detail = externalSkillDetail(await api('/api/skills/' + encodeURIComponent(skillId)), skillId);
811
+ if (detail === null) throw apiError({ error: { code: 'INVALID_RESPONSE', message: t('requestFailed') } });
812
+ const index = state.externalSkills.findIndex((skill) => skill.skillId === skillId);
813
+ if (index < 0) throw apiError({ error: { code: 'INVALID_RESPONSE', message: t('requestFailed') } });
814
+ state.externalSkills[index] = detail.skill;
815
+ renderExternalSkills();
816
+ }
817
+ async function externalSkillAction(skillId, action, confirmed = false) {
818
+ if (state.externalSkillsBusy) return;
819
+ if (action === 'disable' && !confirmed) { state.externalSkillsPendingDisable = skillId; renderExternalSkills(); requestAnimationFrame(() => externalSkillButton('data-external-skill-confirm', skillId)?.focus()); return; }
820
+ state.externalSkillsPendingDisable = null;
821
+ state.externalSkillsBusy = true;
822
+ $('external-skills-refresh').disabled = true;
823
+ $('external-skills-panel').setAttribute('aria-busy', 'true');
824
+ setExternalSkillsStatus(action === 'refresh' ? t('externalSkillsRefreshing') : t('externalSkillsLoading'));
825
+ renderExternalSkills();
826
+ try {
827
+ let actionError = null;
828
+ try {
829
+ await api('/api/skills/' + encodeURIComponent(skillId) + '/' + action, { method: 'POST' });
830
+ } catch (error) {
831
+ actionError = error;
832
+ }
833
+ let reloadError = null;
834
+ try {
835
+ await reloadExternalSkill(skillId);
836
+ } catch (error) {
837
+ reloadError = error;
838
+ }
839
+ if (reloadError) {
840
+ state.externalSkills = [];
841
+ state.externalSkillsPendingDisable = null;
842
+ }
843
+ if (actionError) {
844
+ const reloadFailure = reloadError ? ' / ' + apiErrorText(reloadError) : '';
845
+ setExternalSkillsStatus(apiErrorText(actionError) + reloadFailure, true);
846
+ } else if (reloadError) {
847
+ setExternalSkillsStatus(apiErrorText(reloadError), true);
848
+ } else {
849
+ setExternalSkillsStatus(t(action === 'disable' ? 'externalSkillsDisabled' : action === 'enable' ? 'externalSkillsEnabled' : 'externalSkillsRefreshed'));
850
+ }
851
+ } finally {
852
+ state.externalSkillsBusy = false;
853
+ $('external-skills-refresh').disabled = false;
854
+ $('external-skills-panel').removeAttribute('aria-busy');
855
+ renderExternalSkills();
856
+ requestAnimationFrame(() => externalSkillButton(action === 'refresh' ? 'data-external-skill-refresh' : 'data-external-skill-toggle', skillId)?.focus());
857
+ }
858
+ }
859
+ async function loadExternalSkills(open = true) {
860
+ if (state.externalSkillsBusy) return;
861
+ if (open) openExternalSkills();
862
+ state.externalSkills = [];
863
+ state.externalSkillsPendingDisable = null;
864
+ state.externalSkillsBusy = true;
865
+ $('external-skills-refresh').disabled = true;
866
+ renderExternalSkills();
867
+ setExternalSkillsStatus(t('externalSkillsLoading'));
868
+ $('external-skills-panel').setAttribute('aria-busy', 'true');
869
+ try {
870
+ await reloadExternalSkills();
871
+ setExternalSkillsStatus('');
872
+ } catch (error) {
873
+ setExternalSkillsStatus(t('externalSkillsOffline') + ' ' + apiErrorText(error), true);
874
+ } finally {
875
+ $('external-skills-panel').removeAttribute('aria-busy');
876
+ state.externalSkillsBusy = false;
877
+ $('external-skills-refresh').disabled = false;
878
+ renderExternalSkills();
879
+ }
880
+ }
881
+
882
+ function filterButton(key, label, count, active, onClick) {
883
+ const button = document.createElement('button');
884
+ button.type = 'button';
885
+ button.className = 'genre ' + (active ? 'active' : '');
886
+ const text = document.createElement('span'); text.textContent = label;
887
+ const countBadge = document.createElement('span'); countBadge.className = 'count'; countBadge.textContent = String(count || 0);
888
+ button.append(text, countBadge);
889
+ button.dataset.filter = key;
890
+ button.addEventListener('click', onClick);
891
+ return button;
892
+ }
893
+
894
+ function filterGroup(title, buttons) {
895
+ const group = document.createElement('section'); group.className = 'filter-group';
896
+ const heading = document.createElement('div'); heading.className = 'filter-group-title'; heading.textContent = title; group.append(heading, ...buttons); return group;
897
+ }
898
+
899
+ function renderFilters() {
900
+ const kindCounts = Object.fromEntries(kinds.map(([kind]) => [kind, kind === 'all' ? state.entries.length : state.entries.filter((entry) => entry.kind === kind).length]));
901
+ const tagCounts = Object.fromEntries(state.tags.map((item) => [item.tag, item.count]));
902
+ const botButtons = botModes.map(([tag, label]) => filterButton(tag, t(label), tagCounts[tag], state.tag === tag, () => { state.tag = tag; renderFilters(); loadEntries(); }));
903
+ const kindButtons = kinds.map(([kind, label]) => filterButton(kind, t(label), kindCounts[kind], state.kind === kind, () => { state.kind = kind; renderFilters(); loadEntries(); }));
904
+ const tagButtons = state.tags
905
+ .filter((item) => !botModes.some(([tag]) => tag === item.tag))
906
+ .map((item) => filterButton(item.tag, '#' + item.tag, item.count, state.tag === item.tag, () => { state.tag = item.tag; renderFilters(); loadEntries(); }));
907
+ const root = $('genres'); root.replaceChildren(filterGroup(t('botFilterTitle'), botButtons), filterGroup(t('memoryTypeFilterTitle'), kindButtons));
908
+ if (tagButtons.length > 0) root.append(filterGroup(t('crossTagFilterTitle'), tagButtons));
909
+ }
910
+
911
+ function renderFederatedItems() {
912
+ const list = $('entry-list');
913
+ list.replaceChildren(...state.recallItems.map((item) => {
914
+ const card = document.createElement('article'); card.className = 'entry-card federated-card ' + (item.origin === 'global' ? 'global' : '');
915
+ const meta = document.createElement('div'); meta.className = 'entry-meta';
916
+ const origin = document.createElement('span'); origin.className = 'badge origin-' + item.origin; origin.textContent = labelForOrigin(item.origin);
917
+ const kind = document.createElement('span'); kind.className = 'badge'; kind.textContent = labelForKind(item.kind);
918
+ const status = document.createElement('span'); status.className = 'badge ' + item.status; status.textContent = labelForStatus(item.status);
919
+ meta.append(origin, kind, status);
920
+ const title = document.createElement('h3'); title.textContent = item.title;
921
+ const snippet = document.createElement('p'); snippet.className = 'snippet'; snippet.textContent = item.snippet;
922
+ const source = document.createElement('div'); source.className = 'federated-source';
923
+ const sourceLines = [];
924
+ if (item.sourceWorkspace) sourceLines.push(t('sourceWorkspace', { workspace: item.sourceWorkspace }));
925
+ if (item.sourceProject) sourceLines.push(t('sourceProject', { project: item.sourceProject }));
926
+ source.textContent = sourceLines.join('\n');
927
+ const tags = document.createElement('div'); tags.className = 'tags'; item.tags.forEach((tag) => { const tagItem = document.createElement('span'); tagItem.className = 'tag'; tagItem.textContent = '#' + tag; tags.append(tagItem); });
928
+ const reasons = document.createElement('div'); reasons.className = 'selection-reasons'; reasons.textContent = [t('selectionReasons'), ...item.selectionReasons.map((reason) => '• ' + reason)].join('\n');
929
+ card.append(meta, title, snippet, source, tags, reasons); card.addEventListener('click', () => { state.selected = null; state.selectedRecall = item; renderEntries(); renderEditor(); }); return card;
930
+ }));
931
+ }
932
+
933
+ function renderEntries() {
934
+ const displayed = state.recallItems.length > 0 ? state.recallItems.length : state.entries.length;
935
+ $('result-count').textContent = tp('entryCount', displayed);
936
+ $('list-title').textContent = state.recallItems.length > 0 ? t('entriesTitle') : (state.tag ? '#' + state.tag : (state.kind === 'all' ? t('entriesTitle') : labelForKind(state.kind)));
937
+ const list = $('entry-list');
938
+ if (state.recallItems.length > 0) { renderFederatedItems(); return; }
939
+ if (!state.entries.length) {
940
+ const empty = document.createElement('div'); empty.className = 'editor-empty'; setI18nText(empty, 'noEntries'); list.replaceChildren(empty); return;
941
+ }
942
+ list.replaceChildren(...state.entries.map((entry) => {
943
+ const card = document.createElement('article'); card.className = 'entry-card ' + (state.selected?.id === entry.id ? 'selected' : '');
944
+ const meta = document.createElement('div'); meta.className = 'entry-meta';
945
+ const kind = document.createElement('span'); kind.className = 'badge'; kind.textContent = labelForKind(entry.kind);
946
+ const status = document.createElement('span'); status.className = 'badge ' + entry.status; status.textContent = labelForStatus(entry.status);
947
+ const revision = document.createElement('span'); revision.textContent = t('revision') + ' ' + entry.revision; meta.append(kind, status, revision);
948
+ const title = document.createElement('h3'); title.textContent = entry.title;
949
+ const snippet = document.createElement('p'); snippet.className = 'snippet'; snippet.textContent = entry.summary || entry.body;
950
+ const tags = document.createElement('div'); tags.className = 'tags'; entry.tags.forEach((tag) => { const item = document.createElement('button'); item.type = 'button'; item.className = 'tag'; item.textContent = '#' + tag; item.addEventListener('click', (event) => { event.stopPropagation(); state.tag = tag; renderFilters(); loadEntries(); }); tags.append(item); });
951
+ const edit = document.createElement('button'); edit.type = 'button'; edit.className = 'button'; setI18nText(edit, 'edit'); edit.style.marginTop = '12px'; edit.addEventListener('click', (event) => { event.stopPropagation(); selectEntry(entry.id); });
952
+ card.append(meta, title, snippet, tags, edit); card.addEventListener('click', () => selectEntry(entry.id)); return card;
953
+ }));
954
+ }
955
+
956
+ function renderFederatedDetail() {
957
+ const editor = $('editor'); const item = state.selectedRecall;
958
+ if (!item) return;
959
+ const origin = document.createElement('span'); origin.className = 'badge origin-' + item.origin; origin.textContent = labelForOrigin(item.origin);
960
+ const heading = document.createElement('h3'); heading.textContent = item.title;
961
+ const meta = document.createElement('div'); meta.className = 'entry-meta'; meta.append(origin);
962
+ if (item.sourceWorkspace) { const source = document.createElement('span'); source.className = 'badge'; source.textContent = t('sourceWorkspace', { workspace: item.sourceWorkspace }); meta.append(source); }
963
+ if (item.sourceProject) { const source = document.createElement('span'); source.className = 'badge'; source.textContent = t('sourceProject', { project: item.sourceProject }); meta.append(source); }
964
+ const notice = document.createElement('div'); notice.className = 'notice'; notice.textContent = t('federatedReadOnly');
965
+ const detail = document.createElement('div'); detail.className = 'federated-detail';
966
+ const snippet = document.createElement('div'); snippet.className = 'detail-text'; snippet.textContent = item.snippet;
967
+ const reasons = detailBlock('selectionReasons', item.selectionReasons.join('\n'));
968
+ const tags = detailBlock('commaSeparatedTags', item.tags.map((tag) => '#' + tag).join(' '));
969
+ detail.append(snippet, reasons, tags);
970
+ const stateBadge = $('editor-state'); delete stateBadge.dataset.i18n; delete stateBadge.dataset.i18nStatus; stateBadge.textContent = labelForOrigin(item.origin);
971
+ editor.replaceChildren(meta, heading, notice, detail);
972
+ }
973
+
974
+ function renderEditor() {
975
+ if (state.selectedRecall) { renderFederatedDetail(); return; }
976
+ const editor = $('editor');
977
+ const entry = state.selected;
978
+ updateEditorState();
979
+ if (!entry) { const empty = document.createElement('div'); empty.className = 'editor-empty'; setI18nText(empty, 'selectMemory'); editor.replaceChildren(empty); return; }
980
+ const form = document.createElement('form'); form.className = 'form';
981
+ const row = document.createElement('div'); row.className = 'form-row';
982
+ const kindLabel = document.createElement('label'); const kindLabelText = document.createElement('span'); setI18nText(kindLabelText, 'memoryType'); const kind = document.createElement('select'); kinds.filter(([value]) => value !== 'all').forEach(([value, label]) => { const option = document.createElement('option'); option.value = value; setI18nText(option, label); kind.append(option); }); kind.value = entry.kind; kindLabel.append(kindLabelText, kind);
983
+ const statusLabel = document.createElement('label'); const statusLabelText = document.createElement('span'); setI18nText(statusLabelText, 'status'); const status = document.createElement('input'); status.value = labelForStatus(entry.status); status.dataset.i18nStatus = entry.status; status.disabled = true; statusLabel.append(statusLabelText, status); row.append(kindLabel, statusLabel);
984
+ const titleLabel = document.createElement('label'); const titleLabelText = document.createElement('span'); setI18nText(titleLabelText, 'title'); const title = document.createElement('input'); title.value = entry.title; titleLabel.append(titleLabelText, title);
985
+ const bodyLabel = document.createElement('label'); const bodyLabelText = document.createElement('span'); setI18nText(bodyLabelText, 'body'); const body = document.createElement('textarea'); body.className = 'body'; body.value = entry.body; bodyLabel.append(bodyLabelText, body);
986
+ const summaryLabel = document.createElement('label'); const summaryLabelText = document.createElement('span'); setI18nText(summaryLabelText, 'summary'); const summary = document.createElement('textarea'); summary.value = entry.summary || ''; summaryLabel.append(summaryLabelText, summary);
987
+ const tagsLabel = document.createElement('label'); const tagsLabelText = document.createElement('span'); setI18nText(tagsLabelText, 'commaSeparatedTags'); const tags = document.createElement('input'); tags.value = entry.tags.join(', '); tagsLabel.append(tagsLabelText, tags);
988
+ const jsonRow = document.createElement('div'); jsonRow.className = 'form-row';
989
+ const scopeLabel = document.createElement('label'); const scopeLabelText = document.createElement('span'); setI18nText(scopeLabelText, 'scopeJson'); const scope = document.createElement('textarea'); scope.value = JSON.stringify(entry.scope, null, 2); scopeLabel.append(scopeLabelText, scope);
990
+ const provenanceLabel = document.createElement('label'); const provenanceLabelText = document.createElement('span'); setI18nText(provenanceLabelText, 'provenanceJson'); const provenance = document.createElement('textarea'); provenance.value = JSON.stringify(entry.provenance, null, 2); provenanceLabel.append(provenanceLabelText, provenance); jsonRow.append(scopeLabel, provenanceLabel);
991
+ const actions = document.createElement('div'); actions.className = 'toolbar';
992
+ const save = document.createElement('button'); save.type = 'submit'; save.className = 'button primary'; setI18nText(save, 'save');
993
+ const note = document.createElement('div'); note.className = entry.status === 'candidate' ? 'notice' : 'notice error'; setI18nText(note, entry.status === 'candidate' ? 'candidateNotice' : 'immutableNotice');
994
+ if (entry.status !== 'candidate') { save.disabled = true; [kind, title, body, summary, tags, scope, provenance].forEach((control) => { control.disabled = true; }); }
995
+ const draftText = () => JSON.stringify({ memoryType: kind.value, title: title.value, body: body.value, summary: summary.value, tags: tags.value, scopeJson: scope.value, provenanceJson: provenance.value }, null, 2);
996
+ actions.append(save); form.append(row, titleLabel, bodyLabel, summaryLabel, tagsLabel, jsonRow, note, actions); form.addEventListener('submit', async (event) => { event.preventDefault(); if (save.disabled) return; save.disabled = true; setI18nText(save, 'saving'); try {
997
+ const payload = { expectedRevision: entry.revision, kind: kind.value, title: title.value, body: body.value, summary: summary.value || null, scope: JSON.parse(scope.value || '{}'), provenance: JSON.parse(provenance.value || '{}'), tags: escapeTags(tags.value) };
998
+ await api('/api/entries/' + encodeURIComponent(entry.id) + '?workspace=' + encodeURIComponent(state.workspace), { method: 'PUT', headers: { 'content-type': 'application/json' }, body: JSON.stringify(payload) });
999
+ setLocalizedStatus('saved'); await loadEntries(); await selectEntry(entry.id);
1000
+ } catch (error) { if (error instanceof Error && error.code === 'CONFLICT') showEntryConflictGuide(entry.id, draftText); else setStatus(error instanceof Error ? error.message : t('requestFailed'), true); }
1001
+ finally { if (save.isConnected) { save.disabled = false; setI18nText(save, 'save'); } }
1002
+ }); editor.replaceChildren(form);
1003
+ }
1004
+
1005
+ async function selectEntry(id) { try { await loadEntrySelection(id); } catch (error) { setStatus(error instanceof Error ? error.message : t('requestFailed'), true); } }
1006
+
1007
+ const curatorCandidateKey = (candidate) => candidate.workspace + '\u0000' + candidate.entryId;
1008
+
1009
+ function setCuratorConfirmationStatus(message, error = false) {
1010
+ const element = $('curator-confirm-status');
1011
+ element.textContent = message;
1012
+ element.className = error ? 'status notice error curator-status' : 'status curator-status';
1013
+ }
1014
+
1015
+ function openCuratorConfirmation(candidate, trigger) {
1016
+ if (state.curatorGlobalizeBusy || state.curatorGlobalized.has(curatorCandidateKey(candidate))) return;
1017
+ state.curatorPendingCandidate = candidate;
1018
+ state.curatorConfirmationTrigger = trigger instanceof HTMLElement ? trigger : null;
1019
+ $('curator-confirm-source').textContent = candidate.projectName || candidate.workspace;
1020
+ $('curator-confirm-skill').textContent = candidate.skillName;
1021
+ $('curator-confirm-applicability').textContent = candidate.applicability ? JSON.stringify(candidate.applicability, null, 2) : t('curatorApplicabilityNone');
1022
+ $('curator-confirm-draft').textContent = [
1023
+ t('curatorDraftTitle') + '\n' + candidate.draft.title,
1024
+ t('curatorDraftSummary') + '\n' + candidate.draft.summary,
1025
+ t('curatorDraftBody') + '\n' + candidate.draft.body,
1026
+ t('curatorDraftVersion') + '\n' + candidate.draft.version,
1027
+ ].join('\n\n');
1028
+ setCuratorConfirmationStatus('');
1029
+ const panel = $('curator-panel');
1030
+ panel.inert = true;
1031
+ panel.setAttribute('aria-hidden', 'true');
1032
+ const submit = $('curator-confirm-submit');
1033
+ submit.disabled = false;
1034
+ setI18nText(submit, 'curatorConfirmAction');
1035
+ $('curator-confirm-cancel').disabled = false;
1036
+ $('curator-confirm-modal').hidden = false;
1037
+ requestAnimationFrame(() => submit.focus());
1038
+ }
1039
+
1040
+ function closeCuratorConfirmation(restoreFocus = true) {
1041
+ if (state.curatorGlobalizeBusy) return;
1042
+ $('curator-confirm-modal').hidden = true;
1043
+ const panel = $('curator-panel');
1044
+ panel.inert = false;
1045
+ panel.removeAttribute('aria-hidden');
1046
+ const trigger = state.curatorConfirmationTrigger;
1047
+ state.curatorPendingCandidate = null;
1048
+ state.curatorConfirmationTrigger = null;
1049
+ setCuratorConfirmationStatus('');
1050
+ if (restoreFocus) requestAnimationFrame(() => {
1051
+ if (trigger?.isConnected) trigger.focus();
1052
+ else $('curator-close')?.focus();
1053
+ });
1054
+ }
1055
+
1056
+ function handleCuratorConfirmationKeydown(event) {
1057
+ event.stopPropagation();
1058
+ if (event.key === 'Escape') { event.preventDefault(); closeCuratorConfirmation(); return; }
1059
+ if (event.key !== 'Tab') return;
1060
+ const panel = $('curator-confirm-panel');
1061
+ const focusable = [...panel.querySelectorAll('button:not([disabled]), [tabindex]:not([tabindex="-1"])')];
1062
+ if (!focusable.length) { event.preventDefault(); return; }
1063
+ const first = focusable[0];
1064
+ const last = focusable.at(-1);
1065
+ if (event.shiftKey && document.activeElement === first) { event.preventDefault(); last.focus(); }
1066
+ else if (!event.shiftKey && document.activeElement === last) { event.preventDefault(); first.focus(); }
1067
+ }
1068
+
1069
+ async function globalizePendingCurator() {
1070
+ const candidate = state.curatorPendingCandidate;
1071
+ if (!candidate || state.curatorGlobalizeBusy) return;
1072
+ state.curatorGlobalizeBusy = true;
1073
+ const panel = $('curator-confirm-panel');
1074
+ const cancel = $('curator-confirm-cancel');
1075
+ const submit = $('curator-confirm-submit');
1076
+ panel.setAttribute('aria-busy', 'true');
1077
+ cancel.disabled = true;
1078
+ submit.disabled = true;
1079
+ setI18nText(submit, 'curatorGlobalizing');
1080
+ setCuratorConfirmationStatus(t('curatorGlobalizing'));
1081
+ try {
1082
+ await api('/api/curator/globalize?workspace=' + encodeURIComponent(candidate.workspace), {
1083
+ method: 'POST',
1084
+ headers: { 'content-type': 'application/json' },
1085
+ body: JSON.stringify({ workspace: candidate.workspace, entryId: candidate.entryId, expectedRevision: candidate.revision }),
1086
+ });
1087
+ state.curatorGlobalized.add(curatorCandidateKey(candidate));
1088
+ state.curatorGlobalizeBusy = false;
1089
+ closeCuratorConfirmation(false);
1090
+ await loadCurator();
1091
+ await loadEntries();
1092
+ setLocalizedStatus('curatorAdded');
1093
+ setCuratorStatus(t('curatorAdded'));
1094
+ requestAnimationFrame(() => $('curator-close')?.focus());
1095
+ } catch (error) {
1096
+ const message = error instanceof Error ? error.message : t('curatorGlobalizeFailed');
1097
+ setCuratorConfirmationStatus(t('curatorGlobalizeFailed') + ' ' + message, true);
1098
+ } finally {
1099
+ state.curatorGlobalizeBusy = false;
1100
+ panel.removeAttribute('aria-busy');
1101
+ cancel.disabled = false;
1102
+ submit.disabled = false;
1103
+ setI18nText(submit, 'curatorConfirmAction');
1104
+ }
1105
+ }
1106
+
1107
+ function renderCurator() {
1108
+ if (!state.curatorOpen) return;
1109
+ const modal = $('curator-modal');
1110
+ modal.hidden = false;
1111
+ const root = $('curator-list');
1112
+ $('curator-result-count').textContent = t('curatorResultCount', { count: state.curatorTotalApproximate || state.curatorCandidates.length });
1113
+ const actionRoot = $('curator-actions'); actionRoot.replaceChildren();
1114
+ if (state.curatorNextCursor) {
1115
+ const more = document.createElement('button'); more.type = 'button'; more.className = 'button'; setI18nText(more, 'curatorLoadMore'); more.addEventListener('click', () => loadCurator(true)); actionRoot.append(more);
1116
+ }
1117
+ if (!state.curatorCandidates.length) { const empty = document.createElement('div'); empty.className = 'editor-empty'; setI18nText(empty, 'noCuratorCandidates'); root.replaceChildren(empty); return; }
1118
+ const cards = state.curatorCandidates.map((candidate, index) => {
1119
+ const card = document.createElement('article'); card.className = 'curator-card';
1120
+ const candidateKey = curatorCandidateKey(candidate);
1121
+ const done = state.curatorGlobalized.has(candidateKey);
1122
+ const meta = document.createElement('div'); meta.className = 'entry-meta';
1123
+ const kind = document.createElement('span'); kind.className = 'badge'; kind.textContent = labelForKind(candidate.kind);
1124
+ const score = document.createElement('span'); score.className = 'badge'; score.textContent = t('curatorScore', { score: candidate.score });
1125
+ const workspace = document.createElement('span'); workspace.className = 'badge curator-workspace'; workspace.textContent = t('curatorWorkspace', { workspace: candidate.workspace });
1126
+ meta.append(kind, score, workspace);
1127
+ if (candidate.knowledge && candidate.knowledge.skillReady) { const ready = document.createElement('span'); ready.className = 'badge'; setI18nText(ready, 'curatorSkillReady'); meta.append(ready); }
1128
+ const heading = document.createElement('h3'); heading.textContent = candidate.skillName;
1129
+ const overview = document.createElement('div'); overview.className = 'curator-overview'; overview.textContent = candidate.overview.join('\n');
1130
+ const tags = document.createElement('div'); tags.className = 'tags'; (candidate.tags || []).forEach((tag) => { const tagItem = document.createElement('span'); tagItem.className = 'tag'; tagItem.textContent = '#' + tag; tags.append(tagItem); });
1131
+ const knowledge = document.createElement('div'); knowledge.className = 'curator-reasons'; knowledge.textContent = candidate.knowledge ? [
1132
+ t('curatorEvidence', { hits: candidate.knowledge.qualifiedHits, runs: candidate.knowledge.independentRuns, workspaces: candidate.knowledge.independentWorkspaces }),
1133
+ t('curatorSilo', { value: candidate.knowledge.averageCompleteness }),
1134
+ ...(candidate.knowledge.readinessReasons || []),
1135
+ ].join('\n') : '';
1136
+ const draft = document.createElement('section'); draft.className = 'curator-draft';
1137
+ const draftHeading = document.createElement('h4'); setI18nText(draftHeading, 'curatorDraft');
1138
+ draft.append(draftHeading);
1139
+ const draftFields = [
1140
+ ['curatorDraftTitle', candidate.draft.title],
1141
+ ['curatorDraftSummary', candidate.draft.summary],
1142
+ ['curatorDraftBody', candidate.draft.body],
1143
+ ['curatorDraftVersion', candidate.draft.version],
1144
+ ['curatorDraftChanges', (candidate.draft.changes || []).map((change) => t({
1145
+ 'portable-sections-generated': 'curatorChangePortableSections',
1146
+ 'project-references-normalized': 'curatorChangeProjectReferences',
1147
+ 'paths-generalized': 'curatorChangePaths',
1148
+ 'applicability-retained': 'curatorChangeApplicability',
1149
+ }[change] || 'curatorChangeUnknown')).join('\n')],
1150
+ ];
1151
+ for (const [labelKey, value] of draftFields) {
1152
+ const label = document.createElement('div'); label.className = 'curator-draft-label'; setI18nText(label, labelKey);
1153
+ const content = document.createElement('pre'); content.className = 'curator-draft-value'; content.textContent = value;
1154
+ draft.append(label, content);
1155
+ }
1156
+ const reasons = document.createElement('div'); reasons.className = 'curator-reasons'; reasons.textContent = [...(candidate.reasons || []), ...(candidate.warnings || []).map((warning) => t('curatorWarning', { warning }))].join('\n');
1157
+ const details = document.createElement('div'); details.id = 'curator-review-' + index; details.className = 'curator-review-details'; details.hidden = true; details.append(knowledge, draft, reasons);
1158
+ const actions = document.createElement('div'); actions.className = 'curator-card-actions';
1159
+ const review = document.createElement('button'); review.type = 'button'; review.className = 'button'; review.setAttribute('aria-controls', details.id); review.setAttribute('aria-expanded', 'false'); setI18nText(review, 'curatorReview');
1160
+ review.addEventListener('click', () => { details.hidden = !details.hidden; review.setAttribute('aria-expanded', String(!details.hidden)); setI18nText(review, details.hidden ? 'curatorReview' : 'curatorHideReview'); });
1161
+ const globalize = document.createElement('button'); globalize.type = 'button'; globalize.className = 'button primary'; globalize.disabled = done; setI18nText(globalize, done ? 'globalized' : 'curatorGlobalizeCandidate');
1162
+ globalize.addEventListener('click', () => openCuratorConfirmation(candidate, globalize));
1163
+ actions.append(review, globalize);
1164
+ card.append(meta, heading, overview, tags, actions, details); return card;
1165
+ });
1166
+ root.replaceChildren(...cards);
1167
+ }
1168
+
1169
+ async function loadCurator(append = false) {
1170
+ // Keep the documented legacy URL shape recognizable for clients: /api/curator/candidates?limit=50
1171
+ if (!append) {
1172
+ openCurator();
1173
+ state.curatorCandidates = [];
1174
+ state.curatorNextCursor = null;
1175
+ state.curatorTotalApproximate = 0;
1176
+ } else if (!state.curatorNextCursor) return;
1177
+ const panel = $('curator-panel');
1178
+ panel.setAttribute('aria-busy', 'true');
1179
+ setCuratorStatus(t('curatorLoading'));
1180
+ try {
1181
+ if (!append) {
1182
+ const facetParams = new URLSearchParams({ workspace: 'all' });
1183
+ if (state.curatorIncludeGlobalized) facetParams.set('includeGlobalized', 'true');
1184
+ const facetResult = await api('/api/curator/facets?' + facetParams);
1185
+ state.curatorFacets = facetResult.facets || {};
1186
+ renderCuratorFilters();
1187
+ }
1188
+ const params = new URLSearchParams({ workspace: 'all', limit: '50' });
1189
+ if (state.curatorProject) params.set('project', state.curatorProject);
1190
+ if (state.curatorSearch) params.set('search', state.curatorSearch);
1191
+ if (state.curatorFramework) params.set('framework', state.curatorFramework);
1192
+ if (state.curatorLanguage) params.set('language', state.curatorLanguage);
1193
+ if (state.curatorMemoryClass) params.set('memoryClass', state.curatorMemoryClass);
1194
+ if (state.curatorTier) params.set('tier', state.curatorTier);
1195
+ if (state.curatorReady) params.set('skillReadyOnly', 'true');
1196
+ if (state.curatorIncludeGlobalized) params.set('includeGlobalized', 'true');
1197
+ for (const tag of state.curatorTags) params.append('tag', tag);
1198
+ if (append && state.curatorNextCursor) params.set('cursor', state.curatorNextCursor);
1199
+ const result = await api('/api/curator/candidates?' + params);
1200
+ state.curatorCandidates = append ? [...state.curatorCandidates, ...(result.candidates || [])] : (result.candidates || []);
1201
+ state.curatorNextCursor = result.nextCursor || null;
1202
+ state.curatorTotalApproximate = Number(result.totalApproximate || state.curatorCandidates.length);
1203
+ setCuratorStatus('');
1204
+ renderCurator();
1205
+ }
1206
+ catch (error) { setCuratorStatus(error.message, true); }
1207
+ finally { panel.removeAttribute('aria-busy'); }
1208
+ }
1209
+
1210
+ async function loadRunDetail(runId) {
1211
+ try {
1212
+ const result = await api('/api/operator/runs/' + encodeURIComponent(runId));
1213
+ state.selectedRun = result;
1214
+ renderRunDetail();
1215
+ } catch (error) { setStatus(error.message, true); }
1216
+ }
1217
+
1218
+ function detailBlock(titleKey, value) {
1219
+ const block = document.createElement('section'); block.className = 'detail-block';
1220
+ const heading = document.createElement('h3'); setI18nText(heading, titleKey);
1221
+ const text = document.createElement('div'); text.className = 'detail-text'; text.textContent = typeof value === 'string' ? value : JSON.stringify(value, null, 2);
1222
+ block.append(heading, text); return block;
1223
+ }
1224
+
1225
+ function renderRunDetail() {
1226
+ const root = $('run-detail'); const detail = state.selectedRun;
1227
+ if (!detail) { const empty = document.createElement('div'); empty.className = 'editor-empty'; setI18nText(empty, 'runSelect'); root.replaceChildren(empty); return; }
1228
+ const heading = document.createElement('h3'); setI18nText(heading, 'contextWarning');
1229
+ const blocks = [
1230
+ detailBlock('detailRunIntake', { run: detail.run, intake: detail.intake }),
1231
+ detailBlock('detailInitialProfile', detail.profile.initial),
1232
+ detailBlock('detailProjectedProfile', detail.profile.projected),
1233
+ detailBlock('detailPolicySource', { policyVersion: detail.profile.policyVersion, source: detail.profile.source, initialProfileHash: detail.profile.initialProfileHash }),
1234
+ detailBlock('detailCoverageWarnings', { coverage: detail.coverage, evidenceState: detail.evidenceState, warnings: detail.warnings }),
1235
+ detailBlock('detailTimelineEvidence', { timeline: detail.timeline, evidence: detail.evidence }),
1236
+ detailBlock('detailDeliveriesReasons', detail.deliveries),
1237
+ detailBlock('detailFeedback', detail.feedback),
1238
+ detailBlock('detailProposalLinks', { proposals: detail.proposals, links: detail.memoryLinks }),
1239
+ ];
1240
+ root.replaceChildren(heading, ...blocks);
1241
+ }
1242
+
1243
+ function renderRuns() {
1244
+ const root = $('run-list');
1245
+ if (!state.runs.length) { const empty = document.createElement('div'); empty.className = 'editor-empty'; setI18nText(empty, 'noRuns'); root.replaceChildren(empty); return; }
1246
+ root.replaceChildren(...state.runs.map((run) => {
1247
+ const button = document.createElement('button'); button.type = 'button'; button.className = 'run-card' + (state.selectedRun?.run?.runId === run.runId ? ' selected' : '');
1248
+ button.textContent = run.runId + ' / ' + (run.status || t('unknown')) + ' / ' + (run.title || t('untitled'));
1249
+ button.addEventListener('click', () => loadRunDetail(run.runId)); return button;
1250
+ }));
1251
+ }
1252
+
1253
+ async function loadRuns() {
1254
+ if (!state.workspace) return;
1255
+ try {
1256
+ const result = await api('/api/operator/runs?workspace=' + encodeURIComponent(state.workspace) + '&limit=50');
1257
+ state.runs = result.items || []; renderRuns(); setI18nText($('run-page'), result.nextCursor ? 'nextPage' : 'end');
1258
+ if (!state.selectedRun && state.runs[0]) await loadRunDetail(state.runs[0].runId);
1259
+ else renderRunDetail();
1260
+ } catch (error) { setStatus(error.message, true); }
1261
+ }
1262
+
1263
+ async function loadEntries() {
1264
+ if (!state.workspace) return;
1265
+ try {
1266
+ const params = new URLSearchParams({ workspace: state.workspace });
1267
+ if (state.kind !== 'all') params.set('kind', state.kind);
1268
+ if (state.tag) params.set('tag', state.tag);
1269
+ if (state.query) params.set('q', state.query);
1270
+ const result = await api('/api/entries?' + params);
1271
+ state.entries = result.entries;
1272
+ state.recallItems = [];
1273
+ state.selectedRecall = null;
1274
+ if (state.query && state.kind === 'all' && !state.tag) {
1275
+ const recallParams = new URLSearchParams({ workspace: state.workspace, q: state.query, limit: '100' });
1276
+ const recalled = await api('/api/memory/recall?' + recallParams);
1277
+ state.recallItems = recalled.combined?.items || [];
1278
+ state.selected = null;
1279
+ } else if (state.selected && !state.entries.some((entry) => entry.id === state.selected.id)) state.selected = null;
1280
+ renderEntries(); renderFilters();
1281
+ if (!state.recallItems.length && !state.selected && state.entries[0]) await selectEntry(state.entries[0].id);
1282
+ else renderEditor();
1283
+ setLocalizedCountStatus('displayedCount', state.recallItems.length || result.entries.length);
1284
+ } catch (error) { setStatus(error.message, true); }
1285
+ }
1286
+ async function loadTags() { if (!state.workspace) return; try { const result = await api('/api/tags?workspace=' + encodeURIComponent(state.workspace)); state.tags = result.tags; renderFilters(); } catch (error) { setStatus(error.message, true); } }
1287
+ async function loadWorkspaces() { try { const result = await api('/api/workspaces'); const select = $('workspace'); select.replaceChildren(...result.workspaces.map((item) => { const option = document.createElement('option'); option.value = item.workspace; option.textContent = (item.displayName || item.workspace) + ' (' + item.count + ')'; return option; })); if (!state.workspace && result.workspaces[0]) state.workspace = result.workspaces[0].workspace; select.value = state.workspace; if (state.workspace) { await loadTags(); await loadEntries(); await loadRuns(); } if (state.curatorOpen) await loadCurator(); else if (!state.workspace) setLocalizedStatus('noWorkspace', {}, true); } catch (error) { setStatus(error.message, true); } }
1288
+ $('language-toggle').addEventListener('click', () => {
1289
+ setLanguageMenuOpen($('language-toggle').getAttribute('aria-expanded') !== 'true');
1290
+ });
1291
+ $('language-toggle').addEventListener('keydown', (event) => {
1292
+ if (event.key !== 'ArrowDown' && event.key !== 'ArrowUp') return;
1293
+ event.preventDefault();
1294
+ setLanguageMenuOpen(true);
1295
+ });
1296
+ $('language-menu').addEventListener('keydown', (event) => {
1297
+ const options = [...$('language-menu').querySelectorAll('.language-option')];
1298
+ const current = options.indexOf(document.activeElement);
1299
+ let next = null;
1300
+ if (event.key === 'ArrowDown') next = options[(current + 1) % options.length];
1301
+ if (event.key === 'ArrowUp') next = options[(current - 1 + options.length) % options.length];
1302
+ if (event.key === 'Home') next = options[0];
1303
+ if (event.key === 'End') next = options.at(-1);
1304
+ if (event.key === 'Escape') { event.preventDefault(); setLanguageMenuOpen(false, true); return; }
1305
+ if (next) { event.preventDefault(); next.focus(); }
1306
+ });
1307
+ document.addEventListener('click', (event) => { if (!$('language-picker')?.contains(event.target)) setLanguageMenuOpen(false); });
1308
+ document.addEventListener('focusin', (event) => { if (!$('language-picker')?.contains(event.target)) setLanguageMenuOpen(false); });
1309
+ $('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); });
1310
+ $('curator-button').addEventListener('click', () => loadCurator());
1311
+ $('curator-close').addEventListener('click', () => closeCurator());
1312
+ $('external-skills-button').addEventListener('click', () => loadExternalSkills());
1313
+ $('external-skills-close').addEventListener('click', () => closeExternalSkills());
1314
+ $('external-skills-refresh').addEventListener('click', () => loadExternalSkills(false));
1315
+ $('curator-confirm-cancel').addEventListener('click', () => closeCuratorConfirmation());
1316
+ $('curator-confirm-submit').addEventListener('click', () => globalizePendingCurator());
1317
+ $('curator-confirm-modal').addEventListener('keydown', handleCuratorConfirmationKeydown);
1318
+ $('curator-modal').addEventListener('keydown', handleCuratorKeydown);
1319
+ $('external-skills-modal').addEventListener('keydown', handleExternalSkillsKeydown);
1320
+ window.addEventListener('popstate', () => { restoreCuratorUrl(); if (state.curatorOpen) loadCurator(); });
1321
+ $('refresh').addEventListener('click', () => loadWorkspaces());
1322
+ let searchTimer; $('search').addEventListener('input', (event) => { clearTimeout(searchTimer); state.query = event.target.value.trim(); searchTimer = setTimeout(() => loadEntries(), 180); });
1323
+ applyTranslations();
1324
+ loadWorkspaces();
1325
+ </script>
1326
+ </body>
1327
+ </html>`;
1328
+ //# sourceMappingURL=ui.js.map