@adhdev/daemon-core 0.9.82-rc.311 → 0.9.82-rc.313
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/commands/router.d.ts +15 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +590 -214
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +597 -221
- package/dist/index.mjs.map +1 -1
- package/dist/logging/log-redactor.d.ts +24 -0
- package/dist/logging/log-tail-reader.d.ts +46 -0
- package/dist/repo-mesh-types.d.ts +6 -0
- package/package.json +2 -2
- package/src/commands/router.ts +184 -3
- package/src/index.ts +3 -0
- package/src/logging/log-redactor.ts +100 -0
- package/src/logging/log-tail-reader.ts +220 -0
- package/src/mesh/coordinator-prompt.ts +1 -0
- package/src/providers/provider-loader.ts +78 -0
- package/src/providers/spec/cli-adapter.ts +6 -0
- package/src/repo-mesh-types.ts +6 -0
package/dist/index.mjs
CHANGED
|
@@ -311,10 +311,10 @@ function readInjected(value) {
|
|
|
311
311
|
}
|
|
312
312
|
function getDaemonBuildInfo() {
|
|
313
313
|
if (cached) return cached;
|
|
314
|
-
const commit = readInjected(true ? "
|
|
315
|
-
const commitShort = readInjected(true ? "
|
|
316
|
-
const version = readInjected(true ? "0.9.82-rc.
|
|
317
|
-
const builtAt = readInjected(true ? "2026-06-
|
|
314
|
+
const commit = readInjected(true ? "ed3b7279be8ea9fa191f854f7e9b6ce969159e67" : void 0) ?? "unknown";
|
|
315
|
+
const commitShort = readInjected(true ? "ed3b7279" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
316
|
+
const version = readInjected(true ? "0.9.82-rc.313" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
317
|
+
const builtAt = readInjected(true ? "2026-06-18T00:14:56.582Z" : void 0);
|
|
318
318
|
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
319
319
|
return cached;
|
|
320
320
|
}
|
|
@@ -2113,6 +2113,7 @@ var init_coordinator_prompt = __esm({
|
|
|
2113
2113
|
| \`mesh_read_debug\` | Collect a daemon-side chat/parser debug bundle for a session |
|
|
2114
2114
|
| \`mesh_task_history\` | Read the task ledger \u2014 dispatches, completions, failures. Use to understand what has been done before deciding next steps |
|
|
2115
2115
|
| \`mesh_git_status\` | Check git status on a specific node |
|
|
2116
|
+
| \`mesh_read_node_logs\` | Fetch a remote node's daemon log tail directly over P2P (grep/since/byte-bounded, secrets redacted) \u2014 no session/PowerShell needed to debug a node's daemon |
|
|
2116
2117
|
| \`mesh_fast_forward_node\` | Safely dry-run or explicitly execute an obvious clean fast-forward without launching an agent session |
|
|
2117
2118
|
| \`mesh_checkpoint\` | Create a git checkpoint on a node |
|
|
2118
2119
|
| \`mesh_approve\` | Approve/reject a pending agent action |
|
|
@@ -5824,8 +5825,8 @@ function stripCoordinatorWrapperFile(filePath) {
|
|
|
5824
5825
|
const remaining = (existing.slice(0, openIdx) + existing.slice(closeIdx + CLOSE.length)).replace(/^\s*\n+/, "").replace(/\n+\s*$/, "");
|
|
5825
5826
|
if (!remaining.trim()) {
|
|
5826
5827
|
try {
|
|
5827
|
-
const
|
|
5828
|
-
|
|
5828
|
+
const fs31 = __require("fs");
|
|
5829
|
+
fs31.unlinkSync(filePath);
|
|
5829
5830
|
} catch {
|
|
5830
5831
|
}
|
|
5831
5832
|
} else {
|
|
@@ -10854,8 +10855,8 @@ var init_pty_transport = __esm({
|
|
|
10854
10855
|
let cwd = options.cwd;
|
|
10855
10856
|
if (cwd) {
|
|
10856
10857
|
try {
|
|
10857
|
-
const
|
|
10858
|
-
const stat2 =
|
|
10858
|
+
const fs31 = __require("fs");
|
|
10859
|
+
const stat2 = fs31.statSync(cwd);
|
|
10859
10860
|
if (!stat2.isDirectory()) cwd = os11.homedir();
|
|
10860
10861
|
} catch {
|
|
10861
10862
|
cwd = os11.homedir();
|
|
@@ -10964,9 +10965,9 @@ function findBinary(name) {
|
|
|
10964
10965
|
for (const ext of exes) {
|
|
10965
10966
|
const fullPath = path17.join(p, trimmed + ext);
|
|
10966
10967
|
try {
|
|
10967
|
-
const
|
|
10968
|
-
if (
|
|
10969
|
-
const stat2 =
|
|
10968
|
+
const fs31 = __require("fs");
|
|
10969
|
+
if (fs31.existsSync(fullPath)) {
|
|
10970
|
+
const stat2 = fs31.statSync(fullPath);
|
|
10970
10971
|
if (stat2.isFile() && (isWin || stat2.mode & 73)) {
|
|
10971
10972
|
return fullPath;
|
|
10972
10973
|
}
|
|
@@ -10980,12 +10981,12 @@ function findBinary(name) {
|
|
|
10980
10981
|
function isScriptBinary(binaryPath) {
|
|
10981
10982
|
if (!path17.isAbsolute(binaryPath)) return false;
|
|
10982
10983
|
try {
|
|
10983
|
-
const
|
|
10984
|
-
const resolved =
|
|
10984
|
+
const fs31 = __require("fs");
|
|
10985
|
+
const resolved = fs31.realpathSync(binaryPath);
|
|
10985
10986
|
const head = Buffer.alloc(8);
|
|
10986
|
-
const fd =
|
|
10987
|
-
|
|
10988
|
-
|
|
10987
|
+
const fd = fs31.openSync(resolved, "r");
|
|
10988
|
+
fs31.readSync(fd, head, 0, 8, 0);
|
|
10989
|
+
fs31.closeSync(fd);
|
|
10989
10990
|
let i = 0;
|
|
10990
10991
|
if (head[0] === 239 && head[1] === 187 && head[2] === 191) i = 3;
|
|
10991
10992
|
return head[i] === 35 && head[i + 1] === 33;
|
|
@@ -10996,12 +10997,12 @@ function isScriptBinary(binaryPath) {
|
|
|
10996
10997
|
function looksLikeMachOOrElf(filePath) {
|
|
10997
10998
|
if (!path17.isAbsolute(filePath)) return false;
|
|
10998
10999
|
try {
|
|
10999
|
-
const
|
|
11000
|
-
const resolved =
|
|
11000
|
+
const fs31 = __require("fs");
|
|
11001
|
+
const resolved = fs31.realpathSync(filePath);
|
|
11001
11002
|
const buf = Buffer.alloc(8);
|
|
11002
|
-
const fd =
|
|
11003
|
-
|
|
11004
|
-
|
|
11003
|
+
const fd = fs31.openSync(resolved, "r");
|
|
11004
|
+
fs31.readSync(fd, buf, 0, 8, 0);
|
|
11005
|
+
fs31.closeSync(fd);
|
|
11005
11006
|
let i = 0;
|
|
11006
11007
|
if (buf[0] === 239 && buf[1] === 187 && buf[2] === 191) i = 3;
|
|
11007
11008
|
const b = buf.subarray(i);
|
|
@@ -29489,7 +29490,7 @@ var DaemonCommandHandler = class {
|
|
|
29489
29490
|
return { success: false, error: "invalid type" };
|
|
29490
29491
|
}
|
|
29491
29492
|
const https = __require("https");
|
|
29492
|
-
const
|
|
29493
|
+
const fs31 = __require("fs");
|
|
29493
29494
|
const path41 = __require("path");
|
|
29494
29495
|
const crypto6 = __require("crypto");
|
|
29495
29496
|
const REGISTRY = "https://api.adhf.dev/api/v1/registry";
|
|
@@ -29533,7 +29534,7 @@ var DaemonCommandHandler = class {
|
|
|
29533
29534
|
if (!targetDir.startsWith(installRootResolved + path41.sep)) {
|
|
29534
29535
|
return { success: false, error: "install path escaped upstream root" };
|
|
29535
29536
|
}
|
|
29536
|
-
|
|
29537
|
+
fs31.mkdirSync(targetDir, { recursive: true });
|
|
29537
29538
|
let manifestProbe = {};
|
|
29538
29539
|
try {
|
|
29539
29540
|
manifestProbe = JSON.parse(manifestBody);
|
|
@@ -29558,7 +29559,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
29558
29559
|
}
|
|
29559
29560
|
const targetFile = isV1 ? "provider.v1.json" : "provider.json";
|
|
29560
29561
|
const targetPath = path41.join(targetDir, targetFile);
|
|
29561
|
-
|
|
29562
|
+
fs31.writeFileSync(targetPath, manifestBody, "utf-8");
|
|
29562
29563
|
const manifestJson = JSON.parse(manifestBody);
|
|
29563
29564
|
const scriptFetch = await this.fetchProviderSources(
|
|
29564
29565
|
manifestJson,
|
|
@@ -29628,7 +29629,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
29628
29629
|
const repo = source.repo;
|
|
29629
29630
|
const ref = source.ref;
|
|
29630
29631
|
const https = __require("https");
|
|
29631
|
-
const
|
|
29632
|
+
const fs31 = __require("fs");
|
|
29632
29633
|
const path41 = __require("path");
|
|
29633
29634
|
function fetchJson(url, timeoutMs) {
|
|
29634
29635
|
return new Promise((resolve24, reject) => {
|
|
@@ -29712,8 +29713,8 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
29712
29713
|
const relInside = entry.path.startsWith(sharedDirRel + "/") ? entry.path.slice(sharedDirRel.length + 1) : entry.path;
|
|
29713
29714
|
const outPath = path41.resolve(path41.join(sharedTargetDir, relInside));
|
|
29714
29715
|
if (!outPath.startsWith(path41.resolve(sharedTargetDir) + path41.sep)) continue;
|
|
29715
|
-
|
|
29716
|
-
|
|
29716
|
+
fs31.mkdirSync(path41.dirname(outPath), { recursive: true });
|
|
29717
|
+
fs31.writeFileSync(outPath, body);
|
|
29717
29718
|
fetchedCount++;
|
|
29718
29719
|
} catch (e) {
|
|
29719
29720
|
errors.push(`fetch shared ${entry.path}: ${e?.message ?? e}`);
|
|
@@ -29751,8 +29752,8 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
29751
29752
|
errors.push(`refusing to write outside targetDir: ${entry.path}`);
|
|
29752
29753
|
continue;
|
|
29753
29754
|
}
|
|
29754
|
-
|
|
29755
|
-
|
|
29755
|
+
fs31.mkdirSync(path41.dirname(outPath), { recursive: true });
|
|
29756
|
+
fs31.writeFileSync(outPath, body);
|
|
29756
29757
|
fetchedCount++;
|
|
29757
29758
|
} catch (e) {
|
|
29758
29759
|
errors.push(`fetch ${entry.path}: ${e?.message ?? e}`);
|
|
@@ -29780,7 +29781,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
29780
29781
|
if (!["cli", "ide", "extension", "acp"].includes(category)) {
|
|
29781
29782
|
return { success: false, error: `unknown category: ${category}` };
|
|
29782
29783
|
}
|
|
29783
|
-
const
|
|
29784
|
+
const fs31 = __require("fs");
|
|
29784
29785
|
const path41 = __require("path");
|
|
29785
29786
|
try {
|
|
29786
29787
|
const installRoot = this.getUpstreamInstallRoot();
|
|
@@ -29789,10 +29790,10 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
29789
29790
|
if (!targetDir.startsWith(installRootResolved + path41.sep)) {
|
|
29790
29791
|
return { success: false, error: "refusing to delete outside upstream root" };
|
|
29791
29792
|
}
|
|
29792
|
-
if (!
|
|
29793
|
+
if (!fs31.existsSync(targetDir)) {
|
|
29793
29794
|
return { success: false, error: "not installed" };
|
|
29794
29795
|
}
|
|
29795
|
-
|
|
29796
|
+
fs31.rmSync(targetDir, { recursive: true, force: true });
|
|
29796
29797
|
if (this._ctx.providerLoader) {
|
|
29797
29798
|
this._ctx.providerLoader.reload();
|
|
29798
29799
|
this._ctx.providerLoader.registerToDetector();
|
|
@@ -29808,28 +29809,28 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
29808
29809
|
* the UI and by the update checker.
|
|
29809
29810
|
*/
|
|
29810
29811
|
handleListInstalledProviders(_args) {
|
|
29811
|
-
const
|
|
29812
|
+
const fs31 = __require("fs");
|
|
29812
29813
|
const path41 = __require("path");
|
|
29813
29814
|
const installRoot = this.getUpstreamInstallRoot();
|
|
29814
|
-
if (!
|
|
29815
|
+
if (!fs31.existsSync(installRoot)) return { success: true, providers: [] };
|
|
29815
29816
|
const CATEGORIES = ["cli", "ide", "extension", "acp"];
|
|
29816
29817
|
const items = [];
|
|
29817
29818
|
for (const category of CATEGORIES) {
|
|
29818
29819
|
const categoryDir = path41.join(installRoot, category);
|
|
29819
|
-
if (!
|
|
29820
|
+
if (!fs31.existsSync(categoryDir)) continue;
|
|
29820
29821
|
let entries;
|
|
29821
29822
|
try {
|
|
29822
|
-
entries =
|
|
29823
|
+
entries = fs31.readdirSync(categoryDir);
|
|
29823
29824
|
} catch {
|
|
29824
29825
|
continue;
|
|
29825
29826
|
}
|
|
29826
29827
|
for (const type of entries) {
|
|
29827
29828
|
const v1Path = path41.join(categoryDir, type, "provider.v1.json");
|
|
29828
29829
|
const v0Path = path41.join(categoryDir, type, "provider.json");
|
|
29829
|
-
const manifestPath =
|
|
29830
|
+
const manifestPath = fs31.existsSync(v1Path) ? v1Path : fs31.existsSync(v0Path) ? v0Path : null;
|
|
29830
29831
|
if (!manifestPath) continue;
|
|
29831
29832
|
try {
|
|
29832
|
-
const m = JSON.parse(
|
|
29833
|
+
const m = JSON.parse(fs31.readFileSync(manifestPath, "utf-8"));
|
|
29833
29834
|
items.push({
|
|
29834
29835
|
type,
|
|
29835
29836
|
category,
|
|
@@ -29940,7 +29941,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
29940
29941
|
if (!/^@[a-z0-9_-]+$/i.test(requestedName)) {
|
|
29941
29942
|
return { success: false, error: "name must match @[a-z0-9_-]+" };
|
|
29942
29943
|
}
|
|
29943
|
-
const
|
|
29944
|
+
const fs31 = __require("fs");
|
|
29944
29945
|
const path41 = __require("path");
|
|
29945
29946
|
const { spawnSync: spawnSync2 } = __require("child_process");
|
|
29946
29947
|
const file = ext.loadExternalSources();
|
|
@@ -29951,8 +29952,8 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
29951
29952
|
return { success: false, error: `source url+ref already registered (use a different name to track another ref)` };
|
|
29952
29953
|
}
|
|
29953
29954
|
const sourceDir = path41.join(ext.externalRoot(), requestedName);
|
|
29954
|
-
if (!
|
|
29955
|
-
if (
|
|
29955
|
+
if (!fs31.existsSync(ext.externalRoot())) fs31.mkdirSync(ext.externalRoot(), { recursive: true });
|
|
29956
|
+
if (fs31.existsSync(sourceDir)) {
|
|
29956
29957
|
return { success: false, error: `directory already exists: ${sourceDir} (rename or remove first)` };
|
|
29957
29958
|
}
|
|
29958
29959
|
const clone = spawnSync2("git", ["clone", "--depth=1", "--branch", ref, "--", url, sourceDir], {
|
|
@@ -29962,7 +29963,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
29962
29963
|
});
|
|
29963
29964
|
if (clone.status !== 0) {
|
|
29964
29965
|
try {
|
|
29965
|
-
|
|
29966
|
+
fs31.rmSync(sourceDir, { recursive: true, force: true });
|
|
29966
29967
|
} catch {
|
|
29967
29968
|
}
|
|
29968
29969
|
return { success: false, error: `git clone failed: ${(clone.stderr || clone.stdout || "").trim() || "unknown error"}` };
|
|
@@ -30006,15 +30007,15 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
30006
30007
|
const name = typeof args?.name === "string" ? args.name.trim() : "";
|
|
30007
30008
|
if (!name) return { success: false, error: "name is required" };
|
|
30008
30009
|
const ext = (init_external_sources(), __toCommonJS(external_sources_exports));
|
|
30009
|
-
const
|
|
30010
|
+
const fs31 = __require("fs");
|
|
30010
30011
|
const path41 = __require("path");
|
|
30011
30012
|
const file = ext.loadExternalSources();
|
|
30012
30013
|
const match = file.sources.find((s) => s.name === name);
|
|
30013
30014
|
if (!match) return { success: false, error: `source "${name}" not registered` };
|
|
30014
30015
|
const sourceDir = path41.join(ext.externalRoot(), name);
|
|
30015
|
-
if (
|
|
30016
|
+
if (fs31.existsSync(sourceDir)) {
|
|
30016
30017
|
try {
|
|
30017
|
-
|
|
30018
|
+
fs31.rmSync(sourceDir, { recursive: true, force: true });
|
|
30018
30019
|
} catch (e) {
|
|
30019
30020
|
return { success: false, error: `failed to delete ${sourceDir}: ${e?.message || e}` };
|
|
30020
30021
|
}
|
|
@@ -32056,7 +32057,7 @@ var SpecCliAdapter = class _SpecCliAdapter {
|
|
|
32056
32057
|
}
|
|
32057
32058
|
if (action.type === "open_picker") {
|
|
32058
32059
|
const choiceIndex = typeof flat.choiceIndex === "number" ? flat.choiceIndex : typeof flat.choiceIndex === "string" && flat.choiceIndex.trim() ? Number(flat.choiceIndex) : void 0;
|
|
32059
|
-
const choiceLabel = typeof flat.choiceLabel === "string" ? flat.choiceLabel : typeof flat.choice === "string" ? flat.choice : void 0;
|
|
32060
|
+
const choiceLabel = typeof flat.choiceLabel === "string" ? flat.choiceLabel : typeof flat.choice === "string" ? flat.choice : typeof flat.value === "string" ? flat.value : void 0;
|
|
32060
32061
|
if (typeof choiceIndex === "number" && Number.isFinite(choiceIndex) || choiceLabel && choiceLabel.trim()) {
|
|
32061
32062
|
return this.selectPickerChoice(ctl, action, choiceIndex, choiceLabel);
|
|
32062
32063
|
}
|
|
@@ -38227,6 +38228,39 @@ function registerProviderScriptRootSafely(root) {
|
|
|
38227
38228
|
} catch {
|
|
38228
38229
|
}
|
|
38229
38230
|
}
|
|
38231
|
+
function synthesizeControlsFromControlBar(specControls) {
|
|
38232
|
+
const out = [];
|
|
38233
|
+
specControls.forEach((ctl, index) => {
|
|
38234
|
+
const id = typeof ctl?.id === "string" ? ctl.id.trim() : "";
|
|
38235
|
+
const actionType = ctl?.action?.type;
|
|
38236
|
+
if (!id || !actionType) return;
|
|
38237
|
+
const label = typeof ctl?.label === "string" && ctl.label.trim() ? ctl.label : id;
|
|
38238
|
+
if (actionType === "open_picker") {
|
|
38239
|
+
out.push({
|
|
38240
|
+
id,
|
|
38241
|
+
type: "select",
|
|
38242
|
+
label,
|
|
38243
|
+
placement: "bar",
|
|
38244
|
+
dynamic: true,
|
|
38245
|
+
listScript: id,
|
|
38246
|
+
setScript: id,
|
|
38247
|
+
readFrom: id,
|
|
38248
|
+
order: index
|
|
38249
|
+
});
|
|
38250
|
+
} else if (actionType === "send_keys") {
|
|
38251
|
+
out.push({
|
|
38252
|
+
id,
|
|
38253
|
+
type: "action",
|
|
38254
|
+
label,
|
|
38255
|
+
placement: "bar",
|
|
38256
|
+
invokeScript: id,
|
|
38257
|
+
resultDisplay: "none",
|
|
38258
|
+
order: index
|
|
38259
|
+
});
|
|
38260
|
+
}
|
|
38261
|
+
});
|
|
38262
|
+
return out;
|
|
38263
|
+
}
|
|
38230
38264
|
var ProviderLoader = class _ProviderLoader {
|
|
38231
38265
|
providers = /* @__PURE__ */ new Map();
|
|
38232
38266
|
providerAvailability = /* @__PURE__ */ new Map();
|
|
@@ -39131,7 +39165,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
39131
39165
|
}
|
|
39132
39166
|
if (providerDir) {
|
|
39133
39167
|
try {
|
|
39134
|
-
const
|
|
39168
|
+
const fs31 = __require("fs");
|
|
39135
39169
|
const path41 = __require("path");
|
|
39136
39170
|
const candidates = [];
|
|
39137
39171
|
if (Array.isArray(base.compatibility)) {
|
|
@@ -39143,13 +39177,13 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
39143
39177
|
}
|
|
39144
39178
|
candidates.push(path41.join(providerDir, "specs", "default.json"));
|
|
39145
39179
|
candidates.push(path41.join(providerDir, "spec.json"));
|
|
39146
|
-
const specPath = candidates.find((p) =>
|
|
39180
|
+
const specPath = candidates.find((p) => fs31.existsSync(p));
|
|
39147
39181
|
if (specPath) {
|
|
39148
39182
|
resolved._resolvedSpecPath = specPath;
|
|
39149
39183
|
let specControls;
|
|
39150
39184
|
let nh;
|
|
39151
39185
|
try {
|
|
39152
|
-
const rawSpec = JSON.parse(
|
|
39186
|
+
const rawSpec = JSON.parse(fs31.readFileSync(specPath, "utf8"));
|
|
39153
39187
|
specControls = rawSpec.control_bar;
|
|
39154
39188
|
nh = rawSpec.native_history;
|
|
39155
39189
|
} catch {
|
|
@@ -39165,6 +39199,13 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
39165
39199
|
});
|
|
39166
39200
|
}
|
|
39167
39201
|
}
|
|
39202
|
+
const hasDeclaredControls = Array.isArray(resolved.controls) && resolved.controls.length > 0;
|
|
39203
|
+
if (!hasDeclaredControls) {
|
|
39204
|
+
const synthesized = synthesizeControlsFromControlBar(specControls);
|
|
39205
|
+
if (synthesized.length > 0) {
|
|
39206
|
+
resolved.controls = synthesized;
|
|
39207
|
+
}
|
|
39208
|
+
}
|
|
39168
39209
|
}
|
|
39169
39210
|
if (nh) {
|
|
39170
39211
|
let reader = null;
|
|
@@ -39174,7 +39215,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
39174
39215
|
reader = (input) => executeNativeHistory(nh, input);
|
|
39175
39216
|
} else if (nh.override_path) {
|
|
39176
39217
|
const overrideFile = path41.resolve(providerDir, nh.override_path);
|
|
39177
|
-
if (
|
|
39218
|
+
if (fs31.existsSync(overrideFile)) {
|
|
39178
39219
|
try {
|
|
39179
39220
|
registerProviderScriptRootSafely(path41.dirname(path41.dirname(providerDir)));
|
|
39180
39221
|
delete __require.cache[__require.resolve(overrideFile)];
|
|
@@ -40359,7 +40400,7 @@ async function detectCurrentWorkspace(ideId) {
|
|
|
40359
40400
|
}
|
|
40360
40401
|
} else if (plat === "win32") {
|
|
40361
40402
|
try {
|
|
40362
|
-
const
|
|
40403
|
+
const fs31 = __require("fs");
|
|
40363
40404
|
const appNameMap = getMacAppIdentifiers();
|
|
40364
40405
|
const appName = appNameMap[ideId];
|
|
40365
40406
|
if (appName) {
|
|
@@ -40368,8 +40409,8 @@ async function detectCurrentWorkspace(ideId) {
|
|
|
40368
40409
|
appName,
|
|
40369
40410
|
"storage.json"
|
|
40370
40411
|
);
|
|
40371
|
-
if (
|
|
40372
|
-
const data = JSON.parse(
|
|
40412
|
+
if (fs31.existsSync(storagePath)) {
|
|
40413
|
+
const data = JSON.parse(fs31.readFileSync(storagePath, "utf-8"));
|
|
40373
40414
|
const workspaces = data?.openedPathsList?.workspaces3 || data?.openedPathsList?.entries || [];
|
|
40374
40415
|
if (workspaces.length > 0) {
|
|
40375
40416
|
const recent = workspaces[0];
|
|
@@ -40701,6 +40742,210 @@ cleanOldFiles();
|
|
|
40701
40742
|
// src/commands/router.ts
|
|
40702
40743
|
init_logger();
|
|
40703
40744
|
import * as yaml3 from "js-yaml";
|
|
40745
|
+
|
|
40746
|
+
// src/logging/log-tail-reader.ts
|
|
40747
|
+
init_logger();
|
|
40748
|
+
import * as fs23 from "fs";
|
|
40749
|
+
var DEFAULT_TAIL_BYTES = 64 * 1024;
|
|
40750
|
+
var MAX_TAIL_BYTES = 128 * 1024;
|
|
40751
|
+
var READ_CHUNK_BYTES = 64 * 1024;
|
|
40752
|
+
function resolveLogPath(date) {
|
|
40753
|
+
if (date instanceof Date) return getCurrentDaemonLogPath(date);
|
|
40754
|
+
if (typeof date === "string" && date.trim()) {
|
|
40755
|
+
const parsed = /* @__PURE__ */ new Date(`${date.trim()}T00:00:00.000Z`);
|
|
40756
|
+
if (!Number.isNaN(parsed.getTime())) return getCurrentDaemonLogPath(parsed);
|
|
40757
|
+
}
|
|
40758
|
+
return getCurrentDaemonLogPath();
|
|
40759
|
+
}
|
|
40760
|
+
function clampTailBytes(tailBytes) {
|
|
40761
|
+
if (!Number.isFinite(tailBytes) || tailBytes <= 0) return DEFAULT_TAIL_BYTES;
|
|
40762
|
+
return Math.min(Math.floor(tailBytes), MAX_TAIL_BYTES);
|
|
40763
|
+
}
|
|
40764
|
+
function readByteBoundedTail(filePath, limitBytes) {
|
|
40765
|
+
const fd = fs23.openSync(filePath, "r");
|
|
40766
|
+
try {
|
|
40767
|
+
const stat2 = fs23.fstatSync(fd);
|
|
40768
|
+
const size = stat2.size;
|
|
40769
|
+
if (size === 0) return { text: "", truncated: false, bytesReturned: 0 };
|
|
40770
|
+
const want = Math.min(limitBytes, size);
|
|
40771
|
+
let start = size - want;
|
|
40772
|
+
const truncated = start > 0;
|
|
40773
|
+
const buffers = [];
|
|
40774
|
+
let position = start;
|
|
40775
|
+
while (position < size) {
|
|
40776
|
+
const chunkSize = Math.min(READ_CHUNK_BYTES, size - position);
|
|
40777
|
+
const chunk = Buffer.alloc(chunkSize);
|
|
40778
|
+
fs23.readSync(fd, chunk, 0, chunkSize, position);
|
|
40779
|
+
buffers.push(chunk);
|
|
40780
|
+
position += chunkSize;
|
|
40781
|
+
}
|
|
40782
|
+
let buf = Buffer.concat(buffers);
|
|
40783
|
+
if (truncated) {
|
|
40784
|
+
const firstNewline = buf.indexOf(10);
|
|
40785
|
+
if (firstNewline >= 0) {
|
|
40786
|
+
buf = buf.subarray(firstNewline + 1);
|
|
40787
|
+
}
|
|
40788
|
+
}
|
|
40789
|
+
return { text: buf.toString("utf-8"), truncated, bytesReturned: buf.length };
|
|
40790
|
+
} finally {
|
|
40791
|
+
fs23.closeSync(fd);
|
|
40792
|
+
}
|
|
40793
|
+
}
|
|
40794
|
+
function parseLineEpochMs(line, fileDate) {
|
|
40795
|
+
const m = line.match(/^\[(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,3}))?\]/);
|
|
40796
|
+
if (!m) {
|
|
40797
|
+
const iso = line.match(/\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(?:\.\d+)?/);
|
|
40798
|
+
if (iso) {
|
|
40799
|
+
const t = Date.parse(iso[0].replace(" ", "T"));
|
|
40800
|
+
return Number.isNaN(t) ? null : t;
|
|
40801
|
+
}
|
|
40802
|
+
return null;
|
|
40803
|
+
}
|
|
40804
|
+
const d = new Date(fileDate);
|
|
40805
|
+
d.setHours(Number(m[1]), Number(m[2]), Number(m[3]), m[4] ? Number(m[4].padEnd(3, "0")) : 0);
|
|
40806
|
+
return d.getTime();
|
|
40807
|
+
}
|
|
40808
|
+
function readDaemonLogTail(args = {}) {
|
|
40809
|
+
const platform10 = process.platform;
|
|
40810
|
+
const limitBytes = clampTailBytes(args.tailBytes);
|
|
40811
|
+
let logPath = resolveLogPath(args.date);
|
|
40812
|
+
if (!fs23.existsSync(logPath)) {
|
|
40813
|
+
const backup = logPath.replace(/\.log$/, ".1.log");
|
|
40814
|
+
if (fs23.existsSync(backup)) {
|
|
40815
|
+
logPath = backup;
|
|
40816
|
+
} else {
|
|
40817
|
+
return {
|
|
40818
|
+
success: false,
|
|
40819
|
+
error: `No daemon log file at ${logPath} (dir: ${getDaemonLogDir()})`,
|
|
40820
|
+
lines: [],
|
|
40821
|
+
truncated: false,
|
|
40822
|
+
logPath,
|
|
40823
|
+
platform: platform10,
|
|
40824
|
+
bytesReturned: 0,
|
|
40825
|
+
filtered: false
|
|
40826
|
+
};
|
|
40827
|
+
}
|
|
40828
|
+
}
|
|
40829
|
+
let raw;
|
|
40830
|
+
try {
|
|
40831
|
+
raw = readByteBoundedTail(logPath, limitBytes);
|
|
40832
|
+
} catch (e) {
|
|
40833
|
+
return {
|
|
40834
|
+
success: false,
|
|
40835
|
+
error: `Failed to read ${logPath}: ${e?.message ?? String(e)}`,
|
|
40836
|
+
lines: [],
|
|
40837
|
+
truncated: false,
|
|
40838
|
+
logPath,
|
|
40839
|
+
platform: platform10,
|
|
40840
|
+
bytesReturned: 0,
|
|
40841
|
+
filtered: false
|
|
40842
|
+
};
|
|
40843
|
+
}
|
|
40844
|
+
let lines = raw.text.split("\n");
|
|
40845
|
+
if (lines.length && lines[lines.length - 1] === "") lines.pop();
|
|
40846
|
+
const rawCount = lines.length;
|
|
40847
|
+
if (Number.isFinite(args.sinceMs)) {
|
|
40848
|
+
const fileDate = args.date instanceof Date ? args.date : typeof args.date === "string" && args.date.trim() ? /* @__PURE__ */ new Date(`${args.date.trim()}T00:00:00.000Z`) : /* @__PURE__ */ new Date();
|
|
40849
|
+
const floor = args.sinceMs;
|
|
40850
|
+
lines = lines.filter((line) => {
|
|
40851
|
+
const ts2 = parseLineEpochMs(line, fileDate);
|
|
40852
|
+
return ts2 === null || ts2 >= floor;
|
|
40853
|
+
});
|
|
40854
|
+
}
|
|
40855
|
+
let appliedGrep;
|
|
40856
|
+
if (typeof args.grep === "string" && args.grep.trim()) {
|
|
40857
|
+
appliedGrep = args.grep.trim();
|
|
40858
|
+
let re = null;
|
|
40859
|
+
try {
|
|
40860
|
+
re = new RegExp(appliedGrep, "i");
|
|
40861
|
+
} catch {
|
|
40862
|
+
re = null;
|
|
40863
|
+
}
|
|
40864
|
+
if (re) {
|
|
40865
|
+
const compiled = re;
|
|
40866
|
+
lines = lines.filter((line) => compiled.test(line));
|
|
40867
|
+
} else {
|
|
40868
|
+
const needle = appliedGrep.toLowerCase();
|
|
40869
|
+
lines = lines.filter((line) => line.toLowerCase().includes(needle));
|
|
40870
|
+
}
|
|
40871
|
+
}
|
|
40872
|
+
return {
|
|
40873
|
+
success: true,
|
|
40874
|
+
lines,
|
|
40875
|
+
truncated: raw.truncated,
|
|
40876
|
+
logPath,
|
|
40877
|
+
platform: platform10,
|
|
40878
|
+
bytesReturned: raw.bytesReturned,
|
|
40879
|
+
filtered: lines.length !== rawCount,
|
|
40880
|
+
...appliedGrep ? { grep: appliedGrep } : {}
|
|
40881
|
+
};
|
|
40882
|
+
}
|
|
40883
|
+
|
|
40884
|
+
// src/logging/log-redactor.ts
|
|
40885
|
+
var MASK = "\u2022\u2022\u2022\u2022redacted";
|
|
40886
|
+
function maskKeepTail(token) {
|
|
40887
|
+
if (token.length <= 8) return MASK;
|
|
40888
|
+
return `${MASK}${token.slice(-4)}`;
|
|
40889
|
+
}
|
|
40890
|
+
var RULES = [
|
|
40891
|
+
// `JWT_SECRET=...`, `TOKEN=...`, `API_KEY=...`, `password: ...` env/config dumps.
|
|
40892
|
+
// Captures the key + delimiter and masks only the value.
|
|
40893
|
+
{
|
|
40894
|
+
name: "key_value_secret",
|
|
40895
|
+
pattern: /\b([A-Z0-9_]*(?:SECRET|TOKEN|API[_-]?KEY|PASSWORD|PASSWD|PRIVATE[_-]?KEY|CREDENTIAL|CLIENT[_-]?SECRET)[A-Z0-9_]*)(\s*[:=]\s*)(["']?)([^\s"',;]+)\3/gi,
|
|
40896
|
+
replace: (_m, key, delim, quote) => `${key}${delim}${quote}${MASK}${quote}`
|
|
40897
|
+
},
|
|
40898
|
+
// Authorization: Bearer <token>
|
|
40899
|
+
{
|
|
40900
|
+
name: "bearer_token",
|
|
40901
|
+
pattern: /\b(Bearer\s+)([A-Za-z0-9._\-+/=]{8,})/g,
|
|
40902
|
+
replace: (_m, prefix, token) => `${prefix}${maskKeepTail(token)}`
|
|
40903
|
+
},
|
|
40904
|
+
// ADHDev credential prefixes: API key (adk_), machine secret (adm_), provider key (adp_).
|
|
40905
|
+
{
|
|
40906
|
+
name: "adhdev_prefixed_secret",
|
|
40907
|
+
pattern: /\b(ad[kmp]_)([A-Za-z0-9]{6,})/g,
|
|
40908
|
+
replace: (_m, prefix, token) => `${prefix}${maskKeepTail(prefix + token)}`
|
|
40909
|
+
},
|
|
40910
|
+
// JWT: three base64url segments separated by dots, header starts with eyJ.
|
|
40911
|
+
{
|
|
40912
|
+
name: "jwt",
|
|
40913
|
+
pattern: /\beyJ[A-Za-z0-9_-]{4,}\.[A-Za-z0-9_-]{4,}\.[A-Za-z0-9_-]{4,}/g,
|
|
40914
|
+
replace: () => MASK
|
|
40915
|
+
},
|
|
40916
|
+
// TURN credential: a long credential value following a `credential` key in
|
|
40917
|
+
// any common shape — `credential: x`, `credential=x`, or `credential "x"`.
|
|
40918
|
+
// Mask the credential value only, preserving the key + delimiter/quote.
|
|
40919
|
+
{
|
|
40920
|
+
name: "turn_credential",
|
|
40921
|
+
pattern: /\b(credential["']?\s*(?:[:=]\s*)?["']?)([^\s"',;]{6,})/gi,
|
|
40922
|
+
replace: (_m, prefix) => `${prefix}${MASK}`
|
|
40923
|
+
},
|
|
40924
|
+
// TURN REST username:credential of the form `<expiry-ts>:<base64hmac>`,
|
|
40925
|
+
// where the hmac part is long base64. Mask the hmac.
|
|
40926
|
+
{
|
|
40927
|
+
name: "turn_rest_pair",
|
|
40928
|
+
pattern: /\b(\d{10,}:)([A-Za-z0-9+/]{20,}={0,2})\b/g,
|
|
40929
|
+
replace: (_m, prefix) => `${prefix}${MASK}`
|
|
40930
|
+
}
|
|
40931
|
+
];
|
|
40932
|
+
function redactLogLine(line) {
|
|
40933
|
+
if (!line) return line;
|
|
40934
|
+
let out = line;
|
|
40935
|
+
for (const rule of RULES) {
|
|
40936
|
+
try {
|
|
40937
|
+
out = out.replace(rule.pattern, rule.replace);
|
|
40938
|
+
} catch {
|
|
40939
|
+
}
|
|
40940
|
+
}
|
|
40941
|
+
return out;
|
|
40942
|
+
}
|
|
40943
|
+
function redactLogLines(lines) {
|
|
40944
|
+
return lines.map((line) => redactLogLine(line));
|
|
40945
|
+
}
|
|
40946
|
+
var LOG_REDACTION_RULE_NAMES = RULES.map((r) => r.name);
|
|
40947
|
+
|
|
40948
|
+
// src/commands/router.ts
|
|
40704
40949
|
init_mesh_coordinator();
|
|
40705
40950
|
init_mesh_events();
|
|
40706
40951
|
init_mesh_routing();
|
|
@@ -40797,7 +41042,7 @@ function orderMeshRefineBatchNodes(changeAreas) {
|
|
|
40797
41042
|
|
|
40798
41043
|
// src/mesh/preview-freshness.ts
|
|
40799
41044
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
40800
|
-
import { existsSync as
|
|
41045
|
+
import { existsSync as existsSync34, readFileSync as readFileSync25 } from "fs";
|
|
40801
41046
|
import { resolve as resolve19 } from "path";
|
|
40802
41047
|
var PREVIEW_DEPLOY_RECORD = ".adhdev/preview-deploy.json";
|
|
40803
41048
|
function runGit2(repoRoot, args) {
|
|
@@ -40814,7 +41059,7 @@ function runGit2(repoRoot, args) {
|
|
|
40814
41059
|
}
|
|
40815
41060
|
function readRecord6(repoRoot) {
|
|
40816
41061
|
const path41 = resolve19(repoRoot, PREVIEW_DEPLOY_RECORD);
|
|
40817
|
-
if (!
|
|
41062
|
+
if (!existsSync34(path41)) return null;
|
|
40818
41063
|
try {
|
|
40819
41064
|
const parsed = JSON.parse(readFileSync25(path41, "utf8"));
|
|
40820
41065
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
@@ -40881,7 +41126,7 @@ function buildPreviewFreshness(repoRoot) {
|
|
|
40881
41126
|
init_mesh_refine_status();
|
|
40882
41127
|
|
|
40883
41128
|
// src/mesh/mesh-init.ts
|
|
40884
|
-
import { existsSync as
|
|
41129
|
+
import { existsSync as existsSync35, mkdirSync as mkdirSync15, writeFileSync as writeFileSync17 } from "fs";
|
|
40885
41130
|
import { dirname as dirname7, join as join37 } from "path";
|
|
40886
41131
|
var MESH_INIT_REFINE_CONFIG_PATH = MESH_REFINE_CONFIG_LOCATIONS[0];
|
|
40887
41132
|
var MESH_INIT_WORKTREE_BOOTSTRAP_CONFIG_PATH = MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS[0];
|
|
@@ -40904,14 +41149,14 @@ function writeConfigFile(workspace, relativePath, config) {
|
|
|
40904
41149
|
}
|
|
40905
41150
|
function suggestMeshWorktreeBootstrapConfig(workspace) {
|
|
40906
41151
|
const commands = [];
|
|
40907
|
-
const hasPackageJson =
|
|
40908
|
-
const hasNpmLock =
|
|
41152
|
+
const hasPackageJson = existsSync35(join37(workspace, "package.json"));
|
|
41153
|
+
const hasNpmLock = existsSync35(join37(workspace, "package-lock.json"));
|
|
40909
41154
|
if (hasPackageJson) {
|
|
40910
41155
|
commands.push(
|
|
40911
41156
|
hasNpmLock ? { command: "npm", args: ["ci"] } : { command: "npm", args: ["install"] }
|
|
40912
41157
|
);
|
|
40913
41158
|
}
|
|
40914
|
-
const staleInputs = CANDIDATE_STALE_INPUTS.filter((relative5) =>
|
|
41159
|
+
const staleInputs = CANDIDATE_STALE_INPUTS.filter((relative5) => existsSync35(join37(workspace, relative5)));
|
|
40915
41160
|
if (!commands.length) {
|
|
40916
41161
|
return { commands, staleInputs };
|
|
40917
41162
|
}
|
|
@@ -41345,21 +41590,21 @@ init_build_info();
|
|
|
41345
41590
|
// src/commands/upgrade-helper.ts
|
|
41346
41591
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
41347
41592
|
import { spawn as spawn3 } from "child_process";
|
|
41348
|
-
import * as
|
|
41593
|
+
import * as fs24 from "fs";
|
|
41349
41594
|
import * as os27 from "os";
|
|
41350
41595
|
import * as path35 from "path";
|
|
41351
41596
|
var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
|
|
41352
41597
|
function getUpgradeLogPath() {
|
|
41353
41598
|
const home = os27.homedir();
|
|
41354
41599
|
const dir = path35.join(home, ".adhdev");
|
|
41355
|
-
|
|
41600
|
+
fs24.mkdirSync(dir, { recursive: true });
|
|
41356
41601
|
return path35.join(dir, "daemon-upgrade.log");
|
|
41357
41602
|
}
|
|
41358
41603
|
function appendUpgradeLog(message) {
|
|
41359
41604
|
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
|
|
41360
41605
|
`;
|
|
41361
41606
|
try {
|
|
41362
|
-
|
|
41607
|
+
fs24.appendFileSync(getUpgradeLogPath(), line, "utf8");
|
|
41363
41608
|
} catch {
|
|
41364
41609
|
}
|
|
41365
41610
|
}
|
|
@@ -41367,12 +41612,12 @@ function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platfo
|
|
|
41367
41612
|
const binDir = path35.dirname(nodeExecutable);
|
|
41368
41613
|
if (platform10 === "win32") {
|
|
41369
41614
|
const npmCliPath = path35.join(binDir, "node_modules", "npm", "bin", "npm-cli.js");
|
|
41370
|
-
if (
|
|
41615
|
+
if (fs24.existsSync(npmCliPath)) {
|
|
41371
41616
|
return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
|
|
41372
41617
|
}
|
|
41373
41618
|
for (const candidate of ["npm.exe", "npm"]) {
|
|
41374
41619
|
const candidatePath = path35.join(binDir, candidate);
|
|
41375
|
-
if (
|
|
41620
|
+
if (fs24.existsSync(candidatePath)) {
|
|
41376
41621
|
return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
|
|
41377
41622
|
}
|
|
41378
41623
|
}
|
|
@@ -41380,7 +41625,7 @@ function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platfo
|
|
|
41380
41625
|
}
|
|
41381
41626
|
for (const candidate of ["npm"]) {
|
|
41382
41627
|
const candidatePath = path35.join(binDir, candidate);
|
|
41383
|
-
if (
|
|
41628
|
+
if (fs24.existsSync(candidatePath)) {
|
|
41384
41629
|
return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
|
|
41385
41630
|
}
|
|
41386
41631
|
}
|
|
@@ -41390,12 +41635,12 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
41390
41635
|
if (!currentCliPath) return null;
|
|
41391
41636
|
let resolvedPath = currentCliPath;
|
|
41392
41637
|
try {
|
|
41393
|
-
resolvedPath =
|
|
41638
|
+
resolvedPath = fs24.realpathSync.native(currentCliPath);
|
|
41394
41639
|
} catch {
|
|
41395
41640
|
}
|
|
41396
41641
|
let currentDir = resolvedPath;
|
|
41397
41642
|
try {
|
|
41398
|
-
if (
|
|
41643
|
+
if (fs24.statSync(resolvedPath).isFile()) {
|
|
41399
41644
|
currentDir = path35.dirname(resolvedPath);
|
|
41400
41645
|
}
|
|
41401
41646
|
} catch {
|
|
@@ -41404,8 +41649,8 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
41404
41649
|
while (true) {
|
|
41405
41650
|
const packageJsonPath = path35.join(currentDir, "package.json");
|
|
41406
41651
|
try {
|
|
41407
|
-
if (
|
|
41408
|
-
const parsed = JSON.parse(
|
|
41652
|
+
if (fs24.existsSync(packageJsonPath)) {
|
|
41653
|
+
const parsed = JSON.parse(fs24.readFileSync(packageJsonPath, "utf8"));
|
|
41409
41654
|
if (parsed?.name === packageName) {
|
|
41410
41655
|
const normalized = currentDir.replace(/\\/g, "/");
|
|
41411
41656
|
return normalized.includes("/node_modules/") ? currentDir : null;
|
|
@@ -41554,8 +41799,8 @@ async function waitForPidExit(pid, timeoutMs) {
|
|
|
41554
41799
|
function stopSessionHostProcesses(appName) {
|
|
41555
41800
|
const pidFile = path35.join(os27.homedir(), ".adhdev", `${appName}-session-host.pid`);
|
|
41556
41801
|
try {
|
|
41557
|
-
if (
|
|
41558
|
-
const pid = Number.parseInt(
|
|
41802
|
+
if (fs24.existsSync(pidFile)) {
|
|
41803
|
+
const pid = Number.parseInt(fs24.readFileSync(pidFile, "utf8").trim(), 10);
|
|
41559
41804
|
if (Number.isFinite(pid) && pid !== process.pid && isManagedSessionHostPid(pid)) {
|
|
41560
41805
|
killPid(pid);
|
|
41561
41806
|
}
|
|
@@ -41563,7 +41808,7 @@ function stopSessionHostProcesses(appName) {
|
|
|
41563
41808
|
} catch {
|
|
41564
41809
|
} finally {
|
|
41565
41810
|
try {
|
|
41566
|
-
|
|
41811
|
+
fs24.unlinkSync(pidFile);
|
|
41567
41812
|
} catch {
|
|
41568
41813
|
}
|
|
41569
41814
|
}
|
|
@@ -41571,7 +41816,7 @@ function stopSessionHostProcesses(appName) {
|
|
|
41571
41816
|
function removeDaemonPidFile() {
|
|
41572
41817
|
const pidFile = path35.join(os27.homedir(), ".adhdev", "daemon.pid");
|
|
41573
41818
|
try {
|
|
41574
|
-
|
|
41819
|
+
fs24.unlinkSync(pidFile);
|
|
41575
41820
|
} catch {
|
|
41576
41821
|
}
|
|
41577
41822
|
}
|
|
@@ -41589,23 +41834,23 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
|
|
|
41589
41834
|
if (pkgName.startsWith("@")) {
|
|
41590
41835
|
const [scope, name] = pkgName.split("/");
|
|
41591
41836
|
const scopeDir = path35.join(npmRoot, scope);
|
|
41592
|
-
if (!
|
|
41593
|
-
for (const entry of
|
|
41837
|
+
if (!fs24.existsSync(scopeDir)) return;
|
|
41838
|
+
for (const entry of fs24.readdirSync(scopeDir)) {
|
|
41594
41839
|
if (!entry.startsWith(`.${name}-`)) continue;
|
|
41595
|
-
|
|
41840
|
+
fs24.rmSync(path35.join(scopeDir, entry), { recursive: true, force: true });
|
|
41596
41841
|
appendUpgradeLog(`Removed stale scoped staging dir: ${path35.join(scopeDir, entry)}`);
|
|
41597
41842
|
}
|
|
41598
41843
|
} else {
|
|
41599
|
-
for (const entry of
|
|
41844
|
+
for (const entry of fs24.readdirSync(npmRoot)) {
|
|
41600
41845
|
if (!entry.startsWith(`.${pkgName}-`)) continue;
|
|
41601
|
-
|
|
41846
|
+
fs24.rmSync(path35.join(npmRoot, entry), { recursive: true, force: true });
|
|
41602
41847
|
appendUpgradeLog(`Removed stale staging dir: ${path35.join(npmRoot, entry)}`);
|
|
41603
41848
|
}
|
|
41604
41849
|
}
|
|
41605
|
-
if (
|
|
41606
|
-
for (const entry of
|
|
41850
|
+
if (fs24.existsSync(binDir)) {
|
|
41851
|
+
for (const entry of fs24.readdirSync(binDir)) {
|
|
41607
41852
|
if (!Array.from(binNames).some((name) => entry.startsWith(`.${name}-`))) continue;
|
|
41608
|
-
|
|
41853
|
+
fs24.rmSync(path35.join(binDir, entry), { recursive: true, force: true });
|
|
41609
41854
|
appendUpgradeLog(`Removed stale bin staging entry: ${path35.join(binDir, entry)}`);
|
|
41610
41855
|
}
|
|
41611
41856
|
}
|
|
@@ -41696,7 +41941,7 @@ init_mesh_work_queue();
|
|
|
41696
41941
|
init_repo_mesh_types();
|
|
41697
41942
|
import { homedir as homedir26, hostname as osHostname } from "os";
|
|
41698
41943
|
import { basename as pathBasename, join as pathJoin, resolve as pathResolve2 } from "path";
|
|
41699
|
-
import * as
|
|
41944
|
+
import * as fs25 from "fs";
|
|
41700
41945
|
import { execFileSync as execFileSync6 } from "child_process";
|
|
41701
41946
|
var CHANNEL_NPM_TAG = { stable: "latest", preview: "next" };
|
|
41702
41947
|
var CHANNEL_SERVER_URL = {
|
|
@@ -42022,6 +42267,12 @@ function inlineMeshCarriesTransientNodeTruth(inlineMesh) {
|
|
|
42022
42267
|
function readInlineMeshNodeId(node) {
|
|
42023
42268
|
return normalizeMeshNodeId(node) ?? "";
|
|
42024
42269
|
}
|
|
42270
|
+
function isDeadLocalWorktreeNode(node) {
|
|
42271
|
+
if (node?.isLocalWorktree !== true) return false;
|
|
42272
|
+
const workspace = readStringValue(node?.workspace);
|
|
42273
|
+
if (!workspace) return false;
|
|
42274
|
+
return !fs25.existsSync(workspace);
|
|
42275
|
+
}
|
|
42025
42276
|
function foldMeshNodeIdentityToCanonical(node) {
|
|
42026
42277
|
if (!node || typeof node !== "object" || Array.isArray(node)) return node;
|
|
42027
42278
|
const canonical = normalizeMeshNodeId(node);
|
|
@@ -42268,7 +42519,7 @@ function summarizeInlineMeshBranchConvergence(nodes) {
|
|
|
42268
42519
|
const followUps = nodes.filter((node) => {
|
|
42269
42520
|
if (readObjectRecord(node.branchConvergence).needsConvergence !== true) return false;
|
|
42270
42521
|
const workspace = typeof node.workspace === "string" ? node.workspace : "";
|
|
42271
|
-
if (workspace && !
|
|
42522
|
+
if (workspace && !fs25.existsSync(workspace)) return false;
|
|
42272
42523
|
return true;
|
|
42273
42524
|
}).map((node) => {
|
|
42274
42525
|
const convergence = readObjectRecord(node.branchConvergence);
|
|
@@ -42476,7 +42727,8 @@ async function hydrateInlineMeshDirectTruth(args) {
|
|
|
42476
42727
|
peerAttemptedCount: 0,
|
|
42477
42728
|
peerConfirmedCount: 0,
|
|
42478
42729
|
standingEvidenceCount: 0,
|
|
42479
|
-
unavailableNodeIds: []
|
|
42730
|
+
unavailableNodeIds: [],
|
|
42731
|
+
deadNodeIds: []
|
|
42480
42732
|
};
|
|
42481
42733
|
}
|
|
42482
42734
|
const selectedCoordinatorNodeId = readStringValue(
|
|
@@ -42489,6 +42741,7 @@ async function hydrateInlineMeshDirectTruth(args) {
|
|
|
42489
42741
|
let peerConfirmedCount = 0;
|
|
42490
42742
|
let standingEvidenceCount = 0;
|
|
42491
42743
|
const unavailableNodeIds = [];
|
|
42744
|
+
const deadNodeIds = [];
|
|
42492
42745
|
for (const [nodeIndex, node] of nodes.entries()) {
|
|
42493
42746
|
const nodeId = normalizeMeshNodeId(node) || `node_${nodeIndex}`;
|
|
42494
42747
|
const workspace = readStringValue(node?.workspace);
|
|
@@ -42498,11 +42751,18 @@ async function hydrateInlineMeshDirectTruth(args) {
|
|
|
42498
42751
|
) || Boolean(
|
|
42499
42752
|
daemonId && (daemonId === args.localMachineId || daemonId === args.statusInstanceId)
|
|
42500
42753
|
) || Boolean(args.meshSource !== "local_config" && nodeIndex === 0);
|
|
42754
|
+
const isSelfDaemonNode = Boolean(
|
|
42755
|
+
daemonId && (daemonId === args.localMachineId || daemonId === args.statusInstanceId)
|
|
42756
|
+
);
|
|
42757
|
+
if ((isSelfNode || isSelfDaemonNode) && isDeadLocalWorktreeNode(node)) {
|
|
42758
|
+
deadNodeIds.push(nodeId);
|
|
42759
|
+
continue;
|
|
42760
|
+
}
|
|
42501
42761
|
if (!workspace) {
|
|
42502
42762
|
if (!isSelfNode && daemonId) unavailableNodeIds.push(nodeId);
|
|
42503
42763
|
continue;
|
|
42504
42764
|
}
|
|
42505
|
-
if (
|
|
42765
|
+
if (fs25.existsSync(workspace)) {
|
|
42506
42766
|
try {
|
|
42507
42767
|
const localGit = await getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
|
|
42508
42768
|
if (localGit?.isGitRepo) {
|
|
@@ -42548,7 +42808,8 @@ async function hydrateInlineMeshDirectTruth(args) {
|
|
|
42548
42808
|
peerAttemptedCount,
|
|
42549
42809
|
peerConfirmedCount,
|
|
42550
42810
|
standingEvidenceCount,
|
|
42551
|
-
unavailableNodeIds
|
|
42811
|
+
unavailableNodeIds,
|
|
42812
|
+
deadNodeIds
|
|
42552
42813
|
};
|
|
42553
42814
|
}
|
|
42554
42815
|
function summarizeMeshSessionRecord(record) {
|
|
@@ -42607,7 +42868,7 @@ function readLiveMeshNodeWorkspace(args) {
|
|
|
42607
42868
|
}
|
|
42608
42869
|
function collectLiveMeshSessionRecords(args) {
|
|
42609
42870
|
const nodeWorkspace = readStringValue(args.node?.workspace);
|
|
42610
|
-
const nodeIsMissingLocalWorktree = args.node?.isLocalWorktree === true && !!nodeWorkspace && !
|
|
42871
|
+
const nodeIsMissingLocalWorktree = args.node?.isLocalWorktree === true && !!nodeWorkspace && !fs25.existsSync(nodeWorkspace);
|
|
42611
42872
|
const matches = args.liveSessionRecords.filter((record) => {
|
|
42612
42873
|
const recordNodeId = readStringValue(record?.meta?.meshNodeId);
|
|
42613
42874
|
if (recordNodeId && recordNodeId !== args.nodeId) return false;
|
|
@@ -42634,7 +42895,7 @@ function buildHistoricalMeshSessions(args) {
|
|
|
42634
42895
|
const workspace = readStringValue(node?.workspace);
|
|
42635
42896
|
if (nodeId) liveNodeIds.add(nodeId);
|
|
42636
42897
|
if (workspace) liveWorkspaces.add(workspace);
|
|
42637
|
-
if (nodeId && node?.isLocalWorktree === true && workspace && !
|
|
42898
|
+
if (nodeId && node?.isLocalWorktree === true && workspace && !fs25.existsSync(workspace)) {
|
|
42638
42899
|
missingLocalWorktreeNodeIds.add(nodeId);
|
|
42639
42900
|
}
|
|
42640
42901
|
}
|
|
@@ -42994,7 +43255,7 @@ function isSubmoduleFastForward(submoduleRepoPath, baseCommit, branchCommit) {
|
|
|
42994
43255
|
if (!baseCommit || !branchCommit) return false;
|
|
42995
43256
|
if (baseCommit === branchCommit) return true;
|
|
42996
43257
|
try {
|
|
42997
|
-
if (!
|
|
43258
|
+
if (!fs25.existsSync(submoduleRepoPath)) return false;
|
|
42998
43259
|
execFileSync6("git", ["cat-file", "-e", `${baseCommit}^{commit}`], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
42999
43260
|
execFileSync6("git", ["cat-file", "-e", `${branchCommit}^{commit}`], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
43000
43261
|
execFileSync6("git", ["merge-base", "--is-ancestor", baseCommit, branchCommit], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
@@ -43111,7 +43372,7 @@ function buildTreeWithGitlinksEqualized(repoRoot, commitish, paths, placeholderC
|
|
|
43111
43372
|
return newTree || void 0;
|
|
43112
43373
|
} finally {
|
|
43113
43374
|
try {
|
|
43114
|
-
|
|
43375
|
+
fs25.rmSync(tmpIndex, { force: true });
|
|
43115
43376
|
} catch {
|
|
43116
43377
|
}
|
|
43117
43378
|
}
|
|
@@ -43186,7 +43447,7 @@ function synthesizeTrivialFastForwardMergeTree(repoRoot, baseHead, branchHead, g
|
|
|
43186
43447
|
return newTree || void 0;
|
|
43187
43448
|
} finally {
|
|
43188
43449
|
try {
|
|
43189
|
-
|
|
43450
|
+
fs25.rmSync(tmpIndex, { force: true });
|
|
43190
43451
|
} catch {
|
|
43191
43452
|
}
|
|
43192
43453
|
}
|
|
@@ -43292,7 +43553,7 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
43292
43553
|
return { stdout: String(stdout || ""), stderr: String(stderr || ""), refspec };
|
|
43293
43554
|
};
|
|
43294
43555
|
const importCommitFromWorktreeSubmodule = async (submodulePath, worktreeSubmodulePath, commit) => {
|
|
43295
|
-
if (!
|
|
43556
|
+
if (!fs25.existsSync(worktreeSubmodulePath)) return false;
|
|
43296
43557
|
try {
|
|
43297
43558
|
await runGit3(worktreeSubmodulePath, ["cat-file", "-e", `${commit}^{commit}`]);
|
|
43298
43559
|
} catch {
|
|
@@ -43315,7 +43576,7 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
43315
43576
|
reachable: false
|
|
43316
43577
|
};
|
|
43317
43578
|
try {
|
|
43318
|
-
if (!
|
|
43579
|
+
if (!fs25.existsSync(submodulePath)) {
|
|
43319
43580
|
entry.error = `Submodule checkout missing at ${gitlink.path}`;
|
|
43320
43581
|
entry.publishRequired = true;
|
|
43321
43582
|
if (options.allowAutoPublishSubmoduleMainCommits === true) {
|
|
@@ -43552,9 +43813,9 @@ async function runMeshRefineValidationGate(mesh, workspace, opts) {
|
|
|
43552
43813
|
return ["npm", "pnpm", "yarn", "bun"].includes(command) && candidate.args.some((arg) => arg === "run" || arg === "test" || arg === "exec");
|
|
43553
43814
|
};
|
|
43554
43815
|
const dependenciesLikelyMissing = (cwd) => {
|
|
43555
|
-
if (!
|
|
43556
|
-
if (
|
|
43557
|
-
return ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"].some((lock) =>
|
|
43816
|
+
if (!fs25.existsSync(pathJoin(cwd, "package.json"))) return false;
|
|
43817
|
+
if (fs25.existsSync(pathJoin(cwd, "node_modules"))) return false;
|
|
43818
|
+
return ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"].some((lock) => fs25.existsSync(pathJoin(cwd, lock)));
|
|
43558
43819
|
};
|
|
43559
43820
|
if (runLegacyBootstrapCommands) {
|
|
43560
43821
|
summary.bootstrap = { stage: "legacy" };
|
|
@@ -43656,9 +43917,9 @@ function resolveHermesUserHome() {
|
|
|
43656
43917
|
function loadHermesCoordinatorBaseConfig(targetConfigPath) {
|
|
43657
43918
|
const sourceHome = resolveHermesUserHome();
|
|
43658
43919
|
const sourceConfigPath = pathJoin(sourceHome, "config.yaml");
|
|
43659
|
-
if (!
|
|
43920
|
+
if (!fs25.existsSync(sourceConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
43660
43921
|
if (pathResolve2(sourceConfigPath) === pathResolve2(targetConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
43661
|
-
const parsed = parseMeshCoordinatorMcpConfig(
|
|
43922
|
+
const parsed = parseMeshCoordinatorMcpConfig(fs25.readFileSync(sourceConfigPath, "utf-8"), "hermes_config_yaml");
|
|
43662
43923
|
const { mcp_servers: _mcpServers, ...baseConfig } = parsed;
|
|
43663
43924
|
return { config: baseConfig, sourceHome, sourceConfigPath };
|
|
43664
43925
|
}
|
|
@@ -43695,9 +43956,9 @@ function copyHermesCoordinatorCredentialFiles(sourceHome, targetHome) {
|
|
|
43695
43956
|
for (const fileName of [".env", "auth.json"]) {
|
|
43696
43957
|
const sourcePath = pathJoin(sourceHome, fileName);
|
|
43697
43958
|
const targetPath = pathJoin(targetHome, fileName);
|
|
43698
|
-
if (!
|
|
43959
|
+
if (!fs25.existsSync(sourcePath)) continue;
|
|
43699
43960
|
try {
|
|
43700
|
-
|
|
43961
|
+
fs25.copyFileSync(sourcePath, targetPath);
|
|
43701
43962
|
} catch (error) {
|
|
43702
43963
|
LOG.warn("MeshCoordinator", `Could not copy Hermes ${fileName} into isolated coordinator home: ${error?.message || error}`);
|
|
43703
43964
|
}
|
|
@@ -43855,6 +44116,15 @@ var DaemonCommandRouter = class {
|
|
|
43855
44116
|
* Allows the MCP server to query mesh data via get_mesh even when
|
|
43856
44117
|
* the mesh doesn't exist in the local meshes.json file. */
|
|
43857
44118
|
inlineMeshCache = /* @__PURE__ */ new Map();
|
|
44119
|
+
/** Tombstones for inline mesh nodes removed via remove_mesh_node, keyed by
|
|
44120
|
+
* meshId → set of removed nodeIds. The dashboard keeps echoing the removed
|
|
44121
|
+
* node in the inlineMesh it attaches to every command; without a tombstone,
|
|
44122
|
+
* reconcileInlineMeshCache MERGEs it straight back (resurrection). A
|
|
44123
|
+
* tombstoned node is skipped during reconcile only while its workspace is
|
|
44124
|
+
* absent from disk — a genuine re-registration (same nodeId, workspace back
|
|
44125
|
+
* on disk) clears the tombstone and merges normally, preserving clone
|
|
44126
|
+
* worktree visibility and legitimate node re-creation. */
|
|
44127
|
+
removedInlineMeshNodeIds = /* @__PURE__ */ new Map();
|
|
43858
44128
|
/** Coordinator-owned whole-mesh aggregate status snapshots. Browser callers read this by default. */
|
|
43859
44129
|
aggregateMeshStatusCache = /* @__PURE__ */ new Map();
|
|
43860
44130
|
/** Shared per-peer git_status probe dedup + recently-probed reuse gate.
|
|
@@ -43888,10 +44158,23 @@ var DaemonCommandRouter = class {
|
|
|
43888
44158
|
const unavailableNodeIds = /* @__PURE__ */ new Set();
|
|
43889
44159
|
const sourceOfTruth = readObjectRecord(snapshot.sourceOfTruth);
|
|
43890
44160
|
const directPeerTruth = readObjectRecord(sourceOfTruth.directPeerTruth);
|
|
44161
|
+
const deadNodeIds = /* @__PURE__ */ new Set();
|
|
44162
|
+
for (const node of mesh.nodes) {
|
|
44163
|
+
if (!isDeadLocalWorktreeNode(node)) continue;
|
|
44164
|
+
const deadId = readInlineMeshNodeId(node);
|
|
44165
|
+
if (deadId) deadNodeIds.add(deadId);
|
|
44166
|
+
}
|
|
44167
|
+
let droppedDeadUnavailable = false;
|
|
43891
44168
|
for (const entry of Array.isArray(directPeerTruth.unavailableNodeIds) ? directPeerTruth.unavailableNodeIds : []) {
|
|
43892
44169
|
const nodeId = readStringValue(entry);
|
|
43893
|
-
if (nodeId)
|
|
44170
|
+
if (!nodeId) continue;
|
|
44171
|
+
if (deadNodeIds.has(nodeId)) {
|
|
44172
|
+
droppedDeadUnavailable = true;
|
|
44173
|
+
continue;
|
|
44174
|
+
}
|
|
44175
|
+
unavailableNodeIds.add(nodeId);
|
|
43894
44176
|
}
|
|
44177
|
+
if (droppedDeadUnavailable) changed = true;
|
|
43895
44178
|
const nodes = snapshot.nodes.map((statusNode) => {
|
|
43896
44179
|
const nodeId = normalizeMeshNodeId(statusNode);
|
|
43897
44180
|
const inlineNode = nodeId ? inlineNodesById.get(nodeId) : void 0;
|
|
@@ -44006,7 +44289,10 @@ var DaemonCommandRouter = class {
|
|
|
44006
44289
|
}
|
|
44007
44290
|
warmInlineMeshCache(meshId, inlineMesh) {
|
|
44008
44291
|
if (!inlineMesh || typeof inlineMesh !== "object") return void 0;
|
|
44009
|
-
const sanitizedInlineMesh =
|
|
44292
|
+
const sanitizedInlineMesh = this.applyInlineMeshNodeTombstones(
|
|
44293
|
+
meshId,
|
|
44294
|
+
sanitizeInlineMesh(normalizeInlineMeshNodeIdentity(inlineMesh))
|
|
44295
|
+
);
|
|
44010
44296
|
const cached2 = this.inlineMeshCache.get(meshId);
|
|
44011
44297
|
if (cached2) {
|
|
44012
44298
|
const merged = reconcileInlineMeshCache(cached2, sanitizedInlineMesh);
|
|
@@ -44022,7 +44308,10 @@ var DaemonCommandRouter = class {
|
|
|
44022
44308
|
const cached3 = this.getCachedInlineMesh(meshId);
|
|
44023
44309
|
if (cached3) {
|
|
44024
44310
|
if (inlineMeshCarriesTransientNodeTruth(inlineMesh)) {
|
|
44025
|
-
const merged = reconcileInlineMeshCache(
|
|
44311
|
+
const merged = reconcileInlineMeshCache(
|
|
44312
|
+
cached3,
|
|
44313
|
+
this.applyInlineMeshNodeTombstones(meshId, inlineMesh)
|
|
44314
|
+
);
|
|
44026
44315
|
this.inlineMeshCache.set(meshId, sanitizeInlineMesh(normalizeInlineMeshNodeIdentity(merged)));
|
|
44027
44316
|
return { mesh: merged, inline: true, source: "inline_cache" };
|
|
44028
44317
|
}
|
|
@@ -44073,12 +44362,49 @@ var DaemonCommandRouter = class {
|
|
|
44073
44362
|
if (!mesh || !Array.isArray(mesh.nodes)) return false;
|
|
44074
44363
|
const idx = mesh.nodes.findIndex((entry) => meshNodeIdMatches(entry, nodeId));
|
|
44075
44364
|
if (idx === -1) return false;
|
|
44365
|
+
const canonicalNodeId = readInlineMeshNodeId(mesh.nodes[idx]) || nodeId;
|
|
44076
44366
|
mesh.nodes.splice(idx, 1);
|
|
44077
44367
|
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
44078
44368
|
this.inlineMeshCache.set(meshId, mesh);
|
|
44369
|
+
this.tombstoneRemovedInlineMeshNode(meshId, canonicalNodeId);
|
|
44370
|
+
if (canonicalNodeId !== nodeId) this.tombstoneRemovedInlineMeshNode(meshId, nodeId);
|
|
44079
44371
|
this.invalidateAggregateMeshStatus(meshId);
|
|
44080
44372
|
return true;
|
|
44081
44373
|
}
|
|
44374
|
+
tombstoneRemovedInlineMeshNode(meshId, nodeId) {
|
|
44375
|
+
if (!nodeId) return;
|
|
44376
|
+
let set = this.removedInlineMeshNodeIds.get(meshId);
|
|
44377
|
+
if (!set) {
|
|
44378
|
+
set = /* @__PURE__ */ new Set();
|
|
44379
|
+
this.removedInlineMeshNodeIds.set(meshId, set);
|
|
44380
|
+
}
|
|
44381
|
+
set.add(nodeId);
|
|
44382
|
+
}
|
|
44383
|
+
/** Filter an incoming inline mesh against this mesh's tombstones before it is
|
|
44384
|
+
* reconciled into the cache. A tombstoned node is dropped only while its
|
|
44385
|
+
* workspace is still absent from disk; if the workspace is back (genuine
|
|
44386
|
+
* re-registration), the tombstone is cleared and the node merges normally. */
|
|
44387
|
+
applyInlineMeshNodeTombstones(meshId, incoming) {
|
|
44388
|
+
const tombstones = this.removedInlineMeshNodeIds.get(meshId);
|
|
44389
|
+
if (!tombstones?.size || !incoming || typeof incoming !== "object" || !Array.isArray(incoming.nodes)) {
|
|
44390
|
+
return incoming;
|
|
44391
|
+
}
|
|
44392
|
+
let dropped = false;
|
|
44393
|
+
const nodes = incoming.nodes.filter((node) => {
|
|
44394
|
+
const nodeId = readInlineMeshNodeId(node);
|
|
44395
|
+
if (!nodeId || !tombstones.has(nodeId)) return true;
|
|
44396
|
+
const workspace = readStringValue(node?.workspace);
|
|
44397
|
+
if (workspace && fs25.existsSync(workspace)) {
|
|
44398
|
+
tombstones.delete(nodeId);
|
|
44399
|
+
return true;
|
|
44400
|
+
}
|
|
44401
|
+
dropped = true;
|
|
44402
|
+
return false;
|
|
44403
|
+
});
|
|
44404
|
+
if (tombstones.size === 0) this.removedInlineMeshNodeIds.delete(meshId);
|
|
44405
|
+
if (!dropped) return incoming;
|
|
44406
|
+
return { ...incoming, nodes };
|
|
44407
|
+
}
|
|
44082
44408
|
normalizeMeshSessionCleanupMode(value) {
|
|
44083
44409
|
return value === "stop" || value === "delete_stopped" || value === "stop_and_delete" || value === "preserve" ? value : "preserve";
|
|
44084
44410
|
}
|
|
@@ -44101,13 +44427,13 @@ var DaemonCommandRouter = class {
|
|
|
44101
44427
|
recoveryHint: "Inspect the mesh node record before removing it, or remove stale metadata manually only after confirming no managed worktree remains."
|
|
44102
44428
|
};
|
|
44103
44429
|
}
|
|
44104
|
-
const worktreeExists =
|
|
44430
|
+
const worktreeExists = fs25.existsSync(workspace);
|
|
44105
44431
|
const sourceNode = args.node?.clonedFromNodeId ? args.mesh?.nodes?.find((n) => meshNodeIdMatches(n, args.node.clonedFromNodeId)) : args.mesh?.nodes?.find((n) => !n.isLocalWorktree);
|
|
44106
44432
|
const repoRoot = typeof sourceNode?.repoRoot === "string" && sourceNode.repoRoot.trim() ? sourceNode.repoRoot.trim() : typeof sourceNode?.workspace === "string" && sourceNode.workspace.trim() ? sourceNode.workspace.trim() : "";
|
|
44107
44433
|
if (!worktreeExists) {
|
|
44108
44434
|
return { success: true, skipped: true, removedPath: workspace, repoRoot: repoRoot || void 0, reason: "worktree_path_missing" };
|
|
44109
44435
|
}
|
|
44110
|
-
if (!repoRoot || !
|
|
44436
|
+
if (!repoRoot || !fs25.existsSync(repoRoot)) {
|
|
44111
44437
|
return {
|
|
44112
44438
|
success: false,
|
|
44113
44439
|
code: "mesh_worktree_cleanup_missing_source_repo",
|
|
@@ -44127,7 +44453,7 @@ var DaemonCommandRouter = class {
|
|
|
44127
44453
|
const normalizePath = (value) => {
|
|
44128
44454
|
const resolved = pathResolve2(value);
|
|
44129
44455
|
try {
|
|
44130
|
-
return
|
|
44456
|
+
return fs25.realpathSync(resolved);
|
|
44131
44457
|
} catch {
|
|
44132
44458
|
return resolved;
|
|
44133
44459
|
}
|
|
@@ -44213,7 +44539,7 @@ var DaemonCommandRouter = class {
|
|
|
44213
44539
|
};
|
|
44214
44540
|
} catch (deinitError) {
|
|
44215
44541
|
try {
|
|
44216
|
-
|
|
44542
|
+
fs25.rmSync(workspace, { recursive: true, force: true });
|
|
44217
44543
|
await execFileAsync4("git", ["worktree", "prune"], {
|
|
44218
44544
|
cwd: repoRoot,
|
|
44219
44545
|
encoding: "utf8",
|
|
@@ -45992,8 +46318,8 @@ ${hintLines.join("\n")}` : "",
|
|
|
45992
46318
|
if (sinceTs > 0) {
|
|
45993
46319
|
return { success: true, logs: [], totalBuffered: 0 };
|
|
45994
46320
|
}
|
|
45995
|
-
if (
|
|
45996
|
-
const content =
|
|
46321
|
+
if (fs25.existsSync(LOG_PATH)) {
|
|
46322
|
+
const content = fs25.readFileSync(LOG_PATH, "utf-8");
|
|
45997
46323
|
const allLines = content.split("\n");
|
|
45998
46324
|
const recent = allLines.slice(-count).join("\n");
|
|
45999
46325
|
return { success: true, logs: recent, totalLines: allLines.length };
|
|
@@ -46538,14 +46864,14 @@ ${hintLines.join("\n")}` : "",
|
|
|
46538
46864
|
// Settings page in the dashboard reads/writes via these two
|
|
46539
46865
|
// commands instead of going through fs from the browser.
|
|
46540
46866
|
case "list_coordinator_prompts": {
|
|
46541
|
-
const
|
|
46867
|
+
const fs31 = await import("fs");
|
|
46542
46868
|
const path41 = await import("path");
|
|
46543
46869
|
const os30 = await import("os");
|
|
46544
46870
|
const dir = path41.join(os30.homedir(), ".adhdev", "coordinator-prompts");
|
|
46545
46871
|
const entries = {};
|
|
46546
46872
|
try {
|
|
46547
|
-
if (
|
|
46548
|
-
for (const name of
|
|
46873
|
+
if (fs31.existsSync(dir)) {
|
|
46874
|
+
for (const name of fs31.readdirSync(dir)) {
|
|
46549
46875
|
const matchOverride = name.match(/^([a-zA-Z0-9_.-]+)\.md$/);
|
|
46550
46876
|
const matchAppend = name.match(/^([a-zA-Z0-9_.-]+)\.append\.md$/);
|
|
46551
46877
|
const m = matchAppend || matchOverride;
|
|
@@ -46555,7 +46881,7 @@ ${hintLines.join("\n")}` : "",
|
|
|
46555
46881
|
const full = path41.join(dir, name);
|
|
46556
46882
|
let content = "";
|
|
46557
46883
|
try {
|
|
46558
|
-
content =
|
|
46884
|
+
content = fs31.readFileSync(full, "utf8");
|
|
46559
46885
|
} catch {
|
|
46560
46886
|
}
|
|
46561
46887
|
if (!entries[key]) entries[key] = { override: "", append: "" };
|
|
@@ -46569,7 +46895,7 @@ ${hintLines.join("\n")}` : "",
|
|
|
46569
46895
|
return { success: true, dir, entries };
|
|
46570
46896
|
}
|
|
46571
46897
|
case "write_coordinator_prompt": {
|
|
46572
|
-
const
|
|
46898
|
+
const fs31 = await import("fs");
|
|
46573
46899
|
const path41 = await import("path");
|
|
46574
46900
|
const os30 = await import("os");
|
|
46575
46901
|
const key = typeof args?.key === "string" ? args.key.trim() : "";
|
|
@@ -46582,11 +46908,11 @@ ${hintLines.join("\n")}` : "",
|
|
|
46582
46908
|
const filename = kind === "append" ? `${key}.append.md` : `${key}.md`;
|
|
46583
46909
|
const full = path41.join(dir, filename);
|
|
46584
46910
|
try {
|
|
46585
|
-
|
|
46911
|
+
fs31.mkdirSync(dir, { recursive: true });
|
|
46586
46912
|
if (content.trim()) {
|
|
46587
|
-
|
|
46588
|
-
} else if (
|
|
46589
|
-
|
|
46913
|
+
fs31.writeFileSync(full, content, { encoding: "utf8", mode: 384 });
|
|
46914
|
+
} else if (fs31.existsSync(full)) {
|
|
46915
|
+
fs31.unlinkSync(full);
|
|
46590
46916
|
}
|
|
46591
46917
|
return { success: true, path: full, kind, key };
|
|
46592
46918
|
} catch (error) {
|
|
@@ -47364,6 +47690,55 @@ ${hintLines.join("\n")}` : "",
|
|
|
47364
47690
|
});
|
|
47365
47691
|
return result;
|
|
47366
47692
|
}
|
|
47693
|
+
case "get_mesh_node_logs": {
|
|
47694
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
47695
|
+
const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
|
|
47696
|
+
let nodeDaemonId;
|
|
47697
|
+
if (meshId && nodeId) {
|
|
47698
|
+
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
|
|
47699
|
+
const node = meshRecord?.mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
|
|
47700
|
+
nodeDaemonId = typeof node?.daemonId === "string" ? node.daemonId.trim() : void 0;
|
|
47701
|
+
}
|
|
47702
|
+
const selfDaemonId = this.deps.statusInstanceId;
|
|
47703
|
+
const isRemote = nodeDaemonId && selfDaemonId && nodeDaemonId !== selfDaemonId;
|
|
47704
|
+
if (isRemote && this.deps.dispatchMeshCommand && !args?._meshDirectDispatch) {
|
|
47705
|
+
const forwarded = await this.deps.dispatchMeshCommand(nodeDaemonId, "get_mesh_node_logs", {
|
|
47706
|
+
...typeof args === "object" && args !== null ? args : {},
|
|
47707
|
+
_meshDirectDispatch: true
|
|
47708
|
+
});
|
|
47709
|
+
return forwarded ?? { success: false, error: "no response from remote node" };
|
|
47710
|
+
}
|
|
47711
|
+
const rawTailBytes = Number(args?.tailBytes);
|
|
47712
|
+
const tail = readDaemonLogTail({
|
|
47713
|
+
date: typeof args?.date === "string" ? args.date : void 0,
|
|
47714
|
+
tailBytes: Number.isFinite(rawTailBytes) ? Math.min(rawTailBytes, MAX_TAIL_BYTES) : void 0,
|
|
47715
|
+
grep: typeof args?.grep === "string" ? args.grep : void 0,
|
|
47716
|
+
sinceMs: Number.isFinite(Number(args?.sinceMs)) ? Number(args?.sinceMs) : void 0
|
|
47717
|
+
});
|
|
47718
|
+
if (!tail.success) {
|
|
47719
|
+
return {
|
|
47720
|
+
success: false,
|
|
47721
|
+
error: tail.error || "failed to read daemon log tail",
|
|
47722
|
+
nodeId,
|
|
47723
|
+
logPath: tail.logPath,
|
|
47724
|
+
platform: tail.platform
|
|
47725
|
+
};
|
|
47726
|
+
}
|
|
47727
|
+
const redactedLines = redactLogLines(tail.lines);
|
|
47728
|
+
return {
|
|
47729
|
+
success: true,
|
|
47730
|
+
nodeId,
|
|
47731
|
+
daemonId: selfDaemonId,
|
|
47732
|
+
logPath: tail.logPath,
|
|
47733
|
+
platform: tail.platform,
|
|
47734
|
+
lines: redactedLines,
|
|
47735
|
+
lineCount: redactedLines.length,
|
|
47736
|
+
truncated: tail.truncated,
|
|
47737
|
+
filtered: tail.filtered,
|
|
47738
|
+
bytesReturned: tail.bytesReturned,
|
|
47739
|
+
...tail.grep ? { grep: tail.grep } : {}
|
|
47740
|
+
};
|
|
47741
|
+
}
|
|
47367
47742
|
case "refine_mesh_node": {
|
|
47368
47743
|
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
47369
47744
|
const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
|
|
@@ -48031,15 +48406,15 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
48031
48406
|
}
|
|
48032
48407
|
if (cliType === "codex-cli") {
|
|
48033
48408
|
const repoMcpConfigPath = pathJoin(workspace, ".mcp.json");
|
|
48034
|
-
if (
|
|
48409
|
+
if (fs25.existsSync(repoMcpConfigPath)) {
|
|
48035
48410
|
try {
|
|
48036
48411
|
const repoMcpConfig = parseMeshCoordinatorMcpConfig(
|
|
48037
|
-
|
|
48412
|
+
fs25.readFileSync(repoMcpConfigPath, "utf-8"),
|
|
48038
48413
|
"claude_mcp_json"
|
|
48039
48414
|
);
|
|
48040
48415
|
const existingServers2 = repoMcpConfig.mcpServers;
|
|
48041
48416
|
if (existingServers2 && typeof existingServers2 === "object" && !Array.isArray(existingServers2) && existingServers2[coordinatorSetup.serverName]) {
|
|
48042
|
-
|
|
48417
|
+
fs25.writeFileSync(repoMcpConfigPath, serializeMeshCoordinatorMcpConfig({
|
|
48043
48418
|
...repoMcpConfig,
|
|
48044
48419
|
mcpServers: {
|
|
48045
48420
|
...existingServers2,
|
|
@@ -48155,7 +48530,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
48155
48530
|
workspace
|
|
48156
48531
|
};
|
|
48157
48532
|
}
|
|
48158
|
-
const { existsSync:
|
|
48533
|
+
const { existsSync: existsSync44, readFileSync: readFileSync35, writeFileSync: writeFileSync23, copyFileSync: copyFileSync4, mkdirSync: mkdirSync21 } = await import("fs");
|
|
48159
48534
|
const { dirname: dirname14 } = await import("path");
|
|
48160
48535
|
const mcpConfigPath = coordinatorSetup.configPath;
|
|
48161
48536
|
const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
|
|
@@ -48198,7 +48573,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
48198
48573
|
if (hermesManualFallback) return returnManualFallback(message);
|
|
48199
48574
|
return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
|
|
48200
48575
|
}
|
|
48201
|
-
const hadExistingMcpConfig =
|
|
48576
|
+
const hadExistingMcpConfig = existsSync44(mcpConfigPath);
|
|
48202
48577
|
let existingMcpConfig = hermesBaseConfig?.config || {};
|
|
48203
48578
|
if (hermesBaseConfig) {
|
|
48204
48579
|
copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname14(mcpConfigPath));
|
|
@@ -48375,7 +48750,8 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
48375
48750
|
peerAttemptedCount: 0,
|
|
48376
48751
|
peerConfirmedCount: 0,
|
|
48377
48752
|
standingEvidenceCount: 0,
|
|
48378
|
-
unavailableNodeIds: []
|
|
48753
|
+
unavailableNodeIds: [],
|
|
48754
|
+
deadNodeIds: []
|
|
48379
48755
|
};
|
|
48380
48756
|
const passivePeerTruthNotAttempted = requireDirectPeerTruth && !refreshRequested && directTruth.directEvidenceCount > 0 && directTruth.peerAttemptedCount === 0;
|
|
48381
48757
|
const effectiveDirectTruth = passivePeerTruthNotAttempted ? { ...directTruth, unavailableNodeIds: [] } : directTruth;
|
|
@@ -48515,7 +48891,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
48515
48891
|
}
|
|
48516
48892
|
}
|
|
48517
48893
|
if (workspace) {
|
|
48518
|
-
if (!
|
|
48894
|
+
if (!fs25.existsSync(workspace)) {
|
|
48519
48895
|
const inlineTransitGit = buildInlineMeshTransitGitStatus(node);
|
|
48520
48896
|
let remoteProbeApplied = false;
|
|
48521
48897
|
if (inlineTransitGit) {
|
|
@@ -48606,7 +48982,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
48606
48982
|
const pendingCoordinatorEvents = getPendingMeshCoordinatorEvents(meshId, callerCoordinatorDaemonId);
|
|
48607
48983
|
const unroutableDeliveries = getRecentUnroutableDeliveries();
|
|
48608
48984
|
const previewFreshness = (() => {
|
|
48609
|
-
const localRepoRoot = nodeStatuses.map((node) => readStringValue(node?.git?.repoRoot, node?.repoRoot, node?.workspace)).find((candidate) => !!candidate &&
|
|
48985
|
+
const localRepoRoot = nodeStatuses.map((node) => readStringValue(node?.git?.repoRoot, node?.repoRoot, node?.workspace)).find((candidate) => !!candidate && fs25.existsSync(candidate));
|
|
48610
48986
|
return localRepoRoot ? buildPreviewFreshness(localRepoRoot) : void 0;
|
|
48611
48987
|
})();
|
|
48612
48988
|
const asyncRefineJobs = buildMeshAsyncRefineJobs({
|
|
@@ -48701,7 +49077,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
48701
49077
|
const { deriveMeshReviewInboxItems: deriveMeshReviewInboxItems2 } = await Promise.resolve().then(() => (init_mesh_review_inbox(), mesh_review_inbox_exports));
|
|
48702
49078
|
const { readLedgerEntries: readLedgerEntries2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
48703
49079
|
const { getGitDiffSummary: getGitDiffSummary2 } = await Promise.resolve().then(() => (init_git_diff(), git_diff_exports));
|
|
48704
|
-
const { existsSync:
|
|
49080
|
+
const { existsSync: existsSync44 } = await import("fs");
|
|
48705
49081
|
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
|
|
48706
49082
|
const mesh = meshRecord?.mesh;
|
|
48707
49083
|
if (!mesh) return { success: false, error: "Mesh not found" };
|
|
@@ -48720,7 +49096,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
48720
49096
|
const derivation = deriveMeshReviewInboxItems2({ nodes: nodeStatuses, ledgerEntries });
|
|
48721
49097
|
for (const item of derivation.items) {
|
|
48722
49098
|
const workspace = item.workspace;
|
|
48723
|
-
if (!workspace || !
|
|
49099
|
+
if (!workspace || !existsSync44(workspace)) continue;
|
|
48724
49100
|
const baseRef = item.defaultBranch ? `origin/${item.defaultBranch}` : "origin/main";
|
|
48725
49101
|
try {
|
|
48726
49102
|
const diffResult = await getGitDiffSummary2(workspace, { baseRef, maxFiles: 100 });
|
|
@@ -50466,7 +50842,7 @@ var ProviderInstanceManager = class {
|
|
|
50466
50842
|
};
|
|
50467
50843
|
|
|
50468
50844
|
// src/providers/version-archive.ts
|
|
50469
|
-
import * as
|
|
50845
|
+
import * as fs26 from "fs";
|
|
50470
50846
|
import * as path36 from "path";
|
|
50471
50847
|
import * as os28 from "os";
|
|
50472
50848
|
import { platform as platform8 } from "os";
|
|
@@ -50480,8 +50856,8 @@ var VersionArchive = class {
|
|
|
50480
50856
|
}
|
|
50481
50857
|
load() {
|
|
50482
50858
|
try {
|
|
50483
|
-
if (
|
|
50484
|
-
this.history = JSON.parse(
|
|
50859
|
+
if (fs26.existsSync(ARCHIVE_PATH)) {
|
|
50860
|
+
this.history = JSON.parse(fs26.readFileSync(ARCHIVE_PATH, "utf-8"));
|
|
50485
50861
|
}
|
|
50486
50862
|
} catch {
|
|
50487
50863
|
this.history = {};
|
|
@@ -50518,8 +50894,8 @@ var VersionArchive = class {
|
|
|
50518
50894
|
}
|
|
50519
50895
|
save() {
|
|
50520
50896
|
try {
|
|
50521
|
-
|
|
50522
|
-
|
|
50897
|
+
fs26.mkdirSync(path36.dirname(ARCHIVE_PATH), { recursive: true });
|
|
50898
|
+
fs26.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
|
|
50523
50899
|
} catch {
|
|
50524
50900
|
}
|
|
50525
50901
|
}
|
|
@@ -50544,8 +50920,8 @@ function findBinary2(name) {
|
|
|
50544
50920
|
for (const ext of exes) {
|
|
50545
50921
|
const fullPath = path36.join(p, name + ext);
|
|
50546
50922
|
try {
|
|
50547
|
-
if (
|
|
50548
|
-
const stat2 =
|
|
50923
|
+
if (fs26.existsSync(fullPath)) {
|
|
50924
|
+
const stat2 = fs26.statSync(fullPath);
|
|
50549
50925
|
if (stat2.isFile() && (isWin || stat2.mode & 73)) {
|
|
50550
50926
|
return fullPath;
|
|
50551
50927
|
}
|
|
@@ -50592,9 +50968,9 @@ function checkPathExists2(paths) {
|
|
|
50592
50968
|
if (p.includes("*")) {
|
|
50593
50969
|
const home = os28.homedir();
|
|
50594
50970
|
const resolved = p.replace(/\*/g, home.split(path36.sep).pop() || "");
|
|
50595
|
-
if (
|
|
50971
|
+
if (fs26.existsSync(resolved)) return resolved;
|
|
50596
50972
|
} else {
|
|
50597
|
-
if (
|
|
50973
|
+
if (fs26.existsSync(p)) return p;
|
|
50598
50974
|
}
|
|
50599
50975
|
}
|
|
50600
50976
|
return null;
|
|
@@ -50602,7 +50978,7 @@ function checkPathExists2(paths) {
|
|
|
50602
50978
|
async function getMacAppVersion(appPath) {
|
|
50603
50979
|
if (platform8() !== "darwin" || !appPath.endsWith(".app")) return null;
|
|
50604
50980
|
const plistPath = path36.join(appPath, "Contents", "Info.plist");
|
|
50605
|
-
if (!
|
|
50981
|
+
if (!fs26.existsSync(plistPath)) return null;
|
|
50606
50982
|
const raw = await runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
|
|
50607
50983
|
return raw || null;
|
|
50608
50984
|
}
|
|
@@ -50628,7 +51004,7 @@ async function detectAllVersions(loader, archive) {
|
|
|
50628
51004
|
let resolvedBin = cliBin;
|
|
50629
51005
|
if (!resolvedBin && appPath && currentOs === "darwin") {
|
|
50630
51006
|
const bundled = path36.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
|
|
50631
|
-
if (provider.cli &&
|
|
51007
|
+
if (provider.cli && fs26.existsSync(bundled)) resolvedBin = bundled;
|
|
50632
51008
|
}
|
|
50633
51009
|
info.installed = !!(appPath || resolvedBin);
|
|
50634
51010
|
info.path = appPath || null;
|
|
@@ -50667,7 +51043,7 @@ async function detectAllVersions(loader, archive) {
|
|
|
50667
51043
|
|
|
50668
51044
|
// src/daemon/dev-server.ts
|
|
50669
51045
|
import * as http2 from "http";
|
|
50670
|
-
import * as
|
|
51046
|
+
import * as fs30 from "fs";
|
|
50671
51047
|
import * as path40 from "path";
|
|
50672
51048
|
init_config();
|
|
50673
51049
|
|
|
@@ -51019,7 +51395,7 @@ init_logger();
|
|
|
51019
51395
|
|
|
51020
51396
|
// src/daemon/dev-cdp-handlers.ts
|
|
51021
51397
|
init_logger();
|
|
51022
|
-
import * as
|
|
51398
|
+
import * as fs27 from "fs";
|
|
51023
51399
|
import * as path37 from "path";
|
|
51024
51400
|
async function handleCdpEvaluate(ctx, req, res) {
|
|
51025
51401
|
const body = await ctx.readBody(req);
|
|
@@ -51199,17 +51575,17 @@ async function handleScriptHints(ctx, type, _req, res) {
|
|
|
51199
51575
|
}
|
|
51200
51576
|
let scriptsPath = "";
|
|
51201
51577
|
const directScripts = path37.join(dir, "scripts.js");
|
|
51202
|
-
if (
|
|
51578
|
+
if (fs27.existsSync(directScripts)) {
|
|
51203
51579
|
scriptsPath = directScripts;
|
|
51204
51580
|
} else {
|
|
51205
51581
|
const scriptsDir = path37.join(dir, "scripts");
|
|
51206
|
-
if (
|
|
51207
|
-
const versions =
|
|
51208
|
-
return
|
|
51582
|
+
if (fs27.existsSync(scriptsDir)) {
|
|
51583
|
+
const versions = fs27.readdirSync(scriptsDir).filter((d) => {
|
|
51584
|
+
return fs27.statSync(path37.join(scriptsDir, d)).isDirectory();
|
|
51209
51585
|
}).sort().reverse();
|
|
51210
51586
|
for (const ver of versions) {
|
|
51211
51587
|
const p = path37.join(scriptsDir, ver, "scripts.js");
|
|
51212
|
-
if (
|
|
51588
|
+
if (fs27.existsSync(p)) {
|
|
51213
51589
|
scriptsPath = p;
|
|
51214
51590
|
break;
|
|
51215
51591
|
}
|
|
@@ -51221,7 +51597,7 @@ async function handleScriptHints(ctx, type, _req, res) {
|
|
|
51221
51597
|
return;
|
|
51222
51598
|
}
|
|
51223
51599
|
try {
|
|
51224
|
-
const source =
|
|
51600
|
+
const source = fs27.readFileSync(scriptsPath, "utf-8");
|
|
51225
51601
|
const hints = {};
|
|
51226
51602
|
const funcRegex = /module\.exports\.(\w+)\s*=\s*function\s+\w+\s*\(params\)/g;
|
|
51227
51603
|
let match;
|
|
@@ -52036,7 +52412,7 @@ async function handleDomContext(ctx, type, req, res) {
|
|
|
52036
52412
|
}
|
|
52037
52413
|
|
|
52038
52414
|
// src/daemon/dev-cli-debug.ts
|
|
52039
|
-
import * as
|
|
52415
|
+
import * as fs28 from "fs";
|
|
52040
52416
|
import * as path38 from "path";
|
|
52041
52417
|
function slugifyFixtureName(value) {
|
|
52042
52418
|
const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
@@ -52052,10 +52428,10 @@ function getCliFixtureDir(ctx, type) {
|
|
|
52052
52428
|
function readCliFixture(ctx, type, name) {
|
|
52053
52429
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
52054
52430
|
const filePath = path38.join(fixtureDir, `${name}.json`);
|
|
52055
|
-
if (!
|
|
52431
|
+
if (!fs28.existsSync(filePath)) {
|
|
52056
52432
|
throw new Error(`Fixture not found: ${filePath}`);
|
|
52057
52433
|
}
|
|
52058
|
-
return JSON.parse(
|
|
52434
|
+
return JSON.parse(fs28.readFileSync(filePath, "utf-8"));
|
|
52059
52435
|
}
|
|
52060
52436
|
function getExerciseTranscriptText(result) {
|
|
52061
52437
|
const parts = [];
|
|
@@ -52800,7 +53176,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
52800
53176
|
return;
|
|
52801
53177
|
}
|
|
52802
53178
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
52803
|
-
|
|
53179
|
+
fs28.mkdirSync(fixtureDir, { recursive: true });
|
|
52804
53180
|
const name = slugifyFixtureName(String(body?.name || `${type}-${Date.now()}`));
|
|
52805
53181
|
const result = await runCliExerciseInternal(ctx, { ...request, type });
|
|
52806
53182
|
const fixture = {
|
|
@@ -52828,7 +53204,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
52828
53204
|
notes: typeof body?.notes === "string" ? body.notes : void 0
|
|
52829
53205
|
};
|
|
52830
53206
|
const filePath = path38.join(fixtureDir, `${name}.json`);
|
|
52831
|
-
|
|
53207
|
+
fs28.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
|
|
52832
53208
|
ctx.json(res, 200, {
|
|
52833
53209
|
saved: true,
|
|
52834
53210
|
name,
|
|
@@ -52846,14 +53222,14 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
52846
53222
|
async function handleCliFixtureList(ctx, type, _req, res) {
|
|
52847
53223
|
try {
|
|
52848
53224
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
52849
|
-
if (!
|
|
53225
|
+
if (!fs28.existsSync(fixtureDir)) {
|
|
52850
53226
|
ctx.json(res, 200, { fixtures: [], count: 0 });
|
|
52851
53227
|
return;
|
|
52852
53228
|
}
|
|
52853
|
-
const fixtures =
|
|
53229
|
+
const fixtures = fs28.readdirSync(fixtureDir).filter((file) => file.endsWith(".json")).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file) => {
|
|
52854
53230
|
const fullPath = path38.join(fixtureDir, file);
|
|
52855
53231
|
try {
|
|
52856
|
-
const raw = JSON.parse(
|
|
53232
|
+
const raw = JSON.parse(fs28.readFileSync(fullPath, "utf-8"));
|
|
52857
53233
|
return {
|
|
52858
53234
|
name: raw.name || file.replace(/\.json$/i, ""),
|
|
52859
53235
|
path: fullPath,
|
|
@@ -52986,7 +53362,7 @@ async function handleCliRaw(ctx, req, res) {
|
|
|
52986
53362
|
}
|
|
52987
53363
|
|
|
52988
53364
|
// src/daemon/dev-auto-implement.ts
|
|
52989
|
-
import * as
|
|
53365
|
+
import * as fs29 from "fs";
|
|
52990
53366
|
import * as path39 from "path";
|
|
52991
53367
|
import * as os29 from "os";
|
|
52992
53368
|
import { DEFAULT_SESSION_HOST_COLS as DEFAULT_SESSION_HOST_COLS7, DEFAULT_SESSION_HOST_ROWS as DEFAULT_SESSION_HOST_ROWS7 } from "@adhdev/session-host-core";
|
|
@@ -53035,10 +53411,10 @@ function resolveAutoImplReference(ctx, category, requestedReference, targetType)
|
|
|
53035
53411
|
return fallback?.type || null;
|
|
53036
53412
|
}
|
|
53037
53413
|
function getLatestScriptVersionDir(scriptsDir) {
|
|
53038
|
-
if (!
|
|
53039
|
-
const versions =
|
|
53414
|
+
if (!fs29.existsSync(scriptsDir)) return null;
|
|
53415
|
+
const versions = fs29.readdirSync(scriptsDir).filter((d) => {
|
|
53040
53416
|
try {
|
|
53041
|
-
return
|
|
53417
|
+
return fs29.statSync(path39.join(scriptsDir, d)).isDirectory();
|
|
53042
53418
|
} catch {
|
|
53043
53419
|
return false;
|
|
53044
53420
|
}
|
|
@@ -53060,13 +53436,13 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
|
53060
53436
|
if (!sourceDir) {
|
|
53061
53437
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
53062
53438
|
}
|
|
53063
|
-
if (!
|
|
53064
|
-
|
|
53065
|
-
|
|
53439
|
+
if (!fs29.existsSync(desiredDir)) {
|
|
53440
|
+
fs29.mkdirSync(path39.dirname(desiredDir), { recursive: true });
|
|
53441
|
+
fs29.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
53066
53442
|
ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
53067
53443
|
}
|
|
53068
53444
|
const providerJson = path39.join(desiredDir, "provider.json");
|
|
53069
|
-
if (!
|
|
53445
|
+
if (!fs29.existsSync(providerJson)) {
|
|
53070
53446
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
53071
53447
|
}
|
|
53072
53448
|
return { dir: desiredDir };
|
|
@@ -53074,15 +53450,15 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
|
53074
53450
|
function loadAutoImplReferenceScripts(ctx, referenceType) {
|
|
53075
53451
|
if (!referenceType) return {};
|
|
53076
53452
|
const refDir = ctx.findProviderDir(referenceType);
|
|
53077
|
-
if (!refDir || !
|
|
53453
|
+
if (!refDir || !fs29.existsSync(refDir)) return {};
|
|
53078
53454
|
const referenceScripts = {};
|
|
53079
53455
|
const scriptsDir = path39.join(refDir, "scripts");
|
|
53080
53456
|
const latestDir = getLatestScriptVersionDir(scriptsDir);
|
|
53081
53457
|
if (!latestDir) return referenceScripts;
|
|
53082
|
-
for (const file of
|
|
53458
|
+
for (const file of fs29.readdirSync(latestDir)) {
|
|
53083
53459
|
if (!file.endsWith(".js")) continue;
|
|
53084
53460
|
try {
|
|
53085
|
-
referenceScripts[file] =
|
|
53461
|
+
referenceScripts[file] = fs29.readFileSync(path39.join(latestDir, file), "utf-8");
|
|
53086
53462
|
} catch {
|
|
53087
53463
|
}
|
|
53088
53464
|
}
|
|
@@ -53191,15 +53567,15 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
53191
53567
|
const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
|
|
53192
53568
|
const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
|
|
53193
53569
|
const tmpDir = path39.join(os29.tmpdir(), "adhdev-autoimpl");
|
|
53194
|
-
if (!
|
|
53570
|
+
if (!fs29.existsSync(tmpDir)) fs29.mkdirSync(tmpDir, { recursive: true });
|
|
53195
53571
|
const promptFile = path39.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
|
|
53196
|
-
|
|
53572
|
+
fs29.writeFileSync(promptFile, prompt, "utf-8");
|
|
53197
53573
|
ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
|
|
53198
53574
|
const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
|
|
53199
53575
|
const spawn4 = agentProvider?.spawn;
|
|
53200
53576
|
if (!spawn4?.command) {
|
|
53201
53577
|
try {
|
|
53202
|
-
|
|
53578
|
+
fs29.unlinkSync(promptFile);
|
|
53203
53579
|
} catch {
|
|
53204
53580
|
}
|
|
53205
53581
|
ctx.json(res, 400, { error: `Agent '${agent}' has no spawn config. Select a CLI provider with a spawn configuration.` });
|
|
@@ -53301,7 +53677,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
53301
53677
|
} catch {
|
|
53302
53678
|
}
|
|
53303
53679
|
try {
|
|
53304
|
-
|
|
53680
|
+
fs29.unlinkSync(promptFile);
|
|
53305
53681
|
} catch {
|
|
53306
53682
|
}
|
|
53307
53683
|
ctx.log(`Auto-implement (ACP) ${success ? "completed" : "failed"}: ${type} (exit: ${code})`);
|
|
@@ -53527,7 +53903,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
53527
53903
|
}
|
|
53528
53904
|
});
|
|
53529
53905
|
try {
|
|
53530
|
-
|
|
53906
|
+
fs29.unlinkSync(promptFile);
|
|
53531
53907
|
} catch {
|
|
53532
53908
|
}
|
|
53533
53909
|
ctx.log(`Auto-implement ${success ? "completed" : "failed"}: ${type} (exit: ${code})${verificationSummary ? ` verify=${verificationSummary.pass ? "pass" : "fail"}` : ""}`);
|
|
@@ -53632,10 +54008,10 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
53632
54008
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
53633
54009
|
lines.push("These are the ONLY files you are allowed to modify. Replace the TODO stubs with working implementations.");
|
|
53634
54010
|
lines.push("");
|
|
53635
|
-
for (const file of
|
|
54011
|
+
for (const file of fs29.readdirSync(latestScriptsDir)) {
|
|
53636
54012
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
53637
54013
|
try {
|
|
53638
|
-
const content =
|
|
54014
|
+
const content = fs29.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
|
|
53639
54015
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
53640
54016
|
lines.push("```javascript");
|
|
53641
54017
|
lines.push(content);
|
|
@@ -53645,14 +54021,14 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
53645
54021
|
}
|
|
53646
54022
|
}
|
|
53647
54023
|
}
|
|
53648
|
-
const refFiles =
|
|
54024
|
+
const refFiles = fs29.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
53649
54025
|
if (refFiles.length > 0) {
|
|
53650
54026
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
53651
54027
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
53652
54028
|
lines.push("");
|
|
53653
54029
|
for (const file of refFiles) {
|
|
53654
54030
|
try {
|
|
53655
|
-
const content =
|
|
54031
|
+
const content = fs29.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
|
|
53656
54032
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
53657
54033
|
lines.push("```javascript");
|
|
53658
54034
|
lines.push(content);
|
|
@@ -53697,7 +54073,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
53697
54073
|
const loadGuide = (name) => {
|
|
53698
54074
|
try {
|
|
53699
54075
|
const p = path39.join(docsDir, name);
|
|
53700
|
-
if (
|
|
54076
|
+
if (fs29.existsSync(p)) return fs29.readFileSync(p, "utf-8");
|
|
53701
54077
|
} catch {
|
|
53702
54078
|
}
|
|
53703
54079
|
return null;
|
|
@@ -53941,11 +54317,11 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
53941
54317
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
53942
54318
|
lines.push("These are the ONLY files you are allowed to modify. Replace TODO or heuristic-only logic with working PTY-aware implementations.");
|
|
53943
54319
|
lines.push("");
|
|
53944
|
-
for (const file of
|
|
54320
|
+
for (const file of fs29.readdirSync(latestScriptsDir)) {
|
|
53945
54321
|
if (!file.endsWith(".js")) continue;
|
|
53946
54322
|
if (!targetFileNames.has(file)) continue;
|
|
53947
54323
|
try {
|
|
53948
|
-
const content =
|
|
54324
|
+
const content = fs29.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
|
|
53949
54325
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
53950
54326
|
lines.push("```javascript");
|
|
53951
54327
|
lines.push(content);
|
|
@@ -53954,14 +54330,14 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
53954
54330
|
} catch {
|
|
53955
54331
|
}
|
|
53956
54332
|
}
|
|
53957
|
-
const refFiles =
|
|
54333
|
+
const refFiles = fs29.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
53958
54334
|
if (refFiles.length > 0) {
|
|
53959
54335
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
53960
54336
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
53961
54337
|
lines.push("");
|
|
53962
54338
|
for (const file of refFiles) {
|
|
53963
54339
|
try {
|
|
53964
|
-
const content =
|
|
54340
|
+
const content = fs29.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
|
|
53965
54341
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
53966
54342
|
lines.push("```javascript");
|
|
53967
54343
|
lines.push(content);
|
|
@@ -53998,7 +54374,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
53998
54374
|
const loadGuide = (name) => {
|
|
53999
54375
|
try {
|
|
54000
54376
|
const p = path39.join(docsDir, name);
|
|
54001
|
-
if (
|
|
54377
|
+
if (fs29.existsSync(p)) return fs29.readFileSync(p, "utf-8");
|
|
54002
54378
|
} catch {
|
|
54003
54379
|
}
|
|
54004
54380
|
return null;
|
|
@@ -54738,7 +55114,7 @@ var DevServer = class _DevServer {
|
|
|
54738
55114
|
path40.join(process.cwd(), "packages/web-devconsole/dist")
|
|
54739
55115
|
];
|
|
54740
55116
|
for (const dir of candidates) {
|
|
54741
|
-
if (
|
|
55117
|
+
if (fs30.existsSync(path40.join(dir, "index.html"))) return dir;
|
|
54742
55118
|
}
|
|
54743
55119
|
return null;
|
|
54744
55120
|
}
|
|
@@ -54750,7 +55126,7 @@ var DevServer = class _DevServer {
|
|
|
54750
55126
|
}
|
|
54751
55127
|
const htmlPath = path40.join(distDir, "index.html");
|
|
54752
55128
|
try {
|
|
54753
|
-
const html =
|
|
55129
|
+
const html = fs30.readFileSync(htmlPath, "utf-8");
|
|
54754
55130
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
54755
55131
|
res.end(html);
|
|
54756
55132
|
} catch (e) {
|
|
@@ -54780,7 +55156,7 @@ var DevServer = class _DevServer {
|
|
|
54780
55156
|
return;
|
|
54781
55157
|
}
|
|
54782
55158
|
try {
|
|
54783
|
-
const content =
|
|
55159
|
+
const content = fs30.readFileSync(filePath);
|
|
54784
55160
|
const ext = path40.extname(filePath);
|
|
54785
55161
|
const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
|
|
54786
55162
|
res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
|
|
@@ -54889,14 +55265,14 @@ var DevServer = class _DevServer {
|
|
|
54889
55265
|
const files = [];
|
|
54890
55266
|
const scan = (d, prefix) => {
|
|
54891
55267
|
try {
|
|
54892
|
-
for (const entry of
|
|
55268
|
+
for (const entry of fs30.readdirSync(d, { withFileTypes: true })) {
|
|
54893
55269
|
if (entry.name.startsWith(".") || entry.name.endsWith(".bak")) continue;
|
|
54894
55270
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
54895
55271
|
if (entry.isDirectory()) {
|
|
54896
55272
|
files.push({ path: rel, size: 0, type: "dir" });
|
|
54897
55273
|
scan(path40.join(d, entry.name), rel);
|
|
54898
55274
|
} else {
|
|
54899
|
-
const stat2 =
|
|
55275
|
+
const stat2 = fs30.statSync(path40.join(d, entry.name));
|
|
54900
55276
|
files.push({ path: rel, size: stat2.size, type: "file" });
|
|
54901
55277
|
}
|
|
54902
55278
|
}
|
|
@@ -54924,11 +55300,11 @@ var DevServer = class _DevServer {
|
|
|
54924
55300
|
this.json(res, 403, { error: "Forbidden" });
|
|
54925
55301
|
return;
|
|
54926
55302
|
}
|
|
54927
|
-
if (!
|
|
55303
|
+
if (!fs30.existsSync(fullPath) || fs30.statSync(fullPath).isDirectory()) {
|
|
54928
55304
|
this.json(res, 404, { error: `File not found: ${filePath}` });
|
|
54929
55305
|
return;
|
|
54930
55306
|
}
|
|
54931
|
-
const content =
|
|
55307
|
+
const content = fs30.readFileSync(fullPath, "utf-8");
|
|
54932
55308
|
this.json(res, 200, { type, path: filePath, content, lines: content.split("\n").length });
|
|
54933
55309
|
}
|
|
54934
55310
|
/** POST /api/providers/:type/file — write a file { path, content } */
|
|
@@ -54950,9 +55326,9 @@ var DevServer = class _DevServer {
|
|
|
54950
55326
|
return;
|
|
54951
55327
|
}
|
|
54952
55328
|
try {
|
|
54953
|
-
if (
|
|
54954
|
-
|
|
54955
|
-
|
|
55329
|
+
if (fs30.existsSync(fullPath)) fs30.copyFileSync(fullPath, fullPath + ".bak");
|
|
55330
|
+
fs30.mkdirSync(path40.dirname(fullPath), { recursive: true });
|
|
55331
|
+
fs30.writeFileSync(fullPath, content, "utf-8");
|
|
54956
55332
|
this.log(`File saved: ${fullPath} (${content.length} chars)`);
|
|
54957
55333
|
this.providerLoader.reload();
|
|
54958
55334
|
this.json(res, 200, { saved: true, path: filePath, chars: content.length });
|
|
@@ -54969,8 +55345,8 @@ var DevServer = class _DevServer {
|
|
|
54969
55345
|
}
|
|
54970
55346
|
for (const name of ["scripts.js", "provider.json"]) {
|
|
54971
55347
|
const p = path40.join(dir, name);
|
|
54972
|
-
if (
|
|
54973
|
-
const source =
|
|
55348
|
+
if (fs30.existsSync(p)) {
|
|
55349
|
+
const source = fs30.readFileSync(p, "utf-8");
|
|
54974
55350
|
this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
|
|
54975
55351
|
return;
|
|
54976
55352
|
}
|
|
@@ -54989,11 +55365,11 @@ var DevServer = class _DevServer {
|
|
|
54989
55365
|
this.json(res, 404, { error: `Provider not found: ${type}` });
|
|
54990
55366
|
return;
|
|
54991
55367
|
}
|
|
54992
|
-
const target =
|
|
55368
|
+
const target = fs30.existsSync(path40.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
|
|
54993
55369
|
const targetPath = path40.join(dir, target);
|
|
54994
55370
|
try {
|
|
54995
|
-
if (
|
|
54996
|
-
|
|
55371
|
+
if (fs30.existsSync(targetPath)) fs30.copyFileSync(targetPath, targetPath + ".bak");
|
|
55372
|
+
fs30.writeFileSync(targetPath, source, "utf-8");
|
|
54997
55373
|
this.log(`Saved provider: ${targetPath} (${source.length} chars)`);
|
|
54998
55374
|
this.providerLoader.reload();
|
|
54999
55375
|
this.json(res, 200, { saved: true, path: targetPath, chars: source.length });
|
|
@@ -55138,20 +55514,20 @@ var DevServer = class _DevServer {
|
|
|
55138
55514
|
let targetDir;
|
|
55139
55515
|
targetDir = this.providerLoader.getUserProviderDir(category, type);
|
|
55140
55516
|
const jsonPath = path40.join(targetDir, "provider.json");
|
|
55141
|
-
if (
|
|
55517
|
+
if (fs30.existsSync(jsonPath)) {
|
|
55142
55518
|
this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
|
|
55143
55519
|
return;
|
|
55144
55520
|
}
|
|
55145
55521
|
try {
|
|
55146
55522
|
const result = generateFiles(type, name, category, { cdpPorts, cli, processName, installPath, binary, extensionId, version, osPaths, processNames });
|
|
55147
|
-
|
|
55148
|
-
|
|
55523
|
+
fs30.mkdirSync(targetDir, { recursive: true });
|
|
55524
|
+
fs30.writeFileSync(jsonPath, result["provider.json"], "utf-8");
|
|
55149
55525
|
const createdFiles = ["provider.json"];
|
|
55150
55526
|
if (result.files) {
|
|
55151
55527
|
for (const [relPath, content] of Object.entries(result.files)) {
|
|
55152
55528
|
const fullPath = path40.join(targetDir, relPath);
|
|
55153
|
-
|
|
55154
|
-
|
|
55529
|
+
fs30.mkdirSync(path40.dirname(fullPath), { recursive: true });
|
|
55530
|
+
fs30.writeFileSync(fullPath, content, "utf-8");
|
|
55155
55531
|
createdFiles.push(relPath);
|
|
55156
55532
|
}
|
|
55157
55533
|
}
|
|
@@ -55200,10 +55576,10 @@ var DevServer = class _DevServer {
|
|
|
55200
55576
|
}
|
|
55201
55577
|
// ─── Phase 2: Auto-Implement Backend ───
|
|
55202
55578
|
getLatestScriptVersionDir(scriptsDir) {
|
|
55203
|
-
if (!
|
|
55204
|
-
const versions =
|
|
55579
|
+
if (!fs30.existsSync(scriptsDir)) return null;
|
|
55580
|
+
const versions = fs30.readdirSync(scriptsDir).filter((d) => {
|
|
55205
55581
|
try {
|
|
55206
|
-
return
|
|
55582
|
+
return fs30.statSync(path40.join(scriptsDir, d)).isDirectory();
|
|
55207
55583
|
} catch {
|
|
55208
55584
|
return false;
|
|
55209
55585
|
}
|
|
@@ -55225,13 +55601,13 @@ var DevServer = class _DevServer {
|
|
|
55225
55601
|
if (!sourceDir) {
|
|
55226
55602
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
55227
55603
|
}
|
|
55228
|
-
if (!
|
|
55229
|
-
|
|
55230
|
-
|
|
55604
|
+
if (!fs30.existsSync(desiredDir)) {
|
|
55605
|
+
fs30.mkdirSync(path40.dirname(desiredDir), { recursive: true });
|
|
55606
|
+
fs30.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
55231
55607
|
this.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
55232
55608
|
}
|
|
55233
55609
|
const providerJson = path40.join(desiredDir, "provider.json");
|
|
55234
|
-
if (!
|
|
55610
|
+
if (!fs30.existsSync(providerJson)) {
|
|
55235
55611
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
55236
55612
|
}
|
|
55237
55613
|
return { dir: desiredDir };
|
|
@@ -55274,10 +55650,10 @@ var DevServer = class _DevServer {
|
|
|
55274
55650
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
55275
55651
|
lines.push("These are the ONLY files you are allowed to modify. Replace the TODO stubs with working implementations.");
|
|
55276
55652
|
lines.push("");
|
|
55277
|
-
for (const file of
|
|
55653
|
+
for (const file of fs30.readdirSync(latestScriptsDir)) {
|
|
55278
55654
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
55279
55655
|
try {
|
|
55280
|
-
const content =
|
|
55656
|
+
const content = fs30.readFileSync(path40.join(latestScriptsDir, file), "utf-8");
|
|
55281
55657
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
55282
55658
|
lines.push("```javascript");
|
|
55283
55659
|
lines.push(content);
|
|
@@ -55287,14 +55663,14 @@ var DevServer = class _DevServer {
|
|
|
55287
55663
|
}
|
|
55288
55664
|
}
|
|
55289
55665
|
}
|
|
55290
|
-
const refFiles =
|
|
55666
|
+
const refFiles = fs30.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
55291
55667
|
if (refFiles.length > 0) {
|
|
55292
55668
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
55293
55669
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
55294
55670
|
lines.push("");
|
|
55295
55671
|
for (const file of refFiles) {
|
|
55296
55672
|
try {
|
|
55297
|
-
const content =
|
|
55673
|
+
const content = fs30.readFileSync(path40.join(latestScriptsDir, file), "utf-8");
|
|
55298
55674
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
55299
55675
|
lines.push("```javascript");
|
|
55300
55676
|
lines.push(content);
|
|
@@ -55339,7 +55715,7 @@ var DevServer = class _DevServer {
|
|
|
55339
55715
|
const loadGuide = (name) => {
|
|
55340
55716
|
try {
|
|
55341
55717
|
const p = path40.join(docsDir, name);
|
|
55342
|
-
if (
|
|
55718
|
+
if (fs30.existsSync(p)) return fs30.readFileSync(p, "utf-8");
|
|
55343
55719
|
} catch {
|
|
55344
55720
|
}
|
|
55345
55721
|
return null;
|
|
@@ -55520,11 +55896,11 @@ var DevServer = class _DevServer {
|
|
|
55520
55896
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
55521
55897
|
lines.push("These are the ONLY files you are allowed to modify. Replace TODO or heuristic-only logic with working PTY-aware implementations.");
|
|
55522
55898
|
lines.push("");
|
|
55523
|
-
for (const file of
|
|
55899
|
+
for (const file of fs30.readdirSync(latestScriptsDir)) {
|
|
55524
55900
|
if (!file.endsWith(".js")) continue;
|
|
55525
55901
|
if (!targetFileNames.has(file)) continue;
|
|
55526
55902
|
try {
|
|
55527
|
-
const content =
|
|
55903
|
+
const content = fs30.readFileSync(path40.join(latestScriptsDir, file), "utf-8");
|
|
55528
55904
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
55529
55905
|
lines.push("```javascript");
|
|
55530
55906
|
lines.push(content);
|
|
@@ -55533,14 +55909,14 @@ var DevServer = class _DevServer {
|
|
|
55533
55909
|
} catch {
|
|
55534
55910
|
}
|
|
55535
55911
|
}
|
|
55536
|
-
const refFiles =
|
|
55912
|
+
const refFiles = fs30.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
55537
55913
|
if (refFiles.length > 0) {
|
|
55538
55914
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
55539
55915
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
55540
55916
|
lines.push("");
|
|
55541
55917
|
for (const file of refFiles) {
|
|
55542
55918
|
try {
|
|
55543
|
-
const content =
|
|
55919
|
+
const content = fs30.readFileSync(path40.join(latestScriptsDir, file), "utf-8");
|
|
55544
55920
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
55545
55921
|
lines.push("```javascript");
|
|
55546
55922
|
lines.push(content);
|
|
@@ -55577,7 +55953,7 @@ var DevServer = class _DevServer {
|
|
|
55577
55953
|
const loadGuide = (name) => {
|
|
55578
55954
|
try {
|
|
55579
55955
|
const p = path40.join(docsDir, name);
|
|
55580
|
-
if (
|
|
55956
|
+
if (fs30.existsSync(p)) return fs30.readFileSync(p, "utf-8");
|
|
55581
55957
|
} catch {
|
|
55582
55958
|
}
|
|
55583
55959
|
return null;
|
|
@@ -56685,8 +57061,8 @@ async function installExtension(ide, extension) {
|
|
|
56685
57061
|
const res = await fetch(extension.vsixUrl);
|
|
56686
57062
|
if (res.ok) {
|
|
56687
57063
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
56688
|
-
const
|
|
56689
|
-
|
|
57064
|
+
const fs31 = await import("fs");
|
|
57065
|
+
fs31.writeFileSync(vsixPath, buffer);
|
|
56690
57066
|
return new Promise((resolve24) => {
|
|
56691
57067
|
const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
|
|
56692
57068
|
exec6(cmd, { timeout: 6e4 }, (error, _stdout, stderr) => {
|
|
@@ -57266,7 +57642,7 @@ import { readFileSync as readFileSync33 } from "fs";
|
|
|
57266
57642
|
import { dirname as dirname12, resolve as resolve22 } from "path";
|
|
57267
57643
|
|
|
57268
57644
|
// src/providers/sdk/v1/validators/taint.ts
|
|
57269
|
-
import { readFileSync as readFileSync34, existsSync as
|
|
57645
|
+
import { readFileSync as readFileSync34, existsSync as existsSync43 } from "fs";
|
|
57270
57646
|
import { resolve as resolve23, dirname as dirname13, join as join44 } from "path";
|
|
57271
57647
|
|
|
57272
57648
|
// src/providers/sdk/v1/validators/index.ts
|