@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.js
CHANGED
|
@@ -316,10 +316,10 @@ function readInjected(value) {
|
|
|
316
316
|
}
|
|
317
317
|
function getDaemonBuildInfo() {
|
|
318
318
|
if (cached) return cached;
|
|
319
|
-
const commit = readInjected(true ? "
|
|
320
|
-
const commitShort = readInjected(true ? "
|
|
321
|
-
const version = readInjected(true ? "0.9.82-rc.
|
|
322
|
-
const builtAt = readInjected(true ? "2026-06-
|
|
319
|
+
const commit = readInjected(true ? "ed3b7279be8ea9fa191f854f7e9b6ce969159e67" : void 0) ?? "unknown";
|
|
320
|
+
const commitShort = readInjected(true ? "ed3b7279" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
321
|
+
const version = readInjected(true ? "0.9.82-rc.313" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
322
|
+
const builtAt = readInjected(true ? "2026-06-18T00:14:56.582Z" : void 0);
|
|
323
323
|
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
324
324
|
return cached;
|
|
325
325
|
}
|
|
@@ -2118,6 +2118,7 @@ var init_coordinator_prompt = __esm({
|
|
|
2118
2118
|
| \`mesh_read_debug\` | Collect a daemon-side chat/parser debug bundle for a session |
|
|
2119
2119
|
| \`mesh_task_history\` | Read the task ledger \u2014 dispatches, completions, failures. Use to understand what has been done before deciding next steps |
|
|
2120
2120
|
| \`mesh_git_status\` | Check git status on a specific node |
|
|
2121
|
+
| \`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 |
|
|
2121
2122
|
| \`mesh_fast_forward_node\` | Safely dry-run or explicitly execute an obvious clean fast-forward without launching an agent session |
|
|
2122
2123
|
| \`mesh_checkpoint\` | Create a git checkpoint on a node |
|
|
2123
2124
|
| \`mesh_approve\` | Approve/reject a pending agent action |
|
|
@@ -5825,8 +5826,8 @@ function stripCoordinatorWrapperFile(filePath) {
|
|
|
5825
5826
|
const remaining = (existing.slice(0, openIdx) + existing.slice(closeIdx + CLOSE.length)).replace(/^\s*\n+/, "").replace(/\n+\s*$/, "");
|
|
5826
5827
|
if (!remaining.trim()) {
|
|
5827
5828
|
try {
|
|
5828
|
-
const
|
|
5829
|
-
|
|
5829
|
+
const fs31 = require("fs");
|
|
5830
|
+
fs31.unlinkSync(filePath);
|
|
5830
5831
|
} catch {
|
|
5831
5832
|
}
|
|
5832
5833
|
} else {
|
|
@@ -10858,8 +10859,8 @@ var init_pty_transport = __esm({
|
|
|
10858
10859
|
let cwd = options.cwd;
|
|
10859
10860
|
if (cwd) {
|
|
10860
10861
|
try {
|
|
10861
|
-
const
|
|
10862
|
-
const stat2 =
|
|
10862
|
+
const fs31 = require("fs");
|
|
10863
|
+
const stat2 = fs31.statSync(cwd);
|
|
10863
10864
|
if (!stat2.isDirectory()) cwd = os11.homedir();
|
|
10864
10865
|
} catch {
|
|
10865
10866
|
cwd = os11.homedir();
|
|
@@ -10966,9 +10967,9 @@ function findBinary(name) {
|
|
|
10966
10967
|
for (const ext of exes) {
|
|
10967
10968
|
const fullPath = path17.join(p, trimmed + ext);
|
|
10968
10969
|
try {
|
|
10969
|
-
const
|
|
10970
|
-
if (
|
|
10971
|
-
const stat2 =
|
|
10970
|
+
const fs31 = require("fs");
|
|
10971
|
+
if (fs31.existsSync(fullPath)) {
|
|
10972
|
+
const stat2 = fs31.statSync(fullPath);
|
|
10972
10973
|
if (stat2.isFile() && (isWin || stat2.mode & 73)) {
|
|
10973
10974
|
return fullPath;
|
|
10974
10975
|
}
|
|
@@ -10982,12 +10983,12 @@ function findBinary(name) {
|
|
|
10982
10983
|
function isScriptBinary(binaryPath) {
|
|
10983
10984
|
if (!path17.isAbsolute(binaryPath)) return false;
|
|
10984
10985
|
try {
|
|
10985
|
-
const
|
|
10986
|
-
const resolved =
|
|
10986
|
+
const fs31 = require("fs");
|
|
10987
|
+
const resolved = fs31.realpathSync(binaryPath);
|
|
10987
10988
|
const head = Buffer.alloc(8);
|
|
10988
|
-
const fd =
|
|
10989
|
-
|
|
10990
|
-
|
|
10989
|
+
const fd = fs31.openSync(resolved, "r");
|
|
10990
|
+
fs31.readSync(fd, head, 0, 8, 0);
|
|
10991
|
+
fs31.closeSync(fd);
|
|
10991
10992
|
let i = 0;
|
|
10992
10993
|
if (head[0] === 239 && head[1] === 187 && head[2] === 191) i = 3;
|
|
10993
10994
|
return head[i] === 35 && head[i + 1] === 33;
|
|
@@ -10998,12 +10999,12 @@ function isScriptBinary(binaryPath) {
|
|
|
10998
10999
|
function looksLikeMachOOrElf(filePath) {
|
|
10999
11000
|
if (!path17.isAbsolute(filePath)) return false;
|
|
11000
11001
|
try {
|
|
11001
|
-
const
|
|
11002
|
-
const resolved =
|
|
11002
|
+
const fs31 = require("fs");
|
|
11003
|
+
const resolved = fs31.realpathSync(filePath);
|
|
11003
11004
|
const buf = Buffer.alloc(8);
|
|
11004
|
-
const fd =
|
|
11005
|
-
|
|
11006
|
-
|
|
11005
|
+
const fd = fs31.openSync(resolved, "r");
|
|
11006
|
+
fs31.readSync(fd, buf, 0, 8, 0);
|
|
11007
|
+
fs31.closeSync(fd);
|
|
11007
11008
|
let i = 0;
|
|
11008
11009
|
if (buf[0] === 239 && buf[1] === 187 && buf[2] === 191) i = 3;
|
|
11009
11010
|
const b = buf.subarray(i);
|
|
@@ -29841,7 +29842,7 @@ var DaemonCommandHandler = class {
|
|
|
29841
29842
|
return { success: false, error: "invalid type" };
|
|
29842
29843
|
}
|
|
29843
29844
|
const https = require("https");
|
|
29844
|
-
const
|
|
29845
|
+
const fs31 = require("fs");
|
|
29845
29846
|
const path41 = require("path");
|
|
29846
29847
|
const crypto6 = require("crypto");
|
|
29847
29848
|
const REGISTRY = "https://api.adhf.dev/api/v1/registry";
|
|
@@ -29885,7 +29886,7 @@ var DaemonCommandHandler = class {
|
|
|
29885
29886
|
if (!targetDir.startsWith(installRootResolved + path41.sep)) {
|
|
29886
29887
|
return { success: false, error: "install path escaped upstream root" };
|
|
29887
29888
|
}
|
|
29888
|
-
|
|
29889
|
+
fs31.mkdirSync(targetDir, { recursive: true });
|
|
29889
29890
|
let manifestProbe = {};
|
|
29890
29891
|
try {
|
|
29891
29892
|
manifestProbe = JSON.parse(manifestBody);
|
|
@@ -29910,7 +29911,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
29910
29911
|
}
|
|
29911
29912
|
const targetFile = isV1 ? "provider.v1.json" : "provider.json";
|
|
29912
29913
|
const targetPath = path41.join(targetDir, targetFile);
|
|
29913
|
-
|
|
29914
|
+
fs31.writeFileSync(targetPath, manifestBody, "utf-8");
|
|
29914
29915
|
const manifestJson = JSON.parse(manifestBody);
|
|
29915
29916
|
const scriptFetch = await this.fetchProviderSources(
|
|
29916
29917
|
manifestJson,
|
|
@@ -29980,7 +29981,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
29980
29981
|
const repo = source.repo;
|
|
29981
29982
|
const ref = source.ref;
|
|
29982
29983
|
const https = require("https");
|
|
29983
|
-
const
|
|
29984
|
+
const fs31 = require("fs");
|
|
29984
29985
|
const path41 = require("path");
|
|
29985
29986
|
function fetchJson(url, timeoutMs) {
|
|
29986
29987
|
return new Promise((resolve24, reject) => {
|
|
@@ -30064,8 +30065,8 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
30064
30065
|
const relInside = entry.path.startsWith(sharedDirRel + "/") ? entry.path.slice(sharedDirRel.length + 1) : entry.path;
|
|
30065
30066
|
const outPath = path41.resolve(path41.join(sharedTargetDir, relInside));
|
|
30066
30067
|
if (!outPath.startsWith(path41.resolve(sharedTargetDir) + path41.sep)) continue;
|
|
30067
|
-
|
|
30068
|
-
|
|
30068
|
+
fs31.mkdirSync(path41.dirname(outPath), { recursive: true });
|
|
30069
|
+
fs31.writeFileSync(outPath, body);
|
|
30069
30070
|
fetchedCount++;
|
|
30070
30071
|
} catch (e) {
|
|
30071
30072
|
errors.push(`fetch shared ${entry.path}: ${e?.message ?? e}`);
|
|
@@ -30103,8 +30104,8 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
30103
30104
|
errors.push(`refusing to write outside targetDir: ${entry.path}`);
|
|
30104
30105
|
continue;
|
|
30105
30106
|
}
|
|
30106
|
-
|
|
30107
|
-
|
|
30107
|
+
fs31.mkdirSync(path41.dirname(outPath), { recursive: true });
|
|
30108
|
+
fs31.writeFileSync(outPath, body);
|
|
30108
30109
|
fetchedCount++;
|
|
30109
30110
|
} catch (e) {
|
|
30110
30111
|
errors.push(`fetch ${entry.path}: ${e?.message ?? e}`);
|
|
@@ -30132,7 +30133,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
30132
30133
|
if (!["cli", "ide", "extension", "acp"].includes(category)) {
|
|
30133
30134
|
return { success: false, error: `unknown category: ${category}` };
|
|
30134
30135
|
}
|
|
30135
|
-
const
|
|
30136
|
+
const fs31 = require("fs");
|
|
30136
30137
|
const path41 = require("path");
|
|
30137
30138
|
try {
|
|
30138
30139
|
const installRoot = this.getUpstreamInstallRoot();
|
|
@@ -30141,10 +30142,10 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
30141
30142
|
if (!targetDir.startsWith(installRootResolved + path41.sep)) {
|
|
30142
30143
|
return { success: false, error: "refusing to delete outside upstream root" };
|
|
30143
30144
|
}
|
|
30144
|
-
if (!
|
|
30145
|
+
if (!fs31.existsSync(targetDir)) {
|
|
30145
30146
|
return { success: false, error: "not installed" };
|
|
30146
30147
|
}
|
|
30147
|
-
|
|
30148
|
+
fs31.rmSync(targetDir, { recursive: true, force: true });
|
|
30148
30149
|
if (this._ctx.providerLoader) {
|
|
30149
30150
|
this._ctx.providerLoader.reload();
|
|
30150
30151
|
this._ctx.providerLoader.registerToDetector();
|
|
@@ -30160,28 +30161,28 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
30160
30161
|
* the UI and by the update checker.
|
|
30161
30162
|
*/
|
|
30162
30163
|
handleListInstalledProviders(_args) {
|
|
30163
|
-
const
|
|
30164
|
+
const fs31 = require("fs");
|
|
30164
30165
|
const path41 = require("path");
|
|
30165
30166
|
const installRoot = this.getUpstreamInstallRoot();
|
|
30166
|
-
if (!
|
|
30167
|
+
if (!fs31.existsSync(installRoot)) return { success: true, providers: [] };
|
|
30167
30168
|
const CATEGORIES = ["cli", "ide", "extension", "acp"];
|
|
30168
30169
|
const items = [];
|
|
30169
30170
|
for (const category of CATEGORIES) {
|
|
30170
30171
|
const categoryDir = path41.join(installRoot, category);
|
|
30171
|
-
if (!
|
|
30172
|
+
if (!fs31.existsSync(categoryDir)) continue;
|
|
30172
30173
|
let entries;
|
|
30173
30174
|
try {
|
|
30174
|
-
entries =
|
|
30175
|
+
entries = fs31.readdirSync(categoryDir);
|
|
30175
30176
|
} catch {
|
|
30176
30177
|
continue;
|
|
30177
30178
|
}
|
|
30178
30179
|
for (const type of entries) {
|
|
30179
30180
|
const v1Path = path41.join(categoryDir, type, "provider.v1.json");
|
|
30180
30181
|
const v0Path = path41.join(categoryDir, type, "provider.json");
|
|
30181
|
-
const manifestPath =
|
|
30182
|
+
const manifestPath = fs31.existsSync(v1Path) ? v1Path : fs31.existsSync(v0Path) ? v0Path : null;
|
|
30182
30183
|
if (!manifestPath) continue;
|
|
30183
30184
|
try {
|
|
30184
|
-
const m = JSON.parse(
|
|
30185
|
+
const m = JSON.parse(fs31.readFileSync(manifestPath, "utf-8"));
|
|
30185
30186
|
items.push({
|
|
30186
30187
|
type,
|
|
30187
30188
|
category,
|
|
@@ -30292,7 +30293,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
30292
30293
|
if (!/^@[a-z0-9_-]+$/i.test(requestedName)) {
|
|
30293
30294
|
return { success: false, error: "name must match @[a-z0-9_-]+" };
|
|
30294
30295
|
}
|
|
30295
|
-
const
|
|
30296
|
+
const fs31 = require("fs");
|
|
30296
30297
|
const path41 = require("path");
|
|
30297
30298
|
const { spawnSync: spawnSync2 } = require("child_process");
|
|
30298
30299
|
const file = ext.loadExternalSources();
|
|
@@ -30303,8 +30304,8 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
30303
30304
|
return { success: false, error: `source url+ref already registered (use a different name to track another ref)` };
|
|
30304
30305
|
}
|
|
30305
30306
|
const sourceDir = path41.join(ext.externalRoot(), requestedName);
|
|
30306
|
-
if (!
|
|
30307
|
-
if (
|
|
30307
|
+
if (!fs31.existsSync(ext.externalRoot())) fs31.mkdirSync(ext.externalRoot(), { recursive: true });
|
|
30308
|
+
if (fs31.existsSync(sourceDir)) {
|
|
30308
30309
|
return { success: false, error: `directory already exists: ${sourceDir} (rename or remove first)` };
|
|
30309
30310
|
}
|
|
30310
30311
|
const clone = spawnSync2("git", ["clone", "--depth=1", "--branch", ref, "--", url, sourceDir], {
|
|
@@ -30314,7 +30315,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
30314
30315
|
});
|
|
30315
30316
|
if (clone.status !== 0) {
|
|
30316
30317
|
try {
|
|
30317
|
-
|
|
30318
|
+
fs31.rmSync(sourceDir, { recursive: true, force: true });
|
|
30318
30319
|
} catch {
|
|
30319
30320
|
}
|
|
30320
30321
|
return { success: false, error: `git clone failed: ${(clone.stderr || clone.stdout || "").trim() || "unknown error"}` };
|
|
@@ -30358,15 +30359,15 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
30358
30359
|
const name = typeof args?.name === "string" ? args.name.trim() : "";
|
|
30359
30360
|
if (!name) return { success: false, error: "name is required" };
|
|
30360
30361
|
const ext = (init_external_sources(), __toCommonJS(external_sources_exports));
|
|
30361
|
-
const
|
|
30362
|
+
const fs31 = require("fs");
|
|
30362
30363
|
const path41 = require("path");
|
|
30363
30364
|
const file = ext.loadExternalSources();
|
|
30364
30365
|
const match = file.sources.find((s) => s.name === name);
|
|
30365
30366
|
if (!match) return { success: false, error: `source "${name}" not registered` };
|
|
30366
30367
|
const sourceDir = path41.join(ext.externalRoot(), name);
|
|
30367
|
-
if (
|
|
30368
|
+
if (fs31.existsSync(sourceDir)) {
|
|
30368
30369
|
try {
|
|
30369
|
-
|
|
30370
|
+
fs31.rmSync(sourceDir, { recursive: true, force: true });
|
|
30370
30371
|
} catch (e) {
|
|
30371
30372
|
return { success: false, error: `failed to delete ${sourceDir}: ${e?.message || e}` };
|
|
30372
30373
|
}
|
|
@@ -32408,7 +32409,7 @@ var SpecCliAdapter = class _SpecCliAdapter {
|
|
|
32408
32409
|
}
|
|
32409
32410
|
if (action.type === "open_picker") {
|
|
32410
32411
|
const choiceIndex = typeof flat.choiceIndex === "number" ? flat.choiceIndex : typeof flat.choiceIndex === "string" && flat.choiceIndex.trim() ? Number(flat.choiceIndex) : void 0;
|
|
32411
|
-
const choiceLabel = typeof flat.choiceLabel === "string" ? flat.choiceLabel : typeof flat.choice === "string" ? flat.choice : void 0;
|
|
32412
|
+
const choiceLabel = typeof flat.choiceLabel === "string" ? flat.choiceLabel : typeof flat.choice === "string" ? flat.choice : typeof flat.value === "string" ? flat.value : void 0;
|
|
32412
32413
|
if (typeof choiceIndex === "number" && Number.isFinite(choiceIndex) || choiceLabel && choiceLabel.trim()) {
|
|
32413
32414
|
return this.selectPickerChoice(ctl, action, choiceIndex, choiceLabel);
|
|
32414
32415
|
}
|
|
@@ -38574,6 +38575,39 @@ function registerProviderScriptRootSafely(root) {
|
|
|
38574
38575
|
} catch {
|
|
38575
38576
|
}
|
|
38576
38577
|
}
|
|
38578
|
+
function synthesizeControlsFromControlBar(specControls) {
|
|
38579
|
+
const out = [];
|
|
38580
|
+
specControls.forEach((ctl, index) => {
|
|
38581
|
+
const id = typeof ctl?.id === "string" ? ctl.id.trim() : "";
|
|
38582
|
+
const actionType = ctl?.action?.type;
|
|
38583
|
+
if (!id || !actionType) return;
|
|
38584
|
+
const label = typeof ctl?.label === "string" && ctl.label.trim() ? ctl.label : id;
|
|
38585
|
+
if (actionType === "open_picker") {
|
|
38586
|
+
out.push({
|
|
38587
|
+
id,
|
|
38588
|
+
type: "select",
|
|
38589
|
+
label,
|
|
38590
|
+
placement: "bar",
|
|
38591
|
+
dynamic: true,
|
|
38592
|
+
listScript: id,
|
|
38593
|
+
setScript: id,
|
|
38594
|
+
readFrom: id,
|
|
38595
|
+
order: index
|
|
38596
|
+
});
|
|
38597
|
+
} else if (actionType === "send_keys") {
|
|
38598
|
+
out.push({
|
|
38599
|
+
id,
|
|
38600
|
+
type: "action",
|
|
38601
|
+
label,
|
|
38602
|
+
placement: "bar",
|
|
38603
|
+
invokeScript: id,
|
|
38604
|
+
resultDisplay: "none",
|
|
38605
|
+
order: index
|
|
38606
|
+
});
|
|
38607
|
+
}
|
|
38608
|
+
});
|
|
38609
|
+
return out;
|
|
38610
|
+
}
|
|
38577
38611
|
var ProviderLoader = class _ProviderLoader {
|
|
38578
38612
|
providers = /* @__PURE__ */ new Map();
|
|
38579
38613
|
providerAvailability = /* @__PURE__ */ new Map();
|
|
@@ -39478,7 +39512,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
39478
39512
|
}
|
|
39479
39513
|
if (providerDir) {
|
|
39480
39514
|
try {
|
|
39481
|
-
const
|
|
39515
|
+
const fs31 = require("fs");
|
|
39482
39516
|
const path41 = require("path");
|
|
39483
39517
|
const candidates = [];
|
|
39484
39518
|
if (Array.isArray(base.compatibility)) {
|
|
@@ -39490,13 +39524,13 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
39490
39524
|
}
|
|
39491
39525
|
candidates.push(path41.join(providerDir, "specs", "default.json"));
|
|
39492
39526
|
candidates.push(path41.join(providerDir, "spec.json"));
|
|
39493
|
-
const specPath = candidates.find((p) =>
|
|
39527
|
+
const specPath = candidates.find((p) => fs31.existsSync(p));
|
|
39494
39528
|
if (specPath) {
|
|
39495
39529
|
resolved._resolvedSpecPath = specPath;
|
|
39496
39530
|
let specControls;
|
|
39497
39531
|
let nh;
|
|
39498
39532
|
try {
|
|
39499
|
-
const rawSpec = JSON.parse(
|
|
39533
|
+
const rawSpec = JSON.parse(fs31.readFileSync(specPath, "utf8"));
|
|
39500
39534
|
specControls = rawSpec.control_bar;
|
|
39501
39535
|
nh = rawSpec.native_history;
|
|
39502
39536
|
} catch {
|
|
@@ -39512,6 +39546,13 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
39512
39546
|
});
|
|
39513
39547
|
}
|
|
39514
39548
|
}
|
|
39549
|
+
const hasDeclaredControls = Array.isArray(resolved.controls) && resolved.controls.length > 0;
|
|
39550
|
+
if (!hasDeclaredControls) {
|
|
39551
|
+
const synthesized = synthesizeControlsFromControlBar(specControls);
|
|
39552
|
+
if (synthesized.length > 0) {
|
|
39553
|
+
resolved.controls = synthesized;
|
|
39554
|
+
}
|
|
39555
|
+
}
|
|
39515
39556
|
}
|
|
39516
39557
|
if (nh) {
|
|
39517
39558
|
let reader = null;
|
|
@@ -39521,7 +39562,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
39521
39562
|
reader = (input) => executeNativeHistory(nh, input);
|
|
39522
39563
|
} else if (nh.override_path) {
|
|
39523
39564
|
const overrideFile = path41.resolve(providerDir, nh.override_path);
|
|
39524
|
-
if (
|
|
39565
|
+
if (fs31.existsSync(overrideFile)) {
|
|
39525
39566
|
try {
|
|
39526
39567
|
registerProviderScriptRootSafely(path41.dirname(path41.dirname(providerDir)));
|
|
39527
39568
|
delete require.cache[require.resolve(overrideFile)];
|
|
@@ -40706,7 +40747,7 @@ async function detectCurrentWorkspace(ideId) {
|
|
|
40706
40747
|
}
|
|
40707
40748
|
} else if (plat === "win32") {
|
|
40708
40749
|
try {
|
|
40709
|
-
const
|
|
40750
|
+
const fs31 = require("fs");
|
|
40710
40751
|
const appNameMap = getMacAppIdentifiers();
|
|
40711
40752
|
const appName = appNameMap[ideId];
|
|
40712
40753
|
if (appName) {
|
|
@@ -40715,8 +40756,8 @@ async function detectCurrentWorkspace(ideId) {
|
|
|
40715
40756
|
appName,
|
|
40716
40757
|
"storage.json"
|
|
40717
40758
|
);
|
|
40718
|
-
if (
|
|
40719
|
-
const data = JSON.parse(
|
|
40759
|
+
if (fs31.existsSync(storagePath)) {
|
|
40760
|
+
const data = JSON.parse(fs31.readFileSync(storagePath, "utf-8"));
|
|
40720
40761
|
const workspaces = data?.openedPathsList?.workspaces3 || data?.openedPathsList?.entries || [];
|
|
40721
40762
|
if (workspaces.length > 0) {
|
|
40722
40763
|
const recent = workspaces[0];
|
|
@@ -41048,6 +41089,210 @@ cleanOldFiles();
|
|
|
41048
41089
|
// src/commands/router.ts
|
|
41049
41090
|
var yaml3 = __toESM(require("js-yaml"));
|
|
41050
41091
|
init_logger();
|
|
41092
|
+
|
|
41093
|
+
// src/logging/log-tail-reader.ts
|
|
41094
|
+
var fs23 = __toESM(require("fs"));
|
|
41095
|
+
init_logger();
|
|
41096
|
+
var DEFAULT_TAIL_BYTES = 64 * 1024;
|
|
41097
|
+
var MAX_TAIL_BYTES = 128 * 1024;
|
|
41098
|
+
var READ_CHUNK_BYTES = 64 * 1024;
|
|
41099
|
+
function resolveLogPath(date) {
|
|
41100
|
+
if (date instanceof Date) return getCurrentDaemonLogPath(date);
|
|
41101
|
+
if (typeof date === "string" && date.trim()) {
|
|
41102
|
+
const parsed = /* @__PURE__ */ new Date(`${date.trim()}T00:00:00.000Z`);
|
|
41103
|
+
if (!Number.isNaN(parsed.getTime())) return getCurrentDaemonLogPath(parsed);
|
|
41104
|
+
}
|
|
41105
|
+
return getCurrentDaemonLogPath();
|
|
41106
|
+
}
|
|
41107
|
+
function clampTailBytes(tailBytes) {
|
|
41108
|
+
if (!Number.isFinite(tailBytes) || tailBytes <= 0) return DEFAULT_TAIL_BYTES;
|
|
41109
|
+
return Math.min(Math.floor(tailBytes), MAX_TAIL_BYTES);
|
|
41110
|
+
}
|
|
41111
|
+
function readByteBoundedTail(filePath, limitBytes) {
|
|
41112
|
+
const fd = fs23.openSync(filePath, "r");
|
|
41113
|
+
try {
|
|
41114
|
+
const stat2 = fs23.fstatSync(fd);
|
|
41115
|
+
const size = stat2.size;
|
|
41116
|
+
if (size === 0) return { text: "", truncated: false, bytesReturned: 0 };
|
|
41117
|
+
const want = Math.min(limitBytes, size);
|
|
41118
|
+
let start = size - want;
|
|
41119
|
+
const truncated = start > 0;
|
|
41120
|
+
const buffers = [];
|
|
41121
|
+
let position = start;
|
|
41122
|
+
while (position < size) {
|
|
41123
|
+
const chunkSize = Math.min(READ_CHUNK_BYTES, size - position);
|
|
41124
|
+
const chunk = Buffer.alloc(chunkSize);
|
|
41125
|
+
fs23.readSync(fd, chunk, 0, chunkSize, position);
|
|
41126
|
+
buffers.push(chunk);
|
|
41127
|
+
position += chunkSize;
|
|
41128
|
+
}
|
|
41129
|
+
let buf = Buffer.concat(buffers);
|
|
41130
|
+
if (truncated) {
|
|
41131
|
+
const firstNewline = buf.indexOf(10);
|
|
41132
|
+
if (firstNewline >= 0) {
|
|
41133
|
+
buf = buf.subarray(firstNewline + 1);
|
|
41134
|
+
}
|
|
41135
|
+
}
|
|
41136
|
+
return { text: buf.toString("utf-8"), truncated, bytesReturned: buf.length };
|
|
41137
|
+
} finally {
|
|
41138
|
+
fs23.closeSync(fd);
|
|
41139
|
+
}
|
|
41140
|
+
}
|
|
41141
|
+
function parseLineEpochMs(line, fileDate) {
|
|
41142
|
+
const m = line.match(/^\[(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,3}))?\]/);
|
|
41143
|
+
if (!m) {
|
|
41144
|
+
const iso = line.match(/\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(?:\.\d+)?/);
|
|
41145
|
+
if (iso) {
|
|
41146
|
+
const t = Date.parse(iso[0].replace(" ", "T"));
|
|
41147
|
+
return Number.isNaN(t) ? null : t;
|
|
41148
|
+
}
|
|
41149
|
+
return null;
|
|
41150
|
+
}
|
|
41151
|
+
const d = new Date(fileDate);
|
|
41152
|
+
d.setHours(Number(m[1]), Number(m[2]), Number(m[3]), m[4] ? Number(m[4].padEnd(3, "0")) : 0);
|
|
41153
|
+
return d.getTime();
|
|
41154
|
+
}
|
|
41155
|
+
function readDaemonLogTail(args = {}) {
|
|
41156
|
+
const platform10 = process.platform;
|
|
41157
|
+
const limitBytes = clampTailBytes(args.tailBytes);
|
|
41158
|
+
let logPath = resolveLogPath(args.date);
|
|
41159
|
+
if (!fs23.existsSync(logPath)) {
|
|
41160
|
+
const backup = logPath.replace(/\.log$/, ".1.log");
|
|
41161
|
+
if (fs23.existsSync(backup)) {
|
|
41162
|
+
logPath = backup;
|
|
41163
|
+
} else {
|
|
41164
|
+
return {
|
|
41165
|
+
success: false,
|
|
41166
|
+
error: `No daemon log file at ${logPath} (dir: ${getDaemonLogDir()})`,
|
|
41167
|
+
lines: [],
|
|
41168
|
+
truncated: false,
|
|
41169
|
+
logPath,
|
|
41170
|
+
platform: platform10,
|
|
41171
|
+
bytesReturned: 0,
|
|
41172
|
+
filtered: false
|
|
41173
|
+
};
|
|
41174
|
+
}
|
|
41175
|
+
}
|
|
41176
|
+
let raw;
|
|
41177
|
+
try {
|
|
41178
|
+
raw = readByteBoundedTail(logPath, limitBytes);
|
|
41179
|
+
} catch (e) {
|
|
41180
|
+
return {
|
|
41181
|
+
success: false,
|
|
41182
|
+
error: `Failed to read ${logPath}: ${e?.message ?? String(e)}`,
|
|
41183
|
+
lines: [],
|
|
41184
|
+
truncated: false,
|
|
41185
|
+
logPath,
|
|
41186
|
+
platform: platform10,
|
|
41187
|
+
bytesReturned: 0,
|
|
41188
|
+
filtered: false
|
|
41189
|
+
};
|
|
41190
|
+
}
|
|
41191
|
+
let lines = raw.text.split("\n");
|
|
41192
|
+
if (lines.length && lines[lines.length - 1] === "") lines.pop();
|
|
41193
|
+
const rawCount = lines.length;
|
|
41194
|
+
if (Number.isFinite(args.sinceMs)) {
|
|
41195
|
+
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();
|
|
41196
|
+
const floor = args.sinceMs;
|
|
41197
|
+
lines = lines.filter((line) => {
|
|
41198
|
+
const ts2 = parseLineEpochMs(line, fileDate);
|
|
41199
|
+
return ts2 === null || ts2 >= floor;
|
|
41200
|
+
});
|
|
41201
|
+
}
|
|
41202
|
+
let appliedGrep;
|
|
41203
|
+
if (typeof args.grep === "string" && args.grep.trim()) {
|
|
41204
|
+
appliedGrep = args.grep.trim();
|
|
41205
|
+
let re = null;
|
|
41206
|
+
try {
|
|
41207
|
+
re = new RegExp(appliedGrep, "i");
|
|
41208
|
+
} catch {
|
|
41209
|
+
re = null;
|
|
41210
|
+
}
|
|
41211
|
+
if (re) {
|
|
41212
|
+
const compiled = re;
|
|
41213
|
+
lines = lines.filter((line) => compiled.test(line));
|
|
41214
|
+
} else {
|
|
41215
|
+
const needle = appliedGrep.toLowerCase();
|
|
41216
|
+
lines = lines.filter((line) => line.toLowerCase().includes(needle));
|
|
41217
|
+
}
|
|
41218
|
+
}
|
|
41219
|
+
return {
|
|
41220
|
+
success: true,
|
|
41221
|
+
lines,
|
|
41222
|
+
truncated: raw.truncated,
|
|
41223
|
+
logPath,
|
|
41224
|
+
platform: platform10,
|
|
41225
|
+
bytesReturned: raw.bytesReturned,
|
|
41226
|
+
filtered: lines.length !== rawCount,
|
|
41227
|
+
...appliedGrep ? { grep: appliedGrep } : {}
|
|
41228
|
+
};
|
|
41229
|
+
}
|
|
41230
|
+
|
|
41231
|
+
// src/logging/log-redactor.ts
|
|
41232
|
+
var MASK = "\u2022\u2022\u2022\u2022redacted";
|
|
41233
|
+
function maskKeepTail(token) {
|
|
41234
|
+
if (token.length <= 8) return MASK;
|
|
41235
|
+
return `${MASK}${token.slice(-4)}`;
|
|
41236
|
+
}
|
|
41237
|
+
var RULES = [
|
|
41238
|
+
// `JWT_SECRET=...`, `TOKEN=...`, `API_KEY=...`, `password: ...` env/config dumps.
|
|
41239
|
+
// Captures the key + delimiter and masks only the value.
|
|
41240
|
+
{
|
|
41241
|
+
name: "key_value_secret",
|
|
41242
|
+
pattern: /\b([A-Z0-9_]*(?:SECRET|TOKEN|API[_-]?KEY|PASSWORD|PASSWD|PRIVATE[_-]?KEY|CREDENTIAL|CLIENT[_-]?SECRET)[A-Z0-9_]*)(\s*[:=]\s*)(["']?)([^\s"',;]+)\3/gi,
|
|
41243
|
+
replace: (_m, key, delim, quote) => `${key}${delim}${quote}${MASK}${quote}`
|
|
41244
|
+
},
|
|
41245
|
+
// Authorization: Bearer <token>
|
|
41246
|
+
{
|
|
41247
|
+
name: "bearer_token",
|
|
41248
|
+
pattern: /\b(Bearer\s+)([A-Za-z0-9._\-+/=]{8,})/g,
|
|
41249
|
+
replace: (_m, prefix, token) => `${prefix}${maskKeepTail(token)}`
|
|
41250
|
+
},
|
|
41251
|
+
// ADHDev credential prefixes: API key (adk_), machine secret (adm_), provider key (adp_).
|
|
41252
|
+
{
|
|
41253
|
+
name: "adhdev_prefixed_secret",
|
|
41254
|
+
pattern: /\b(ad[kmp]_)([A-Za-z0-9]{6,})/g,
|
|
41255
|
+
replace: (_m, prefix, token) => `${prefix}${maskKeepTail(prefix + token)}`
|
|
41256
|
+
},
|
|
41257
|
+
// JWT: three base64url segments separated by dots, header starts with eyJ.
|
|
41258
|
+
{
|
|
41259
|
+
name: "jwt",
|
|
41260
|
+
pattern: /\beyJ[A-Za-z0-9_-]{4,}\.[A-Za-z0-9_-]{4,}\.[A-Za-z0-9_-]{4,}/g,
|
|
41261
|
+
replace: () => MASK
|
|
41262
|
+
},
|
|
41263
|
+
// TURN credential: a long credential value following a `credential` key in
|
|
41264
|
+
// any common shape — `credential: x`, `credential=x`, or `credential "x"`.
|
|
41265
|
+
// Mask the credential value only, preserving the key + delimiter/quote.
|
|
41266
|
+
{
|
|
41267
|
+
name: "turn_credential",
|
|
41268
|
+
pattern: /\b(credential["']?\s*(?:[:=]\s*)?["']?)([^\s"',;]{6,})/gi,
|
|
41269
|
+
replace: (_m, prefix) => `${prefix}${MASK}`
|
|
41270
|
+
},
|
|
41271
|
+
// TURN REST username:credential of the form `<expiry-ts>:<base64hmac>`,
|
|
41272
|
+
// where the hmac part is long base64. Mask the hmac.
|
|
41273
|
+
{
|
|
41274
|
+
name: "turn_rest_pair",
|
|
41275
|
+
pattern: /\b(\d{10,}:)([A-Za-z0-9+/]{20,}={0,2})\b/g,
|
|
41276
|
+
replace: (_m, prefix) => `${prefix}${MASK}`
|
|
41277
|
+
}
|
|
41278
|
+
];
|
|
41279
|
+
function redactLogLine(line) {
|
|
41280
|
+
if (!line) return line;
|
|
41281
|
+
let out = line;
|
|
41282
|
+
for (const rule of RULES) {
|
|
41283
|
+
try {
|
|
41284
|
+
out = out.replace(rule.pattern, rule.replace);
|
|
41285
|
+
} catch {
|
|
41286
|
+
}
|
|
41287
|
+
}
|
|
41288
|
+
return out;
|
|
41289
|
+
}
|
|
41290
|
+
function redactLogLines(lines) {
|
|
41291
|
+
return lines.map((line) => redactLogLine(line));
|
|
41292
|
+
}
|
|
41293
|
+
var LOG_REDACTION_RULE_NAMES = RULES.map((r) => r.name);
|
|
41294
|
+
|
|
41295
|
+
// src/commands/router.ts
|
|
41051
41296
|
init_mesh_coordinator();
|
|
41052
41297
|
init_mesh_events();
|
|
41053
41298
|
init_mesh_routing();
|
|
@@ -41692,21 +41937,21 @@ init_build_info();
|
|
|
41692
41937
|
// src/commands/upgrade-helper.ts
|
|
41693
41938
|
var import_child_process8 = require("child_process");
|
|
41694
41939
|
var import_child_process9 = require("child_process");
|
|
41695
|
-
var
|
|
41940
|
+
var fs24 = __toESM(require("fs"));
|
|
41696
41941
|
var os27 = __toESM(require("os"));
|
|
41697
41942
|
var path35 = __toESM(require("path"));
|
|
41698
41943
|
var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
|
|
41699
41944
|
function getUpgradeLogPath() {
|
|
41700
41945
|
const home = os27.homedir();
|
|
41701
41946
|
const dir = path35.join(home, ".adhdev");
|
|
41702
|
-
|
|
41947
|
+
fs24.mkdirSync(dir, { recursive: true });
|
|
41703
41948
|
return path35.join(dir, "daemon-upgrade.log");
|
|
41704
41949
|
}
|
|
41705
41950
|
function appendUpgradeLog(message) {
|
|
41706
41951
|
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
|
|
41707
41952
|
`;
|
|
41708
41953
|
try {
|
|
41709
|
-
|
|
41954
|
+
fs24.appendFileSync(getUpgradeLogPath(), line, "utf8");
|
|
41710
41955
|
} catch {
|
|
41711
41956
|
}
|
|
41712
41957
|
}
|
|
@@ -41714,12 +41959,12 @@ function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platfo
|
|
|
41714
41959
|
const binDir = path35.dirname(nodeExecutable);
|
|
41715
41960
|
if (platform10 === "win32") {
|
|
41716
41961
|
const npmCliPath = path35.join(binDir, "node_modules", "npm", "bin", "npm-cli.js");
|
|
41717
|
-
if (
|
|
41962
|
+
if (fs24.existsSync(npmCliPath)) {
|
|
41718
41963
|
return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
|
|
41719
41964
|
}
|
|
41720
41965
|
for (const candidate of ["npm.exe", "npm"]) {
|
|
41721
41966
|
const candidatePath = path35.join(binDir, candidate);
|
|
41722
|
-
if (
|
|
41967
|
+
if (fs24.existsSync(candidatePath)) {
|
|
41723
41968
|
return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
|
|
41724
41969
|
}
|
|
41725
41970
|
}
|
|
@@ -41727,7 +41972,7 @@ function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platfo
|
|
|
41727
41972
|
}
|
|
41728
41973
|
for (const candidate of ["npm"]) {
|
|
41729
41974
|
const candidatePath = path35.join(binDir, candidate);
|
|
41730
|
-
if (
|
|
41975
|
+
if (fs24.existsSync(candidatePath)) {
|
|
41731
41976
|
return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
|
|
41732
41977
|
}
|
|
41733
41978
|
}
|
|
@@ -41737,12 +41982,12 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
41737
41982
|
if (!currentCliPath) return null;
|
|
41738
41983
|
let resolvedPath = currentCliPath;
|
|
41739
41984
|
try {
|
|
41740
|
-
resolvedPath =
|
|
41985
|
+
resolvedPath = fs24.realpathSync.native(currentCliPath);
|
|
41741
41986
|
} catch {
|
|
41742
41987
|
}
|
|
41743
41988
|
let currentDir = resolvedPath;
|
|
41744
41989
|
try {
|
|
41745
|
-
if (
|
|
41990
|
+
if (fs24.statSync(resolvedPath).isFile()) {
|
|
41746
41991
|
currentDir = path35.dirname(resolvedPath);
|
|
41747
41992
|
}
|
|
41748
41993
|
} catch {
|
|
@@ -41751,8 +41996,8 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
41751
41996
|
while (true) {
|
|
41752
41997
|
const packageJsonPath = path35.join(currentDir, "package.json");
|
|
41753
41998
|
try {
|
|
41754
|
-
if (
|
|
41755
|
-
const parsed = JSON.parse(
|
|
41999
|
+
if (fs24.existsSync(packageJsonPath)) {
|
|
42000
|
+
const parsed = JSON.parse(fs24.readFileSync(packageJsonPath, "utf8"));
|
|
41756
42001
|
if (parsed?.name === packageName) {
|
|
41757
42002
|
const normalized = currentDir.replace(/\\/g, "/");
|
|
41758
42003
|
return normalized.includes("/node_modules/") ? currentDir : null;
|
|
@@ -41901,8 +42146,8 @@ async function waitForPidExit(pid, timeoutMs) {
|
|
|
41901
42146
|
function stopSessionHostProcesses(appName) {
|
|
41902
42147
|
const pidFile = path35.join(os27.homedir(), ".adhdev", `${appName}-session-host.pid`);
|
|
41903
42148
|
try {
|
|
41904
|
-
if (
|
|
41905
|
-
const pid = Number.parseInt(
|
|
42149
|
+
if (fs24.existsSync(pidFile)) {
|
|
42150
|
+
const pid = Number.parseInt(fs24.readFileSync(pidFile, "utf8").trim(), 10);
|
|
41906
42151
|
if (Number.isFinite(pid) && pid !== process.pid && isManagedSessionHostPid(pid)) {
|
|
41907
42152
|
killPid(pid);
|
|
41908
42153
|
}
|
|
@@ -41910,7 +42155,7 @@ function stopSessionHostProcesses(appName) {
|
|
|
41910
42155
|
} catch {
|
|
41911
42156
|
} finally {
|
|
41912
42157
|
try {
|
|
41913
|
-
|
|
42158
|
+
fs24.unlinkSync(pidFile);
|
|
41914
42159
|
} catch {
|
|
41915
42160
|
}
|
|
41916
42161
|
}
|
|
@@ -41918,7 +42163,7 @@ function stopSessionHostProcesses(appName) {
|
|
|
41918
42163
|
function removeDaemonPidFile() {
|
|
41919
42164
|
const pidFile = path35.join(os27.homedir(), ".adhdev", "daemon.pid");
|
|
41920
42165
|
try {
|
|
41921
|
-
|
|
42166
|
+
fs24.unlinkSync(pidFile);
|
|
41922
42167
|
} catch {
|
|
41923
42168
|
}
|
|
41924
42169
|
}
|
|
@@ -41936,23 +42181,23 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
|
|
|
41936
42181
|
if (pkgName.startsWith("@")) {
|
|
41937
42182
|
const [scope, name] = pkgName.split("/");
|
|
41938
42183
|
const scopeDir = path35.join(npmRoot, scope);
|
|
41939
|
-
if (!
|
|
41940
|
-
for (const entry of
|
|
42184
|
+
if (!fs24.existsSync(scopeDir)) return;
|
|
42185
|
+
for (const entry of fs24.readdirSync(scopeDir)) {
|
|
41941
42186
|
if (!entry.startsWith(`.${name}-`)) continue;
|
|
41942
|
-
|
|
42187
|
+
fs24.rmSync(path35.join(scopeDir, entry), { recursive: true, force: true });
|
|
41943
42188
|
appendUpgradeLog(`Removed stale scoped staging dir: ${path35.join(scopeDir, entry)}`);
|
|
41944
42189
|
}
|
|
41945
42190
|
} else {
|
|
41946
|
-
for (const entry of
|
|
42191
|
+
for (const entry of fs24.readdirSync(npmRoot)) {
|
|
41947
42192
|
if (!entry.startsWith(`.${pkgName}-`)) continue;
|
|
41948
|
-
|
|
42193
|
+
fs24.rmSync(path35.join(npmRoot, entry), { recursive: true, force: true });
|
|
41949
42194
|
appendUpgradeLog(`Removed stale staging dir: ${path35.join(npmRoot, entry)}`);
|
|
41950
42195
|
}
|
|
41951
42196
|
}
|
|
41952
|
-
if (
|
|
41953
|
-
for (const entry of
|
|
42197
|
+
if (fs24.existsSync(binDir)) {
|
|
42198
|
+
for (const entry of fs24.readdirSync(binDir)) {
|
|
41954
42199
|
if (!Array.from(binNames).some((name) => entry.startsWith(`.${name}-`))) continue;
|
|
41955
|
-
|
|
42200
|
+
fs24.rmSync(path35.join(binDir, entry), { recursive: true, force: true });
|
|
41956
42201
|
appendUpgradeLog(`Removed stale bin staging entry: ${path35.join(binDir, entry)}`);
|
|
41957
42202
|
}
|
|
41958
42203
|
}
|
|
@@ -42043,7 +42288,7 @@ init_mesh_work_queue();
|
|
|
42043
42288
|
init_repo_mesh_types();
|
|
42044
42289
|
var import_os3 = require("os");
|
|
42045
42290
|
var import_path11 = require("path");
|
|
42046
|
-
var
|
|
42291
|
+
var fs25 = __toESM(require("fs"));
|
|
42047
42292
|
var import_node_child_process6 = require("child_process");
|
|
42048
42293
|
var CHANNEL_NPM_TAG = { stable: "latest", preview: "next" };
|
|
42049
42294
|
var CHANNEL_SERVER_URL = {
|
|
@@ -42369,6 +42614,12 @@ function inlineMeshCarriesTransientNodeTruth(inlineMesh) {
|
|
|
42369
42614
|
function readInlineMeshNodeId(node) {
|
|
42370
42615
|
return normalizeMeshNodeId(node) ?? "";
|
|
42371
42616
|
}
|
|
42617
|
+
function isDeadLocalWorktreeNode(node) {
|
|
42618
|
+
if (node?.isLocalWorktree !== true) return false;
|
|
42619
|
+
const workspace = readStringValue(node?.workspace);
|
|
42620
|
+
if (!workspace) return false;
|
|
42621
|
+
return !fs25.existsSync(workspace);
|
|
42622
|
+
}
|
|
42372
42623
|
function foldMeshNodeIdentityToCanonical(node) {
|
|
42373
42624
|
if (!node || typeof node !== "object" || Array.isArray(node)) return node;
|
|
42374
42625
|
const canonical = normalizeMeshNodeId(node);
|
|
@@ -42615,7 +42866,7 @@ function summarizeInlineMeshBranchConvergence(nodes) {
|
|
|
42615
42866
|
const followUps = nodes.filter((node) => {
|
|
42616
42867
|
if (readObjectRecord(node.branchConvergence).needsConvergence !== true) return false;
|
|
42617
42868
|
const workspace = typeof node.workspace === "string" ? node.workspace : "";
|
|
42618
|
-
if (workspace && !
|
|
42869
|
+
if (workspace && !fs25.existsSync(workspace)) return false;
|
|
42619
42870
|
return true;
|
|
42620
42871
|
}).map((node) => {
|
|
42621
42872
|
const convergence = readObjectRecord(node.branchConvergence);
|
|
@@ -42823,7 +43074,8 @@ async function hydrateInlineMeshDirectTruth(args) {
|
|
|
42823
43074
|
peerAttemptedCount: 0,
|
|
42824
43075
|
peerConfirmedCount: 0,
|
|
42825
43076
|
standingEvidenceCount: 0,
|
|
42826
|
-
unavailableNodeIds: []
|
|
43077
|
+
unavailableNodeIds: [],
|
|
43078
|
+
deadNodeIds: []
|
|
42827
43079
|
};
|
|
42828
43080
|
}
|
|
42829
43081
|
const selectedCoordinatorNodeId = readStringValue(
|
|
@@ -42836,6 +43088,7 @@ async function hydrateInlineMeshDirectTruth(args) {
|
|
|
42836
43088
|
let peerConfirmedCount = 0;
|
|
42837
43089
|
let standingEvidenceCount = 0;
|
|
42838
43090
|
const unavailableNodeIds = [];
|
|
43091
|
+
const deadNodeIds = [];
|
|
42839
43092
|
for (const [nodeIndex, node] of nodes.entries()) {
|
|
42840
43093
|
const nodeId = normalizeMeshNodeId(node) || `node_${nodeIndex}`;
|
|
42841
43094
|
const workspace = readStringValue(node?.workspace);
|
|
@@ -42845,11 +43098,18 @@ async function hydrateInlineMeshDirectTruth(args) {
|
|
|
42845
43098
|
) || Boolean(
|
|
42846
43099
|
daemonId && (daemonId === args.localMachineId || daemonId === args.statusInstanceId)
|
|
42847
43100
|
) || Boolean(args.meshSource !== "local_config" && nodeIndex === 0);
|
|
43101
|
+
const isSelfDaemonNode = Boolean(
|
|
43102
|
+
daemonId && (daemonId === args.localMachineId || daemonId === args.statusInstanceId)
|
|
43103
|
+
);
|
|
43104
|
+
if ((isSelfNode || isSelfDaemonNode) && isDeadLocalWorktreeNode(node)) {
|
|
43105
|
+
deadNodeIds.push(nodeId);
|
|
43106
|
+
continue;
|
|
43107
|
+
}
|
|
42848
43108
|
if (!workspace) {
|
|
42849
43109
|
if (!isSelfNode && daemonId) unavailableNodeIds.push(nodeId);
|
|
42850
43110
|
continue;
|
|
42851
43111
|
}
|
|
42852
|
-
if (
|
|
43112
|
+
if (fs25.existsSync(workspace)) {
|
|
42853
43113
|
try {
|
|
42854
43114
|
const localGit = await getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
|
|
42855
43115
|
if (localGit?.isGitRepo) {
|
|
@@ -42895,7 +43155,8 @@ async function hydrateInlineMeshDirectTruth(args) {
|
|
|
42895
43155
|
peerAttemptedCount,
|
|
42896
43156
|
peerConfirmedCount,
|
|
42897
43157
|
standingEvidenceCount,
|
|
42898
|
-
unavailableNodeIds
|
|
43158
|
+
unavailableNodeIds,
|
|
43159
|
+
deadNodeIds
|
|
42899
43160
|
};
|
|
42900
43161
|
}
|
|
42901
43162
|
function summarizeMeshSessionRecord(record) {
|
|
@@ -42954,7 +43215,7 @@ function readLiveMeshNodeWorkspace(args) {
|
|
|
42954
43215
|
}
|
|
42955
43216
|
function collectLiveMeshSessionRecords(args) {
|
|
42956
43217
|
const nodeWorkspace = readStringValue(args.node?.workspace);
|
|
42957
|
-
const nodeIsMissingLocalWorktree = args.node?.isLocalWorktree === true && !!nodeWorkspace && !
|
|
43218
|
+
const nodeIsMissingLocalWorktree = args.node?.isLocalWorktree === true && !!nodeWorkspace && !fs25.existsSync(nodeWorkspace);
|
|
42958
43219
|
const matches = args.liveSessionRecords.filter((record) => {
|
|
42959
43220
|
const recordNodeId = readStringValue(record?.meta?.meshNodeId);
|
|
42960
43221
|
if (recordNodeId && recordNodeId !== args.nodeId) return false;
|
|
@@ -42981,7 +43242,7 @@ function buildHistoricalMeshSessions(args) {
|
|
|
42981
43242
|
const workspace = readStringValue(node?.workspace);
|
|
42982
43243
|
if (nodeId) liveNodeIds.add(nodeId);
|
|
42983
43244
|
if (workspace) liveWorkspaces.add(workspace);
|
|
42984
|
-
if (nodeId && node?.isLocalWorktree === true && workspace && !
|
|
43245
|
+
if (nodeId && node?.isLocalWorktree === true && workspace && !fs25.existsSync(workspace)) {
|
|
42985
43246
|
missingLocalWorktreeNodeIds.add(nodeId);
|
|
42986
43247
|
}
|
|
42987
43248
|
}
|
|
@@ -43341,7 +43602,7 @@ function isSubmoduleFastForward(submoduleRepoPath, baseCommit, branchCommit) {
|
|
|
43341
43602
|
if (!baseCommit || !branchCommit) return false;
|
|
43342
43603
|
if (baseCommit === branchCommit) return true;
|
|
43343
43604
|
try {
|
|
43344
|
-
if (!
|
|
43605
|
+
if (!fs25.existsSync(submoduleRepoPath)) return false;
|
|
43345
43606
|
(0, import_node_child_process6.execFileSync)("git", ["cat-file", "-e", `${baseCommit}^{commit}`], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
43346
43607
|
(0, import_node_child_process6.execFileSync)("git", ["cat-file", "-e", `${branchCommit}^{commit}`], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
43347
43608
|
(0, import_node_child_process6.execFileSync)("git", ["merge-base", "--is-ancestor", baseCommit, branchCommit], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
@@ -43458,7 +43719,7 @@ function buildTreeWithGitlinksEqualized(repoRoot, commitish, paths, placeholderC
|
|
|
43458
43719
|
return newTree || void 0;
|
|
43459
43720
|
} finally {
|
|
43460
43721
|
try {
|
|
43461
|
-
|
|
43722
|
+
fs25.rmSync(tmpIndex, { force: true });
|
|
43462
43723
|
} catch {
|
|
43463
43724
|
}
|
|
43464
43725
|
}
|
|
@@ -43533,7 +43794,7 @@ function synthesizeTrivialFastForwardMergeTree(repoRoot, baseHead, branchHead, g
|
|
|
43533
43794
|
return newTree || void 0;
|
|
43534
43795
|
} finally {
|
|
43535
43796
|
try {
|
|
43536
|
-
|
|
43797
|
+
fs25.rmSync(tmpIndex, { force: true });
|
|
43537
43798
|
} catch {
|
|
43538
43799
|
}
|
|
43539
43800
|
}
|
|
@@ -43639,7 +43900,7 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
43639
43900
|
return { stdout: String(stdout || ""), stderr: String(stderr || ""), refspec };
|
|
43640
43901
|
};
|
|
43641
43902
|
const importCommitFromWorktreeSubmodule = async (submodulePath, worktreeSubmodulePath, commit) => {
|
|
43642
|
-
if (!
|
|
43903
|
+
if (!fs25.existsSync(worktreeSubmodulePath)) return false;
|
|
43643
43904
|
try {
|
|
43644
43905
|
await runGit3(worktreeSubmodulePath, ["cat-file", "-e", `${commit}^{commit}`]);
|
|
43645
43906
|
} catch {
|
|
@@ -43662,7 +43923,7 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
43662
43923
|
reachable: false
|
|
43663
43924
|
};
|
|
43664
43925
|
try {
|
|
43665
|
-
if (!
|
|
43926
|
+
if (!fs25.existsSync(submodulePath)) {
|
|
43666
43927
|
entry.error = `Submodule checkout missing at ${gitlink.path}`;
|
|
43667
43928
|
entry.publishRequired = true;
|
|
43668
43929
|
if (options.allowAutoPublishSubmoduleMainCommits === true) {
|
|
@@ -43899,9 +44160,9 @@ async function runMeshRefineValidationGate(mesh, workspace, opts) {
|
|
|
43899
44160
|
return ["npm", "pnpm", "yarn", "bun"].includes(command) && candidate.args.some((arg) => arg === "run" || arg === "test" || arg === "exec");
|
|
43900
44161
|
};
|
|
43901
44162
|
const dependenciesLikelyMissing = (cwd) => {
|
|
43902
|
-
if (!
|
|
43903
|
-
if (
|
|
43904
|
-
return ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"].some((lock) =>
|
|
44163
|
+
if (!fs25.existsSync((0, import_path11.join)(cwd, "package.json"))) return false;
|
|
44164
|
+
if (fs25.existsSync((0, import_path11.join)(cwd, "node_modules"))) return false;
|
|
44165
|
+
return ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"].some((lock) => fs25.existsSync((0, import_path11.join)(cwd, lock)));
|
|
43905
44166
|
};
|
|
43906
44167
|
if (runLegacyBootstrapCommands) {
|
|
43907
44168
|
summary.bootstrap = { stage: "legacy" };
|
|
@@ -44003,9 +44264,9 @@ function resolveHermesUserHome() {
|
|
|
44003
44264
|
function loadHermesCoordinatorBaseConfig(targetConfigPath) {
|
|
44004
44265
|
const sourceHome = resolveHermesUserHome();
|
|
44005
44266
|
const sourceConfigPath = (0, import_path11.join)(sourceHome, "config.yaml");
|
|
44006
|
-
if (!
|
|
44267
|
+
if (!fs25.existsSync(sourceConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
44007
44268
|
if ((0, import_path11.resolve)(sourceConfigPath) === (0, import_path11.resolve)(targetConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
44008
|
-
const parsed = parseMeshCoordinatorMcpConfig(
|
|
44269
|
+
const parsed = parseMeshCoordinatorMcpConfig(fs25.readFileSync(sourceConfigPath, "utf-8"), "hermes_config_yaml");
|
|
44009
44270
|
const { mcp_servers: _mcpServers, ...baseConfig } = parsed;
|
|
44010
44271
|
return { config: baseConfig, sourceHome, sourceConfigPath };
|
|
44011
44272
|
}
|
|
@@ -44042,9 +44303,9 @@ function copyHermesCoordinatorCredentialFiles(sourceHome, targetHome) {
|
|
|
44042
44303
|
for (const fileName of [".env", "auth.json"]) {
|
|
44043
44304
|
const sourcePath = (0, import_path11.join)(sourceHome, fileName);
|
|
44044
44305
|
const targetPath = (0, import_path11.join)(targetHome, fileName);
|
|
44045
|
-
if (!
|
|
44306
|
+
if (!fs25.existsSync(sourcePath)) continue;
|
|
44046
44307
|
try {
|
|
44047
|
-
|
|
44308
|
+
fs25.copyFileSync(sourcePath, targetPath);
|
|
44048
44309
|
} catch (error) {
|
|
44049
44310
|
LOG.warn("MeshCoordinator", `Could not copy Hermes ${fileName} into isolated coordinator home: ${error?.message || error}`);
|
|
44050
44311
|
}
|
|
@@ -44202,6 +44463,15 @@ var DaemonCommandRouter = class {
|
|
|
44202
44463
|
* Allows the MCP server to query mesh data via get_mesh even when
|
|
44203
44464
|
* the mesh doesn't exist in the local meshes.json file. */
|
|
44204
44465
|
inlineMeshCache = /* @__PURE__ */ new Map();
|
|
44466
|
+
/** Tombstones for inline mesh nodes removed via remove_mesh_node, keyed by
|
|
44467
|
+
* meshId → set of removed nodeIds. The dashboard keeps echoing the removed
|
|
44468
|
+
* node in the inlineMesh it attaches to every command; without a tombstone,
|
|
44469
|
+
* reconcileInlineMeshCache MERGEs it straight back (resurrection). A
|
|
44470
|
+
* tombstoned node is skipped during reconcile only while its workspace is
|
|
44471
|
+
* absent from disk — a genuine re-registration (same nodeId, workspace back
|
|
44472
|
+
* on disk) clears the tombstone and merges normally, preserving clone
|
|
44473
|
+
* worktree visibility and legitimate node re-creation. */
|
|
44474
|
+
removedInlineMeshNodeIds = /* @__PURE__ */ new Map();
|
|
44205
44475
|
/** Coordinator-owned whole-mesh aggregate status snapshots. Browser callers read this by default. */
|
|
44206
44476
|
aggregateMeshStatusCache = /* @__PURE__ */ new Map();
|
|
44207
44477
|
/** Shared per-peer git_status probe dedup + recently-probed reuse gate.
|
|
@@ -44235,10 +44505,23 @@ var DaemonCommandRouter = class {
|
|
|
44235
44505
|
const unavailableNodeIds = /* @__PURE__ */ new Set();
|
|
44236
44506
|
const sourceOfTruth = readObjectRecord(snapshot.sourceOfTruth);
|
|
44237
44507
|
const directPeerTruth = readObjectRecord(sourceOfTruth.directPeerTruth);
|
|
44508
|
+
const deadNodeIds = /* @__PURE__ */ new Set();
|
|
44509
|
+
for (const node of mesh.nodes) {
|
|
44510
|
+
if (!isDeadLocalWorktreeNode(node)) continue;
|
|
44511
|
+
const deadId = readInlineMeshNodeId(node);
|
|
44512
|
+
if (deadId) deadNodeIds.add(deadId);
|
|
44513
|
+
}
|
|
44514
|
+
let droppedDeadUnavailable = false;
|
|
44238
44515
|
for (const entry of Array.isArray(directPeerTruth.unavailableNodeIds) ? directPeerTruth.unavailableNodeIds : []) {
|
|
44239
44516
|
const nodeId = readStringValue(entry);
|
|
44240
|
-
if (nodeId)
|
|
44517
|
+
if (!nodeId) continue;
|
|
44518
|
+
if (deadNodeIds.has(nodeId)) {
|
|
44519
|
+
droppedDeadUnavailable = true;
|
|
44520
|
+
continue;
|
|
44521
|
+
}
|
|
44522
|
+
unavailableNodeIds.add(nodeId);
|
|
44241
44523
|
}
|
|
44524
|
+
if (droppedDeadUnavailable) changed = true;
|
|
44242
44525
|
const nodes = snapshot.nodes.map((statusNode) => {
|
|
44243
44526
|
const nodeId = normalizeMeshNodeId(statusNode);
|
|
44244
44527
|
const inlineNode = nodeId ? inlineNodesById.get(nodeId) : void 0;
|
|
@@ -44353,7 +44636,10 @@ var DaemonCommandRouter = class {
|
|
|
44353
44636
|
}
|
|
44354
44637
|
warmInlineMeshCache(meshId, inlineMesh) {
|
|
44355
44638
|
if (!inlineMesh || typeof inlineMesh !== "object") return void 0;
|
|
44356
|
-
const sanitizedInlineMesh =
|
|
44639
|
+
const sanitizedInlineMesh = this.applyInlineMeshNodeTombstones(
|
|
44640
|
+
meshId,
|
|
44641
|
+
sanitizeInlineMesh(normalizeInlineMeshNodeIdentity(inlineMesh))
|
|
44642
|
+
);
|
|
44357
44643
|
const cached2 = this.inlineMeshCache.get(meshId);
|
|
44358
44644
|
if (cached2) {
|
|
44359
44645
|
const merged = reconcileInlineMeshCache(cached2, sanitizedInlineMesh);
|
|
@@ -44369,7 +44655,10 @@ var DaemonCommandRouter = class {
|
|
|
44369
44655
|
const cached3 = this.getCachedInlineMesh(meshId);
|
|
44370
44656
|
if (cached3) {
|
|
44371
44657
|
if (inlineMeshCarriesTransientNodeTruth(inlineMesh)) {
|
|
44372
|
-
const merged = reconcileInlineMeshCache(
|
|
44658
|
+
const merged = reconcileInlineMeshCache(
|
|
44659
|
+
cached3,
|
|
44660
|
+
this.applyInlineMeshNodeTombstones(meshId, inlineMesh)
|
|
44661
|
+
);
|
|
44373
44662
|
this.inlineMeshCache.set(meshId, sanitizeInlineMesh(normalizeInlineMeshNodeIdentity(merged)));
|
|
44374
44663
|
return { mesh: merged, inline: true, source: "inline_cache" };
|
|
44375
44664
|
}
|
|
@@ -44420,12 +44709,49 @@ var DaemonCommandRouter = class {
|
|
|
44420
44709
|
if (!mesh || !Array.isArray(mesh.nodes)) return false;
|
|
44421
44710
|
const idx = mesh.nodes.findIndex((entry) => meshNodeIdMatches(entry, nodeId));
|
|
44422
44711
|
if (idx === -1) return false;
|
|
44712
|
+
const canonicalNodeId = readInlineMeshNodeId(mesh.nodes[idx]) || nodeId;
|
|
44423
44713
|
mesh.nodes.splice(idx, 1);
|
|
44424
44714
|
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
44425
44715
|
this.inlineMeshCache.set(meshId, mesh);
|
|
44716
|
+
this.tombstoneRemovedInlineMeshNode(meshId, canonicalNodeId);
|
|
44717
|
+
if (canonicalNodeId !== nodeId) this.tombstoneRemovedInlineMeshNode(meshId, nodeId);
|
|
44426
44718
|
this.invalidateAggregateMeshStatus(meshId);
|
|
44427
44719
|
return true;
|
|
44428
44720
|
}
|
|
44721
|
+
tombstoneRemovedInlineMeshNode(meshId, nodeId) {
|
|
44722
|
+
if (!nodeId) return;
|
|
44723
|
+
let set = this.removedInlineMeshNodeIds.get(meshId);
|
|
44724
|
+
if (!set) {
|
|
44725
|
+
set = /* @__PURE__ */ new Set();
|
|
44726
|
+
this.removedInlineMeshNodeIds.set(meshId, set);
|
|
44727
|
+
}
|
|
44728
|
+
set.add(nodeId);
|
|
44729
|
+
}
|
|
44730
|
+
/** Filter an incoming inline mesh against this mesh's tombstones before it is
|
|
44731
|
+
* reconciled into the cache. A tombstoned node is dropped only while its
|
|
44732
|
+
* workspace is still absent from disk; if the workspace is back (genuine
|
|
44733
|
+
* re-registration), the tombstone is cleared and the node merges normally. */
|
|
44734
|
+
applyInlineMeshNodeTombstones(meshId, incoming) {
|
|
44735
|
+
const tombstones = this.removedInlineMeshNodeIds.get(meshId);
|
|
44736
|
+
if (!tombstones?.size || !incoming || typeof incoming !== "object" || !Array.isArray(incoming.nodes)) {
|
|
44737
|
+
return incoming;
|
|
44738
|
+
}
|
|
44739
|
+
let dropped = false;
|
|
44740
|
+
const nodes = incoming.nodes.filter((node) => {
|
|
44741
|
+
const nodeId = readInlineMeshNodeId(node);
|
|
44742
|
+
if (!nodeId || !tombstones.has(nodeId)) return true;
|
|
44743
|
+
const workspace = readStringValue(node?.workspace);
|
|
44744
|
+
if (workspace && fs25.existsSync(workspace)) {
|
|
44745
|
+
tombstones.delete(nodeId);
|
|
44746
|
+
return true;
|
|
44747
|
+
}
|
|
44748
|
+
dropped = true;
|
|
44749
|
+
return false;
|
|
44750
|
+
});
|
|
44751
|
+
if (tombstones.size === 0) this.removedInlineMeshNodeIds.delete(meshId);
|
|
44752
|
+
if (!dropped) return incoming;
|
|
44753
|
+
return { ...incoming, nodes };
|
|
44754
|
+
}
|
|
44429
44755
|
normalizeMeshSessionCleanupMode(value) {
|
|
44430
44756
|
return value === "stop" || value === "delete_stopped" || value === "stop_and_delete" || value === "preserve" ? value : "preserve";
|
|
44431
44757
|
}
|
|
@@ -44448,13 +44774,13 @@ var DaemonCommandRouter = class {
|
|
|
44448
44774
|
recoveryHint: "Inspect the mesh node record before removing it, or remove stale metadata manually only after confirming no managed worktree remains."
|
|
44449
44775
|
};
|
|
44450
44776
|
}
|
|
44451
|
-
const worktreeExists =
|
|
44777
|
+
const worktreeExists = fs25.existsSync(workspace);
|
|
44452
44778
|
const sourceNode = args.node?.clonedFromNodeId ? args.mesh?.nodes?.find((n) => meshNodeIdMatches(n, args.node.clonedFromNodeId)) : args.mesh?.nodes?.find((n) => !n.isLocalWorktree);
|
|
44453
44779
|
const repoRoot = typeof sourceNode?.repoRoot === "string" && sourceNode.repoRoot.trim() ? sourceNode.repoRoot.trim() : typeof sourceNode?.workspace === "string" && sourceNode.workspace.trim() ? sourceNode.workspace.trim() : "";
|
|
44454
44780
|
if (!worktreeExists) {
|
|
44455
44781
|
return { success: true, skipped: true, removedPath: workspace, repoRoot: repoRoot || void 0, reason: "worktree_path_missing" };
|
|
44456
44782
|
}
|
|
44457
|
-
if (!repoRoot || !
|
|
44783
|
+
if (!repoRoot || !fs25.existsSync(repoRoot)) {
|
|
44458
44784
|
return {
|
|
44459
44785
|
success: false,
|
|
44460
44786
|
code: "mesh_worktree_cleanup_missing_source_repo",
|
|
@@ -44474,7 +44800,7 @@ var DaemonCommandRouter = class {
|
|
|
44474
44800
|
const normalizePath = (value) => {
|
|
44475
44801
|
const resolved = (0, import_path11.resolve)(value);
|
|
44476
44802
|
try {
|
|
44477
|
-
return
|
|
44803
|
+
return fs25.realpathSync(resolved);
|
|
44478
44804
|
} catch {
|
|
44479
44805
|
return resolved;
|
|
44480
44806
|
}
|
|
@@ -44560,7 +44886,7 @@ var DaemonCommandRouter = class {
|
|
|
44560
44886
|
};
|
|
44561
44887
|
} catch (deinitError) {
|
|
44562
44888
|
try {
|
|
44563
|
-
|
|
44889
|
+
fs25.rmSync(workspace, { recursive: true, force: true });
|
|
44564
44890
|
await execFileAsync4("git", ["worktree", "prune"], {
|
|
44565
44891
|
cwd: repoRoot,
|
|
44566
44892
|
encoding: "utf8",
|
|
@@ -46339,8 +46665,8 @@ ${hintLines.join("\n")}` : "",
|
|
|
46339
46665
|
if (sinceTs > 0) {
|
|
46340
46666
|
return { success: true, logs: [], totalBuffered: 0 };
|
|
46341
46667
|
}
|
|
46342
|
-
if (
|
|
46343
|
-
const content =
|
|
46668
|
+
if (fs25.existsSync(LOG_PATH)) {
|
|
46669
|
+
const content = fs25.readFileSync(LOG_PATH, "utf-8");
|
|
46344
46670
|
const allLines = content.split("\n");
|
|
46345
46671
|
const recent = allLines.slice(-count).join("\n");
|
|
46346
46672
|
return { success: true, logs: recent, totalLines: allLines.length };
|
|
@@ -46885,14 +47211,14 @@ ${hintLines.join("\n")}` : "",
|
|
|
46885
47211
|
// Settings page in the dashboard reads/writes via these two
|
|
46886
47212
|
// commands instead of going through fs from the browser.
|
|
46887
47213
|
case "list_coordinator_prompts": {
|
|
46888
|
-
const
|
|
47214
|
+
const fs31 = await import("fs");
|
|
46889
47215
|
const path41 = await import("path");
|
|
46890
47216
|
const os30 = await import("os");
|
|
46891
47217
|
const dir = path41.join(os30.homedir(), ".adhdev", "coordinator-prompts");
|
|
46892
47218
|
const entries = {};
|
|
46893
47219
|
try {
|
|
46894
|
-
if (
|
|
46895
|
-
for (const name of
|
|
47220
|
+
if (fs31.existsSync(dir)) {
|
|
47221
|
+
for (const name of fs31.readdirSync(dir)) {
|
|
46896
47222
|
const matchOverride = name.match(/^([a-zA-Z0-9_.-]+)\.md$/);
|
|
46897
47223
|
const matchAppend = name.match(/^([a-zA-Z0-9_.-]+)\.append\.md$/);
|
|
46898
47224
|
const m = matchAppend || matchOverride;
|
|
@@ -46902,7 +47228,7 @@ ${hintLines.join("\n")}` : "",
|
|
|
46902
47228
|
const full = path41.join(dir, name);
|
|
46903
47229
|
let content = "";
|
|
46904
47230
|
try {
|
|
46905
|
-
content =
|
|
47231
|
+
content = fs31.readFileSync(full, "utf8");
|
|
46906
47232
|
} catch {
|
|
46907
47233
|
}
|
|
46908
47234
|
if (!entries[key]) entries[key] = { override: "", append: "" };
|
|
@@ -46916,7 +47242,7 @@ ${hintLines.join("\n")}` : "",
|
|
|
46916
47242
|
return { success: true, dir, entries };
|
|
46917
47243
|
}
|
|
46918
47244
|
case "write_coordinator_prompt": {
|
|
46919
|
-
const
|
|
47245
|
+
const fs31 = await import("fs");
|
|
46920
47246
|
const path41 = await import("path");
|
|
46921
47247
|
const os30 = await import("os");
|
|
46922
47248
|
const key = typeof args?.key === "string" ? args.key.trim() : "";
|
|
@@ -46929,11 +47255,11 @@ ${hintLines.join("\n")}` : "",
|
|
|
46929
47255
|
const filename = kind === "append" ? `${key}.append.md` : `${key}.md`;
|
|
46930
47256
|
const full = path41.join(dir, filename);
|
|
46931
47257
|
try {
|
|
46932
|
-
|
|
47258
|
+
fs31.mkdirSync(dir, { recursive: true });
|
|
46933
47259
|
if (content.trim()) {
|
|
46934
|
-
|
|
46935
|
-
} else if (
|
|
46936
|
-
|
|
47260
|
+
fs31.writeFileSync(full, content, { encoding: "utf8", mode: 384 });
|
|
47261
|
+
} else if (fs31.existsSync(full)) {
|
|
47262
|
+
fs31.unlinkSync(full);
|
|
46937
47263
|
}
|
|
46938
47264
|
return { success: true, path: full, kind, key };
|
|
46939
47265
|
} catch (error) {
|
|
@@ -47711,6 +48037,55 @@ ${hintLines.join("\n")}` : "",
|
|
|
47711
48037
|
});
|
|
47712
48038
|
return result;
|
|
47713
48039
|
}
|
|
48040
|
+
case "get_mesh_node_logs": {
|
|
48041
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
48042
|
+
const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
|
|
48043
|
+
let nodeDaemonId;
|
|
48044
|
+
if (meshId && nodeId) {
|
|
48045
|
+
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
|
|
48046
|
+
const node = meshRecord?.mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
|
|
48047
|
+
nodeDaemonId = typeof node?.daemonId === "string" ? node.daemonId.trim() : void 0;
|
|
48048
|
+
}
|
|
48049
|
+
const selfDaemonId = this.deps.statusInstanceId;
|
|
48050
|
+
const isRemote = nodeDaemonId && selfDaemonId && nodeDaemonId !== selfDaemonId;
|
|
48051
|
+
if (isRemote && this.deps.dispatchMeshCommand && !args?._meshDirectDispatch) {
|
|
48052
|
+
const forwarded = await this.deps.dispatchMeshCommand(nodeDaemonId, "get_mesh_node_logs", {
|
|
48053
|
+
...typeof args === "object" && args !== null ? args : {},
|
|
48054
|
+
_meshDirectDispatch: true
|
|
48055
|
+
});
|
|
48056
|
+
return forwarded ?? { success: false, error: "no response from remote node" };
|
|
48057
|
+
}
|
|
48058
|
+
const rawTailBytes = Number(args?.tailBytes);
|
|
48059
|
+
const tail = readDaemonLogTail({
|
|
48060
|
+
date: typeof args?.date === "string" ? args.date : void 0,
|
|
48061
|
+
tailBytes: Number.isFinite(rawTailBytes) ? Math.min(rawTailBytes, MAX_TAIL_BYTES) : void 0,
|
|
48062
|
+
grep: typeof args?.grep === "string" ? args.grep : void 0,
|
|
48063
|
+
sinceMs: Number.isFinite(Number(args?.sinceMs)) ? Number(args?.sinceMs) : void 0
|
|
48064
|
+
});
|
|
48065
|
+
if (!tail.success) {
|
|
48066
|
+
return {
|
|
48067
|
+
success: false,
|
|
48068
|
+
error: tail.error || "failed to read daemon log tail",
|
|
48069
|
+
nodeId,
|
|
48070
|
+
logPath: tail.logPath,
|
|
48071
|
+
platform: tail.platform
|
|
48072
|
+
};
|
|
48073
|
+
}
|
|
48074
|
+
const redactedLines = redactLogLines(tail.lines);
|
|
48075
|
+
return {
|
|
48076
|
+
success: true,
|
|
48077
|
+
nodeId,
|
|
48078
|
+
daemonId: selfDaemonId,
|
|
48079
|
+
logPath: tail.logPath,
|
|
48080
|
+
platform: tail.platform,
|
|
48081
|
+
lines: redactedLines,
|
|
48082
|
+
lineCount: redactedLines.length,
|
|
48083
|
+
truncated: tail.truncated,
|
|
48084
|
+
filtered: tail.filtered,
|
|
48085
|
+
bytesReturned: tail.bytesReturned,
|
|
48086
|
+
...tail.grep ? { grep: tail.grep } : {}
|
|
48087
|
+
};
|
|
48088
|
+
}
|
|
47714
48089
|
case "refine_mesh_node": {
|
|
47715
48090
|
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
47716
48091
|
const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
|
|
@@ -48378,15 +48753,15 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
48378
48753
|
}
|
|
48379
48754
|
if (cliType === "codex-cli") {
|
|
48380
48755
|
const repoMcpConfigPath = (0, import_path11.join)(workspace, ".mcp.json");
|
|
48381
|
-
if (
|
|
48756
|
+
if (fs25.existsSync(repoMcpConfigPath)) {
|
|
48382
48757
|
try {
|
|
48383
48758
|
const repoMcpConfig = parseMeshCoordinatorMcpConfig(
|
|
48384
|
-
|
|
48759
|
+
fs25.readFileSync(repoMcpConfigPath, "utf-8"),
|
|
48385
48760
|
"claude_mcp_json"
|
|
48386
48761
|
);
|
|
48387
48762
|
const existingServers2 = repoMcpConfig.mcpServers;
|
|
48388
48763
|
if (existingServers2 && typeof existingServers2 === "object" && !Array.isArray(existingServers2) && existingServers2[coordinatorSetup.serverName]) {
|
|
48389
|
-
|
|
48764
|
+
fs25.writeFileSync(repoMcpConfigPath, serializeMeshCoordinatorMcpConfig({
|
|
48390
48765
|
...repoMcpConfig,
|
|
48391
48766
|
mcpServers: {
|
|
48392
48767
|
...existingServers2,
|
|
@@ -48502,7 +48877,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
48502
48877
|
workspace
|
|
48503
48878
|
};
|
|
48504
48879
|
}
|
|
48505
|
-
const { existsSync:
|
|
48880
|
+
const { existsSync: existsSync44, readFileSync: readFileSync35, writeFileSync: writeFileSync23, copyFileSync: copyFileSync4, mkdirSync: mkdirSync21 } = await import("fs");
|
|
48506
48881
|
const { dirname: dirname14 } = await import("path");
|
|
48507
48882
|
const mcpConfigPath = coordinatorSetup.configPath;
|
|
48508
48883
|
const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
|
|
@@ -48545,7 +48920,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
48545
48920
|
if (hermesManualFallback) return returnManualFallback(message);
|
|
48546
48921
|
return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
|
|
48547
48922
|
}
|
|
48548
|
-
const hadExistingMcpConfig =
|
|
48923
|
+
const hadExistingMcpConfig = existsSync44(mcpConfigPath);
|
|
48549
48924
|
let existingMcpConfig = hermesBaseConfig?.config || {};
|
|
48550
48925
|
if (hermesBaseConfig) {
|
|
48551
48926
|
copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname14(mcpConfigPath));
|
|
@@ -48722,7 +49097,8 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
48722
49097
|
peerAttemptedCount: 0,
|
|
48723
49098
|
peerConfirmedCount: 0,
|
|
48724
49099
|
standingEvidenceCount: 0,
|
|
48725
|
-
unavailableNodeIds: []
|
|
49100
|
+
unavailableNodeIds: [],
|
|
49101
|
+
deadNodeIds: []
|
|
48726
49102
|
};
|
|
48727
49103
|
const passivePeerTruthNotAttempted = requireDirectPeerTruth && !refreshRequested && directTruth.directEvidenceCount > 0 && directTruth.peerAttemptedCount === 0;
|
|
48728
49104
|
const effectiveDirectTruth = passivePeerTruthNotAttempted ? { ...directTruth, unavailableNodeIds: [] } : directTruth;
|
|
@@ -48862,7 +49238,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
48862
49238
|
}
|
|
48863
49239
|
}
|
|
48864
49240
|
if (workspace) {
|
|
48865
|
-
if (!
|
|
49241
|
+
if (!fs25.existsSync(workspace)) {
|
|
48866
49242
|
const inlineTransitGit = buildInlineMeshTransitGitStatus(node);
|
|
48867
49243
|
let remoteProbeApplied = false;
|
|
48868
49244
|
if (inlineTransitGit) {
|
|
@@ -48953,7 +49329,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
48953
49329
|
const pendingCoordinatorEvents = getPendingMeshCoordinatorEvents(meshId, callerCoordinatorDaemonId);
|
|
48954
49330
|
const unroutableDeliveries = getRecentUnroutableDeliveries();
|
|
48955
49331
|
const previewFreshness = (() => {
|
|
48956
|
-
const localRepoRoot = nodeStatuses.map((node) => readStringValue(node?.git?.repoRoot, node?.repoRoot, node?.workspace)).find((candidate) => !!candidate &&
|
|
49332
|
+
const localRepoRoot = nodeStatuses.map((node) => readStringValue(node?.git?.repoRoot, node?.repoRoot, node?.workspace)).find((candidate) => !!candidate && fs25.existsSync(candidate));
|
|
48957
49333
|
return localRepoRoot ? buildPreviewFreshness(localRepoRoot) : void 0;
|
|
48958
49334
|
})();
|
|
48959
49335
|
const asyncRefineJobs = buildMeshAsyncRefineJobs({
|
|
@@ -49048,7 +49424,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
49048
49424
|
const { deriveMeshReviewInboxItems: deriveMeshReviewInboxItems2 } = await Promise.resolve().then(() => (init_mesh_review_inbox(), mesh_review_inbox_exports));
|
|
49049
49425
|
const { readLedgerEntries: readLedgerEntries2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
49050
49426
|
const { getGitDiffSummary: getGitDiffSummary2 } = await Promise.resolve().then(() => (init_git_diff(), git_diff_exports));
|
|
49051
|
-
const { existsSync:
|
|
49427
|
+
const { existsSync: existsSync44 } = await import("fs");
|
|
49052
49428
|
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
|
|
49053
49429
|
const mesh = meshRecord?.mesh;
|
|
49054
49430
|
if (!mesh) return { success: false, error: "Mesh not found" };
|
|
@@ -49067,7 +49443,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
49067
49443
|
const derivation = deriveMeshReviewInboxItems2({ nodes: nodeStatuses, ledgerEntries });
|
|
49068
49444
|
for (const item of derivation.items) {
|
|
49069
49445
|
const workspace = item.workspace;
|
|
49070
|
-
if (!workspace || !
|
|
49446
|
+
if (!workspace || !existsSync44(workspace)) continue;
|
|
49071
49447
|
const baseRef = item.defaultBranch ? `origin/${item.defaultBranch}` : "origin/main";
|
|
49072
49448
|
try {
|
|
49073
49449
|
const diffResult = await getGitDiffSummary2(workspace, { baseRef, maxFiles: 100 });
|
|
@@ -50813,7 +51189,7 @@ var ProviderInstanceManager = class {
|
|
|
50813
51189
|
};
|
|
50814
51190
|
|
|
50815
51191
|
// src/providers/version-archive.ts
|
|
50816
|
-
var
|
|
51192
|
+
var fs26 = __toESM(require("fs"));
|
|
50817
51193
|
var path36 = __toESM(require("path"));
|
|
50818
51194
|
var os28 = __toESM(require("os"));
|
|
50819
51195
|
var import_os4 = require("os");
|
|
@@ -50827,8 +51203,8 @@ var VersionArchive = class {
|
|
|
50827
51203
|
}
|
|
50828
51204
|
load() {
|
|
50829
51205
|
try {
|
|
50830
|
-
if (
|
|
50831
|
-
this.history = JSON.parse(
|
|
51206
|
+
if (fs26.existsSync(ARCHIVE_PATH)) {
|
|
51207
|
+
this.history = JSON.parse(fs26.readFileSync(ARCHIVE_PATH, "utf-8"));
|
|
50832
51208
|
}
|
|
50833
51209
|
} catch {
|
|
50834
51210
|
this.history = {};
|
|
@@ -50865,8 +51241,8 @@ var VersionArchive = class {
|
|
|
50865
51241
|
}
|
|
50866
51242
|
save() {
|
|
50867
51243
|
try {
|
|
50868
|
-
|
|
50869
|
-
|
|
51244
|
+
fs26.mkdirSync(path36.dirname(ARCHIVE_PATH), { recursive: true });
|
|
51245
|
+
fs26.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
|
|
50870
51246
|
} catch {
|
|
50871
51247
|
}
|
|
50872
51248
|
}
|
|
@@ -50891,8 +51267,8 @@ function findBinary2(name) {
|
|
|
50891
51267
|
for (const ext of exes) {
|
|
50892
51268
|
const fullPath = path36.join(p, name + ext);
|
|
50893
51269
|
try {
|
|
50894
|
-
if (
|
|
50895
|
-
const stat2 =
|
|
51270
|
+
if (fs26.existsSync(fullPath)) {
|
|
51271
|
+
const stat2 = fs26.statSync(fullPath);
|
|
50896
51272
|
if (stat2.isFile() && (isWin || stat2.mode & 73)) {
|
|
50897
51273
|
return fullPath;
|
|
50898
51274
|
}
|
|
@@ -50939,9 +51315,9 @@ function checkPathExists2(paths) {
|
|
|
50939
51315
|
if (p.includes("*")) {
|
|
50940
51316
|
const home = os28.homedir();
|
|
50941
51317
|
const resolved = p.replace(/\*/g, home.split(path36.sep).pop() || "");
|
|
50942
|
-
if (
|
|
51318
|
+
if (fs26.existsSync(resolved)) return resolved;
|
|
50943
51319
|
} else {
|
|
50944
|
-
if (
|
|
51320
|
+
if (fs26.existsSync(p)) return p;
|
|
50945
51321
|
}
|
|
50946
51322
|
}
|
|
50947
51323
|
return null;
|
|
@@ -50949,7 +51325,7 @@ function checkPathExists2(paths) {
|
|
|
50949
51325
|
async function getMacAppVersion(appPath) {
|
|
50950
51326
|
if ((0, import_os4.platform)() !== "darwin" || !appPath.endsWith(".app")) return null;
|
|
50951
51327
|
const plistPath = path36.join(appPath, "Contents", "Info.plist");
|
|
50952
|
-
if (!
|
|
51328
|
+
if (!fs26.existsSync(plistPath)) return null;
|
|
50953
51329
|
const raw = await runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
|
|
50954
51330
|
return raw || null;
|
|
50955
51331
|
}
|
|
@@ -50975,7 +51351,7 @@ async function detectAllVersions(loader, archive) {
|
|
|
50975
51351
|
let resolvedBin = cliBin;
|
|
50976
51352
|
if (!resolvedBin && appPath && currentOs === "darwin") {
|
|
50977
51353
|
const bundled = path36.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
|
|
50978
|
-
if (provider.cli &&
|
|
51354
|
+
if (provider.cli && fs26.existsSync(bundled)) resolvedBin = bundled;
|
|
50979
51355
|
}
|
|
50980
51356
|
info.installed = !!(appPath || resolvedBin);
|
|
50981
51357
|
info.path = appPath || null;
|
|
@@ -51014,7 +51390,7 @@ async function detectAllVersions(loader, archive) {
|
|
|
51014
51390
|
|
|
51015
51391
|
// src/daemon/dev-server.ts
|
|
51016
51392
|
var http2 = __toESM(require("http"));
|
|
51017
|
-
var
|
|
51393
|
+
var fs30 = __toESM(require("fs"));
|
|
51018
51394
|
var path40 = __toESM(require("path"));
|
|
51019
51395
|
init_config();
|
|
51020
51396
|
|
|
@@ -51365,7 +51741,7 @@ async (params) => {
|
|
|
51365
51741
|
init_logger();
|
|
51366
51742
|
|
|
51367
51743
|
// src/daemon/dev-cdp-handlers.ts
|
|
51368
|
-
var
|
|
51744
|
+
var fs27 = __toESM(require("fs"));
|
|
51369
51745
|
var path37 = __toESM(require("path"));
|
|
51370
51746
|
init_logger();
|
|
51371
51747
|
async function handleCdpEvaluate(ctx, req, res) {
|
|
@@ -51546,17 +51922,17 @@ async function handleScriptHints(ctx, type, _req, res) {
|
|
|
51546
51922
|
}
|
|
51547
51923
|
let scriptsPath = "";
|
|
51548
51924
|
const directScripts = path37.join(dir, "scripts.js");
|
|
51549
|
-
if (
|
|
51925
|
+
if (fs27.existsSync(directScripts)) {
|
|
51550
51926
|
scriptsPath = directScripts;
|
|
51551
51927
|
} else {
|
|
51552
51928
|
const scriptsDir = path37.join(dir, "scripts");
|
|
51553
|
-
if (
|
|
51554
|
-
const versions =
|
|
51555
|
-
return
|
|
51929
|
+
if (fs27.existsSync(scriptsDir)) {
|
|
51930
|
+
const versions = fs27.readdirSync(scriptsDir).filter((d) => {
|
|
51931
|
+
return fs27.statSync(path37.join(scriptsDir, d)).isDirectory();
|
|
51556
51932
|
}).sort().reverse();
|
|
51557
51933
|
for (const ver of versions) {
|
|
51558
51934
|
const p = path37.join(scriptsDir, ver, "scripts.js");
|
|
51559
|
-
if (
|
|
51935
|
+
if (fs27.existsSync(p)) {
|
|
51560
51936
|
scriptsPath = p;
|
|
51561
51937
|
break;
|
|
51562
51938
|
}
|
|
@@ -51568,7 +51944,7 @@ async function handleScriptHints(ctx, type, _req, res) {
|
|
|
51568
51944
|
return;
|
|
51569
51945
|
}
|
|
51570
51946
|
try {
|
|
51571
|
-
const source =
|
|
51947
|
+
const source = fs27.readFileSync(scriptsPath, "utf-8");
|
|
51572
51948
|
const hints = {};
|
|
51573
51949
|
const funcRegex = /module\.exports\.(\w+)\s*=\s*function\s+\w+\s*\(params\)/g;
|
|
51574
51950
|
let match;
|
|
@@ -52383,7 +52759,7 @@ async function handleDomContext(ctx, type, req, res) {
|
|
|
52383
52759
|
}
|
|
52384
52760
|
|
|
52385
52761
|
// src/daemon/dev-cli-debug.ts
|
|
52386
|
-
var
|
|
52762
|
+
var fs28 = __toESM(require("fs"));
|
|
52387
52763
|
var path38 = __toESM(require("path"));
|
|
52388
52764
|
function slugifyFixtureName(value) {
|
|
52389
52765
|
const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
@@ -52399,10 +52775,10 @@ function getCliFixtureDir(ctx, type) {
|
|
|
52399
52775
|
function readCliFixture(ctx, type, name) {
|
|
52400
52776
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
52401
52777
|
const filePath = path38.join(fixtureDir, `${name}.json`);
|
|
52402
|
-
if (!
|
|
52778
|
+
if (!fs28.existsSync(filePath)) {
|
|
52403
52779
|
throw new Error(`Fixture not found: ${filePath}`);
|
|
52404
52780
|
}
|
|
52405
|
-
return JSON.parse(
|
|
52781
|
+
return JSON.parse(fs28.readFileSync(filePath, "utf-8"));
|
|
52406
52782
|
}
|
|
52407
52783
|
function getExerciseTranscriptText(result) {
|
|
52408
52784
|
const parts = [];
|
|
@@ -53147,7 +53523,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
53147
53523
|
return;
|
|
53148
53524
|
}
|
|
53149
53525
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
53150
|
-
|
|
53526
|
+
fs28.mkdirSync(fixtureDir, { recursive: true });
|
|
53151
53527
|
const name = slugifyFixtureName(String(body?.name || `${type}-${Date.now()}`));
|
|
53152
53528
|
const result = await runCliExerciseInternal(ctx, { ...request, type });
|
|
53153
53529
|
const fixture = {
|
|
@@ -53175,7 +53551,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
53175
53551
|
notes: typeof body?.notes === "string" ? body.notes : void 0
|
|
53176
53552
|
};
|
|
53177
53553
|
const filePath = path38.join(fixtureDir, `${name}.json`);
|
|
53178
|
-
|
|
53554
|
+
fs28.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
|
|
53179
53555
|
ctx.json(res, 200, {
|
|
53180
53556
|
saved: true,
|
|
53181
53557
|
name,
|
|
@@ -53193,14 +53569,14 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
53193
53569
|
async function handleCliFixtureList(ctx, type, _req, res) {
|
|
53194
53570
|
try {
|
|
53195
53571
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
53196
|
-
if (!
|
|
53572
|
+
if (!fs28.existsSync(fixtureDir)) {
|
|
53197
53573
|
ctx.json(res, 200, { fixtures: [], count: 0 });
|
|
53198
53574
|
return;
|
|
53199
53575
|
}
|
|
53200
|
-
const fixtures =
|
|
53576
|
+
const fixtures = fs28.readdirSync(fixtureDir).filter((file) => file.endsWith(".json")).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file) => {
|
|
53201
53577
|
const fullPath = path38.join(fixtureDir, file);
|
|
53202
53578
|
try {
|
|
53203
|
-
const raw = JSON.parse(
|
|
53579
|
+
const raw = JSON.parse(fs28.readFileSync(fullPath, "utf-8"));
|
|
53204
53580
|
return {
|
|
53205
53581
|
name: raw.name || file.replace(/\.json$/i, ""),
|
|
53206
53582
|
path: fullPath,
|
|
@@ -53333,7 +53709,7 @@ async function handleCliRaw(ctx, req, res) {
|
|
|
53333
53709
|
}
|
|
53334
53710
|
|
|
53335
53711
|
// src/daemon/dev-auto-implement.ts
|
|
53336
|
-
var
|
|
53712
|
+
var fs29 = __toESM(require("fs"));
|
|
53337
53713
|
var path39 = __toESM(require("path"));
|
|
53338
53714
|
var os29 = __toESM(require("os"));
|
|
53339
53715
|
var import_session_host_core8 = require("@adhdev/session-host-core");
|
|
@@ -53382,10 +53758,10 @@ function resolveAutoImplReference(ctx, category, requestedReference, targetType)
|
|
|
53382
53758
|
return fallback?.type || null;
|
|
53383
53759
|
}
|
|
53384
53760
|
function getLatestScriptVersionDir(scriptsDir) {
|
|
53385
|
-
if (!
|
|
53386
|
-
const versions =
|
|
53761
|
+
if (!fs29.existsSync(scriptsDir)) return null;
|
|
53762
|
+
const versions = fs29.readdirSync(scriptsDir).filter((d) => {
|
|
53387
53763
|
try {
|
|
53388
|
-
return
|
|
53764
|
+
return fs29.statSync(path39.join(scriptsDir, d)).isDirectory();
|
|
53389
53765
|
} catch {
|
|
53390
53766
|
return false;
|
|
53391
53767
|
}
|
|
@@ -53407,13 +53783,13 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
|
53407
53783
|
if (!sourceDir) {
|
|
53408
53784
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
53409
53785
|
}
|
|
53410
|
-
if (!
|
|
53411
|
-
|
|
53412
|
-
|
|
53786
|
+
if (!fs29.existsSync(desiredDir)) {
|
|
53787
|
+
fs29.mkdirSync(path39.dirname(desiredDir), { recursive: true });
|
|
53788
|
+
fs29.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
53413
53789
|
ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
53414
53790
|
}
|
|
53415
53791
|
const providerJson = path39.join(desiredDir, "provider.json");
|
|
53416
|
-
if (!
|
|
53792
|
+
if (!fs29.existsSync(providerJson)) {
|
|
53417
53793
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
53418
53794
|
}
|
|
53419
53795
|
return { dir: desiredDir };
|
|
@@ -53421,15 +53797,15 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
|
53421
53797
|
function loadAutoImplReferenceScripts(ctx, referenceType) {
|
|
53422
53798
|
if (!referenceType) return {};
|
|
53423
53799
|
const refDir = ctx.findProviderDir(referenceType);
|
|
53424
|
-
if (!refDir || !
|
|
53800
|
+
if (!refDir || !fs29.existsSync(refDir)) return {};
|
|
53425
53801
|
const referenceScripts = {};
|
|
53426
53802
|
const scriptsDir = path39.join(refDir, "scripts");
|
|
53427
53803
|
const latestDir = getLatestScriptVersionDir(scriptsDir);
|
|
53428
53804
|
if (!latestDir) return referenceScripts;
|
|
53429
|
-
for (const file of
|
|
53805
|
+
for (const file of fs29.readdirSync(latestDir)) {
|
|
53430
53806
|
if (!file.endsWith(".js")) continue;
|
|
53431
53807
|
try {
|
|
53432
|
-
referenceScripts[file] =
|
|
53808
|
+
referenceScripts[file] = fs29.readFileSync(path39.join(latestDir, file), "utf-8");
|
|
53433
53809
|
} catch {
|
|
53434
53810
|
}
|
|
53435
53811
|
}
|
|
@@ -53538,15 +53914,15 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
53538
53914
|
const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
|
|
53539
53915
|
const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
|
|
53540
53916
|
const tmpDir = path39.join(os29.tmpdir(), "adhdev-autoimpl");
|
|
53541
|
-
if (!
|
|
53917
|
+
if (!fs29.existsSync(tmpDir)) fs29.mkdirSync(tmpDir, { recursive: true });
|
|
53542
53918
|
const promptFile = path39.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
|
|
53543
|
-
|
|
53919
|
+
fs29.writeFileSync(promptFile, prompt, "utf-8");
|
|
53544
53920
|
ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
|
|
53545
53921
|
const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
|
|
53546
53922
|
const spawn4 = agentProvider?.spawn;
|
|
53547
53923
|
if (!spawn4?.command) {
|
|
53548
53924
|
try {
|
|
53549
|
-
|
|
53925
|
+
fs29.unlinkSync(promptFile);
|
|
53550
53926
|
} catch {
|
|
53551
53927
|
}
|
|
53552
53928
|
ctx.json(res, 400, { error: `Agent '${agent}' has no spawn config. Select a CLI provider with a spawn configuration.` });
|
|
@@ -53648,7 +54024,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
53648
54024
|
} catch {
|
|
53649
54025
|
}
|
|
53650
54026
|
try {
|
|
53651
|
-
|
|
54027
|
+
fs29.unlinkSync(promptFile);
|
|
53652
54028
|
} catch {
|
|
53653
54029
|
}
|
|
53654
54030
|
ctx.log(`Auto-implement (ACP) ${success ? "completed" : "failed"}: ${type} (exit: ${code})`);
|
|
@@ -53874,7 +54250,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
53874
54250
|
}
|
|
53875
54251
|
});
|
|
53876
54252
|
try {
|
|
53877
|
-
|
|
54253
|
+
fs29.unlinkSync(promptFile);
|
|
53878
54254
|
} catch {
|
|
53879
54255
|
}
|
|
53880
54256
|
ctx.log(`Auto-implement ${success ? "completed" : "failed"}: ${type} (exit: ${code})${verificationSummary ? ` verify=${verificationSummary.pass ? "pass" : "fail"}` : ""}`);
|
|
@@ -53979,10 +54355,10 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
53979
54355
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
53980
54356
|
lines.push("These are the ONLY files you are allowed to modify. Replace the TODO stubs with working implementations.");
|
|
53981
54357
|
lines.push("");
|
|
53982
|
-
for (const file of
|
|
54358
|
+
for (const file of fs29.readdirSync(latestScriptsDir)) {
|
|
53983
54359
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
53984
54360
|
try {
|
|
53985
|
-
const content =
|
|
54361
|
+
const content = fs29.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
|
|
53986
54362
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
53987
54363
|
lines.push("```javascript");
|
|
53988
54364
|
lines.push(content);
|
|
@@ -53992,14 +54368,14 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
53992
54368
|
}
|
|
53993
54369
|
}
|
|
53994
54370
|
}
|
|
53995
|
-
const refFiles =
|
|
54371
|
+
const refFiles = fs29.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
53996
54372
|
if (refFiles.length > 0) {
|
|
53997
54373
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
53998
54374
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
53999
54375
|
lines.push("");
|
|
54000
54376
|
for (const file of refFiles) {
|
|
54001
54377
|
try {
|
|
54002
|
-
const content =
|
|
54378
|
+
const content = fs29.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
|
|
54003
54379
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
54004
54380
|
lines.push("```javascript");
|
|
54005
54381
|
lines.push(content);
|
|
@@ -54044,7 +54420,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
54044
54420
|
const loadGuide = (name) => {
|
|
54045
54421
|
try {
|
|
54046
54422
|
const p = path39.join(docsDir, name);
|
|
54047
|
-
if (
|
|
54423
|
+
if (fs29.existsSync(p)) return fs29.readFileSync(p, "utf-8");
|
|
54048
54424
|
} catch {
|
|
54049
54425
|
}
|
|
54050
54426
|
return null;
|
|
@@ -54288,11 +54664,11 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
54288
54664
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
54289
54665
|
lines.push("These are the ONLY files you are allowed to modify. Replace TODO or heuristic-only logic with working PTY-aware implementations.");
|
|
54290
54666
|
lines.push("");
|
|
54291
|
-
for (const file of
|
|
54667
|
+
for (const file of fs29.readdirSync(latestScriptsDir)) {
|
|
54292
54668
|
if (!file.endsWith(".js")) continue;
|
|
54293
54669
|
if (!targetFileNames.has(file)) continue;
|
|
54294
54670
|
try {
|
|
54295
|
-
const content =
|
|
54671
|
+
const content = fs29.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
|
|
54296
54672
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
54297
54673
|
lines.push("```javascript");
|
|
54298
54674
|
lines.push(content);
|
|
@@ -54301,14 +54677,14 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
54301
54677
|
} catch {
|
|
54302
54678
|
}
|
|
54303
54679
|
}
|
|
54304
|
-
const refFiles =
|
|
54680
|
+
const refFiles = fs29.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
54305
54681
|
if (refFiles.length > 0) {
|
|
54306
54682
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
54307
54683
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
54308
54684
|
lines.push("");
|
|
54309
54685
|
for (const file of refFiles) {
|
|
54310
54686
|
try {
|
|
54311
|
-
const content =
|
|
54687
|
+
const content = fs29.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
|
|
54312
54688
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
54313
54689
|
lines.push("```javascript");
|
|
54314
54690
|
lines.push(content);
|
|
@@ -54345,7 +54721,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
54345
54721
|
const loadGuide = (name) => {
|
|
54346
54722
|
try {
|
|
54347
54723
|
const p = path39.join(docsDir, name);
|
|
54348
|
-
if (
|
|
54724
|
+
if (fs29.existsSync(p)) return fs29.readFileSync(p, "utf-8");
|
|
54349
54725
|
} catch {
|
|
54350
54726
|
}
|
|
54351
54727
|
return null;
|
|
@@ -55085,7 +55461,7 @@ var DevServer = class _DevServer {
|
|
|
55085
55461
|
path40.join(process.cwd(), "packages/web-devconsole/dist")
|
|
55086
55462
|
];
|
|
55087
55463
|
for (const dir of candidates) {
|
|
55088
|
-
if (
|
|
55464
|
+
if (fs30.existsSync(path40.join(dir, "index.html"))) return dir;
|
|
55089
55465
|
}
|
|
55090
55466
|
return null;
|
|
55091
55467
|
}
|
|
@@ -55097,7 +55473,7 @@ var DevServer = class _DevServer {
|
|
|
55097
55473
|
}
|
|
55098
55474
|
const htmlPath = path40.join(distDir, "index.html");
|
|
55099
55475
|
try {
|
|
55100
|
-
const html =
|
|
55476
|
+
const html = fs30.readFileSync(htmlPath, "utf-8");
|
|
55101
55477
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
55102
55478
|
res.end(html);
|
|
55103
55479
|
} catch (e) {
|
|
@@ -55127,7 +55503,7 @@ var DevServer = class _DevServer {
|
|
|
55127
55503
|
return;
|
|
55128
55504
|
}
|
|
55129
55505
|
try {
|
|
55130
|
-
const content =
|
|
55506
|
+
const content = fs30.readFileSync(filePath);
|
|
55131
55507
|
const ext = path40.extname(filePath);
|
|
55132
55508
|
const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
|
|
55133
55509
|
res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
|
|
@@ -55236,14 +55612,14 @@ var DevServer = class _DevServer {
|
|
|
55236
55612
|
const files = [];
|
|
55237
55613
|
const scan = (d, prefix) => {
|
|
55238
55614
|
try {
|
|
55239
|
-
for (const entry of
|
|
55615
|
+
for (const entry of fs30.readdirSync(d, { withFileTypes: true })) {
|
|
55240
55616
|
if (entry.name.startsWith(".") || entry.name.endsWith(".bak")) continue;
|
|
55241
55617
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
55242
55618
|
if (entry.isDirectory()) {
|
|
55243
55619
|
files.push({ path: rel, size: 0, type: "dir" });
|
|
55244
55620
|
scan(path40.join(d, entry.name), rel);
|
|
55245
55621
|
} else {
|
|
55246
|
-
const stat2 =
|
|
55622
|
+
const stat2 = fs30.statSync(path40.join(d, entry.name));
|
|
55247
55623
|
files.push({ path: rel, size: stat2.size, type: "file" });
|
|
55248
55624
|
}
|
|
55249
55625
|
}
|
|
@@ -55271,11 +55647,11 @@ var DevServer = class _DevServer {
|
|
|
55271
55647
|
this.json(res, 403, { error: "Forbidden" });
|
|
55272
55648
|
return;
|
|
55273
55649
|
}
|
|
55274
|
-
if (!
|
|
55650
|
+
if (!fs30.existsSync(fullPath) || fs30.statSync(fullPath).isDirectory()) {
|
|
55275
55651
|
this.json(res, 404, { error: `File not found: ${filePath}` });
|
|
55276
55652
|
return;
|
|
55277
55653
|
}
|
|
55278
|
-
const content =
|
|
55654
|
+
const content = fs30.readFileSync(fullPath, "utf-8");
|
|
55279
55655
|
this.json(res, 200, { type, path: filePath, content, lines: content.split("\n").length });
|
|
55280
55656
|
}
|
|
55281
55657
|
/** POST /api/providers/:type/file — write a file { path, content } */
|
|
@@ -55297,9 +55673,9 @@ var DevServer = class _DevServer {
|
|
|
55297
55673
|
return;
|
|
55298
55674
|
}
|
|
55299
55675
|
try {
|
|
55300
|
-
if (
|
|
55301
|
-
|
|
55302
|
-
|
|
55676
|
+
if (fs30.existsSync(fullPath)) fs30.copyFileSync(fullPath, fullPath + ".bak");
|
|
55677
|
+
fs30.mkdirSync(path40.dirname(fullPath), { recursive: true });
|
|
55678
|
+
fs30.writeFileSync(fullPath, content, "utf-8");
|
|
55303
55679
|
this.log(`File saved: ${fullPath} (${content.length} chars)`);
|
|
55304
55680
|
this.providerLoader.reload();
|
|
55305
55681
|
this.json(res, 200, { saved: true, path: filePath, chars: content.length });
|
|
@@ -55316,8 +55692,8 @@ var DevServer = class _DevServer {
|
|
|
55316
55692
|
}
|
|
55317
55693
|
for (const name of ["scripts.js", "provider.json"]) {
|
|
55318
55694
|
const p = path40.join(dir, name);
|
|
55319
|
-
if (
|
|
55320
|
-
const source =
|
|
55695
|
+
if (fs30.existsSync(p)) {
|
|
55696
|
+
const source = fs30.readFileSync(p, "utf-8");
|
|
55321
55697
|
this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
|
|
55322
55698
|
return;
|
|
55323
55699
|
}
|
|
@@ -55336,11 +55712,11 @@ var DevServer = class _DevServer {
|
|
|
55336
55712
|
this.json(res, 404, { error: `Provider not found: ${type}` });
|
|
55337
55713
|
return;
|
|
55338
55714
|
}
|
|
55339
|
-
const target =
|
|
55715
|
+
const target = fs30.existsSync(path40.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
|
|
55340
55716
|
const targetPath = path40.join(dir, target);
|
|
55341
55717
|
try {
|
|
55342
|
-
if (
|
|
55343
|
-
|
|
55718
|
+
if (fs30.existsSync(targetPath)) fs30.copyFileSync(targetPath, targetPath + ".bak");
|
|
55719
|
+
fs30.writeFileSync(targetPath, source, "utf-8");
|
|
55344
55720
|
this.log(`Saved provider: ${targetPath} (${source.length} chars)`);
|
|
55345
55721
|
this.providerLoader.reload();
|
|
55346
55722
|
this.json(res, 200, { saved: true, path: targetPath, chars: source.length });
|
|
@@ -55485,20 +55861,20 @@ var DevServer = class _DevServer {
|
|
|
55485
55861
|
let targetDir;
|
|
55486
55862
|
targetDir = this.providerLoader.getUserProviderDir(category, type);
|
|
55487
55863
|
const jsonPath = path40.join(targetDir, "provider.json");
|
|
55488
|
-
if (
|
|
55864
|
+
if (fs30.existsSync(jsonPath)) {
|
|
55489
55865
|
this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
|
|
55490
55866
|
return;
|
|
55491
55867
|
}
|
|
55492
55868
|
try {
|
|
55493
55869
|
const result = generateFiles(type, name, category, { cdpPorts, cli, processName, installPath, binary, extensionId, version, osPaths, processNames });
|
|
55494
|
-
|
|
55495
|
-
|
|
55870
|
+
fs30.mkdirSync(targetDir, { recursive: true });
|
|
55871
|
+
fs30.writeFileSync(jsonPath, result["provider.json"], "utf-8");
|
|
55496
55872
|
const createdFiles = ["provider.json"];
|
|
55497
55873
|
if (result.files) {
|
|
55498
55874
|
for (const [relPath, content] of Object.entries(result.files)) {
|
|
55499
55875
|
const fullPath = path40.join(targetDir, relPath);
|
|
55500
|
-
|
|
55501
|
-
|
|
55876
|
+
fs30.mkdirSync(path40.dirname(fullPath), { recursive: true });
|
|
55877
|
+
fs30.writeFileSync(fullPath, content, "utf-8");
|
|
55502
55878
|
createdFiles.push(relPath);
|
|
55503
55879
|
}
|
|
55504
55880
|
}
|
|
@@ -55547,10 +55923,10 @@ var DevServer = class _DevServer {
|
|
|
55547
55923
|
}
|
|
55548
55924
|
// ─── Phase 2: Auto-Implement Backend ───
|
|
55549
55925
|
getLatestScriptVersionDir(scriptsDir) {
|
|
55550
|
-
if (!
|
|
55551
|
-
const versions =
|
|
55926
|
+
if (!fs30.existsSync(scriptsDir)) return null;
|
|
55927
|
+
const versions = fs30.readdirSync(scriptsDir).filter((d) => {
|
|
55552
55928
|
try {
|
|
55553
|
-
return
|
|
55929
|
+
return fs30.statSync(path40.join(scriptsDir, d)).isDirectory();
|
|
55554
55930
|
} catch {
|
|
55555
55931
|
return false;
|
|
55556
55932
|
}
|
|
@@ -55572,13 +55948,13 @@ var DevServer = class _DevServer {
|
|
|
55572
55948
|
if (!sourceDir) {
|
|
55573
55949
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
55574
55950
|
}
|
|
55575
|
-
if (!
|
|
55576
|
-
|
|
55577
|
-
|
|
55951
|
+
if (!fs30.existsSync(desiredDir)) {
|
|
55952
|
+
fs30.mkdirSync(path40.dirname(desiredDir), { recursive: true });
|
|
55953
|
+
fs30.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
55578
55954
|
this.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
55579
55955
|
}
|
|
55580
55956
|
const providerJson = path40.join(desiredDir, "provider.json");
|
|
55581
|
-
if (!
|
|
55957
|
+
if (!fs30.existsSync(providerJson)) {
|
|
55582
55958
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
55583
55959
|
}
|
|
55584
55960
|
return { dir: desiredDir };
|
|
@@ -55621,10 +55997,10 @@ var DevServer = class _DevServer {
|
|
|
55621
55997
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
55622
55998
|
lines.push("These are the ONLY files you are allowed to modify. Replace the TODO stubs with working implementations.");
|
|
55623
55999
|
lines.push("");
|
|
55624
|
-
for (const file of
|
|
56000
|
+
for (const file of fs30.readdirSync(latestScriptsDir)) {
|
|
55625
56001
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
55626
56002
|
try {
|
|
55627
|
-
const content =
|
|
56003
|
+
const content = fs30.readFileSync(path40.join(latestScriptsDir, file), "utf-8");
|
|
55628
56004
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
55629
56005
|
lines.push("```javascript");
|
|
55630
56006
|
lines.push(content);
|
|
@@ -55634,14 +56010,14 @@ var DevServer = class _DevServer {
|
|
|
55634
56010
|
}
|
|
55635
56011
|
}
|
|
55636
56012
|
}
|
|
55637
|
-
const refFiles =
|
|
56013
|
+
const refFiles = fs30.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
55638
56014
|
if (refFiles.length > 0) {
|
|
55639
56015
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
55640
56016
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
55641
56017
|
lines.push("");
|
|
55642
56018
|
for (const file of refFiles) {
|
|
55643
56019
|
try {
|
|
55644
|
-
const content =
|
|
56020
|
+
const content = fs30.readFileSync(path40.join(latestScriptsDir, file), "utf-8");
|
|
55645
56021
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
55646
56022
|
lines.push("```javascript");
|
|
55647
56023
|
lines.push(content);
|
|
@@ -55686,7 +56062,7 @@ var DevServer = class _DevServer {
|
|
|
55686
56062
|
const loadGuide = (name) => {
|
|
55687
56063
|
try {
|
|
55688
56064
|
const p = path40.join(docsDir, name);
|
|
55689
|
-
if (
|
|
56065
|
+
if (fs30.existsSync(p)) return fs30.readFileSync(p, "utf-8");
|
|
55690
56066
|
} catch {
|
|
55691
56067
|
}
|
|
55692
56068
|
return null;
|
|
@@ -55867,11 +56243,11 @@ var DevServer = class _DevServer {
|
|
|
55867
56243
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
55868
56244
|
lines.push("These are the ONLY files you are allowed to modify. Replace TODO or heuristic-only logic with working PTY-aware implementations.");
|
|
55869
56245
|
lines.push("");
|
|
55870
|
-
for (const file of
|
|
56246
|
+
for (const file of fs30.readdirSync(latestScriptsDir)) {
|
|
55871
56247
|
if (!file.endsWith(".js")) continue;
|
|
55872
56248
|
if (!targetFileNames.has(file)) continue;
|
|
55873
56249
|
try {
|
|
55874
|
-
const content =
|
|
56250
|
+
const content = fs30.readFileSync(path40.join(latestScriptsDir, file), "utf-8");
|
|
55875
56251
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
55876
56252
|
lines.push("```javascript");
|
|
55877
56253
|
lines.push(content);
|
|
@@ -55880,14 +56256,14 @@ var DevServer = class _DevServer {
|
|
|
55880
56256
|
} catch {
|
|
55881
56257
|
}
|
|
55882
56258
|
}
|
|
55883
|
-
const refFiles =
|
|
56259
|
+
const refFiles = fs30.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
55884
56260
|
if (refFiles.length > 0) {
|
|
55885
56261
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
55886
56262
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
55887
56263
|
lines.push("");
|
|
55888
56264
|
for (const file of refFiles) {
|
|
55889
56265
|
try {
|
|
55890
|
-
const content =
|
|
56266
|
+
const content = fs30.readFileSync(path40.join(latestScriptsDir, file), "utf-8");
|
|
55891
56267
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
55892
56268
|
lines.push("```javascript");
|
|
55893
56269
|
lines.push(content);
|
|
@@ -55924,7 +56300,7 @@ var DevServer = class _DevServer {
|
|
|
55924
56300
|
const loadGuide = (name) => {
|
|
55925
56301
|
try {
|
|
55926
56302
|
const p = path40.join(docsDir, name);
|
|
55927
|
-
if (
|
|
56303
|
+
if (fs30.existsSync(p)) return fs30.readFileSync(p, "utf-8");
|
|
55928
56304
|
} catch {
|
|
55929
56305
|
}
|
|
55930
56306
|
return null;
|
|
@@ -57025,8 +57401,8 @@ async function installExtension(ide, extension) {
|
|
|
57025
57401
|
const res = await fetch(extension.vsixUrl);
|
|
57026
57402
|
if (res.ok) {
|
|
57027
57403
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
57028
|
-
const
|
|
57029
|
-
|
|
57404
|
+
const fs31 = await import("fs");
|
|
57405
|
+
fs31.writeFileSync(vsixPath, buffer);
|
|
57030
57406
|
return new Promise((resolve24) => {
|
|
57031
57407
|
const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
|
|
57032
57408
|
(0, import_child_process11.exec)(cmd, { timeout: 6e4 }, (error, _stdout, stderr) => {
|