@askdkc/kiokuko 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 (391) hide show
  1. package/LICENSE +21 -0
  2. package/README.ja.md +112 -0
  3. package/README.ko.md +112 -0
  4. package/README.md +147 -0
  5. package/README.zh-CN.md +112 -0
  6. package/dist/agent-file/atomic-write.d.ts +6 -0
  7. package/dist/agent-file/atomic-write.d.ts.map +1 -0
  8. package/dist/agent-file/atomic-write.js +36 -0
  9. package/dist/agent-file/atomic-write.js.map +1 -0
  10. package/dist/agent-file/managed-block.d.ts +12 -0
  11. package/dist/agent-file/managed-block.d.ts.map +1 -0
  12. package/dist/agent-file/managed-block.js +56 -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 +41 -0
  17. package/dist/agent-file/render.js.map +1 -0
  18. package/dist/akinator/domain.d.ts +25 -0
  19. package/dist/akinator/domain.d.ts.map +1 -0
  20. package/dist/akinator/domain.js +255 -0
  21. package/dist/akinator/domain.js.map +1 -0
  22. package/dist/akinator/orchestrator.d.ts +8 -0
  23. package/dist/akinator/orchestrator.d.ts.map +1 -0
  24. package/dist/akinator/orchestrator.js +11 -0
  25. package/dist/akinator/orchestrator.js.map +1 -0
  26. package/dist/akinator/service.d.ts +35 -0
  27. package/dist/akinator/service.d.ts.map +1 -0
  28. package/dist/akinator/service.js +296 -0
  29. package/dist/akinator/service.js.map +1 -0
  30. package/dist/akinator/store.d.ts +96 -0
  31. package/dist/akinator/store.d.ts.map +1 -0
  32. package/dist/akinator/store.js +583 -0
  33. package/dist/akinator/store.js.map +1 -0
  34. package/dist/akinator/types.d.ts +49 -0
  35. package/dist/akinator/types.d.ts.map +1 -0
  36. package/dist/akinator/types.js +2 -0
  37. package/dist/akinator/types.js.map +1 -0
  38. package/dist/bin/kiokuko.d.ts +3 -0
  39. package/dist/bin/kiokuko.d.ts.map +1 -0
  40. package/dist/bin/kiokuko.js +6 -0
  41. package/dist/bin/kiokuko.js.map +1 -0
  42. package/dist/cli.d.ts +10 -0
  43. package/dist/cli.d.ts.map +1 -0
  44. package/dist/cli.js +362 -0
  45. package/dist/cli.js.map +1 -0
  46. package/dist/client/runtime-discovery.d.ts +15 -0
  47. package/dist/client/runtime-discovery.d.ts.map +1 -0
  48. package/dist/client/runtime-discovery.js +45 -0
  49. package/dist/client/runtime-discovery.js.map +1 -0
  50. package/dist/client/server-client.d.ts +20 -0
  51. package/dist/client/server-client.d.ts.map +1 -0
  52. package/dist/client/server-client.js +424 -0
  53. package/dist/client/server-client.js.map +1 -0
  54. package/dist/commands/agent.d.ts +10 -0
  55. package/dist/commands/agent.d.ts.map +1 -0
  56. package/dist/commands/agent.js +283 -0
  57. package/dist/commands/agent.js.map +1 -0
  58. package/dist/commands/backup.d.ts +5 -0
  59. package/dist/commands/backup.d.ts.map +1 -0
  60. package/dist/commands/backup.js +14 -0
  61. package/dist/commands/backup.js.map +1 -0
  62. package/dist/commands/call.d.ts +7 -0
  63. package/dist/commands/call.d.ts.map +1 -0
  64. package/dist/commands/call.js +10 -0
  65. package/dist/commands/call.js.map +1 -0
  66. package/dist/commands/doctor.d.ts +31 -0
  67. package/dist/commands/doctor.d.ts.map +1 -0
  68. package/dist/commands/doctor.js +142 -0
  69. package/dist/commands/doctor.js.map +1 -0
  70. package/dist/commands/export.d.ts +21 -0
  71. package/dist/commands/export.d.ts.map +1 -0
  72. package/dist/commands/export.js +68 -0
  73. package/dist/commands/export.js.map +1 -0
  74. package/dist/commands/import.d.ts +15 -0
  75. package/dist/commands/import.d.ts.map +1 -0
  76. package/dist/commands/import.js +265 -0
  77. package/dist/commands/import.js.map +1 -0
  78. package/dist/commands/init.d.ts +14 -0
  79. package/dist/commands/init.d.ts.map +1 -0
  80. package/dist/commands/init.js +26 -0
  81. package/dist/commands/init.js.map +1 -0
  82. package/dist/commands/ledger.d.ts +7 -0
  83. package/dist/commands/ledger.d.ts.map +1 -0
  84. package/dist/commands/ledger.js +66 -0
  85. package/dist/commands/ledger.js.map +1 -0
  86. package/dist/commands/link.d.ts +6 -0
  87. package/dist/commands/link.d.ts.map +1 -0
  88. package/dist/commands/link.js +6 -0
  89. package/dist/commands/link.js.map +1 -0
  90. package/dist/commands/promote.d.ts +6 -0
  91. package/dist/commands/promote.d.ts.map +1 -0
  92. package/dist/commands/promote.js +6 -0
  93. package/dist/commands/promote.js.map +1 -0
  94. package/dist/commands/purge.d.ts +10 -0
  95. package/dist/commands/purge.d.ts.map +1 -0
  96. package/dist/commands/purge.js +26 -0
  97. package/dist/commands/purge.js.map +1 -0
  98. package/dist/commands/read.d.ts +6 -0
  99. package/dist/commands/read.d.ts.map +1 -0
  100. package/dist/commands/read.js +4 -0
  101. package/dist/commands/read.js.map +1 -0
  102. package/dist/commands/recall.d.ts +6 -0
  103. package/dist/commands/recall.d.ts.map +1 -0
  104. package/dist/commands/recall.js +4 -0
  105. package/dist/commands/recall.js.map +1 -0
  106. package/dist/commands/record.d.ts +6 -0
  107. package/dist/commands/record.d.ts.map +1 -0
  108. package/dist/commands/record.js +4 -0
  109. package/dist/commands/record.js.map +1 -0
  110. package/dist/commands/search.d.ts +6 -0
  111. package/dist/commands/search.d.ts.map +1 -0
  112. package/dist/commands/search.js +4 -0
  113. package/dist/commands/search.js.map +1 -0
  114. package/dist/commands/serve.d.ts +34 -0
  115. package/dist/commands/serve.d.ts.map +1 -0
  116. package/dist/commands/serve.js +120 -0
  117. package/dist/commands/serve.js.map +1 -0
  118. package/dist/commands/server-status.d.ts +20 -0
  119. package/dist/commands/server-status.d.ts.map +1 -0
  120. package/dist/commands/server-status.js +21 -0
  121. package/dist/commands/server-status.js.map +1 -0
  122. package/dist/commands/server.d.ts +13 -0
  123. package/dist/commands/server.d.ts.map +1 -0
  124. package/dist/commands/server.js +89 -0
  125. package/dist/commands/server.js.map +1 -0
  126. package/dist/commands/setup.d.ts +32 -0
  127. package/dist/commands/setup.d.ts.map +1 -0
  128. package/dist/commands/setup.js +121 -0
  129. package/dist/commands/setup.js.map +1 -0
  130. package/dist/commands/supersede.d.ts +6 -0
  131. package/dist/commands/supersede.d.ts.map +1 -0
  132. package/dist/commands/supersede.js +6 -0
  133. package/dist/commands/supersede.js.map +1 -0
  134. package/dist/commands/use.d.ts +28 -0
  135. package/dist/commands/use.d.ts.map +1 -0
  136. package/dist/commands/use.js +176 -0
  137. package/dist/commands/use.js.map +1 -0
  138. package/dist/config/paths.d.ts +18 -0
  139. package/dist/config/paths.d.ts.map +1 -0
  140. package/dist/config/paths.js +104 -0
  141. package/dist/config/paths.js.map +1 -0
  142. package/dist/config/project-config.d.ts +10 -0
  143. package/dist/config/project-config.d.ts.map +1 -0
  144. package/dist/config/project-config.js +59 -0
  145. package/dist/config/project-config.js.map +1 -0
  146. package/dist/context/broker.d.ts +80 -0
  147. package/dist/context/broker.d.ts.map +1 -0
  148. package/dist/context/broker.js +437 -0
  149. package/dist/context/broker.js.map +1 -0
  150. package/dist/context/delivery.d.ts +66 -0
  151. package/dist/context/delivery.d.ts.map +1 -0
  152. package/dist/context/delivery.js +758 -0
  153. package/dist/context/delivery.js.map +1 -0
  154. package/dist/context/feedback.d.ts +75 -0
  155. package/dist/context/feedback.d.ts.map +1 -0
  156. package/dist/context/feedback.js +997 -0
  157. package/dist/context/feedback.js.map +1 -0
  158. package/dist/context/ranking.d.ts +98 -0
  159. package/dist/context/ranking.d.ts.map +1 -0
  160. package/dist/context/ranking.js +513 -0
  161. package/dist/context/ranking.js.map +1 -0
  162. package/dist/context/recommendations.d.ts +85 -0
  163. package/dist/context/recommendations.d.ts.map +1 -0
  164. package/dist/context/recommendations.js +342 -0
  165. package/dist/context/recommendations.js.map +1 -0
  166. package/dist/db/adapter.d.ts +25 -0
  167. package/dist/db/adapter.d.ts.map +1 -0
  168. package/dist/db/adapter.js +37 -0
  169. package/dist/db/adapter.js.map +1 -0
  170. package/dist/db/capabilities.d.ts +13 -0
  171. package/dist/db/capabilities.d.ts.map +1 -0
  172. package/dist/db/capabilities.js +25 -0
  173. package/dist/db/capabilities.js.map +1 -0
  174. package/dist/db/connection.d.ts +6 -0
  175. package/dist/db/connection.d.ts.map +1 -0
  176. package/dist/db/connection.js +42 -0
  177. package/dist/db/connection.js.map +1 -0
  178. package/dist/db/migrate.d.ts +9 -0
  179. package/dist/db/migrate.d.ts.map +1 -0
  180. package/dist/db/migrate.js +102 -0
  181. package/dist/db/migrate.js.map +1 -0
  182. package/dist/db/transaction.d.ts +4 -0
  183. package/dist/db/transaction.d.ts.map +1 -0
  184. package/dist/db/transaction.js +39 -0
  185. package/dist/db/transaction.js.map +1 -0
  186. package/dist/errors.d.ts +9 -0
  187. package/dist/errors.d.ts.map +1 -0
  188. package/dist/errors.js +32 -0
  189. package/dist/errors.js.map +1 -0
  190. package/dist/gateway/agent-service.d.ts +69 -0
  191. package/dist/gateway/agent-service.d.ts.map +1 -0
  192. package/dist/gateway/agent-service.js +581 -0
  193. package/dist/gateway/agent-service.js.map +1 -0
  194. package/dist/gateway/checkpoint-service.d.ts +42 -0
  195. package/dist/gateway/checkpoint-service.d.ts.map +1 -0
  196. package/dist/gateway/checkpoint-service.js +295 -0
  197. package/dist/gateway/checkpoint-service.js.map +1 -0
  198. package/dist/knowledge/sources.d.ts +72 -0
  199. package/dist/knowledge/sources.d.ts.map +1 -0
  200. package/dist/knowledge/sources.js +406 -0
  201. package/dist/knowledge/sources.js.map +1 -0
  202. package/dist/ledger/archive.d.ts +50 -0
  203. package/dist/ledger/archive.d.ts.map +1 -0
  204. package/dist/ledger/archive.js +1072 -0
  205. package/dist/ledger/archive.js.map +1 -0
  206. package/dist/ledger/hash.d.ts +22 -0
  207. package/dist/ledger/hash.d.ts.map +1 -0
  208. package/dist/ledger/hash.js +25 -0
  209. package/dist/ledger/hash.js.map +1 -0
  210. package/dist/ledger/maintenance.d.ts +78 -0
  211. package/dist/ledger/maintenance.d.ts.map +1 -0
  212. package/dist/ledger/maintenance.js +683 -0
  213. package/dist/ledger/maintenance.js.map +1 -0
  214. package/dist/ledger/projection.d.ts +37 -0
  215. package/dist/ledger/projection.d.ts.map +1 -0
  216. package/dist/ledger/projection.js +307 -0
  217. package/dist/ledger/projection.js.map +1 -0
  218. package/dist/ledger/promotion.d.ts +28 -0
  219. package/dist/ledger/promotion.d.ts.map +1 -0
  220. package/dist/ledger/promotion.js +308 -0
  221. package/dist/ledger/promotion.js.map +1 -0
  222. package/dist/ledger/query.d.ts +55 -0
  223. package/dist/ledger/query.d.ts.map +1 -0
  224. package/dist/ledger/query.js +321 -0
  225. package/dist/ledger/query.js.map +1 -0
  226. package/dist/ledger/redaction.d.ts +8 -0
  227. package/dist/ledger/redaction.d.ts.map +1 -0
  228. package/dist/ledger/redaction.js +40 -0
  229. package/dist/ledger/redaction.js.map +1 -0
  230. package/dist/ledger/store.d.ts +46 -0
  231. package/dist/ledger/store.d.ts.map +1 -0
  232. package/dist/ledger/store.js +324 -0
  233. package/dist/ledger/store.js.map +1 -0
  234. package/dist/ledger/types.d.ts +119 -0
  235. package/dist/ledger/types.d.ts.map +1 -0
  236. package/dist/ledger/types.js +22 -0
  237. package/dist/ledger/types.js.map +1 -0
  238. package/dist/ledger/validate.d.ts +10 -0
  239. package/dist/ledger/validate.d.ts.map +1 -0
  240. package/dist/ledger/validate.js +183 -0
  241. package/dist/ledger/validate.js.map +1 -0
  242. package/dist/mcp/server.d.ts +9 -0
  243. package/dist/mcp/server.d.ts.map +1 -0
  244. package/dist/mcp/server.js +86 -0
  245. package/dist/mcp/server.js.map +1 -0
  246. package/dist/memory/audit.d.ts +14 -0
  247. package/dist/memory/audit.d.ts.map +1 -0
  248. package/dist/memory/audit.js +16 -0
  249. package/dist/memory/audit.js.map +1 -0
  250. package/dist/memory/entries.d.ts +65 -0
  251. package/dist/memory/entries.d.ts.map +1 -0
  252. package/dist/memory/entries.js +200 -0
  253. package/dist/memory/entries.js.map +1 -0
  254. package/dist/memory/lifecycle.d.ts +29 -0
  255. package/dist/memory/lifecycle.d.ts.map +1 -0
  256. package/dist/memory/lifecycle.js +61 -0
  257. package/dist/memory/lifecycle.js.map +1 -0
  258. package/dist/memory/retrieval.d.ts +44 -0
  259. package/dist/memory/retrieval.d.ts.map +1 -0
  260. package/dist/memory/retrieval.js +174 -0
  261. package/dist/memory/retrieval.js.map +1 -0
  262. package/dist/memory/scoped-memory.d.ts +41 -0
  263. package/dist/memory/scoped-memory.d.ts.map +1 -0
  264. package/dist/memory/scoped-memory.js +65 -0
  265. package/dist/memory/scoped-memory.js.map +1 -0
  266. package/dist/memory/secrets.d.ts +6 -0
  267. package/dist/memory/secrets.d.ts.map +1 -0
  268. package/dist/memory/secrets.js +17 -0
  269. package/dist/memory/secrets.js.map +1 -0
  270. package/dist/memory/workspaces.d.ts +17 -0
  271. package/dist/memory/workspaces.d.ts.map +1 -0
  272. package/dist/memory/workspaces.js +92 -0
  273. package/dist/memory/workspaces.js.map +1 -0
  274. package/dist/repository/binding.d.ts +19 -0
  275. package/dist/repository/binding.d.ts.map +1 -0
  276. package/dist/repository/binding.js +78 -0
  277. package/dist/repository/binding.js.map +1 -0
  278. package/dist/repository/detect-root.d.ts +12 -0
  279. package/dist/repository/detect-root.d.ts.map +1 -0
  280. package/dist/repository/detect-root.js +57 -0
  281. package/dist/repository/detect-root.js.map +1 -0
  282. package/dist/repository/git-origin.d.ts +2 -0
  283. package/dist/repository/git-origin.d.ts.map +1 -0
  284. package/dist/repository/git-origin.js +15 -0
  285. package/dist/repository/git-origin.js.map +1 -0
  286. package/dist/repository/identity.d.ts +19 -0
  287. package/dist/repository/identity.d.ts.map +1 -0
  288. package/dist/repository/identity.js +23 -0
  289. package/dist/repository/identity.js.map +1 -0
  290. package/dist/repository/remote-url.d.ts +4 -0
  291. package/dist/repository/remote-url.d.ts.map +1 -0
  292. package/dist/repository/remote-url.js +36 -0
  293. package/dist/repository/remote-url.js.map +1 -0
  294. package/dist/security/sanitize.d.ts +4 -0
  295. package/dist/security/sanitize.d.ts.map +1 -0
  296. package/dist/security/sanitize.js +174 -0
  297. package/dist/security/sanitize.js.map +1 -0
  298. package/dist/serialization/envelope.d.ts +20 -0
  299. package/dist/serialization/envelope.d.ts.map +1 -0
  300. package/dist/serialization/envelope.js +11 -0
  301. package/dist/serialization/envelope.js.map +1 -0
  302. package/dist/serialization/validate.d.ts +31 -0
  303. package/dist/serialization/validate.d.ts.map +1 -0
  304. package/dist/serialization/validate.js +168 -0
  305. package/dist/serialization/validate.js.map +1 -0
  306. package/dist/server/agent-application.d.ts +6 -0
  307. package/dist/server/agent-application.d.ts.map +1 -0
  308. package/dist/server/agent-application.js +60 -0
  309. package/dist/server/agent-application.js.map +1 -0
  310. package/dist/server/app.d.ts +5 -0
  311. package/dist/server/app.d.ts.map +1 -0
  312. package/dist/server/app.js +87 -0
  313. package/dist/server/app.js.map +1 -0
  314. package/dist/server/auth.d.ts +2 -0
  315. package/dist/server/auth.d.ts.map +1 -0
  316. package/dist/server/auth.js +22 -0
  317. package/dist/server/auth.js.map +1 -0
  318. package/dist/server/http.d.ts +69 -0
  319. package/dist/server/http.d.ts.map +1 -0
  320. package/dist/server/http.js +349 -0
  321. package/dist/server/http.js.map +1 -0
  322. package/dist/server/idempotency.d.ts +12 -0
  323. package/dist/server/idempotency.d.ts.map +1 -0
  324. package/dist/server/idempotency.js +210 -0
  325. package/dist/server/idempotency.js.map +1 -0
  326. package/dist/server/instance-lock.d.ts +17 -0
  327. package/dist/server/instance-lock.d.ts.map +1 -0
  328. package/dist/server/instance-lock.js +118 -0
  329. package/dist/server/instance-lock.js.map +1 -0
  330. package/dist/server/router.d.ts +29 -0
  331. package/dist/server/router.d.ts.map +1 -0
  332. package/dist/server/router.js +112 -0
  333. package/dist/server/router.js.map +1 -0
  334. package/dist/server/routes/agent-events.d.ts +5 -0
  335. package/dist/server/routes/agent-events.d.ts.map +1 -0
  336. package/dist/server/routes/agent-events.js +46 -0
  337. package/dist/server/routes/agent-events.js.map +1 -0
  338. package/dist/server/routes/agent-intake.d.ts +5 -0
  339. package/dist/server/routes/agent-intake.d.ts.map +1 -0
  340. package/dist/server/routes/agent-intake.js +42 -0
  341. package/dist/server/routes/agent-intake.js.map +1 -0
  342. package/dist/server/routes/agent-promotions.d.ts +5 -0
  343. package/dist/server/routes/agent-promotions.d.ts.map +1 -0
  344. package/dist/server/routes/agent-promotions.js +52 -0
  345. package/dist/server/routes/agent-promotions.js.map +1 -0
  346. package/dist/server/routes/agent-runs.d.ts +25 -0
  347. package/dist/server/routes/agent-runs.d.ts.map +1 -0
  348. package/dist/server/routes/agent-runs.js +151 -0
  349. package/dist/server/routes/agent-runs.js.map +1 -0
  350. package/dist/server/routes/task5-support.d.ts +11 -0
  351. package/dist/server/routes/task5-support.d.ts.map +1 -0
  352. package/dist/server/routes/task5-support.js +22 -0
  353. package/dist/server/routes/task5-support.js.map +1 -0
  354. package/dist/server/routes/task5.d.ts +5 -0
  355. package/dist/server/routes/task5.d.ts.map +1 -0
  356. package/dist/server/routes/task5.js +72 -0
  357. package/dist/server/routes/task5.js.map +1 -0
  358. package/dist/server/runtime-descriptor.d.ts +24 -0
  359. package/dist/server/runtime-descriptor.d.ts.map +1 -0
  360. package/dist/server/runtime-descriptor.js +156 -0
  361. package/dist/server/runtime-descriptor.js.map +1 -0
  362. package/dist/server/write-queue.d.ts +20 -0
  363. package/dist/server/write-queue.d.ts.map +1 -0
  364. package/dist/server/write-queue.js +83 -0
  365. package/dist/server/write-queue.js.map +1 -0
  366. package/dist/setup/managed-text.d.ts +6 -0
  367. package/dist/setup/managed-text.d.ts.map +1 -0
  368. package/dist/setup/managed-text.js +42 -0
  369. package/dist/setup/managed-text.js.map +1 -0
  370. package/dist/setup/opencode-config.d.ts +3 -0
  371. package/dist/setup/opencode-config.d.ts.map +1 -0
  372. package/dist/setup/opencode-config.js +26 -0
  373. package/dist/setup/opencode-config.js.map +1 -0
  374. package/dist/setup/render.d.ts +8 -0
  375. package/dist/setup/render.d.ts.map +1 -0
  376. package/dist/setup/render.js +45 -0
  377. package/dist/setup/render.js.map +1 -0
  378. package/dist/web/server.d.ts +16 -0
  379. package/dist/web/server.d.ts.map +1 -0
  380. package/dist/web/server.js +424 -0
  381. package/dist/web/server.js.map +1 -0
  382. package/dist/web/ui.d.ts +2 -0
  383. package/dist/web/ui.d.ts.map +1 -0
  384. package/dist/web/ui.js +271 -0
  385. package/dist/web/ui.js.map +1 -0
  386. package/migrations/001_initial.sql +89 -0
  387. package/migrations/002_fts.sql +66 -0
  388. package/migrations/003_akinator.sql +30 -0
  389. package/migrations/004_agent_gateway.sql +259 -0
  390. package/package.json +45 -0
  391. package/templates/AGENTS.md +29 -0
package/dist/web/ui.js ADDED
@@ -0,0 +1,271 @@
1
+ export const WEB_HTML = String.raw `<!doctype html>
2
+ <html lang="ja">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>Kiokuko Web</title>
7
+ <style>
8
+ :root { color-scheme: light; --ink:#1e293b; --muted:#64748b; --line:#e2e8f0; --panel:#ffffff; --surface:#f8fafc; --accent:#2563eb; --accent-soft:#eff6ff; --warn:#b45309; --danger:#b91c1c; }
9
+ * { box-sizing:border-box; }
10
+ 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; }
11
+ button,input,select,textarea { font:inherit; }
12
+ button { cursor:pointer; }
13
+ .shell { max-width:1440px; margin:0 auto; padding:28px; }
14
+ .topbar { display:flex; gap:18px; justify-content:space-between; align-items:flex-end; margin-bottom:22px; }
15
+ .eyebrow { color:var(--accent); font-size:12px; font-weight:800; letter-spacing:.16em; text-transform:uppercase; }
16
+ h1 { margin:4px 0 0; font-size:clamp(28px,4vw,44px); letter-spacing:-.04em; }
17
+ .subtitle { margin:8px 0 0; color:var(--muted); }
18
+ .toolbar { display:flex; gap:10px; align-items:center; flex-wrap:wrap; }
19
+ .control, .search { border:1px solid var(--line); border-radius:12px; background:var(--panel); color:var(--ink); padding:10px 12px; }
20
+ .search { min-width:260px; }
21
+ .button { border:1px solid var(--line); border-radius:12px; background:var(--panel); color:var(--ink); padding:10px 14px; font-weight:700; }
22
+ .button.primary { background:var(--accent); color:#fff; border-color:var(--accent); }
23
+ .button:disabled { cursor:not-allowed; opacity:.45; }
24
+ .layout { display:grid; grid-template-columns:220px minmax(300px,1fr) minmax(360px,1.15fr); gap:16px; align-items:start; }
25
+ .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; }
26
+ .panel-head { padding:18px 20px; border-bottom:1px solid var(--line); display:flex; justify-content:space-between; align-items:center; gap:12px; }
27
+ .panel-head h2 { margin:0; font-size:16px; }
28
+ .panel-body { padding:16px; }
29
+ .genres { padding:10px; }
30
+ .filter-group + .filter-group { border-top:1px solid var(--line); margin-top:8px; padding-top:8px; }
31
+ .filter-group-title { color:var(--muted); font-size:11px; font-weight:800; letter-spacing:.08em; padding:8px 12px 4px; text-transform:uppercase; }
32
+ .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; }
33
+ .genre:hover,.genre.active { background:var(--accent-soft); color:var(--accent); }
34
+ .count { min-width:26px; padding:2px 7px; border-radius:999px; background:#e2e8f0; color:var(--muted); font-size:12px; text-align:center; }
35
+ .genre.active .count { background:#dbeafe; color:var(--accent); }
36
+ .entry-list { display:flex; flex-direction:column; gap:10px; max-height:calc(100vh - 220px); overflow:auto; }
37
+ .entry-card { border:1px solid var(--line); border-radius:14px; padding:14px; background:var(--panel); transition:.16s ease; }
38
+ .entry-card:hover,.entry-card.selected { border-color:#93c5fd; box-shadow:0 8px 20px rgba(37,99,235,.10); }
39
+ .entry-meta { display:flex; gap:7px; align-items:center; flex-wrap:wrap; color:var(--muted); font-size:12px; }
40
+ .badge { border-radius:999px; padding:3px 8px; background:#f1f5f9; color:#475569; font-weight:700; }
41
+ .badge.verified { background:#dcfce7; color:#166534; }
42
+ .badge.candidate { background:#fef3c7; color:#92400e; }
43
+ .badge.superseded { background:#fee2e2; color:#991b1b; }
44
+ .entry-card h3 { margin:9px 0 6px; font-size:16px; }
45
+ .snippet { margin:0; color:var(--muted); display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical; overflow:hidden; white-space:pre-wrap; }
46
+ .tags { display:flex; gap:6px; flex-wrap:wrap; margin-top:10px; }
47
+ .tag { border:0; background:transparent; color:var(--accent); font-size:12px; padding:0; }
48
+ .tag:hover { text-decoration:underline; }
49
+ .form { display:grid; gap:12px; }
50
+ label { display:grid; gap:6px; color:var(--muted); font-size:12px; font-weight:800; letter-spacing:.04em; }
51
+ textarea,input,select { width:100%; border:1px solid var(--line); border-radius:10px; padding:10px 11px; background:#fff; color:var(--ink); }
52
+ textarea { min-height:120px; resize:vertical; line-height:1.55; }
53
+ textarea.body { min-height:260px; }
54
+ .form-row { display:grid; grid-template-columns:1fr 1fr; gap:10px; }
55
+ .editor-empty { color:var(--muted); padding:30px 10px; text-align:center; }
56
+ .notice { border-radius:12px; padding:11px 12px; background:#fffbeb; color:var(--warn); font-size:13px; }
57
+ .notice.error { background:#fef2f2; color:var(--danger); }
58
+ .status { color:var(--muted); font-size:12px; min-height:18px; }
59
+ .operator-panel { grid-column:1 / -1; }
60
+ .operator-grid { display:grid; grid-template-columns:minmax(240px,.7fr) minmax(420px,1.3fr); gap:16px; }
61
+ .run-list { display:flex; flex-direction:column; gap:8px; max-height:360px; overflow:auto; }
62
+ .run-card { border:1px solid var(--line); border-radius:12px; padding:11px; background:var(--panel); text-align:left; }
63
+ .run-card.selected { border-color:#93c5fd; background:var(--accent-soft); }
64
+ .detail-block { border-top:1px solid var(--line); padding-top:12px; margin-top:12px; }
65
+ .detail-block h3 { margin:0 0 8px; font-size:14px; }
66
+ .detail-text { white-space:pre-wrap; overflow-wrap:anywhere; color:var(--muted); font-size:13px; }
67
+ @media (max-width:680px) { .operator-grid { grid-template-columns:1fr; } }
68
+ @media (max-width:1050px) { .layout { grid-template-columns:180px minmax(280px,1fr); } .editor-panel { grid-column:1 / -1; } }
69
+ @media (max-width:680px) { .shell { padding:16px; } .topbar { display:block; } .toolbar { margin-top:16px; } .search { min-width:0; flex:1; } .layout { grid-template-columns:1fr; } .genres-panel { order:0; } .list-panel { order:1; } .editor-panel { order:2; } .entry-list { max-height:none; } }
70
+ </style>
71
+ </head>
72
+ <body>
73
+ <main class="shell">
74
+ <header class="topbar">
75
+ <div>
76
+ <div class="eyebrow">Local memory console</div>
77
+ <h1>Kiokuko Web</h1>
78
+ <p class="subtitle">Bot用途・記憶タイプ・横断タグからSQLiteの記憶を確認し、安全に候補エントリを編集します。</p>
79
+ </div>
80
+ <div class="toolbar">
81
+ <select id="workspace" class="control" aria-label="ワークスペース"></select>
82
+ <input id="search" class="search" type="search" placeholder="記憶を検索…" aria-label="記憶を検索">
83
+ <button id="refresh" class="button" type="button">更新</button>
84
+ </div>
85
+ </header>
86
+ <div id="status" class="status" role="status"></div>
87
+ <section class="layout">
88
+ <aside class="panel genres-panel">
89
+ <div class="panel-head"><h2>Bot用途 / タグ</h2></div>
90
+ <nav id="genres" class="genres" aria-label="Bot用途・記憶タイプ・タグのフィルター"></nav>
91
+ </aside>
92
+ <section class="panel list-panel">
93
+ <div class="panel-head"><h2 id="list-title">記憶</h2><span id="result-count" class="badge">0件</span></div>
94
+ <div class="panel-body"><div id="entry-list" class="entry-list"></div></div>
95
+ </section>
96
+ <section class="panel editor-panel">
97
+ <div class="panel-head"><h2>内容</h2><span id="editor-state" class="badge">未選択</span></div>
98
+ <div class="panel-body"><div id="editor"></div></div>
99
+ </section>
100
+ </section>
101
+ <section class="panel operator-panel">
102
+ <div class="panel-head"><h2>Agent run operator view</h2><span class="badge">stored data is untrusted / non-actionable</span></div>
103
+ <div class="panel-body operator-grid">
104
+ <div><div id="run-list" class="run-list"></div><div id="run-page" class="status"></div></div>
105
+ <div id="run-detail"><div class="editor-empty">runを選択すると intake、profile、timeline、delivery、feedback、coverage を表示します。</div></div>
106
+ </div>
107
+ </section>
108
+ </main>
109
+ <script>
110
+ const kinds = [
111
+ ['all', 'すべて'], ['fact', '事実'], ['decision', '決定'], ['lesson', '教訓'], ['preference', '好み'], ['reference', '参照']
112
+ ];
113
+ const botModes = [
114
+ ['bot:common', '共通'], ['bot:researcher', 'Researcher'], ['bot:builder', 'Builder'], ['bot:reviewer', 'Reviewer'], ['bot:devops', 'DevOps'], ['bot:writer', 'Writer'], ['bot:analyst', 'Analyst']
115
+ ];
116
+ const state = { workspace: '', kind: 'all', tag: '', query: '', entries: [], tags: [], selected: null, runs: [], selectedRun: null };
117
+ const $ = (id) => document.getElementById(id);
118
+ const api = async (path, options) => {
119
+ const response = await fetch(path, options);
120
+ const value = await response.json();
121
+ if (!response.ok) throw new Error(value.error?.message || 'リクエストに失敗しました');
122
+ return value;
123
+ };
124
+ const setStatus = (message, error = false) => { $('status').textContent = message; $('status').className = error ? 'status notice error' : 'status'; };
125
+ const labelForKind = (kind) => (kinds.find((item) => item[0] === kind) || [kind, kind])[1];
126
+ const escapeTags = (value) => value.split(',').map((item) => item.trim()).filter(Boolean);
127
+
128
+ function filterButton(key, label, count, active, onClick) {
129
+ const button = document.createElement('button');
130
+ button.type = 'button';
131
+ button.className = 'genre ' + (active ? 'active' : '');
132
+ const text = document.createElement('span'); text.textContent = label;
133
+ const countBadge = document.createElement('span'); countBadge.className = 'count'; countBadge.textContent = String(count || 0);
134
+ button.append(text, countBadge);
135
+ button.dataset.filter = key;
136
+ button.addEventListener('click', onClick);
137
+ return button;
138
+ }
139
+
140
+ function filterGroup(title, buttons) {
141
+ const group = document.createElement('section'); group.className = 'filter-group';
142
+ const heading = document.createElement('div'); heading.className = 'filter-group-title'; heading.textContent = title; group.append(heading, ...buttons); return group;
143
+ }
144
+
145
+ function renderFilters() {
146
+ const kindCounts = Object.fromEntries(kinds.map(([kind]) => [kind, kind === 'all' ? state.entries.length : state.entries.filter((entry) => entry.kind === kind).length]));
147
+ const tagCounts = Object.fromEntries(state.tags.map((item) => [item.tag, item.count]));
148
+ const botButtons = botModes.map(([tag, label]) => filterButton(tag, label, tagCounts[tag], state.tag === tag, () => { state.tag = tag; renderFilters(); loadEntries(); }));
149
+ const kindButtons = kinds.map(([kind, label]) => filterButton(kind, label, kindCounts[kind], state.kind === kind, () => { state.kind = kind; renderFilters(); loadEntries(); }));
150
+ const tagButtons = state.tags
151
+ .filter((item) => !botModes.some(([tag]) => tag === item.tag))
152
+ .map((item) => filterButton(item.tag, '#' + item.tag, item.count, state.tag === item.tag, () => { state.tag = item.tag; renderFilters(); loadEntries(); }));
153
+ const root = $('genres'); root.replaceChildren(filterGroup('Bot用途(タグ)', botButtons), filterGroup('記憶タイプ', kindButtons));
154
+ if (tagButtons.length > 0) root.append(filterGroup('横断タグ', tagButtons));
155
+ }
156
+
157
+ function renderEntries() {
158
+ $('result-count').textContent = String(state.entries.length) + '件';
159
+ $('list-title').textContent = state.tag ? '#' + state.tag : (state.kind === 'all' ? '記憶' : labelForKind(state.kind));
160
+ const list = $('entry-list');
161
+ if (!state.entries.length) {
162
+ const empty = document.createElement('div'); empty.className = 'editor-empty'; empty.textContent = '該当する記憶はありません。'; list.replaceChildren(empty); return;
163
+ }
164
+ list.replaceChildren(...state.entries.map((entry) => {
165
+ const card = document.createElement('article'); card.className = 'entry-card ' + (state.selected?.id === entry.id ? 'selected' : '');
166
+ const meta = document.createElement('div'); meta.className = 'entry-meta';
167
+ const kind = document.createElement('span'); kind.className = 'badge'; kind.textContent = labelForKind(entry.kind);
168
+ const status = document.createElement('span'); status.className = 'badge ' + entry.status; status.textContent = entry.status;
169
+ const revision = document.createElement('span'); revision.textContent = 'revision ' + entry.revision; meta.append(kind, status, revision);
170
+ const title = document.createElement('h3'); title.textContent = entry.title;
171
+ const snippet = document.createElement('p'); snippet.className = 'snippet'; snippet.textContent = entry.summary || entry.body;
172
+ 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); });
173
+ const edit = document.createElement('button'); edit.type = 'button'; edit.className = 'button'; edit.textContent = '編集'; edit.style.marginTop = '12px'; edit.addEventListener('click', (event) => { event.stopPropagation(); selectEntry(entry.id); });
174
+ card.append(meta, title, snippet, tags, edit); card.addEventListener('click', () => selectEntry(entry.id)); return card;
175
+ }));
176
+ }
177
+
178
+ function renderEditor() {
179
+ const editor = $('editor');
180
+ const entry = state.selected;
181
+ $('editor-state').textContent = entry ? entry.status : '未選択';
182
+ if (!entry) { const empty = document.createElement('div'); empty.className = 'editor-empty'; empty.textContent = '左の記憶を選択すると内容を編集できます。'; editor.replaceChildren(empty); return; }
183
+ const form = document.createElement('form'); form.className = 'form';
184
+ const row = document.createElement('div'); row.className = 'form-row';
185
+ const kindLabel = document.createElement('label'); kindLabel.textContent = '記憶タイプ'; const kind = document.createElement('select'); kinds.filter(([value]) => value !== 'all').forEach(([value, label]) => { const option = document.createElement('option'); option.value = value; option.textContent = label; kind.append(option); }); kind.value = entry.kind; kindLabel.append(kind);
186
+ const statusLabel = document.createElement('label'); statusLabel.textContent = '状態'; const status = document.createElement('input'); status.value = entry.status; status.disabled = true; statusLabel.append(status); row.append(kindLabel, statusLabel);
187
+ const titleLabel = document.createElement('label'); titleLabel.textContent = 'タイトル'; const title = document.createElement('input'); title.value = entry.title; titleLabel.append(title);
188
+ const bodyLabel = document.createElement('label'); bodyLabel.textContent = '本文'; const body = document.createElement('textarea'); body.className = 'body'; body.value = entry.body; bodyLabel.append(body);
189
+ const summaryLabel = document.createElement('label'); summaryLabel.textContent = '要約'; const summary = document.createElement('textarea'); summary.value = entry.summary || ''; summaryLabel.append(summary);
190
+ const tagsLabel = document.createElement('label'); tagsLabel.textContent = 'タグ(カンマ区切り)'; const tags = document.createElement('input'); tags.value = entry.tags.join(', '); tagsLabel.append(tags);
191
+ const jsonRow = document.createElement('div'); jsonRow.className = 'form-row';
192
+ const scopeLabel = document.createElement('label'); scopeLabel.textContent = 'scope JSON'; const scope = document.createElement('textarea'); scope.value = JSON.stringify(entry.scope, null, 2); scopeLabel.append(scope);
193
+ const provenanceLabel = document.createElement('label'); provenanceLabel.textContent = 'provenance JSON'; const provenance = document.createElement('textarea'); provenance.value = JSON.stringify(entry.provenance, null, 2); provenanceLabel.append(provenance); jsonRow.append(scopeLabel, provenanceLabel);
194
+ const actions = document.createElement('div'); actions.className = 'toolbar';
195
+ const save = document.createElement('button'); save.type = 'submit'; save.className = 'button primary'; save.textContent = '保存';
196
+ const note = document.createElement('div'); note.className = entry.status === 'candidate' ? 'notice' : 'notice error'; note.textContent = entry.status === 'candidate' ? '候補エントリはrevisionを確認して更新します。' : 'verified / superseded は直接上書きできません。履歴を保つためCLIで置換してください。';
197
+ if (entry.status !== 'candidate') { save.disabled = true; [kind, title, body, summary, tags, scope, provenance].forEach((control) => { control.disabled = true; }); }
198
+ actions.append(save); form.append(row, titleLabel, bodyLabel, summaryLabel, tagsLabel, jsonRow, note, actions); form.addEventListener('submit', async (event) => { event.preventDefault(); if (save.disabled) return; try {
199
+ 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) };
200
+ await api('/api/entries/' + encodeURIComponent(entry.id) + '?workspace=' + encodeURIComponent(state.workspace), { method: 'PUT', headers: { 'content-type': 'application/json' }, body: JSON.stringify(payload) });
201
+ setStatus('保存しました。'); await loadEntries(); await selectEntry(entry.id);
202
+ } catch (error) { setStatus(error.message, true); }
203
+ }); editor.replaceChildren(form);
204
+ }
205
+
206
+ async function selectEntry(id) { try { const result = await api('/api/entries/' + encodeURIComponent(id) + '?workspace=' + encodeURIComponent(state.workspace)); state.selected = result.entry; renderEntries(); renderEditor(); } catch (error) { setStatus(error.message, true); } }
207
+
208
+ async function loadRunDetail(runId) {
209
+ try {
210
+ const result = await api('/api/operator/runs/' + encodeURIComponent(runId));
211
+ state.selectedRun = result;
212
+ renderRunDetail();
213
+ } catch (error) { setStatus(error.message, true); }
214
+ }
215
+
216
+ function detailBlock(title, value) {
217
+ const block = document.createElement('section'); block.className = 'detail-block';
218
+ const heading = document.createElement('h3'); heading.textContent = title;
219
+ const text = document.createElement('div'); text.className = 'detail-text'; text.textContent = typeof value === 'string' ? value : JSON.stringify(value, null, 2);
220
+ block.append(heading, text); return block;
221
+ }
222
+
223
+ function renderRunDetail() {
224
+ const root = $('run-detail'); const detail = state.selectedRun;
225
+ if (!detail) { const empty = document.createElement('div'); empty.className = 'editor-empty'; empty.textContent = 'runを選択すると詳細を表示します。'; root.replaceChildren(empty); return; }
226
+ const heading = document.createElement('h3'); heading.textContent = 'Stored context / recommendations: untrusted, non-actionable';
227
+ const blocks = [
228
+ detailBlock('run / intake', { run: detail.run, intake: detail.intake }),
229
+ detailBlock('initial profile (immutable view)', detail.profile.initial),
230
+ detailBlock('projected profile (ledger revisions)', detail.profile.projected),
231
+ detailBlock('policy / profile source', { policyVersion: detail.profile.policyVersion, source: detail.profile.source, initialProfileHash: detail.profile.initialProfileHash }),
232
+ detailBlock('coverage / evidence warnings', { coverage: detail.coverage, evidenceState: detail.evidenceState, warnings: detail.warnings }),
233
+ detailBlock('timeline / evidence', { timeline: detail.timeline, evidence: detail.evidence }),
234
+ detailBlock('context deliveries / selection reasons', detail.deliveries),
235
+ detailBlock('context / run / intake feedback', detail.feedback),
236
+ detailBlock('memory proposal links', { proposals: detail.proposals, links: detail.memoryLinks }),
237
+ ];
238
+ root.replaceChildren(heading, ...blocks);
239
+ }
240
+
241
+ function renderRuns() {
242
+ const root = $('run-list');
243
+ if (!state.runs.length) { const empty = document.createElement('div'); empty.className = 'editor-empty'; empty.textContent = 'runはありません。'; root.replaceChildren(empty); return; }
244
+ root.replaceChildren(...state.runs.map((run) => {
245
+ const button = document.createElement('button'); button.type = 'button'; button.className = 'run-card' + (state.selectedRun?.run?.runId === run.runId ? ' selected' : '');
246
+ button.textContent = run.runId + ' / ' + (run.status || 'unknown') + ' / ' + (run.title || 'untitled');
247
+ button.addEventListener('click', () => loadRunDetail(run.runId)); return button;
248
+ }));
249
+ }
250
+
251
+ async function loadRuns() {
252
+ if (!state.workspace) return;
253
+ try {
254
+ const result = await api('/api/operator/runs?workspace=' + encodeURIComponent(state.workspace) + '&limit=50');
255
+ state.runs = result.items || []; renderRuns(); $('run-page').textContent = result.nextCursor ? '次ページあり(bounded cursor)' : '末尾';
256
+ if (!state.selectedRun && state.runs[0]) await loadRunDetail(state.runs[0].runId);
257
+ else renderRunDetail();
258
+ } catch (error) { setStatus(error.message, true); }
259
+ }
260
+
261
+ async function loadEntries() { if (!state.workspace) return; try { const params = new URLSearchParams({ workspace: state.workspace }); if (state.kind !== 'all') params.set('kind', state.kind); if (state.tag) params.set('tag', state.tag); if (state.query) params.set('q', state.query); const result = await api('/api/entries?' + params); state.entries = result.entries; if (state.selected && !state.entries.some((entry) => entry.id === state.selected.id)) state.selected = null; renderEntries(); renderFilters(); if (!state.selected && state.entries[0]) await selectEntry(state.entries[0].id); else renderEditor(); setStatus(String(result.entries.length) + '件を表示中'); } catch (error) { setStatus(error.message, true); } }
262
+ 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); } }
263
+ 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(); } else setStatus('workspaceがありません。CLIで kiokuko use または record を実行してください。', true); } catch (error) { setStatus(error.message, true); } }
264
+ $('workspace').addEventListener('change', (event) => { state.workspace = event.target.value; state.selected = null; state.selectedRun = null; state.runs = []; state.tag = ''; loadTags().then(loadEntries).then(loadRuns); });
265
+ $('refresh').addEventListener('click', () => loadWorkspaces());
266
+ let searchTimer; $('search').addEventListener('input', (event) => { clearTimeout(searchTimer); state.query = event.target.value.trim(); searchTimer = setTimeout(() => loadEntries(), 180); });
267
+ loadWorkspaces();
268
+ </script>
269
+ </body>
270
+ </html>`;
271
+ //# sourceMappingURL=ui.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.js","sourceRoot":"","sources":["../../src/web/ui.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA6Q1B,CAAC"}
@@ -0,0 +1,89 @@
1
+ CREATE TABLE IF NOT EXISTS schema_migrations (
2
+ version INTEGER PRIMARY KEY,
3
+ name TEXT NOT NULL,
4
+ checksum TEXT NOT NULL,
5
+ applied_at TEXT NOT NULL
6
+ );
7
+
8
+ CREATE TABLE repositories (
9
+ repository_id TEXT PRIMARY KEY,
10
+ workspace TEXT NOT NULL UNIQUE,
11
+ display_name TEXT NOT NULL,
12
+ remote_fingerprint TEXT,
13
+ binding_schema_version INTEGER NOT NULL,
14
+ agent_template_version INTEGER NOT NULL,
15
+ created_at TEXT NOT NULL,
16
+ last_used_at TEXT NOT NULL
17
+ );
18
+
19
+ CREATE TABLE repository_locations (
20
+ repository_id TEXT NOT NULL REFERENCES repositories(repository_id),
21
+ canonical_root TEXT NOT NULL UNIQUE,
22
+ first_seen_at TEXT NOT NULL,
23
+ last_seen_at TEXT NOT NULL,
24
+ PRIMARY KEY (repository_id, canonical_root)
25
+ );
26
+
27
+ CREATE TABLE entries (
28
+ id TEXT PRIMARY KEY,
29
+ workspace TEXT NOT NULL,
30
+ kind TEXT NOT NULL CHECK (
31
+ kind IN ('fact', 'decision', 'lesson', 'preference', 'reference')
32
+ ),
33
+ status TEXT NOT NULL CHECK (
34
+ status IN ('candidate', 'verified', 'superseded')
35
+ ),
36
+ title TEXT NOT NULL,
37
+ body TEXT NOT NULL,
38
+ summary TEXT,
39
+ scope_json TEXT NOT NULL DEFAULT '{}',
40
+ provenance_json TEXT NOT NULL DEFAULT '{}',
41
+ trust_level TEXT NOT NULL DEFAULT 'user_asserted' CHECK (
42
+ trust_level IN ('untrusted', 'user_asserted', 'source_verified', 'system_verified')
43
+ ),
44
+ confidence REAL NOT NULL CHECK (confidence >= 0.0 AND confidence <= 1.0),
45
+ content_hash TEXT NOT NULL,
46
+ revision INTEGER NOT NULL DEFAULT 1,
47
+ superseded_by TEXT REFERENCES entries(id),
48
+ created_by TEXT NOT NULL,
49
+ created_at TEXT NOT NULL,
50
+ updated_at TEXT NOT NULL,
51
+ verified_at TEXT,
52
+ CHECK (status != 'superseded' OR superseded_by IS NOT NULL)
53
+ );
54
+
55
+ CREATE UNIQUE INDEX idx_entries_workspace_hash
56
+ ON entries(workspace, content_hash);
57
+ CREATE INDEX idx_entries_workspace_status
58
+ ON entries(workspace, status, updated_at DESC);
59
+ CREATE INDEX idx_entries_workspace_kind
60
+ ON entries(workspace, kind, updated_at DESC);
61
+
62
+ CREATE TABLE tags (
63
+ entry_id TEXT NOT NULL REFERENCES entries(id) ON DELETE CASCADE,
64
+ tag TEXT NOT NULL,
65
+ PRIMARY KEY (entry_id, tag)
66
+ );
67
+
68
+ CREATE TABLE entry_links (
69
+ from_entry_id TEXT NOT NULL REFERENCES entries(id),
70
+ to_entry_id TEXT NOT NULL REFERENCES entries(id),
71
+ relation TEXT NOT NULL CHECK (
72
+ relation IN ('supports', 'contradicts', 'derived_from', 'related_to')
73
+ ),
74
+ created_at TEXT NOT NULL,
75
+ created_by TEXT NOT NULL,
76
+ PRIMARY KEY (from_entry_id, to_entry_id, relation)
77
+ );
78
+
79
+ CREATE TABLE audit_events (
80
+ event_id TEXT PRIMARY KEY,
81
+ entry_id TEXT REFERENCES entries(id),
82
+ workspace TEXT NOT NULL,
83
+ operation TEXT NOT NULL CHECK (
84
+ operation IN ('record', 'promote', 'supersede', 'link', 'import', 'purge')
85
+ ),
86
+ actor TEXT NOT NULL,
87
+ details_json TEXT NOT NULL DEFAULT '{}',
88
+ created_at TEXT NOT NULL
89
+ );
@@ -0,0 +1,66 @@
1
+ CREATE VIRTUAL TABLE entries_fts USING fts5(
2
+ title,
3
+ body,
4
+ summary,
5
+ tags_text,
6
+ tokenize='unicode61 remove_diacritics 2'
7
+ );
8
+
9
+ CREATE TRIGGER entries_fts_ai AFTER INSERT ON entries BEGIN
10
+ INSERT INTO entries_fts(rowid, title, body, summary, tags_text)
11
+ VALUES (
12
+ new.rowid,
13
+ new.title,
14
+ new.body,
15
+ COALESCE(new.summary, ''),
16
+ COALESCE((SELECT group_concat(tag, ' ') FROM tags WHERE entry_id = new.id), '')
17
+ );
18
+ END;
19
+
20
+ CREATE TRIGGER entries_fts_ad AFTER DELETE ON entries BEGIN
21
+ DELETE FROM entries_fts WHERE rowid = old.rowid;
22
+ END;
23
+
24
+ CREATE TRIGGER entries_fts_au AFTER UPDATE ON entries BEGIN
25
+ DELETE FROM entries_fts WHERE rowid = old.rowid;
26
+ INSERT INTO entries_fts(rowid, title, body, summary, tags_text)
27
+ VALUES (
28
+ new.rowid,
29
+ new.title,
30
+ new.body,
31
+ COALESCE(new.summary, ''),
32
+ COALESCE((SELECT group_concat(tag, ' ') FROM tags WHERE entry_id = new.id), '')
33
+ );
34
+ END;
35
+
36
+ CREATE TRIGGER tags_fts_ai AFTER INSERT ON tags BEGIN
37
+ DELETE FROM entries_fts WHERE rowid = (SELECT rowid FROM entries WHERE id = new.entry_id);
38
+ INSERT INTO entries_fts(rowid, title, body, summary, tags_text)
39
+ SELECT entries.rowid, entries.title, entries.body, COALESCE(entries.summary, ''),
40
+ COALESCE((SELECT group_concat(tag, ' ') FROM tags WHERE entry_id = entries.id), '')
41
+ FROM entries WHERE entries.id = new.entry_id;
42
+ END;
43
+
44
+ CREATE TRIGGER tags_fts_ad AFTER DELETE ON tags BEGIN
45
+ DELETE FROM entries_fts WHERE rowid = (SELECT rowid FROM entries WHERE id = old.entry_id);
46
+ INSERT INTO entries_fts(rowid, title, body, summary, tags_text)
47
+ SELECT entries.rowid, entries.title, entries.body, COALESCE(entries.summary, ''),
48
+ COALESCE((SELECT group_concat(tag, ' ') FROM tags WHERE entry_id = entries.id), '')
49
+ FROM entries WHERE entries.id = old.entry_id;
50
+ END;
51
+
52
+ CREATE TRIGGER tags_fts_au AFTER UPDATE OF tag ON tags BEGIN
53
+ DELETE FROM entries_fts WHERE rowid = (SELECT rowid FROM entries WHERE id = old.entry_id);
54
+ INSERT INTO entries_fts(rowid, title, body, summary, tags_text)
55
+ SELECT entries.rowid, entries.title, entries.body, COALESCE(entries.summary, ''),
56
+ COALESCE((SELECT group_concat(tag, ' ') FROM tags WHERE entry_id = entries.id), '')
57
+ FROM entries WHERE entries.id = new.entry_id;
58
+ END;
59
+
60
+ INSERT INTO entries_fts(rowid, title, body, summary, tags_text)
61
+ SELECT entries.rowid,
62
+ entries.title,
63
+ entries.body,
64
+ COALESCE(entries.summary, ''),
65
+ COALESCE((SELECT group_concat(tag, ' ') FROM tags WHERE entry_id = entries.id), '')
66
+ FROM entries;
@@ -0,0 +1,30 @@
1
+ CREATE TABLE akinator_sessions (
2
+ id TEXT PRIMARY KEY,
3
+ workspace TEXT NOT NULL,
4
+ task_text TEXT NOT NULL,
5
+ profile_json TEXT NOT NULL,
6
+ status TEXT NOT NULL CHECK (status IN ('active', 'ready', 'exhausted')),
7
+ question_count INTEGER NOT NULL DEFAULT 0 CHECK (question_count >= 0),
8
+ created_at TEXT NOT NULL,
9
+ updated_at TEXT NOT NULL
10
+ );
11
+
12
+ CREATE INDEX idx_akinator_sessions_workspace
13
+ ON akinator_sessions(workspace, updated_at DESC);
14
+
15
+ CREATE TABLE akinator_answers (
16
+ session_id TEXT NOT NULL REFERENCES akinator_sessions(id) ON DELETE CASCADE,
17
+ question_id TEXT NOT NULL,
18
+ answer_json TEXT NOT NULL,
19
+ created_at TEXT NOT NULL,
20
+ PRIMARY KEY (session_id, question_id)
21
+ );
22
+
23
+ CREATE TABLE knowledge_sources (
24
+ source_id TEXT PRIMARY KEY,
25
+ repository_url TEXT NOT NULL UNIQUE,
26
+ ref_name TEXT NOT NULL,
27
+ commit_sha TEXT NOT NULL,
28
+ document_count INTEGER NOT NULL DEFAULT 0,
29
+ last_synced_at TEXT NOT NULL
30
+ );