@goondocks/myco 0.9.0 → 0.10.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.
- package/.claude-plugin/marketplace.json +1 -4
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +19 -2
- package/dist/{agent-run-EFICNTAU.js → agent-run-CGXF5PPC.js} +7 -7
- package/dist/{agent-tasks-RXJ7Z5NG.js → agent-tasks-T7NVI3R7.js} +7 -7
- package/dist/{chunk-JMJJEQ3P.js → chunk-5LPERML5.js} +3 -3
- package/dist/{chunk-RJ6ZQKG5.js → chunk-5QERXFH7.js} +2 -2
- package/dist/{chunk-UBZPD4HN.js → chunk-5SDH75YC.js} +2 -2
- package/dist/{chunk-5VZ52A4T.js → chunk-76ZO5RGT.js} +16 -2
- package/dist/{chunk-5VZ52A4T.js.map → chunk-76ZO5RGT.js.map} +1 -1
- package/dist/{chunk-46PWOKSI.js → chunk-AEJS57ZK.js} +2 -2
- package/dist/{chunk-DCXRSSBP.js → chunk-C3AEZ3BZ.js} +3 -3
- package/dist/{chunk-4LPQ26CK.js → chunk-CUDM5YJY.js} +25 -8
- package/dist/chunk-CUDM5YJY.js.map +1 -0
- package/dist/{chunk-YDN4OM33.js → chunk-D6DXYAFK.js} +20 -7
- package/dist/chunk-D6DXYAFK.js.map +1 -0
- package/dist/chunk-ENWBFX7F.js +50 -0
- package/dist/chunk-ENWBFX7F.js.map +1 -0
- package/dist/{chunk-OXZSXYAT.js → chunk-FFQES5MC.js} +48 -21
- package/dist/chunk-FFQES5MC.js.map +1 -0
- package/dist/{chunk-U3IBO3O3.js → chunk-FMIWFRAM.js} +3 -3
- package/dist/{chunk-KYLDNM7H.js → chunk-FPMEIN2W.js} +2 -2
- package/dist/{chunk-PB6TOLRQ.js → chunk-G2LQBFE3.js} +2 -2
- package/dist/{chunk-XNOCTDHF.js → chunk-J4RVYUH4.js} +2 -2
- package/dist/{chunk-MHSCMET3.js → chunk-MAZOVVDU.js} +33 -3
- package/dist/chunk-MAZOVVDU.js.map +1 -0
- package/dist/{chunk-JYOOJCPQ.js → chunk-MKKXCCQ5.js} +5 -5
- package/dist/{chunk-QIK2XSDQ.js → chunk-MSXYUXZR.js} +4 -4
- package/dist/{chunk-FFAYUQ5N.js → chunk-RJMXDUMA.js} +2 -1
- package/dist/{chunk-WGTCA2NU.js → chunk-S6I62FAH.js} +10 -2
- package/dist/{chunk-WGTCA2NU.js.map → chunk-S6I62FAH.js.map} +1 -1
- package/dist/{chunk-3K5WGSJ4.js → chunk-U7UUJ4FD.js} +23 -8
- package/dist/chunk-U7UUJ4FD.js.map +1 -0
- package/dist/{chunk-PT5IC642.js → chunk-W6HI4CCS.js} +2 -2
- package/dist/{chunk-KB4DGYIY.js → chunk-WXSJKESH.js} +12 -7
- package/dist/{chunk-KB4DGYIY.js.map → chunk-WXSJKESH.js.map} +1 -1
- package/dist/{chunk-KV4OC4H3.js → chunk-WZZH3YXJ.js} +119 -16
- package/dist/chunk-WZZH3YXJ.js.map +1 -0
- package/dist/chunk-XLY3REL3.js +165 -0
- package/dist/chunk-XLY3REL3.js.map +1 -0
- package/dist/{chunk-TRUJLI6K.js → chunk-YZMNEIFI.js} +9 -5
- package/dist/chunk-YZMNEIFI.js.map +1 -0
- package/dist/{chunk-2T7RPVPP.js → chunk-ZESTWGJT.js} +2 -2
- package/dist/{chunk-BUSP3OJB.js → chunk-ZMW6KQX2.js} +3 -3
- package/dist/{cli-ODLFRIYS.js → cli-6CPFJGRZ.js} +47 -36
- package/dist/cli-6CPFJGRZ.js.map +1 -0
- package/dist/client-B27SN5QG.js +15 -0
- package/dist/{config-UR5BSGVX.js → config-G3CSGI7P.js} +2 -2
- package/dist/{detect-providers-Q42OD4OS.js → detect-providers-AZ6DEQU7.js} +5 -5
- package/dist/{doctor-JLKTXDEH.js → doctor-RHHWJTMB.js} +10 -10
- package/dist/{executor-ONSDHPGX.js → executor-A5C5KDLP.js} +33 -20
- package/dist/executor-A5C5KDLP.js.map +1 -0
- package/dist/{init-6GWY345B.js → init-ARJROOWV.js} +15 -15
- package/dist/{init-wizard-UONLDYLI.js → init-wizard-XNFOZCEB.js} +8 -8
- package/dist/llm-XJFHRFHB.js +17 -0
- package/dist/{loader-SH67XD54.js → loader-GKXR5ONU.js} +4 -4
- package/dist/{loader-XVXKZZDH.js → loader-PZ7ZRSA4.js} +8 -4
- package/dist/{logs-QZVYF6FP.js → logs-LXHPDKUA.js} +3 -3
- package/dist/machine-id-RCM7TXPJ.js +13 -0
- package/dist/{main-BMCL7CPO.js → main-PVX6R3I6.js} +752 -80
- package/dist/main-PVX6R3I6.js.map +1 -0
- package/dist/{openai-embeddings-C265WRNK.js → openai-embeddings-ST3B6GW7.js} +5 -5
- package/dist/{openrouter-U6VFCRX2.js → openrouter-HJHOO3EO.js} +5 -5
- package/dist/{post-compact-OWFSOITU.js → post-compact-LR3DSGT3.js} +7 -7
- package/dist/{post-tool-use-DOUM7CGQ.js → post-tool-use-SOFVNFU3.js} +6 -6
- package/dist/{post-tool-use-failure-SG3C7PE6.js → post-tool-use-failure-2CZZZASB.js} +7 -7
- package/dist/{pre-compact-3J33CHXQ.js → pre-compact-3E3D6565.js} +7 -7
- package/dist/{provider-check-3WBPZADE.js → provider-check-SOTDYLJE.js} +5 -5
- package/dist/{registry-J4XTWARS.js → registry-WVZG6R2R.js} +5 -5
- package/dist/{resolution-events-TFEQPVKS.js → resolution-events-UPHJJLDQ.js} +5 -2
- package/dist/{restart-2VM33WOB.js → restart-XIUFVS33.js} +8 -8
- package/dist/{search-ZGQR5MDE.js → search-VB6Z2ZXV.js} +8 -8
- package/dist/{server-6KMBJCHZ.js → server-AKPBRP6Z.js} +5 -5
- package/dist/{session-Z2FXDDG6.js → session-UVZS6CY5.js} +9 -8
- package/dist/{session-Z2FXDDG6.js.map → session-UVZS6CY5.js.map} +1 -1
- package/dist/{session-end-FLVX32LE.js → session-end-YMQ44U6Z.js} +6 -6
- package/dist/{session-start-UCLK7PXE.js → session-start-3754HF3N.js} +11 -10
- package/dist/{session-start-UCLK7PXE.js.map → session-start-3754HF3N.js.map} +1 -1
- package/dist/{setup-llm-GKMCHURK.js → setup-llm-NWHOPJUV.js} +8 -8
- package/dist/src/cli.js +1 -1
- package/dist/src/daemon/main.js +1 -1
- package/dist/src/hooks/post-tool-use.js +1 -1
- package/dist/src/hooks/session-end.js +1 -1
- package/dist/src/hooks/session-start.js +1 -1
- package/dist/src/hooks/stop.js +1 -1
- package/dist/src/hooks/user-prompt-submit.js +1 -1
- package/dist/src/mcp/server.js +1 -1
- package/dist/{stats-IUJPZSVZ.js → stats-CDQXOTEC.js} +9 -9
- package/dist/{stop-XRQLLXST.js → stop-WSFGRPXZ.js} +6 -6
- package/dist/{stop-failure-2CAJJKRG.js → stop-failure-4FR7574F.js} +7 -7
- package/dist/{subagent-start-MWWQTZMQ.js → subagent-start-7SGBXJYP.js} +7 -7
- package/dist/{subagent-stop-PJXYGRXB.js → subagent-stop-MRVTNX3V.js} +7 -7
- package/dist/{task-completed-4LFRJVGI.js → task-completed-XXPYPSRV.js} +7 -7
- package/dist/team-XMHYCKFF.js +251 -0
- package/dist/team-XMHYCKFF.js.map +1 -0
- package/dist/ui/assets/index-BGbil7f1.css +1 -0
- package/dist/ui/assets/index-CPA_uq_j.js +794 -0
- package/dist/ui/index.html +2 -2
- package/dist/update-W3UFZU4G.js +79 -0
- package/dist/update-W3UFZU4G.js.map +1 -0
- package/dist/{user-prompt-submit-KSM3AR6P.js → user-prompt-submit-LSWCYUW3.js} +6 -6
- package/dist/{verify-UDAYVX37.js → verify-O7TQ5DDY.js} +9 -9
- package/dist/{version-KLBN4HZT.js → version-VWWY7SPQ.js} +2 -2
- package/dist/version-VWWY7SPQ.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-3K5WGSJ4.js.map +0 -1
- package/dist/chunk-4LPQ26CK.js.map +0 -1
- package/dist/chunk-KV4OC4H3.js.map +0 -1
- package/dist/chunk-MHSCMET3.js.map +0 -1
- package/dist/chunk-OXZSXYAT.js.map +0 -1
- package/dist/chunk-TRUJLI6K.js.map +0 -1
- package/dist/chunk-YDN4OM33.js.map +0 -1
- package/dist/cli-ODLFRIYS.js.map +0 -1
- package/dist/client-MXRNQ5FI.js +0 -13
- package/dist/executor-ONSDHPGX.js.map +0 -1
- package/dist/llm-BV3QNVRD.js +0 -17
- package/dist/main-BMCL7CPO.js.map +0 -1
- package/dist/ui/assets/index-DZrElonz.js +0 -744
- package/dist/ui/assets/index-TkeiYbZB.css +0 -1
- /package/dist/{agent-run-EFICNTAU.js.map → agent-run-CGXF5PPC.js.map} +0 -0
- /package/dist/{agent-tasks-RXJ7Z5NG.js.map → agent-tasks-T7NVI3R7.js.map} +0 -0
- /package/dist/{chunk-JMJJEQ3P.js.map → chunk-5LPERML5.js.map} +0 -0
- /package/dist/{chunk-RJ6ZQKG5.js.map → chunk-5QERXFH7.js.map} +0 -0
- /package/dist/{chunk-UBZPD4HN.js.map → chunk-5SDH75YC.js.map} +0 -0
- /package/dist/{chunk-46PWOKSI.js.map → chunk-AEJS57ZK.js.map} +0 -0
- /package/dist/{chunk-DCXRSSBP.js.map → chunk-C3AEZ3BZ.js.map} +0 -0
- /package/dist/{chunk-U3IBO3O3.js.map → chunk-FMIWFRAM.js.map} +0 -0
- /package/dist/{chunk-KYLDNM7H.js.map → chunk-FPMEIN2W.js.map} +0 -0
- /package/dist/{chunk-PB6TOLRQ.js.map → chunk-G2LQBFE3.js.map} +0 -0
- /package/dist/{chunk-XNOCTDHF.js.map → chunk-J4RVYUH4.js.map} +0 -0
- /package/dist/{chunk-JYOOJCPQ.js.map → chunk-MKKXCCQ5.js.map} +0 -0
- /package/dist/{chunk-QIK2XSDQ.js.map → chunk-MSXYUXZR.js.map} +0 -0
- /package/dist/{chunk-FFAYUQ5N.js.map → chunk-RJMXDUMA.js.map} +0 -0
- /package/dist/{chunk-PT5IC642.js.map → chunk-W6HI4CCS.js.map} +0 -0
- /package/dist/{chunk-2T7RPVPP.js.map → chunk-ZESTWGJT.js.map} +0 -0
- /package/dist/{chunk-BUSP3OJB.js.map → chunk-ZMW6KQX2.js.map} +0 -0
- /package/dist/{client-MXRNQ5FI.js.map → client-B27SN5QG.js.map} +0 -0
- /package/dist/{config-UR5BSGVX.js.map → config-G3CSGI7P.js.map} +0 -0
- /package/dist/{detect-providers-Q42OD4OS.js.map → detect-providers-AZ6DEQU7.js.map} +0 -0
- /package/dist/{doctor-JLKTXDEH.js.map → doctor-RHHWJTMB.js.map} +0 -0
- /package/dist/{init-6GWY345B.js.map → init-ARJROOWV.js.map} +0 -0
- /package/dist/{init-wizard-UONLDYLI.js.map → init-wizard-XNFOZCEB.js.map} +0 -0
- /package/dist/{llm-BV3QNVRD.js.map → llm-XJFHRFHB.js.map} +0 -0
- /package/dist/{loader-SH67XD54.js.map → loader-GKXR5ONU.js.map} +0 -0
- /package/dist/{loader-XVXKZZDH.js.map → loader-PZ7ZRSA4.js.map} +0 -0
- /package/dist/{logs-QZVYF6FP.js.map → logs-LXHPDKUA.js.map} +0 -0
- /package/dist/{openai-embeddings-C265WRNK.js.map → machine-id-RCM7TXPJ.js.map} +0 -0
- /package/dist/{openrouter-U6VFCRX2.js.map → openai-embeddings-ST3B6GW7.js.map} +0 -0
- /package/dist/{provider-check-3WBPZADE.js.map → openrouter-HJHOO3EO.js.map} +0 -0
- /package/dist/{post-compact-OWFSOITU.js.map → post-compact-LR3DSGT3.js.map} +0 -0
- /package/dist/{post-tool-use-DOUM7CGQ.js.map → post-tool-use-SOFVNFU3.js.map} +0 -0
- /package/dist/{post-tool-use-failure-SG3C7PE6.js.map → post-tool-use-failure-2CZZZASB.js.map} +0 -0
- /package/dist/{pre-compact-3J33CHXQ.js.map → pre-compact-3E3D6565.js.map} +0 -0
- /package/dist/{registry-J4XTWARS.js.map → provider-check-SOTDYLJE.js.map} +0 -0
- /package/dist/{resolution-events-TFEQPVKS.js.map → registry-WVZG6R2R.js.map} +0 -0
- /package/dist/{version-KLBN4HZT.js.map → resolution-events-UPHJJLDQ.js.map} +0 -0
- /package/dist/{restart-2VM33WOB.js.map → restart-XIUFVS33.js.map} +0 -0
- /package/dist/{search-ZGQR5MDE.js.map → search-VB6Z2ZXV.js.map} +0 -0
- /package/dist/{server-6KMBJCHZ.js.map → server-AKPBRP6Z.js.map} +0 -0
- /package/dist/{session-end-FLVX32LE.js.map → session-end-YMQ44U6Z.js.map} +0 -0
- /package/dist/{setup-llm-GKMCHURK.js.map → setup-llm-NWHOPJUV.js.map} +0 -0
- /package/dist/{stats-IUJPZSVZ.js.map → stats-CDQXOTEC.js.map} +0 -0
- /package/dist/{stop-XRQLLXST.js.map → stop-WSFGRPXZ.js.map} +0 -0
- /package/dist/{stop-failure-2CAJJKRG.js.map → stop-failure-4FR7574F.js.map} +0 -0
- /package/dist/{subagent-start-MWWQTZMQ.js.map → subagent-start-7SGBXJYP.js.map} +0 -0
- /package/dist/{subagent-stop-PJXYGRXB.js.map → subagent-stop-MRVTNX3V.js.map} +0 -0
- /package/dist/{task-completed-4LFRJVGI.js.map → task-completed-XXPYPSRV.js.map} +0 -0
- /package/dist/{user-prompt-submit-KSM3AR6P.js.map → user-prompt-submit-LSWCYUW3.js.map} +0 -0
- /package/dist/{verify-UDAYVX37.js.map → verify-O7TQ5DDY.js.map} +0 -0
|
@@ -2,7 +2,7 @@ import { createRequire as __cr } from 'node:module'; const require = __cr(import
|
|
|
2
2
|
import {
|
|
3
3
|
DaemonLogger,
|
|
4
4
|
LEVEL_ORDER
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-ZESTWGJT.js";
|
|
6
6
|
import {
|
|
7
7
|
EMBEDDABLE_TABLES,
|
|
8
8
|
EMBEDDABLE_TEXT_COLUMNS,
|
|
@@ -12,13 +12,16 @@ import {
|
|
|
12
12
|
getEmbeddingQueueDepth,
|
|
13
13
|
getUnembedded,
|
|
14
14
|
markEmbedded
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-MSXYUXZR.js";
|
|
16
16
|
import {
|
|
17
17
|
withTaskConfig
|
|
18
18
|
} from "./chunk-M5XWW7UI.js";
|
|
19
|
+
import {
|
|
20
|
+
getMachineId
|
|
21
|
+
} from "./chunk-ENWBFX7F.js";
|
|
19
22
|
import {
|
|
20
23
|
createEmbeddingProvider
|
|
21
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-MKKXCCQ5.js";
|
|
22
25
|
import {
|
|
23
26
|
closeOpenBatches,
|
|
24
27
|
countRuns,
|
|
@@ -41,45 +44,47 @@ import {
|
|
|
41
44
|
listTurnsByRun,
|
|
42
45
|
populateBatchResponses,
|
|
43
46
|
setResponseSummary
|
|
44
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-FFQES5MC.js";
|
|
45
48
|
import {
|
|
46
49
|
fullTextSearch,
|
|
47
50
|
hydrateSearchResults
|
|
48
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-W6HI4CCS.js";
|
|
49
52
|
import {
|
|
50
53
|
copyTaskToUser,
|
|
51
54
|
deleteUserTask,
|
|
52
55
|
loadAllTasks,
|
|
53
56
|
validateTaskName,
|
|
54
57
|
writeUserTask
|
|
55
|
-
} from "./chunk-
|
|
58
|
+
} from "./chunk-ZMW6KQX2.js";
|
|
56
59
|
import {
|
|
57
60
|
AgentTaskSchema,
|
|
58
61
|
registerAgent,
|
|
59
62
|
resolveDefinitionsDir,
|
|
60
63
|
taskFromParsed
|
|
61
|
-
} from "./chunk-
|
|
64
|
+
} from "./chunk-5LPERML5.js";
|
|
62
65
|
import {
|
|
63
66
|
checkLocalProvider
|
|
64
|
-
} from "./chunk-
|
|
67
|
+
} from "./chunk-C3AEZ3BZ.js";
|
|
65
68
|
import {
|
|
66
69
|
EventBuffer,
|
|
67
70
|
cleanStaleBuffers,
|
|
68
71
|
listBufferSessionIds
|
|
69
72
|
} from "./chunk-V7XG6V6C.js";
|
|
70
73
|
import "./chunk-IB76KGBY.js";
|
|
71
|
-
import "./chunk-
|
|
72
|
-
import "./chunk-
|
|
73
|
-
import "./chunk-
|
|
74
|
+
import "./chunk-AEJS57ZK.js";
|
|
75
|
+
import "./chunk-5QERXFH7.js";
|
|
76
|
+
import "./chunk-FPMEIN2W.js";
|
|
74
77
|
import {
|
|
75
|
-
loadSecrets
|
|
76
|
-
|
|
78
|
+
loadSecrets,
|
|
79
|
+
readSecrets,
|
|
80
|
+
writeSecret
|
|
81
|
+
} from "./chunk-RJMXDUMA.js";
|
|
77
82
|
import {
|
|
78
83
|
SymbiontRegistry,
|
|
79
84
|
claudeCodeAdapter,
|
|
80
85
|
createPerProjectAdapter,
|
|
81
86
|
extensionForMimeType
|
|
82
|
-
} from "./chunk-
|
|
87
|
+
} from "./chunk-WXSJKESH.js";
|
|
83
88
|
import "./chunk-SAKJMNSR.js";
|
|
84
89
|
import {
|
|
85
90
|
loadManifests
|
|
@@ -87,14 +92,14 @@ import {
|
|
|
87
92
|
import {
|
|
88
93
|
LmStudioBackend,
|
|
89
94
|
OllamaBackend
|
|
90
|
-
} from "./chunk-
|
|
95
|
+
} from "./chunk-5SDH75YC.js";
|
|
91
96
|
import {
|
|
92
97
|
countSpores,
|
|
93
98
|
getSpore,
|
|
94
99
|
insertSpore,
|
|
95
100
|
listSpores,
|
|
96
101
|
updateSporeStatus
|
|
97
|
-
} from "./chunk-
|
|
102
|
+
} from "./chunk-U7UUJ4FD.js";
|
|
98
103
|
import {
|
|
99
104
|
closeSession,
|
|
100
105
|
countSessions,
|
|
@@ -104,17 +109,29 @@ import {
|
|
|
104
109
|
listSessions,
|
|
105
110
|
updateSession,
|
|
106
111
|
upsertSession
|
|
107
|
-
} from "./chunk-
|
|
112
|
+
} from "./chunk-CUDM5YJY.js";
|
|
113
|
+
import {
|
|
114
|
+
backfillUnsynced,
|
|
115
|
+
countPending,
|
|
116
|
+
initTeamContext,
|
|
117
|
+
listPending,
|
|
118
|
+
markSent,
|
|
119
|
+
pruneOld,
|
|
120
|
+
syncRow
|
|
121
|
+
} from "./chunk-XLY3REL3.js";
|
|
108
122
|
import {
|
|
109
123
|
EMBEDDING_DIMENSIONS,
|
|
124
|
+
SCHEMA_VERSION,
|
|
110
125
|
createSchema
|
|
111
|
-
} from "./chunk-
|
|
126
|
+
} from "./chunk-WZZH3YXJ.js";
|
|
112
127
|
import {
|
|
113
128
|
CONFIG_FILENAME,
|
|
114
129
|
MycoConfigSchema,
|
|
115
130
|
loadConfig,
|
|
116
|
-
|
|
117
|
-
|
|
131
|
+
updateBackupConfig,
|
|
132
|
+
updateConfig,
|
|
133
|
+
updateTeamConfig
|
|
134
|
+
} from "./chunk-MAZOVVDU.js";
|
|
118
135
|
import {
|
|
119
136
|
require_dist
|
|
120
137
|
} from "./chunk-D7TYRPRM.js";
|
|
@@ -128,13 +145,16 @@ import {
|
|
|
128
145
|
initDatabase,
|
|
129
146
|
vaultDbPath
|
|
130
147
|
} from "./chunk-MYX5NCRH.js";
|
|
131
|
-
import
|
|
148
|
+
import {
|
|
149
|
+
resolveCliEntryPath
|
|
150
|
+
} from "./chunk-YZMNEIFI.js";
|
|
132
151
|
import {
|
|
133
152
|
CONTENT_HASH_ALGORITHM,
|
|
134
153
|
DAEMON_EVICT_POLL_MS,
|
|
135
154
|
DAEMON_EVICT_TIMEOUT_MS,
|
|
136
155
|
DEAD_SESSION_MAX_PROMPTS,
|
|
137
156
|
DEFAULT_AGENT_ID,
|
|
157
|
+
DEFAULT_MACHINE_ID,
|
|
138
158
|
EMBEDDING_BATCH_SIZE,
|
|
139
159
|
EXCLUDED_SPORE_STATUSES,
|
|
140
160
|
FEED_DEFAULT_LIMIT,
|
|
@@ -157,19 +177,24 @@ import {
|
|
|
157
177
|
SEARCH_SIMILARITY_THRESHOLD,
|
|
158
178
|
STALE_BUFFER_MAX_AGE_MS,
|
|
159
179
|
STALE_SESSION_THRESHOLD_MS,
|
|
180
|
+
SYNC_PROTOCOL_VERSION,
|
|
181
|
+
TEAM_API_KEY_SECRET,
|
|
182
|
+
TEAM_HEALTH_TIMEOUT_MS,
|
|
183
|
+
TEAM_SEARCH_TIMEOUT_MS,
|
|
184
|
+
TEAM_SOURCE_PREFIX,
|
|
160
185
|
USER_AGENT_ID,
|
|
161
186
|
USER_AGENT_NAME,
|
|
162
187
|
USER_TASK_SOURCE,
|
|
163
188
|
epochSeconds,
|
|
164
189
|
estimateTokens
|
|
165
|
-
} from "./chunk-
|
|
190
|
+
} from "./chunk-76ZO5RGT.js";
|
|
166
191
|
import {
|
|
167
192
|
LOG_KINDS,
|
|
168
193
|
kindToComponent
|
|
169
|
-
} from "./chunk-
|
|
194
|
+
} from "./chunk-S6I62FAH.js";
|
|
170
195
|
import {
|
|
171
196
|
getPluginVersion
|
|
172
|
-
} from "./chunk-
|
|
197
|
+
} from "./chunk-G2LQBFE3.js";
|
|
173
198
|
import {
|
|
174
199
|
findPackageRoot
|
|
175
200
|
} from "./chunk-LPUQPDC2.js";
|
|
@@ -633,7 +658,9 @@ var PLAN_COLUMNS = [
|
|
|
633
658
|
"processed",
|
|
634
659
|
"embedded",
|
|
635
660
|
"created_at",
|
|
636
|
-
"updated_at"
|
|
661
|
+
"updated_at",
|
|
662
|
+
"machine_id",
|
|
663
|
+
"synced_at"
|
|
637
664
|
];
|
|
638
665
|
var SELECT_COLUMNS = PLAN_COLUMNS.join(", ");
|
|
639
666
|
function toPlanRow(row) {
|
|
@@ -651,7 +678,9 @@ function toPlanRow(row) {
|
|
|
651
678
|
processed: row.processed,
|
|
652
679
|
embedded: row.embedded ?? 0,
|
|
653
680
|
created_at: row.created_at,
|
|
654
|
-
updated_at: row.updated_at ?? null
|
|
681
|
+
updated_at: row.updated_at ?? null,
|
|
682
|
+
machine_id: row.machine_id ?? DEFAULT_MACHINE_ID,
|
|
683
|
+
synced_at: row.synced_at ?? null
|
|
655
684
|
};
|
|
656
685
|
}
|
|
657
686
|
function upsertPlan(data) {
|
|
@@ -660,11 +689,11 @@ function upsertPlan(data) {
|
|
|
660
689
|
`INSERT INTO plans (
|
|
661
690
|
id, status, author, title, content,
|
|
662
691
|
source_path, tags, session_id, prompt_batch_id, content_hash,
|
|
663
|
-
processed, created_at, updated_at
|
|
692
|
+
processed, created_at, updated_at, machine_id
|
|
664
693
|
) VALUES (
|
|
665
694
|
?, ?, ?, ?, ?,
|
|
666
695
|
?, ?, ?, ?, ?,
|
|
667
|
-
?, ?, ?
|
|
696
|
+
?, ?, ?, ?
|
|
668
697
|
)
|
|
669
698
|
ON CONFLICT (id) DO UPDATE SET
|
|
670
699
|
status = EXCLUDED.status,
|
|
@@ -695,11 +724,14 @@ function upsertPlan(data) {
|
|
|
695
724
|
data.content_hash ?? null,
|
|
696
725
|
data.processed ?? DEFAULT_PROCESSED,
|
|
697
726
|
data.created_at,
|
|
698
|
-
data.updated_at ?? null
|
|
727
|
+
data.updated_at ?? null,
|
|
728
|
+
data.machine_id ?? DEFAULT_MACHINE_ID
|
|
699
729
|
);
|
|
700
|
-
|
|
730
|
+
const row = toPlanRow(
|
|
701
731
|
db.prepare(`SELECT ${SELECT_COLUMNS} FROM plans WHERE id = ?`).get(data.id)
|
|
702
732
|
);
|
|
733
|
+
syncRow("plans", row);
|
|
734
|
+
return row;
|
|
703
735
|
}
|
|
704
736
|
function listPlans(options = {}) {
|
|
705
737
|
const db = getDatabase();
|
|
@@ -787,7 +819,9 @@ function mergeConfigSections(current, incoming) {
|
|
|
787
819
|
embedding: { ...current.embedding, ...incoming.embedding },
|
|
788
820
|
capture: { ...current.capture, ...incoming.capture },
|
|
789
821
|
agent: { ...current.agent, ...incoming.agent },
|
|
790
|
-
context: { ...current.context, ...incoming.context }
|
|
822
|
+
context: { ...current.context, ...incoming.context },
|
|
823
|
+
backup: { ...current.backup, ...incoming.backup },
|
|
824
|
+
team: { ...current.team, ...incoming.team }
|
|
791
825
|
};
|
|
792
826
|
}
|
|
793
827
|
async function handleGetConfig(vaultDir) {
|
|
@@ -1025,8 +1059,8 @@ async function handleRestart(deps, body) {
|
|
|
1025
1059
|
body: { status: "busy", message: "Active operations in progress. Use force=true to override." }
|
|
1026
1060
|
};
|
|
1027
1061
|
}
|
|
1028
|
-
const
|
|
1029
|
-
const shellCmd = `sleep ${RESTART_CHILD_DELAY_SECONDS} && ${
|
|
1062
|
+
const { execPath, cliEntry } = resolveCliEntryPath();
|
|
1063
|
+
const shellCmd = `sleep ${RESTART_CHILD_DELAY_SECONDS} && ${execPath} ${cliEntry} daemon --vault ${deps.vaultDir}`;
|
|
1030
1064
|
const child = spawn("/bin/sh", ["-c", shellCmd], {
|
|
1031
1065
|
detached: true,
|
|
1032
1066
|
stdio: "ignore"
|
|
@@ -1038,6 +1072,431 @@ async function handleRestart(deps, body) {
|
|
|
1038
1072
|
return { body: { status: "restarting" } };
|
|
1039
1073
|
}
|
|
1040
1074
|
|
|
1075
|
+
// src/daemon/backup.ts
|
|
1076
|
+
import fs3 from "fs";
|
|
1077
|
+
import path4 from "path";
|
|
1078
|
+
var BACKUP_TABLES = [
|
|
1079
|
+
"sessions",
|
|
1080
|
+
"prompt_batches",
|
|
1081
|
+
"spores",
|
|
1082
|
+
"entities",
|
|
1083
|
+
"graph_edges",
|
|
1084
|
+
"entity_mentions",
|
|
1085
|
+
"resolution_events",
|
|
1086
|
+
"plans",
|
|
1087
|
+
"artifacts",
|
|
1088
|
+
"digest_extracts",
|
|
1089
|
+
"team_members"
|
|
1090
|
+
];
|
|
1091
|
+
var BACKUP_EXTENSION = ".sql";
|
|
1092
|
+
var BACKUP_HEADER_TEMPLATE = "-- Myco backup";
|
|
1093
|
+
function escapeSql(value) {
|
|
1094
|
+
return value.replace(/'/g, "''");
|
|
1095
|
+
}
|
|
1096
|
+
function toSqlLiteral(value) {
|
|
1097
|
+
if (value === null || value === void 0) return "NULL";
|
|
1098
|
+
if (typeof value === "number") return String(value);
|
|
1099
|
+
if (Buffer.isBuffer(value)) return `X'${value.toString("hex")}'`;
|
|
1100
|
+
return `'${escapeSql(String(value))}'`;
|
|
1101
|
+
}
|
|
1102
|
+
function createBackup(db, backupDir, machineId) {
|
|
1103
|
+
fs3.mkdirSync(backupDir, { recursive: true });
|
|
1104
|
+
const lines = [];
|
|
1105
|
+
const timestamp = epochSeconds();
|
|
1106
|
+
lines.push(`${BACKUP_HEADER_TEMPLATE}: machine_id=${machineId}, created_at=${timestamp}`);
|
|
1107
|
+
lines.push(`-- Protocol version: ${SYNC_PROTOCOL_VERSION}`);
|
|
1108
|
+
lines.push("");
|
|
1109
|
+
for (const table of BACKUP_TABLES) {
|
|
1110
|
+
const rows = db.prepare(`SELECT * FROM ${table}`).all();
|
|
1111
|
+
if (rows.length === 0) continue;
|
|
1112
|
+
lines.push(`-- Table: ${table} (${rows.length} rows)`);
|
|
1113
|
+
const columns = Object.keys(rows[0]);
|
|
1114
|
+
const columnList = columns.map((c) => `"${c}"`).join(", ");
|
|
1115
|
+
for (const row of rows) {
|
|
1116
|
+
const values = columns.map((c) => toSqlLiteral(row[c])).join(", ");
|
|
1117
|
+
lines.push(`INSERT OR IGNORE INTO ${table} (${columnList}) VALUES (${values});`);
|
|
1118
|
+
}
|
|
1119
|
+
lines.push("");
|
|
1120
|
+
}
|
|
1121
|
+
const filePath = path4.join(backupDir, `${machineId}${BACKUP_EXTENSION}`);
|
|
1122
|
+
fs3.writeFileSync(filePath, lines.join("\n"), "utf-8");
|
|
1123
|
+
return filePath;
|
|
1124
|
+
}
|
|
1125
|
+
function listBackups(backupDir) {
|
|
1126
|
+
let entries;
|
|
1127
|
+
try {
|
|
1128
|
+
entries = fs3.readdirSync(backupDir);
|
|
1129
|
+
} catch {
|
|
1130
|
+
return [];
|
|
1131
|
+
}
|
|
1132
|
+
const backups = [];
|
|
1133
|
+
for (const entry of entries) {
|
|
1134
|
+
if (!entry.endsWith(BACKUP_EXTENSION)) continue;
|
|
1135
|
+
const filePath = path4.join(backupDir, entry);
|
|
1136
|
+
const stat = fs3.statSync(filePath);
|
|
1137
|
+
backups.push({
|
|
1138
|
+
machine_id: entry.slice(0, -BACKUP_EXTENSION.length),
|
|
1139
|
+
file_name: entry,
|
|
1140
|
+
size_bytes: stat.size,
|
|
1141
|
+
modified_at: stat.mtime.toISOString()
|
|
1142
|
+
});
|
|
1143
|
+
}
|
|
1144
|
+
return backups.sort((a, b) => b.modified_at.localeCompare(a.modified_at));
|
|
1145
|
+
}
|
|
1146
|
+
var INSERT_REGEX = /^INSERT OR IGNORE INTO (\w+)\s+\(([^)]+)\)\s+VALUES\s+\((.+)\);$/;
|
|
1147
|
+
function parseBackupFile(backupPath) {
|
|
1148
|
+
const content = fs3.readFileSync(backupPath, "utf-8");
|
|
1149
|
+
const inserts = [];
|
|
1150
|
+
for (const line of content.split("\n")) {
|
|
1151
|
+
const match = INSERT_REGEX.exec(line);
|
|
1152
|
+
if (!match) continue;
|
|
1153
|
+
inserts.push({
|
|
1154
|
+
table: match[1],
|
|
1155
|
+
columns: match[2].split(",").map((c) => c.trim().replace(/"/g, "")),
|
|
1156
|
+
valueSql: match[3]
|
|
1157
|
+
});
|
|
1158
|
+
}
|
|
1159
|
+
return inserts;
|
|
1160
|
+
}
|
|
1161
|
+
function restorePreview(db, backupPath) {
|
|
1162
|
+
const inserts = parseBackupFile(backupPath);
|
|
1163
|
+
const counts = /* @__PURE__ */ new Map();
|
|
1164
|
+
db.pragma("foreign_keys = OFF");
|
|
1165
|
+
db.exec("SAVEPOINT restore_preview");
|
|
1166
|
+
try {
|
|
1167
|
+
for (const insert of inserts) {
|
|
1168
|
+
if (!counts.has(insert.table)) {
|
|
1169
|
+
counts.set(insert.table, { new: 0, existing: 0 });
|
|
1170
|
+
}
|
|
1171
|
+
const tableCounts = counts.get(insert.table);
|
|
1172
|
+
try {
|
|
1173
|
+
const columnList = insert.columns.map((c) => `"${c}"`).join(", ");
|
|
1174
|
+
const stmt = `INSERT OR IGNORE INTO ${insert.table} (${columnList}) VALUES (${insert.valueSql})`;
|
|
1175
|
+
const result = db.prepare(stmt).run();
|
|
1176
|
+
if (result.changes > 0) {
|
|
1177
|
+
tableCounts.new++;
|
|
1178
|
+
} else {
|
|
1179
|
+
tableCounts.existing++;
|
|
1180
|
+
}
|
|
1181
|
+
} catch {
|
|
1182
|
+
tableCounts.existing++;
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
} finally {
|
|
1186
|
+
db.exec("ROLLBACK TO restore_preview");
|
|
1187
|
+
db.exec("RELEASE restore_preview");
|
|
1188
|
+
db.pragma("foreign_keys = ON");
|
|
1189
|
+
}
|
|
1190
|
+
return Array.from(counts.entries()).map(([table, c]) => ({
|
|
1191
|
+
table,
|
|
1192
|
+
new: c.new,
|
|
1193
|
+
existing: c.existing
|
|
1194
|
+
}));
|
|
1195
|
+
}
|
|
1196
|
+
function restoreBackup(db, backupPath) {
|
|
1197
|
+
const inserts = parseBackupFile(backupPath);
|
|
1198
|
+
const counts = /* @__PURE__ */ new Map();
|
|
1199
|
+
db.pragma("foreign_keys = OFF");
|
|
1200
|
+
try {
|
|
1201
|
+
const runRestore = db.transaction(() => {
|
|
1202
|
+
for (const insert of inserts) {
|
|
1203
|
+
if (!counts.has(insert.table)) {
|
|
1204
|
+
counts.set(insert.table, { new: 0, existing: 0 });
|
|
1205
|
+
}
|
|
1206
|
+
const tableCounts = counts.get(insert.table);
|
|
1207
|
+
const columnList = insert.columns.map((c) => `"${c}"`).join(", ");
|
|
1208
|
+
const stmt = `INSERT OR IGNORE INTO ${insert.table} (${columnList}) VALUES (${insert.valueSql})`;
|
|
1209
|
+
const result = db.prepare(stmt).run();
|
|
1210
|
+
if (result.changes > 0) {
|
|
1211
|
+
tableCounts.new++;
|
|
1212
|
+
} else {
|
|
1213
|
+
tableCounts.existing++;
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
});
|
|
1217
|
+
runRestore();
|
|
1218
|
+
} finally {
|
|
1219
|
+
db.pragma("foreign_keys = ON");
|
|
1220
|
+
}
|
|
1221
|
+
const tables = Array.from(counts.entries()).map(([table, c]) => ({
|
|
1222
|
+
table,
|
|
1223
|
+
new: c.new,
|
|
1224
|
+
existing: c.existing
|
|
1225
|
+
}));
|
|
1226
|
+
const total_restored = tables.reduce((sum, t) => sum + t.new, 0);
|
|
1227
|
+
const total_skipped = tables.reduce((sum, t) => sum + t.existing, 0);
|
|
1228
|
+
return { tables, total_restored, total_skipped };
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
// src/daemon/api/backup.ts
|
|
1232
|
+
function createBackupHandlers(deps) {
|
|
1233
|
+
async function handleCreateBackup(_req) {
|
|
1234
|
+
const filePath = createBackup(deps.db, deps.backupDir, deps.machineId);
|
|
1235
|
+
const backups = listBackups(deps.backupDir);
|
|
1236
|
+
const created = backups.find((b) => b.machine_id === deps.machineId);
|
|
1237
|
+
return {
|
|
1238
|
+
body: {
|
|
1239
|
+
file_path: filePath,
|
|
1240
|
+
machine_id: deps.machineId,
|
|
1241
|
+
size_bytes: created?.size_bytes ?? 0
|
|
1242
|
+
}
|
|
1243
|
+
};
|
|
1244
|
+
}
|
|
1245
|
+
async function handleListBackups(_req) {
|
|
1246
|
+
const backups = listBackups(deps.backupDir);
|
|
1247
|
+
return { body: { backups } };
|
|
1248
|
+
}
|
|
1249
|
+
async function handleRestorePreview(req) {
|
|
1250
|
+
const { machine_id } = req.body;
|
|
1251
|
+
if (!machine_id) {
|
|
1252
|
+
return { status: 400, body: { error: "missing_machine_id" } };
|
|
1253
|
+
}
|
|
1254
|
+
const backups = listBackups(deps.backupDir);
|
|
1255
|
+
const backup = backups.find((b) => b.machine_id === machine_id);
|
|
1256
|
+
if (!backup) {
|
|
1257
|
+
return { status: 404, body: { error: "backup_not_found" } };
|
|
1258
|
+
}
|
|
1259
|
+
const backupPath = `${deps.backupDir}/${backup.file_name}`;
|
|
1260
|
+
const tables = restorePreview(deps.db, backupPath);
|
|
1261
|
+
const total_new = tables.reduce((sum, t) => sum + t.new, 0);
|
|
1262
|
+
const total_existing = tables.reduce((sum, t) => sum + t.existing, 0);
|
|
1263
|
+
return { body: { machine_id, tables, total_new, total_existing } };
|
|
1264
|
+
}
|
|
1265
|
+
async function handleRestore(req) {
|
|
1266
|
+
const { machine_id } = req.body;
|
|
1267
|
+
if (!machine_id) {
|
|
1268
|
+
return { status: 400, body: { error: "missing_machine_id" } };
|
|
1269
|
+
}
|
|
1270
|
+
const backups = listBackups(deps.backupDir);
|
|
1271
|
+
const backup = backups.find((b) => b.machine_id === machine_id);
|
|
1272
|
+
if (!backup) {
|
|
1273
|
+
return { status: 404, body: { error: "backup_not_found" } };
|
|
1274
|
+
}
|
|
1275
|
+
const backupPath = `${deps.backupDir}/${backup.file_name}`;
|
|
1276
|
+
const result = restoreBackup(deps.db, backupPath);
|
|
1277
|
+
return { body: { machine_id, ...result } };
|
|
1278
|
+
}
|
|
1279
|
+
return {
|
|
1280
|
+
handleCreateBackup,
|
|
1281
|
+
handleListBackups,
|
|
1282
|
+
handleRestorePreview,
|
|
1283
|
+
handleRestore
|
|
1284
|
+
};
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
// src/daemon/team-sync.ts
|
|
1288
|
+
var TeamSyncClient = class {
|
|
1289
|
+
workerUrl;
|
|
1290
|
+
apiKey;
|
|
1291
|
+
machineId;
|
|
1292
|
+
syncProtocolVersion;
|
|
1293
|
+
fetchFn;
|
|
1294
|
+
constructor(options) {
|
|
1295
|
+
this.workerUrl = options.workerUrl.replace(/\/+$/, "");
|
|
1296
|
+
this.apiKey = options.apiKey;
|
|
1297
|
+
this.machineId = options.machineId;
|
|
1298
|
+
this.syncProtocolVersion = options.syncProtocolVersion;
|
|
1299
|
+
this.fetchFn = options.fetch ?? globalThis.fetch;
|
|
1300
|
+
}
|
|
1301
|
+
/**
|
|
1302
|
+
* Register this machine with the team worker.
|
|
1303
|
+
*/
|
|
1304
|
+
async connect(info) {
|
|
1305
|
+
const res = await this.request("POST", "/connect", {
|
|
1306
|
+
...info,
|
|
1307
|
+
machine_id: this.machineId,
|
|
1308
|
+
sync_protocol_version: this.syncProtocolVersion
|
|
1309
|
+
});
|
|
1310
|
+
return res;
|
|
1311
|
+
}
|
|
1312
|
+
/**
|
|
1313
|
+
* Push a batch of outbox records to the team worker.
|
|
1314
|
+
*
|
|
1315
|
+
* @returns the number of records accepted by the worker.
|
|
1316
|
+
*/
|
|
1317
|
+
async pushBatch(records) {
|
|
1318
|
+
const res = await this.request("POST", "/sync", {
|
|
1319
|
+
machine_id: this.machineId,
|
|
1320
|
+
sync_protocol_version: this.syncProtocolVersion,
|
|
1321
|
+
records: records.map((r) => {
|
|
1322
|
+
const data = typeof r.payload === "string" ? JSON.parse(r.payload) : r.payload;
|
|
1323
|
+
return {
|
|
1324
|
+
table: r.table_name,
|
|
1325
|
+
id: String(r.row_id),
|
|
1326
|
+
machine_id: r.machine_id,
|
|
1327
|
+
operation: r.operation,
|
|
1328
|
+
data,
|
|
1329
|
+
content_hash: data.content_hash ?? null
|
|
1330
|
+
};
|
|
1331
|
+
})
|
|
1332
|
+
});
|
|
1333
|
+
return res;
|
|
1334
|
+
}
|
|
1335
|
+
/**
|
|
1336
|
+
* Search team knowledge across all connected machines.
|
|
1337
|
+
*
|
|
1338
|
+
* Uses AbortController for timeout enforcement.
|
|
1339
|
+
*/
|
|
1340
|
+
async search(query, options = {}) {
|
|
1341
|
+
const timeoutMs = options.timeoutMs ?? TEAM_SEARCH_TIMEOUT_MS;
|
|
1342
|
+
const controller = new AbortController();
|
|
1343
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
1344
|
+
try {
|
|
1345
|
+
const params = new URLSearchParams({ q: query });
|
|
1346
|
+
if (options.limit) params.set("limit", String(options.limit));
|
|
1347
|
+
if (options.tables) params.set("tables", options.tables.join(","));
|
|
1348
|
+
const res = await this.fetchFn(`${this.workerUrl}/search?${params}`, {
|
|
1349
|
+
method: "GET",
|
|
1350
|
+
headers: this.headers(),
|
|
1351
|
+
signal: controller.signal
|
|
1352
|
+
});
|
|
1353
|
+
if (!res.ok) {
|
|
1354
|
+
throw new Error(`Team search failed: ${res.status} ${res.statusText}`);
|
|
1355
|
+
}
|
|
1356
|
+
return await res.json();
|
|
1357
|
+
} finally {
|
|
1358
|
+
clearTimeout(timer);
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1361
|
+
/**
|
|
1362
|
+
* Check worker health.
|
|
1363
|
+
*/
|
|
1364
|
+
async health() {
|
|
1365
|
+
const controller = new AbortController();
|
|
1366
|
+
const timer = setTimeout(() => controller.abort(), TEAM_HEALTH_TIMEOUT_MS);
|
|
1367
|
+
try {
|
|
1368
|
+
const res = await this.fetchFn(`${this.workerUrl}/health`, {
|
|
1369
|
+
method: "GET",
|
|
1370
|
+
headers: this.headers(),
|
|
1371
|
+
signal: controller.signal
|
|
1372
|
+
});
|
|
1373
|
+
if (!res.ok) {
|
|
1374
|
+
throw new Error(`Health check failed: ${res.status} ${res.statusText}`);
|
|
1375
|
+
}
|
|
1376
|
+
return await res.json();
|
|
1377
|
+
} finally {
|
|
1378
|
+
clearTimeout(timer);
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
/**
|
|
1382
|
+
* Get team configuration from the worker.
|
|
1383
|
+
*/
|
|
1384
|
+
async getConfig() {
|
|
1385
|
+
const res = await this.request("GET", "/config");
|
|
1386
|
+
return res;
|
|
1387
|
+
}
|
|
1388
|
+
// ---------------------------------------------------------------------------
|
|
1389
|
+
// Internal
|
|
1390
|
+
// ---------------------------------------------------------------------------
|
|
1391
|
+
headers() {
|
|
1392
|
+
return {
|
|
1393
|
+
"Authorization": `Bearer ${this.apiKey}`,
|
|
1394
|
+
"Content-Type": "application/json"
|
|
1395
|
+
};
|
|
1396
|
+
}
|
|
1397
|
+
async request(method, path8, body) {
|
|
1398
|
+
const res = await this.fetchFn(`${this.workerUrl}${path8}`, {
|
|
1399
|
+
method,
|
|
1400
|
+
headers: this.headers(),
|
|
1401
|
+
body: body !== void 0 ? JSON.stringify(body) : void 0
|
|
1402
|
+
});
|
|
1403
|
+
if (!res.ok) {
|
|
1404
|
+
const text = await res.text().catch(() => "");
|
|
1405
|
+
throw new Error(`Team sync request ${method} ${path8} failed: ${res.status} ${text}`);
|
|
1406
|
+
}
|
|
1407
|
+
return res.json();
|
|
1408
|
+
}
|
|
1409
|
+
};
|
|
1410
|
+
|
|
1411
|
+
// src/daemon/api/team-connect.ts
|
|
1412
|
+
function createTeamHandlers(deps) {
|
|
1413
|
+
const { vaultDir, machineId } = deps;
|
|
1414
|
+
async function handleConnect(req) {
|
|
1415
|
+
const { url, api_key } = req.body;
|
|
1416
|
+
if (!url || !api_key) {
|
|
1417
|
+
return {
|
|
1418
|
+
status: 400,
|
|
1419
|
+
body: { error: "missing_fields", message: "Both url and api_key are required" }
|
|
1420
|
+
};
|
|
1421
|
+
}
|
|
1422
|
+
try {
|
|
1423
|
+
new URL(url);
|
|
1424
|
+
} catch {
|
|
1425
|
+
return {
|
|
1426
|
+
status: 400,
|
|
1427
|
+
body: { error: "invalid_url", message: "Invalid worker URL" }
|
|
1428
|
+
};
|
|
1429
|
+
}
|
|
1430
|
+
const client = new TeamSyncClient({
|
|
1431
|
+
workerUrl: url,
|
|
1432
|
+
apiKey: api_key,
|
|
1433
|
+
machineId,
|
|
1434
|
+
syncProtocolVersion: SYNC_PROTOCOL_VERSION
|
|
1435
|
+
});
|
|
1436
|
+
try {
|
|
1437
|
+
await client.health();
|
|
1438
|
+
} catch (err) {
|
|
1439
|
+
return {
|
|
1440
|
+
status: 502,
|
|
1441
|
+
body: {
|
|
1442
|
+
error: "connection_failed",
|
|
1443
|
+
message: `Could not connect to team worker: ${err.message}`
|
|
1444
|
+
}
|
|
1445
|
+
};
|
|
1446
|
+
}
|
|
1447
|
+
updateTeamConfig(vaultDir, {
|
|
1448
|
+
enabled: true,
|
|
1449
|
+
worker_url: url
|
|
1450
|
+
});
|
|
1451
|
+
writeSecret(vaultDir, TEAM_API_KEY_SECRET, api_key);
|
|
1452
|
+
deps.setTeamClient(client);
|
|
1453
|
+
const config = loadConfig(vaultDir);
|
|
1454
|
+
return { body: { connected: true, team: config.team } };
|
|
1455
|
+
}
|
|
1456
|
+
async function handleDisconnect(_req) {
|
|
1457
|
+
updateTeamConfig(vaultDir, { enabled: false });
|
|
1458
|
+
deps.setTeamClient(null);
|
|
1459
|
+
return { body: { connected: false } };
|
|
1460
|
+
}
|
|
1461
|
+
async function handleStatus(_req) {
|
|
1462
|
+
const config = loadConfig(vaultDir);
|
|
1463
|
+
const client = deps.getTeamClient();
|
|
1464
|
+
const secrets = readSecrets(vaultDir);
|
|
1465
|
+
const hasApiKey = Boolean(secrets[TEAM_API_KEY_SECRET]);
|
|
1466
|
+
let healthy = false;
|
|
1467
|
+
let healthError;
|
|
1468
|
+
if (client && config.team.enabled) {
|
|
1469
|
+
try {
|
|
1470
|
+
await client.health();
|
|
1471
|
+
healthy = true;
|
|
1472
|
+
} catch (err) {
|
|
1473
|
+
healthError = err.message;
|
|
1474
|
+
}
|
|
1475
|
+
}
|
|
1476
|
+
let pendingCount = 0;
|
|
1477
|
+
try {
|
|
1478
|
+
pendingCount = countPending();
|
|
1479
|
+
} catch {
|
|
1480
|
+
}
|
|
1481
|
+
return {
|
|
1482
|
+
body: {
|
|
1483
|
+
enabled: config.team.enabled,
|
|
1484
|
+
worker_url: config.team.worker_url ?? null,
|
|
1485
|
+
has_api_key: hasApiKey,
|
|
1486
|
+
api_key: secrets[TEAM_API_KEY_SECRET] ?? null,
|
|
1487
|
+
healthy,
|
|
1488
|
+
health_error: healthError,
|
|
1489
|
+
pending_sync_count: pendingCount,
|
|
1490
|
+
machine_id: machineId,
|
|
1491
|
+
package_version: getPluginVersion(),
|
|
1492
|
+
schema_version: SCHEMA_VERSION,
|
|
1493
|
+
sync_protocol_version: SYNC_PROTOCOL_VERSION
|
|
1494
|
+
}
|
|
1495
|
+
};
|
|
1496
|
+
}
|
|
1497
|
+
return { handleConnect, handleDisconnect, handleStatus };
|
|
1498
|
+
}
|
|
1499
|
+
|
|
1041
1500
|
// src/daemon/api/progress.ts
|
|
1042
1501
|
import { randomUUID } from "crypto";
|
|
1043
1502
|
var MAX_CONCURRENT_OPERATIONS = 10;
|
|
@@ -1179,12 +1638,12 @@ async function handleGetModels(req) {
|
|
|
1179
1638
|
|
|
1180
1639
|
// src/daemon/api/stats.ts
|
|
1181
1640
|
import { createHash as createHash3 } from "crypto";
|
|
1182
|
-
import
|
|
1183
|
-
import
|
|
1641
|
+
import fs4 from "fs";
|
|
1642
|
+
import path5 from "path";
|
|
1184
1643
|
function computeConfigHash(vaultDir) {
|
|
1185
1644
|
try {
|
|
1186
|
-
const configPath =
|
|
1187
|
-
const raw =
|
|
1645
|
+
const configPath = path5.join(vaultDir, CONFIG_FILENAME);
|
|
1646
|
+
const raw = fs4.readFileSync(configPath, "utf-8");
|
|
1188
1647
|
return createHash3("md5").update(raw).digest("hex");
|
|
1189
1648
|
} catch {
|
|
1190
1649
|
return "";
|
|
@@ -1574,6 +2033,86 @@ async function handleGetGraph(req) {
|
|
|
1574
2033
|
}
|
|
1575
2034
|
};
|
|
1576
2035
|
}
|
|
2036
|
+
var FULL_GRAPH_NODE_LIMIT = 500;
|
|
2037
|
+
async function handleGetFullGraph(_req) {
|
|
2038
|
+
const db = getDatabase();
|
|
2039
|
+
const entityRows = db.prepare(
|
|
2040
|
+
`SELECT id, type, name, properties, status, first_seen as created_at
|
|
2041
|
+
FROM entities WHERE agent_id = ? LIMIT ?`
|
|
2042
|
+
).all(DEFAULT_AGENT_ID, FULL_GRAPH_NODE_LIMIT);
|
|
2043
|
+
const sporeRows = db.prepare(
|
|
2044
|
+
`SELECT id, observation_type, status, content, properties, created_at
|
|
2045
|
+
FROM spores WHERE agent_id = ? AND status = 'active' LIMIT ?`
|
|
2046
|
+
).all(DEFAULT_AGENT_ID, FULL_GRAPH_NODE_LIMIT);
|
|
2047
|
+
const sessionRows = db.prepare(
|
|
2048
|
+
`SELECT id, title, summary, status, started_at as created_at
|
|
2049
|
+
FROM sessions ORDER BY created_at DESC LIMIT ?`
|
|
2050
|
+
).all(FULL_GRAPH_NODE_LIMIT);
|
|
2051
|
+
const allIds = /* @__PURE__ */ new Set();
|
|
2052
|
+
for (const r of [...entityRows, ...sporeRows, ...sessionRows]) {
|
|
2053
|
+
allIds.add(r.id);
|
|
2054
|
+
}
|
|
2055
|
+
const excludedTypes = Array.from(EXCLUDED_GRAPH_EDGE_TYPES).map(() => "?").join(", ");
|
|
2056
|
+
const allIdsList = Array.from(allIds);
|
|
2057
|
+
const idPlaceholders = allIdsList.map(() => "?").join(", ");
|
|
2058
|
+
const edgeRows = db.prepare(
|
|
2059
|
+
`SELECT source_id, source_type, target_id, target_type, type, confidence
|
|
2060
|
+
FROM graph_edges
|
|
2061
|
+
WHERE agent_id = ?
|
|
2062
|
+
AND type NOT IN (${excludedTypes})
|
|
2063
|
+
AND source_id IN (${idPlaceholders})
|
|
2064
|
+
AND target_id IN (${idPlaceholders})`
|
|
2065
|
+
).all(DEFAULT_AGENT_ID, ...Array.from(EXCLUDED_GRAPH_EDGE_TYPES), ...allIdsList, ...allIdsList);
|
|
2066
|
+
const filteredEdges = edgeRows;
|
|
2067
|
+
const mentionCounts = /* @__PURE__ */ new Map();
|
|
2068
|
+
const entityIdArray = entityRows.map((r) => r.id);
|
|
2069
|
+
if (entityIdArray.length > 0) {
|
|
2070
|
+
const placeholders = entityIdArray.map(() => "?").join(", ");
|
|
2071
|
+
const mentionRows = db.prepare(
|
|
2072
|
+
`SELECT entity_id, COUNT(*) as count FROM entity_mentions
|
|
2073
|
+
WHERE entity_id IN (${placeholders}) GROUP BY entity_id`
|
|
2074
|
+
).all(...entityIdArray);
|
|
2075
|
+
for (const row of mentionRows) {
|
|
2076
|
+
mentionCounts.set(row.entity_id, Number(row.count));
|
|
2077
|
+
}
|
|
2078
|
+
}
|
|
2079
|
+
const nodes = [
|
|
2080
|
+
...entityRows.map((n) => ({
|
|
2081
|
+
id: n.id,
|
|
2082
|
+
name: n.name,
|
|
2083
|
+
type: n.type,
|
|
2084
|
+
status: n.status ?? void 0,
|
|
2085
|
+
created_at: n.created_at,
|
|
2086
|
+
properties: n.properties ?? void 0,
|
|
2087
|
+
mention_count: mentionCounts.get(n.id) ?? 0
|
|
2088
|
+
})),
|
|
2089
|
+
...sporeRows.map((n) => ({
|
|
2090
|
+
id: n.id,
|
|
2091
|
+
name: (n.content ?? "").slice(0, SPORE_NAME_PREVIEW_CHARS),
|
|
2092
|
+
type: "spore",
|
|
2093
|
+
status: n.status ?? void 0,
|
|
2094
|
+
created_at: n.created_at,
|
|
2095
|
+
content: n.content,
|
|
2096
|
+
properties: n.properties ?? void 0,
|
|
2097
|
+
observation_type: n.observation_type
|
|
2098
|
+
})),
|
|
2099
|
+
...sessionRows.map((n) => ({
|
|
2100
|
+
id: n.id,
|
|
2101
|
+
name: n.title ?? `Session ${n.id.slice(-6)}`,
|
|
2102
|
+
type: "session",
|
|
2103
|
+
status: n.status ?? void 0,
|
|
2104
|
+
created_at: n.created_at,
|
|
2105
|
+
content: n.summary ?? void 0
|
|
2106
|
+
}))
|
|
2107
|
+
];
|
|
2108
|
+
const edges = filteredEdges.map((e) => ({
|
|
2109
|
+
source_id: e.source_id,
|
|
2110
|
+
target_id: e.target_id,
|
|
2111
|
+
label: e.type,
|
|
2112
|
+
weight: e.confidence
|
|
2113
|
+
}));
|
|
2114
|
+
return { body: { nodes, edges } };
|
|
2115
|
+
}
|
|
1577
2116
|
async function handleGetDigest(req) {
|
|
1578
2117
|
const agentId = req.query.agent_id ?? DEFAULT_AGENT_ID;
|
|
1579
2118
|
const extracts = listDigestExtracts(agentId);
|
|
@@ -1590,14 +2129,14 @@ function createSearchHandler(deps) {
|
|
|
1590
2129
|
const limit = Number(req.query.limit) || SEARCH_RESULTS_DEFAULT_LIMIT;
|
|
1591
2130
|
const namespace = req.query.namespace;
|
|
1592
2131
|
if (mode === "fts") {
|
|
1593
|
-
const
|
|
1594
|
-
return { body: { mode: "fts", results
|
|
2132
|
+
const results = fullTextSearch(query, { type, limit });
|
|
2133
|
+
return { body: { mode: "fts", results } };
|
|
1595
2134
|
}
|
|
1596
2135
|
const queryVector = await deps.embeddingManager.embedQuery(query);
|
|
1597
2136
|
if (queryVector === null) {
|
|
1598
2137
|
if (mode === "auto") {
|
|
1599
|
-
const
|
|
1600
|
-
return { body: { mode: "fts", results
|
|
2138
|
+
const results = fullTextSearch(query, { type, limit });
|
|
2139
|
+
return { body: { mode: "fts", results, fallback: true } };
|
|
1601
2140
|
}
|
|
1602
2141
|
return { body: { mode: "semantic", results: [], provider_unavailable: true } };
|
|
1603
2142
|
}
|
|
@@ -1607,8 +2146,25 @@ function createSearchHandler(deps) {
|
|
|
1607
2146
|
limit,
|
|
1608
2147
|
threshold: SEARCH_SIMILARITY_THRESHOLD
|
|
1609
2148
|
});
|
|
1610
|
-
const
|
|
1611
|
-
|
|
2149
|
+
const localResults = hydrateSearchResults(vectorResults).map((r) => ({
|
|
2150
|
+
...r,
|
|
2151
|
+
source: "local"
|
|
2152
|
+
}));
|
|
2153
|
+
const teamClient = deps.getTeamClient?.();
|
|
2154
|
+
let teamResults = [];
|
|
2155
|
+
if (teamClient) {
|
|
2156
|
+
try {
|
|
2157
|
+
const teamResponse = await teamClient.search(query, { limit });
|
|
2158
|
+
teamResults = teamResponse.results.map((r) => ({
|
|
2159
|
+
...r,
|
|
2160
|
+
source: `${TEAM_SOURCE_PREFIX}${r.machine_id}`
|
|
2161
|
+
}));
|
|
2162
|
+
} catch {
|
|
2163
|
+
}
|
|
2164
|
+
}
|
|
2165
|
+
const dedupedTeam = deps.machineId ? teamResults.filter((r) => r.machine_id !== deps.machineId) : teamResults;
|
|
2166
|
+
const merged = [...localResults, ...dedupedTeam].sort((a, b) => (b.score ?? 0) - (a.score ?? 0)).slice(0, limit);
|
|
2167
|
+
return { body: { mode: "semantic", results: merged } };
|
|
1612
2168
|
};
|
|
1613
2169
|
}
|
|
1614
2170
|
|
|
@@ -2903,19 +3459,19 @@ function testCloud() {
|
|
|
2903
3459
|
}
|
|
2904
3460
|
|
|
2905
3461
|
// src/daemon/log-reconcile.ts
|
|
2906
|
-
import
|
|
2907
|
-
import
|
|
3462
|
+
import fs5 from "fs";
|
|
3463
|
+
import path6 from "path";
|
|
2908
3464
|
function reconcileLogBuffer(logDir, sinceTimestamp) {
|
|
2909
3465
|
let replayed = 0;
|
|
2910
3466
|
const files = [];
|
|
2911
3467
|
for (let i = 3; i >= 1; i--) {
|
|
2912
|
-
const rotated =
|
|
2913
|
-
if (
|
|
3468
|
+
const rotated = path6.join(logDir, `daemon.${i}.log`);
|
|
3469
|
+
if (fs5.existsSync(rotated)) files.push(rotated);
|
|
2914
3470
|
}
|
|
2915
|
-
const current =
|
|
2916
|
-
if (
|
|
3471
|
+
const current = path6.join(logDir, "daemon.log");
|
|
3472
|
+
if (fs5.existsSync(current)) files.push(current);
|
|
2917
3473
|
for (const file of files) {
|
|
2918
|
-
const content =
|
|
3474
|
+
const content = fs5.readFileSync(file, "utf-8");
|
|
2919
3475
|
for (const line of content.split("\n")) {
|
|
2920
3476
|
if (!line.trim()) continue;
|
|
2921
3477
|
try {
|
|
@@ -3131,8 +3687,8 @@ async function runSessionMaintenance(deps) {
|
|
|
3131
3687
|
}
|
|
3132
3688
|
|
|
3133
3689
|
// src/daemon/main.ts
|
|
3134
|
-
import
|
|
3135
|
-
import
|
|
3690
|
+
import fs6 from "fs";
|
|
3691
|
+
import path7 from "path";
|
|
3136
3692
|
var AGENT_RUNS_DEFAULT_LIMIT = 50;
|
|
3137
3693
|
var TOOL_INPUT_STORE_LIMIT = 4e3;
|
|
3138
3694
|
var TOOL_OUTPUT_STORE_LIMIT = 2e3;
|
|
@@ -3258,10 +3814,10 @@ function handleCompact(sessionId, phase, trigger, compactSummary) {
|
|
|
3258
3814
|
});
|
|
3259
3815
|
}
|
|
3260
3816
|
function killStaleDaemon(vaultDir, logger) {
|
|
3261
|
-
const daemonJsonPath =
|
|
3817
|
+
const daemonJsonPath = path7.join(vaultDir, "daemon.json");
|
|
3262
3818
|
try {
|
|
3263
|
-
if (!
|
|
3264
|
-
const info = JSON.parse(
|
|
3819
|
+
if (!fs6.existsSync(daemonJsonPath)) return;
|
|
3820
|
+
const info = JSON.parse(fs6.readFileSync(daemonJsonPath, "utf-8"));
|
|
3265
3821
|
if (!info.pid) return;
|
|
3266
3822
|
if (info.pid === process.pid) return;
|
|
3267
3823
|
try {
|
|
@@ -3270,7 +3826,7 @@ function killStaleDaemon(vaultDir, logger) {
|
|
|
3270
3826
|
logger.info(LOG_KINDS.DAEMON_START, "Killed stale daemon", { pid: info.pid });
|
|
3271
3827
|
} catch {
|
|
3272
3828
|
}
|
|
3273
|
-
|
|
3829
|
+
fs6.unlinkSync(daemonJsonPath);
|
|
3274
3830
|
} catch {
|
|
3275
3831
|
}
|
|
3276
3832
|
}
|
|
@@ -3280,7 +3836,7 @@ async function main() {
|
|
|
3280
3836
|
process.stderr.write("Usage: mycod --vault <path>\n");
|
|
3281
3837
|
process.exit(1);
|
|
3282
3838
|
}
|
|
3283
|
-
const vaultDir =
|
|
3839
|
+
const vaultDir = path7.resolve(vaultArg);
|
|
3284
3840
|
loadSecrets(vaultDir);
|
|
3285
3841
|
const config = loadConfig(vaultDir);
|
|
3286
3842
|
const manifests = loadManifests();
|
|
@@ -3291,7 +3847,7 @@ async function main() {
|
|
|
3291
3847
|
projectRoot,
|
|
3292
3848
|
extensions: config.capture.artifact_extensions
|
|
3293
3849
|
};
|
|
3294
|
-
const logger = new DaemonLogger(
|
|
3850
|
+
const logger = new DaemonLogger(path7.join(vaultDir, "logs"), {
|
|
3295
3851
|
level: config.daemon.log_level
|
|
3296
3852
|
});
|
|
3297
3853
|
killStaleDaemon(vaultDir, logger);
|
|
@@ -3300,9 +3856,12 @@ async function main() {
|
|
|
3300
3856
|
embedding_provider: config.embedding.provider
|
|
3301
3857
|
});
|
|
3302
3858
|
logger.info(LOG_KINDS.CAPTURE_PLAN, "Plan watch directories", { dirs: planWatchConfig.watchDirs });
|
|
3859
|
+
const machineId = getMachineId(vaultDir);
|
|
3860
|
+
logger.info(LOG_KINDS.DAEMON_START, "Machine ID resolved", { machine_id: machineId });
|
|
3303
3861
|
const db = initDatabase(vaultDbPath(vaultDir));
|
|
3304
|
-
createSchema(db);
|
|
3862
|
+
createSchema(db, machineId);
|
|
3305
3863
|
logger.info(LOG_KINDS.DAEMON_START, "SQLite initialized", { vault: vaultDir });
|
|
3864
|
+
initTeamContext(config.team.enabled, machineId);
|
|
3306
3865
|
logger.setPersistFn((entry) => {
|
|
3307
3866
|
const { timestamp, level, kind, component, message, ...rest } = entry;
|
|
3308
3867
|
insertLogEntry({
|
|
@@ -3317,13 +3876,13 @@ async function main() {
|
|
|
3317
3876
|
});
|
|
3318
3877
|
const lastLogTimestamp = getMaxTimestamp();
|
|
3319
3878
|
if (lastLogTimestamp) {
|
|
3320
|
-
const logDir =
|
|
3879
|
+
const logDir = path7.join(vaultDir, "logs");
|
|
3321
3880
|
const replayedCount = reconcileLogBuffer(logDir, lastLogTimestamp);
|
|
3322
3881
|
if (replayedCount > 0) {
|
|
3323
3882
|
logger.info(LOG_KINDS.DAEMON_RECONCILE, `Replayed ${replayedCount} log entries from buffer`, { replayed: replayedCount });
|
|
3324
3883
|
}
|
|
3325
3884
|
}
|
|
3326
|
-
const vectorsDbPath =
|
|
3885
|
+
const vectorsDbPath = path7.join(vaultDir, "vectors.db");
|
|
3327
3886
|
const vectorStore = new SqliteVecVectorStore(vectorsDbPath);
|
|
3328
3887
|
const llmProvider = createEmbeddingProvider(config.embedding);
|
|
3329
3888
|
const embeddingProvider = new EmbeddingProviderAdapter(llmProvider, config.embedding);
|
|
@@ -3331,7 +3890,7 @@ async function main() {
|
|
|
3331
3890
|
const embeddingManager = new EmbeddingManager(vectorStore, embeddingProvider, recordSource, logger);
|
|
3332
3891
|
logger.info(LOG_KINDS.EMBEDDING_EMBED, "EmbeddingManager initialized", { vectors_db: vectorsDbPath });
|
|
3333
3892
|
try {
|
|
3334
|
-
const { registerBuiltInAgentsAndTasks, resolveDefinitionsDir: resolveDefinitionsDir2 } = await import("./loader-
|
|
3893
|
+
const { registerBuiltInAgentsAndTasks, resolveDefinitionsDir: resolveDefinitionsDir2 } = await import("./loader-GKXR5ONU.js");
|
|
3335
3894
|
const definitionsDir = resolveDefinitionsDir2();
|
|
3336
3895
|
await registerBuiltInAgentsAndTasks(definitionsDir, vaultDir);
|
|
3337
3896
|
logger.info(LOG_KINDS.AGENT_TASK, "Built-in agents and tasks registered");
|
|
@@ -3357,10 +3916,10 @@ async function main() {
|
|
|
3357
3916
|
}
|
|
3358
3917
|
let uiDir = null;
|
|
3359
3918
|
{
|
|
3360
|
-
const root = findPackageRoot(
|
|
3919
|
+
const root = findPackageRoot(path7.dirname(new URL(import.meta.url).pathname));
|
|
3361
3920
|
if (root) {
|
|
3362
|
-
const candidate =
|
|
3363
|
-
if (
|
|
3921
|
+
const candidate = path7.join(root, "dist", "ui");
|
|
3922
|
+
if (fs6.existsSync(candidate)) uiDir = candidate;
|
|
3364
3923
|
}
|
|
3365
3924
|
}
|
|
3366
3925
|
if (uiDir) {
|
|
@@ -3397,7 +3956,7 @@ async function main() {
|
|
|
3397
3956
|
const running = getRunningRun(DEFAULT_AGENT_ID);
|
|
3398
3957
|
if (running) return;
|
|
3399
3958
|
try {
|
|
3400
|
-
const { runAgent } = await import("./executor-
|
|
3959
|
+
const { runAgent } = await import("./executor-A5C5KDLP.js");
|
|
3401
3960
|
runAgent(vaultDir, {
|
|
3402
3961
|
task: "title-summary",
|
|
3403
3962
|
instruction: `Process session ${sessionId} only`,
|
|
@@ -3406,7 +3965,7 @@ async function main() {
|
|
|
3406
3965
|
} catch {
|
|
3407
3966
|
}
|
|
3408
3967
|
}
|
|
3409
|
-
const bufferDir =
|
|
3968
|
+
const bufferDir = path7.join(vaultDir, "buffer");
|
|
3410
3969
|
const sessionBuffers = /* @__PURE__ */ new Map();
|
|
3411
3970
|
const startupCleanedCount = cleanStaleBuffers(bufferDir, STALE_BUFFER_MAX_AGE_MS);
|
|
3412
3971
|
if (startupCleanedCount > 0) {
|
|
@@ -3450,9 +4009,9 @@ async function main() {
|
|
|
3450
4009
|
function reconcileSession(sessionId) {
|
|
3451
4010
|
if (reconciledSessions.has(sessionId)) return;
|
|
3452
4011
|
reconciledSessions.add(sessionId);
|
|
3453
|
-
const bufferPath =
|
|
3454
|
-
if (!
|
|
3455
|
-
const content =
|
|
4012
|
+
const bufferPath = path7.join(bufferDir, `${sessionId}.jsonl`);
|
|
4013
|
+
if (!fs6.existsSync(bufferPath)) return;
|
|
4014
|
+
const content = fs6.readFileSync(bufferPath, "utf-8").trim();
|
|
3456
4015
|
if (!content) return;
|
|
3457
4016
|
if (!getSession(sessionId)) {
|
|
3458
4017
|
logger.debug(LOG_KINDS.LIFECYCLE_RECONCILE, "Skipping reconciliation for deleted session", { session_id: sessionId });
|
|
@@ -3606,10 +4165,10 @@ async function main() {
|
|
|
3606
4165
|
);
|
|
3607
4166
|
if (planFilePath) {
|
|
3608
4167
|
const captureSessionId = event.session_id;
|
|
3609
|
-
|
|
4168
|
+
fs6.promises.readFile(planFilePath, "utf-8").then((planContent) => {
|
|
3610
4169
|
const latestBatch = getLatestBatch(captureSessionId);
|
|
3611
4170
|
capturePlan({
|
|
3612
|
-
sourcePath:
|
|
4171
|
+
sourcePath: path7.relative(projectRoot, planFilePath),
|
|
3613
4172
|
content: planContent,
|
|
3614
4173
|
sessionId: captureSessionId,
|
|
3615
4174
|
promptBatchId: latestBatch?.id ?? null
|
|
@@ -4024,6 +4583,7 @@ async function main() {
|
|
|
4024
4583
|
server.registerRoute("GET", "/api/spores", handleListSpores);
|
|
4025
4584
|
server.registerRoute("GET", "/api/spores/:id", handleGetSpore);
|
|
4026
4585
|
server.registerRoute("GET", "/api/entities", handleListEntities);
|
|
4586
|
+
server.registerRoute("GET", "/api/graph", handleGetFullGraph);
|
|
4027
4587
|
server.registerRoute("GET", "/api/graph/:id", handleGetGraph);
|
|
4028
4588
|
server.registerRoute("GET", "/api/digest", handleGetDigest);
|
|
4029
4589
|
const ATTACHMENT_MEDIA_TYPES = {
|
|
@@ -4043,14 +4603,14 @@ async function main() {
|
|
|
4043
4603
|
const contentType2 = att.media_type ?? "application/octet-stream";
|
|
4044
4604
|
return { status: 200, headers: { "Content-Type": contentType2 }, body: att.data };
|
|
4045
4605
|
}
|
|
4046
|
-
const filePath =
|
|
4606
|
+
const filePath = path7.join(vaultDir, "attachments", filename);
|
|
4047
4607
|
let diskData;
|
|
4048
4608
|
try {
|
|
4049
|
-
diskData =
|
|
4609
|
+
diskData = fs6.readFileSync(filePath);
|
|
4050
4610
|
} catch {
|
|
4051
4611
|
return { status: 404, body: { error: "not_found" } };
|
|
4052
4612
|
}
|
|
4053
|
-
const ext =
|
|
4613
|
+
const ext = path7.extname(filename).slice(1).toLowerCase();
|
|
4054
4614
|
const contentType = ATTACHMENT_MEDIA_TYPES[ext] ?? "application/octet-stream";
|
|
4055
4615
|
return { status: 200, headers: { "Content-Type": contentType }, body: diskData };
|
|
4056
4616
|
});
|
|
@@ -4061,7 +4621,7 @@ async function main() {
|
|
|
4061
4621
|
});
|
|
4062
4622
|
server.registerRoute("POST", "/api/agent/run", async (req) => {
|
|
4063
4623
|
const { task, instruction, agentId } = AgentRunBody.parse(req.body);
|
|
4064
|
-
const { runAgent } = await import("./executor-
|
|
4624
|
+
const { runAgent } = await import("./executor-A5C5KDLP.js");
|
|
4065
4625
|
const resultPromise = runAgent(vaultDir, { task, instruction, agentId, embeddingManager });
|
|
4066
4626
|
const effectiveAgentId = agentId ?? "myco-agent";
|
|
4067
4627
|
const latestRun = getRunningRun(effectiveAgentId);
|
|
@@ -4242,7 +4802,7 @@ async function main() {
|
|
|
4242
4802
|
name: USER_AGENT_NAME,
|
|
4243
4803
|
created_at: now
|
|
4244
4804
|
});
|
|
4245
|
-
const { insertResolutionEvent } = await import("./resolution-events-
|
|
4805
|
+
const { insertResolutionEvent } = await import("./resolution-events-UPHJJLDQ.js");
|
|
4246
4806
|
const resolutionId = `res-${randomBytes(RESOLUTION_ID_RANDOM_BYTES).toString("hex")}`;
|
|
4247
4807
|
insertResolutionEvent({
|
|
4248
4808
|
id: resolutionId,
|
|
@@ -4261,7 +4821,69 @@ async function main() {
|
|
|
4261
4821
|
}
|
|
4262
4822
|
};
|
|
4263
4823
|
});
|
|
4264
|
-
|
|
4824
|
+
const backupDir = config.backup.dir ? path7.resolve(config.backup.dir) : path7.resolve(vaultDir, "backups");
|
|
4825
|
+
const backupHandlers = createBackupHandlers({ db, backupDir, machineId });
|
|
4826
|
+
server.registerRoute("POST", "/api/backup", backupHandlers.handleCreateBackup);
|
|
4827
|
+
server.registerRoute("GET", "/api/backups", backupHandlers.handleListBackups);
|
|
4828
|
+
server.registerRoute("POST", "/api/restore/preview", backupHandlers.handleRestorePreview);
|
|
4829
|
+
server.registerRoute("POST", "/api/restore", backupHandlers.handleRestore);
|
|
4830
|
+
server.registerRoute("GET", "/api/backup/config", async () => {
|
|
4831
|
+
const cfg = loadConfig(vaultDir);
|
|
4832
|
+
return { body: { dir: cfg.backup.dir ?? null, default_dir: path7.resolve(vaultDir, "backups") } };
|
|
4833
|
+
});
|
|
4834
|
+
server.registerRoute("PUT", "/api/backup/config", async (req) => {
|
|
4835
|
+
const { dir } = req.body;
|
|
4836
|
+
updateBackupConfig(vaultDir, { dir: dir || void 0 });
|
|
4837
|
+
return { body: { dir: dir || null } };
|
|
4838
|
+
});
|
|
4839
|
+
let teamClient = null;
|
|
4840
|
+
if (config.team.enabled && config.team.worker_url) {
|
|
4841
|
+
const secrets = readSecrets(vaultDir);
|
|
4842
|
+
const teamApiKey = secrets["MYCO_TEAM_API_KEY"];
|
|
4843
|
+
if (teamApiKey) {
|
|
4844
|
+
teamClient = new TeamSyncClient({
|
|
4845
|
+
workerUrl: config.team.worker_url,
|
|
4846
|
+
apiKey: teamApiKey,
|
|
4847
|
+
machineId,
|
|
4848
|
+
syncProtocolVersion: SYNC_PROTOCOL_VERSION
|
|
4849
|
+
});
|
|
4850
|
+
logger.info(LOG_KINDS.TEAM_SYNC_START, "Team sync client initialized", { worker_url: config.team.worker_url });
|
|
4851
|
+
teamClient.connect({
|
|
4852
|
+
machine_id: machineId,
|
|
4853
|
+
version: server.version
|
|
4854
|
+
}).then(() => {
|
|
4855
|
+
logger.info(LOG_KINDS.TEAM_SYNC_START, "Node registered with team worker");
|
|
4856
|
+
}).catch((err) => {
|
|
4857
|
+
logger.warn(LOG_KINDS.TEAM_SYNC_ERROR, "Node registration failed (will retry on next flush)", { error: err.message });
|
|
4858
|
+
});
|
|
4859
|
+
setTimeout(() => {
|
|
4860
|
+
try {
|
|
4861
|
+
const backfilled = backfillUnsynced(machineId);
|
|
4862
|
+
if (backfilled > 0) {
|
|
4863
|
+
logger.info(LOG_KINDS.TEAM_SYNC_START, `Backfilled ${backfilled} unsynced records into outbox`);
|
|
4864
|
+
}
|
|
4865
|
+
} catch (err) {
|
|
4866
|
+
logger.error(LOG_KINDS.TEAM_SYNC_ERROR, "Backfill failed", { error: err.message });
|
|
4867
|
+
}
|
|
4868
|
+
}, 0);
|
|
4869
|
+
}
|
|
4870
|
+
}
|
|
4871
|
+
const teamHandlers = createTeamHandlers({
|
|
4872
|
+
vaultDir,
|
|
4873
|
+
machineId,
|
|
4874
|
+
getTeamClient: () => teamClient,
|
|
4875
|
+
setTeamClient: (c) => {
|
|
4876
|
+
teamClient = c;
|
|
4877
|
+
}
|
|
4878
|
+
});
|
|
4879
|
+
server.registerRoute("POST", "/api/team/connect", teamHandlers.handleConnect);
|
|
4880
|
+
server.registerRoute("POST", "/api/team/disconnect", teamHandlers.handleDisconnect);
|
|
4881
|
+
server.registerRoute("GET", "/api/team/status", teamHandlers.handleStatus);
|
|
4882
|
+
server.registerRoute("POST", "/api/team/backfill", async () => {
|
|
4883
|
+
const count = backfillUnsynced(machineId);
|
|
4884
|
+
return { body: { enqueued: count } };
|
|
4885
|
+
});
|
|
4886
|
+
server.registerRoute("GET", "/api/search", createSearchHandler({ embeddingManager, getTeamClient: () => teamClient, machineId }));
|
|
4265
4887
|
server.registerRoute("GET", "/api/activity", handleGetFeed);
|
|
4266
4888
|
server.registerRoute("GET", "/api/embedding/status", async () => handleGetEmbeddingStatus(vaultDir));
|
|
4267
4889
|
server.registerRoute("GET", "/api/embedding/details", async () => handleEmbeddingDetails(embeddingManager));
|
|
@@ -4335,7 +4957,7 @@ async function main() {
|
|
|
4335
4957
|
lastAgentRun = Date.now();
|
|
4336
4958
|
try {
|
|
4337
4959
|
logger.info(LOG_KINDS.AGENT_AUTO_RUN, "Unprocessed batches found, starting agent", { count });
|
|
4338
|
-
const { runAgent } = await import("./executor-
|
|
4960
|
+
const { runAgent } = await import("./executor-A5C5KDLP.js");
|
|
4339
4961
|
const runResult = await runAgent(vaultDir, { embeddingManager });
|
|
4340
4962
|
logger.info(LOG_KINDS.AGENT_RUN, "Agent run completed", { status: runResult.status, runId: runResult.runId });
|
|
4341
4963
|
} catch (err) {
|
|
@@ -4360,6 +4982,56 @@ async function main() {
|
|
|
4360
4982
|
}
|
|
4361
4983
|
}
|
|
4362
4984
|
});
|
|
4985
|
+
powerManager.register({
|
|
4986
|
+
name: "auto-backup",
|
|
4987
|
+
runIn: ["idle", "sleep"],
|
|
4988
|
+
fn: async () => {
|
|
4989
|
+
try {
|
|
4990
|
+
logger.info(LOG_KINDS.BACKUP_START, "Auto-backup starting");
|
|
4991
|
+
const filePath = createBackup(db, backupDir, machineId);
|
|
4992
|
+
logger.info(LOG_KINDS.BACKUP_COMPLETE, "Auto-backup complete", { file_path: filePath });
|
|
4993
|
+
} catch (err) {
|
|
4994
|
+
logger.error(LOG_KINDS.BACKUP_ERROR, "Auto-backup failed", { error: err.message });
|
|
4995
|
+
}
|
|
4996
|
+
}
|
|
4997
|
+
});
|
|
4998
|
+
if (config.team.enabled) {
|
|
4999
|
+
powerManager.register({
|
|
5000
|
+
name: "team-sync-flush",
|
|
5001
|
+
runIn: ["active", "idle"],
|
|
5002
|
+
fn: async () => {
|
|
5003
|
+
const client = teamClient;
|
|
5004
|
+
if (!client) return;
|
|
5005
|
+
try {
|
|
5006
|
+
const pending = listPending();
|
|
5007
|
+
if (pending.length === 0) return;
|
|
5008
|
+
logger.info(LOG_KINDS.TEAM_SYNC_START, "Flushing outbox", { count: pending.length });
|
|
5009
|
+
const result = await client.pushBatch(pending);
|
|
5010
|
+
if (result.synced > 0 || result.skipped > 0) {
|
|
5011
|
+
const failedIds = new Set(result.errors.map((e) => e.id));
|
|
5012
|
+
const sentIds = pending.filter((r) => !failedIds.has(String(r.row_id))).map((r) => r.id);
|
|
5013
|
+
if (sentIds.length > 0) {
|
|
5014
|
+
markSent(sentIds, epochSeconds());
|
|
5015
|
+
}
|
|
5016
|
+
}
|
|
5017
|
+
if (result.errors.length > 0) {
|
|
5018
|
+
logger.warn(LOG_KINDS.TEAM_SYNC_ERROR, `Sync errors: ${result.errors.length}`, {
|
|
5019
|
+
errors: result.errors.slice(0, 5)
|
|
5020
|
+
});
|
|
5021
|
+
}
|
|
5022
|
+
pruneOld();
|
|
5023
|
+
logger.info(LOG_KINDS.TEAM_SYNC_COMPLETE, "Outbox flush complete", {
|
|
5024
|
+
synced: result.synced,
|
|
5025
|
+
skipped: result.skipped,
|
|
5026
|
+
errors: result.errors.length,
|
|
5027
|
+
total: pending.length
|
|
5028
|
+
});
|
|
5029
|
+
} catch (err) {
|
|
5030
|
+
logger.error(LOG_KINDS.TEAM_SYNC_ERROR, "Outbox flush failed", { error: err.message });
|
|
5031
|
+
}
|
|
5032
|
+
}
|
|
5033
|
+
});
|
|
5034
|
+
}
|
|
4363
5035
|
powerManager.start();
|
|
4364
5036
|
const shutdown = async (signal) => {
|
|
4365
5037
|
logger.info(LOG_KINDS.DAEMON_START, `${signal} received`);
|
|
@@ -4390,4 +5062,4 @@ export {
|
|
|
4390
5062
|
handleUserPrompt,
|
|
4391
5063
|
main
|
|
4392
5064
|
};
|
|
4393
|
-
//# sourceMappingURL=main-
|
|
5065
|
+
//# sourceMappingURL=main-PVX6R3I6.js.map
|