@johpaz/hive-sdk 0.1.3 → 0.1.5

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 (272) hide show
  1. package/CHANGELOG.md +97 -0
  2. package/README.md +78 -23
  3. package/bunfig.toml +4 -2
  4. package/docs/API-AGENTS.md +78 -27
  5. package/docs/API-CONTEXT-COMPILER.md +31 -34
  6. package/docs/API-TOOLS-SKILLS-CHANNELS.md +58 -22
  7. package/docs/HIVE-HARNESS.md +1 -1
  8. package/docs/INDEX.md +4 -4
  9. package/docs/TEMPLATE-HIVE-APP.md +10 -10
  10. package/package.json +9 -4
  11. package/packages/cli/package.json +2 -2
  12. package/packages/cli/src/commands/create-app.test.ts +36 -7
  13. package/packages/cli/src/commands/init.ts +3 -3
  14. package/packages/cli/src/commands/run.ts +1 -1
  15. package/packages/cli/src/commands/test.ts +37 -25
  16. package/packages/cli/src/commands/trace.ts +30 -28
  17. package/packages/cli/templates/hive-app/.env.example +10 -2
  18. package/packages/cli/templates/hive-app/README.md +103 -0
  19. package/packages/cli/templates/hive-app/hive.config.ts +9 -3
  20. package/packages/cli/templates/hive-app/src/agents/coordinator.ts +8 -1
  21. package/packages/cli/templates/hive-app/src/main.ts +12 -19
  22. package/packages/core/package.json +5 -4
  23. package/packages/core/src/agent/acceptance-checks.ts +166 -0
  24. package/packages/core/src/agent/agent-catalog.ts +348 -0
  25. package/packages/core/src/agent/agent-loop.ts +1373 -0
  26. package/packages/core/src/agent/capability-search.ts +186 -0
  27. package/packages/core/src/agent/catalog-selector.ts +103 -0
  28. package/packages/core/src/agent/{Compaction.ts → compaction.ts} +86 -63
  29. package/packages/core/src/agent/context-compiler.ts +689 -0
  30. package/packages/core/src/agent/conversation-store.ts +381 -0
  31. package/packages/core/src/agent/curator.ts +276 -0
  32. package/packages/core/src/agent/delegation-runtime.ts +241 -0
  33. package/packages/core/src/agent/goal-runner.ts +323 -0
  34. package/packages/core/src/agent/index.ts +17 -12
  35. package/packages/core/src/agent/llm-client.ts +266 -0
  36. package/packages/core/src/agent/llm-providers/anthropic.ts +264 -0
  37. package/packages/core/src/agent/llm-providers/deepseek.ts +8 -0
  38. package/packages/core/src/agent/{providers → llm-providers}/gemini.ts +98 -60
  39. package/packages/core/src/agent/llm-providers/groq.ts +5 -0
  40. package/packages/core/src/agent/llm-providers/hiveagents.ts +253 -0
  41. package/packages/core/src/agent/{providers → llm-providers}/interface.ts +73 -13
  42. package/packages/core/src/agent/llm-providers/kimi.ts +8 -0
  43. package/packages/core/src/agent/llm-providers/minimax.ts +13 -0
  44. package/packages/core/src/agent/llm-providers/mistral.ts +5 -0
  45. package/packages/core/src/agent/llm-providers/modelscope.ts +5 -0
  46. package/packages/core/src/agent/llm-providers/nvidia.ts +5 -0
  47. package/packages/core/src/agent/{providers → llm-providers}/ollama.ts +31 -5
  48. package/packages/core/src/agent/llm-providers/openai-compat-base.ts +418 -0
  49. package/packages/core/src/agent/llm-providers/openai.ts +5 -0
  50. package/packages/core/src/agent/llm-providers/opencode-go.ts +9 -0
  51. package/packages/core/src/agent/llm-providers/openrouter.ts +5 -0
  52. package/packages/core/src/agent/llm-providers/qwen.ts +5 -0
  53. package/packages/core/src/agent/llm-providers/z-ai.ts +5 -0
  54. package/packages/core/src/agent/minimal-loadout.ts +47 -0
  55. package/packages/core/src/agent/playbook-selector.ts +119 -0
  56. package/packages/core/src/agent/{PromptBuilder.ts → prompt-builder.ts} +21 -22
  57. package/packages/core/src/{harness → agent}/proof-packet.ts +16 -21
  58. package/packages/core/src/agent/providers/index.ts +35 -16
  59. package/packages/core/src/agent/reflector.ts +320 -0
  60. package/packages/core/src/agent/routing-intent.ts +22 -0
  61. package/packages/core/src/{harness → agent}/run-epoch.ts +4 -3
  62. package/packages/core/src/{harness → agent}/run-store.ts +142 -81
  63. package/packages/core/src/agent/{Service.ts → service.ts} +37 -26
  64. package/packages/core/src/agent/skill-selector.ts +374 -0
  65. package/packages/core/src/agent/stuck-loop.ts +209 -0
  66. package/packages/core/src/agent/{selectors/ToolSelector.ts → tool-selector.ts} +188 -178
  67. package/packages/core/src/{ace/Tracer.ts → agent/tracer.ts} +37 -27
  68. package/packages/core/src/api/createAgent.test.ts +139 -27
  69. package/packages/core/src/api/createAgent.ts +232 -44
  70. package/packages/core/src/artifacts/store.ts +162 -0
  71. package/packages/core/src/canvas/canvas-manager.ts +161 -0
  72. package/packages/core/src/canvas/canvas.test.ts +8 -4
  73. package/packages/core/src/canvas/emitter.ts +131 -80
  74. package/packages/core/src/canvas/index.ts +1 -3
  75. package/packages/core/src/channels/base.ts +9 -1
  76. package/packages/core/src/channels/discord.ts +5 -4
  77. package/packages/core/src/channels/manager.ts +122 -30
  78. package/packages/core/src/channels/slack.ts +5 -4
  79. package/packages/core/src/channels/telegram.ts +36 -6
  80. package/packages/core/src/channels/webchat.ts +11 -10
  81. package/packages/core/src/channels/whatsapp.ts +23 -7
  82. package/packages/core/src/config/index.ts +13 -2
  83. package/packages/core/src/config/loader.ts +71 -29
  84. package/packages/core/src/ethics/EthicsGuard.test.ts +90 -36
  85. package/packages/core/src/ethics/EthicsGuard.ts +51 -47
  86. package/packages/core/src/events/agent-bus.ts +44 -68
  87. package/packages/core/src/events/channel-narration.ts +150 -0
  88. package/packages/core/src/events/narration.ts +82 -0
  89. package/packages/core/src/events/tool-narration.ts +62 -0
  90. package/packages/core/src/gateway/delegation-groups.ts +258 -0
  91. package/packages/core/src/{harness → gateway}/durable-queue.ts +102 -42
  92. package/packages/core/src/{harness → gateway}/job-store.ts +85 -48
  93. package/packages/core/src/gateway/lane-queue.ts +173 -0
  94. package/packages/core/src/gateway/notification-inbox.ts +57 -0
  95. package/packages/core/src/gateway/server.ts +1 -1
  96. package/packages/core/src/harness/index.ts +46 -27
  97. package/packages/core/src/index.ts +33 -20
  98. package/packages/core/src/mcp/hot-reload.ts +32 -23
  99. package/packages/core/src/mcp/index.ts +6 -3
  100. package/packages/core/src/mcp/singleton.ts +1 -4
  101. package/packages/core/src/mcp/tool-sync.ts +138 -0
  102. package/packages/core/src/memory/Scratchpad.test.ts +39 -20
  103. package/packages/core/src/memory/Scratchpad.ts +27 -34
  104. package/packages/core/src/multimodal/vision-service.ts +44 -38
  105. package/packages/core/src/resilience/retry.ts +95 -0
  106. package/packages/core/src/scheduler/CronScheduler.ts +334 -287
  107. package/packages/core/src/scheduler/index.ts +9 -7
  108. package/packages/core/src/scheduler/integration.ts +46 -26
  109. package/packages/core/src/scheduler/scheduler.test.ts +9 -13
  110. package/packages/core/src/scheduler/types.ts +7 -2
  111. package/packages/core/src/security/Pairing.ts +1 -1
  112. package/packages/core/src/skills/bundled/a2ui/a2ui_dashboard/SKILL.md +176 -0
  113. package/packages/core/src/skills/bundled/a2ui/a2ui_form/SKILL.md +202 -0
  114. package/packages/core/src/skills/bundled/a2ui/a2ui_interactive/SKILL.md +206 -0
  115. package/packages/core/src/skills/bundled/agents/agent_spawner/SKILL.md +173 -0
  116. package/packages/core/src/skills/bundled/agents/memory_manager/SKILL.md +143 -0
  117. package/packages/core/src/skills/bundled/agents/research_and_remember/SKILL.md +139 -0
  118. package/packages/core/src/skills/bundled/agents/task_orchestrator/SKILL.md +98 -0
  119. package/packages/core/src/skills/bundled/api/api_client/SKILL.md +132 -0
  120. package/packages/core/src/skills/bundled/cli/cli_pipeline/SKILL.md +135 -0
  121. package/packages/core/src/skills/bundled/cli/cli_safe_exec/SKILL.md +125 -0
  122. package/packages/core/src/skills/bundled/cli/software_engineering/SKILL.md +23 -0
  123. package/packages/core/src/skills/bundled/cron_manager/SKILL.md +188 -0
  124. package/packages/core/src/skills/bundled/cron_reminder/SKILL.md +112 -0
  125. package/packages/core/src/skills/bundled/filesystem/file_manager/SKILL.md +118 -0
  126. package/packages/core/src/skills/bundled/filesystem/file_read_and_summarize/SKILL.md +109 -0
  127. package/packages/core/src/skills/bundled/filesystem/file_writer/SKILL.md +129 -0
  128. package/packages/core/src/skills/bundled/filesystem/workspace_file_operator/SKILL.md +22 -0
  129. package/packages/core/src/skills/bundled/office/office_document_manager/SKILL.md +262 -0
  130. package/packages/core/src/skills/bundled/search_knowledge/capability_discovery/SKILL.md +75 -0
  131. package/packages/core/src/skills/bundled/web/browser_automate/SKILL.md +120 -0
  132. package/packages/core/src/skills/bundled/web/browser_scrape/SKILL.md +109 -0
  133. package/packages/core/src/skills/bundled/web/web_monitor/SKILL.md +127 -0
  134. package/packages/core/src/skills/bundled/web/web_research/SKILL.md +119 -0
  135. package/packages/core/src/skills/bundled-data.generated.ts +731 -2678
  136. package/packages/core/src/skills/skills.test.ts +52 -11
  137. package/packages/core/src/{harness → storage}/boot-id.ts +5 -2
  138. package/packages/core/src/storage/bootstrap.ts +151 -0
  139. package/packages/core/src/storage/causal-events.ts +84 -0
  140. package/packages/core/src/storage/collections.ts +680 -0
  141. package/packages/core/src/storage/crypto.ts +205 -74
  142. package/packages/core/src/{harness/db-helpers.ts → storage/hive.ts} +63 -7
  143. package/packages/core/src/storage/hivedb.ts +61 -0
  144. package/packages/core/src/storage/index.ts +111 -17
  145. package/packages/core/src/storage/model-id.ts +53 -0
  146. package/packages/core/src/storage/onboarding.ts +540 -972
  147. package/packages/core/src/storage/reconcile.ts +238 -0
  148. package/packages/core/src/storage/seed.ts +572 -406
  149. package/packages/core/src/storage/usage.ts +285 -225
  150. package/packages/core/src/storage/user-email.ts +11 -0
  151. package/packages/core/src/swarm/AgentExecutor.ts +1 -1
  152. package/packages/core/src/swarm/EventBridge.ts +1 -1
  153. package/packages/core/src/swarm/index.ts +12 -9
  154. package/packages/core/src/tool-runtime/index.ts +146 -23
  155. package/packages/core/src/tool-runtime/tool-worker.ts +2 -2
  156. package/packages/core/src/tool-runtime/worker-tools.ts +27 -0
  157. package/packages/core/src/{canvas/a2ui-tools.ts → tools/a2ui/index.ts} +17 -8
  158. package/packages/core/src/tools/agents/get-available-models.ts +36 -54
  159. package/packages/core/src/tools/agents/index.ts +784 -292
  160. package/packages/core/src/tools/api/api-request.test.ts +164 -0
  161. package/packages/core/src/tools/api/api-request.ts +174 -0
  162. package/packages/core/src/tools/api/index.ts +16 -0
  163. package/packages/core/src/tools/cli/index.ts +4 -0
  164. package/packages/core/src/tools/core/index.ts +281 -112
  165. package/packages/core/src/tools/cron/index.ts +121 -124
  166. package/packages/core/src/tools/index.ts +63 -78
  167. package/packages/core/src/tools/office/office-escribir-xlsx.ts +3 -1
  168. package/packages/core/src/tools/types.ts +3 -1
  169. package/packages/core/src/tools/web/artifact-inspect.ts +23 -0
  170. package/packages/core/src/tools/web/browser-screenshot.ts +26 -5
  171. package/packages/core/src/tools/web/browser-service.ts +5 -0
  172. package/packages/core/src/tools/web/browser-type.ts +3 -8
  173. package/packages/core/src/tools/web/index.ts +4 -4
  174. package/packages/core/src/voice/index.ts +89 -63
  175. package/packages/core/src/workers/agent.worker.ts +2 -2
  176. package/packages/core/src/workers/workers.test.ts +3 -10
  177. package/scripts/bump-version.ts +248 -0
  178. package/scripts/generate-skill-bundle.ts +108 -0
  179. package/test/agent-loop-terminal-synthesis.test.ts +32 -0
  180. package/test/catalog-agents-stay-enabled.test.ts +117 -0
  181. package/test/causal-events.test.ts +117 -0
  182. package/test/compaction.test.ts +105 -0
  183. package/test/context-compiler.test.ts +269 -0
  184. package/test/curator.test.ts +130 -0
  185. package/test/durable-queue.test.ts +114 -0
  186. package/test/harness-barrel.test.ts +64 -0
  187. package/test/hive-helpers.test.ts +130 -0
  188. package/test/hivedb-search.test.ts +189 -0
  189. package/test/internal-turns.test.ts +166 -0
  190. package/test/job-idempotency.test.ts +68 -0
  191. package/test/job-retry-backoff.test.ts +184 -0
  192. package/test/job-store.test.ts +381 -0
  193. package/test/llm-retry.test.ts +97 -0
  194. package/test/memory-perf.test.ts +774 -0
  195. package/test/minimal-loadout.test.ts +78 -0
  196. package/test/model-catalog.test.ts +105 -0
  197. package/test/preload.ts +12 -0
  198. package/test/reflector.test.ts +320 -0
  199. package/test/retention-cap.test.ts +91 -0
  200. package/test/retired-capabilities-pruned.test.ts +192 -0
  201. package/test/run-store.test.ts +355 -0
  202. package/test/scratchpad.test.ts +74 -0
  203. package/test/secrets-durability.test.ts +119 -0
  204. package/test/seed-model-reseed.test.ts +155 -0
  205. package/test/setup-agent-seed.test.ts +264 -0
  206. package/test/tool-inventory.test.ts +65 -0
  207. package/test/tool-runtime.test.ts +258 -0
  208. package/test/toon.test.ts +429 -0
  209. package/tsconfig.json +2 -0
  210. package/packages/core/src/ace/Curator.ts +0 -158
  211. package/packages/core/src/ace/Reflector.ts +0 -200
  212. package/packages/core/src/ace/index.ts +0 -4
  213. package/packages/core/src/agent/AgentRunner.ts +0 -711
  214. package/packages/core/src/agent/ContextCompiler.ts +0 -567
  215. package/packages/core/src/agent/ContextGuard.ts +0 -91
  216. package/packages/core/src/agent/ConversationStore.ts +0 -254
  217. package/packages/core/src/agent/Hooks.ts +0 -166
  218. package/packages/core/src/agent/StuckLoop.ts +0 -133
  219. package/packages/core/src/agent/providers/LLMClient.ts +0 -149
  220. package/packages/core/src/agent/providers/anthropic.ts +0 -212
  221. package/packages/core/src/agent/providers/openai-compat.ts +0 -231
  222. package/packages/core/src/agent/selectors/PlaybookSelector.ts +0 -121
  223. package/packages/core/src/agent/selectors/SkillSelector.ts +0 -322
  224. package/packages/core/src/agent/selectors/index.ts +0 -6
  225. package/packages/core/src/auth/auth.ts +0 -121
  226. package/packages/core/src/auth/index.ts +0 -1
  227. package/packages/core/src/canvas/CanvasManager.ts +0 -390
  228. package/packages/core/src/canvas/canvas-tools.ts +0 -448
  229. package/packages/core/src/harness/collections.ts +0 -98
  230. package/packages/core/src/harness/goal-verifier.ts +0 -141
  231. package/packages/core/src/harness/harness.test.ts +0 -236
  232. package/packages/core/src/harness/reconcile.ts +0 -149
  233. package/packages/core/src/mcp/MCPToolAdapter.ts +0 -176
  234. package/packages/core/src/multimodal/VisionService.ts +0 -293
  235. package/packages/core/src/scheduler/dag/AgentExecutor.ts +0 -53
  236. package/packages/core/src/scheduler/dag/DAGScheduler.ts +0 -250
  237. package/packages/core/src/scheduler/dag/EventBridge.ts +0 -122
  238. package/packages/core/src/scheduler/dag/TaskGraph.ts +0 -192
  239. package/packages/core/src/scheduler/dag/TaskNode.ts +0 -97
  240. package/packages/core/src/scheduler/dag/TaskResult.ts +0 -22
  241. package/packages/core/src/scheduler/dag/errors.ts +0 -37
  242. package/packages/core/src/scheduler/dag/index.ts +0 -26
  243. package/packages/core/src/scheduler/dag/presets/ResearchPreset.ts +0 -97
  244. package/packages/core/src/scheduler/dag/strategies/ParallelStrategy.ts +0 -21
  245. package/packages/core/src/scheduler/dag/strategies/PriorityStrategy.ts +0 -46
  246. package/packages/core/src/storage/HiveDBStorage.ts +0 -64
  247. package/packages/core/src/storage/SQLiteStorage.ts +0 -414
  248. package/packages/core/src/storage/hiveSeed.ts +0 -308
  249. package/packages/core/src/storage/hiveStorage.test.ts +0 -38
  250. package/packages/core/src/storage/schema.ts +0 -689
  251. package/packages/core/src/storage/storage.test.ts +0 -37
  252. package/packages/core/src/swarm/AgentBus.ts +0 -460
  253. package/packages/core/src/swarm/EventBus.ts +0 -169
  254. package/packages/core/src/swarm/WorkerPool.ts +0 -236
  255. package/packages/core/src/tools/bridge-events.ts +0 -26
  256. package/packages/core/src/tools/canvas/index.ts +0 -375
  257. package/packages/core/src/tools/codebridge/index.ts +0 -342
  258. package/packages/core/src/tools/meeting/index.ts +0 -353
  259. package/packages/core/src/tools/projects/index.ts +0 -37
  260. package/packages/core/src/tools/projects/project-create.ts +0 -94
  261. package/packages/core/src/tools/projects/project-done.ts +0 -66
  262. package/packages/core/src/tools/projects/project-fail.ts +0 -66
  263. package/packages/core/src/tools/projects/project-list.ts +0 -96
  264. package/packages/core/src/tools/projects/project-update.ts +0 -72
  265. package/packages/core/src/tools/projects/task-create.ts +0 -68
  266. package/packages/core/src/tools/projects/task-evaluate.ts +0 -93
  267. package/packages/core/src/tools/projects/task-update.ts +0 -93
  268. package/packages/core/src/tools/voice/index.ts +0 -104
  269. package/packages/core/src/tools/web/api-request.test.ts +0 -170
  270. package/packages/core/src/tools/web/api-request.ts +0 -239
  271. package/test/setup-db.ts +0 -216
  272. /package/packages/core/src/agent/{NativeTools.ts → native-tools.ts} +0 -0
@@ -1,21 +1,62 @@
1
+ /**
2
+ * El catálogo de skills bundled se genera desde los SKILL.md de `skills/bundled/`
3
+ * con `bun run skills:bundle`. Hasta 0.1.5 el SDK traía 44 skills copiadas a
4
+ * mano, 21 de las cuales invocaban tools que ya no existen (`voice_*`,
5
+ * `meeting_transcription`, `canvas_*`, `code_*`, `project_*`): el selector se
6
+ * las podía ofrecer al modelo y la ejecución moría sin ejecutor.
7
+ */
8
+
1
9
  import { describe, it, expect } from "bun:test";
2
10
  import { BUNDLED_SKILLS_DATA } from "./bundled-data.generated.ts";
11
+ import { createAllTools } from "../tools/index.ts";
12
+ import { loadConfig } from "../config/loader.ts";
3
13
 
4
14
  describe("Bundled skills", () => {
5
- it("includes web_browser_research skill", () => {
6
- const skill = BUNDLED_SKILLS_DATA.find((s) => s.name === "web_browser_research");
7
- expect(skill).toBeDefined();
8
- expect(skill?.category).toBe("web");
9
- expect(skill?.tools).toContain("web_search");
10
- expect(skill?.tools).toContain("browser_navigate");
11
- expect(skill?.tools).toContain("browser_extract");
12
- expect(skill?.triggers.length).toBeGreaterThan(0);
13
- });
14
-
15
- it("includes existing web and browser skills", () => {
15
+ it("incluye las skills web y de browser", () => {
16
16
  const names = BUNDLED_SKILLS_DATA.map((s) => s.name);
17
17
  expect(names).toContain("web_research");
18
18
  expect(names).toContain("browser_scrape");
19
19
  expect(names).toContain("browser_automate");
20
20
  });
21
+
22
+ it("no arrastra las skills retiradas", () => {
23
+ const names = BUNDLED_SKILLS_DATA.map((s) => s.name);
24
+ for (const retired of [
25
+ "web_browser_research",
26
+ "voice_input",
27
+ "voice_output",
28
+ "voice_assistant",
29
+ "meeting_transcription",
30
+ "canvas_report",
31
+ "canvas_dashboard",
32
+ "code_review",
33
+ "code_generate",
34
+ "project_planner",
35
+ "busqueda_fts5",
36
+ "ai_coder",
37
+ "data_analyst",
38
+ ]) {
39
+ expect(names, `la skill retirada "${retired}" volvió al bundle`).not.toContain(retired);
40
+ }
41
+ });
42
+
43
+ it("cada skill declara sólo tools que existen en el registry", async () => {
44
+ const available = new Set(createAllTools(await loadConfig()).map((t) => t.name));
45
+
46
+ const dangling = BUNDLED_SKILLS_DATA.flatMap((skill) =>
47
+ (skill.tools ?? [])
48
+ .filter((tool) => !available.has(tool))
49
+ .map((tool) => `${skill.name} → ${tool}`)
50
+ );
51
+
52
+ expect(dangling, `skills apuntando a tools inexistentes:\n${dangling.join("\n")}`).toEqual([]);
53
+ });
54
+
55
+ it("toda skill tiene nombre, descripción y categoría", () => {
56
+ for (const skill of BUNDLED_SKILLS_DATA) {
57
+ expect(skill.name, "skill sin nombre").toBeTruthy();
58
+ expect(skill.description, `${skill.name} sin descripción`).toBeTruthy();
59
+ expect(skill.category, `${skill.name} sin categoría`).toBeTruthy();
60
+ }
61
+ });
21
62
  });
@@ -1,7 +1,10 @@
1
1
  /**
2
2
  * boot-id — a unique id generated on every process start so that durable
3
- * leases (harness runs / jobs) can detect which rows belong to a dead
3
+ * leases (agentRuns / jobQueue) can detect which rows belong to a dead
4
4
  * process after a crash/restart.
5
+ *
6
+ * The id is a short hex string; it is stable for the lifetime of the
7
+ * process and can be passed to {@link reconcileOnBoot}.
5
8
  */
6
9
 
7
10
  import { randomBytes } from "node:crypto";
@@ -17,4 +20,4 @@ export function getBootId(): string {
17
20
 
18
21
  export function resetBootId(): void {
19
22
  currentBootId = null;
20
- }
23
+ }
@@ -0,0 +1,151 @@
1
+ /**
2
+ * HiveDB bootstrap — replaces initializeDatabase() + seedAllData() +
3
+ * runStartupMigrations().
4
+ *
5
+ * A brand-new install never has legacy SQLite data to migrate, so there is
6
+ * no version-gated migration list: ensureHiveDb() just makes sure every
7
+ * collection's secondary indexes exist (idempotent, safe every boot) and
8
+ * that the static catalogs are (re)seeded from their canonical source
9
+ * (SEED_DATA / SkillLoader) — same "reseed every boot so code changes
10
+ * always take effect" behavior `seedAllData()` had, just via `put()`
11
+ * instead of `DELETE`+`INSERT`.
12
+ */
13
+
14
+ import { getHiveDb } from "./hivedb";
15
+ import { col } from "./hive";
16
+ import { seedAllData } from "./seed";
17
+ import { ensureSecretsBackend } from "./crypto";
18
+
19
+ interface IndexSpec {
20
+ collection: string;
21
+ field: string;
22
+ unique?: boolean;
23
+ }
24
+
25
+ /**
26
+ * Every equality index used by `findBy()` across the codebase. Grouped by
27
+ * the migration stage that introduces the collection; kept in one place so
28
+ * a missing index is a loud error (`findBy` throws) rather than a silent
29
+ * empty result.
30
+ */
31
+ const INDEXES: IndexSpec[] = [
32
+ // Stage 1 — identity/config core
33
+ { collection: "models", field: "provider_id" },
34
+ { collection: "models", field: "model_type" },
35
+ { collection: "agents", field: "user_id" },
36
+ { collection: "agents", field: "model_id" },
37
+ { collection: "agents", field: "parent_id" },
38
+ { collection: "agents", field: "role" },
39
+ { collection: "agents", field: "status" },
40
+ { collection: "agents", field: "source" },
41
+ // Stage 2 — catalog
42
+ { collection: "channels", field: "user_id" },
43
+ { collection: "channels", field: "type" },
44
+ { collection: "skills", field: "category" },
45
+ { collection: "skills", field: "active" },
46
+ { collection: "tools", field: "category" },
47
+ { collection: "tools", field: "active" },
48
+ { collection: "ethics", field: "active" },
49
+ { collection: "mcpTools", field: "server_id" },
50
+ { collection: "mcpTools", field: "active" },
51
+ // Stage 3 — auth/identity
52
+ { collection: "userChannels", field: "channel" },
53
+ { collection: "refreshTokens", field: "token_hash", unique: true },
54
+ { collection: "refreshTokens", field: "user_id" },
55
+ { collection: "notifications", field: "user_id" },
56
+ { collection: "notifications", field: "channel" },
57
+ // Stage 4 — chat/ACE
58
+ { collection: "traces", field: "thread_id" },
59
+ { collection: "traces", field: "agent_id" },
60
+ { collection: "traces", field: "success" },
61
+ { collection: "playbook", field: "active" },
62
+ { collection: "playbook", field: "category" },
63
+ // Stage 5 — scheduler
64
+ { collection: "cronJobs", field: "status" },
65
+ { collection: "cronJobs", field: "task_type" },
66
+ { collection: "cronJobs", field: "agent_id" },
67
+ { collection: "agentRuns", field: "status" },
68
+ { collection: "agentRuns", field: "thread_id" },
69
+ { collection: "agentRuns", field: "agent_id" },
70
+ { collection: "agentRuns", field: "kind" },
71
+ { collection: "agentRuns", field: "catalog_agent_id" },
72
+ { collection: "jobQueue", field: "status" },
73
+ { collection: "jobQueue", field: "lane" },
74
+ { collection: "jobQueue", field: "type" },
75
+ { collection: "jobQueue", field: "run_id" },
76
+ { collection: "jobQueue", field: "idempotency_key" },
77
+ { collection: "proofPackets", field: "run_id" },
78
+ { collection: "proofPackets", field: "agent_id" },
79
+ { collection: "proofPackets", field: "catalog_agent_id" },
80
+ { collection: "artifacts", field: "run_id" },
81
+ { collection: "artifacts", field: "task_id" },
82
+ { collection: "artifacts", field: "user_id" },
83
+ { collection: "artifacts", field: "status" },
84
+ { collection: "agentProposals", field: "agent_id" },
85
+ { collection: "agentProposals", field: "status" },
86
+ { collection: "agentProposals", field: "type" },
87
+ // Stage 6 — orchestration
88
+ { collection: "tasks", field: "agent_id" },
89
+ { collection: "tasks", field: "status" },
90
+ { collection: "tasks", field: "catalog_agent_id" },
91
+ { collection: "tasks", field: "delegation_group_id" },
92
+ { collection: "delegationGroups", field: "turn_id", unique: true },
93
+ { collection: "delegationGroups", field: "thread_id" },
94
+ { collection: "delegationGroups", field: "status" },
95
+ { collection: "agentBusMessages", field: "to_worker_id" },
96
+ { collection: "agentBusMessages", field: "from_worker_id" },
97
+ { collection: "agentBusMessages", field: "event_type" },
98
+ { collection: "narrationEvents", field: "turn_id" },
99
+ { collection: "narrationEvents", field: "thread_id" },
100
+ { collection: "narrationEvents", field: "user_id" },
101
+ { collection: "narrationEvents", field: "kind" },
102
+ // Stage 7 — meeting
103
+ { collection: "meetingSessions", field: "user_id" },
104
+ { collection: "meetingSessions", field: "status" },
105
+ ];
106
+
107
+ async function ensureIndexes(): Promise<void> {
108
+ for (const spec of INDEXES) {
109
+ const c = await col(spec.collection);
110
+ await c.createIndex(spec.field, { unique: spec.unique });
111
+ }
112
+ }
113
+
114
+ /**
115
+ * Seeds the static catalogs (tools, skills, providers, models, mcp servers,
116
+ * channels, ethics, ACE playbook) from their canonical source every boot —
117
+ * same "reseed every boot so code changes always take effect" behavior the
118
+ * old SQLite seedAllData() had. Fully idempotent: uses putIfAbsent for
119
+ * user-toggleable fields (enabled/active) and doesn't touch `users`, so it's
120
+ * safe to call unconditionally before any onboarding has happened.
121
+ */
122
+ async function ensureSeedData(): Promise<void> {
123
+ await seedAllData();
124
+ }
125
+
126
+ let bootstrapped = false;
127
+
128
+ /**
129
+ * Idempotent entry point: opens the database, ensures indexes, reseeds the
130
+ * static catalogs, and records the schema version. Safe to call on every
131
+ * gateway boot.
132
+ */
133
+ export async function ensureHiveDb(): Promise<void> {
134
+ await getHiveDb();
135
+ await ensureIndexes();
136
+ // Mint the master key before anything can save an API key, so a fresh
137
+ // install is durable from the first keystroke rather than after a restart
138
+ // has already dropped the secret.
139
+ ensureSecretsBackend();
140
+ await ensureSeedData();
141
+
142
+ const meta = await col<{ value: number }>("meta");
143
+ const existing = await meta.get("schemaVersion");
144
+ if (!existing) await meta.put("schemaVersion", { value: 1 }, { expectedVersion: 0 });
145
+
146
+ bootstrapped = true;
147
+ }
148
+
149
+ export function isBootstrapped(): boolean {
150
+ return bootstrapped;
151
+ }
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Live-tail wrapper over HiveDB's G9 causal event log (subscribe()/events()).
3
+ *
4
+ * Read-side, separate from agent-loop.ts's write-side appendCausalEvent()
5
+ * (module-private there, write-only). This is the read/watch counterpart,
6
+ * co-located with the DB singleton accessor.
7
+ */
8
+
9
+ import { getHiveDb } from "./hivedb"
10
+ import type { Event, EventPattern } from "@johpaz/hive-db"
11
+
12
+ export type { Event as CausalEvent, EventPattern as CausalEventPattern }
13
+
14
+ /**
15
+ * Live-tail causal events matching `pattern`. Forward-only: only events
16
+ * appended AFTER this call resolves are delivered. hive-db's subscribe()/
17
+ * events() are a pure in-process pub/sub (see hiveBD's reactive.rs — a
18
+ * DashMap of subscribers, dispatched right after the durable write, with no
19
+ * backing read of the log on subscribe) — there is no historical replay.
20
+ * Combine with causalThread()/read(seq) if backfill is ever needed.
21
+ *
22
+ * Note: `pattern.kind` matches exactly one kind at a time, not an OR of
23
+ * several — call watchCausalEvents() once per kind if you need more than one.
24
+ *
25
+ * Process constraint (confirmed by testing): getHiveDb() opens the database
26
+ * exclusively — there is no shared/read-only mode, so this can only be
27
+ * called from within the SAME process as whatever else has the DB open
28
+ * (e.g. embedded inside the gateway). A separate process (like the `hive
29
+ * causal watch` CLI) calling this while a `hive` gateway is already running
30
+ * against the same DB fails fast with an "already open" error.
31
+ */
32
+ export async function watchCausalEvents(
33
+ pattern: EventPattern
34
+ ): Promise<AsyncIterable<Event> & { close(): void }> {
35
+ const db = await getHiveDb()
36
+ return db.events(pattern)
37
+ }
38
+
39
+ /** One-line human-readable summary of a causal event, keyed by its kindTag. */
40
+ export function formatCausalEvent(event: Event): string {
41
+ let payload: Record<string, unknown> = {}
42
+ try {
43
+ payload = JSON.parse(event.payload)
44
+ } catch {
45
+ // Malformed payload — still print seq/kind/agent/stream below.
46
+ }
47
+
48
+ const streamShort = event.streamId.slice(0, 8)
49
+ const header = `[${event.seq}] ${kindIcon(event.kindTag)} ${event.kindTag.padEnd(16)} agent=${event.agentId} stream=${streamShort}…`
50
+
51
+ switch (event.kindTag) {
52
+ case "IntentLogged":
53
+ return `${header} "${truncate(String(payload.intent ?? ""), 120)}"`
54
+ case "StateTransition":
55
+ return `${header} "${truncate(String(payload.description ?? ""), 120)}"`
56
+ case "ToolCall": {
57
+ const outcome = payload.outcome
58
+ const outcomeStr =
59
+ outcome === "Ok" ? "ok"
60
+ : outcome === "Timeout" ? "TIMEOUT"
61
+ : (outcome && typeof outcome === "object" && "Err" in (outcome as object))
62
+ ? `ERR: ${(outcome as { Err: string }).Err}`
63
+ : String(outcome)
64
+ const latency = payload.latency_ms !== undefined ? `${payload.latency_ms}ms` : "?ms"
65
+ return `${header} tool=${payload.tool} ${latency} ${outcomeStr}`
66
+ }
67
+ default:
68
+ return `${header} ${truncate(JSON.stringify(payload), 120)}`
69
+ }
70
+ }
71
+
72
+ function kindIcon(kindTag: string): string {
73
+ switch (kindTag) {
74
+ case "IntentLogged": return "🎯"
75
+ case "StateTransition": return "🔀"
76
+ case "ToolCall": return "🔧"
77
+ case "LearningProposal": return "📄"
78
+ default: return "•"
79
+ }
80
+ }
81
+
82
+ function truncate(s: string, max: number): string {
83
+ return s.length > max ? s.slice(0, max) + "…" : s
84
+ }