@jagilber-org/index-server 1.19.1

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 (360) hide show
  1. package/CHANGELOG.md +1218 -0
  2. package/CODE_OF_CONDUCT.md +49 -0
  3. package/CONTRIBUTING.md +75 -0
  4. package/LICENSE +21 -0
  5. package/README.md +523 -0
  6. package/SECURITY.md +50 -0
  7. package/dist/config/configUtils.d.ts +11 -0
  8. package/dist/config/configUtils.js +87 -0
  9. package/dist/config/dashboardConfig.d.ts +45 -0
  10. package/dist/config/dashboardConfig.js +63 -0
  11. package/dist/config/defaultValues.d.ts +61 -0
  12. package/dist/config/defaultValues.js +70 -0
  13. package/dist/config/dirConstants.d.ts +17 -0
  14. package/dist/config/dirConstants.js +28 -0
  15. package/dist/config/featureConfig.d.ts +61 -0
  16. package/dist/config/featureConfig.js +121 -0
  17. package/dist/config/runtimeConfig.d.ts +145 -0
  18. package/dist/config/runtimeConfig.js +334 -0
  19. package/dist/config/serverConfig.d.ts +90 -0
  20. package/dist/config/serverConfig.js +164 -0
  21. package/dist/dashboard/analytics/AnalyticsEngine.d.ts +142 -0
  22. package/dist/dashboard/analytics/AnalyticsEngine.js +373 -0
  23. package/dist/dashboard/analytics/BusinessIntelligence.d.ts +187 -0
  24. package/dist/dashboard/analytics/BusinessIntelligence.js +594 -0
  25. package/dist/dashboard/client/admin.html +2150 -0
  26. package/dist/dashboard/client/chunks/mermaid-layout-elk.esm.min/chunk-SP2CHFBE.mjs +1 -0
  27. package/dist/dashboard/client/chunks/mermaid-layout-elk.esm.min/render-T6MDALS3.mjs +27 -0
  28. package/dist/dashboard/client/css/admin.css +1466 -0
  29. package/dist/dashboard/client/js/admin.boot.js +359 -0
  30. package/dist/dashboard/client/js/admin.config.js +196 -0
  31. package/dist/dashboard/client/js/admin.embeddings.js +425 -0
  32. package/dist/dashboard/client/js/admin.graph.js +583 -0
  33. package/dist/dashboard/client/js/admin.instances.js +120 -0
  34. package/dist/dashboard/client/js/admin.instructions.js +552 -0
  35. package/dist/dashboard/client/js/admin.logs.js +113 -0
  36. package/dist/dashboard/client/js/admin.maintenance.js +354 -0
  37. package/dist/dashboard/client/js/admin.messaging.js +635 -0
  38. package/dist/dashboard/client/js/admin.monitor.js +181 -0
  39. package/dist/dashboard/client/js/admin.overview.js +221 -0
  40. package/dist/dashboard/client/js/admin.performance.js +61 -0
  41. package/dist/dashboard/client/js/admin.sessions.js +293 -0
  42. package/dist/dashboard/client/js/admin.sqlite.js +366 -0
  43. package/dist/dashboard/client/js/admin.utils.js +49 -0
  44. package/dist/dashboard/client/js/chart.umd.js +14 -0
  45. package/dist/dashboard/client/js/elk.bundled.js +6696 -0
  46. package/dist/dashboard/client/js/marked.umd.js +74 -0
  47. package/dist/dashboard/client/js/mermaid.min.js +3022 -0
  48. package/dist/dashboard/client/mermaid-layout-elk.esm.min.mjs +1 -0
  49. package/dist/dashboard/export/DataExporter.d.ts +169 -0
  50. package/dist/dashboard/export/DataExporter.js +737 -0
  51. package/dist/dashboard/export/exporters/csvExporter.d.ts +11 -0
  52. package/dist/dashboard/export/exporters/csvExporter.js +46 -0
  53. package/dist/dashboard/export/exporters/exportTypes.d.ts +89 -0
  54. package/dist/dashboard/export/exporters/exportTypes.js +5 -0
  55. package/dist/dashboard/export/exporters/jsonExporter.d.ts +7 -0
  56. package/dist/dashboard/export/exporters/jsonExporter.js +22 -0
  57. package/dist/dashboard/export/exporters/xmlExporter.d.ts +17 -0
  58. package/dist/dashboard/export/exporters/xmlExporter.js +175 -0
  59. package/dist/dashboard/integration/APIIntegration.d.ts +41 -0
  60. package/dist/dashboard/integration/APIIntegration.js +95 -0
  61. package/dist/dashboard/security/SecurityMonitor.d.ts +167 -0
  62. package/dist/dashboard/security/SecurityMonitor.js +559 -0
  63. package/dist/dashboard/server/AdminPanel.d.ts +183 -0
  64. package/dist/dashboard/server/AdminPanel.js +792 -0
  65. package/dist/dashboard/server/AdminPanelConfig.d.ts +42 -0
  66. package/dist/dashboard/server/AdminPanelConfig.js +80 -0
  67. package/dist/dashboard/server/AdminPanelState.d.ts +47 -0
  68. package/dist/dashboard/server/AdminPanelState.js +214 -0
  69. package/dist/dashboard/server/ApiRoutes.d.ts +17 -0
  70. package/dist/dashboard/server/ApiRoutes.js +149 -0
  71. package/dist/dashboard/server/DashboardServer.d.ts +49 -0
  72. package/dist/dashboard/server/DashboardServer.js +159 -0
  73. package/dist/dashboard/server/FileMetricsStorage.d.ts +49 -0
  74. package/dist/dashboard/server/FileMetricsStorage.js +195 -0
  75. package/dist/dashboard/server/HttpTransport.d.ts +23 -0
  76. package/dist/dashboard/server/HttpTransport.js +116 -0
  77. package/dist/dashboard/server/InstanceManager.d.ts +53 -0
  78. package/dist/dashboard/server/InstanceManager.js +284 -0
  79. package/dist/dashboard/server/KnowledgeStore.d.ts +35 -0
  80. package/dist/dashboard/server/KnowledgeStore.js +105 -0
  81. package/dist/dashboard/server/LeaderElection.d.ts +81 -0
  82. package/dist/dashboard/server/LeaderElection.js +268 -0
  83. package/dist/dashboard/server/MetricsCollector.d.ts +200 -0
  84. package/dist/dashboard/server/MetricsCollector.js +803 -0
  85. package/dist/dashboard/server/SessionPersistenceManager.d.ts +88 -0
  86. package/dist/dashboard/server/SessionPersistenceManager.js +457 -0
  87. package/dist/dashboard/server/ThinClient.d.ts +64 -0
  88. package/dist/dashboard/server/ThinClient.js +237 -0
  89. package/dist/dashboard/server/WebSocketManager.d.ts +161 -0
  90. package/dist/dashboard/server/WebSocketManager.js +463 -0
  91. package/dist/dashboard/server/httpLifecycle.d.ts +17 -0
  92. package/dist/dashboard/server/httpLifecycle.js +35 -0
  93. package/dist/dashboard/server/legacyDashboardHtml.d.ts +9 -0
  94. package/dist/dashboard/server/legacyDashboardHtml.js +618 -0
  95. package/dist/dashboard/server/legacyDashboardStyles.d.ts +5 -0
  96. package/dist/dashboard/server/legacyDashboardStyles.js +490 -0
  97. package/dist/dashboard/server/metricsAggregation.d.ts +252 -0
  98. package/dist/dashboard/server/metricsAggregation.js +206 -0
  99. package/dist/dashboard/server/metricsSerializer.d.ts +25 -0
  100. package/dist/dashboard/server/metricsSerializer.js +195 -0
  101. package/dist/dashboard/server/routes/admin.routes.d.ts +16 -0
  102. package/dist/dashboard/server/routes/admin.routes.js +596 -0
  103. package/dist/dashboard/server/routes/alerts.routes.d.ts +7 -0
  104. package/dist/dashboard/server/routes/alerts.routes.js +93 -0
  105. package/dist/dashboard/server/routes/api.feedback.routes.d.ts +73 -0
  106. package/dist/dashboard/server/routes/api.feedback.routes.js +171 -0
  107. package/dist/dashboard/server/routes/api.instructions.routes.d.ts +101 -0
  108. package/dist/dashboard/server/routes/api.instructions.routes.js +213 -0
  109. package/dist/dashboard/server/routes/api.usage.routes.d.ts +57 -0
  110. package/dist/dashboard/server/routes/api.usage.routes.js +374 -0
  111. package/dist/dashboard/server/routes/embeddings.routes.d.ts +6 -0
  112. package/dist/dashboard/server/routes/embeddings.routes.js +246 -0
  113. package/dist/dashboard/server/routes/graph.routes.d.ts +6 -0
  114. package/dist/dashboard/server/routes/graph.routes.js +280 -0
  115. package/dist/dashboard/server/routes/index.d.ts +38 -0
  116. package/dist/dashboard/server/routes/index.js +194 -0
  117. package/dist/dashboard/server/routes/instances.routes.d.ts +6 -0
  118. package/dist/dashboard/server/routes/instances.routes.js +35 -0
  119. package/dist/dashboard/server/routes/instructions.routes.d.ts +8 -0
  120. package/dist/dashboard/server/routes/instructions.routes.js +336 -0
  121. package/dist/dashboard/server/routes/knowledge.routes.d.ts +6 -0
  122. package/dist/dashboard/server/routes/knowledge.routes.js +82 -0
  123. package/dist/dashboard/server/routes/logs.routes.d.ts +6 -0
  124. package/dist/dashboard/server/routes/logs.routes.js +164 -0
  125. package/dist/dashboard/server/routes/messaging.routes.d.ts +16 -0
  126. package/dist/dashboard/server/routes/messaging.routes.js +293 -0
  127. package/dist/dashboard/server/routes/metrics.routes.d.ts +10 -0
  128. package/dist/dashboard/server/routes/metrics.routes.js +346 -0
  129. package/dist/dashboard/server/routes/scripts.routes.d.ts +9 -0
  130. package/dist/dashboard/server/routes/scripts.routes.js +84 -0
  131. package/dist/dashboard/server/routes/sqlite.routes.d.ts +9 -0
  132. package/dist/dashboard/server/routes/sqlite.routes.js +569 -0
  133. package/dist/dashboard/server/routes/status.routes.d.ts +7 -0
  134. package/dist/dashboard/server/routes/status.routes.js +183 -0
  135. package/dist/dashboard/server/routes/synthetic.routes.d.ts +7 -0
  136. package/dist/dashboard/server/routes/synthetic.routes.js +195 -0
  137. package/dist/dashboard/server/routes/tools.routes.d.ts +6 -0
  138. package/dist/dashboard/server/routes/tools.routes.js +46 -0
  139. package/dist/dashboard/server/routes/usage.routes.d.ts +6 -0
  140. package/dist/dashboard/server/routes/usage.routes.js +25 -0
  141. package/dist/dashboard/server/wsInit.d.ts +16 -0
  142. package/dist/dashboard/server/wsInit.js +35 -0
  143. package/dist/externalClientLib.d.ts +1 -0
  144. package/dist/externalClientLib.js +2 -0
  145. package/dist/minimal/index.d.ts +1 -0
  146. package/dist/minimal/index.js +140 -0
  147. package/dist/models/SessionPersistence.d.ts +115 -0
  148. package/dist/models/SessionPersistence.js +66 -0
  149. package/dist/models/instruction.d.ts +45 -0
  150. package/dist/models/instruction.js +2 -0
  151. package/dist/perf/benchmark.d.ts +1 -0
  152. package/dist/perf/benchmark.js +50 -0
  153. package/dist/portableClientWrapper.d.ts +1 -0
  154. package/dist/portableClientWrapper.js +2 -0
  155. package/dist/schemas/index.d.ts +128 -0
  156. package/dist/schemas/index.js +371 -0
  157. package/dist/scripts/runPerformanceBaseline.d.ts +1 -0
  158. package/dist/scripts/runPerformanceBaseline.js +17 -0
  159. package/dist/server/handshakeManager.d.ts +25 -0
  160. package/dist/server/handshakeManager.js +472 -0
  161. package/dist/server/index-server.d.ts +56 -0
  162. package/dist/server/index-server.js +822 -0
  163. package/dist/server/registry.d.ts +44 -0
  164. package/dist/server/registry.js +236 -0
  165. package/dist/server/sdkServer.d.ts +8 -0
  166. package/dist/server/sdkServer.js +299 -0
  167. package/dist/server/shutdownGuard.d.ts +41 -0
  168. package/dist/server/shutdownGuard.js +52 -0
  169. package/dist/server/thin-client.d.ts +22 -0
  170. package/dist/server/thin-client.js +111 -0
  171. package/dist/server/transport.d.ts +41 -0
  172. package/dist/server/transport.js +312 -0
  173. package/dist/server/transportFactory.d.ts +21 -0
  174. package/dist/server/transportFactory.js +429 -0
  175. package/dist/services/atomicFs.d.ts +22 -0
  176. package/dist/services/atomicFs.js +103 -0
  177. package/dist/services/auditLog.d.ts +38 -0
  178. package/dist/services/auditLog.js +142 -0
  179. package/dist/services/autoBackup.d.ts +14 -0
  180. package/dist/services/autoBackup.js +171 -0
  181. package/dist/services/autoSplit.d.ts +32 -0
  182. package/dist/services/autoSplit.js +113 -0
  183. package/dist/services/backupZip.d.ts +25 -0
  184. package/dist/services/backupZip.js +110 -0
  185. package/dist/services/bootstrapGating.d.ts +123 -0
  186. package/dist/services/bootstrapGating.js +221 -0
  187. package/dist/services/canonical.d.ts +23 -0
  188. package/dist/services/canonical.js +65 -0
  189. package/dist/services/categoryRules.d.ts +7 -0
  190. package/dist/services/categoryRules.js +37 -0
  191. package/dist/services/classificationService.d.ts +42 -0
  192. package/dist/services/classificationService.js +168 -0
  193. package/dist/services/embeddingService.d.ts +62 -0
  194. package/dist/services/embeddingService.js +259 -0
  195. package/dist/services/errors.d.ts +22 -0
  196. package/dist/services/errors.js +31 -0
  197. package/dist/services/featureFlags.d.ts +25 -0
  198. package/dist/services/featureFlags.js +89 -0
  199. package/dist/services/features.d.ts +13 -0
  200. package/dist/services/features.js +35 -0
  201. package/dist/services/handlers/instructions.add.d.ts +1 -0
  202. package/dist/services/handlers/instructions.add.js +496 -0
  203. package/dist/services/handlers/instructions.groom.d.ts +1 -0
  204. package/dist/services/handlers/instructions.groom.js +523 -0
  205. package/dist/services/handlers/instructions.import.d.ts +1 -0
  206. package/dist/services/handlers/instructions.import.js +173 -0
  207. package/dist/services/handlers/instructions.patch.d.ts +1 -0
  208. package/dist/services/handlers/instructions.patch.js +167 -0
  209. package/dist/services/handlers/instructions.query.d.ts +163 -0
  210. package/dist/services/handlers/instructions.query.js +522 -0
  211. package/dist/services/handlers/instructions.reload.d.ts +1 -0
  212. package/dist/services/handlers/instructions.reload.js +13 -0
  213. package/dist/services/handlers/instructions.remove.d.ts +1 -0
  214. package/dist/services/handlers/instructions.remove.js +118 -0
  215. package/dist/services/handlers/instructions.shared.d.ts +31 -0
  216. package/dist/services/handlers/instructions.shared.js +124 -0
  217. package/dist/services/handlers.activation.d.ts +1 -0
  218. package/dist/services/handlers.activation.js +203 -0
  219. package/dist/services/handlers.bootstrap.d.ts +1 -0
  220. package/dist/services/handlers.bootstrap.js +38 -0
  221. package/dist/services/handlers.dashboardConfig.d.ts +34 -0
  222. package/dist/services/handlers.dashboardConfig.js +108 -0
  223. package/dist/services/handlers.diagnostics.d.ts +1 -0
  224. package/dist/services/handlers.diagnostics.js +64 -0
  225. package/dist/services/handlers.feedback.d.ts +15 -0
  226. package/dist/services/handlers.feedback.js +378 -0
  227. package/dist/services/handlers.gates.d.ts +1 -0
  228. package/dist/services/handlers.gates.js +46 -0
  229. package/dist/services/handlers.graph.d.ts +53 -0
  230. package/dist/services/handlers.graph.js +231 -0
  231. package/dist/services/handlers.help.d.ts +1 -0
  232. package/dist/services/handlers.help.js +119 -0
  233. package/dist/services/handlers.instructionSchema.d.ts +1 -0
  234. package/dist/services/handlers.instructionSchema.js +227 -0
  235. package/dist/services/handlers.instructions.d.ts +8 -0
  236. package/dist/services/handlers.instructions.js +14 -0
  237. package/dist/services/handlers.instructionsDiagnostics.d.ts +1 -0
  238. package/dist/services/handlers.instructionsDiagnostics.js +14 -0
  239. package/dist/services/handlers.integrity.d.ts +1 -0
  240. package/dist/services/handlers.integrity.js +35 -0
  241. package/dist/services/handlers.manifest.d.ts +1 -0
  242. package/dist/services/handlers.manifest.js +24 -0
  243. package/dist/services/handlers.messaging.d.ts +12 -0
  244. package/dist/services/handlers.messaging.js +203 -0
  245. package/dist/services/handlers.metrics.d.ts +1 -0
  246. package/dist/services/handlers.metrics.js +43 -0
  247. package/dist/services/handlers.promote.d.ts +1 -0
  248. package/dist/services/handlers.promote.js +306 -0
  249. package/dist/services/handlers.prompt.d.ts +1 -0
  250. package/dist/services/handlers.prompt.js +7 -0
  251. package/dist/services/handlers.search.d.ts +69 -0
  252. package/dist/services/handlers.search.js +645 -0
  253. package/dist/services/handlers.testPrimitive.d.ts +1 -0
  254. package/dist/services/handlers.testPrimitive.js +5 -0
  255. package/dist/services/handlers.trace.d.ts +1 -0
  256. package/dist/services/handlers.trace.js +31 -0
  257. package/dist/services/handlers.usage.d.ts +1 -0
  258. package/dist/services/handlers.usage.js +11 -0
  259. package/dist/services/hotScore.d.ts +137 -0
  260. package/dist/services/hotScore.js +244 -0
  261. package/dist/services/indexContext.d.ts +117 -0
  262. package/dist/services/indexContext.js +968 -0
  263. package/dist/services/indexLoader.d.ts +44 -0
  264. package/dist/services/indexLoader.js +921 -0
  265. package/dist/services/indexRepository.d.ts +32 -0
  266. package/dist/services/indexRepository.js +71 -0
  267. package/dist/services/indexingService.d.ts +1 -0
  268. package/dist/services/indexingService.js +2 -0
  269. package/dist/services/instructions.dispatcher.d.ts +1 -0
  270. package/dist/services/instructions.dispatcher.js +231 -0
  271. package/dist/services/logPrefix.d.ts +1 -0
  272. package/dist/services/logPrefix.js +30 -0
  273. package/dist/services/logger.d.ts +52 -0
  274. package/dist/services/logger.js +268 -0
  275. package/dist/services/manifestManager.d.ts +82 -0
  276. package/dist/services/manifestManager.js +200 -0
  277. package/dist/services/messaging/agentMailbox.d.ts +60 -0
  278. package/dist/services/messaging/agentMailbox.js +353 -0
  279. package/dist/services/messaging/messagingPersistence.d.ts +20 -0
  280. package/dist/services/messaging/messagingPersistence.js +111 -0
  281. package/dist/services/messaging/messagingTypes.d.ts +150 -0
  282. package/dist/services/messaging/messagingTypes.js +66 -0
  283. package/dist/services/ownershipService.d.ts +1 -0
  284. package/dist/services/ownershipService.js +38 -0
  285. package/dist/services/performanceBaseline.d.ts +19 -0
  286. package/dist/services/performanceBaseline.js +210 -0
  287. package/dist/services/preflight.d.ts +12 -0
  288. package/dist/services/preflight.js +79 -0
  289. package/dist/services/promptReviewService.d.ts +44 -0
  290. package/dist/services/promptReviewService.js +101 -0
  291. package/dist/services/responseEnvelope.d.ts +6 -0
  292. package/dist/services/responseEnvelope.js +25 -0
  293. package/dist/services/seedBootstrap.d.ts +34 -0
  294. package/dist/services/seedBootstrap.js +427 -0
  295. package/dist/services/storage/factory.d.ts +17 -0
  296. package/dist/services/storage/factory.js +35 -0
  297. package/dist/services/storage/hashUtils.d.ts +11 -0
  298. package/dist/services/storage/hashUtils.js +35 -0
  299. package/dist/services/storage/index.d.ts +12 -0
  300. package/dist/services/storage/index.js +18 -0
  301. package/dist/services/storage/jsonFileStore.d.ts +32 -0
  302. package/dist/services/storage/jsonFileStore.js +241 -0
  303. package/dist/services/storage/migrationEngine.d.ts +35 -0
  304. package/dist/services/storage/migrationEngine.js +93 -0
  305. package/dist/services/storage/sqliteMessageStore.d.ts +53 -0
  306. package/dist/services/storage/sqliteMessageStore.js +146 -0
  307. package/dist/services/storage/sqliteSchema.d.ts +12 -0
  308. package/dist/services/storage/sqliteSchema.js +122 -0
  309. package/dist/services/storage/sqliteStore.d.ts +41 -0
  310. package/dist/services/storage/sqliteStore.js +339 -0
  311. package/dist/services/storage/sqliteUsageStore.d.ts +35 -0
  312. package/dist/services/storage/sqliteUsageStore.js +94 -0
  313. package/dist/services/storage/types.d.ts +171 -0
  314. package/dist/services/storage/types.js +12 -0
  315. package/dist/services/toolHandlers.d.ts +23 -0
  316. package/dist/services/toolHandlers.js +50 -0
  317. package/dist/services/toolRegistry.d.ts +20 -0
  318. package/dist/services/toolRegistry.js +490 -0
  319. package/dist/services/toolRegistry.zod.d.ts +10 -0
  320. package/dist/services/toolRegistry.zod.js +323 -0
  321. package/dist/services/tracing.d.ts +26 -0
  322. package/dist/services/tracing.js +260 -0
  323. package/dist/services/usageBuckets.d.ts +161 -0
  324. package/dist/services/usageBuckets.js +364 -0
  325. package/dist/services/validationService.d.ts +38 -0
  326. package/dist/services/validationService.js +125 -0
  327. package/dist/utils/BufferRing.d.ts +203 -0
  328. package/dist/utils/BufferRing.js +551 -0
  329. package/dist/utils/BufferRingExamples.d.ts +55 -0
  330. package/dist/utils/BufferRingExamples.js +188 -0
  331. package/dist/utils/envUtils.d.ts +42 -0
  332. package/dist/utils/envUtils.js +80 -0
  333. package/dist/utils/memoryMonitor.d.ts +83 -0
  334. package/dist/utils/memoryMonitor.js +275 -0
  335. package/dist/versioning/schemaVersion.d.ts +6 -0
  336. package/dist/versioning/schemaVersion.js +93 -0
  337. package/package.json +134 -0
  338. package/schemas/README.md +13 -0
  339. package/schemas/feedback-entry.schema.json +27 -0
  340. package/schemas/graph-export-v2.schema.json +60 -0
  341. package/schemas/index-server.code-schema.json +38477 -0
  342. package/schemas/instruction.schema.json +262 -0
  343. package/schemas/json-schema/SessionPersistence-persisted-admin-session.schema.json +54 -0
  344. package/schemas/json-schema/SessionPersistence-persisted-session-history-entry.schema.json +51 -0
  345. package/schemas/json-schema/SessionPersistence-persisted-web-socket-connection.schema.json +54 -0
  346. package/schemas/json-schema/SessionPersistence-session-persistence-config.schema.json +110 -0
  347. package/schemas/json-schema/SessionPersistence-session-persistence-data.schema.json +229 -0
  348. package/schemas/json-schema/SessionPersistence-session-persistence-manifest.schema.json +109 -0
  349. package/schemas/json-schema/SessionPersistence-session-persistence-metadata.schema.json +55 -0
  350. package/schemas/json-schema/instruction-audience-scope.schema.json +14 -0
  351. package/schemas/json-schema/instruction-content-type.schema.json +17 -0
  352. package/schemas/json-schema/instruction-instruction-entry.schema.json +206 -0
  353. package/schemas/json-schema/instruction-requirement-level.schema.json +16 -0
  354. package/schemas/manifest.json +78 -0
  355. package/schemas/manifest.schema.json +33 -0
  356. package/schemas/usage-batch.schema.json +16 -0
  357. package/schemas/usage-buckets.schema.json +30 -0
  358. package/schemas/usage-event.schema.json +17 -0
  359. package/scripts/copy-dashboard-assets.mjs +170 -0
  360. package/scripts/setup-hooks.cjs +28 -0
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ /**
3
+ * SQLite schema DDL for instruction storage.
4
+ *
5
+ * Uses Node.js built-in node:sqlite (DatabaseSync). No third-party packages.
6
+ * WAL mode enabled for concurrent read performance.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.PRAGMAS = exports.FTS5_DDL = exports.INSTRUCTIONS_DDL = exports.SCHEMA_VERSION = void 0;
10
+ exports.SCHEMA_VERSION = '1';
11
+ exports.INSTRUCTIONS_DDL = `
12
+ CREATE TABLE IF NOT EXISTS instructions (
13
+ id TEXT PRIMARY KEY,
14
+ title TEXT NOT NULL,
15
+ body TEXT NOT NULL,
16
+ rationale TEXT,
17
+ priority INTEGER NOT NULL DEFAULT 50,
18
+ audience TEXT NOT NULL DEFAULT 'all',
19
+ requirement TEXT NOT NULL DEFAULT 'recommended',
20
+ categories TEXT NOT NULL DEFAULT '[]',
21
+ content_type TEXT NOT NULL DEFAULT 'instruction',
22
+ primary_category TEXT,
23
+ source_hash TEXT NOT NULL DEFAULT '',
24
+ schema_version TEXT NOT NULL DEFAULT '4',
25
+ deprecated_by TEXT,
26
+ created_at TEXT NOT NULL,
27
+ updated_at TEXT NOT NULL,
28
+ version TEXT DEFAULT '1.0.0',
29
+ status TEXT DEFAULT 'approved',
30
+ owner TEXT,
31
+ priority_tier TEXT,
32
+ classification TEXT DEFAULT 'public',
33
+ last_reviewed_at TEXT,
34
+ next_review_due TEXT,
35
+ review_interval_days INTEGER,
36
+ change_log TEXT DEFAULT '[]',
37
+ supersedes TEXT,
38
+ archived_at TEXT,
39
+ workspace_id TEXT,
40
+ user_id TEXT,
41
+ team_ids TEXT DEFAULT '[]',
42
+ semantic_summary TEXT,
43
+ created_by_agent TEXT,
44
+ source_workspace TEXT,
45
+ risk_score REAL,
46
+ usage_count INTEGER DEFAULT 0,
47
+ first_seen_ts TEXT,
48
+ last_used_at TEXT
49
+ );
50
+
51
+ CREATE INDEX IF NOT EXISTS idx_instructions_content_type ON instructions(content_type);
52
+ CREATE INDEX IF NOT EXISTS idx_instructions_status ON instructions(status);
53
+ CREATE INDEX IF NOT EXISTS idx_instructions_priority ON instructions(priority);
54
+ CREATE INDEX IF NOT EXISTS idx_instructions_priority_tier ON instructions(priority_tier);
55
+ CREATE INDEX IF NOT EXISTS idx_instructions_audience ON instructions(audience);
56
+
57
+ CREATE TABLE IF NOT EXISTS usage (
58
+ instruction_id TEXT PRIMARY KEY,
59
+ usage_count INTEGER DEFAULT 0,
60
+ first_seen_ts TEXT,
61
+ last_used_at TEXT,
62
+ last_action TEXT,
63
+ last_signal TEXT,
64
+ last_comment TEXT
65
+ );
66
+
67
+ CREATE TABLE IF NOT EXISTS messages (
68
+ id TEXT PRIMARY KEY,
69
+ channel TEXT NOT NULL,
70
+ sender TEXT NOT NULL,
71
+ recipients TEXT NOT NULL DEFAULT '[]',
72
+ body TEXT NOT NULL,
73
+ priority TEXT DEFAULT 'normal',
74
+ tags TEXT DEFAULT '[]',
75
+ parent_id TEXT,
76
+ persistent INTEGER DEFAULT 0,
77
+ ttl_seconds INTEGER,
78
+ requires_ack INTEGER DEFAULT 0,
79
+ ack_by_seconds INTEGER,
80
+ read_by TEXT DEFAULT '[]',
81
+ payload TEXT,
82
+ created_at TEXT NOT NULL,
83
+ updated_at TEXT NOT NULL
84
+ );
85
+
86
+ CREATE INDEX IF NOT EXISTS idx_messages_channel ON messages(channel);
87
+ CREATE INDEX IF NOT EXISTS idx_messages_sender ON messages(sender);
88
+ CREATE INDEX IF NOT EXISTS idx_messages_parent_id ON messages(parent_id);
89
+ CREATE INDEX IF NOT EXISTS idx_messages_created_at ON messages(created_at);
90
+
91
+ CREATE TABLE IF NOT EXISTS metadata (
92
+ key TEXT PRIMARY KEY,
93
+ value TEXT
94
+ );
95
+ `;
96
+ /** FTS5 virtual table for full-text search. Created separately since it needs content sync. */
97
+ exports.FTS5_DDL = `
98
+ CREATE VIRTUAL TABLE IF NOT EXISTS instructions_fts USING fts5(
99
+ id, title, body, categories,
100
+ content='instructions',
101
+ content_rowid='rowid'
102
+ );
103
+
104
+ -- Triggers to keep FTS5 in sync with instructions table
105
+ CREATE TRIGGER IF NOT EXISTS instructions_ai AFTER INSERT ON instructions BEGIN
106
+ INSERT INTO instructions_fts(rowid, id, title, body, categories) VALUES (new.rowid, new.id, new.title, new.body, new.categories);
107
+ END;
108
+ CREATE TRIGGER IF NOT EXISTS instructions_ad AFTER DELETE ON instructions BEGIN
109
+ INSERT INTO instructions_fts(instructions_fts, rowid, id, title, body, categories) VALUES('delete', old.rowid, old.id, old.title, old.body, old.categories);
110
+ END;
111
+ CREATE TRIGGER IF NOT EXISTS instructions_au AFTER UPDATE ON instructions BEGIN
112
+ INSERT INTO instructions_fts(instructions_fts, rowid, id, title, body, categories) VALUES('delete', old.rowid, old.id, old.title, old.body, old.categories);
113
+ INSERT INTO instructions_fts(rowid, id, title, body, categories) VALUES (new.rowid, new.id, new.title, new.body, new.categories);
114
+ END;
115
+ `;
116
+ /** Enable WAL mode and recommended pragmas. */
117
+ exports.PRAGMAS = `
118
+ PRAGMA journal_mode=WAL;
119
+ PRAGMA busy_timeout=5000;
120
+ PRAGMA synchronous=NORMAL;
121
+ PRAGMA foreign_keys=ON;
122
+ `;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * SqliteStore — SQLite storage backend using Node.js built-in node:sqlite.
3
+ *
4
+ * ⚠️ EXPERIMENTAL — LIMITED TESTING PERFORMED.
5
+ * This backend is behind the INDEX_SERVER_STORAGE_BACKEND=sqlite feature flag
6
+ * and should NOT be used in production without thorough validation.
7
+ * Data loss, migration issues, or compatibility problems may occur.
8
+ *
9
+ * Uses DatabaseSync (synchronous API) — zero third-party dependencies.
10
+ * Requires Node.js >= 22.5.0.
11
+ *
12
+ * Implements IInstructionStore for the storage abstraction layer.
13
+ */
14
+ import { InstructionEntry } from '../../models/instruction.js';
15
+ import type { IInstructionStore, ListOptions, QueryOptions, ScopedListOptions, SearchOptions, SearchResult, LoadResult } from './types.js';
16
+ export declare class SqliteStore implements IInstructionStore {
17
+ private db;
18
+ private loaded;
19
+ private cache;
20
+ constructor(dbPath: string);
21
+ private initSchema;
22
+ load(): LoadResult;
23
+ close(): void;
24
+ get(id: string): InstructionEntry | null;
25
+ write(entry: InstructionEntry): void;
26
+ remove(id: string): void;
27
+ list(opts?: ListOptions): InstructionEntry[];
28
+ query(opts: QueryOptions): InstructionEntry[];
29
+ listScoped(opts: ScopedListOptions): InstructionEntry[];
30
+ search(opts: SearchOptions): SearchResult[];
31
+ categories(): Map<string, number>;
32
+ /**
33
+ * Full-text search using FTS5 with BM25 ranking.
34
+ * More efficient than in-memory scan for large instruction sets.
35
+ * Falls back to in-memory search if FTS5 is unavailable.
36
+ */
37
+ searchFts(opts: SearchOptions): SearchResult[];
38
+ computeHash(): string;
39
+ count(): number;
40
+ private ensureLoaded;
41
+ }
@@ -0,0 +1,339 @@
1
+ "use strict";
2
+ /**
3
+ * SqliteStore — SQLite storage backend using Node.js built-in node:sqlite.
4
+ *
5
+ * ⚠️ EXPERIMENTAL — LIMITED TESTING PERFORMED.
6
+ * This backend is behind the INDEX_SERVER_STORAGE_BACKEND=sqlite feature flag
7
+ * and should NOT be used in production without thorough validation.
8
+ * Data loss, migration issues, or compatibility problems may occur.
9
+ *
10
+ * Uses DatabaseSync (synchronous API) — zero third-party dependencies.
11
+ * Requires Node.js >= 22.5.0.
12
+ *
13
+ * Implements IInstructionStore for the storage abstraction layer.
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.SqliteStore = void 0;
17
+ const node_sqlite_1 = require("node:sqlite");
18
+ const hashUtils_js_1 = require("./hashUtils.js");
19
+ const sqliteSchema_js_1 = require("./sqliteSchema.js");
20
+ // ── Column Mapping ───────────────────────────────────────────────────────────
21
+ /** Map DB row (snake_case) to InstructionEntry (camelCase). */
22
+ function rowToEntry(row) {
23
+ return {
24
+ id: row.id,
25
+ title: row.title,
26
+ body: row.body,
27
+ rationale: row.rationale,
28
+ priority: row.priority,
29
+ audience: row.audience,
30
+ requirement: row.requirement,
31
+ categories: safeJsonParse(row.categories, []),
32
+ contentType: row.content_type ?? 'instruction',
33
+ primaryCategory: row.primary_category,
34
+ sourceHash: row.source_hash,
35
+ schemaVersion: row.schema_version,
36
+ deprecatedBy: row.deprecated_by,
37
+ createdAt: row.created_at,
38
+ updatedAt: row.updated_at,
39
+ version: row.version,
40
+ status: row.status,
41
+ owner: row.owner,
42
+ priorityTier: row.priority_tier,
43
+ classification: row.classification,
44
+ lastReviewedAt: row.last_reviewed_at,
45
+ nextReviewDue: row.next_review_due,
46
+ reviewIntervalDays: row.review_interval_days,
47
+ changeLog: safeJsonParse(row.change_log, undefined),
48
+ supersedes: row.supersedes,
49
+ archivedAt: row.archived_at,
50
+ workspaceId: row.workspace_id,
51
+ userId: row.user_id,
52
+ teamIds: safeJsonParse(row.team_ids, undefined),
53
+ semanticSummary: row.semantic_summary,
54
+ createdByAgent: row.created_by_agent,
55
+ sourceWorkspace: row.source_workspace,
56
+ riskScore: row.risk_score,
57
+ usageCount: row.usage_count,
58
+ firstSeenTs: row.first_seen_ts,
59
+ lastUsedAt: row.last_used_at,
60
+ };
61
+ }
62
+ /** Safely parse a JSON string, returning fallback on failure. */
63
+ function safeJsonParse(raw, fallback) {
64
+ if (raw == null)
65
+ return fallback;
66
+ try {
67
+ return JSON.parse(raw);
68
+ }
69
+ catch {
70
+ return fallback;
71
+ }
72
+ }
73
+ /** Strip undefined values from entry to avoid SQLite binding issues. */
74
+ function val(v) {
75
+ return v === undefined ? null : v;
76
+ }
77
+ // ── SqliteStore ──────────────────────────────────────────────────────────────
78
+ class SqliteStore {
79
+ db;
80
+ loaded = false;
81
+ cache = new Map();
82
+ constructor(dbPath) {
83
+ this.db = new node_sqlite_1.DatabaseSync(dbPath);
84
+ this.initSchema();
85
+ }
86
+ initSchema() {
87
+ this.db.exec(sqliteSchema_js_1.PRAGMAS);
88
+ this.db.exec(sqliteSchema_js_1.INSTRUCTIONS_DDL);
89
+ // FTS5 for full-text search (with content sync triggers)
90
+ try {
91
+ this.db.exec(sqliteSchema_js_1.FTS5_DDL);
92
+ }
93
+ catch { /* FTS5 may already exist */ }
94
+ // Stamp schema version if not present
95
+ const meta = this.db.prepare('SELECT value FROM metadata WHERE key = ?').get('schema_version');
96
+ if (!meta) {
97
+ this.db.prepare('INSERT INTO metadata (key, value) VALUES (?, ?)').run('schema_version', sqliteSchema_js_1.SCHEMA_VERSION);
98
+ }
99
+ }
100
+ // ── Lifecycle ──────────────────────────────────────────────────────
101
+ load() {
102
+ const rows = this.db.prepare('SELECT * FROM instructions').all();
103
+ const entries = [];
104
+ const errors = [];
105
+ for (const row of rows) {
106
+ try {
107
+ entries.push(rowToEntry(row));
108
+ }
109
+ catch (err) {
110
+ errors.push({
111
+ file: row.id ?? 'unknown',
112
+ error: err instanceof Error ? err.message : 'Row parse error',
113
+ });
114
+ }
115
+ }
116
+ this.cache.clear();
117
+ for (const e of entries) {
118
+ this.cache.set(e.id, e);
119
+ }
120
+ this.loaded = true;
121
+ return {
122
+ entries,
123
+ hash: (0, hashUtils_js_1.computeGovernanceHashFromEntries)(entries),
124
+ errors,
125
+ debug: { scanned: rows.length, accepted: entries.length, skipped: errors.length },
126
+ summary: {
127
+ scanned: rows.length,
128
+ accepted: entries.length,
129
+ skipped: errors.length,
130
+ reasons: errors.length > 0 ? { 'row-parse-error': errors.length } : {},
131
+ },
132
+ };
133
+ }
134
+ close() {
135
+ this.cache.clear();
136
+ this.loaded = false;
137
+ this.db.close();
138
+ }
139
+ // ── CRUD ───────────────────────────────────────────────────────────
140
+ get(id) {
141
+ this.ensureLoaded();
142
+ return this.cache.get(id) ?? null;
143
+ }
144
+ write(entry) {
145
+ const sql = `INSERT OR REPLACE INTO instructions (
146
+ id, title, body, rationale, priority, audience, requirement,
147
+ categories, content_type, primary_category, source_hash,
148
+ schema_version, deprecated_by, created_at, updated_at,
149
+ version, status, owner, priority_tier, classification,
150
+ last_reviewed_at, next_review_due, review_interval_days,
151
+ change_log, supersedes, archived_at, workspace_id, user_id,
152
+ team_ids, semantic_summary, created_by_agent, source_workspace,
153
+ risk_score, usage_count, first_seen_ts, last_used_at
154
+ ) VALUES (
155
+ ?, ?, ?, ?, ?, ?, ?,
156
+ ?, ?, ?, ?,
157
+ ?, ?, ?, ?,
158
+ ?, ?, ?, ?, ?,
159
+ ?, ?, ?,
160
+ ?, ?, ?, ?, ?,
161
+ ?, ?, ?, ?,
162
+ ?, ?, ?, ?
163
+ )`;
164
+ this.db.prepare(sql).run(entry.id, entry.title, entry.body, val(entry.rationale), val(entry.priority) ?? 0, val(entry.audience) ?? 'all', val(entry.requirement) ?? 'may', JSON.stringify(entry.categories ?? []), val(entry.contentType) ?? 'instruction', val(entry.primaryCategory), entry.sourceHash ?? '', entry.schemaVersion ?? '4', val(entry.deprecatedBy), val(entry.createdAt) ?? new Date().toISOString(), val(entry.updatedAt) ?? new Date().toISOString(), val(entry.version), val(entry.status), val(entry.owner), val(entry.priorityTier), val(entry.classification), val(entry.lastReviewedAt), val(entry.nextReviewDue), val(entry.reviewIntervalDays), JSON.stringify(entry.changeLog ?? []), val(entry.supersedes), val(entry.archivedAt), val(entry.workspaceId), val(entry.userId), JSON.stringify(entry.teamIds ?? []), val(entry.semanticSummary), val(entry.createdByAgent), val(entry.sourceWorkspace), val(entry.riskScore), val(entry.usageCount) ?? 0, val(entry.firstSeenTs), val(entry.lastUsedAt));
165
+ // Update in-memory cache
166
+ this.cache.set(entry.id, entry);
167
+ this.loaded = true;
168
+ }
169
+ remove(id) {
170
+ this.db.prepare('DELETE FROM instructions WHERE id = ?').run(id);
171
+ this.cache.delete(id);
172
+ }
173
+ // ── Queries ────────────────────────────────────────────────────────
174
+ list(opts) {
175
+ this.ensureLoaded();
176
+ let result = Array.from(this.cache.values());
177
+ if (opts?.category) {
178
+ result = result.filter(e => e.categories?.includes(opts.category));
179
+ }
180
+ if (opts?.contentType) {
181
+ result = result.filter(e => e.contentType === opts.contentType);
182
+ }
183
+ return result;
184
+ }
185
+ query(opts) {
186
+ this.ensureLoaded();
187
+ let result = Array.from(this.cache.values());
188
+ if (opts.text) {
189
+ const lower = opts.text.toLowerCase();
190
+ result = result.filter(e => e.title.toLowerCase().includes(lower) ||
191
+ e.body.toLowerCase().includes(lower) ||
192
+ (e.semanticSummary && e.semanticSummary.toLowerCase().includes(lower)));
193
+ }
194
+ if (opts.categoriesAny?.length) {
195
+ const set = new Set(opts.categoriesAny);
196
+ result = result.filter(e => e.categories?.some(c => set.has(c)));
197
+ }
198
+ if (opts.categoriesAll?.length) {
199
+ result = result.filter(e => opts.categoriesAll.every(c => e.categories?.includes(c)));
200
+ }
201
+ if (opts.excludeCategories?.length) {
202
+ const excl = new Set(opts.excludeCategories);
203
+ result = result.filter(e => !e.categories?.some(c => excl.has(c)));
204
+ }
205
+ if (opts.contentType) {
206
+ result = result.filter(e => e.contentType === opts.contentType);
207
+ }
208
+ if (opts.priorityMin !== undefined) {
209
+ result = result.filter(e => e.priority >= opts.priorityMin);
210
+ }
211
+ if (opts.priorityMax !== undefined) {
212
+ result = result.filter(e => e.priority <= opts.priorityMax);
213
+ }
214
+ if (opts.priorityTiers?.length) {
215
+ const tiers = new Set(opts.priorityTiers);
216
+ result = result.filter(e => e.priorityTier && tiers.has(e.priorityTier));
217
+ }
218
+ if (opts.requirements?.length) {
219
+ const reqs = new Set(opts.requirements);
220
+ result = result.filter(e => reqs.has(e.requirement));
221
+ }
222
+ if (opts.offset) {
223
+ result = result.slice(opts.offset);
224
+ }
225
+ if (opts.limit) {
226
+ result = result.slice(0, opts.limit);
227
+ }
228
+ return result;
229
+ }
230
+ listScoped(opts) {
231
+ this.ensureLoaded();
232
+ let result = Array.from(this.cache.values());
233
+ if (opts.userId) {
234
+ result = result.filter(e => e.userId === opts.userId || e.audience === 'all');
235
+ }
236
+ if (opts.workspaceId) {
237
+ result = result.filter(e => e.workspaceId === opts.workspaceId || e.audience === 'all');
238
+ }
239
+ if (opts.teamIds?.length) {
240
+ const teams = new Set(opts.teamIds);
241
+ result = result.filter(e => e.audience === 'all' ||
242
+ e.teamIds?.some(t => teams.has(t)));
243
+ }
244
+ return result;
245
+ }
246
+ search(opts) {
247
+ this.ensureLoaded();
248
+ const results = [];
249
+ for (const entry of this.cache.values()) {
250
+ let score = 0;
251
+ const titleLower = entry.title.toLowerCase();
252
+ const bodyLower = entry.body.toLowerCase();
253
+ const catStr = (entry.categories ?? []).join(' ').toLowerCase();
254
+ for (const kw of opts.keywords) {
255
+ const kwLower = opts.caseSensitive ? kw : kw.toLowerCase();
256
+ const title = opts.caseSensitive ? entry.title : titleLower;
257
+ const body = opts.caseSensitive ? entry.body : bodyLower;
258
+ if (title.includes(kwLower))
259
+ score += 3;
260
+ if (body.includes(kwLower))
261
+ score += 1;
262
+ if (opts.includeCategories && catStr.includes(kwLower))
263
+ score += 2;
264
+ }
265
+ if (score > 0) {
266
+ results.push({ id: entry.id, score });
267
+ }
268
+ }
269
+ results.sort((a, b) => b.score - a.score);
270
+ if (opts.limit) {
271
+ return results.slice(0, opts.limit);
272
+ }
273
+ return results;
274
+ }
275
+ categories() {
276
+ this.ensureLoaded();
277
+ const counts = new Map();
278
+ for (const entry of this.cache.values()) {
279
+ for (const cat of entry.categories ?? []) {
280
+ counts.set(cat, (counts.get(cat) ?? 0) + 1);
281
+ }
282
+ }
283
+ return counts;
284
+ }
285
+ // ── FTS5 Search ────────────────────────────────────────────────────
286
+ /**
287
+ * Full-text search using FTS5 with BM25 ranking.
288
+ * More efficient than in-memory scan for large instruction sets.
289
+ * Falls back to in-memory search if FTS5 is unavailable.
290
+ */
291
+ searchFts(opts) {
292
+ this.ensureLoaded();
293
+ try {
294
+ // Build FTS5 MATCH query: OR all keywords
295
+ const matchTerms = opts.keywords
296
+ .map(kw => `"${kw.replace(/"/g, '""')}"`)
297
+ .join(' OR ');
298
+ const sql = `
299
+ SELECT id, bm25(instructions_fts, 0, 10.0, 5.0, 1.0) as rank
300
+ FROM instructions_fts
301
+ WHERE instructions_fts MATCH ?
302
+ ORDER BY rank
303
+ ${opts.limit ? 'LIMIT ?' : ''}
304
+ `;
305
+ const params = [matchTerms];
306
+ if (opts.limit)
307
+ params.push(opts.limit);
308
+ const rows = this.db.prepare(sql).all(...params);
309
+ return rows.map(row => {
310
+ const r = row;
311
+ return {
312
+ id: r.id,
313
+ // BM25 returns negative scores (lower = better), negate for positive ranking
314
+ score: -r.rank,
315
+ };
316
+ });
317
+ }
318
+ catch {
319
+ // FTS5 unavailable — fall back to in-memory search
320
+ return this.search(opts);
321
+ }
322
+ }
323
+ // ── Integrity ──────────────────────────────────────────────────────
324
+ computeHash() {
325
+ this.ensureLoaded();
326
+ return (0, hashUtils_js_1.computeGovernanceHashFromEntries)(Array.from(this.cache.values()));
327
+ }
328
+ count() {
329
+ this.ensureLoaded();
330
+ return this.cache.size;
331
+ }
332
+ // ── Internal ───────────────────────────────────────────────────────
333
+ ensureLoaded() {
334
+ if (!this.loaded) {
335
+ this.load();
336
+ }
337
+ }
338
+ }
339
+ exports.SqliteStore = SqliteStore;
@@ -0,0 +1,35 @@
1
+ /**
2
+ * SqliteUsageStore — Usage tracking backed by node:sqlite.
3
+ *
4
+ * Stores instruction usage counts, timestamps, and signals in the
5
+ * usage table. Provides atomic increment and bulk snapshot operations.
6
+ */
7
+ export interface UsageRecord {
8
+ instructionId: string;
9
+ usageCount: number;
10
+ firstSeenTs: string | null;
11
+ lastUsedAt: string | null;
12
+ lastAction: string | null;
13
+ lastSignal: string | null;
14
+ lastComment: string | null;
15
+ }
16
+ export interface TrackOptions {
17
+ action?: string;
18
+ signal?: string;
19
+ comment?: string;
20
+ }
21
+ export declare class SqliteUsageStore {
22
+ private db;
23
+ constructor(dbPath: string);
24
+ /** Get usage record for an instruction. */
25
+ get(instructionId: string): UsageRecord | null;
26
+ /** Increment usage count and update timestamps/signals. */
27
+ increment(instructionId: string, opts?: TrackOptions): UsageRecord;
28
+ /** Get all usage records as a snapshot. */
29
+ snapshot(): Record<string, UsageRecord>;
30
+ /** Reset usage for a specific instruction or all. */
31
+ flush(instructionId?: string): void;
32
+ /** Count of tracked instructions. */
33
+ count(): number;
34
+ close(): void;
35
+ }
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ /**
3
+ * SqliteUsageStore — Usage tracking backed by node:sqlite.
4
+ *
5
+ * Stores instruction usage counts, timestamps, and signals in the
6
+ * usage table. Provides atomic increment and bulk snapshot operations.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.SqliteUsageStore = void 0;
10
+ const node_sqlite_1 = require("node:sqlite");
11
+ const sqliteSchema_js_1 = require("./sqliteSchema.js");
12
+ class SqliteUsageStore {
13
+ db;
14
+ constructor(dbPath) {
15
+ this.db = new node_sqlite_1.DatabaseSync(dbPath);
16
+ this.db.exec(sqliteSchema_js_1.PRAGMAS);
17
+ this.db.exec(sqliteSchema_js_1.INSTRUCTIONS_DDL);
18
+ }
19
+ /** Get usage record for an instruction. */
20
+ get(instructionId) {
21
+ const row = this.db.prepare('SELECT * FROM usage WHERE instruction_id = ?').get(instructionId);
22
+ if (!row)
23
+ return null;
24
+ return {
25
+ instructionId: row.instruction_id,
26
+ usageCount: row.usage_count ?? 0,
27
+ firstSeenTs: row.first_seen_ts,
28
+ lastUsedAt: row.last_used_at,
29
+ lastAction: row.last_action,
30
+ lastSignal: row.last_signal,
31
+ lastComment: row.last_comment,
32
+ };
33
+ }
34
+ /** Increment usage count and update timestamps/signals. */
35
+ increment(instructionId, opts) {
36
+ const now = new Date().toISOString();
37
+ const existing = this.get(instructionId);
38
+ if (existing) {
39
+ this.db.prepare(`
40
+ UPDATE usage SET
41
+ usage_count = usage_count + 1,
42
+ last_used_at = ?,
43
+ last_action = COALESCE(?, last_action),
44
+ last_signal = COALESCE(?, last_signal),
45
+ last_comment = COALESCE(?, last_comment)
46
+ WHERE instruction_id = ?
47
+ `).run(now, opts?.action ?? null, opts?.signal ?? null, opts?.comment ?? null, instructionId);
48
+ }
49
+ else {
50
+ this.db.prepare(`
51
+ INSERT INTO usage (instruction_id, usage_count, first_seen_ts, last_used_at, last_action, last_signal, last_comment)
52
+ VALUES (?, 1, ?, ?, ?, ?, ?)
53
+ `).run(instructionId, now, now, opts?.action ?? null, opts?.signal ?? null, opts?.comment ?? null);
54
+ }
55
+ return this.get(instructionId);
56
+ }
57
+ /** Get all usage records as a snapshot. */
58
+ snapshot() {
59
+ const rows = this.db.prepare('SELECT * FROM usage').all();
60
+ const result = {};
61
+ for (const row of rows) {
62
+ const r = row;
63
+ const id = r.instruction_id;
64
+ result[id] = {
65
+ instructionId: id,
66
+ usageCount: r.usage_count ?? 0,
67
+ firstSeenTs: r.first_seen_ts,
68
+ lastUsedAt: r.last_used_at,
69
+ lastAction: r.last_action,
70
+ lastSignal: r.last_signal,
71
+ lastComment: r.last_comment,
72
+ };
73
+ }
74
+ return result;
75
+ }
76
+ /** Reset usage for a specific instruction or all. */
77
+ flush(instructionId) {
78
+ if (instructionId) {
79
+ this.db.prepare('DELETE FROM usage WHERE instruction_id = ?').run(instructionId);
80
+ }
81
+ else {
82
+ this.db.exec('DELETE FROM usage');
83
+ }
84
+ }
85
+ /** Count of tracked instructions. */
86
+ count() {
87
+ const row = this.db.prepare('SELECT COUNT(*) as cnt FROM usage').get();
88
+ return row?.cnt ?? 0;
89
+ }
90
+ close() {
91
+ this.db.close();
92
+ }
93
+ }
94
+ exports.SqliteUsageStore = SqliteUsageStore;