@goondocks/myco 0.12.10 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. package/README.md +6 -0
  2. package/dist/{agent-run-GUHXRNZB.js → agent-run-3WLMSLMJ.js} +8 -7
  3. package/dist/{agent-run-GUHXRNZB.js.map → agent-run-3WLMSLMJ.js.map} +1 -1
  4. package/dist/{agent-tasks-GWZI5WSB.js → agent-tasks-BQE2GEVS.js} +8 -7
  5. package/dist/{agent-tasks-GWZI5WSB.js.map → agent-tasks-BQE2GEVS.js.map} +1 -1
  6. package/dist/{chunk-PW5QVY44.js → chunk-4VF6KQ2Z.js} +371 -6
  7. package/dist/chunk-4VF6KQ2Z.js.map +1 -0
  8. package/dist/{chunk-QL2RBFIC.js → chunk-5YQ6VOFZ.js} +2 -2
  9. package/dist/{chunk-MCARJFBA.js → chunk-745SWTQX.js} +4 -4
  10. package/dist/{chunk-D4M2AV65.js → chunk-DTE3SHYK.js} +46 -3
  11. package/dist/chunk-DTE3SHYK.js.map +1 -0
  12. package/dist/{chunk-HLGPGHT7.js → chunk-EVPG26CR.js} +3 -3
  13. package/dist/{chunk-YRUJ5KGV.js → chunk-GDCSPMH4.js} +3 -3
  14. package/dist/{chunk-LUQBT2Y4.js → chunk-HHZ3RTEI.js} +2 -2
  15. package/dist/{chunk-TCGOSLW6.js → chunk-JJXVDCEX.js} +613 -98
  16. package/dist/chunk-JJXVDCEX.js.map +1 -0
  17. package/dist/{chunk-D4ESHOOJ.js → chunk-KNTJOMWY.js} +3 -3
  18. package/dist/{chunk-JHLALJPB.js → chunk-LD6U3L6O.js} +8 -8
  19. package/dist/{chunk-7NBDELZB.js → chunk-NVCGF2DS.js} +26 -8
  20. package/dist/{chunk-7NBDELZB.js.map → chunk-NVCGF2DS.js.map} +1 -1
  21. package/dist/{chunk-SW62AX75.js → chunk-OKCSSDFC.js} +2 -2
  22. package/dist/{chunk-RR75ZKEV.js → chunk-OQVKLTQY.js} +4 -4
  23. package/dist/{chunk-OAGY5APE.js → chunk-PSYLKCWQ.js} +83 -7
  24. package/dist/chunk-PSYLKCWQ.js.map +1 -0
  25. package/dist/{chunk-Q2AYS2QE.js → chunk-PX5KIOKY.js} +5 -7
  26. package/dist/chunk-PX5KIOKY.js.map +1 -0
  27. package/dist/chunk-QLCD77AN.js +93 -0
  28. package/dist/chunk-QLCD77AN.js.map +1 -0
  29. package/dist/{chunk-J3L2RTYK.js → chunk-RBFECYNA.js} +2 -2
  30. package/dist/{chunk-4VSNNMEU.js → chunk-S66YG6QK.js} +26 -3
  31. package/dist/{chunk-4VSNNMEU.js.map → chunk-S66YG6QK.js.map} +1 -1
  32. package/dist/chunk-SBVDG5JP.js +112 -0
  33. package/dist/chunk-SBVDG5JP.js.map +1 -0
  34. package/dist/{chunk-M5XWW7UI.js → chunk-SODRR3HE.js} +8 -1
  35. package/dist/chunk-SODRR3HE.js.map +1 -0
  36. package/dist/{chunk-SFC4GXEN.js → chunk-TNCBMGWB.js} +39 -104
  37. package/dist/chunk-TNCBMGWB.js.map +1 -0
  38. package/dist/{chunk-PIRWYDOH.js → chunk-TRA3R4EC.js} +7 -1
  39. package/dist/chunk-TRA3R4EC.js.map +1 -0
  40. package/dist/{chunk-LGPBVBFY.js → chunk-TVV6PZOC.js} +5 -7
  41. package/dist/chunk-TVV6PZOC.js.map +1 -0
  42. package/dist/{chunk-SVQAPEYH.js → chunk-UWXJCLCK.js} +22 -5
  43. package/dist/chunk-UWXJCLCK.js.map +1 -0
  44. package/dist/{chunk-JROOQQH6.js → chunk-X34OFKYU.js} +12 -7
  45. package/dist/chunk-X34OFKYU.js.map +1 -0
  46. package/dist/{chunk-FYGFMIS6.js → chunk-ZKXW46HZ.js} +2 -2
  47. package/dist/{cli-CFOIDXOY.js → cli-SKCINMJI.js} +41 -40
  48. package/dist/{cli-CFOIDXOY.js.map → cli-SKCINMJI.js.map} +1 -1
  49. package/dist/{client-ZBCGODTS.js → client-KZGZHHXT.js} +5 -5
  50. package/dist/{config-6RQ7FAEV.js → config-H657SF6B.js} +5 -3
  51. package/dist/{config-6RQ7FAEV.js.map → config-H657SF6B.js.map} +1 -1
  52. package/dist/{detect-providers-JFE3QLJI.js → detect-providers-PAVE2X6O.js} +4 -4
  53. package/dist/{doctor-W3I7RVU4.js → doctor-6FKSHJRU.js} +13 -11
  54. package/dist/{doctor-W3I7RVU4.js.map → doctor-6FKSHJRU.js.map} +1 -1
  55. package/dist/{executor-LKDWMGC7.js → executor-W5MKZH7B.js} +407 -46
  56. package/dist/executor-W5MKZH7B.js.map +1 -0
  57. package/dist/{init-M3HYJGHE.js → init-5QHCXBLF.js} +16 -15
  58. package/dist/{init-M3HYJGHE.js.map → init-5QHCXBLF.js.map} +1 -1
  59. package/dist/{init-wizard-C4WQA47U.js → init-wizard-HEY4HMG3.js} +12 -12
  60. package/dist/installer-25TSX4SR.js +13 -0
  61. package/dist/{llm-O46QYWEM.js → llm-T3QVHC3Y.js} +7 -7
  62. package/dist/{loader-4FMGOVWF.js → loader-JQLO6K44.js} +4 -2
  63. package/dist/{loader-BQ4X4K3F.js → loader-WQKVWL5D.js} +4 -4
  64. package/dist/{main-CMWNMCW2.js → main-IZ277SHB.js} +689 -124
  65. package/dist/main-IZ277SHB.js.map +1 -0
  66. package/dist/{open-4N7T37XV.js → open-S7YUWON4.js} +8 -7
  67. package/dist/{open-4N7T37XV.js.map → open-S7YUWON4.js.map} +1 -1
  68. package/dist/{openai-embeddings-HWAKOGUM.js → openai-embeddings-5T5ZP7LO.js} +4 -4
  69. package/dist/{openrouter-GXZK7JXR.js → openrouter-RD2COFC7.js} +4 -4
  70. package/dist/{post-compact-BPICHUPV.js → post-compact-EFKFT7TM.js} +7 -7
  71. package/dist/{post-tool-use-OHJ2EH7I.js → post-tool-use-624YC6ZH.js} +7 -7
  72. package/dist/{post-tool-use-failure-CBPY2TSN.js → post-tool-use-failure-QCHZAWQH.js} +7 -7
  73. package/dist/{pre-compact-ULAA4XIB.js → pre-compact-7DWH2EM3.js} +7 -7
  74. package/dist/{provider-check-CKZW3GQX.js → provider-check-QN7OGXZA.js} +4 -4
  75. package/dist/{registry-ZHUVXGPO.js → registry-2XQMCPA6.js} +5 -5
  76. package/dist/{remove-52PTVOCJ.js → remove-ESVIET5C.js} +10 -8
  77. package/dist/{remove-52PTVOCJ.js.map → remove-ESVIET5C.js.map} +1 -1
  78. package/dist/{resolution-events-WZHPQQMN.js → resolution-events-5EVUEWHS.js} +4 -4
  79. package/dist/{restart-O37BUPLH.js → restart-AZHV6OKM.js} +9 -8
  80. package/dist/{restart-O37BUPLH.js.map → restart-AZHV6OKM.js.map} +1 -1
  81. package/dist/{search-52YK2ZWU.js → search-JS4HXYGS.js} +9 -8
  82. package/dist/{search-52YK2ZWU.js.map → search-JS4HXYGS.js.map} +1 -1
  83. package/dist/{server-7OKRAJCM.js → server-KT5GW333.js} +115 -14
  84. package/dist/server-KT5GW333.js.map +1 -0
  85. package/dist/{session-57IAZYRK.js → session-JSI67FEM.js} +10 -9
  86. package/dist/{session-57IAZYRK.js.map → session-JSI67FEM.js.map} +1 -1
  87. package/dist/{session-end-WRKDJEWM.js → session-end-4CM462MC.js} +6 -6
  88. package/dist/{session-start-7VWGEVOX.js → session-start-ZGF7F6DE.js} +12 -12
  89. package/dist/{setup-llm-IDQPX22O.js → setup-llm-S2UYJYIS.js} +10 -9
  90. package/dist/{setup-llm-IDQPX22O.js.map → setup-llm-S2UYJYIS.js.map} +1 -1
  91. package/dist/src/agent/definitions/agent.yaml +2 -0
  92. package/dist/src/agent/definitions/tasks/digest-only.yaml +1 -0
  93. package/dist/src/agent/definitions/tasks/extract-only.yaml +1 -0
  94. package/dist/src/agent/definitions/tasks/full-intelligence.yaml +8 -0
  95. package/dist/src/agent/definitions/tasks/graph-maintenance.yaml +1 -0
  96. package/dist/src/agent/definitions/tasks/review-session.yaml +1 -0
  97. package/dist/src/agent/definitions/tasks/skill-evolve.yaml +155 -0
  98. package/dist/src/agent/definitions/tasks/skill-generate.yaml +210 -0
  99. package/dist/src/agent/definitions/tasks/skill-survey.yaml +149 -0
  100. package/dist/src/agent/definitions/tasks/supersession-sweep.yaml +1 -0
  101. package/dist/src/agent/definitions/tasks/title-summary.yaml +1 -0
  102. package/dist/src/agent/prompts/agent.md +29 -0
  103. package/dist/src/cli.js +1 -1
  104. package/dist/src/daemon/main.js +1 -1
  105. package/dist/src/hooks/post-tool-use.js +1 -1
  106. package/dist/src/hooks/session-end.js +1 -1
  107. package/dist/src/hooks/session-start.js +1 -1
  108. package/dist/src/hooks/stop.js +1 -1
  109. package/dist/src/hooks/user-prompt-submit.js +1 -1
  110. package/dist/src/mcp/server.js +1 -1
  111. package/dist/src/worker/src/index.ts +3 -0
  112. package/dist/src/worker/src/schema.ts +56 -0
  113. package/dist/{stats-D7U5HQ3L.js → stats-D2FM6ZXO.js} +10 -9
  114. package/dist/{stats-D7U5HQ3L.js.map → stats-D2FM6ZXO.js.map} +1 -1
  115. package/dist/{stop-VJU4AAOQ.js → stop-DQEKVNST.js} +6 -6
  116. package/dist/{stop-failure-ILPHO26U.js → stop-failure-EHH7AN5E.js} +7 -7
  117. package/dist/{subagent-start-77MY4UMP.js → subagent-start-6R52PAFA.js} +7 -7
  118. package/dist/{subagent-stop-DABERMXZ.js → subagent-stop-CLDFJKYQ.js} +7 -7
  119. package/dist/{task-completed-TBWBOAJ6.js → task-completed-V47JA3OV.js} +7 -7
  120. package/dist/{team-K6H4B3ZD.js → team-SJPDXELY.js} +45 -19
  121. package/dist/team-SJPDXELY.js.map +1 -0
  122. package/dist/turns-3ZQAF6HF.js +16 -0
  123. package/dist/turns-3ZQAF6HF.js.map +1 -0
  124. package/dist/ui/assets/index-BmsHIwjl.css +1 -0
  125. package/dist/ui/assets/index-Cn6cQwJy.js +842 -0
  126. package/dist/ui/index.html +2 -2
  127. package/dist/{update-GW774ZMW.js → update-ZNIYDQHJ.js} +8 -7
  128. package/dist/{update-GW774ZMW.js.map → update-ZNIYDQHJ.js.map} +1 -1
  129. package/dist/{user-prompt-submit-C47Y5Y5I.js → user-prompt-submit-6TX6VECI.js} +6 -6
  130. package/dist/{verify-MQAANTUR.js → verify-JHIMXTY5.js} +8 -8
  131. package/dist/{version-42DQW43N.js → version-UMEN7OJU.js} +2 -2
  132. package/dist/version-UMEN7OJU.js.map +1 -0
  133. package/package.json +6 -6
  134. package/dist/chunk-D4M2AV65.js.map +0 -1
  135. package/dist/chunk-JROOQQH6.js.map +0 -1
  136. package/dist/chunk-LGPBVBFY.js.map +0 -1
  137. package/dist/chunk-M5XWW7UI.js.map +0 -1
  138. package/dist/chunk-OAGY5APE.js.map +0 -1
  139. package/dist/chunk-PIRWYDOH.js.map +0 -1
  140. package/dist/chunk-PW5QVY44.js.map +0 -1
  141. package/dist/chunk-Q2AYS2QE.js.map +0 -1
  142. package/dist/chunk-SFC4GXEN.js.map +0 -1
  143. package/dist/chunk-SVQAPEYH.js.map +0 -1
  144. package/dist/chunk-TCGOSLW6.js.map +0 -1
  145. package/dist/executor-LKDWMGC7.js.map +0 -1
  146. package/dist/main-CMWNMCW2.js.map +0 -1
  147. package/dist/server-7OKRAJCM.js.map +0 -1
  148. package/dist/team-K6H4B3ZD.js.map +0 -1
  149. package/dist/ui/assets/index-BGbil7f1.css +0 -1
  150. package/dist/ui/assets/index-ZSGlKT25.js +0 -804
  151. /package/dist/{chunk-QL2RBFIC.js.map → chunk-5YQ6VOFZ.js.map} +0 -0
  152. /package/dist/{chunk-MCARJFBA.js.map → chunk-745SWTQX.js.map} +0 -0
  153. /package/dist/{chunk-HLGPGHT7.js.map → chunk-EVPG26CR.js.map} +0 -0
  154. /package/dist/{chunk-YRUJ5KGV.js.map → chunk-GDCSPMH4.js.map} +0 -0
  155. /package/dist/{chunk-LUQBT2Y4.js.map → chunk-HHZ3RTEI.js.map} +0 -0
  156. /package/dist/{chunk-D4ESHOOJ.js.map → chunk-KNTJOMWY.js.map} +0 -0
  157. /package/dist/{chunk-JHLALJPB.js.map → chunk-LD6U3L6O.js.map} +0 -0
  158. /package/dist/{chunk-SW62AX75.js.map → chunk-OKCSSDFC.js.map} +0 -0
  159. /package/dist/{chunk-RR75ZKEV.js.map → chunk-OQVKLTQY.js.map} +0 -0
  160. /package/dist/{chunk-J3L2RTYK.js.map → chunk-RBFECYNA.js.map} +0 -0
  161. /package/dist/{chunk-FYGFMIS6.js.map → chunk-ZKXW46HZ.js.map} +0 -0
  162. /package/dist/{client-ZBCGODTS.js.map → client-KZGZHHXT.js.map} +0 -0
  163. /package/dist/{detect-providers-JFE3QLJI.js.map → detect-providers-PAVE2X6O.js.map} +0 -0
  164. /package/dist/{init-wizard-C4WQA47U.js.map → init-wizard-HEY4HMG3.js.map} +0 -0
  165. /package/dist/{llm-O46QYWEM.js.map → installer-25TSX4SR.js.map} +0 -0
  166. /package/dist/{loader-4FMGOVWF.js.map → llm-T3QVHC3Y.js.map} +0 -0
  167. /package/dist/{loader-BQ4X4K3F.js.map → loader-JQLO6K44.js.map} +0 -0
  168. /package/dist/{openai-embeddings-HWAKOGUM.js.map → loader-WQKVWL5D.js.map} +0 -0
  169. /package/dist/{openrouter-GXZK7JXR.js.map → openai-embeddings-5T5ZP7LO.js.map} +0 -0
  170. /package/dist/{provider-check-CKZW3GQX.js.map → openrouter-RD2COFC7.js.map} +0 -0
  171. /package/dist/{post-compact-BPICHUPV.js.map → post-compact-EFKFT7TM.js.map} +0 -0
  172. /package/dist/{post-tool-use-OHJ2EH7I.js.map → post-tool-use-624YC6ZH.js.map} +0 -0
  173. /package/dist/{post-tool-use-failure-CBPY2TSN.js.map → post-tool-use-failure-QCHZAWQH.js.map} +0 -0
  174. /package/dist/{pre-compact-ULAA4XIB.js.map → pre-compact-7DWH2EM3.js.map} +0 -0
  175. /package/dist/{registry-ZHUVXGPO.js.map → provider-check-QN7OGXZA.js.map} +0 -0
  176. /package/dist/{resolution-events-WZHPQQMN.js.map → registry-2XQMCPA6.js.map} +0 -0
  177. /package/dist/{version-42DQW43N.js.map → resolution-events-5EVUEWHS.js.map} +0 -0
  178. /package/dist/{session-end-WRKDJEWM.js.map → session-end-4CM462MC.js.map} +0 -0
  179. /package/dist/{session-start-7VWGEVOX.js.map → session-start-ZGF7F6DE.js.map} +0 -0
  180. /package/dist/{stop-VJU4AAOQ.js.map → stop-DQEKVNST.js.map} +0 -0
  181. /package/dist/{stop-failure-ILPHO26U.js.map → stop-failure-EHH7AN5E.js.map} +0 -0
  182. /package/dist/{subagent-start-77MY4UMP.js.map → subagent-start-6R52PAFA.js.map} +0 -0
  183. /package/dist/{subagent-stop-DABERMXZ.js.map → subagent-stop-CLDFJKYQ.js.map} +0 -0
  184. /package/dist/{task-completed-TBWBOAJ6.js.map → task-completed-V47JA3OV.js.map} +0 -0
  185. /package/dist/{user-prompt-submit-C47Y5Y5I.js.map → user-prompt-submit-6TX6VECI.js.map} +0 -0
  186. /package/dist/{verify-MQAANTUR.js.map → verify-JHIMXTY5.js.map} +0 -0
@@ -3,119 +3,151 @@ import {
3
3
  DaemonLogger,
4
4
  LEVEL_ORDER
5
5
  } from "./chunk-ZESTWGJT.js";
6
- import {
7
- withTaskConfig
8
- } from "./chunk-M5XWW7UI.js";
9
- import {
10
- EMBEDDABLE_TABLES,
11
- EMBEDDABLE_TEXT_COLUMNS,
12
- assertValidTable,
13
- clearEmbedded,
14
- gatherStats,
15
- getEmbeddingQueueDepth,
16
- getUnembedded,
17
- markEmbedded
18
- } from "./chunk-MCARJFBA.js";
19
- import {
20
- getMachineId
21
- } from "./chunk-ENWBFX7F.js";
22
- import {
23
- createEmbeddingProvider
24
- } from "./chunk-JHLALJPB.js";
25
6
  import {
26
7
  closeOpenBatches,
8
+ countBatchesBySession,
9
+ countCandidates,
10
+ countNotifications,
27
11
  countRuns,
12
+ countSkillRecords,
28
13
  createBatchLineage,
14
+ deleteCandidate,
15
+ deleteSkillRecordCascade,
16
+ dismissAllNotifications,
29
17
  errorMessage,
30
18
  findBatchByPromptPrefix,
19
+ getAllDomains,
20
+ getCandidate,
31
21
  getDigestExtract,
32
22
  getEntity,
33
23
  getGraphForNode,
34
24
  getLatestBatch,
25
+ getLatestRunId,
26
+ getNotification,
35
27
  getRun,
36
- getRunningRun,
28
+ getSkillRecord,
29
+ getSkillRecordByName,
37
30
  incrementActivityCount,
31
+ incrementSkillUsageCount,
38
32
  insertBatchStateless,
39
33
  listBatchesBySession,
34
+ listCandidates,
35
+ listCandidatesWithCount,
40
36
  listDigestExtracts,
41
37
  listEntities,
38
+ listLineageForSkill,
39
+ listNotifications,
42
40
  listReports,
43
41
  listRuns,
44
- listTurnsByRun,
42
+ listSkillRecords,
43
+ listSkillRecordsWithCount,
44
+ markAllRead,
45
+ notify,
45
46
  populateBatchResponses,
46
- setResponseSummary
47
- } from "./chunk-TCGOSLW6.js";
47
+ register,
48
+ setResponseSummary,
49
+ updateCandidate,
50
+ updateNotificationStatus
51
+ } from "./chunk-JJXVDCEX.js";
48
52
  import {
49
53
  fullTextSearch,
50
54
  hydrateSearchResults
51
- } from "./chunk-D4M2AV65.js";
55
+ } from "./chunk-DTE3SHYK.js";
56
+ import {
57
+ withTaskConfig
58
+ } from "./chunk-SODRR3HE.js";
59
+ import {
60
+ EMBEDDABLE_TABLES,
61
+ EMBEDDABLE_TEXT_COLUMNS,
62
+ assertValidTable,
63
+ clearEmbedded,
64
+ gatherStats,
65
+ getEmbeddingQueueDepth,
66
+ getUnembedded,
67
+ markEmbedded
68
+ } from "./chunk-745SWTQX.js";
69
+ import {
70
+ getMachineId
71
+ } from "./chunk-ENWBFX7F.js";
72
+ import {
73
+ createEmbeddingProvider
74
+ } from "./chunk-LD6U3L6O.js";
52
75
  import {
53
76
  copyTaskToUser,
54
77
  deleteUserTask,
55
78
  loadAllTasks,
56
79
  validateTaskName,
57
80
  writeUserTask
58
- } from "./chunk-D4ESHOOJ.js";
81
+ } from "./chunk-KNTJOMWY.js";
59
82
  import {
60
83
  AgentTaskSchema,
61
84
  registerAgent,
62
85
  resolveDefinitionsDir,
63
86
  taskFromParsed
64
- } from "./chunk-7NBDELZB.js";
87
+ } from "./chunk-NVCGF2DS.js";
88
+ import {
89
+ listTurnsByRun
90
+ } from "./chunk-QLCD77AN.js";
91
+ import {
92
+ loadSecrets,
93
+ readSecrets,
94
+ writeSecret
95
+ } from "./chunk-RJMXDUMA.js";
96
+ import "./chunk-SBVDG5JP.js";
97
+ import "./chunk-SAKJMNSR.js";
65
98
  import {
66
99
  checkLocalProvider
67
- } from "./chunk-YRUJ5KGV.js";
100
+ } from "./chunk-GDCSPMH4.js";
68
101
  import {
69
102
  EventBuffer,
70
103
  cleanStaleBuffers,
71
104
  listBufferSessionIds
72
105
  } from "./chunk-V7XG6V6C.js";
73
106
  import "./chunk-IB76KGBY.js";
74
- import "./chunk-J3L2RTYK.js";
75
- import "./chunk-SW62AX75.js";
76
- import "./chunk-QL2RBFIC.js";
77
- import {
78
- loadSecrets,
79
- readSecrets,
80
- writeSecret
81
- } from "./chunk-RJMXDUMA.js";
82
- import "./chunk-SFC4GXEN.js";
83
- import "./chunk-SAKJMNSR.js";
107
+ import "./chunk-TNCBMGWB.js";
84
108
  import {
85
109
  LmStudioBackend,
86
110
  OllamaBackend
87
- } from "./chunk-LUQBT2Y4.js";
111
+ } from "./chunk-HHZ3RTEI.js";
112
+ import "./chunk-RBFECYNA.js";
113
+ import "./chunk-OKCSSDFC.js";
114
+ import "./chunk-5YQ6VOFZ.js";
88
115
  import {
89
116
  countSpores,
90
117
  getSpore,
91
118
  insertSpore,
92
119
  listSpores,
93
120
  updateSporeStatus
94
- } from "./chunk-Q2AYS2QE.js";
121
+ } from "./chunk-PX5KIOKY.js";
95
122
  import {
96
123
  closeSession,
97
124
  countSessions,
98
125
  deleteSessionCascade,
99
126
  getSession,
100
127
  getSessionImpact,
128
+ incrementSessionToolCount,
101
129
  listSessions,
102
130
  updateSession,
103
131
  upsertSession
104
- } from "./chunk-JROOQQH6.js";
132
+ } from "./chunk-X34OFKYU.js";
105
133
  import {
106
134
  backfillUnsynced,
107
135
  countPending,
136
+ enqueueOutbox,
137
+ getTeamMachineId,
108
138
  initTeamContext,
139
+ isTeamSyncEnabled,
109
140
  listPending,
110
141
  markSent,
142
+ markSourceRowsSynced,
111
143
  pruneOld,
112
144
  syncRow
113
- } from "./chunk-4VSNNMEU.js";
145
+ } from "./chunk-S66YG6QK.js";
114
146
  import {
115
147
  EMBEDDING_DIMENSIONS,
116
148
  SCHEMA_VERSION,
117
149
  createSchema
118
- } from "./chunk-PW5QVY44.js";
150
+ } from "./chunk-4VF6KQ2Z.js";
119
151
  import {
120
152
  CONFIG_FILENAME,
121
153
  MycoConfigSchema,
@@ -123,7 +155,7 @@ import {
123
155
  updateBackupConfig,
124
156
  updateConfig,
125
157
  updateTeamConfig
126
- } from "./chunk-OAGY5APE.js";
158
+ } from "./chunk-PSYLKCWQ.js";
127
159
  import {
128
160
  closeDatabase,
129
161
  getDatabase,
@@ -132,14 +164,23 @@ import {
132
164
  } from "./chunk-MYX5NCRH.js";
133
165
  import {
134
166
  resolveCliEntryPath
135
- } from "./chunk-SVQAPEYH.js";
167
+ } from "./chunk-UWXJCLCK.js";
168
+ import {
169
+ getPluginVersion
170
+ } from "./chunk-ZKXW46HZ.js";
171
+ import {
172
+ loadManifests
173
+ } from "./chunk-QFMBZ72S.js";
174
+ import {
175
+ findPackageRoot
176
+ } from "./chunk-LPUQPDC2.js";
136
177
  import {
137
178
  CONTENT_HASH_ALGORITHM,
138
179
  DAEMON_EVICT_POLL_MS,
139
180
  DAEMON_EVICT_TIMEOUT_MS,
140
181
  DEAD_SESSION_MAX_PROMPTS,
141
182
  DEFAULT_AGENT_ID,
142
- DEFAULT_MACHINE_ID,
183
+ DEFAULT_LIST_LIMIT,
143
184
  DEFAULT_RELEASE_CHANNEL,
144
185
  EMBEDDING_BATCH_SIZE,
145
186
  EXCLUDED_SPORE_STATUSES,
@@ -184,20 +225,11 @@ import {
184
225
  USER_TASK_SOURCE,
185
226
  epochSeconds,
186
227
  estimateTokens
187
- } from "./chunk-PIRWYDOH.js";
228
+ } from "./chunk-TRA3R4EC.js";
188
229
  import {
189
230
  LOG_KINDS,
190
231
  kindToComponent
191
232
  } from "./chunk-S6I62FAH.js";
192
- import {
193
- getPluginVersion
194
- } from "./chunk-FYGFMIS6.js";
195
- import {
196
- loadManifests
197
- } from "./chunk-QFMBZ72S.js";
198
- import {
199
- findPackageRoot
200
- } from "./chunk-LPUQPDC2.js";
201
233
  import {
202
234
  require_dist
203
235
  } from "./chunk-D7TYRPRM.js";
@@ -370,7 +402,7 @@ var DaemonServer = class {
370
402
  if (match) {
371
403
  this.onRequest?.();
372
404
  try {
373
- const body = req.method === "POST" || req.method === "PUT" ? await readBody(req) : void 0;
405
+ const body = req.method === "POST" || req.method === "PUT" || req.method === "PATCH" ? await readBody(req) : void 0;
374
406
  const result = await match.handler({
375
407
  body,
376
408
  query: match.query,
@@ -1238,7 +1270,7 @@ import os6 from "os";
1238
1270
  import path9 from "path";
1239
1271
 
1240
1272
  // src/db/queries/plans.ts
1241
- var DEFAULT_LIST_LIMIT = 100;
1273
+ var DEFAULT_LIST_LIMIT2 = 100;
1242
1274
  var DEFAULT_STATUS2 = "active";
1243
1275
  var DEFAULT_PROCESSED = 0;
1244
1276
  var PLAN_COLUMNS = [
@@ -1276,7 +1308,7 @@ function toPlanRow(row) {
1276
1308
  embedded: row.embedded ?? 0,
1277
1309
  created_at: row.created_at,
1278
1310
  updated_at: row.updated_at ?? null,
1279
- machine_id: row.machine_id ?? DEFAULT_MACHINE_ID,
1311
+ machine_id: row.machine_id ?? "local",
1280
1312
  synced_at: row.synced_at ?? null
1281
1313
  };
1282
1314
  }
@@ -1322,7 +1354,7 @@ function upsertPlan(data) {
1322
1354
  data.processed ?? DEFAULT_PROCESSED,
1323
1355
  data.created_at,
1324
1356
  data.updated_at ?? null,
1325
- data.machine_id ?? DEFAULT_MACHINE_ID
1357
+ data.machine_id ?? getTeamMachineId()
1326
1358
  );
1327
1359
  const row = toPlanRow(
1328
1360
  db.prepare(`SELECT ${SELECT_COLUMNS} FROM plans WHERE id = ?`).get(data.id)
@@ -1339,7 +1371,7 @@ function listPlans(options = {}) {
1339
1371
  params.push(options.status);
1340
1372
  }
1341
1373
  const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
1342
- const limit = options.limit ?? DEFAULT_LIST_LIMIT;
1374
+ const limit = options.limit ?? DEFAULT_LIST_LIMIT2;
1343
1375
  params.push(limit);
1344
1376
  const rows = db.prepare(
1345
1377
  `SELECT ${SELECT_COLUMNS}
@@ -1419,7 +1451,8 @@ function mergeConfigSections(current, incoming) {
1419
1451
  agent: { ...current.agent, ...incoming.agent },
1420
1452
  context: { ...current.context, ...incoming.context },
1421
1453
  backup: { ...current.backup, ...incoming.backup },
1422
- team: { ...current.team, ...incoming.team }
1454
+ team: { ...current.team, ...incoming.team },
1455
+ notifications: { ...current.notifications, ...incoming.notifications }
1423
1456
  };
1424
1457
  }
1425
1458
  async function handleGetConfig(vaultDir) {
@@ -2621,6 +2654,13 @@ function listActivitiesByBatch(batchId) {
2621
2654
  ).all(batchId);
2622
2655
  return rows.map(toActivityRow);
2623
2656
  }
2657
+ function countActivities(sessionId) {
2658
+ const db = getDatabase();
2659
+ const row = db.prepare(
2660
+ `SELECT COUNT(*) AS count FROM activities WHERE session_id = ?`
2661
+ ).get(sessionId);
2662
+ return row.count;
2663
+ }
2624
2664
 
2625
2665
  // src/db/queries/attachments.ts
2626
2666
  var ATTACHMENT_COLUMNS = [
@@ -2702,10 +2742,10 @@ function getAttachmentByFilePath(filePath) {
2702
2742
  }
2703
2743
 
2704
2744
  // src/daemon/api/sessions.ts
2705
- var DEFAULT_LIST_LIMIT2 = 50;
2745
+ var DEFAULT_LIST_LIMIT3 = 50;
2706
2746
  var DEFAULT_LIST_OFFSET = 0;
2707
2747
  async function handleListSessions(req) {
2708
- const limit = req.query.limit ? Number(req.query.limit) : DEFAULT_LIST_LIMIT2;
2748
+ const limit = req.query.limit ? Number(req.query.limit) : DEFAULT_LIST_LIMIT3;
2709
2749
  const offset = req.query.offset ? Number(req.query.offset) : DEFAULT_LIST_OFFSET;
2710
2750
  const status = req.query.status || void 0;
2711
2751
  const agent = req.query.agent || void 0;
@@ -2728,7 +2768,9 @@ async function handleListSessions(req) {
2728
2768
  async function handleGetSession(req) {
2729
2769
  const session = getSession(req.params.id);
2730
2770
  if (!session) return { status: 404, body: { error: "not_found" } };
2731
- return { body: session };
2771
+ const promptCount = countBatchesBySession(session.id);
2772
+ const toolCount = countActivities(session.id);
2773
+ return { body: { ...session, prompt_count: promptCount, tool_count: toolCount } };
2732
2774
  }
2733
2775
  async function handleGetSessionBatches(req) {
2734
2776
  const batches = listBatchesBySession(req.params.id);
@@ -2750,7 +2792,7 @@ async function handleGetSessionPlans(req) {
2750
2792
  }
2751
2793
 
2752
2794
  // src/daemon/api/mycelium.ts
2753
- var DEFAULT_LIST_LIMIT3 = 50;
2795
+ var DEFAULT_LIST_LIMIT4 = 50;
2754
2796
  var DEFAULT_LIST_OFFSET2 = 0;
2755
2797
  var DEFAULT_GRAPH_DEPTH = 1;
2756
2798
  var MAX_GRAPH_DEPTH = 3;
@@ -2760,7 +2802,7 @@ async function handleListSpores(req) {
2760
2802
  const agentId = req.query.agent_id;
2761
2803
  const type = req.query.type;
2762
2804
  const status = req.query.status;
2763
- const limit = req.query.limit ? Number(req.query.limit) : DEFAULT_LIST_LIMIT3;
2805
+ const limit = req.query.limit ? Number(req.query.limit) : DEFAULT_LIST_LIMIT4;
2764
2806
  const offset = req.query.offset ? Number(req.query.offset) : DEFAULT_LIST_OFFSET2;
2765
2807
  const search = req.query.search || void 0;
2766
2808
  const filterOpts = {
@@ -2783,7 +2825,7 @@ async function handleListEntities(req) {
2783
2825
  const type = req.query.type;
2784
2826
  const mentioned_in = req.query.mentioned_in;
2785
2827
  const note_type = req.query.note_type;
2786
- const limit = req.query.limit ? Number(req.query.limit) : DEFAULT_LIST_LIMIT3;
2828
+ const limit = req.query.limit ? Number(req.query.limit) : DEFAULT_LIST_LIMIT4;
2787
2829
  const offset = req.query.offset ? Number(req.query.offset) : DEFAULT_LIST_OFFSET2;
2788
2830
  const entities = listEntities({
2789
2831
  agent_id: agentId,
@@ -4114,6 +4156,142 @@ var SqliteRecordSource = class {
4114
4156
  }
4115
4157
  };
4116
4158
 
4159
+ // src/notifications/domains.ts
4160
+ function registerBuiltinDomains() {
4161
+ register({
4162
+ domain: "agents",
4163
+ label: "Agent Tasks",
4164
+ types: [
4165
+ { id: "agent.task.success", label: "Task completed", defaultMode: "banner", defaultLevel: "success" },
4166
+ { id: "agent.task.failure", label: "Task failed", defaultMode: "banner", defaultLevel: "error" }
4167
+ ]
4168
+ });
4169
+ register({
4170
+ domain: "sessions",
4171
+ label: "Sessions",
4172
+ types: [
4173
+ { id: "session.started", label: "Session started", defaultMode: "summary", defaultLevel: "info" },
4174
+ { id: "session.ended", label: "Session ended", defaultMode: "summary", defaultLevel: "info" }
4175
+ ]
4176
+ });
4177
+ register({
4178
+ domain: "skills",
4179
+ label: "Skills",
4180
+ types: [
4181
+ { id: "skill.surveyed", label: "Skill candidate surveyed", defaultMode: "summary", defaultLevel: "info" },
4182
+ { id: "skill.created", label: "Skill created", defaultMode: "banner", defaultLevel: "success" },
4183
+ { id: "skill.evolved", label: "Skill evolved", defaultMode: "banner", defaultLevel: "info" }
4184
+ ]
4185
+ });
4186
+ register({
4187
+ domain: "mycelium",
4188
+ label: "Mycelium",
4189
+ types: [
4190
+ { id: "mycelium.digest.completed", label: "Digest cycle completed", defaultMode: "summary", defaultLevel: "info" },
4191
+ { id: "mycelium.spore.created", label: "New spore extracted", defaultMode: "summary", defaultLevel: "info" }
4192
+ ]
4193
+ });
4194
+ }
4195
+
4196
+ // src/daemon/api/notifications.ts
4197
+ var CreateNotificationBody = external_exports.object({
4198
+ domain: external_exports.string().min(1),
4199
+ type: external_exports.string().min(1),
4200
+ level: external_exports.enum(["info", "success", "warning", "error"]).optional(),
4201
+ title: external_exports.string().min(1),
4202
+ message: external_exports.string().optional(),
4203
+ mode: external_exports.enum(["banner", "summary"]).optional(),
4204
+ link: external_exports.string().optional(),
4205
+ metadata: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
4206
+ });
4207
+ var UpdateStatusBody = external_exports.object({
4208
+ status: external_exports.enum(["read", "dismissed"])
4209
+ });
4210
+ async function handleListNotifications(_vaultDir, query) {
4211
+ const status = query.status;
4212
+ const domain = query.domain;
4213
+ const mode = query.mode;
4214
+ const limit = query.limit ? Number(query.limit) : void 0;
4215
+ const offset = query.offset ? Number(query.offset) : void 0;
4216
+ const items = listNotifications({ status, domain, mode, limit, offset });
4217
+ const unreadCount = countNotifications("unread");
4218
+ return {
4219
+ body: {
4220
+ items: items.map(parseNotificationRow),
4221
+ unread_count: unreadCount
4222
+ }
4223
+ };
4224
+ }
4225
+ async function handleCreateNotification(vaultDir, body) {
4226
+ const parsed = CreateNotificationBody.safeParse(body);
4227
+ if (!parsed.success) {
4228
+ return { status: 400, body: { error: "validation_failed", issues: parsed.error.issues } };
4229
+ }
4230
+ const { domain, type, title, message, link, metadata } = parsed.data;
4231
+ const config = loadConfig(vaultDir);
4232
+ if (!config.notifications.enabled) {
4233
+ return { body: { ok: true, suppressed: true, reason: "notifications_disabled" } };
4234
+ }
4235
+ const domainConfig = config.notifications.domains[domain];
4236
+ if (domainConfig && !domainConfig.enabled) {
4237
+ return { body: { ok: true, suppressed: true, reason: "domain_disabled" } };
4238
+ }
4239
+ const id = notify(vaultDir, {
4240
+ domain,
4241
+ type,
4242
+ title,
4243
+ message,
4244
+ link,
4245
+ metadata,
4246
+ level: parsed.data.level,
4247
+ mode: parsed.data.mode
4248
+ }, config);
4249
+ if (!id) {
4250
+ return { body: { ok: true, suppressed: true, reason: "unknown" } };
4251
+ }
4252
+ return {
4253
+ body: {
4254
+ ok: true,
4255
+ id,
4256
+ notification: parseNotificationRow(getNotification(id))
4257
+ }
4258
+ };
4259
+ }
4260
+ async function handleUpdateNotification(_vaultDir, id, body) {
4261
+ const parsed = UpdateStatusBody.safeParse(body);
4262
+ if (!parsed.success) {
4263
+ return { status: 400, body: { error: "validation_failed", issues: parsed.error.issues } };
4264
+ }
4265
+ const updated = updateNotificationStatus(id, parsed.data.status);
4266
+ if (!updated) {
4267
+ return { status: 404, body: { error: "not_found" } };
4268
+ }
4269
+ return { body: { ok: true } };
4270
+ }
4271
+ async function handleDismissAll(_vaultDir, body) {
4272
+ const domain = body?.domain;
4273
+ const count = dismissAllNotifications(domain);
4274
+ return { body: { ok: true, dismissed: count } };
4275
+ }
4276
+ async function handleMarkAllRead(_vaultDir, body) {
4277
+ const domain = body?.domain;
4278
+ const count = markAllRead(domain);
4279
+ return { body: { ok: true, marked: count } };
4280
+ }
4281
+ async function handleGetRegistry() {
4282
+ return { body: { domains: getAllDomains() } };
4283
+ }
4284
+ async function handleUnreadCount() {
4285
+ return { body: { count: countNotifications("unread") } };
4286
+ }
4287
+ function parseNotificationRow(row) {
4288
+ if (!row) return null;
4289
+ return {
4290
+ ...row,
4291
+ metadata: row.metadata ? JSON.parse(row.metadata) : null
4292
+ };
4293
+ }
4294
+
4117
4295
  // src/daemon/api/agent-tasks.ts
4118
4296
  var import_yaml2 = __toESM(require_dist(), 1);
4119
4297
  var HTTP_OK = 200;
@@ -4335,6 +4513,186 @@ function testCloud() {
4335
4513
  return { ok: true };
4336
4514
  }
4337
4515
 
4516
+ // src/db/queries/skill-usage.ts
4517
+ var USAGE_COLUMNS = [
4518
+ "id",
4519
+ "skill_id",
4520
+ "session_id",
4521
+ "machine_id",
4522
+ "detected_at"
4523
+ ];
4524
+ var SELECT_COLUMNS4 = USAGE_COLUMNS.join(", ");
4525
+ function toUsageRow(row) {
4526
+ return {
4527
+ id: row.id,
4528
+ skill_id: row.skill_id,
4529
+ session_id: row.session_id,
4530
+ machine_id: row.machine_id ?? getTeamMachineId(),
4531
+ detected_at: row.detected_at
4532
+ };
4533
+ }
4534
+ function insertSkillUsage(data) {
4535
+ const db = getDatabase();
4536
+ db.prepare(
4537
+ `INSERT INTO skill_usage (
4538
+ id, skill_id, session_id, machine_id, detected_at
4539
+ ) VALUES (
4540
+ ?, ?, ?, ?, ?
4541
+ )`
4542
+ ).run(
4543
+ data.id,
4544
+ data.skill_id,
4545
+ data.session_id,
4546
+ data.machine_id ?? getTeamMachineId(),
4547
+ data.detected_at
4548
+ );
4549
+ const row = toUsageRow(
4550
+ db.prepare(`SELECT ${SELECT_COLUMNS4} FROM skill_usage WHERE id = ?`).get(data.id)
4551
+ );
4552
+ return row;
4553
+ }
4554
+ function hasUsageForSkillAndSession(skillId, sessionId) {
4555
+ const db = getDatabase();
4556
+ const row = db.prepare(
4557
+ `SELECT 1 FROM skill_usage WHERE skill_id = ? AND session_id = ? LIMIT 1`
4558
+ ).get(skillId, sessionId);
4559
+ return row !== void 0;
4560
+ }
4561
+ function countUsageForSkill(skillId) {
4562
+ const db = getDatabase();
4563
+ const row = db.prepare(
4564
+ `SELECT COUNT(*) as count FROM skill_usage WHERE skill_id = ?`
4565
+ ).get(skillId);
4566
+ return row.count;
4567
+ }
4568
+
4569
+ // src/daemon/api/skills.ts
4570
+ var DEFAULT_LIST_OFFSET3 = 0;
4571
+ async function handleListCandidates(req) {
4572
+ const status = req.query.status || void 0;
4573
+ const limit = req.query.limit ? Number(req.query.limit) : DEFAULT_LIST_LIMIT;
4574
+ const offset = req.query.offset ? Number(req.query.offset) : DEFAULT_LIST_OFFSET3;
4575
+ const { items: candidates, total } = listCandidatesWithCount({ status, limit, offset });
4576
+ return { status: 200, body: { candidates, total } };
4577
+ }
4578
+ async function handleGetCandidate(req) {
4579
+ const candidate = getCandidate(req.params.id);
4580
+ if (!candidate) {
4581
+ return { status: 404, body: { error: `Not found: ${req.params.id}` } };
4582
+ }
4583
+ return { status: 200, body: { candidate } };
4584
+ }
4585
+ async function handleUpdateCandidate(req) {
4586
+ const id = req.params.id;
4587
+ const body = req.body;
4588
+ if (!body) return { status: 400, body: { error: "Request body required" } };
4589
+ const { status, topic, rationale, confidence, source_ids, skill_id } = body;
4590
+ const updated = updateCandidate(id, {
4591
+ ...status !== void 0 ? { status } : {},
4592
+ ...topic !== void 0 ? { topic } : {},
4593
+ ...rationale !== void 0 ? { rationale } : {},
4594
+ ...confidence !== void 0 ? { confidence } : {},
4595
+ ...source_ids !== void 0 ? { source_ids } : {},
4596
+ ...skill_id !== void 0 ? { skill_id } : {},
4597
+ updated_at: epochSeconds()
4598
+ });
4599
+ if (!updated) return { status: 404, body: { error: `Candidate not found: ${id}` } };
4600
+ return { status: 200, body: { candidate: updated } };
4601
+ }
4602
+ async function handleListSkillRecords(req) {
4603
+ const status = req.query.status || void 0;
4604
+ const limit = req.query.limit ? Number(req.query.limit) : DEFAULT_LIST_LIMIT;
4605
+ const offset = req.query.offset ? Number(req.query.offset) : DEFAULT_LIST_OFFSET3;
4606
+ const { items: records, total } = listSkillRecordsWithCount({ status, limit, offset });
4607
+ return { status: 200, body: { records, total } };
4608
+ }
4609
+ async function handleGetSkillRecord(req) {
4610
+ const idOrName = req.params.id;
4611
+ const record = getSkillRecord(idOrName) ?? getSkillRecordByName(idOrName);
4612
+ if (!record) {
4613
+ return { status: 404, body: { error: `Not found: ${idOrName}` } };
4614
+ }
4615
+ const lineage = listLineageForSkill(record.id);
4616
+ const usage_total = countUsageForSkill(record.id);
4617
+ const latestSnapshot = lineage[0]?.content_snapshot;
4618
+ const frontmatterFields = {};
4619
+ if (latestSnapshot) {
4620
+ const fmMatch = latestSnapshot.match(/^---\n([\s\S]*?)\n---/);
4621
+ if (fmMatch) {
4622
+ for (const line of fmMatch[1].split("\n")) {
4623
+ const colonIdx = line.indexOf(":");
4624
+ if (colonIdx > 0) {
4625
+ const key = line.slice(0, colonIdx).trim();
4626
+ const val = line.slice(colonIdx + 1).trim();
4627
+ if (key && val) frontmatterFields[key] = val;
4628
+ }
4629
+ }
4630
+ }
4631
+ }
4632
+ return { status: 200, body: { ...record, lineage, usage_total, frontmatter: frontmatterFields } };
4633
+ }
4634
+ async function handleDeleteCandidate(req) {
4635
+ const id = req.params.id;
4636
+ const deleted = deleteCandidate(id);
4637
+ if (!deleted) return { status: 404, body: { error: `Not found: ${id}` } };
4638
+ return { status: 200, body: { deleted: true, id } };
4639
+ }
4640
+ async function handleDeleteSkillRecord(req) {
4641
+ const idOrName = req.params.id;
4642
+ const result = deleteSkillRecordCascade(idOrName);
4643
+ if (!result) return { status: 404, body: { error: `Not found: ${idOrName}` } };
4644
+ if (isTeamSyncEnabled()) {
4645
+ try {
4646
+ enqueueOutbox({
4647
+ table_name: "skill_records",
4648
+ row_id: result.id,
4649
+ operation: "delete",
4650
+ payload: JSON.stringify({ id: result.id, name: result.name }),
4651
+ machine_id: getTeamMachineId(),
4652
+ created_at: epochSeconds()
4653
+ });
4654
+ } catch (err) {
4655
+ console.warn("[team-sync] Failed to enqueue skill record deletion:", err instanceof Error ? err.message : err);
4656
+ }
4657
+ }
4658
+ return { status: 200, body: { deleted: true, id: result.id, name: result.name } };
4659
+ }
4660
+
4661
+ // src/daemon/skill-usage.ts
4662
+ import crypto from "crypto";
4663
+ var SKILL_USAGE_DETECTION_ENABLED = false;
4664
+ var MAX_ACTIVE_SKILLS_CHECK = 1e3;
4665
+ function detectSkillUsage(sessionId, transcriptContent) {
4666
+ if (transcriptContent.includes("vault_write_skill")) return;
4667
+ if (!SKILL_USAGE_DETECTION_ENABLED) return;
4668
+ const activeSkills = listSkillRecords({ status: "active", limit: MAX_ACTIVE_SKILLS_CHECK });
4669
+ if (activeSkills.length === 0) return;
4670
+ const skillPatterns = activeSkills.map((skill) => ({
4671
+ skill,
4672
+ pattern: new RegExp(
4673
+ `skills/${escapeRegex(skill.name)}/SKILL\\.md|<skill[^>]*name=["']${escapeRegex(skill.name)}["']`
4674
+ )
4675
+ }));
4676
+ const now = epochSeconds();
4677
+ for (const { skill, pattern } of skillPatterns) {
4678
+ try {
4679
+ if (!pattern.test(transcriptContent)) continue;
4680
+ if (hasUsageForSkillAndSession(skill.id, sessionId)) continue;
4681
+ insertSkillUsage({
4682
+ id: crypto.randomUUID(),
4683
+ skill_id: skill.id,
4684
+ session_id: sessionId,
4685
+ detected_at: now
4686
+ });
4687
+ incrementSkillUsageCount(skill.id, now);
4688
+ } catch {
4689
+ }
4690
+ }
4691
+ }
4692
+ function escapeRegex(s) {
4693
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
4694
+ }
4695
+
4338
4696
  // src/daemon/log-reconcile.ts
4339
4697
  import fs12 from "fs";
4340
4698
  import path14 from "path";
@@ -4471,6 +4829,50 @@ var PowerManager = class {
4471
4829
  }
4472
4830
  };
4473
4831
 
4832
+ // src/daemon/task-scheduler.ts
4833
+ function resolveSchedule(yamlSchedule, configOverride) {
4834
+ if (!configOverride?.schedule) return yamlSchedule;
4835
+ return {
4836
+ enabled: configOverride.schedule.enabled ?? yamlSchedule.enabled,
4837
+ intervalSeconds: configOverride.schedule.intervalSeconds ?? yamlSchedule.intervalSeconds,
4838
+ runIn: configOverride.schedule.runIn ?? yamlSchedule.runIn,
4839
+ preCondition: configOverride.schedule.preCondition ?? yamlSchedule.preCondition
4840
+ };
4841
+ }
4842
+ function buildScheduledJobs(tasks, configOverrides, context, initialLastRuns) {
4843
+ const jobs = [];
4844
+ for (const task of tasks) {
4845
+ if (!task.schedule) continue;
4846
+ const override = configOverrides[task.name];
4847
+ const effective = resolveSchedule(task.schedule, override);
4848
+ if (!effective.enabled) continue;
4849
+ let lastRun = initialLastRuns?.[task.name] ?? 0;
4850
+ const intervalMs = effective.intervalSeconds * 1e3;
4851
+ jobs.push({
4852
+ name: `scheduled:${task.name}`,
4853
+ runIn: effective.runIn,
4854
+ fn: async () => {
4855
+ if (!context) return;
4856
+ if (context.isTaskRunning(task.name)) return;
4857
+ if (Date.now() - lastRun < intervalMs) return;
4858
+ if (effective.preCondition) {
4859
+ const check = context.preConditions[effective.preCondition];
4860
+ if (!check) return;
4861
+ if (!check()) return;
4862
+ }
4863
+ try {
4864
+ context.setTaskRunning(task.name, true);
4865
+ await context.runTask(task.name);
4866
+ } finally {
4867
+ lastRun = Date.now();
4868
+ context.setTaskRunning(task.name, false);
4869
+ }
4870
+ }
4871
+ });
4872
+ }
4873
+ return jobs;
4874
+ }
4875
+
4474
4876
  // src/daemon/jobs/session-cleanup.ts
4475
4877
  import { unlink, glob } from "fs/promises";
4476
4878
  async function cleanupAfterSessionCascade(sessionId, result, embeddingManager, vaultDir) {
@@ -4587,7 +4989,8 @@ function handleUserPrompt(sessionId, prompt) {
4587
4989
  session_id: sessionId,
4588
4990
  user_prompt: prompt ?? null,
4589
4991
  started_at: now,
4590
- created_at: now
4992
+ created_at: now,
4993
+ machine_id: getTeamMachineId()
4591
4994
  });
4592
4995
  const promptNumber = batch.prompt_number;
4593
4996
  try {
@@ -4613,6 +5016,7 @@ function handleToolUse(sessionId, toolName, toolInput, toolOutput) {
4613
5016
  if (activity.prompt_batch_id !== null) {
4614
5017
  incrementActivityCount(activity.prompt_batch_id);
4615
5018
  }
5019
+ incrementSessionToolCount(sessionId);
4616
5020
  }
4617
5021
  function handleStopBatches(sessionId) {
4618
5022
  closeOpenBatches(sessionId, epochSeconds());
@@ -4738,6 +5142,7 @@ async function main() {
4738
5142
  logger.info(LOG_KINDS.DAEMON_START, "Machine ID resolved", { machine_id: machineId });
4739
5143
  const db = initDatabase(vaultDbPath(vaultDir));
4740
5144
  createSchema(db, machineId);
5145
+ registerBuiltinDomains();
4741
5146
  logger.info(LOG_KINDS.DAEMON_START, "SQLite initialized", { vault: vaultDir });
4742
5147
  initTeamContext(config.team.enabled, machineId);
4743
5148
  logger.setPersistFn((entry) => {
@@ -4767,9 +5172,10 @@ async function main() {
4767
5172
  const recordSource = new SqliteRecordSource();
4768
5173
  const embeddingManager = new EmbeddingManager(vectorStore, embeddingProvider, recordSource, logger);
4769
5174
  logger.info(LOG_KINDS.EMBEDDING_EMBED, "EmbeddingManager initialized", { vectors_db: vectorsDbPath });
5175
+ let definitionsDir;
4770
5176
  try {
4771
- const { registerBuiltInAgentsAndTasks, resolveDefinitionsDir: resolveDefinitionsDir2 } = await import("./loader-BQ4X4K3F.js");
4772
- const definitionsDir = resolveDefinitionsDir2();
5177
+ const { registerBuiltInAgentsAndTasks, resolveDefinitionsDir: resolveDefinitionsDir2 } = await import("./loader-WQKVWL5D.js");
5178
+ definitionsDir = resolveDefinitionsDir2();
4773
5179
  await registerBuiltInAgentsAndTasks(definitionsDir, vaultDir);
4774
5180
  logger.info(LOG_KINDS.AGENT_TASK, "Built-in agents and tasks registered");
4775
5181
  } catch (err) {
@@ -4814,8 +5220,11 @@ async function main() {
4814
5220
  const server = new DaemonServer({
4815
5221
  vaultDir,
4816
5222
  logger,
4817
- uiDir: uiDir ?? void 0,
4818
- onRequest: () => powerManager.recordActivity()
5223
+ uiDir: uiDir ?? void 0
5224
+ // Don't record activity on every HTTP request — UI polling (every 3-10s)
5225
+ // would prevent the PowerManager from ever reaching 'idle' state, blocking
5226
+ // all idle-only scheduled tasks (skill-survey, skill-generate, skill-evolve).
5227
+ // Activity is recorded on meaningful events below (session register, prompt capture, etc.).
4819
5228
  });
4820
5229
  const registry = new SessionRegistry({
4821
5230
  gracePeriod: 0,
@@ -4831,10 +5240,8 @@ async function main() {
4831
5240
  const sessionTitleCache = /* @__PURE__ */ new Map();
4832
5241
  async function triggerTitleSummary(sessionId) {
4833
5242
  if (config.agent.summary_batch_interval <= 0) return;
4834
- const running = getRunningRun(DEFAULT_AGENT_ID);
4835
- if (running) return;
4836
5243
  try {
4837
- const { runAgent } = await import("./executor-LKDWMGC7.js");
5244
+ const { runAgent } = await import("./executor-W5MKZH7B.js");
4838
5245
  runAgent(vaultDir, {
4839
5246
  task: "title-summary",
4840
5247
  instruction: `Process session ${sessionId} only`,
@@ -4950,6 +5357,7 @@ async function main() {
4950
5357
  last_assistant_message: external_exports.string().optional()
4951
5358
  });
4952
5359
  server.registerRoute("POST", "/sessions/register", async (req) => {
5360
+ powerManager.recordActivity();
4953
5361
  const { session_id, agent, branch, started_at } = RegisterBody.parse(req.body);
4954
5362
  const resolvedStartedAt = started_at ?? (/* @__PURE__ */ new Date()).toISOString();
4955
5363
  registry.register(session_id, { started_at: resolvedStartedAt, branch });
@@ -4964,11 +5372,20 @@ async function main() {
4964
5372
  branch: branch ?? null,
4965
5373
  started_at: startedEpoch,
4966
5374
  created_at: now,
4967
- status: "active"
5375
+ status: "active",
5376
+ machine_id: machineId
4968
5377
  });
4969
5378
  updateSession(session_id, { ended_at: null, status: "active" });
4970
5379
  reconcileSession(session_id);
4971
5380
  logger.info(LOG_KINDS.LIFECYCLE_REGISTER, "Session registered", { session_id, branch, started_at: started_at ?? null });
5381
+ notify(vaultDir, {
5382
+ domain: "sessions",
5383
+ type: "session.started",
5384
+ title: "Session started",
5385
+ message: branch ? `Branch: ${branch}` : void 0,
5386
+ link: `/sessions/${session_id}`,
5387
+ metadata: { sessionId: session_id, agent: agent ?? "claude-code", branch }
5388
+ }, config);
4972
5389
  return { body: { ok: true, sessions: registry.sessions } };
4973
5390
  });
4974
5391
  server.registerRoute("POST", "/sessions/unregister", async (req) => {
@@ -4981,6 +5398,13 @@ async function main() {
4981
5398
  reconciledSessions.delete(session_id);
4982
5399
  server.updateDaemonJsonSessions(registry.sessions);
4983
5400
  logger.info(LOG_KINDS.LIFECYCLE_UNREGISTER, "Session unregistered", { session_id });
5401
+ notify(vaultDir, {
5402
+ domain: "sessions",
5403
+ type: "session.ended",
5404
+ title: "Session ended",
5405
+ link: `/sessions/${session_id}`,
5406
+ metadata: { sessionId: session_id }
5407
+ }, config);
4984
5408
  return { body: { ok: true, sessions: registry.sessions } };
4985
5409
  });
4986
5410
  server.registerRoute("POST", "/events", async (req) => {
@@ -4997,7 +5421,8 @@ async function main() {
4997
5421
  agent: event.agent ?? "claude-code",
4998
5422
  status: "active",
4999
5423
  started_at: startedEpoch,
5000
- created_at: now
5424
+ created_at: now,
5425
+ machine_id: machineId
5001
5426
  });
5002
5427
  reconcileSession(event.session_id);
5003
5428
  }
@@ -5006,6 +5431,7 @@ async function main() {
5006
5431
  }
5007
5432
  sessionBuffers.get(event.session_id).append(event);
5008
5433
  if (event.type === "user_prompt") {
5434
+ powerManager.recordActivity();
5009
5435
  const promptText = String(event.prompt ?? "");
5010
5436
  if (isSystemMessage(promptText)) {
5011
5437
  logger.debug(LOG_KINDS.HOOKS_PROMPT, "Skipped system-injected message", {
@@ -5301,16 +5727,37 @@ async function main() {
5301
5727
  }
5302
5728
  }
5303
5729
  }
5730
+ const currentSession = getSession(sessionId);
5731
+ const transcriptPromptCount = allTurns.length;
5732
+ const transcriptToolCount = allTurns.reduce((sum, t) => sum + t.toolCount, 0);
5304
5733
  const updateFields = {
5305
5734
  transcript_path: hookTranscriptPath ?? null,
5306
- prompt_count: allTurns.length,
5307
- tool_count: allTurns.reduce((sum, t) => sum + t.toolCount, 0)
5735
+ prompt_count: Math.max(transcriptPromptCount, currentSession?.prompt_count ?? 0),
5736
+ tool_count: Math.max(transcriptToolCount, currentSession?.tool_count ?? 0)
5308
5737
  };
5309
5738
  if (user) updateFields.user = user;
5310
5739
  if (!hasTitle && sessionTitleCache.has(sessionId)) {
5311
5740
  updateFields.title = sessionTitleCache.get(sessionId);
5312
5741
  }
5313
5742
  updateSession(sessionId, updateFields);
5743
+ if (SKILL_USAGE_DETECTION_ENABLED) {
5744
+ try {
5745
+ let transcriptText = null;
5746
+ if (hookTranscriptPath) {
5747
+ try {
5748
+ transcriptText = fs13.readFileSync(hookTranscriptPath, "utf-8");
5749
+ } catch {
5750
+ }
5751
+ }
5752
+ if (!transcriptText && allTurns.length > 0) {
5753
+ transcriptText = allTurns.map((t) => [t.prompt ?? "", t.aiResponse ?? ""].join(" ")).join("\n");
5754
+ }
5755
+ if (transcriptText) {
5756
+ detectSkillUsage(sessionId, transcriptText);
5757
+ }
5758
+ } catch {
5759
+ }
5760
+ }
5314
5761
  const responses = [];
5315
5762
  for (let i = 0; i < allTurns.length; i++) {
5316
5763
  if (allTurns[i].aiResponse) {
@@ -5474,6 +5921,34 @@ async function main() {
5474
5921
  server.registerRoute("GET", "/api/batches/:id/activities", handleGetBatchActivities);
5475
5922
  server.registerRoute("GET", "/api/sessions/:id/attachments", handleGetSessionAttachments);
5476
5923
  server.registerRoute("GET", "/api/sessions/:id/plans", handleGetSessionPlans);
5924
+ server.registerRoute("GET", "/api/skill-candidates", handleListCandidates);
5925
+ server.registerRoute("GET", "/api/skill-candidates/:id", handleGetCandidate);
5926
+ server.registerRoute("PUT", "/api/skill-candidates/:id", handleUpdateCandidate);
5927
+ server.registerRoute("GET", "/api/skill-records", handleListSkillRecords);
5928
+ server.registerRoute("GET", "/api/skill-records/:id", handleGetSkillRecord);
5929
+ server.registerRoute("DELETE", "/api/skill-candidates/:id", handleDeleteCandidate);
5930
+ server.registerRoute("DELETE", "/api/skill-records/:id", async (req) => {
5931
+ const result = await handleDeleteSkillRecord(req);
5932
+ if (result.body?.deleted) {
5933
+ const record = result.body;
5934
+ if (record.name) {
5935
+ const projectRoot2 = path15.resolve(vaultDir, "..");
5936
+ const skillDir = path15.resolve(projectRoot2, ".agents", "skills", record.name);
5937
+ try {
5938
+ fs13.rmSync(skillDir, { recursive: true, force: true });
5939
+ } catch (err) {
5940
+ logger.warn(LOG_KINDS.PROCESSOR_BATCH, "Failed to remove skill directory", { name: record.name, error: String(err) });
5941
+ }
5942
+ try {
5943
+ const { syncSkillSymlinks } = await import("./installer-25TSX4SR.js");
5944
+ syncSkillSymlinks(projectRoot2, record.name, { remove: true });
5945
+ } catch (err) {
5946
+ logger.warn(LOG_KINDS.PROCESSOR_BATCH, "Failed to remove skill symlinks", { name: record.name, error: String(err) });
5947
+ }
5948
+ }
5949
+ }
5950
+ return result;
5951
+ });
5477
5952
  server.registerRoute("GET", "/api/spores", handleListSpores);
5478
5953
  server.registerRoute("GET", "/api/spores/:id", handleGetSpore);
5479
5954
  server.registerRoute("GET", "/api/entities", handleListEntities);
@@ -5508,18 +5983,28 @@ async function main() {
5508
5983
  const contentType = ATTACHMENT_MEDIA_TYPES[ext] ?? "application/octet-stream";
5509
5984
  return { status: 200, headers: { "Content-Type": contentType }, body: diskData };
5510
5985
  });
5986
+ function buildSkillGenerateInstruction() {
5987
+ const candidates = listCandidates({ status: "approved", limit: 1 });
5988
+ if (candidates.length > 0) {
5989
+ return `Generate skill for candidate id=${candidates[0].id} topic="${candidates[0].topic}"`;
5990
+ }
5991
+ return void 0;
5992
+ }
5511
5993
  const AgentRunBody = external_exports.object({
5512
5994
  task: external_exports.string().optional(),
5513
5995
  instruction: external_exports.string().optional(),
5514
5996
  agentId: external_exports.string().optional()
5515
5997
  });
5516
5998
  server.registerRoute("POST", "/api/agent/run", async (req) => {
5517
- const { task, instruction, agentId } = AgentRunBody.parse(req.body);
5518
- const { runAgent } = await import("./executor-LKDWMGC7.js");
5999
+ const { task, instruction: rawInstruction, agentId } = AgentRunBody.parse(req.body);
6000
+ let instruction = rawInstruction;
6001
+ if (task === "skill-generate" && !instruction) {
6002
+ instruction = buildSkillGenerateInstruction();
6003
+ }
6004
+ const { runAgent } = await import("./executor-W5MKZH7B.js");
5519
6005
  const resultPromise = runAgent(vaultDir, { task, instruction, agentId, embeddingManager });
5520
6006
  const effectiveAgentId = agentId ?? "myco-agent";
5521
- const latestRun = getRunningRun(effectiveAgentId);
5522
- const runId = latestRun?.id;
6007
+ const runId = getLatestRunId(effectiveAgentId, task);
5523
6008
  resultPromise.then((result) => {
5524
6009
  if (result.status === "failed") {
5525
6010
  logger.error(LOG_KINDS.AGENT_ERROR, "Agent run failed", {
@@ -5601,6 +6086,7 @@ async function main() {
5601
6086
  const spore = insertSpore({
5602
6087
  id,
5603
6088
  agent_id: USER_AGENT_ID,
6089
+ machine_id: machineId,
5604
6090
  observation_type: observationType,
5605
6091
  content,
5606
6092
  tags: tags ? tags.join(", ") : null,
@@ -5696,11 +6182,12 @@ async function main() {
5696
6182
  name: USER_AGENT_NAME,
5697
6183
  created_at: now
5698
6184
  });
5699
- const { insertResolutionEvent } = await import("./resolution-events-WZHPQQMN.js");
6185
+ const { insertResolutionEvent } = await import("./resolution-events-5EVUEWHS.js");
5700
6186
  const resolutionId = `res-${randomBytes(RESOLUTION_ID_RANDOM_BYTES).toString("hex")}`;
5701
6187
  insertResolutionEvent({
5702
6188
  id: resolutionId,
5703
6189
  agent_id: USER_AGENT_ID,
6190
+ machine_id: machineId,
5704
6191
  spore_id: old_spore_id,
5705
6192
  action: "supersede",
5706
6193
  new_spore_id,
@@ -5786,6 +6273,13 @@ async function main() {
5786
6273
  server.registerRoute("POST", "/api/embedding/reconcile", async () => handleEmbeddingReconcile(embeddingManager));
5787
6274
  server.registerRoute("POST", "/api/embedding/clean-orphans", async () => handleEmbeddingCleanOrphans(embeddingManager));
5788
6275
  server.registerRoute("POST", "/api/embedding/reembed-stale", async () => handleEmbeddingReembedStale(embeddingManager));
6276
+ server.registerRoute("GET", "/api/notifications", async (req) => handleListNotifications(vaultDir, req.query));
6277
+ server.registerRoute("POST", "/api/notifications", async (req) => handleCreateNotification(vaultDir, req.body));
6278
+ server.registerRoute("PATCH", "/api/notifications/:id", async (req) => handleUpdateNotification(vaultDir, req.params.id, req.body));
6279
+ server.registerRoute("POST", "/api/notifications/dismiss-all", async (req) => handleDismissAll(vaultDir, req.body));
6280
+ server.registerRoute("POST", "/api/notifications/mark-all-read", async (req) => handleMarkAllRead(vaultDir, req.body));
6281
+ server.registerRoute("GET", "/api/notifications/registry", async () => handleGetRegistry());
6282
+ server.registerRoute("GET", "/api/notifications/unread-count", async () => handleUnreadCount());
5789
6283
  await server.evictExistingDaemon();
5790
6284
  const resolvedPort = await resolvePort(config.daemon.port, vaultDir);
5791
6285
  if (resolvedPort === 0) {
@@ -5828,43 +6322,6 @@ async function main() {
5828
6322
  vaultDir
5829
6323
  })
5830
6324
  });
5831
- if (config.agent.auto_run) {
5832
- let agentRunning = false;
5833
- const agentIntervalMs = config.agent.interval_seconds * MS_PER_SECOND;
5834
- const lastRunRow = getDatabase().prepare(
5835
- `SELECT started_at FROM agent_runs WHERE agent_id = ? AND status IN ('completed', 'failed') ORDER BY started_at DESC LIMIT 1`
5836
- ).get(DEFAULT_AGENT_ID);
5837
- let lastAgentRun = lastRunRow ? lastRunRow.started_at * MS_PER_SECOND : 0;
5838
- powerManager.register({
5839
- name: "agent-auto-run",
5840
- runIn: ["active", "idle"],
5841
- fn: async () => {
5842
- if (agentRunning) return;
5843
- if (Date.now() - lastAgentRun < agentIntervalMs) return;
5844
- const agentDb = getDatabase();
5845
- const checkRow = agentDb.prepare("SELECT COUNT(*) as count FROM prompt_batches WHERE processed = 0").get();
5846
- const count = Number(checkRow.count);
5847
- if (count === 0) {
5848
- logger.debug(LOG_KINDS.AGENT_AUTO_RUN, "No unprocessed batches, skipping cycle");
5849
- return;
5850
- }
5851
- agentRunning = true;
5852
- lastAgentRun = Date.now();
5853
- try {
5854
- logger.info(LOG_KINDS.AGENT_AUTO_RUN, "Unprocessed batches found, starting agent", { count });
5855
- const { runAgent } = await import("./executor-LKDWMGC7.js");
5856
- const runResult = await runAgent(vaultDir, { embeddingManager });
5857
- logger.info(LOG_KINDS.AGENT_RUN, "Agent run completed", { status: runResult.status, runId: runResult.runId });
5858
- } catch (err) {
5859
- logger.error(LOG_KINDS.AGENT_ERROR, "Agent auto-run failed", { error: err.message });
5860
- } finally {
5861
- agentRunning = false;
5862
- }
5863
- }
5864
- });
5865
- } else {
5866
- logger.info(LOG_KINDS.AGENT_AUTO_RUN, "Auto-agent disabled (agent.auto_run = false)");
5867
- }
5868
6325
  powerManager.register({
5869
6326
  name: "log-retention",
5870
6327
  runIn: ["idle", "sleep"],
@@ -5904,9 +6361,12 @@ async function main() {
5904
6361
  const result = await client.pushBatch(pending);
5905
6362
  if (result.synced > 0 || result.skipped > 0) {
5906
6363
  const failedIds = new Set(result.errors.map((e) => e.id));
5907
- const sentIds = pending.filter((r) => !failedIds.has(String(r.row_id))).map((r) => r.id);
6364
+ const sentRecords = pending.filter((r) => !failedIds.has(String(r.row_id)));
6365
+ const sentIds = sentRecords.map((r) => r.id);
5908
6366
  if (sentIds.length > 0) {
5909
- markSent(sentIds, epochSeconds());
6367
+ const now = epochSeconds();
6368
+ markSent(sentIds, now);
6369
+ markSourceRowsSynced(sentRecords, now);
5910
6370
  }
5911
6371
  }
5912
6372
  if (result.errors.length > 0) {
@@ -5927,6 +6387,111 @@ async function main() {
5927
6387
  }
5928
6388
  });
5929
6389
  }
6390
+ {
6391
+ const runningTasks = /* @__PURE__ */ new Set();
6392
+ if (definitionsDir) {
6393
+ const { loadAllTasks: loadAllTasks2 } = await import("./registry-2XQMCPA6.js");
6394
+ const allTasks = Array.from(loadAllTasks2(definitionsDir, vaultDir).values());
6395
+ const initialLastRuns = {};
6396
+ try {
6397
+ const recentRuns = getDatabase().prepare(
6398
+ `SELECT task, MAX(completed_at) as last_completed
6399
+ FROM agent_runs
6400
+ WHERE status IN ('completed', 'failed') AND completed_at IS NOT NULL
6401
+ GROUP BY task`
6402
+ ).all();
6403
+ for (const row of recentRuns) {
6404
+ initialLastRuns[row.task] = row.last_completed * 1e3;
6405
+ }
6406
+ } catch {
6407
+ }
6408
+ const scheduledContext = {
6409
+ isTaskRunning: (name) => runningTasks.has(name),
6410
+ setTaskRunning: (name, running) => {
6411
+ if (running) runningTasks.add(name);
6412
+ else runningTasks.delete(name);
6413
+ },
6414
+ runTask: async (taskName) => {
6415
+ const { runAgent } = await import("./executor-W5MKZH7B.js");
6416
+ const instruction = taskName === "skill-generate" ? buildSkillGenerateInstruction() : void 0;
6417
+ const result = await runAgent(vaultDir, { task: taskName, instruction, embeddingManager });
6418
+ logger.info(LOG_KINDS.AGENT_RUN, `Scheduled task ${taskName} completed`, {
6419
+ status: result.status,
6420
+ runId: result.runId
6421
+ });
6422
+ if (result.status === "failed") {
6423
+ notify(vaultDir, {
6424
+ domain: "agents",
6425
+ type: "agent.task.failure",
6426
+ title: `Task failed: ${taskName}`,
6427
+ message: result.error ?? "Unknown error",
6428
+ link: `/agent?run=${result.runId}`,
6429
+ metadata: { taskName, runId: result.runId }
6430
+ }, config);
6431
+ } else if (result.status === "completed") {
6432
+ notify(vaultDir, {
6433
+ domain: "agents",
6434
+ type: "agent.task.success",
6435
+ title: `Task completed: ${taskName}`,
6436
+ link: `/agent?run=${result.runId}`,
6437
+ metadata: { taskName, runId: result.runId }
6438
+ }, config);
6439
+ const { countToolCallsByRun } = await import("./turns-3ZQAF6HF.js");
6440
+ const counts = countToolCallsByRun(result.runId, ["vault_create_spore", "vault_write_digest"]);
6441
+ const sporeCount = counts["vault_create_spore"] ?? 0;
6442
+ const digestCount = counts["vault_write_digest"] ?? 0;
6443
+ if (sporeCount > 0) {
6444
+ notify(vaultDir, {
6445
+ domain: "mycelium",
6446
+ type: "mycelium.spore.created",
6447
+ title: sporeCount === 1 ? "Extracted 1 observation" : `Extracted ${sporeCount} observations`,
6448
+ message: `From ${taskName} run`,
6449
+ link: "/mycelium?tab=spores",
6450
+ metadata: { count: sporeCount, taskName, runId: result.runId }
6451
+ }, config);
6452
+ }
6453
+ if (digestCount > 0) {
6454
+ notify(vaultDir, {
6455
+ domain: "mycelium",
6456
+ type: "mycelium.digest.completed",
6457
+ title: `Digest updated (${digestCount} ${digestCount === 1 ? "tier" : "tiers"})`,
6458
+ link: "/mycelium?tab=digest",
6459
+ metadata: { tierCount: digestCount, taskName, runId: result.runId }
6460
+ }, config);
6461
+ }
6462
+ }
6463
+ },
6464
+ preConditions: {
6465
+ "has-unprocessed-batches": () => {
6466
+ const row = getDatabase().prepare(
6467
+ "SELECT 1 FROM prompt_batches WHERE processed = 0 LIMIT 1"
6468
+ ).get();
6469
+ return row !== void 0;
6470
+ },
6471
+ "has-active-skills": () => {
6472
+ return countSkillRecords({ status: "active" }) > 0;
6473
+ },
6474
+ "has-approved-candidates": () => {
6475
+ return countCandidates({ status: "approved" }) > 0;
6476
+ }
6477
+ }
6478
+ };
6479
+ const scheduledJobs = buildScheduledJobs(
6480
+ allTasks,
6481
+ config.agent.tasks ?? {},
6482
+ scheduledContext,
6483
+ initialLastRuns
6484
+ );
6485
+ for (const job of scheduledJobs) {
6486
+ powerManager.register(job);
6487
+ }
6488
+ logger.info(LOG_KINDS.DAEMON_START, `Registered ${scheduledJobs.length} scheduled task(s)`, {
6489
+ tasks: scheduledJobs.map((j) => j.name)
6490
+ });
6491
+ } else {
6492
+ logger.warn(LOG_KINDS.AGENT_ERROR, "Skipping dynamic task scheduling \u2014 definitions directory unavailable");
6493
+ }
6494
+ }
5930
6495
  powerManager.start();
5931
6496
  const shutdown = async (signal) => {
5932
6497
  logger.info(LOG_KINDS.DAEMON_START, `${signal} received`);
@@ -5957,4 +6522,4 @@ export {
5957
6522
  handleUserPrompt,
5958
6523
  main
5959
6524
  };
5960
- //# sourceMappingURL=main-CMWNMCW2.js.map
6525
+ //# sourceMappingURL=main-IZ277SHB.js.map