@goondocks/myco 0.18.0 → 0.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{agent-run-2NFYMQXW.js → agent-run-I4O2K2CK.js} +4 -4
- package/dist/{agent-tasks-MEIYLXGN.js → agent-tasks-UOW5BQIB.js} +4 -4
- package/dist/{chunk-JMOUFG6Y.js → chunk-44PZCAYS.js} +47 -5
- package/dist/chunk-44PZCAYS.js.map +1 -0
- package/dist/{chunk-JDI4DPWD.js → chunk-C3EGL5JX.js} +632 -145
- package/dist/chunk-C3EGL5JX.js.map +1 -0
- package/dist/{chunk-OW433Q4C.js → chunk-CURS2TNP.js} +44 -3
- package/dist/chunk-CURS2TNP.js.map +1 -0
- package/dist/{chunk-FABWUX5G.js → chunk-DPSLJ242.js} +16 -2
- package/dist/chunk-DPSLJ242.js.map +1 -0
- package/dist/{chunk-DLFDBKEV.js → chunk-LSP5HYOO.js} +17 -14
- package/dist/chunk-LSP5HYOO.js.map +1 -0
- package/dist/{chunk-VOCGURV7.js → chunk-N75GMQGA.js} +3 -3
- package/dist/{chunk-U7GJTVSX.js → chunk-RIDSOQDR.js} +20 -6
- package/dist/chunk-RIDSOQDR.js.map +1 -0
- package/dist/{chunk-KWTOCJLB.js → chunk-TCSVDQF5.js} +1128 -193
- package/dist/chunk-TCSVDQF5.js.map +1 -0
- package/dist/{chunk-55QEICRO.js → chunk-TLK46KKD.js} +2 -2
- package/dist/{chunk-NZI7WBZI.js → chunk-TOER6RNC.js} +21 -1
- package/dist/chunk-TOER6RNC.js.map +1 -0
- package/dist/{chunk-7OYXB2NM.js → chunk-TZAXQKO6.js} +5 -1
- package/dist/chunk-TZAXQKO6.js.map +1 -0
- package/dist/{chunk-EO2RQW4S.js → chunk-W7WENJ6F.js} +2 -2
- package/dist/{chunk-BUIR3JWM.js → chunk-XWOQL4XN.js} +2 -2
- package/dist/{chunk-PFWIPRF6.js → chunk-YZPI2Y3E.js} +2 -2
- package/dist/{cli-IIMBALPV.js → cli-D3TJYJ2U.js} +35 -35
- package/dist/{client-VZCUISHZ.js → client-4LLEXLVK.js} +3 -3
- package/dist/{detect-GEM3NVK6.js → detect-SZ2KDUF4.js} +2 -2
- package/dist/{doctor-QYD34X7Q.js → doctor-KCTXPX5D.js} +6 -6
- package/dist/{executor-NSPRTH4M.js → executor-UYIZC3L5.js} +83 -275
- package/dist/executor-UYIZC3L5.js.map +1 -0
- package/dist/{init-WYYL44KZ.js → init-QFNBKKDC.js} +7 -7
- package/dist/{llm-KEDHK3TQ.js → llm-SMA5ZEAW.js} +2 -2
- package/dist/{main-6PY3ITQ5.js → main-5THODR77.js} +427 -196
- package/dist/main-5THODR77.js.map +1 -0
- package/dist/{open-HRFMJDQX.js → open-7737CSPN.js} +4 -4
- package/dist/{post-compact-HT24YMAN.js → post-compact-2TJ5FPZH.js} +6 -6
- package/dist/{post-tool-use-DENRI5WB.js → post-tool-use-FRTSICC3.js} +5 -5
- package/dist/{post-tool-use-failure-A6SNJX42.js → post-tool-use-failure-KYO2NCNB.js} +6 -6
- package/dist/{pre-compact-3Q4BALCL.js → pre-compact-J6GCJEJR.js} +6 -6
- package/dist/{remove-YB5A6HY2.js → remove-3WZZC7AX.js} +5 -5
- package/dist/{restart-RGDVHELZ.js → restart-HUHEFOXU.js} +5 -5
- package/dist/{search-WOHT3G55.js → search-ZGN3LDXG.js} +5 -5
- package/dist/{server-6SUNYDV7.js → server-PTXLVVEE.js} +3 -3
- package/dist/{session-W3SKRFRV.js → session-7VV3IQMO.js} +5 -5
- package/dist/{session-end-OUTY7AFF.js → session-end-SMU55UCM.js} +5 -5
- package/dist/{session-start-5MB3LFOA.js → session-start-NIMWEOIZ.js} +16 -11
- package/dist/{session-start-5MB3LFOA.js.map → session-start-NIMWEOIZ.js.map} +1 -1
- package/dist/{setup-llm-ZMYGIQX5.js → setup-llm-7S3VPAPN.js} +4 -4
- package/dist/src/agent/definitions/tasks/extract-only.yaml +1 -1
- package/dist/src/agent/definitions/tasks/full-intelligence.yaml +10 -0
- package/dist/src/agent/definitions/tasks/skill-evolve.yaml +163 -49
- package/dist/src/agent/definitions/tasks/skill-generate.yaml +44 -27
- package/dist/src/agent/definitions/tasks/skill-survey.yaml +132 -138
- package/dist/src/agent/definitions/tasks/supersession-sweep.yaml +1 -1
- 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/src/symbionts/manifests/codex.yaml +45 -7
- package/dist/src/worker/src/index.ts +8 -2
- package/dist/src/worker/src/schema.ts +2 -0
- package/dist/{stats-DGI6B3HX.js → stats-GEOQ2DFF.js} +5 -5
- package/dist/{stop-YGHODSP7.js → stop-7AKYBJJ2.js} +5 -5
- package/dist/{stop-failure-7IJTPJ6W.js → stop-failure-NLE2EURG.js} +6 -6
- package/dist/{subagent-start-ZBQ5PJB5.js → subagent-start-LBNZF2TG.js} +6 -6
- package/dist/{subagent-stop-N2TDQU2D.js → subagent-stop-B2Z5GYAB.js} +6 -6
- package/dist/{task-completed-BDLMRSBB.js → task-completed-PO5TETJ7.js} +6 -6
- package/dist/{team-2ZFGTSIN.js → team-DPNP2RN7.js} +3 -3
- package/dist/ui/assets/{index-DtT9_nlT.js → index-CiI1fwas.js} +2 -2
- package/dist/ui/index.html +1 -1
- package/dist/{update-STLAN7LR.js → update-WBWB5URU.js} +5 -5
- package/dist/{user-prompt-submit-4IBFUYQ3.js → user-prompt-submit-IZJC3NV7.js} +11 -8
- package/dist/user-prompt-submit-IZJC3NV7.js.map +1 -0
- package/dist/{verify-EJYPO7QA.js → verify-FNSP62I3.js} +2 -2
- package/dist/{version-YPBIKH77.js → version-QEVU66NT.js} +2 -2
- package/package.json +7 -7
- package/dist/chunk-7OYXB2NM.js.map +0 -1
- package/dist/chunk-DLFDBKEV.js.map +0 -1
- package/dist/chunk-FABWUX5G.js.map +0 -1
- package/dist/chunk-JDI4DPWD.js.map +0 -1
- package/dist/chunk-JMOUFG6Y.js.map +0 -1
- package/dist/chunk-KWTOCJLB.js.map +0 -1
- package/dist/chunk-NZI7WBZI.js.map +0 -1
- package/dist/chunk-OW433Q4C.js.map +0 -1
- package/dist/chunk-U7GJTVSX.js.map +0 -1
- package/dist/executor-NSPRTH4M.js.map +0 -1
- package/dist/main-6PY3ITQ5.js.map +0 -1
- package/dist/user-prompt-submit-4IBFUYQ3.js.map +0 -1
- /package/dist/{agent-run-2NFYMQXW.js.map → agent-run-I4O2K2CK.js.map} +0 -0
- /package/dist/{agent-tasks-MEIYLXGN.js.map → agent-tasks-UOW5BQIB.js.map} +0 -0
- /package/dist/{chunk-VOCGURV7.js.map → chunk-N75GMQGA.js.map} +0 -0
- /package/dist/{chunk-55QEICRO.js.map → chunk-TLK46KKD.js.map} +0 -0
- /package/dist/{chunk-EO2RQW4S.js.map → chunk-W7WENJ6F.js.map} +0 -0
- /package/dist/{chunk-BUIR3JWM.js.map → chunk-XWOQL4XN.js.map} +0 -0
- /package/dist/{chunk-PFWIPRF6.js.map → chunk-YZPI2Y3E.js.map} +0 -0
- /package/dist/{cli-IIMBALPV.js.map → cli-D3TJYJ2U.js.map} +0 -0
- /package/dist/{client-VZCUISHZ.js.map → client-4LLEXLVK.js.map} +0 -0
- /package/dist/{detect-GEM3NVK6.js.map → detect-SZ2KDUF4.js.map} +0 -0
- /package/dist/{doctor-QYD34X7Q.js.map → doctor-KCTXPX5D.js.map} +0 -0
- /package/dist/{init-WYYL44KZ.js.map → init-QFNBKKDC.js.map} +0 -0
- /package/dist/{llm-KEDHK3TQ.js.map → llm-SMA5ZEAW.js.map} +0 -0
- /package/dist/{open-HRFMJDQX.js.map → open-7737CSPN.js.map} +0 -0
- /package/dist/{post-compact-HT24YMAN.js.map → post-compact-2TJ5FPZH.js.map} +0 -0
- /package/dist/{post-tool-use-DENRI5WB.js.map → post-tool-use-FRTSICC3.js.map} +0 -0
- /package/dist/{post-tool-use-failure-A6SNJX42.js.map → post-tool-use-failure-KYO2NCNB.js.map} +0 -0
- /package/dist/{pre-compact-3Q4BALCL.js.map → pre-compact-J6GCJEJR.js.map} +0 -0
- /package/dist/{remove-YB5A6HY2.js.map → remove-3WZZC7AX.js.map} +0 -0
- /package/dist/{restart-RGDVHELZ.js.map → restart-HUHEFOXU.js.map} +0 -0
- /package/dist/{search-WOHT3G55.js.map → search-ZGN3LDXG.js.map} +0 -0
- /package/dist/{server-6SUNYDV7.js.map → server-PTXLVVEE.js.map} +0 -0
- /package/dist/{session-W3SKRFRV.js.map → session-7VV3IQMO.js.map} +0 -0
- /package/dist/{session-end-OUTY7AFF.js.map → session-end-SMU55UCM.js.map} +0 -0
- /package/dist/{setup-llm-ZMYGIQX5.js.map → setup-llm-7S3VPAPN.js.map} +0 -0
- /package/dist/{stats-DGI6B3HX.js.map → stats-GEOQ2DFF.js.map} +0 -0
- /package/dist/{stop-YGHODSP7.js.map → stop-7AKYBJJ2.js.map} +0 -0
- /package/dist/{stop-failure-7IJTPJ6W.js.map → stop-failure-NLE2EURG.js.map} +0 -0
- /package/dist/{subagent-start-ZBQ5PJB5.js.map → subagent-start-LBNZF2TG.js.map} +0 -0
- /package/dist/{subagent-stop-N2TDQU2D.js.map → subagent-stop-B2Z5GYAB.js.map} +0 -0
- /package/dist/{task-completed-BDLMRSBB.js.map → task-completed-PO5TETJ7.js.map} +0 -0
- /package/dist/{team-2ZFGTSIN.js.map → team-DPNP2RN7.js.map} +0 -0
- /package/dist/{update-STLAN7LR.js.map → update-WBWB5URU.js.map} +0 -0
- /package/dist/{verify-EJYPO7QA.js.map → verify-FNSP62I3.js.map} +0 -0
- /package/dist/{version-YPBIKH77.js.map → version-QEVU66NT.js.map} +0 -0
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
getEmbeddingQueueDepth,
|
|
16
16
|
getUnembedded,
|
|
17
17
|
markEmbedded
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-LSP5HYOO.js";
|
|
19
19
|
import {
|
|
20
20
|
loadSecrets,
|
|
21
21
|
readSecrets,
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
import {
|
|
25
25
|
Anthropic,
|
|
26
26
|
createEmbeddingProvider
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-TCSVDQF5.js";
|
|
28
28
|
import {
|
|
29
29
|
buildTaskInstruction,
|
|
30
30
|
closeOpenBatches,
|
|
@@ -72,11 +72,11 @@ import {
|
|
|
72
72
|
setResponseSummary,
|
|
73
73
|
updateCandidate,
|
|
74
74
|
updateNotificationStatus
|
|
75
|
-
} from "./chunk-
|
|
75
|
+
} from "./chunk-C3EGL5JX.js";
|
|
76
76
|
import {
|
|
77
77
|
fullTextSearch,
|
|
78
78
|
hydrateSearchResults
|
|
79
|
-
} from "./chunk-
|
|
79
|
+
} from "./chunk-TOER6RNC.js";
|
|
80
80
|
import {
|
|
81
81
|
copyTaskToUser,
|
|
82
82
|
deleteUserTask,
|
|
@@ -106,7 +106,7 @@ import {
|
|
|
106
106
|
listBufferSessionIds
|
|
107
107
|
} from "./chunk-V7XG6V6C.js";
|
|
108
108
|
import "./chunk-IB76KGBY.js";
|
|
109
|
-
import "./chunk-
|
|
109
|
+
import "./chunk-TLK46KKD.js";
|
|
110
110
|
import "./chunk-SAKJMNSR.js";
|
|
111
111
|
import "./chunk-WYOE4IAX.js";
|
|
112
112
|
import {
|
|
@@ -122,7 +122,7 @@ import {
|
|
|
122
122
|
insertSpore,
|
|
123
123
|
listSpores,
|
|
124
124
|
updateSporeStatus
|
|
125
|
-
} from "./chunk-
|
|
125
|
+
} from "./chunk-TZAXQKO6.js";
|
|
126
126
|
import {
|
|
127
127
|
closeSession,
|
|
128
128
|
countSessions,
|
|
@@ -133,7 +133,7 @@ import {
|
|
|
133
133
|
listSessions,
|
|
134
134
|
updateSession,
|
|
135
135
|
upsertSession
|
|
136
|
-
} from "./chunk-
|
|
136
|
+
} from "./chunk-RIDSOQDR.js";
|
|
137
137
|
import {
|
|
138
138
|
backfillUnsynced,
|
|
139
139
|
countDeadLettered,
|
|
@@ -155,7 +155,7 @@ import {
|
|
|
155
155
|
REST_SETTABLE_STATUSES,
|
|
156
156
|
SCHEMA_VERSION,
|
|
157
157
|
createSchema
|
|
158
|
-
} from "./chunk-
|
|
158
|
+
} from "./chunk-CURS2TNP.js";
|
|
159
159
|
import {
|
|
160
160
|
CONFIG_FILENAME,
|
|
161
161
|
MycoConfigSchema,
|
|
@@ -173,13 +173,13 @@ import {
|
|
|
173
173
|
} from "./chunk-MYX5NCRH.js";
|
|
174
174
|
import {
|
|
175
175
|
resolveCliEntryPath
|
|
176
|
-
} from "./chunk-
|
|
176
|
+
} from "./chunk-XWOQL4XN.js";
|
|
177
177
|
import {
|
|
178
178
|
getPluginVersion
|
|
179
|
-
} from "./chunk-
|
|
179
|
+
} from "./chunk-W7WENJ6F.js";
|
|
180
180
|
import {
|
|
181
181
|
loadManifests
|
|
182
|
-
} from "./chunk-
|
|
182
|
+
} from "./chunk-DPSLJ242.js";
|
|
183
183
|
import {
|
|
184
184
|
findPackageRoot
|
|
185
185
|
} from "./chunk-LPUQPDC2.js";
|
|
@@ -372,7 +372,7 @@ var DaemonServer = class {
|
|
|
372
372
|
this.router.add(method, routePath, handler);
|
|
373
373
|
}
|
|
374
374
|
async start(port = 0) {
|
|
375
|
-
return new Promise((
|
|
375
|
+
return new Promise((resolve3, reject) => {
|
|
376
376
|
this.server = http.createServer((req, res) => this.handleRequest(req, res));
|
|
377
377
|
this.server.on("error", reject);
|
|
378
378
|
this.server.listen(port, "127.0.0.1", () => {
|
|
@@ -380,20 +380,20 @@ var DaemonServer = class {
|
|
|
380
380
|
this.port = addr.port;
|
|
381
381
|
this.writeDaemonJson();
|
|
382
382
|
this.logger.info(LOG_KINDS.DAEMON_PORT, "Server started", { port: this.port, dashboard: `http://localhost:${this.port}/` });
|
|
383
|
-
|
|
383
|
+
resolve3();
|
|
384
384
|
});
|
|
385
385
|
});
|
|
386
386
|
}
|
|
387
387
|
async stop() {
|
|
388
|
-
return new Promise((
|
|
388
|
+
return new Promise((resolve3) => {
|
|
389
389
|
this.removeDaemonJson();
|
|
390
390
|
if (this.server) {
|
|
391
391
|
this.server.close(() => {
|
|
392
392
|
this.logger.info(LOG_KINDS.DAEMON_START, "Server stopped");
|
|
393
|
-
|
|
393
|
+
resolve3();
|
|
394
394
|
});
|
|
395
395
|
} else {
|
|
396
|
-
|
|
396
|
+
resolve3();
|
|
397
397
|
}
|
|
398
398
|
});
|
|
399
399
|
}
|
|
@@ -541,14 +541,14 @@ var DaemonServer = class {
|
|
|
541
541
|
}
|
|
542
542
|
};
|
|
543
543
|
function readBody(req) {
|
|
544
|
-
return new Promise((
|
|
544
|
+
return new Promise((resolve3, reject) => {
|
|
545
545
|
let data = "";
|
|
546
546
|
req.on("data", (chunk) => {
|
|
547
547
|
data += chunk;
|
|
548
548
|
});
|
|
549
549
|
req.on("end", () => {
|
|
550
550
|
try {
|
|
551
|
-
|
|
551
|
+
resolve3(data ? JSON.parse(data) : {});
|
|
552
552
|
} catch (e) {
|
|
553
553
|
reject(e);
|
|
554
554
|
}
|
|
@@ -628,11 +628,11 @@ async function resolvePort(configPort, vaultPath) {
|
|
|
628
628
|
return 0;
|
|
629
629
|
}
|
|
630
630
|
function isPortAvailable(port) {
|
|
631
|
-
return new Promise((
|
|
631
|
+
return new Promise((resolve3) => {
|
|
632
632
|
const server = net.createServer();
|
|
633
|
-
server.once("error", () =>
|
|
633
|
+
server.once("error", () => resolve3(false));
|
|
634
634
|
server.once("listening", () => {
|
|
635
|
-
server.close(() =>
|
|
635
|
+
server.close(() => resolve3(true));
|
|
636
636
|
});
|
|
637
637
|
server.listen(port, "127.0.0.1");
|
|
638
638
|
});
|
|
@@ -641,6 +641,53 @@ function isPortAvailable(port) {
|
|
|
641
641
|
// src/symbionts/adapter.ts
|
|
642
642
|
import fs3 from "fs";
|
|
643
643
|
import path3 from "path";
|
|
644
|
+
|
|
645
|
+
// src/symbionts/parsers/standard-jsonl.ts
|
|
646
|
+
var IMAGE_TEXT_REF_PATTERN = /\[Image: source: [^\]]+\]\n*/g;
|
|
647
|
+
var StandardJsonlParser = class {
|
|
648
|
+
constructor(opts) {
|
|
649
|
+
this.opts = opts;
|
|
650
|
+
}
|
|
651
|
+
parseTurns(content) {
|
|
652
|
+
const lines = content.split("\n").filter(Boolean);
|
|
653
|
+
const turns = [];
|
|
654
|
+
let current = null;
|
|
655
|
+
for (const line of lines) {
|
|
656
|
+
let entry;
|
|
657
|
+
try {
|
|
658
|
+
entry = JSON.parse(line);
|
|
659
|
+
} catch {
|
|
660
|
+
continue;
|
|
661
|
+
}
|
|
662
|
+
const role = entry[this.opts.roleField];
|
|
663
|
+
const timestamp = this.opts.extractTimestamp ? entry.timestamp ?? "" : "";
|
|
664
|
+
if (role === "user") {
|
|
665
|
+
if (entry.isMeta === true) continue;
|
|
666
|
+
const msg = entry.message;
|
|
667
|
+
const blocks = Array.isArray(msg?.content) ? msg.content : [];
|
|
668
|
+
const hasText = blocks.some((b) => b.type === "text" && b.text?.trim());
|
|
669
|
+
if (!hasText) continue;
|
|
670
|
+
if (current) turns.push(current);
|
|
671
|
+
const rawPrompt = blocks.filter((b) => b.type === "text" && b.text).map((b) => b.text).join("\n");
|
|
672
|
+
const promptText = (this.opts.stripImageTextRefs ? rawPrompt.replace(IMAGE_TEXT_REF_PATTERN, "") : rawPrompt).trim().slice(0, PROMPT_PREVIEW_CHARS);
|
|
673
|
+
const images = blocks.filter((b) => b.type === "image" && b.source?.type === "base64" && b.source.data).map((b) => ({ data: b.source.data, mediaType: b.source.media_type ?? "image/png" }));
|
|
674
|
+
current = { prompt: promptText, toolCount: 0, timestamp, ...images.length > 0 ? { images } : {} };
|
|
675
|
+
} else if (role === "assistant" && current) {
|
|
676
|
+
const msg = entry.message;
|
|
677
|
+
if (Array.isArray(msg?.content)) {
|
|
678
|
+
const textParts = msg.content.filter((b) => b.type === "text" && b.text).map((b) => b.text);
|
|
679
|
+
const text = textParts.join("\n").trim();
|
|
680
|
+
if (text) current.aiResponse = text;
|
|
681
|
+
current.toolCount += msg.content.filter((b) => b.type === "tool_use").length;
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
if (current) turns.push(current);
|
|
686
|
+
return turns;
|
|
687
|
+
}
|
|
688
|
+
};
|
|
689
|
+
|
|
690
|
+
// src/symbionts/adapter.ts
|
|
644
691
|
function findJsonlInSubdirs(baseDir, sessionId) {
|
|
645
692
|
try {
|
|
646
693
|
for (const entry of fs3.readdirSync(baseDir, { withFileTypes: true })) {
|
|
@@ -685,44 +732,8 @@ var EXT_TO_MIME = {
|
|
|
685
732
|
function mimeTypeForExtension(ext) {
|
|
686
733
|
return EXT_TO_MIME[ext.toLowerCase()] ?? "image/png";
|
|
687
734
|
}
|
|
688
|
-
var IMAGE_TEXT_REF_PATTERN = /\[Image: source: [^\]]+\]\n*/g;
|
|
689
735
|
function parseJsonlTurns(content, opts) {
|
|
690
|
-
|
|
691
|
-
const turns = [];
|
|
692
|
-
let current = null;
|
|
693
|
-
for (const line of lines) {
|
|
694
|
-
let entry;
|
|
695
|
-
try {
|
|
696
|
-
entry = JSON.parse(line);
|
|
697
|
-
} catch {
|
|
698
|
-
continue;
|
|
699
|
-
}
|
|
700
|
-
const role = entry[opts.roleField];
|
|
701
|
-
const timestamp = opts.extractTimestamp ? entry.timestamp ?? "" : "";
|
|
702
|
-
if (role === "user") {
|
|
703
|
-
if (entry.isMeta === true) continue;
|
|
704
|
-
const msg = entry.message;
|
|
705
|
-
const blocks = Array.isArray(msg?.content) ? msg.content : [];
|
|
706
|
-
const hasText = blocks.some((b) => b.type === "text" && b.text?.trim());
|
|
707
|
-
if (!hasText && opts.skipToolResultUsers) continue;
|
|
708
|
-
if (!hasText) continue;
|
|
709
|
-
if (current) turns.push(current);
|
|
710
|
-
const rawPrompt = blocks.filter((b) => b.type === "text" && b.text).map((b) => b.text).join("\n");
|
|
711
|
-
const promptText = (opts.stripImageTextRefs ? rawPrompt.replace(IMAGE_TEXT_REF_PATTERN, "") : rawPrompt).trim().slice(0, PROMPT_PREVIEW_CHARS);
|
|
712
|
-
const images = blocks.filter((b) => b.type === "image" && b.source?.type === "base64" && b.source.data).map((b) => ({ data: b.source.data, mediaType: b.source.media_type ?? "image/png" }));
|
|
713
|
-
current = { prompt: promptText, toolCount: 0, timestamp, ...images.length > 0 ? { images } : {} };
|
|
714
|
-
} else if (role === "assistant" && current) {
|
|
715
|
-
const msg = entry.message;
|
|
716
|
-
if (Array.isArray(msg?.content)) {
|
|
717
|
-
const textParts = msg.content.filter((b) => b.type === "text" && b.text).map((b) => b.text);
|
|
718
|
-
const text = textParts.join("\n").trim();
|
|
719
|
-
if (text) current.aiResponse = text;
|
|
720
|
-
current.toolCount += msg.content.filter((b) => b.type === "tool_use").length;
|
|
721
|
-
}
|
|
722
|
-
}
|
|
723
|
-
}
|
|
724
|
-
if (current) turns.push(current);
|
|
725
|
-
return turns;
|
|
736
|
+
return new StandardJsonlParser(opts).parseTurns(content);
|
|
726
737
|
}
|
|
727
738
|
|
|
728
739
|
// src/symbionts/claude-code.ts
|
|
@@ -876,10 +887,100 @@ function parseCursorText(content) {
|
|
|
876
887
|
return turns;
|
|
877
888
|
}
|
|
878
889
|
|
|
890
|
+
// src/symbionts/parsers/codex-jsonl.ts
|
|
891
|
+
function parseDataUrl(url) {
|
|
892
|
+
const match = url.match(/^data:([^;]+);base64,(.+)$/);
|
|
893
|
+
if (!match) return null;
|
|
894
|
+
return { mediaType: match[1], data: match[2] };
|
|
895
|
+
}
|
|
896
|
+
var IMAGE_WRAPPER_TAG = /^<\/?image\b[^>]*>$/;
|
|
897
|
+
var CODEX_PROMPT_MARKER = "## My request for Codex:\n";
|
|
898
|
+
function cleanCodexPromptText(text) {
|
|
899
|
+
if (IMAGE_WRAPPER_TAG.test(text.trim())) return "";
|
|
900
|
+
const idx = text.indexOf(CODEX_PROMPT_MARKER);
|
|
901
|
+
if (idx !== -1) return text.slice(idx + CODEX_PROMPT_MARKER.length);
|
|
902
|
+
return text;
|
|
903
|
+
}
|
|
904
|
+
var CodexJsonlParser = class {
|
|
905
|
+
parseTurns(content) {
|
|
906
|
+
const lines = content.split("\n").filter(Boolean);
|
|
907
|
+
const turns = [];
|
|
908
|
+
let current = null;
|
|
909
|
+
for (const line of lines) {
|
|
910
|
+
let entry;
|
|
911
|
+
try {
|
|
912
|
+
entry = JSON.parse(line);
|
|
913
|
+
} catch {
|
|
914
|
+
continue;
|
|
915
|
+
}
|
|
916
|
+
if (entry.type !== "response_item") continue;
|
|
917
|
+
const payload = entry.payload;
|
|
918
|
+
if (!payload) continue;
|
|
919
|
+
const payloadType = payload.type;
|
|
920
|
+
const timestamp = entry.timestamp ?? "";
|
|
921
|
+
if (payloadType === "function_call") {
|
|
922
|
+
if (current) current.toolCount++;
|
|
923
|
+
continue;
|
|
924
|
+
}
|
|
925
|
+
if (payloadType !== "message") continue;
|
|
926
|
+
const role = payload.role;
|
|
927
|
+
const blocks = Array.isArray(payload.content) ? payload.content : [];
|
|
928
|
+
if (role === "user") {
|
|
929
|
+
const textParts = blocks.filter((b) => b.type === "input_text" && b.text?.trim()).map((b) => cleanCodexPromptText(b.text)).filter((t) => t.trim());
|
|
930
|
+
if (textParts.length === 0) continue;
|
|
931
|
+
if (current) turns.push(current);
|
|
932
|
+
const promptText = textParts.join("\n").trim().slice(0, PROMPT_PREVIEW_CHARS);
|
|
933
|
+
const images = [];
|
|
934
|
+
for (const b of blocks) {
|
|
935
|
+
if (b.type === "input_image" && b.image_url) {
|
|
936
|
+
const parsed = parseDataUrl(b.image_url);
|
|
937
|
+
if (parsed) images.push(parsed);
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
current = { prompt: promptText, toolCount: 0, timestamp, ...images.length > 0 ? { images } : {} };
|
|
941
|
+
} else if (role === "assistant" && current) {
|
|
942
|
+
const textParts = blocks.filter((b) => b.type === "output_text" && b.text).map((b) => b.text);
|
|
943
|
+
const text = textParts.join("\n").trim();
|
|
944
|
+
if (text) current.aiResponse = text;
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
if (current) turns.push(current);
|
|
948
|
+
return turns;
|
|
949
|
+
}
|
|
950
|
+
};
|
|
951
|
+
|
|
879
952
|
// src/symbionts/codex.ts
|
|
953
|
+
import fs5 from "fs";
|
|
880
954
|
import path6 from "path";
|
|
881
955
|
import os3 from "os";
|
|
882
956
|
var TRANSCRIPT_BASE2 = path6.join(os3.homedir(), ".codex");
|
|
957
|
+
var codexParser = new CodexJsonlParser();
|
|
958
|
+
function findCodexTranscript(baseDir, sessionId) {
|
|
959
|
+
const sessionsDir = path6.join(baseDir, "sessions");
|
|
960
|
+
try {
|
|
961
|
+
return scanForSessionFile(sessionsDir, sessionId);
|
|
962
|
+
} catch {
|
|
963
|
+
return null;
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
function scanForSessionFile(dir, sessionId) {
|
|
967
|
+
let entries;
|
|
968
|
+
try {
|
|
969
|
+
entries = fs5.readdirSync(dir, { withFileTypes: true });
|
|
970
|
+
} catch {
|
|
971
|
+
return null;
|
|
972
|
+
}
|
|
973
|
+
for (const entry of entries) {
|
|
974
|
+
const fullPath = path6.join(dir, entry.name);
|
|
975
|
+
if (entry.isDirectory()) {
|
|
976
|
+
const found = scanForSessionFile(fullPath, sessionId);
|
|
977
|
+
if (found) return found;
|
|
978
|
+
} else if (entry.isFile() && entry.name.includes(sessionId) && entry.name.endsWith(".jsonl")) {
|
|
979
|
+
return fullPath;
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
return null;
|
|
983
|
+
}
|
|
883
984
|
var codexAdapter = {
|
|
884
985
|
name: "codex",
|
|
885
986
|
displayName: "Codex",
|
|
@@ -893,18 +994,12 @@ var codexAdapter = {
|
|
|
893
994
|
toolInput: "tool_input",
|
|
894
995
|
toolOutput: "tool_output"
|
|
895
996
|
},
|
|
896
|
-
findTranscript: (sessionId) =>
|
|
897
|
-
|
|
898
|
-
parseTurns: (content) => parseJsonlTurns(content, {
|
|
899
|
-
roleField: "role",
|
|
900
|
-
extractTimestamp: false,
|
|
901
|
-
skipToolResultUsers: false,
|
|
902
|
-
stripImageTextRefs: false
|
|
903
|
-
})
|
|
997
|
+
findTranscript: (sessionId) => findCodexTranscript(TRANSCRIPT_BASE2, sessionId),
|
|
998
|
+
parseTurns: (content) => codexParser.parseTurns(content)
|
|
904
999
|
};
|
|
905
1000
|
|
|
906
1001
|
// src/symbionts/gemini.ts
|
|
907
|
-
import
|
|
1002
|
+
import fs6 from "fs";
|
|
908
1003
|
import path7 from "path";
|
|
909
1004
|
import os4 from "os";
|
|
910
1005
|
var GEMINI_TMP = path7.join(os4.homedir(), ".gemini", "tmp");
|
|
@@ -924,15 +1019,15 @@ var geminiAdapter = {
|
|
|
924
1019
|
},
|
|
925
1020
|
findTranscript(sessionId) {
|
|
926
1021
|
try {
|
|
927
|
-
for (const project of
|
|
1022
|
+
for (const project of fs6.readdirSync(GEMINI_TMP, { withFileTypes: true })) {
|
|
928
1023
|
if (!project.isDirectory()) continue;
|
|
929
1024
|
const chatsDir = path7.join(GEMINI_TMP, project.name, "chats");
|
|
930
1025
|
try {
|
|
931
|
-
for (const file of
|
|
1026
|
+
for (const file of fs6.readdirSync(chatsDir)) {
|
|
932
1027
|
if (!file.endsWith(".json")) continue;
|
|
933
1028
|
if (file.includes(sessionId.slice(0, 8))) {
|
|
934
1029
|
try {
|
|
935
|
-
const data = JSON.parse(
|
|
1030
|
+
const data = JSON.parse(fs6.readFileSync(path7.join(chatsDir, file), "utf-8"));
|
|
936
1031
|
if (data.sessionId === sessionId) {
|
|
937
1032
|
return path7.join(chatsDir, file);
|
|
938
1033
|
}
|
|
@@ -986,7 +1081,7 @@ function parseGeminiJson(content) {
|
|
|
986
1081
|
}
|
|
987
1082
|
|
|
988
1083
|
// src/symbionts/windsurf.ts
|
|
989
|
-
import
|
|
1084
|
+
import fs7 from "fs";
|
|
990
1085
|
import path8 from "path";
|
|
991
1086
|
import os5 from "os";
|
|
992
1087
|
var TRANSCRIPT_DIR = path8.join(os5.homedir(), ".windsurf", "transcripts");
|
|
@@ -1009,7 +1104,7 @@ var windsurfAdapter = {
|
|
|
1009
1104
|
findTranscript(sessionId) {
|
|
1010
1105
|
const candidate = path8.join(TRANSCRIPT_DIR, `${sessionId}.jsonl`);
|
|
1011
1106
|
try {
|
|
1012
|
-
|
|
1107
|
+
fs7.accessSync(candidate);
|
|
1013
1108
|
return candidate;
|
|
1014
1109
|
} catch {
|
|
1015
1110
|
return null;
|
|
@@ -1144,7 +1239,7 @@ function normalizeResponseParts(response) {
|
|
|
1144
1239
|
}
|
|
1145
1240
|
|
|
1146
1241
|
// src/symbionts/registry.ts
|
|
1147
|
-
import
|
|
1242
|
+
import fs8 from "fs";
|
|
1148
1243
|
var ALL_ADAPTERS = [
|
|
1149
1244
|
claudeCodeAdapter,
|
|
1150
1245
|
cursorAdapter,
|
|
@@ -1167,7 +1262,7 @@ var SymbiontRegistry = class {
|
|
|
1167
1262
|
const filePath = adapter.findTranscript(sessionId);
|
|
1168
1263
|
if (!filePath) continue;
|
|
1169
1264
|
try {
|
|
1170
|
-
const content =
|
|
1265
|
+
const content = fs8.readFileSync(filePath, "utf-8");
|
|
1171
1266
|
const turns = adapter.parseTurns(content);
|
|
1172
1267
|
if (turns.length > 0) {
|
|
1173
1268
|
return { turns, source: adapter.name };
|
|
@@ -1201,7 +1296,7 @@ var SymbiontRegistry = class {
|
|
|
1201
1296
|
*/
|
|
1202
1297
|
parseTurnsFromPath(filePath) {
|
|
1203
1298
|
try {
|
|
1204
|
-
const content =
|
|
1299
|
+
const content = fs8.readFileSync(filePath, "utf-8");
|
|
1205
1300
|
const active = this.detectActiveAgent();
|
|
1206
1301
|
const orderedAdapters = active ? [active, ...this.adapters.filter((a) => a !== active)] : this.adapters;
|
|
1207
1302
|
for (const adapter of orderedAdapters) {
|
|
@@ -1601,7 +1696,7 @@ async function handleRestart(deps, body) {
|
|
|
1601
1696
|
|
|
1602
1697
|
// src/daemon/update-checker.ts
|
|
1603
1698
|
var import_yaml = __toESM(require_dist(), 1);
|
|
1604
|
-
import
|
|
1699
|
+
import fs9 from "fs";
|
|
1605
1700
|
import path9 from "path";
|
|
1606
1701
|
import { execFileSync } from "child_process";
|
|
1607
1702
|
import semver from "semver";
|
|
@@ -1638,7 +1733,7 @@ function defaultUpdateConfig() {
|
|
|
1638
1733
|
}
|
|
1639
1734
|
function readUpdateConfig() {
|
|
1640
1735
|
try {
|
|
1641
|
-
const raw =
|
|
1736
|
+
const raw = fs9.readFileSync(UPDATE_CONFIG_PATH, "utf-8");
|
|
1642
1737
|
const parsed = import_yaml.default.parse(raw);
|
|
1643
1738
|
const channel = RELEASE_CHANNELS.includes(parsed?.channel) ? parsed.channel : DEFAULT_RELEASE_CHANNEL;
|
|
1644
1739
|
const check_interval_hours = typeof parsed?.check_interval_hours === "number" && parsed.check_interval_hours > 0 ? parsed.check_interval_hours : UPDATE_CHECK_INTERVAL_HOURS;
|
|
@@ -1648,12 +1743,12 @@ function readUpdateConfig() {
|
|
|
1648
1743
|
}
|
|
1649
1744
|
}
|
|
1650
1745
|
function writeUpdateConfig(config) {
|
|
1651
|
-
|
|
1652
|
-
|
|
1746
|
+
fs9.mkdirSync(MYCO_GLOBAL_DIR, { recursive: true });
|
|
1747
|
+
fs9.writeFileSync(UPDATE_CONFIG_PATH, import_yaml.default.stringify(config), "utf-8");
|
|
1653
1748
|
}
|
|
1654
1749
|
function readCachedCheck() {
|
|
1655
1750
|
try {
|
|
1656
|
-
const raw =
|
|
1751
|
+
const raw = fs9.readFileSync(UPDATE_CHECK_CACHE_PATH, "utf-8");
|
|
1657
1752
|
return JSON.parse(raw);
|
|
1658
1753
|
} catch {
|
|
1659
1754
|
return null;
|
|
@@ -1661,7 +1756,7 @@ function readCachedCheck() {
|
|
|
1661
1756
|
}
|
|
1662
1757
|
function clearCachedCheck() {
|
|
1663
1758
|
try {
|
|
1664
|
-
|
|
1759
|
+
fs9.unlinkSync(UPDATE_CHECK_CACHE_PATH);
|
|
1665
1760
|
} catch {
|
|
1666
1761
|
}
|
|
1667
1762
|
}
|
|
@@ -1711,7 +1806,7 @@ function getInstalledVersion(globalPrefix) {
|
|
|
1711
1806
|
NPM_PACKAGE_NAME,
|
|
1712
1807
|
"package.json"
|
|
1713
1808
|
);
|
|
1714
|
-
const raw =
|
|
1809
|
+
const raw = fs9.readFileSync(pkgPath, "utf-8");
|
|
1715
1810
|
const pkg = JSON.parse(raw);
|
|
1716
1811
|
return pkg.version ?? null;
|
|
1717
1812
|
} catch {
|
|
@@ -1760,8 +1855,8 @@ async function checkForUpdate(currentVersion) {
|
|
|
1760
1855
|
channel: config.channel
|
|
1761
1856
|
};
|
|
1762
1857
|
try {
|
|
1763
|
-
|
|
1764
|
-
|
|
1858
|
+
fs9.mkdirSync(path9.dirname(UPDATE_CHECK_CACHE_PATH), { recursive: true });
|
|
1859
|
+
fs9.writeFileSync(UPDATE_CHECK_CACHE_PATH, JSON.stringify(freshCache, null, 2), "utf-8");
|
|
1765
1860
|
} catch {
|
|
1766
1861
|
}
|
|
1767
1862
|
return buildCheckResult(currentVersion, freshCache, config, null);
|
|
@@ -1774,7 +1869,7 @@ function statusFromCache(currentVersion, cache, config) {
|
|
|
1774
1869
|
}
|
|
1775
1870
|
|
|
1776
1871
|
// src/daemon/update-installer.ts
|
|
1777
|
-
import
|
|
1872
|
+
import fs10 from "fs";
|
|
1778
1873
|
import os6 from "os";
|
|
1779
1874
|
import path10 from "path";
|
|
1780
1875
|
import { spawn as spawn2 } from "child_process";
|
|
@@ -1815,7 +1910,7 @@ rm -f "$0"
|
|
|
1815
1910
|
}
|
|
1816
1911
|
function spawnDetachedScript(namePrefix, content) {
|
|
1817
1912
|
const scriptPath = path10.join(os6.tmpdir(), `${namePrefix}-${Date.now()}.sh`);
|
|
1818
|
-
|
|
1913
|
+
fs10.writeFileSync(scriptPath, content, { encoding: "utf-8", mode: 493 });
|
|
1819
1914
|
const child = spawn2("/bin/sh", [scriptPath], {
|
|
1820
1915
|
detached: true,
|
|
1821
1916
|
stdio: "ignore"
|
|
@@ -1824,7 +1919,7 @@ function spawnDetachedScript(namePrefix, content) {
|
|
|
1824
1919
|
return scriptPath;
|
|
1825
1920
|
}
|
|
1826
1921
|
function spawnUpdateScript(params) {
|
|
1827
|
-
|
|
1922
|
+
fs10.mkdirSync(MYCO_GLOBAL_DIR, { recursive: true });
|
|
1828
1923
|
return spawnDetachedScript("myco-update", generateUpdateScript(params));
|
|
1829
1924
|
}
|
|
1830
1925
|
function generateRestartScript(params) {
|
|
@@ -1866,7 +1961,7 @@ function spawnRestartScript(params) {
|
|
|
1866
1961
|
|
|
1867
1962
|
// src/daemon/api/update.ts
|
|
1868
1963
|
import semver2 from "semver";
|
|
1869
|
-
import
|
|
1964
|
+
import fs11 from "fs";
|
|
1870
1965
|
import path11 from "path";
|
|
1871
1966
|
var ChannelBodySchema = external_exports.object({
|
|
1872
1967
|
channel: external_exports.enum(RELEASE_CHANNELS)
|
|
@@ -1877,7 +1972,7 @@ function createUpdateHandlers(deps) {
|
|
|
1877
1972
|
function isStampCurrent() {
|
|
1878
1973
|
try {
|
|
1879
1974
|
const stampPath = path11.join(vaultDir, UPDATE_STAMP_FILENAME);
|
|
1880
|
-
const stamp =
|
|
1975
|
+
const stamp = fs11.readFileSync(stampPath, "utf-8").trim();
|
|
1881
1976
|
return stamp === currentVersion;
|
|
1882
1977
|
} catch {
|
|
1883
1978
|
return false;
|
|
@@ -2000,7 +2095,7 @@ function createUpdateHandlers(deps) {
|
|
|
2000
2095
|
}
|
|
2001
2096
|
|
|
2002
2097
|
// src/daemon/backup.ts
|
|
2003
|
-
import
|
|
2098
|
+
import fs12 from "fs";
|
|
2004
2099
|
import path12 from "path";
|
|
2005
2100
|
var BACKUP_TABLES = [
|
|
2006
2101
|
"sessions",
|
|
@@ -2028,7 +2123,7 @@ function toSqlLiteral(value) {
|
|
|
2028
2123
|
return `'${escapeSql(String(value))}'`;
|
|
2029
2124
|
}
|
|
2030
2125
|
function createBackup(db, backupDir, machineId) {
|
|
2031
|
-
|
|
2126
|
+
fs12.mkdirSync(backupDir, { recursive: true });
|
|
2032
2127
|
const lines = [];
|
|
2033
2128
|
const timestamp = epochSeconds();
|
|
2034
2129
|
lines.push(`${BACKUP_HEADER_TEMPLATE}: machine_id=${machineId}, created_at=${timestamp}`);
|
|
@@ -2047,13 +2142,13 @@ function createBackup(db, backupDir, machineId) {
|
|
|
2047
2142
|
lines.push("");
|
|
2048
2143
|
}
|
|
2049
2144
|
const filePath = path12.join(backupDir, `${machineId}${BACKUP_EXTENSION}`);
|
|
2050
|
-
|
|
2145
|
+
fs12.writeFileSync(filePath, lines.join("\n"), "utf-8");
|
|
2051
2146
|
return filePath;
|
|
2052
2147
|
}
|
|
2053
2148
|
function listBackups(backupDir) {
|
|
2054
2149
|
let entries;
|
|
2055
2150
|
try {
|
|
2056
|
-
entries =
|
|
2151
|
+
entries = fs12.readdirSync(backupDir);
|
|
2057
2152
|
} catch {
|
|
2058
2153
|
return [];
|
|
2059
2154
|
}
|
|
@@ -2061,7 +2156,7 @@ function listBackups(backupDir) {
|
|
|
2061
2156
|
for (const entry of entries) {
|
|
2062
2157
|
if (!BACKUP_FILENAME_PATTERN.test(entry)) continue;
|
|
2063
2158
|
const filePath = path12.join(backupDir, entry);
|
|
2064
|
-
const stat =
|
|
2159
|
+
const stat = fs12.statSync(filePath);
|
|
2065
2160
|
backups.push({
|
|
2066
2161
|
machine_id: entry.slice(0, -BACKUP_EXTENSION.length),
|
|
2067
2162
|
file_name: entry,
|
|
@@ -2073,7 +2168,7 @@ function listBackups(backupDir) {
|
|
|
2073
2168
|
}
|
|
2074
2169
|
var INSERT_REGEX = /^INSERT OR IGNORE INTO (\w+)\s+\(([^)]+)\)\s+VALUES\s+\((.+)\);$/;
|
|
2075
2170
|
function parseBackupFile(backupPath) {
|
|
2076
|
-
const content =
|
|
2171
|
+
const content = fs12.readFileSync(backupPath, "utf-8");
|
|
2077
2172
|
const inserts = [];
|
|
2078
2173
|
for (const line of content.split("\n")) {
|
|
2079
2174
|
const match = INSERT_REGEX.exec(line);
|
|
@@ -2490,7 +2585,7 @@ function createTeamHandlers(deps) {
|
|
|
2490
2585
|
return { body: { retried: count } };
|
|
2491
2586
|
}
|
|
2492
2587
|
async function handleUpgradeWorker(_req) {
|
|
2493
|
-
const { upgradeWorker } = await import("./team-
|
|
2588
|
+
const { upgradeWorker } = await import("./team-DPNP2RN7.js");
|
|
2494
2589
|
logger.info("team-sync.upgrade.start", "Starting worker upgrade");
|
|
2495
2590
|
const result = upgradeWorker(vaultDir);
|
|
2496
2591
|
if (!result.success) {
|
|
@@ -2616,7 +2711,7 @@ function createSessionLifecycleHandlers(deps) {
|
|
|
2616
2711
|
}
|
|
2617
2712
|
|
|
2618
2713
|
// src/daemon/api/skills.ts
|
|
2619
|
-
import
|
|
2714
|
+
import fs13 from "fs";
|
|
2620
2715
|
import path14 from "path";
|
|
2621
2716
|
|
|
2622
2717
|
// src/db/queries/skill-usage.ts
|
|
@@ -2787,7 +2882,7 @@ function createSkillRecordDeleteHandler(deps) {
|
|
|
2787
2882
|
const projectRoot = path14.resolve(vaultDir, "..");
|
|
2788
2883
|
const skillDir = path14.resolve(projectRoot, ".agents", "skills", record.name);
|
|
2789
2884
|
try {
|
|
2790
|
-
|
|
2885
|
+
fs13.rmSync(skillDir, { recursive: true, force: true });
|
|
2791
2886
|
} catch (err) {
|
|
2792
2887
|
logger.warn(LOG_KINDS.PROCESSOR_BATCH, "Failed to remove skill directory", { name: record.name, error: String(err) });
|
|
2793
2888
|
}
|
|
@@ -3045,12 +3140,12 @@ async function handleGetModels(req) {
|
|
|
3045
3140
|
|
|
3046
3141
|
// src/daemon/api/stats.ts
|
|
3047
3142
|
import { createHash as createHash2 } from "crypto";
|
|
3048
|
-
import
|
|
3143
|
+
import fs14 from "fs";
|
|
3049
3144
|
import path15 from "path";
|
|
3050
3145
|
function computeConfigHash(vaultDir) {
|
|
3051
3146
|
try {
|
|
3052
3147
|
const configPath = path15.join(vaultDir, CONFIG_FILENAME);
|
|
3053
|
-
const raw =
|
|
3148
|
+
const raw = fs14.readFileSync(configPath, "utf-8");
|
|
3054
3149
|
return createHash2("md5").update(raw).digest("hex");
|
|
3055
3150
|
} catch {
|
|
3056
3151
|
return "";
|
|
@@ -4403,6 +4498,13 @@ var EmbeddingManager = class {
|
|
|
4403
4498
|
searchVectors(query, options) {
|
|
4404
4499
|
return this.vectorStore.search(query, options);
|
|
4405
4500
|
}
|
|
4501
|
+
/**
|
|
4502
|
+
* Compute pairwise cosine similarity between all vectors in a namespace.
|
|
4503
|
+
* Used by the evolve instruction builder to find semantically overlapping skills.
|
|
4504
|
+
*/
|
|
4505
|
+
pairwiseSimilarity(namespace, threshold) {
|
|
4506
|
+
return this.vectorStore.pairwiseSimilarity(namespace, threshold);
|
|
4507
|
+
}
|
|
4406
4508
|
// -------------------------------------------------------------------------
|
|
4407
4509
|
// Private helpers
|
|
4408
4510
|
// -------------------------------------------------------------------------
|
|
@@ -4673,6 +4775,48 @@ var SqliteVecVectorStore = class {
|
|
|
4673
4775
|
const rows = this.embeddedIdsStmt.all(namespace);
|
|
4674
4776
|
return rows.map((r) => r.record_id);
|
|
4675
4777
|
}
|
|
4778
|
+
/**
|
|
4779
|
+
* Compute pairwise cosine similarity between all vectors in a namespace.
|
|
4780
|
+
* Returns pairs above the threshold, sorted by similarity DESC.
|
|
4781
|
+
*
|
|
4782
|
+
* Uses sqlite-vec's KNN search: for each vector, find the top-K nearest
|
|
4783
|
+
* neighbors within the same namespace. O(n * K) where K is small.
|
|
4784
|
+
*/
|
|
4785
|
+
pairwiseSimilarity(namespace, threshold = 0.5) {
|
|
4786
|
+
this.validateNamespace(namespace);
|
|
4787
|
+
const ns = namespace;
|
|
4788
|
+
const allRows = this.db.prepare(
|
|
4789
|
+
`SELECT record_id, embedding FROM vec_${ns}`
|
|
4790
|
+
).all();
|
|
4791
|
+
if (allRows.length < 2) return [];
|
|
4792
|
+
const pairs = [];
|
|
4793
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4794
|
+
const searchStmt = this.searchStmts.get(ns);
|
|
4795
|
+
for (const row of allRows) {
|
|
4796
|
+
const results = searchStmt.all(
|
|
4797
|
+
row.embedding,
|
|
4798
|
+
// Use the raw embedding as the query vector
|
|
4799
|
+
allRows.length
|
|
4800
|
+
// K = all rows to get exhaustive comparison
|
|
4801
|
+
);
|
|
4802
|
+
for (const match of results) {
|
|
4803
|
+
if (match.record_id === row.record_id) continue;
|
|
4804
|
+
const pairKey = [row.record_id, match.record_id].sort().join("|");
|
|
4805
|
+
if (seen.has(pairKey)) continue;
|
|
4806
|
+
seen.add(pairKey);
|
|
4807
|
+
const similarity = cosineDistanceToSimilarity(match.distance);
|
|
4808
|
+
if (similarity >= threshold) {
|
|
4809
|
+
pairs.push({
|
|
4810
|
+
idA: row.record_id,
|
|
4811
|
+
idB: match.record_id,
|
|
4812
|
+
similarity: Math.round(similarity * 1e3) / 1e3
|
|
4813
|
+
});
|
|
4814
|
+
}
|
|
4815
|
+
}
|
|
4816
|
+
}
|
|
4817
|
+
pairs.sort((a, b) => b.similarity - a.similarity);
|
|
4818
|
+
return pairs;
|
|
4819
|
+
}
|
|
4676
4820
|
// -------------------------------------------------------------------------
|
|
4677
4821
|
// Lifecycle
|
|
4678
4822
|
// -------------------------------------------------------------------------
|
|
@@ -4810,6 +4954,12 @@ function planMetadata(row) {
|
|
|
4810
4954
|
...row.source_path != null ? { source_path: row.source_path } : {}
|
|
4811
4955
|
};
|
|
4812
4956
|
}
|
|
4957
|
+
function skillRecordMetadata(row) {
|
|
4958
|
+
return {
|
|
4959
|
+
...row.status != null ? { status: row.status } : {},
|
|
4960
|
+
...row.name != null ? { name: row.name } : {}
|
|
4961
|
+
};
|
|
4962
|
+
}
|
|
4813
4963
|
function metadataFor(namespace, row) {
|
|
4814
4964
|
switch (namespace) {
|
|
4815
4965
|
case "sessions":
|
|
@@ -4820,6 +4970,8 @@ function metadataFor(namespace, row) {
|
|
|
4820
4970
|
return planMetadata(row);
|
|
4821
4971
|
case "artifacts":
|
|
4822
4972
|
return emptyMetadata();
|
|
4973
|
+
case "skill_records":
|
|
4974
|
+
return skillRecordMetadata(row);
|
|
4823
4975
|
}
|
|
4824
4976
|
}
|
|
4825
4977
|
var SqliteRecordSource = class {
|
|
@@ -4834,6 +4986,9 @@ var SqliteRecordSource = class {
|
|
|
4834
4986
|
if (namespace === "spores") {
|
|
4835
4987
|
return this.getUnembeddedActiveSpores(limit);
|
|
4836
4988
|
}
|
|
4989
|
+
if (namespace === "skill_records") {
|
|
4990
|
+
return this.getUnembeddedActiveSkillRecords(limit);
|
|
4991
|
+
}
|
|
4837
4992
|
const rows = getUnembedded(namespace, limit);
|
|
4838
4993
|
const db = getDatabase();
|
|
4839
4994
|
return rows.map((row) => {
|
|
@@ -4880,6 +5035,12 @@ var SqliteRecordSource = class {
|
|
|
4880
5035
|
).all();
|
|
4881
5036
|
return rows.map((r) => r.id);
|
|
4882
5037
|
}
|
|
5038
|
+
case "skill_records": {
|
|
5039
|
+
const rows = db.prepare(
|
|
5040
|
+
`SELECT id FROM skill_records WHERE status = ?`
|
|
5041
|
+
).all(ACTIVE_STATUS2);
|
|
5042
|
+
return rows.map((r) => r.id);
|
|
5043
|
+
}
|
|
4883
5044
|
}
|
|
4884
5045
|
}
|
|
4885
5046
|
/**
|
|
@@ -4934,7 +5095,7 @@ var SqliteRecordSource = class {
|
|
|
4934
5095
|
assertValidTable(namespace);
|
|
4935
5096
|
const db = getDatabase();
|
|
4936
5097
|
const contentFilter = namespace === "sessions" ? " AND summary IS NOT NULL" : "";
|
|
4937
|
-
const statusFilter = namespace === "spores" ? ` AND status = '${ACTIVE_STATUS2}'` : "";
|
|
5098
|
+
const statusFilter = namespace === "spores" || namespace === "skill_records" ? ` AND status = '${ACTIVE_STATUS2}'` : "";
|
|
4938
5099
|
const row = db.prepare(
|
|
4939
5100
|
`SELECT COUNT(*) AS cnt FROM ${namespace} WHERE embedded = 0${contentFilter}${statusFilter}`
|
|
4940
5101
|
).get();
|
|
@@ -4959,20 +5120,36 @@ var SqliteRecordSource = class {
|
|
|
4959
5120
|
metadata: sporeMetadata(row)
|
|
4960
5121
|
}));
|
|
4961
5122
|
}
|
|
5123
|
+
/** Custom query for skill_records: embedded=0 AND status='active'. */
|
|
5124
|
+
getUnembeddedActiveSkillRecords(limit) {
|
|
5125
|
+
const db = getDatabase();
|
|
5126
|
+
const rows = db.prepare(
|
|
5127
|
+
`SELECT id, description AS text, status, name
|
|
5128
|
+
FROM skill_records
|
|
5129
|
+
WHERE embedded = 0 AND status = ?
|
|
5130
|
+
ORDER BY created_at ASC
|
|
5131
|
+
LIMIT ?`
|
|
5132
|
+
).all(ACTIVE_STATUS2, limit);
|
|
5133
|
+
return rows.map((row) => ({
|
|
5134
|
+
id: String(row.id),
|
|
5135
|
+
text: row.text,
|
|
5136
|
+
metadata: skillRecordMetadata(row)
|
|
5137
|
+
}));
|
|
5138
|
+
}
|
|
4962
5139
|
};
|
|
4963
5140
|
|
|
4964
5141
|
// src/daemon/database/manager.ts
|
|
4965
|
-
import
|
|
5142
|
+
import fs16 from "fs";
|
|
4966
5143
|
|
|
4967
5144
|
// src/db/queries/database.ts
|
|
4968
|
-
import
|
|
5145
|
+
import fs15 from "fs";
|
|
4969
5146
|
function pragmaScalar(name) {
|
|
4970
5147
|
const db = getDatabase();
|
|
4971
5148
|
return db.pragma(name, { simple: true });
|
|
4972
5149
|
}
|
|
4973
5150
|
function safeFileSize(filePath) {
|
|
4974
5151
|
try {
|
|
4975
|
-
return
|
|
5152
|
+
return fs15.statSync(filePath).size;
|
|
4976
5153
|
} catch (err) {
|
|
4977
5154
|
if (err.code === "ENOENT") return 0;
|
|
4978
5155
|
throw err;
|
|
@@ -5244,7 +5421,7 @@ var DatabaseMaintenanceManager = class {
|
|
|
5244
5421
|
}
|
|
5245
5422
|
async vacuum() {
|
|
5246
5423
|
const size_before = this.fileSize();
|
|
5247
|
-
const stats = await
|
|
5424
|
+
const stats = await fs16.promises.statfs(this.vaultDir);
|
|
5248
5425
|
const free_bytes = Number(stats.bavail) * Number(stats.bsize);
|
|
5249
5426
|
const required_bytes = size_before * VACUUM_FREE_SPACE_MULTIPLIER;
|
|
5250
5427
|
if (free_bytes < required_bytes) {
|
|
@@ -5292,7 +5469,7 @@ var DatabaseMaintenanceManager = class {
|
|
|
5292
5469
|
}
|
|
5293
5470
|
fileSize() {
|
|
5294
5471
|
try {
|
|
5295
|
-
return
|
|
5472
|
+
return fs16.statSync(this.dbPath).size;
|
|
5296
5473
|
} catch {
|
|
5297
5474
|
return 0;
|
|
5298
5475
|
}
|
|
@@ -5685,6 +5862,9 @@ function testAnthropic() {
|
|
|
5685
5862
|
return { ok: true };
|
|
5686
5863
|
}
|
|
5687
5864
|
|
|
5865
|
+
// src/daemon/task-scheduling.ts
|
|
5866
|
+
import { resolve } from "path";
|
|
5867
|
+
|
|
5688
5868
|
// src/daemon/task-scheduler.ts
|
|
5689
5869
|
function resolveSchedule(yamlSchedule, configOverride) {
|
|
5690
5870
|
if (!configOverride?.schedule) return yamlSchedule;
|
|
@@ -5744,6 +5924,10 @@ async function registerScheduledTasks(powerManager, deps) {
|
|
|
5744
5924
|
}
|
|
5745
5925
|
const { loadAllTasks: loadAllTasks2 } = await import("./registry-O2NZLO3V.js");
|
|
5746
5926
|
const allTasks = Array.from(loadAllTasks2(definitionsDir, vaultDir).values());
|
|
5927
|
+
const taskAgentMap = /* @__PURE__ */ new Map();
|
|
5928
|
+
for (const task of allTasks) {
|
|
5929
|
+
taskAgentMap.set(task.name, task.agent);
|
|
5930
|
+
}
|
|
5747
5931
|
const initialLastRuns = {};
|
|
5748
5932
|
try {
|
|
5749
5933
|
const recentRuns = getDatabase().prepare(
|
|
@@ -5764,9 +5948,10 @@ async function registerScheduledTasks(powerManager, deps) {
|
|
|
5764
5948
|
else runningTasks.delete(name);
|
|
5765
5949
|
},
|
|
5766
5950
|
runTask: async (taskName) => {
|
|
5767
|
-
const { runAgent } = await import("./executor-
|
|
5951
|
+
const { runAgent } = await import("./executor-UYIZC3L5.js");
|
|
5768
5952
|
const taskConfig = config.agent.tasks?.[taskName];
|
|
5769
|
-
const
|
|
5953
|
+
const projectRoot = resolve(vaultDir, "..");
|
|
5954
|
+
const built = buildTaskInstruction(taskName, taskConfig?.params, taskAgentMap.get(taskName), projectRoot, embeddingManager);
|
|
5770
5955
|
if (isInstructionRequiredTask(taskName) && !built) {
|
|
5771
5956
|
logger.info(
|
|
5772
5957
|
LOG_KINDS.AGENT_RUN,
|
|
@@ -6015,6 +6200,7 @@ function createMcpProxyHandlers(deps) {
|
|
|
6015
6200
|
}
|
|
6016
6201
|
|
|
6017
6202
|
// src/daemon/api/agent-runs.ts
|
|
6203
|
+
import { resolve as resolve2 } from "path";
|
|
6018
6204
|
var AGENT_RUNS_DEFAULT_LIMIT = 50;
|
|
6019
6205
|
var AgentRunBody = external_exports.object({
|
|
6020
6206
|
task: external_exports.string().optional(),
|
|
@@ -6041,9 +6227,11 @@ function createAgentRunHandlers(deps) {
|
|
|
6041
6227
|
let built;
|
|
6042
6228
|
try {
|
|
6043
6229
|
const taskParams = mycoConfig.agent.tasks?.[task]?.params;
|
|
6044
|
-
|
|
6230
|
+
const projectRoot = resolve2(vaultDir, "..");
|
|
6231
|
+
built = buildTaskInstruction(task, taskParams, agentId, projectRoot, embeddingManager);
|
|
6045
6232
|
} catch {
|
|
6046
|
-
|
|
6233
|
+
const projectRoot = resolve2(vaultDir, "..");
|
|
6234
|
+
built = buildTaskInstruction(task, void 0, agentId, projectRoot, embeddingManager);
|
|
6047
6235
|
}
|
|
6048
6236
|
instruction = built?.instruction;
|
|
6049
6237
|
runContext = built?.context;
|
|
@@ -6058,7 +6246,7 @@ function createAgentRunHandlers(deps) {
|
|
|
6058
6246
|
};
|
|
6059
6247
|
}
|
|
6060
6248
|
}
|
|
6061
|
-
const { runAgent } = await import("./executor-
|
|
6249
|
+
const { runAgent } = await import("./executor-UYIZC3L5.js");
|
|
6062
6250
|
const resultPromise = runAgent(vaultDir, {
|
|
6063
6251
|
task,
|
|
6064
6252
|
instruction,
|
|
@@ -6127,7 +6315,7 @@ function createAgentRunHandlers(deps) {
|
|
|
6127
6315
|
}
|
|
6128
6316
|
|
|
6129
6317
|
// src/daemon/api/attachments.ts
|
|
6130
|
-
import
|
|
6318
|
+
import fs17 from "fs";
|
|
6131
6319
|
import path16 from "path";
|
|
6132
6320
|
var ATTACHMENT_MEDIA_TYPES = {
|
|
6133
6321
|
png: "image/png",
|
|
@@ -6151,7 +6339,7 @@ function createAttachmentHandler(deps) {
|
|
|
6151
6339
|
const filePath = path16.join(vaultDir, "attachments", filename);
|
|
6152
6340
|
let diskData;
|
|
6153
6341
|
try {
|
|
6154
|
-
diskData =
|
|
6342
|
+
diskData = fs17.readFileSync(filePath);
|
|
6155
6343
|
} catch {
|
|
6156
6344
|
return { status: 404, body: { error: "not_found" } };
|
|
6157
6345
|
}
|
|
@@ -6163,19 +6351,19 @@ function createAttachmentHandler(deps) {
|
|
|
6163
6351
|
}
|
|
6164
6352
|
|
|
6165
6353
|
// src/daemon/log-reconcile.ts
|
|
6166
|
-
import
|
|
6354
|
+
import fs18 from "fs";
|
|
6167
6355
|
import path17 from "path";
|
|
6168
6356
|
function reconcileLogBuffer(logDir, sinceTimestamp) {
|
|
6169
6357
|
let replayed = 0;
|
|
6170
6358
|
const files = [];
|
|
6171
6359
|
for (let i = 3; i >= 1; i--) {
|
|
6172
6360
|
const rotated = path17.join(logDir, `daemon.${i}.log`);
|
|
6173
|
-
if (
|
|
6361
|
+
if (fs18.existsSync(rotated)) files.push(rotated);
|
|
6174
6362
|
}
|
|
6175
6363
|
const current = path17.join(logDir, "daemon.log");
|
|
6176
|
-
if (
|
|
6364
|
+
if (fs18.existsSync(current)) files.push(current);
|
|
6177
6365
|
for (const file of files) {
|
|
6178
|
-
const content =
|
|
6366
|
+
const content = fs18.readFileSync(file, "utf-8");
|
|
6179
6367
|
for (const line of content.split("\n")) {
|
|
6180
6368
|
if (!line.trim()) continue;
|
|
6181
6369
|
try {
|
|
@@ -6454,7 +6642,7 @@ function registerPowerJobs(powerManager, deps) {
|
|
|
6454
6642
|
}
|
|
6455
6643
|
|
|
6456
6644
|
// src/daemon/reconciliation.ts
|
|
6457
|
-
import
|
|
6645
|
+
import fs19 from "fs";
|
|
6458
6646
|
import path18 from "path";
|
|
6459
6647
|
|
|
6460
6648
|
// src/daemon/event-handlers.ts
|
|
@@ -6627,7 +6815,7 @@ function createReconciler({ bufferDir, logger }) {
|
|
|
6627
6815
|
const bufferPath = path18.join(bufferDir, `${sessionId}.jsonl`);
|
|
6628
6816
|
let content;
|
|
6629
6817
|
try {
|
|
6630
|
-
content =
|
|
6818
|
+
content = fs19.readFileSync(bufferPath, "utf-8").trim();
|
|
6631
6819
|
} catch {
|
|
6632
6820
|
return;
|
|
6633
6821
|
}
|
|
@@ -6696,7 +6884,7 @@ function createReconciler({ bufferDir, logger }) {
|
|
|
6696
6884
|
}
|
|
6697
6885
|
|
|
6698
6886
|
// src/daemon/stop-processing.ts
|
|
6699
|
-
import
|
|
6887
|
+
import fs20 from "fs";
|
|
6700
6888
|
|
|
6701
6889
|
// src/daemon/capture-images.ts
|
|
6702
6890
|
var SESSION_SHORT_LEN = 6;
|
|
@@ -6733,6 +6921,78 @@ function captureBatchImages(input) {
|
|
|
6733
6921
|
}
|
|
6734
6922
|
}
|
|
6735
6923
|
|
|
6924
|
+
// src/daemon/plan-capture.ts
|
|
6925
|
+
import { createHash as createHash4 } from "crypto";
|
|
6926
|
+
import os7 from "os";
|
|
6927
|
+
import path19 from "path";
|
|
6928
|
+
function extractTaggedPlans(text, tags) {
|
|
6929
|
+
const results = [];
|
|
6930
|
+
for (const tag of tags) {
|
|
6931
|
+
const regex = new RegExp(`<${tag}>\\n?([\\s\\S]*?)\\n?</${tag}>`, "g");
|
|
6932
|
+
let match;
|
|
6933
|
+
while ((match = regex.exec(text)) !== null) {
|
|
6934
|
+
const content = match[1].trim();
|
|
6935
|
+
if (content) results.push({ tag, content });
|
|
6936
|
+
}
|
|
6937
|
+
}
|
|
6938
|
+
return results;
|
|
6939
|
+
}
|
|
6940
|
+
var TRANSCRIPT_SOURCE_PREFIX = "transcript:";
|
|
6941
|
+
var FILE_WRITE_TOOLS = /* @__PURE__ */ new Set([
|
|
6942
|
+
"Write",
|
|
6943
|
+
"Edit",
|
|
6944
|
+
"Create",
|
|
6945
|
+
"write",
|
|
6946
|
+
"edit",
|
|
6947
|
+
"patch",
|
|
6948
|
+
"create"
|
|
6949
|
+
]);
|
|
6950
|
+
var HEADING_REGEX = /^#\s+(.+)$/m;
|
|
6951
|
+
var PLAN_ID_HASH_LENGTH = 16;
|
|
6952
|
+
function isInPlanDirectory(filePath, watchDirs, projectRoot) {
|
|
6953
|
+
const abs = path19.isAbsolute(filePath) ? filePath : path19.resolve(projectRoot, filePath);
|
|
6954
|
+
return watchDirs.some((dir) => {
|
|
6955
|
+
const expanded = dir.startsWith("~/") ? path19.join(os7.homedir(), dir.slice(2)) : dir;
|
|
6956
|
+
const absDir = path19.isAbsolute(expanded) ? expanded : path19.resolve(projectRoot, expanded);
|
|
6957
|
+
const prefix = absDir.endsWith(path19.sep) ? absDir : absDir + path19.sep;
|
|
6958
|
+
return abs === absDir || abs.startsWith(prefix);
|
|
6959
|
+
});
|
|
6960
|
+
}
|
|
6961
|
+
function isPlanWriteEvent(toolName, toolInput, config) {
|
|
6962
|
+
if (!FILE_WRITE_TOOLS.has(toolName)) return null;
|
|
6963
|
+
const filePath = toolInput?.file_path ?? toolInput?.path ?? toolInput?.filePath;
|
|
6964
|
+
if (typeof filePath !== "string") return null;
|
|
6965
|
+
if (!isInPlanDirectory(filePath, config.watchDirs, config.projectRoot)) return null;
|
|
6966
|
+
if (config.extensions?.length) {
|
|
6967
|
+
const ext = path19.extname(filePath).toLowerCase();
|
|
6968
|
+
if (!config.extensions.includes(ext)) return null;
|
|
6969
|
+
}
|
|
6970
|
+
return filePath;
|
|
6971
|
+
}
|
|
6972
|
+
function parsePlanTitle(content, filename) {
|
|
6973
|
+
const match = HEADING_REGEX.exec(content);
|
|
6974
|
+
if (match) return match[1].trim();
|
|
6975
|
+
return filename ?? null;
|
|
6976
|
+
}
|
|
6977
|
+
function capturePlan(input) {
|
|
6978
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
6979
|
+
const contentHash = createHash4(CONTENT_HASH_ALGORITHM).update(input.content).digest("hex");
|
|
6980
|
+
const id = createHash4("md5").update(input.sourcePath).digest("hex").slice(0, PLAN_ID_HASH_LENGTH);
|
|
6981
|
+
const title = parsePlanTitle(input.content, path19.basename(input.sourcePath));
|
|
6982
|
+
return upsertPlan({
|
|
6983
|
+
id,
|
|
6984
|
+
title,
|
|
6985
|
+
content: input.content,
|
|
6986
|
+
source_path: input.sourcePath,
|
|
6987
|
+
session_id: input.sessionId,
|
|
6988
|
+
prompt_batch_id: input.promptBatchId ?? null,
|
|
6989
|
+
content_hash: contentHash,
|
|
6990
|
+
status: "active",
|
|
6991
|
+
created_at: now,
|
|
6992
|
+
updated_at: now
|
|
6993
|
+
});
|
|
6994
|
+
}
|
|
6995
|
+
|
|
6736
6996
|
// src/daemon/skill-usage.ts
|
|
6737
6997
|
import crypto from "crypto";
|
|
6738
6998
|
var SKILL_USAGE_DETECTION_ENABLED = false;
|
|
@@ -6809,7 +7069,7 @@ function createStopProcessor(deps) {
|
|
|
6809
7069
|
if (config.agent.summary_batch_interval <= 0) return;
|
|
6810
7070
|
if (config.agent.event_tasks_enabled === false) return;
|
|
6811
7071
|
try {
|
|
6812
|
-
const { runAgent } = await import("./executor-
|
|
7072
|
+
const { runAgent } = await import("./executor-UYIZC3L5.js");
|
|
6813
7073
|
runAgent(vaultDir, {
|
|
6814
7074
|
task: "title-summary",
|
|
6815
7075
|
instruction: `Process session ${sessionId} only`,
|
|
@@ -6899,7 +7159,7 @@ function createStopProcessor(deps) {
|
|
|
6899
7159
|
let transcriptText = null;
|
|
6900
7160
|
if (hookTranscriptPath) {
|
|
6901
7161
|
try {
|
|
6902
|
-
transcriptText =
|
|
7162
|
+
transcriptText = fs20.readFileSync(hookTranscriptPath, "utf-8");
|
|
6903
7163
|
} catch {
|
|
6904
7164
|
}
|
|
6905
7165
|
}
|
|
@@ -6925,6 +7185,33 @@ function createStopProcessor(deps) {
|
|
|
6925
7185
|
logger.warn(LOG_KINDS.PROCESSOR_BATCH, "Failed to populate batch responses", { error: String(err) });
|
|
6926
7186
|
}
|
|
6927
7187
|
}
|
|
7188
|
+
if (deps.planTags.length > 0) {
|
|
7189
|
+
for (const turn of allTurns) {
|
|
7190
|
+
if (!turn.aiResponse) continue;
|
|
7191
|
+
const taggedPlans = extractTaggedPlans(turn.aiResponse, deps.planTags);
|
|
7192
|
+
for (const { tag, content } of taggedPlans) {
|
|
7193
|
+
try {
|
|
7194
|
+
capturePlan({
|
|
7195
|
+
sourcePath: `${TRANSCRIPT_SOURCE_PREFIX}${tag}`,
|
|
7196
|
+
content,
|
|
7197
|
+
sessionId,
|
|
7198
|
+
promptBatchId: latestBatch?.id ?? null
|
|
7199
|
+
});
|
|
7200
|
+
logger.info(LOG_KINDS.CAPTURE_PLAN, "Plan captured from transcript tag", {
|
|
7201
|
+
session_id: sessionId,
|
|
7202
|
+
tag,
|
|
7203
|
+
content_length: content.length
|
|
7204
|
+
});
|
|
7205
|
+
} catch (err) {
|
|
7206
|
+
logger.warn(LOG_KINDS.CAPTURE_PLAN, "Failed to capture plan from transcript tag", {
|
|
7207
|
+
session_id: sessionId,
|
|
7208
|
+
tag,
|
|
7209
|
+
error: err.message
|
|
7210
|
+
});
|
|
7211
|
+
}
|
|
7212
|
+
}
|
|
7213
|
+
}
|
|
7214
|
+
}
|
|
6928
7215
|
if (!hasTitle) {
|
|
6929
7216
|
triggerTitleSummary(sessionId);
|
|
6930
7217
|
}
|
|
@@ -7008,69 +7295,8 @@ function createStopProcessor(deps) {
|
|
|
7008
7295
|
}
|
|
7009
7296
|
|
|
7010
7297
|
// src/daemon/event-dispatch.ts
|
|
7011
|
-
import
|
|
7298
|
+
import fs21 from "fs";
|
|
7012
7299
|
import path20 from "path";
|
|
7013
|
-
|
|
7014
|
-
// src/daemon/plan-capture.ts
|
|
7015
|
-
import { createHash as createHash4 } from "crypto";
|
|
7016
|
-
import os7 from "os";
|
|
7017
|
-
import path19 from "path";
|
|
7018
|
-
var FILE_WRITE_TOOLS = /* @__PURE__ */ new Set([
|
|
7019
|
-
"Write",
|
|
7020
|
-
"Edit",
|
|
7021
|
-
"Create",
|
|
7022
|
-
"write",
|
|
7023
|
-
"edit",
|
|
7024
|
-
"patch",
|
|
7025
|
-
"create"
|
|
7026
|
-
]);
|
|
7027
|
-
var HEADING_REGEX = /^#\s+(.+)$/m;
|
|
7028
|
-
var PLAN_ID_HASH_LENGTH = 16;
|
|
7029
|
-
function isInPlanDirectory(filePath, watchDirs, projectRoot) {
|
|
7030
|
-
const abs = path19.isAbsolute(filePath) ? filePath : path19.resolve(projectRoot, filePath);
|
|
7031
|
-
return watchDirs.some((dir) => {
|
|
7032
|
-
const expanded = dir.startsWith("~/") ? path19.join(os7.homedir(), dir.slice(2)) : dir;
|
|
7033
|
-
const absDir = path19.isAbsolute(expanded) ? expanded : path19.resolve(projectRoot, expanded);
|
|
7034
|
-
const prefix = absDir.endsWith(path19.sep) ? absDir : absDir + path19.sep;
|
|
7035
|
-
return abs === absDir || abs.startsWith(prefix);
|
|
7036
|
-
});
|
|
7037
|
-
}
|
|
7038
|
-
function isPlanWriteEvent(toolName, toolInput, config) {
|
|
7039
|
-
if (!FILE_WRITE_TOOLS.has(toolName)) return null;
|
|
7040
|
-
const filePath = toolInput?.file_path ?? toolInput?.path ?? toolInput?.filePath;
|
|
7041
|
-
if (typeof filePath !== "string") return null;
|
|
7042
|
-
if (!isInPlanDirectory(filePath, config.watchDirs, config.projectRoot)) return null;
|
|
7043
|
-
if (config.extensions?.length) {
|
|
7044
|
-
const ext = path19.extname(filePath).toLowerCase();
|
|
7045
|
-
if (!config.extensions.includes(ext)) return null;
|
|
7046
|
-
}
|
|
7047
|
-
return filePath;
|
|
7048
|
-
}
|
|
7049
|
-
function parsePlanTitle(content, filename) {
|
|
7050
|
-
const match = HEADING_REGEX.exec(content);
|
|
7051
|
-
if (match) return match[1].trim();
|
|
7052
|
-
return filename ?? null;
|
|
7053
|
-
}
|
|
7054
|
-
function capturePlan(input) {
|
|
7055
|
-
const now = Math.floor(Date.now() / 1e3);
|
|
7056
|
-
const contentHash = createHash4(CONTENT_HASH_ALGORITHM).update(input.content).digest("hex");
|
|
7057
|
-
const id = createHash4("md5").update(input.sourcePath).digest("hex").slice(0, PLAN_ID_HASH_LENGTH);
|
|
7058
|
-
const title = parsePlanTitle(input.content, path19.basename(input.sourcePath));
|
|
7059
|
-
return upsertPlan({
|
|
7060
|
-
id,
|
|
7061
|
-
title,
|
|
7062
|
-
content: input.content,
|
|
7063
|
-
source_path: input.sourcePath,
|
|
7064
|
-
session_id: input.sessionId,
|
|
7065
|
-
prompt_batch_id: input.promptBatchId ?? null,
|
|
7066
|
-
content_hash: contentHash,
|
|
7067
|
-
status: "active",
|
|
7068
|
-
created_at: now,
|
|
7069
|
-
updated_at: now
|
|
7070
|
-
});
|
|
7071
|
-
}
|
|
7072
|
-
|
|
7073
|
-
// src/daemon/event-dispatch.ts
|
|
7074
7300
|
var EventBody = external_exports.object({ type: external_exports.string(), session_id: external_exports.string() }).passthrough();
|
|
7075
7301
|
function createEventDispatcher(deps) {
|
|
7076
7302
|
const {
|
|
@@ -7163,7 +7389,7 @@ function createEventDispatcher(deps) {
|
|
|
7163
7389
|
);
|
|
7164
7390
|
if (planFilePath) {
|
|
7165
7391
|
const captureSessionId = event.session_id;
|
|
7166
|
-
|
|
7392
|
+
fs21.promises.readFile(planFilePath, "utf-8").then((planContent) => {
|
|
7167
7393
|
const latestBatch = getLatestBatch(captureSessionId);
|
|
7168
7394
|
capturePlan({
|
|
7169
7395
|
sourcePath: path20.relative(projectRoot, planFilePath),
|
|
@@ -7308,14 +7534,14 @@ function createEventDispatcher(deps) {
|
|
|
7308
7534
|
}
|
|
7309
7535
|
|
|
7310
7536
|
// src/daemon/main.ts
|
|
7311
|
-
import
|
|
7537
|
+
import fs22 from "fs";
|
|
7312
7538
|
import os8 from "os";
|
|
7313
7539
|
import path21 from "path";
|
|
7314
7540
|
function killStaleDaemon(vaultDir, logger) {
|
|
7315
7541
|
const daemonJsonPath = path21.join(vaultDir, "daemon.json");
|
|
7316
7542
|
try {
|
|
7317
|
-
if (!
|
|
7318
|
-
const info = JSON.parse(
|
|
7543
|
+
if (!fs22.existsSync(daemonJsonPath)) return;
|
|
7544
|
+
const info = JSON.parse(fs22.readFileSync(daemonJsonPath, "utf-8"));
|
|
7319
7545
|
if (!info.pid) return;
|
|
7320
7546
|
if (info.pid === process.pid) return;
|
|
7321
7547
|
try {
|
|
@@ -7324,7 +7550,7 @@ function killStaleDaemon(vaultDir, logger) {
|
|
|
7324
7550
|
logger.info(LOG_KINDS.DAEMON_START, "Killed stale daemon", { pid: info.pid });
|
|
7325
7551
|
} catch {
|
|
7326
7552
|
}
|
|
7327
|
-
|
|
7553
|
+
fs22.unlinkSync(daemonJsonPath);
|
|
7328
7554
|
} catch {
|
|
7329
7555
|
}
|
|
7330
7556
|
}
|
|
@@ -7339,6 +7565,7 @@ async function main() {
|
|
|
7339
7565
|
const config = loadConfig(vaultDir);
|
|
7340
7566
|
const manifests = loadManifests();
|
|
7341
7567
|
const symbiontPlanDirs = manifests.flatMap((m) => m.capture?.planDirs ?? []);
|
|
7568
|
+
const symbiontPlanTags = [...new Set(manifests.flatMap((m) => m.capture?.planTags ?? []))];
|
|
7342
7569
|
const projectRoot = process.cwd();
|
|
7343
7570
|
let planWatchConfig = {
|
|
7344
7571
|
watchDirs: [.../* @__PURE__ */ new Set([...symbiontPlanDirs, ...config.capture.plan_dirs ?? []])],
|
|
@@ -7357,6 +7584,9 @@ async function main() {
|
|
|
7357
7584
|
embedding_provider: config.embedding.provider
|
|
7358
7585
|
});
|
|
7359
7586
|
logger.info(LOG_KINDS.CAPTURE_PLAN, "Plan watch directories", { dirs: planWatchConfig.watchDirs });
|
|
7587
|
+
if (symbiontPlanTags.length > 0) {
|
|
7588
|
+
logger.info(LOG_KINDS.CAPTURE_PLAN, "Plan transcript tags", { tags: symbiontPlanTags });
|
|
7589
|
+
}
|
|
7360
7590
|
const machineId = getMachineId(vaultDir);
|
|
7361
7591
|
logger.info(LOG_KINDS.DAEMON_START, "Machine ID resolved", { machine_id: machineId });
|
|
7362
7592
|
let globalPrefix = null;
|
|
@@ -7371,7 +7601,7 @@ async function main() {
|
|
|
7371
7601
|
const devCliEntry = detectDevBuild(
|
|
7372
7602
|
globalPrefix,
|
|
7373
7603
|
process.argv[1],
|
|
7374
|
-
|
|
7604
|
+
fs22.realpathSync
|
|
7375
7605
|
);
|
|
7376
7606
|
if (devCliEntry) {
|
|
7377
7607
|
setDevBuildCliEntry(devCliEntry);
|
|
@@ -7387,9 +7617,9 @@ async function main() {
|
|
|
7387
7617
|
{
|
|
7388
7618
|
const reasonPath = path21.join(vaultDir, RESTART_REASON_FILENAME);
|
|
7389
7619
|
try {
|
|
7390
|
-
if (
|
|
7391
|
-
const raw = JSON.parse(
|
|
7392
|
-
|
|
7620
|
+
if (fs22.existsSync(reasonPath)) {
|
|
7621
|
+
const raw = JSON.parse(fs22.readFileSync(reasonPath, "utf-8"));
|
|
7622
|
+
fs22.unlinkSync(reasonPath);
|
|
7393
7623
|
if (raw.reason === "version_sync" && raw.to_version) {
|
|
7394
7624
|
const message = raw.local_update_ran ? "Restarted and updated local project hooks." : "Restarted to pick up the latest version.";
|
|
7395
7625
|
notify(vaultDir, {
|
|
@@ -7476,7 +7706,7 @@ async function main() {
|
|
|
7476
7706
|
const root = findPackageRoot(path21.dirname(new URL(import.meta.url).pathname));
|
|
7477
7707
|
if (root) {
|
|
7478
7708
|
const candidate = path21.join(root, "dist", "ui");
|
|
7479
|
-
if (
|
|
7709
|
+
if (fs22.existsSync(candidate)) uiDir = candidate;
|
|
7480
7710
|
}
|
|
7481
7711
|
}
|
|
7482
7712
|
if (uiDir) {
|
|
@@ -7520,7 +7750,8 @@ async function main() {
|
|
|
7520
7750
|
embeddingManager,
|
|
7521
7751
|
logger,
|
|
7522
7752
|
config,
|
|
7523
|
-
vaultDir
|
|
7753
|
+
vaultDir,
|
|
7754
|
+
planTags: symbiontPlanTags
|
|
7524
7755
|
});
|
|
7525
7756
|
const sessionLifecycle = createSessionLifecycleHandlers({
|
|
7526
7757
|
registry,
|
|
@@ -7756,4 +7987,4 @@ export {
|
|
|
7756
7987
|
handleUserPrompt,
|
|
7757
7988
|
main
|
|
7758
7989
|
};
|
|
7759
|
-
//# sourceMappingURL=main-
|
|
7990
|
+
//# sourceMappingURL=main-5THODR77.js.map
|