@goondocks/myco 0.15.1 → 0.16.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 (181) hide show
  1. package/README.md +6 -4
  2. package/dist/{agent-run-T433ENJS.js → agent-run-LOZGH6P5.js} +8 -8
  3. package/dist/{agent-tasks-TAIU3V5I.js → agent-tasks-SNQ55FUN.js} +8 -8
  4. package/dist/{chunk-TRA3R4EC.js → chunk-34NHDRWI.js} +1 -3
  5. package/dist/chunk-34NHDRWI.js.map +1 -0
  6. package/dist/{chunk-6GG2IVNV.js → chunk-35FAQCKJ.js} +4 -4
  7. package/dist/{chunk-LF5Z62X6.js → chunk-4JVHWBZF.js} +2 -2
  8. package/dist/{chunk-GDCSPMH4.js → chunk-6JZEAOLG.js} +3 -3
  9. package/dist/{chunk-2QMDRZPJ.js → chunk-C3GNF7RJ.js} +5 -5
  10. package/dist/{chunk-DJQOYEK3.js → chunk-CJ2KTRWI.js} +52 -4
  11. package/dist/chunk-CJ2KTRWI.js.map +1 -0
  12. package/dist/{chunk-3MEOYXOW.js → chunk-D2NTFSVO.js} +3 -3
  13. package/dist/{chunk-75J2BR4P.js → chunk-D63XTGBV.js} +580 -415
  14. package/dist/chunk-D63XTGBV.js.map +1 -0
  15. package/dist/{chunk-5YQ6VOFZ.js → chunk-DZWSHCAC.js} +2 -2
  16. package/dist/{chunk-CUADDHHU.js → chunk-E7NUADTQ.js} +9 -1
  17. package/dist/chunk-E7NUADTQ.js.map +1 -0
  18. package/dist/{chunk-4O3QNM5I.js → chunk-G42PTGMC.js} +3 -3
  19. package/dist/{chunk-SV6UCB2Z.js → chunk-GSKXOCFG.js} +3 -1
  20. package/dist/chunk-GSKXOCFG.js.map +1 -0
  21. package/dist/{chunk-GCCBXCHF.js → chunk-HA7HO2X2.js} +3 -3
  22. package/dist/{chunk-RBFECYNA.js → chunk-I3S6L7QC.js} +2 -2
  23. package/dist/{chunk-SPJGJEFV.js → chunk-IRSNOBGD.js} +2 -2
  24. package/dist/{chunk-GYIA6XLB.js → chunk-MVBCON4D.js} +2 -2
  25. package/dist/chunk-MVBCON4D.js.map +1 -0
  26. package/dist/{chunk-Z7TZJ2SP.js → chunk-P6C6ADBU.js} +2 -2
  27. package/dist/{chunk-OKCSSDFC.js → chunk-RPILIIYT.js} +2 -2
  28. package/dist/{chunk-23FJUKCN.js → chunk-SGYYOTNM.js} +10 -4
  29. package/dist/{chunk-23FJUKCN.js.map → chunk-SGYYOTNM.js.map} +1 -1
  30. package/dist/{chunk-X5IXK5KO.js → chunk-TIAYBVSI.js} +153 -18
  31. package/dist/chunk-TIAYBVSI.js.map +1 -0
  32. package/dist/{chunk-TQO4PF5K.js → chunk-TPTF3R77.js} +4 -4
  33. package/dist/chunk-U5EW2VIQ.js +86 -0
  34. package/dist/chunk-U5EW2VIQ.js.map +1 -0
  35. package/dist/{chunk-DTE3SHYK.js → chunk-UILSK6DK.js} +2 -2
  36. package/dist/{chunk-EYMKBNRP.js → chunk-V2ZBYKDU.js} +3 -3
  37. package/dist/{chunk-BFM6AM6R.js → chunk-VTSNXAW7.js} +2 -2
  38. package/dist/{chunk-HHZ3RTEI.js → chunk-VWXDSDJU.js} +2 -2
  39. package/dist/{chunk-X4XFJG6I.js → chunk-W7ZOOZMK.js} +3 -3
  40. package/dist/{chunk-4BQ5QE76.js → chunk-XAXQ72L3.js} +9 -2
  41. package/dist/chunk-XAXQ72L3.js.map +1 -0
  42. package/dist/{cli-W37MRZHD.js → cli-W66XNY2H.js} +42 -42
  43. package/dist/{client-YNTTC75R.js → client-IZM3GJMT.js} +5 -5
  44. package/dist/{config-MOWCOJJ4.js → config-VHHCGE4F.js} +4 -4
  45. package/dist/{detect-GFYKKHLJ.js → detect-6FNYONJF.js} +2 -2
  46. package/dist/{detect-providers-EU35RUL3.js → detect-providers-R7QOB3H6.js} +5 -5
  47. package/dist/{doctor-PAAQU5AS.js → doctor-WLV7QNRP.js} +13 -13
  48. package/dist/{executor-4OXDK4ZA.js → executor-PUKL76TU.js} +495 -157
  49. package/dist/executor-PUKL76TU.js.map +1 -0
  50. package/dist/{init-PHQAQANR.js → init-5TB6A2RV.js} +18 -18
  51. package/dist/{init-wizard-RFD46XAJ.js → init-wizard-2Y52AX2A.js} +8 -8
  52. package/dist/{installer-BTUNKWOU.js → installer-AARSFXI6.js} +2 -2
  53. package/dist/llm-LS7U7BHC.js +17 -0
  54. package/dist/{loader-WGDVRGLM.js → loader-QDWQTBX4.js} +4 -4
  55. package/dist/{loader-WC4U5NM5.js → loader-YQDG5GI5.js} +4 -4
  56. package/dist/{logs-WFBX2I7C.js → logs-TMKNLSJY.js} +3 -3
  57. package/dist/{main-ADLCOYKM.js → main-3ZXFA56L.js} +608 -214
  58. package/dist/main-3ZXFA56L.js.map +1 -0
  59. package/dist/{open-3VPUP3HD.js → open-ZOZLFBEA.js} +8 -8
  60. package/dist/{openai-embeddings-SEIV7AM3.js → openai-embeddings-FUW6CSN2.js} +5 -5
  61. package/dist/{openrouter-ELODIZRP.js → openrouter-YSIUSUQL.js} +5 -5
  62. package/dist/{post-compact-5NYLOC46.js → post-compact-QSID23PX.js} +8 -8
  63. package/dist/{post-tool-use-SNNXSZ5Y.js → post-tool-use-4MTNNDTO.js} +7 -7
  64. package/dist/{post-tool-use-failure-POKVXQHY.js → post-tool-use-failure-WKSMUGJI.js} +8 -8
  65. package/dist/{pre-compact-ZUICBJEX.js → pre-compact-HFGKNBYV.js} +8 -8
  66. package/dist/{provider-check-B66E5PWS.js → provider-check-VEYONGNU.js} +5 -5
  67. package/dist/{registry-DHWVHXWY.js → registry-5R3DLJQH.js} +5 -5
  68. package/dist/{remove-SVU2V4Q7.js → remove-S5G6VGVT.js} +10 -10
  69. package/dist/{resolution-events-DBCRVZGU.js → resolution-events-CHOKR35X.js} +5 -5
  70. package/dist/{restart-NBB5CXJ4.js → restart-A7HJTFFM.js} +9 -9
  71. package/dist/{search-YUQZFRZX.js → search-HKBGO3QV.js} +9 -9
  72. package/dist/{server-NBRX56VL.js → server-UAATWKNX.js} +5 -5
  73. package/dist/{session-2QP4HMZ5.js → session-D2WPQTSR.js} +10 -10
  74. package/dist/{session-end-NNFBW7CQ.js → session-end-S4RYJG3Y.js} +7 -7
  75. package/dist/{session-start-NPNP4IXX.js → session-start-4RJ32KS5.js} +12 -12
  76. package/dist/{setup-llm-C3IGFLRN.js → setup-llm-EZRNEIW2.js} +9 -9
  77. package/dist/skill-staging-SWM7UC5D.js +25 -0
  78. package/dist/src/agent/definitions/tasks/full-intelligence.yaml +1 -1
  79. package/dist/src/agent/definitions/tasks/skill-generate.yaml +55 -21
  80. package/dist/src/cli.js +1 -1
  81. package/dist/src/daemon/main.js +1 -1
  82. package/dist/src/hooks/post-tool-use.js +1 -1
  83. package/dist/src/hooks/session-end.js +1 -1
  84. package/dist/src/hooks/session-start.js +1 -1
  85. package/dist/src/hooks/stop.js +1 -1
  86. package/dist/src/hooks/user-prompt-submit.js +1 -1
  87. package/dist/src/mcp/server.js +1 -1
  88. package/dist/src/symbionts/manifests/codex.yaml +1 -0
  89. package/dist/src/symbionts/templates/codex/settings.json +5 -0
  90. package/dist/src/worker/src/schema.ts +16 -0
  91. package/dist/{stats-FEEXIRMS.js → stats-PW7OGIBR.js} +10 -10
  92. package/dist/{stop-FGDGWXTK.js → stop-FVMLTWXU.js} +7 -7
  93. package/dist/{stop-failure-5YAGH2TQ.js → stop-failure-MD52CGFX.js} +8 -8
  94. package/dist/{subagent-start-UCKVJDR4.js → subagent-start-ZJZA7EAJ.js} +8 -8
  95. package/dist/{subagent-stop-H25B3QEC.js → subagent-stop-56H22JSE.js} +8 -8
  96. package/dist/{task-completed-2JGZN2CF.js → task-completed-TQ4WW2HW.js} +8 -8
  97. package/dist/{team-TG5WZXWO.js → team-RXYFXGUT.js} +6 -6
  98. package/dist/ui/assets/index-Bjv_ck3c.css +1 -0
  99. package/dist/ui/assets/index-RYHXSJv1.js +842 -0
  100. package/dist/ui/index.html +2 -2
  101. package/dist/{update-EG3N2EXI.js → update-HIJUK5ZK.js} +10 -10
  102. package/dist/{user-prompt-submit-7FFQ3ORA.js → user-prompt-submit-SLQNTQFL.js} +7 -7
  103. package/dist/{verify-2M3DYHEY.js → verify-ITBMLK67.js} +9 -9
  104. package/dist/{version-JUQU5W22.js → version-4YUDRPU4.js} +2 -2
  105. package/dist/version-4YUDRPU4.js.map +1 -0
  106. package/package.json +1 -1
  107. package/dist/chunk-4BQ5QE76.js.map +0 -1
  108. package/dist/chunk-75J2BR4P.js.map +0 -1
  109. package/dist/chunk-CUADDHHU.js.map +0 -1
  110. package/dist/chunk-DJQOYEK3.js.map +0 -1
  111. package/dist/chunk-GYIA6XLB.js.map +0 -1
  112. package/dist/chunk-SV6UCB2Z.js.map +0 -1
  113. package/dist/chunk-TRA3R4EC.js.map +0 -1
  114. package/dist/chunk-X5IXK5KO.js.map +0 -1
  115. package/dist/executor-4OXDK4ZA.js.map +0 -1
  116. package/dist/llm-D4VWYUK7.js +0 -17
  117. package/dist/main-ADLCOYKM.js.map +0 -1
  118. package/dist/ui/assets/index-7Vimyg7g.js +0 -837
  119. package/dist/ui/assets/index-DlEQ8A8Y.css +0 -1
  120. /package/dist/{agent-run-T433ENJS.js.map → agent-run-LOZGH6P5.js.map} +0 -0
  121. /package/dist/{agent-tasks-TAIU3V5I.js.map → agent-tasks-SNQ55FUN.js.map} +0 -0
  122. /package/dist/{chunk-6GG2IVNV.js.map → chunk-35FAQCKJ.js.map} +0 -0
  123. /package/dist/{chunk-LF5Z62X6.js.map → chunk-4JVHWBZF.js.map} +0 -0
  124. /package/dist/{chunk-GDCSPMH4.js.map → chunk-6JZEAOLG.js.map} +0 -0
  125. /package/dist/{chunk-2QMDRZPJ.js.map → chunk-C3GNF7RJ.js.map} +0 -0
  126. /package/dist/{chunk-3MEOYXOW.js.map → chunk-D2NTFSVO.js.map} +0 -0
  127. /package/dist/{chunk-5YQ6VOFZ.js.map → chunk-DZWSHCAC.js.map} +0 -0
  128. /package/dist/{chunk-4O3QNM5I.js.map → chunk-G42PTGMC.js.map} +0 -0
  129. /package/dist/{chunk-GCCBXCHF.js.map → chunk-HA7HO2X2.js.map} +0 -0
  130. /package/dist/{chunk-RBFECYNA.js.map → chunk-I3S6L7QC.js.map} +0 -0
  131. /package/dist/{chunk-SPJGJEFV.js.map → chunk-IRSNOBGD.js.map} +0 -0
  132. /package/dist/{chunk-Z7TZJ2SP.js.map → chunk-P6C6ADBU.js.map} +0 -0
  133. /package/dist/{chunk-OKCSSDFC.js.map → chunk-RPILIIYT.js.map} +0 -0
  134. /package/dist/{chunk-TQO4PF5K.js.map → chunk-TPTF3R77.js.map} +0 -0
  135. /package/dist/{chunk-DTE3SHYK.js.map → chunk-UILSK6DK.js.map} +0 -0
  136. /package/dist/{chunk-EYMKBNRP.js.map → chunk-V2ZBYKDU.js.map} +0 -0
  137. /package/dist/{chunk-BFM6AM6R.js.map → chunk-VTSNXAW7.js.map} +0 -0
  138. /package/dist/{chunk-HHZ3RTEI.js.map → chunk-VWXDSDJU.js.map} +0 -0
  139. /package/dist/{chunk-X4XFJG6I.js.map → chunk-W7ZOOZMK.js.map} +0 -0
  140. /package/dist/{cli-W37MRZHD.js.map → cli-W66XNY2H.js.map} +0 -0
  141. /package/dist/{client-YNTTC75R.js.map → client-IZM3GJMT.js.map} +0 -0
  142. /package/dist/{config-MOWCOJJ4.js.map → config-VHHCGE4F.js.map} +0 -0
  143. /package/dist/{detect-GFYKKHLJ.js.map → detect-6FNYONJF.js.map} +0 -0
  144. /package/dist/{detect-providers-EU35RUL3.js.map → detect-providers-R7QOB3H6.js.map} +0 -0
  145. /package/dist/{doctor-PAAQU5AS.js.map → doctor-WLV7QNRP.js.map} +0 -0
  146. /package/dist/{init-PHQAQANR.js.map → init-5TB6A2RV.js.map} +0 -0
  147. /package/dist/{init-wizard-RFD46XAJ.js.map → init-wizard-2Y52AX2A.js.map} +0 -0
  148. /package/dist/{installer-BTUNKWOU.js.map → installer-AARSFXI6.js.map} +0 -0
  149. /package/dist/{llm-D4VWYUK7.js.map → llm-LS7U7BHC.js.map} +0 -0
  150. /package/dist/{loader-WC4U5NM5.js.map → loader-QDWQTBX4.js.map} +0 -0
  151. /package/dist/{loader-WGDVRGLM.js.map → loader-YQDG5GI5.js.map} +0 -0
  152. /package/dist/{logs-WFBX2I7C.js.map → logs-TMKNLSJY.js.map} +0 -0
  153. /package/dist/{open-3VPUP3HD.js.map → open-ZOZLFBEA.js.map} +0 -0
  154. /package/dist/{openai-embeddings-SEIV7AM3.js.map → openai-embeddings-FUW6CSN2.js.map} +0 -0
  155. /package/dist/{openrouter-ELODIZRP.js.map → openrouter-YSIUSUQL.js.map} +0 -0
  156. /package/dist/{post-compact-5NYLOC46.js.map → post-compact-QSID23PX.js.map} +0 -0
  157. /package/dist/{post-tool-use-SNNXSZ5Y.js.map → post-tool-use-4MTNNDTO.js.map} +0 -0
  158. /package/dist/{post-tool-use-failure-POKVXQHY.js.map → post-tool-use-failure-WKSMUGJI.js.map} +0 -0
  159. /package/dist/{pre-compact-ZUICBJEX.js.map → pre-compact-HFGKNBYV.js.map} +0 -0
  160. /package/dist/{provider-check-B66E5PWS.js.map → provider-check-VEYONGNU.js.map} +0 -0
  161. /package/dist/{registry-DHWVHXWY.js.map → registry-5R3DLJQH.js.map} +0 -0
  162. /package/dist/{remove-SVU2V4Q7.js.map → remove-S5G6VGVT.js.map} +0 -0
  163. /package/dist/{resolution-events-DBCRVZGU.js.map → resolution-events-CHOKR35X.js.map} +0 -0
  164. /package/dist/{restart-NBB5CXJ4.js.map → restart-A7HJTFFM.js.map} +0 -0
  165. /package/dist/{search-YUQZFRZX.js.map → search-HKBGO3QV.js.map} +0 -0
  166. /package/dist/{server-NBRX56VL.js.map → server-UAATWKNX.js.map} +0 -0
  167. /package/dist/{session-2QP4HMZ5.js.map → session-D2WPQTSR.js.map} +0 -0
  168. /package/dist/{session-end-NNFBW7CQ.js.map → session-end-S4RYJG3Y.js.map} +0 -0
  169. /package/dist/{session-start-NPNP4IXX.js.map → session-start-4RJ32KS5.js.map} +0 -0
  170. /package/dist/{setup-llm-C3IGFLRN.js.map → setup-llm-EZRNEIW2.js.map} +0 -0
  171. /package/dist/{version-JUQU5W22.js.map → skill-staging-SWM7UC5D.js.map} +0 -0
  172. /package/dist/{stats-FEEXIRMS.js.map → stats-PW7OGIBR.js.map} +0 -0
  173. /package/dist/{stop-FGDGWXTK.js.map → stop-FVMLTWXU.js.map} +0 -0
  174. /package/dist/{stop-failure-5YAGH2TQ.js.map → stop-failure-MD52CGFX.js.map} +0 -0
  175. /package/dist/{subagent-start-UCKVJDR4.js.map → subagent-start-ZJZA7EAJ.js.map} +0 -0
  176. /package/dist/{subagent-stop-H25B3QEC.js.map → subagent-stop-56H22JSE.js.map} +0 -0
  177. /package/dist/{task-completed-2JGZN2CF.js.map → task-completed-TQ4WW2HW.js.map} +0 -0
  178. /package/dist/{team-TG5WZXWO.js.map → team-RXYFXGUT.js.map} +0 -0
  179. /package/dist/{update-EG3N2EXI.js.map → update-HIJUK5ZK.js.map} +0 -0
  180. /package/dist/{user-prompt-submit-7FFQ3ORA.js.map → user-prompt-submit-SLQNTQFL.js.map} +0 -0
  181. /package/dist/{verify-2M3DYHEY.js.map → verify-ITBMLK67.js.map} +0 -0
@@ -1,11 +1,18 @@
1
1
  import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
2
+ import {
3
+ getSpore,
4
+ listSporeIdsSince
5
+ } from "./chunk-IRSNOBGD.js";
6
+ import {
7
+ getSession
8
+ } from "./chunk-SGYYOTNM.js";
2
9
  import {
3
10
  getTeamMachineId,
4
11
  syncRow
5
- } from "./chunk-LF5Z62X6.js";
12
+ } from "./chunk-4JVHWBZF.js";
6
13
  import {
7
14
  loadConfig
8
- } from "./chunk-4BQ5QE76.js";
15
+ } from "./chunk-XAXQ72L3.js";
9
16
  import {
10
17
  getDatabase
11
18
  } from "./chunk-MYX5NCRH.js";
@@ -19,7 +26,7 @@ import {
19
26
  GRAPH_EDGE_DEFAULT_CONFIDENCE,
20
27
  QUERY_DEFAULT_LIST_LIMIT,
21
28
  epochSeconds
22
- } from "./chunk-TRA3R4EC.js";
29
+ } from "./chunk-34NHDRWI.js";
23
30
 
24
31
  // src/utils/error-message.ts
25
32
  function errorMessage(err) {
@@ -32,461 +39,198 @@ function errorMessage(err) {
32
39
  }
33
40
  }
34
41
 
35
- // src/db/queries/runs.ts
36
- var DEFAULT_LIST_LIMIT2 = 100;
37
- var DEFAULT_STATUS = "pending";
38
- var STATUS_RUNNING = "running";
39
- var STATUS_COMPLETED = "completed";
40
- var STATUS_FAILED = "failed";
41
- var RUN_COLUMNS = [
42
+ // src/db/queries/skill-candidates.ts
43
+ var DEFAULT_CONFIDENCE = 0;
44
+ var DEFAULT_STATUS = "identified";
45
+ var CANDIDATE_COLUMNS = [
42
46
  "id",
43
47
  "agent_id",
44
- "task",
45
- "instruction",
48
+ "machine_id",
49
+ "topic",
50
+ "rationale",
51
+ "confidence",
46
52
  "status",
47
- "started_at",
48
- "completed_at",
49
- "tokens_used",
50
- "cost_usd",
51
- "actions_taken",
52
- "error"
53
+ "source_ids",
54
+ "skill_id",
55
+ "approved_at",
56
+ "created_at",
57
+ "updated_at",
58
+ "synced_at"
53
59
  ];
54
- var SELECT_COLUMNS = RUN_COLUMNS.join(", ");
55
- function toRunRow(row) {
60
+ var SELECT_COLUMNS = CANDIDATE_COLUMNS.join(", ");
61
+ function toCandidateRow(row) {
56
62
  return {
57
63
  id: row.id,
58
64
  agent_id: row.agent_id,
59
- task: row.task ?? null,
60
- instruction: row.instruction ?? null,
65
+ machine_id: row.machine_id ?? getTeamMachineId(),
66
+ topic: row.topic,
67
+ rationale: row.rationale,
68
+ confidence: row.confidence,
61
69
  status: row.status,
62
- started_at: row.started_at ?? null,
63
- completed_at: row.completed_at ?? null,
64
- tokens_used: row.tokens_used ?? null,
65
- cost_usd: row.cost_usd ?? null,
66
- actions_taken: row.actions_taken ?? null,
67
- error: row.error ?? null
70
+ source_ids: row.source_ids ?? "[]",
71
+ skill_id: row.skill_id ?? null,
72
+ approved_at: row.approved_at ?? null,
73
+ created_at: row.created_at,
74
+ updated_at: row.updated_at,
75
+ synced_at: row.synced_at ?? null
68
76
  };
69
77
  }
70
- function insertRun(data) {
78
+ function buildWhere(options) {
79
+ const conditions = [];
80
+ const params = [];
81
+ if (options.agent_id !== void 0) {
82
+ conditions.push(`agent_id = ?`);
83
+ params.push(options.agent_id);
84
+ }
85
+ if (options.statuses !== void 0 && options.statuses.length > 0) {
86
+ const placeholders = options.statuses.map(() => "?").join(", ");
87
+ conditions.push(`status IN (${placeholders})`);
88
+ params.push(...options.statuses);
89
+ } else if (options.status !== void 0) {
90
+ conditions.push(`status = ?`);
91
+ params.push(options.status);
92
+ }
93
+ return {
94
+ where: conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "",
95
+ params
96
+ };
97
+ }
98
+ function insertCandidate(data) {
71
99
  const db = getDatabase();
72
100
  db.prepare(
73
- `INSERT INTO agent_runs (
74
- id, agent_id, task, instruction, status,
75
- started_at, completed_at, tokens_used, cost_usd,
76
- actions_taken, error
101
+ `INSERT INTO skill_candidates (
102
+ id, agent_id, machine_id, topic, rationale,
103
+ confidence, status, source_ids, skill_id, approved_at,
104
+ created_at, updated_at
77
105
  ) VALUES (
78
106
  ?, ?, ?, ?, ?,
79
- ?, ?, ?, ?,
107
+ ?, ?, ?, ?, ?,
80
108
  ?, ?
81
109
  )`
82
110
  ).run(
83
111
  data.id,
84
112
  data.agent_id,
85
- data.task ?? null,
86
- data.instruction ?? null,
113
+ data.machine_id ?? getTeamMachineId(),
114
+ data.topic,
115
+ data.rationale,
116
+ data.confidence ?? DEFAULT_CONFIDENCE,
87
117
  data.status ?? DEFAULT_STATUS,
88
- data.started_at ?? null,
89
- data.completed_at ?? null,
90
- data.tokens_used ?? null,
91
- data.cost_usd ?? null,
92
- data.actions_taken ?? null,
93
- data.error ?? null
94
- );
95
- return toRunRow(
96
- db.prepare(`SELECT ${SELECT_COLUMNS} FROM agent_runs WHERE id = ?`).get(data.id)
118
+ data.source_ids ?? "[]",
119
+ data.skill_id ?? null,
120
+ data.approved_at ?? null,
121
+ data.created_at,
122
+ data.updated_at
97
123
  );
124
+ const raw = db.prepare(`SELECT ${SELECT_COLUMNS} FROM skill_candidates WHERE id = ?`).get(data.id);
125
+ if (!raw) throw new Error(`Failed to insert skill candidate: ${data.id}`);
126
+ const row = toCandidateRow(raw);
127
+ syncRow("skill_candidates", row);
128
+ return row;
98
129
  }
99
- function getRun(id) {
130
+ function getCandidate(id) {
100
131
  const db = getDatabase();
101
132
  const row = db.prepare(
102
- `SELECT ${SELECT_COLUMNS} FROM agent_runs WHERE id = ?`
133
+ `SELECT ${SELECT_COLUMNS} FROM skill_candidates WHERE id = ?`
103
134
  ).get(id);
104
135
  if (!row) return null;
105
- return toRunRow(row);
106
- }
107
- function buildRunsWhere(options) {
108
- const conditions = [];
109
- const params = [];
110
- if (options.agent_id !== void 0) {
111
- conditions.push(`agent_id = ?`);
112
- params.push(options.agent_id);
113
- }
114
- if (options.status !== void 0) {
115
- conditions.push(`status = ?`);
116
- params.push(options.status);
117
- }
118
- if (options.task !== void 0) {
119
- conditions.push(`task = ?`);
120
- params.push(options.task);
121
- }
122
- if (options.search !== void 0 && options.search.length > 0) {
123
- conditions.push(`task LIKE ?`);
124
- params.push(`%${options.search}%`);
125
- }
126
- return {
127
- where: conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "",
128
- params
129
- };
136
+ return toCandidateRow(row);
130
137
  }
131
- function listRuns(options = {}) {
138
+ function listCandidates(options = {}) {
132
139
  const db = getDatabase();
133
- const { where, params } = buildRunsWhere(options);
134
- const limit = options.limit ?? DEFAULT_LIST_LIMIT2;
140
+ const { where, params } = buildWhere(options);
141
+ const limit = options.limit ?? DEFAULT_LIST_LIMIT;
135
142
  const offset = options.offset ?? 0;
136
143
  const rows = db.prepare(
137
144
  `SELECT ${SELECT_COLUMNS}
138
- FROM agent_runs
145
+ FROM skill_candidates
139
146
  ${where}
140
- ORDER BY started_at DESC NULLS LAST
147
+ ORDER BY confidence DESC, created_at DESC
141
148
  LIMIT ?
142
149
  OFFSET ?`
143
150
  ).all(...params, limit, offset);
144
- return rows.map(toRunRow);
145
- }
146
- function countRuns(options = {}) {
147
- const db = getDatabase();
148
- const { where, params } = buildRunsWhere(options);
149
- const row = db.prepare(
150
- `SELECT COUNT(*) as count FROM agent_runs ${where}`
151
- ).get(...params);
152
- return row.count;
151
+ return rows.map(toCandidateRow);
153
152
  }
154
- function updateRunStatus(id, status, completion) {
153
+ function updateCandidate(id, updates) {
155
154
  const db = getDatabase();
156
- const setClauses = ["status = ?"];
157
- const params = [status];
158
- if (completion?.completed_at !== void 0) {
159
- setClauses.push(`completed_at = ?`);
160
- params.push(completion.completed_at);
161
- }
162
- if (completion?.tokens_used !== void 0) {
163
- setClauses.push(`tokens_used = ?`);
164
- params.push(completion.tokens_used);
165
- }
166
- if (completion?.cost_usd !== void 0) {
167
- setClauses.push(`cost_usd = ?`);
168
- params.push(completion.cost_usd);
169
- }
170
- if (completion?.actions_taken !== void 0) {
171
- setClauses.push(`actions_taken = ?`);
172
- params.push(completion.actions_taken);
155
+ let autoApprovedAt;
156
+ if (updates.status === "approved" && updates.approved_at === void 0) {
157
+ const existing = getCandidate(id);
158
+ if (existing && existing.approved_at === null) {
159
+ autoApprovedAt = updates.updated_at;
160
+ }
173
161
  }
174
- if (completion?.error !== void 0) {
175
- setClauses.push(`error = ?`);
176
- params.push(completion.error);
162
+ const fieldMap = {
163
+ topic: "topic",
164
+ rationale: "rationale",
165
+ confidence: "confidence",
166
+ status: "status",
167
+ source_ids: "source_ids",
168
+ skill_id: "skill_id",
169
+ approved_at: "approved_at",
170
+ updated_at: "updated_at"
171
+ };
172
+ const setClauses = [];
173
+ const params = [];
174
+ const updateValues = updates;
175
+ for (const [key, column] of Object.entries(fieldMap)) {
176
+ if (key in updates) {
177
+ setClauses.push(`${column} = ?`);
178
+ params.push(updateValues[key] ?? null);
179
+ } else if (key === "approved_at" && autoApprovedAt !== void 0) {
180
+ setClauses.push(`${column} = ?`);
181
+ params.push(autoApprovedAt);
182
+ }
177
183
  }
184
+ if (setClauses.length === 0) return getCandidate(id);
178
185
  params.push(id);
179
- const info = db.prepare(
180
- `UPDATE agent_runs
186
+ db.prepare(
187
+ `UPDATE skill_candidates
181
188
  SET ${setClauses.join(", ")}
182
189
  WHERE id = ?`
183
190
  ).run(...params);
184
- if (info.changes === 0) return null;
185
- return toRunRow(
186
- db.prepare(`SELECT ${SELECT_COLUMNS} FROM agent_runs WHERE id = ?`).get(id)
187
- );
191
+ const updated = getCandidate(id);
192
+ if (updated) syncRow("skill_candidates", updated);
193
+ return updated;
188
194
  }
189
- function getRunningRunForTask(agentId, taskName) {
195
+ function listCandidatesWithCount(options = {}) {
190
196
  const db = getDatabase();
191
- const row = db.prepare(
192
- `SELECT id FROM agent_runs
193
- WHERE agent_id = ? AND task = ? AND status = ?
194
- LIMIT 1`
195
- ).get(agentId, taskName, STATUS_RUNNING);
196
- return row?.id ?? null;
197
+ const { where, params } = buildWhere(options);
198
+ const limit = options.limit ?? DEFAULT_LIST_LIMIT;
199
+ const offset = options.offset ?? 0;
200
+ const rows = db.prepare(
201
+ `SELECT ${SELECT_COLUMNS}, COUNT(*) OVER () AS __total
202
+ FROM skill_candidates
203
+ ${where}
204
+ ORDER BY confidence DESC, created_at DESC
205
+ LIMIT ?
206
+ OFFSET ?`
207
+ ).all(...params, limit, offset);
208
+ if (rows.length === 0) {
209
+ return { items: [], total: countCandidates(options) };
210
+ }
211
+ const total = Number(rows[0].__total);
212
+ const items = rows.map((row) => {
213
+ const { __total: _drop, ...rest } = row;
214
+ return toCandidateRow(rest);
215
+ });
216
+ return { items, total };
197
217
  }
198
- function getLatestRunId(agentId, taskName) {
218
+ function countCandidates(options = {}) {
199
219
  const db = getDatabase();
200
- if (taskName) {
201
- const row2 = db.prepare(
202
- `SELECT id FROM agent_runs
203
- WHERE agent_id = ? AND task = ?
204
- ORDER BY started_at DESC
205
- LIMIT 1`
206
- ).get(agentId, taskName);
207
- return row2?.id ?? null;
208
- }
220
+ const { where, params } = buildWhere(options);
209
221
  const row = db.prepare(
210
- `SELECT id FROM agent_runs
211
- WHERE agent_id = ?
212
- ORDER BY started_at DESC
213
- LIMIT 1`
214
- ).get(agentId);
215
- return row?.id ?? null;
222
+ `SELECT COUNT(*) as count FROM skill_candidates ${where}`
223
+ ).get(...params);
224
+ return row.count;
216
225
  }
217
-
218
- // src/db/queries/notifications.ts
219
- var DEFAULT_LIMIT = 50;
220
- var NOTIFICATION_PRUNE_AGE_SECONDS = 30 * 24 * 60 * 60;
221
- function insertNotification(n) {
226
+ function deleteCandidate(id) {
222
227
  const db = getDatabase();
223
- db.prepare(
224
- `INSERT INTO notifications (id, domain, type, level, title, message, mode, status, link, metadata, created_at)
225
- VALUES (?, ?, ?, ?, ?, ?, ?, 'unread', ?, ?, ?)`
226
- ).run(n.id, n.domain, n.type, n.level, n.title, n.message, n.mode, n.link, n.metadata, epochSeconds());
227
- }
228
- function listNotifications(opts = {}) {
229
- const db = getDatabase();
230
- const conditions = [];
231
- const params = [];
232
- if (opts.status) {
233
- conditions.push("status = ?");
234
- params.push(opts.status);
235
- }
236
- if (opts.domain) {
237
- conditions.push("domain = ?");
238
- params.push(opts.domain);
239
- }
240
- if (opts.mode) {
241
- conditions.push("mode = ?");
242
- params.push(opts.mode);
243
- }
244
- const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
245
- const limit = opts.limit ?? DEFAULT_LIMIT;
246
- const offset = opts.offset ?? 0;
247
- return db.prepare(
248
- `SELECT * FROM notifications ${where} ORDER BY created_at DESC LIMIT ? OFFSET ?`
249
- ).all(...params, limit, offset);
250
- }
251
- function countNotifications(status) {
252
- const db = getDatabase();
253
- if (status) {
254
- const row2 = db.prepare("SELECT COUNT(*) as count FROM notifications WHERE status = ?").get(status);
255
- return row2.count;
256
- }
257
- const row = db.prepare("SELECT COUNT(*) as count FROM notifications").get();
258
- return row.count;
259
- }
260
- function getNotification(id) {
261
- const db = getDatabase();
262
- return db.prepare("SELECT * FROM notifications WHERE id = ?").get(id);
263
- }
264
- function updateNotificationStatus(id, status) {
265
- const db = getDatabase();
266
- const result = db.prepare("UPDATE notifications SET status = ? WHERE id = ?").run(status, id);
267
- return result.changes > 0;
268
- }
269
- function dismissAllNotifications(domain) {
270
- const db = getDatabase();
271
- if (domain) {
272
- const result2 = db.prepare("UPDATE notifications SET status = 'dismissed' WHERE domain = ? AND status != 'dismissed'").run(domain);
273
- return result2.changes;
274
- }
275
- const result = db.prepare("UPDATE notifications SET status = 'dismissed' WHERE status != 'dismissed'").run();
276
- return result.changes;
277
- }
278
- function markAllRead(domain) {
279
- const db = getDatabase();
280
- if (domain) {
281
- const result2 = db.prepare("UPDATE notifications SET status = 'read' WHERE domain = ? AND status = 'unread'").run(domain);
282
- return result2.changes;
283
- }
284
- const result = db.prepare("UPDATE notifications SET status = 'read' WHERE status = 'unread'").run();
285
- return result.changes;
286
- }
287
-
288
- // src/notifications/registry.ts
289
- var domains = /* @__PURE__ */ new Map();
290
- function register(descriptor) {
291
- domains.set(descriptor.domain, descriptor);
292
- }
293
- function getAllDomains() {
294
- return [...domains.values()].sort((a, b) => a.domain.localeCompare(b.domain));
295
- }
296
- function getType(typeId) {
297
- for (const descriptor of domains.values()) {
298
- const match = descriptor.types.find((t) => t.id === typeId);
299
- if (match) return { domain: descriptor, type: match };
300
- }
301
- return void 0;
302
- }
303
-
304
- // src/notifications/notify.ts
305
- import crypto from "crypto";
306
- function notify(vaultDir, payload, config) {
307
- if (!vaultDir) return null;
308
- try {
309
- const cfg = config ?? loadConfig(vaultDir);
310
- if (!cfg.notifications.enabled) return null;
311
- const domainConfig = cfg.notifications.domains[payload.domain];
312
- if (domainConfig && !domainConfig.enabled) return null;
313
- const registeredType = getType(payload.type);
314
- const mode = payload.mode ?? domainConfig?.mode ?? registeredType?.type.defaultMode ?? cfg.notifications.default_mode;
315
- const level = payload.level ?? registeredType?.type.defaultLevel ?? "info";
316
- const id = crypto.randomUUID();
317
- insertNotification({
318
- id,
319
- domain: payload.domain,
320
- type: payload.type,
321
- level,
322
- title: payload.title,
323
- message: payload.message ?? null,
324
- mode,
325
- link: payload.link ?? null,
326
- metadata: payload.metadata ? JSON.stringify(payload.metadata) : null
327
- });
328
- return id;
329
- } catch (err) {
330
- console.warn("[notify] Failed to emit notification:", err instanceof Error ? err.message : err);
331
- return null;
332
- }
333
- }
334
-
335
- // src/db/queries/skill-candidates.ts
336
- var DEFAULT_CONFIDENCE = 0;
337
- var DEFAULT_STATUS2 = "identified";
338
- var CANDIDATE_COLUMNS = [
339
- "id",
340
- "agent_id",
341
- "machine_id",
342
- "topic",
343
- "rationale",
344
- "confidence",
345
- "status",
346
- "source_ids",
347
- "skill_id",
348
- "created_at",
349
- "updated_at",
350
- "synced_at"
351
- ];
352
- var SELECT_COLUMNS2 = CANDIDATE_COLUMNS.join(", ");
353
- function toCandidateRow(row) {
354
- return {
355
- id: row.id,
356
- agent_id: row.agent_id,
357
- machine_id: row.machine_id ?? getTeamMachineId(),
358
- topic: row.topic,
359
- rationale: row.rationale,
360
- confidence: row.confidence,
361
- status: row.status,
362
- source_ids: row.source_ids ?? "[]",
363
- skill_id: row.skill_id ?? null,
364
- created_at: row.created_at,
365
- updated_at: row.updated_at,
366
- synced_at: row.synced_at ?? null
367
- };
368
- }
369
- function buildWhere(options) {
370
- const conditions = [];
371
- const params = [];
372
- if (options.agent_id !== void 0) {
373
- conditions.push(`agent_id = ?`);
374
- params.push(options.agent_id);
375
- }
376
- if (options.status !== void 0) {
377
- conditions.push(`status = ?`);
378
- params.push(options.status);
379
- }
380
- return {
381
- where: conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "",
382
- params
383
- };
384
- }
385
- function insertCandidate(data) {
386
- const db = getDatabase();
387
- db.prepare(
388
- `INSERT INTO skill_candidates (
389
- id, agent_id, machine_id, topic, rationale,
390
- confidence, status, source_ids, skill_id,
391
- created_at, updated_at
392
- ) VALUES (
393
- ?, ?, ?, ?, ?,
394
- ?, ?, ?, ?,
395
- ?, ?
396
- )`
397
- ).run(
398
- data.id,
399
- data.agent_id,
400
- data.machine_id ?? getTeamMachineId(),
401
- data.topic,
402
- data.rationale,
403
- data.confidence ?? DEFAULT_CONFIDENCE,
404
- data.status ?? DEFAULT_STATUS2,
405
- data.source_ids ?? "[]",
406
- data.skill_id ?? null,
407
- data.created_at,
408
- data.updated_at
409
- );
410
- const raw = db.prepare(`SELECT ${SELECT_COLUMNS2} FROM skill_candidates WHERE id = ?`).get(data.id);
411
- if (!raw) throw new Error(`Failed to insert skill candidate: ${data.id}`);
412
- const row = toCandidateRow(raw);
413
- syncRow("skill_candidates", row);
414
- return row;
415
- }
416
- function getCandidate(id) {
417
- const db = getDatabase();
418
- const row = db.prepare(
419
- `SELECT ${SELECT_COLUMNS2} FROM skill_candidates WHERE id = ?`
420
- ).get(id);
421
- if (!row) return null;
422
- return toCandidateRow(row);
423
- }
424
- function listCandidates(options = {}) {
425
- const db = getDatabase();
426
- const { where, params } = buildWhere(options);
427
- const limit = options.limit ?? DEFAULT_LIST_LIMIT;
428
- const offset = options.offset ?? 0;
429
- const rows = db.prepare(
430
- `SELECT ${SELECT_COLUMNS2}
431
- FROM skill_candidates
432
- ${where}
433
- ORDER BY confidence DESC, created_at DESC
434
- LIMIT ?
435
- OFFSET ?`
436
- ).all(...params, limit, offset);
437
- return rows.map(toCandidateRow);
438
- }
439
- function updateCandidate(id, updates) {
440
- const db = getDatabase();
441
- const setClauses = [];
442
- const params = [];
443
- const fieldMap = {
444
- topic: "topic",
445
- rationale: "rationale",
446
- confidence: "confidence",
447
- status: "status",
448
- source_ids: "source_ids",
449
- skill_id: "skill_id",
450
- updated_at: "updated_at"
451
- };
452
- for (const [key, column] of Object.entries(fieldMap)) {
453
- if (key in updates) {
454
- setClauses.push(`${column} = ?`);
455
- params.push(updates[key] ?? null);
456
- }
457
- }
458
- if (setClauses.length === 0) return getCandidate(id);
459
- params.push(id);
460
- db.prepare(
461
- `UPDATE skill_candidates
462
- SET ${setClauses.join(", ")}
463
- WHERE id = ?`
464
- ).run(...params);
465
- const updated = getCandidate(id);
466
- if (updated) syncRow("skill_candidates", updated);
467
- return updated;
468
- }
469
- function listCandidatesWithCount(options = {}) {
470
- const items = listCandidates(options);
471
- const total = countCandidates(options);
472
- return { items, total };
473
- }
474
- function countCandidates(options = {}) {
475
- const db = getDatabase();
476
- const { where, params } = buildWhere(options);
477
- const row = db.prepare(
478
- `SELECT COUNT(*) as count FROM skill_candidates ${where}`
479
- ).get(...params);
480
- return row.count;
481
- }
482
- function deleteCandidate(id) {
483
- const db = getDatabase();
484
- const info = db.prepare("DELETE FROM skill_candidates WHERE id = ?").run(id);
485
- return info.changes > 0;
228
+ const info = db.prepare("DELETE FROM skill_candidates WHERE id = ?").run(id);
229
+ return info.changes > 0;
486
230
  }
487
231
 
488
232
  // src/db/queries/skill-records.ts
489
- var DEFAULT_STATUS3 = "active";
233
+ var DEFAULT_STATUS2 = "active";
490
234
  var DEFAULT_GENERATION = 1;
491
235
  var RECORD_COLUMNS = [
492
236
  "id",
@@ -507,7 +251,7 @@ var RECORD_COLUMNS = [
507
251
  "properties",
508
252
  "synced_at"
509
253
  ];
510
- var SELECT_COLUMNS3 = RECORD_COLUMNS.join(", ");
254
+ var SELECT_COLUMNS2 = RECORD_COLUMNS.join(", ");
511
255
  function toSkillRecordRow(row) {
512
256
  return {
513
257
  id: row.id,
@@ -564,7 +308,7 @@ function insertSkillRecord(data) {
564
308
  data.name,
565
309
  data.display_name,
566
310
  data.description,
567
- data.status ?? DEFAULT_STATUS3,
311
+ data.status ?? DEFAULT_STATUS2,
568
312
  data.generation ?? DEFAULT_GENERATION,
569
313
  data.candidate_id ?? null,
570
314
  data.source_ids ?? "[]",
@@ -573,7 +317,7 @@ function insertSkillRecord(data) {
573
317
  data.updated_at,
574
318
  data.properties ?? "{}"
575
319
  );
576
- const raw = db.prepare(`SELECT ${SELECT_COLUMNS3} FROM skill_records WHERE id = ?`).get(data.id);
320
+ const raw = db.prepare(`SELECT ${SELECT_COLUMNS2} FROM skill_records WHERE id = ?`).get(data.id);
577
321
  if (!raw) throw new Error(`Failed to insert skill record: ${data.id}`);
578
322
  const row = toSkillRecordRow(raw);
579
323
  syncRow("skill_records", row);
@@ -582,7 +326,7 @@ function insertSkillRecord(data) {
582
326
  function getSkillRecord(id) {
583
327
  const db = getDatabase();
584
328
  const row = db.prepare(
585
- `SELECT ${SELECT_COLUMNS3} FROM skill_records WHERE id = ?`
329
+ `SELECT ${SELECT_COLUMNS2} FROM skill_records WHERE id = ?`
586
330
  ).get(id);
587
331
  if (!row) return null;
588
332
  return toSkillRecordRow(row);
@@ -590,7 +334,7 @@ function getSkillRecord(id) {
590
334
  function getSkillRecordByName(name) {
591
335
  const db = getDatabase();
592
336
  const row = db.prepare(
593
- `SELECT ${SELECT_COLUMNS3} FROM skill_records WHERE name = ?`
337
+ `SELECT ${SELECT_COLUMNS2} FROM skill_records WHERE name = ?`
594
338
  ).get(name);
595
339
  if (!row) return null;
596
340
  return toSkillRecordRow(row);
@@ -601,7 +345,7 @@ function listSkillRecords(options = {}) {
601
345
  const limit = options.limit ?? DEFAULT_LIST_LIMIT;
602
346
  const offset = options.offset ?? 0;
603
347
  const rows = db.prepare(
604
- `SELECT ${SELECT_COLUMNS3}
348
+ `SELECT ${SELECT_COLUMNS2}
605
349
  FROM skill_records
606
350
  ${where}
607
351
  ORDER BY updated_at DESC
@@ -693,7 +437,7 @@ var LINEAGE_COLUMNS = [
693
437
  "content_snapshot",
694
438
  "created_at"
695
439
  ];
696
- var SELECT_COLUMNS4 = LINEAGE_COLUMNS.join(", ");
440
+ var SELECT_COLUMNS3 = LINEAGE_COLUMNS.join(", ");
697
441
  function toLineageRow(row) {
698
442
  return {
699
443
  id: row.id,
@@ -727,13 +471,13 @@ function insertLineage(data) {
727
471
  data.created_at
728
472
  );
729
473
  return toLineageRow(
730
- db.prepare(`SELECT ${SELECT_COLUMNS4} FROM skill_lineage WHERE id = ?`).get(data.id)
474
+ db.prepare(`SELECT ${SELECT_COLUMNS3} FROM skill_lineage WHERE id = ?`).get(data.id)
731
475
  );
732
476
  }
733
477
  function listLineageForSkill(skillId, limit = 50) {
734
478
  const db = getDatabase();
735
479
  const rows = db.prepare(
736
- `SELECT ${SELECT_COLUMNS4}
480
+ `SELECT ${SELECT_COLUMNS3}
737
481
  FROM skill_lineage
738
482
  WHERE skill_id = ?
739
483
  ORDER BY generation DESC
@@ -742,6 +486,424 @@ function listLineageForSkill(skillId, limit = 50) {
742
486
  return rows.map(toLineageRow);
743
487
  }
744
488
 
489
+ // src/agent/instruction-builders.ts
490
+ var SKILL_GENERATE_TASK = "skill-generate";
491
+ var SKILL_EVOLVE_TASK = "skill-evolve";
492
+ function buildSkillGenerateInstruction() {
493
+ const candidates = listCandidates({ status: "approved", limit: 1 });
494
+ if (candidates.length === 0) return void 0;
495
+ const c = candidates[0];
496
+ const parts = [
497
+ `candidate_id: ${c.id}`,
498
+ `topic: ${c.topic}`,
499
+ `confidence: ${c.confidence}`,
500
+ `rationale: ${c.rationale}`,
501
+ "",
502
+ "## Source Material"
503
+ ];
504
+ let sourceIds = [];
505
+ try {
506
+ sourceIds = JSON.parse(c.source_ids || "[]");
507
+ } catch {
508
+ }
509
+ for (const src of sourceIds) {
510
+ if (src.type === "spore") {
511
+ const spore = getSpore(src.id);
512
+ if (spore) {
513
+ parts.push(`
514
+ ### Spore: ${src.id} (${spore.observation_type}, importance ${spore.importance})`);
515
+ parts.push(spore.content);
516
+ if (spore.context) parts.push(`Context: ${spore.context}`);
517
+ if (spore.tags) parts.push(`Tags: ${spore.tags}`);
518
+ }
519
+ } else if (src.type === "session") {
520
+ const session = getSession(src.id);
521
+ if (session) {
522
+ parts.push(`
523
+ ### Session: ${src.id}`);
524
+ if (session.title) parts.push(`Title: ${session.title}`);
525
+ if (session.summary) parts.push(session.summary);
526
+ }
527
+ }
528
+ }
529
+ return {
530
+ instruction: parts.join("\n"),
531
+ context: { candidate_id: c.id }
532
+ };
533
+ }
534
+ var SKILL_EVOLVE_DEFAULT_ASSESS_INTERVAL_HOURS = 24;
535
+ var SKILL_EVOLVE_DEFAULT_MAX_SKILLS_PER_RUN = 5;
536
+ function buildSkillEvolveInstruction(params) {
537
+ const assessIntervalHours = Number(params?.assess_interval_hours ?? SKILL_EVOLVE_DEFAULT_ASSESS_INTERVAL_HOURS);
538
+ const maxSkillsPerRun = Number(params?.max_skills_per_run ?? SKILL_EVOLVE_DEFAULT_MAX_SKILLS_PER_RUN);
539
+ const now = epochSeconds();
540
+ const intervalSeconds = assessIntervalHours * 3600;
541
+ const allSkills = listSkillRecords({ status: "active", limit: 100 });
542
+ const needsAssessment = [];
543
+ for (const skill of allSkills) {
544
+ let props = {};
545
+ try {
546
+ props = JSON.parse(skill.properties || "{}");
547
+ } catch {
548
+ props = {};
549
+ }
550
+ const lastAssessedAt = typeof props.last_assessed_at === "number" ? props.last_assessed_at : 0;
551
+ const knowledgeWatermark = typeof props.knowledge_watermark === "number" ? props.knowledge_watermark : 0;
552
+ if (lastAssessedAt > 0 && now - lastAssessedAt < intervalSeconds) continue;
553
+ const newSporeIds = listSporeIdsSince(knowledgeWatermark, 10);
554
+ if (newSporeIds.length === 0) continue;
555
+ const lineage = listLineageForSkill(skill.id, 1);
556
+ if (lineage.length === 0) continue;
557
+ needsAssessment.push({
558
+ id: skill.id,
559
+ name: skill.name,
560
+ generation: skill.generation,
561
+ description: skill.description,
562
+ contentSnapshot: lineage[0].content_snapshot,
563
+ newSporeIds
564
+ });
565
+ if (needsAssessment.length >= maxSkillsPerRun) {
566
+ break;
567
+ }
568
+ }
569
+ if (needsAssessment.length === 0) {
570
+ return "No skills need assessment. All active skills are current or were recently assessed. Report skip via vault_report and finish.";
571
+ }
572
+ const parts = [
573
+ `${needsAssessment.length} skill(s) need assessment.`,
574
+ `assess_interval_hours: ${assessIntervalHours}`,
575
+ `max_skills_per_run: ${maxSkillsPerRun}`
576
+ ];
577
+ for (const skill of needsAssessment) {
578
+ parts.push("");
579
+ parts.push("---");
580
+ parts.push(`## Skill: ${skill.name} (gen ${skill.generation})`);
581
+ parts.push(`id: ${skill.id}`);
582
+ parts.push(`description: ${skill.description}`);
583
+ parts.push(`new_spore_ids: ${JSON.stringify(skill.newSporeIds)}`);
584
+ parts.push("");
585
+ parts.push("### Current Content");
586
+ parts.push("");
587
+ parts.push(skill.contentSnapshot);
588
+ }
589
+ return parts.join("\n");
590
+ }
591
+ function buildTaskInstruction(taskName, taskParams) {
592
+ switch (taskName) {
593
+ case SKILL_GENERATE_TASK:
594
+ return buildSkillGenerateInstruction();
595
+ case SKILL_EVOLVE_TASK: {
596
+ const instruction = buildSkillEvolveInstruction(taskParams);
597
+ return instruction ? { instruction } : void 0;
598
+ }
599
+ default:
600
+ return void 0;
601
+ }
602
+ }
603
+ function isInstructionRequiredTask(taskName) {
604
+ return taskName === SKILL_GENERATE_TASK || taskName === SKILL_EVOLVE_TASK;
605
+ }
606
+
607
+ // src/db/queries/runs.ts
608
+ var DEFAULT_LIST_LIMIT2 = 100;
609
+ var DEFAULT_STATUS3 = "pending";
610
+ var STATUS_RUNNING = "running";
611
+ var STATUS_COMPLETED = "completed";
612
+ var STATUS_FAILED = "failed";
613
+ var RUN_COLUMNS = [
614
+ "id",
615
+ "agent_id",
616
+ "task",
617
+ "instruction",
618
+ "status",
619
+ "started_at",
620
+ "completed_at",
621
+ "tokens_used",
622
+ "cost_usd",
623
+ "actions_taken",
624
+ "error"
625
+ ];
626
+ var SELECT_COLUMNS4 = RUN_COLUMNS.join(", ");
627
+ function toRunRow(row) {
628
+ return {
629
+ id: row.id,
630
+ agent_id: row.agent_id,
631
+ task: row.task ?? null,
632
+ instruction: row.instruction ?? null,
633
+ status: row.status,
634
+ started_at: row.started_at ?? null,
635
+ completed_at: row.completed_at ?? null,
636
+ tokens_used: row.tokens_used ?? null,
637
+ cost_usd: row.cost_usd ?? null,
638
+ actions_taken: row.actions_taken ?? null,
639
+ error: row.error ?? null
640
+ };
641
+ }
642
+ function insertRun(data) {
643
+ const db = getDatabase();
644
+ db.prepare(
645
+ `INSERT INTO agent_runs (
646
+ id, agent_id, task, instruction, status,
647
+ started_at, completed_at, tokens_used, cost_usd,
648
+ actions_taken, error
649
+ ) VALUES (
650
+ ?, ?, ?, ?, ?,
651
+ ?, ?, ?, ?,
652
+ ?, ?
653
+ )`
654
+ ).run(
655
+ data.id,
656
+ data.agent_id,
657
+ data.task ?? null,
658
+ data.instruction ?? null,
659
+ data.status ?? DEFAULT_STATUS3,
660
+ data.started_at ?? null,
661
+ data.completed_at ?? null,
662
+ data.tokens_used ?? null,
663
+ data.cost_usd ?? null,
664
+ data.actions_taken ?? null,
665
+ data.error ?? null
666
+ );
667
+ return toRunRow(
668
+ db.prepare(`SELECT ${SELECT_COLUMNS4} FROM agent_runs WHERE id = ?`).get(data.id)
669
+ );
670
+ }
671
+ function getRun(id) {
672
+ const db = getDatabase();
673
+ const row = db.prepare(
674
+ `SELECT ${SELECT_COLUMNS4} FROM agent_runs WHERE id = ?`
675
+ ).get(id);
676
+ if (!row) return null;
677
+ return toRunRow(row);
678
+ }
679
+ function buildRunsWhere(options) {
680
+ const conditions = [];
681
+ const params = [];
682
+ if (options.agent_id !== void 0) {
683
+ conditions.push(`agent_id = ?`);
684
+ params.push(options.agent_id);
685
+ }
686
+ if (options.status !== void 0) {
687
+ conditions.push(`status = ?`);
688
+ params.push(options.status);
689
+ }
690
+ if (options.task !== void 0) {
691
+ conditions.push(`task = ?`);
692
+ params.push(options.task);
693
+ }
694
+ if (options.search !== void 0 && options.search.length > 0) {
695
+ conditions.push(`task LIKE ?`);
696
+ params.push(`%${options.search}%`);
697
+ }
698
+ return {
699
+ where: conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "",
700
+ params
701
+ };
702
+ }
703
+ function listRuns(options = {}) {
704
+ const db = getDatabase();
705
+ const { where, params } = buildRunsWhere(options);
706
+ const limit = options.limit ?? DEFAULT_LIST_LIMIT2;
707
+ const offset = options.offset ?? 0;
708
+ const rows = db.prepare(
709
+ `SELECT ${SELECT_COLUMNS4}
710
+ FROM agent_runs
711
+ ${where}
712
+ ORDER BY started_at DESC NULLS LAST
713
+ LIMIT ?
714
+ OFFSET ?`
715
+ ).all(...params, limit, offset);
716
+ return rows.map(toRunRow);
717
+ }
718
+ function countRuns(options = {}) {
719
+ const db = getDatabase();
720
+ const { where, params } = buildRunsWhere(options);
721
+ const row = db.prepare(
722
+ `SELECT COUNT(*) as count FROM agent_runs ${where}`
723
+ ).get(...params);
724
+ return row.count;
725
+ }
726
+ function updateRunStatus(id, status, completion) {
727
+ const db = getDatabase();
728
+ const setClauses = ["status = ?"];
729
+ const params = [status];
730
+ if (completion?.completed_at !== void 0) {
731
+ setClauses.push(`completed_at = ?`);
732
+ params.push(completion.completed_at);
733
+ }
734
+ if (completion?.tokens_used !== void 0) {
735
+ setClauses.push(`tokens_used = ?`);
736
+ params.push(completion.tokens_used);
737
+ }
738
+ if (completion?.cost_usd !== void 0) {
739
+ setClauses.push(`cost_usd = ?`);
740
+ params.push(completion.cost_usd);
741
+ }
742
+ if (completion?.actions_taken !== void 0) {
743
+ setClauses.push(`actions_taken = ?`);
744
+ params.push(completion.actions_taken);
745
+ }
746
+ if (completion?.error !== void 0) {
747
+ setClauses.push(`error = ?`);
748
+ params.push(completion.error);
749
+ }
750
+ params.push(id);
751
+ const info = db.prepare(
752
+ `UPDATE agent_runs
753
+ SET ${setClauses.join(", ")}
754
+ WHERE id = ?`
755
+ ).run(...params);
756
+ if (info.changes === 0) return null;
757
+ return toRunRow(
758
+ db.prepare(`SELECT ${SELECT_COLUMNS4} FROM agent_runs WHERE id = ?`).get(id)
759
+ );
760
+ }
761
+ function getRunningRunForTask(agentId, taskName) {
762
+ const db = getDatabase();
763
+ const row = db.prepare(
764
+ `SELECT id FROM agent_runs
765
+ WHERE agent_id = ? AND task = ? AND status = ?
766
+ LIMIT 1`
767
+ ).get(agentId, taskName, STATUS_RUNNING);
768
+ return row?.id ?? null;
769
+ }
770
+ function getLatestRunId(agentId, taskName) {
771
+ const db = getDatabase();
772
+ if (taskName) {
773
+ const row2 = db.prepare(
774
+ `SELECT id FROM agent_runs
775
+ WHERE agent_id = ? AND task = ?
776
+ ORDER BY started_at DESC
777
+ LIMIT 1`
778
+ ).get(agentId, taskName);
779
+ return row2?.id ?? null;
780
+ }
781
+ const row = db.prepare(
782
+ `SELECT id FROM agent_runs
783
+ WHERE agent_id = ?
784
+ ORDER BY started_at DESC
785
+ LIMIT 1`
786
+ ).get(agentId);
787
+ return row?.id ?? null;
788
+ }
789
+
790
+ // src/db/queries/notifications.ts
791
+ var DEFAULT_LIMIT = 50;
792
+ var NOTIFICATION_PRUNE_AGE_SECONDS = 30 * 24 * 60 * 60;
793
+ function insertNotification(n) {
794
+ const db = getDatabase();
795
+ db.prepare(
796
+ `INSERT INTO notifications (id, domain, type, level, title, message, mode, status, link, metadata, created_at)
797
+ VALUES (?, ?, ?, ?, ?, ?, ?, 'unread', ?, ?, ?)`
798
+ ).run(n.id, n.domain, n.type, n.level, n.title, n.message, n.mode, n.link, n.metadata, epochSeconds());
799
+ }
800
+ function listNotifications(opts = {}) {
801
+ const db = getDatabase();
802
+ const conditions = [];
803
+ const params = [];
804
+ if (opts.status) {
805
+ conditions.push("status = ?");
806
+ params.push(opts.status);
807
+ }
808
+ if (opts.domain) {
809
+ conditions.push("domain = ?");
810
+ params.push(opts.domain);
811
+ }
812
+ if (opts.mode) {
813
+ conditions.push("mode = ?");
814
+ params.push(opts.mode);
815
+ }
816
+ const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
817
+ const limit = opts.limit ?? DEFAULT_LIMIT;
818
+ const offset = opts.offset ?? 0;
819
+ return db.prepare(
820
+ `SELECT * FROM notifications ${where} ORDER BY created_at DESC LIMIT ? OFFSET ?`
821
+ ).all(...params, limit, offset);
822
+ }
823
+ function countNotifications(status) {
824
+ const db = getDatabase();
825
+ if (status) {
826
+ const row2 = db.prepare("SELECT COUNT(*) as count FROM notifications WHERE status = ?").get(status);
827
+ return row2.count;
828
+ }
829
+ const row = db.prepare("SELECT COUNT(*) as count FROM notifications").get();
830
+ return row.count;
831
+ }
832
+ function getNotification(id) {
833
+ const db = getDatabase();
834
+ return db.prepare("SELECT * FROM notifications WHERE id = ?").get(id);
835
+ }
836
+ function updateNotificationStatus(id, status) {
837
+ const db = getDatabase();
838
+ const result = db.prepare("UPDATE notifications SET status = ? WHERE id = ?").run(status, id);
839
+ return result.changes > 0;
840
+ }
841
+ function dismissAllNotifications(domain) {
842
+ const db = getDatabase();
843
+ if (domain) {
844
+ const result2 = db.prepare("UPDATE notifications SET status = 'dismissed' WHERE domain = ? AND status != 'dismissed'").run(domain);
845
+ return result2.changes;
846
+ }
847
+ const result = db.prepare("UPDATE notifications SET status = 'dismissed' WHERE status != 'dismissed'").run();
848
+ return result.changes;
849
+ }
850
+ function markAllRead(domain) {
851
+ const db = getDatabase();
852
+ if (domain) {
853
+ const result2 = db.prepare("UPDATE notifications SET status = 'read' WHERE domain = ? AND status = 'unread'").run(domain);
854
+ return result2.changes;
855
+ }
856
+ const result = db.prepare("UPDATE notifications SET status = 'read' WHERE status = 'unread'").run();
857
+ return result.changes;
858
+ }
859
+
860
+ // src/notifications/registry.ts
861
+ var domains = /* @__PURE__ */ new Map();
862
+ function register(descriptor) {
863
+ domains.set(descriptor.domain, descriptor);
864
+ }
865
+ function getAllDomains() {
866
+ return [...domains.values()].sort((a, b) => a.domain.localeCompare(b.domain));
867
+ }
868
+ function getType(typeId) {
869
+ for (const descriptor of domains.values()) {
870
+ const match = descriptor.types.find((t) => t.id === typeId);
871
+ if (match) return { domain: descriptor, type: match };
872
+ }
873
+ return void 0;
874
+ }
875
+
876
+ // src/notifications/notify.ts
877
+ import crypto from "crypto";
878
+ function notify(vaultDir, payload, config) {
879
+ if (!vaultDir) return null;
880
+ try {
881
+ const cfg = config ?? loadConfig(vaultDir);
882
+ if (!cfg.notifications.enabled) return null;
883
+ const domainConfig = cfg.notifications.domains[payload.domain];
884
+ if (domainConfig && !domainConfig.enabled) return null;
885
+ const registeredType = getType(payload.type);
886
+ const mode = payload.mode ?? domainConfig?.mode ?? registeredType?.type.defaultMode ?? cfg.notifications.default_mode;
887
+ const level = payload.level ?? registeredType?.type.defaultLevel ?? "info";
888
+ const id = crypto.randomUUID();
889
+ insertNotification({
890
+ id,
891
+ domain: payload.domain,
892
+ type: payload.type,
893
+ level,
894
+ title: payload.title,
895
+ message: payload.message ?? null,
896
+ mode,
897
+ link: payload.link ?? null,
898
+ metadata: payload.metadata ? JSON.stringify(payload.metadata) : null
899
+ });
900
+ return id;
901
+ } catch (err) {
902
+ console.warn("[notify] Failed to emit notification:", err instanceof Error ? err.message : err);
903
+ return null;
904
+ }
905
+ }
906
+
745
907
  // src/db/queries/batches.ts
746
908
  var DEFAULT_UNPROCESSED_LIMIT = 100;
747
909
  var BATCHES_DEFAULT_LIMIT = 200;
@@ -1399,6 +1561,9 @@ export {
1399
1561
  getDigestExtract,
1400
1562
  listDigestExtracts,
1401
1563
  errorMessage,
1564
+ SKILL_GENERATE_TASK,
1565
+ buildTaskInstruction,
1566
+ isInstructionRequiredTask,
1402
1567
  STATUS_RUNNING,
1403
1568
  STATUS_COMPLETED,
1404
1569
  STATUS_FAILED,
@@ -1414,4 +1579,4 @@ export {
1414
1579
  insertReport,
1415
1580
  listReports
1416
1581
  };
1417
- //# sourceMappingURL=chunk-75J2BR4P.js.map
1582
+ //# sourceMappingURL=chunk-D63XTGBV.js.map