@adhdev/daemon-core 0.9.82-rc.164 → 0.9.82-rc.166
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/handler.d.ts +61 -17
- package/dist/index.js +1335 -764
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1333 -762
- package/dist/index.mjs.map +1 -1
- package/dist/providers/external-sources.d.ts +71 -0
- package/dist/providers/provider-loader.d.ts +7 -3
- package/dist/providers/provider-trust.d.ts +31 -0
- package/dist/providers/sdk/v1/index.d.ts +1 -1
- package/dist/providers/sdk/v1/validators/manifest.d.ts +1 -1
- package/dist/providers/sdk/v1/validators/taint.d.ts +1 -1
- package/dist/providers/spec/cli-adapter.d.ts +9 -0
- package/dist/shared-types.d.ts +27 -1
- package/package.json +1 -1
- package/src/commands/cli-manager.ts +19 -0
- package/src/commands/handler.ts +286 -24
- package/src/providers/cli-provider-instance.ts +9 -1
- package/src/providers/external-sources.ts +218 -0
- package/src/providers/provider-loader.ts +180 -34
- package/src/providers/provider-trust.ts +114 -0
- package/src/providers/sdk/v1/index.ts +1 -1
- package/src/providers/sdk/v1/sandbox/require-whitelist.ts +1 -1
- package/src/providers/sdk/v1/schemas/cli/provider.schema.json +4 -3
- package/src/providers/sdk/v1/validators/manifest.ts +1 -1
- package/src/providers/sdk/v1/validators/taint.ts +1 -1
- package/src/providers/spec/cli-adapter.ts +9 -0
- package/src/providers/spec/native-history-executor.ts +13 -2
- package/src/shared-types.ts +33 -1
- package/src/status/snapshot.ts +49 -14
package/dist/index.mjs
CHANGED
|
@@ -106,8 +106,8 @@ function normalizeGitOutput(value) {
|
|
|
106
106
|
return String(value).replace(/\r\n/g, "\n");
|
|
107
107
|
}
|
|
108
108
|
function isPathInside(parent, child) {
|
|
109
|
-
const
|
|
110
|
-
return
|
|
109
|
+
const relative5 = path.relative(path.resolve(parent), path.resolve(child));
|
|
110
|
+
return relative5 === "" || !relative5.startsWith("..") && !path.isAbsolute(relative5);
|
|
111
111
|
}
|
|
112
112
|
async function validateWorkspace(workspace) {
|
|
113
113
|
if (typeof workspace !== "string" || workspace.length === 0 || workspace.includes("\0")) {
|
|
@@ -768,10 +768,10 @@ function getMeshConfigPath() {
|
|
|
768
768
|
return join4(getConfigDir(), "meshes.json");
|
|
769
769
|
}
|
|
770
770
|
function loadMeshConfig() {
|
|
771
|
-
const
|
|
772
|
-
if (!existsSync4(
|
|
771
|
+
const path40 = getMeshConfigPath();
|
|
772
|
+
if (!existsSync4(path40)) return { meshes: [] };
|
|
773
773
|
try {
|
|
774
|
-
const raw = JSON.parse(readFileSync2(
|
|
774
|
+
const raw = JSON.parse(readFileSync2(path40, "utf-8"));
|
|
775
775
|
if (!raw || !Array.isArray(raw.meshes)) return { meshes: [] };
|
|
776
776
|
return raw;
|
|
777
777
|
} catch {
|
|
@@ -779,16 +779,16 @@ function loadMeshConfig() {
|
|
|
779
779
|
}
|
|
780
780
|
}
|
|
781
781
|
function saveMeshConfig(config) {
|
|
782
|
-
const
|
|
783
|
-
writeFileSync2(
|
|
782
|
+
const path40 = getMeshConfigPath();
|
|
783
|
+
writeFileSync2(path40, JSON.stringify(config, null, 2), { encoding: "utf-8", mode: 384 });
|
|
784
784
|
}
|
|
785
785
|
function normalizeRepoIdentity(remoteUrl) {
|
|
786
786
|
let identity = remoteUrl.trim();
|
|
787
787
|
if (identity.startsWith("http://") || identity.startsWith("https://")) {
|
|
788
788
|
try {
|
|
789
789
|
const url = new URL(identity);
|
|
790
|
-
const
|
|
791
|
-
return `${url.hostname}/${
|
|
790
|
+
const path40 = url.pathname.replace(/^\//, "").replace(/\.git$/, "");
|
|
791
|
+
return `${url.hostname}/${path40}`;
|
|
792
792
|
} catch {
|
|
793
793
|
}
|
|
794
794
|
}
|
|
@@ -1717,8 +1717,8 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
1717
1717
|
}
|
|
1718
1718
|
const serverName = mcpConfig.serverName?.trim() || DEFAULT_SERVER_NAME;
|
|
1719
1719
|
if (mcpConfig.mode === "auto_import") {
|
|
1720
|
-
const
|
|
1721
|
-
if (!
|
|
1720
|
+
const path40 = mcpConfig.path?.trim();
|
|
1721
|
+
if (!path40) {
|
|
1722
1722
|
return { kind: "unsupported", reason: "Provider auto-import MCP config is missing a config path" };
|
|
1723
1723
|
}
|
|
1724
1724
|
const mcpServer = resolveAdhdevMcpServerLaunch({
|
|
@@ -1736,7 +1736,7 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
1736
1736
|
return {
|
|
1737
1737
|
kind: "auto_import",
|
|
1738
1738
|
serverName,
|
|
1739
|
-
configPath: resolveMcpConfigPath(
|
|
1739
|
+
configPath: resolveMcpConfigPath(path40, workspace),
|
|
1740
1740
|
configFormat: mcpConfig.format,
|
|
1741
1741
|
mcpServer
|
|
1742
1742
|
};
|
|
@@ -1893,8 +1893,8 @@ function stripCoordinatorWrapperFile(filePath) {
|
|
|
1893
1893
|
const remaining = (existing.slice(0, openIdx) + existing.slice(closeIdx + CLOSE.length)).replace(/^\s*\n+/, "").replace(/\n+\s*$/, "");
|
|
1894
1894
|
if (!remaining.trim()) {
|
|
1895
1895
|
try {
|
|
1896
|
-
const
|
|
1897
|
-
|
|
1896
|
+
const fs28 = __require("fs");
|
|
1897
|
+
fs28.unlinkSync(filePath);
|
|
1898
1898
|
} catch {
|
|
1899
1899
|
}
|
|
1900
1900
|
} else {
|
|
@@ -2032,10 +2032,10 @@ function rotateArchiveFile(meshId, archivePath) {
|
|
|
2032
2032
|
}
|
|
2033
2033
|
}
|
|
2034
2034
|
function readArchivedCounts(meshId) {
|
|
2035
|
-
const
|
|
2036
|
-
if (!existsSync10(
|
|
2035
|
+
const path40 = getArchivedCountsPath(meshId);
|
|
2036
|
+
if (!existsSync10(path40)) return { taskCompleted: 0, taskFailed: 0, taskStalled: 0, recoveryAttempted: 0, totalArchived: 0, lastArchivedAt: "" };
|
|
2037
2037
|
try {
|
|
2038
|
-
return JSON.parse(readFileSync8(
|
|
2038
|
+
return JSON.parse(readFileSync8(path40, "utf-8"));
|
|
2039
2039
|
} catch {
|
|
2040
2040
|
return { taskCompleted: 0, taskFailed: 0, taskStalled: 0, recoveryAttempted: 0, totalArchived: 0, lastArchivedAt: "" };
|
|
2041
2041
|
}
|
|
@@ -2685,10 +2685,10 @@ var init_beads_db = __esm({
|
|
|
2685
2685
|
this.migratedMeshIds.add(meshId);
|
|
2686
2686
|
const count = this.db.prepare("SELECT COUNT(*) AS count FROM mesh_queue WHERE mesh_id = ?").get(meshId);
|
|
2687
2687
|
if (count.count > 0) return;
|
|
2688
|
-
const
|
|
2689
|
-
if (!existsSync11(
|
|
2688
|
+
const path40 = legacyQueuePath(meshId);
|
|
2689
|
+
if (!existsSync11(path40)) return;
|
|
2690
2690
|
try {
|
|
2691
|
-
const entries = JSON.parse(readFileSync9(
|
|
2691
|
+
const entries = JSON.parse(readFileSync9(path40, "utf-8"));
|
|
2692
2692
|
if (!Array.isArray(entries)) return;
|
|
2693
2693
|
const insert = this.db.prepare(`
|
|
2694
2694
|
INSERT OR REPLACE INTO mesh_queue (
|
|
@@ -3399,10 +3399,10 @@ function readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId) {
|
|
|
3399
3399
|
if (!meshId) return [];
|
|
3400
3400
|
const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
|
|
3401
3401
|
const events = [];
|
|
3402
|
-
for (const
|
|
3403
|
-
if (!existsSync13(
|
|
3402
|
+
for (const path40 of paths) {
|
|
3403
|
+
if (!existsSync13(path40)) continue;
|
|
3404
3404
|
try {
|
|
3405
|
-
const raw = readFileSync10(
|
|
3405
|
+
const raw = readFileSync10(path40, "utf-8");
|
|
3406
3406
|
const parsed = raw.split("\n").filter(Boolean).flatMap((line) => {
|
|
3407
3407
|
try {
|
|
3408
3408
|
return [JSON.parse(line)];
|
|
@@ -3410,7 +3410,7 @@ function readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId) {
|
|
|
3410
3410
|
return [];
|
|
3411
3411
|
}
|
|
3412
3412
|
});
|
|
3413
|
-
const filtered = coordinatorDaemonId &&
|
|
3413
|
+
const filtered = coordinatorDaemonId && path40 === getPendingEventsPath(meshId) ? parsed.filter((e) => !e.targetCoordinatorDaemonId || e.targetCoordinatorDaemonId === coordinatorDaemonId) : parsed;
|
|
3414
3414
|
events.push(...filtered);
|
|
3415
3415
|
} catch {
|
|
3416
3416
|
}
|
|
@@ -3479,13 +3479,13 @@ function reconcilePendingMeshCoordinatorEvents(meshId, events) {
|
|
|
3479
3479
|
...backfilled
|
|
3480
3480
|
];
|
|
3481
3481
|
}
|
|
3482
|
-
function trimPendingEventsIfNeeded(
|
|
3482
|
+
function trimPendingEventsIfNeeded(path40) {
|
|
3483
3483
|
try {
|
|
3484
|
-
if (!existsSync13(
|
|
3485
|
-
if (statSync5(
|
|
3486
|
-
const lines = readFileSync10(
|
|
3484
|
+
if (!existsSync13(path40)) return;
|
|
3485
|
+
if (statSync5(path40).size <= MAX_PENDING_EVENTS_BYTES) return;
|
|
3486
|
+
const lines = readFileSync10(path40, "utf-8").split("\n").filter(Boolean);
|
|
3487
3487
|
if (lines.length <= MAX_PENDING_EVENTS_KEEP) return;
|
|
3488
|
-
writeFileSync6(
|
|
3488
|
+
writeFileSync6(path40, lines.slice(-MAX_PENDING_EVENTS_KEEP).join("\n") + "\n", "utf-8");
|
|
3489
3489
|
} catch {
|
|
3490
3490
|
}
|
|
3491
3491
|
}
|
|
@@ -3499,19 +3499,19 @@ function queuePendingMeshCoordinatorEvent(event) {
|
|
|
3499
3499
|
LOG.info("MeshEvents", `Suppressed duplicate pending ${event.event} for mesh ${event.meshId}`);
|
|
3500
3500
|
return true;
|
|
3501
3501
|
}
|
|
3502
|
-
const
|
|
3503
|
-
trimPendingEventsIfNeeded(
|
|
3504
|
-
appendFileSync2(
|
|
3502
|
+
const path40 = getPendingEventsPath(event.meshId, event.targetCoordinatorDaemonId);
|
|
3503
|
+
trimPendingEventsIfNeeded(path40);
|
|
3504
|
+
appendFileSync2(path40, JSON.stringify(event) + "\n", "utf-8");
|
|
3505
3505
|
return true;
|
|
3506
3506
|
} catch (e) {
|
|
3507
3507
|
LOG.warn("MeshEvents", `Failed to persist pending coordinator event: ${e?.message || e}`);
|
|
3508
3508
|
return false;
|
|
3509
3509
|
}
|
|
3510
3510
|
}
|
|
3511
|
-
function atomicDrainFile(
|
|
3512
|
-
const tmpPath = `${
|
|
3511
|
+
function atomicDrainFile(path40) {
|
|
3512
|
+
const tmpPath = `${path40}.draining`;
|
|
3513
3513
|
try {
|
|
3514
|
-
renameSync3(
|
|
3514
|
+
renameSync3(path40, tmpPath);
|
|
3515
3515
|
} catch {
|
|
3516
3516
|
return null;
|
|
3517
3517
|
}
|
|
@@ -3534,8 +3534,8 @@ function drainPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
3534
3534
|
if (!meshId) return [];
|
|
3535
3535
|
const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
|
|
3536
3536
|
const all = [];
|
|
3537
|
-
for (const
|
|
3538
|
-
const content = atomicDrainFile(
|
|
3537
|
+
for (const path40 of paths) {
|
|
3538
|
+
const content = atomicDrainFile(path40);
|
|
3539
3539
|
if (!content) continue;
|
|
3540
3540
|
const parsed = content.split("\n").filter(Boolean).flatMap((line) => {
|
|
3541
3541
|
try {
|
|
@@ -3544,7 +3544,7 @@ function drainPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
3544
3544
|
return [];
|
|
3545
3545
|
}
|
|
3546
3546
|
});
|
|
3547
|
-
const filtered = coordinatorDaemonId &&
|
|
3547
|
+
const filtered = coordinatorDaemonId && path40 === getPendingEventsPath(meshId) ? parsed.filter((e) => !e.targetCoordinatorDaemonId || e.targetCoordinatorDaemonId === coordinatorDaemonId) : parsed;
|
|
3548
3548
|
all.push(...filtered);
|
|
3549
3549
|
}
|
|
3550
3550
|
if (all.length === 0) return [];
|
|
@@ -3557,9 +3557,9 @@ function getPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
3557
3557
|
function clearPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
3558
3558
|
if (!meshId) return;
|
|
3559
3559
|
const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
|
|
3560
|
-
for (const
|
|
3561
|
-
if (existsSync13(
|
|
3562
|
-
unlinkSync2(
|
|
3560
|
+
for (const path40 of paths) {
|
|
3561
|
+
if (existsSync13(path40)) try {
|
|
3562
|
+
unlinkSync2(path40);
|
|
3563
3563
|
} catch {
|
|
3564
3564
|
}
|
|
3565
3565
|
}
|
|
@@ -4683,6 +4683,56 @@ var init_debug_config = __esm({
|
|
|
4683
4683
|
}
|
|
4684
4684
|
});
|
|
4685
4685
|
|
|
4686
|
+
// src/providers/provider-trust.ts
|
|
4687
|
+
var provider_trust_exports = {};
|
|
4688
|
+
__export(provider_trust_exports, {
|
|
4689
|
+
classifyTrust: () => classifyTrust,
|
|
4690
|
+
describeTrust: () => describeTrust,
|
|
4691
|
+
inspectManifestShape: () => inspectManifestShape,
|
|
4692
|
+
requiresConfirmation: () => requiresConfirmation
|
|
4693
|
+
});
|
|
4694
|
+
function inspectManifestShape(manifest) {
|
|
4695
|
+
const hasTui = !!manifest.tui && typeof manifest.tui === "object" && Object.keys(manifest.tui).length > 0;
|
|
4696
|
+
const hasOverrides = !!manifest.overrides && typeof manifest.overrides === "object" && !Array.isArray(manifest.overrides) && Object.keys(manifest.overrides).length > 0;
|
|
4697
|
+
const compat = Array.isArray(manifest.compatibility) ? manifest.compatibility : [];
|
|
4698
|
+
const compatHasScriptDir = compat.some((entry) => typeof entry?.scriptDir === "string");
|
|
4699
|
+
const hasScriptDir = compatHasScriptDir || typeof manifest.defaultScriptDir === "string";
|
|
4700
|
+
return { hasTui, hasOverrides, hasScriptDir };
|
|
4701
|
+
}
|
|
4702
|
+
function classifyTrust(layer, shape) {
|
|
4703
|
+
const isSpecOnly = !shape.hasTui && !shape.hasOverrides && !shape.hasScriptDir;
|
|
4704
|
+
switch (layer) {
|
|
4705
|
+
case "user":
|
|
4706
|
+
return "user-custom";
|
|
4707
|
+
case "upstream":
|
|
4708
|
+
return isSpecOnly ? "trusted" : "trusted-with-scripts";
|
|
4709
|
+
case "external":
|
|
4710
|
+
return isSpecOnly ? "external-safe" : "external-untrusted";
|
|
4711
|
+
}
|
|
4712
|
+
}
|
|
4713
|
+
function requiresConfirmation(trust) {
|
|
4714
|
+
return trust === "external-untrusted";
|
|
4715
|
+
}
|
|
4716
|
+
function describeTrust(trust) {
|
|
4717
|
+
switch (trust) {
|
|
4718
|
+
case "user-custom":
|
|
4719
|
+
return "Hand-authored in ~/.adhdev/providers/. Runs your own code.";
|
|
4720
|
+
case "trusted":
|
|
4721
|
+
return "Official, declarative-only manifest from the ADHDev registry.";
|
|
4722
|
+
case "trusted-with-scripts":
|
|
4723
|
+
return "Official manifest from the ADHDev registry. Ships JavaScript hooks executed by the daemon.";
|
|
4724
|
+
case "external-safe":
|
|
4725
|
+
return "Manifest from a 3rd-party git source you added. Declarative-only \u2014 the daemon never runs JS from this source.";
|
|
4726
|
+
case "external-untrusted":
|
|
4727
|
+
return "Manifest from a 3rd-party git source you added. Ships JavaScript that the daemon will execute. Treat as untrusted code \u2014 review the source before enabling.";
|
|
4728
|
+
}
|
|
4729
|
+
}
|
|
4730
|
+
var init_provider_trust = __esm({
|
|
4731
|
+
"src/providers/provider-trust.ts"() {
|
|
4732
|
+
"use strict";
|
|
4733
|
+
}
|
|
4734
|
+
});
|
|
4735
|
+
|
|
4686
4736
|
// src/providers/sdk/v1/schemas/cli/provider.schema.json
|
|
4687
4737
|
var provider_schema_default;
|
|
4688
4738
|
var init_provider_schema = __esm({
|
|
@@ -4926,14 +4976,15 @@ var init_provider_schema = __esm({
|
|
|
4926
4976
|
minItems: 1,
|
|
4927
4977
|
items: {
|
|
4928
4978
|
type: "object",
|
|
4929
|
-
required: ["
|
|
4979
|
+
required: ["ideVersion"],
|
|
4930
4980
|
additionalProperties: false,
|
|
4931
4981
|
properties: {
|
|
4932
4982
|
ideVersion: { type: "string", description: "SemVer range." },
|
|
4933
|
-
scriptDir: { type: "string", pattern: "^scripts/[^/]+$" }
|
|
4983
|
+
scriptDir: { type: "string", pattern: "^scripts/[^/]+$" },
|
|
4984
|
+
spec: { type: "string", pattern: "^specs/[^/]+\\.json$", description: "Path to declarative spec.json driving SpecCliAdapter for this version range." }
|
|
4934
4985
|
}
|
|
4935
4986
|
},
|
|
4936
|
-
description: "Maps installed agent versions to script subdirectories."
|
|
4987
|
+
description: "Maps installed agent versions to script subdirectories and/or declarative specs."
|
|
4937
4988
|
},
|
|
4938
4989
|
defaultScriptDir: {
|
|
4939
4990
|
type: "string",
|
|
@@ -5187,7 +5238,7 @@ function getCliValidator() {
|
|
|
5187
5238
|
return _cliValidator;
|
|
5188
5239
|
}
|
|
5189
5240
|
function formatIssue(err) {
|
|
5190
|
-
const
|
|
5241
|
+
const path40 = err.instancePath || "";
|
|
5191
5242
|
const params = err.params;
|
|
5192
5243
|
let message = err.message || "validation failed";
|
|
5193
5244
|
let allowed;
|
|
@@ -5205,7 +5256,7 @@ function formatIssue(err) {
|
|
|
5205
5256
|
} else if (err.keyword === "type") {
|
|
5206
5257
|
message = `must be ${params.type}`;
|
|
5207
5258
|
}
|
|
5208
|
-
return { path:
|
|
5259
|
+
return { path: path40, keyword: err.keyword, message, ...allowed !== void 0 ? { allowed } : {} };
|
|
5209
5260
|
}
|
|
5210
5261
|
function validateCliProviderManifest(manifest) {
|
|
5211
5262
|
const validator = getCliValidator();
|
|
@@ -5230,6 +5281,156 @@ var init_manifest = __esm({
|
|
|
5230
5281
|
}
|
|
5231
5282
|
});
|
|
5232
5283
|
|
|
5284
|
+
// src/providers/external-sources.ts
|
|
5285
|
+
var external_sources_exports = {};
|
|
5286
|
+
__export(external_sources_exports, {
|
|
5287
|
+
activeFilePath: () => activeFilePath,
|
|
5288
|
+
deriveSourceName: () => deriveSourceName,
|
|
5289
|
+
externalRoot: () => externalRoot,
|
|
5290
|
+
inventoryExternalSources: () => inventoryExternalSources,
|
|
5291
|
+
loadExternalSources: () => loadExternalSources,
|
|
5292
|
+
loadProvidersActive: () => loadProvidersActive,
|
|
5293
|
+
resolveActiveSource: () => resolveActiveSource,
|
|
5294
|
+
saveExternalSources: () => saveExternalSources,
|
|
5295
|
+
saveProvidersActive: () => saveProvidersActive,
|
|
5296
|
+
sourcesFilePath: () => sourcesFilePath,
|
|
5297
|
+
sourcesProviding: () => sourcesProviding
|
|
5298
|
+
});
|
|
5299
|
+
import * as fs8 from "fs";
|
|
5300
|
+
import * as os10 from "os";
|
|
5301
|
+
import * as path15 from "path";
|
|
5302
|
+
function adhdevDir() {
|
|
5303
|
+
return path15.join(os10.homedir(), ".adhdev");
|
|
5304
|
+
}
|
|
5305
|
+
function externalRoot() {
|
|
5306
|
+
return path15.join(adhdevDir(), "external");
|
|
5307
|
+
}
|
|
5308
|
+
function sourcesFilePath() {
|
|
5309
|
+
return path15.join(adhdevDir(), SOURCES_FILENAME);
|
|
5310
|
+
}
|
|
5311
|
+
function activeFilePath() {
|
|
5312
|
+
return path15.join(adhdevDir(), ACTIVE_FILENAME);
|
|
5313
|
+
}
|
|
5314
|
+
function ensureAdhdevDir() {
|
|
5315
|
+
const d = adhdevDir();
|
|
5316
|
+
if (!fs8.existsSync(d)) fs8.mkdirSync(d, { recursive: true });
|
|
5317
|
+
}
|
|
5318
|
+
function loadExternalSources() {
|
|
5319
|
+
const p = sourcesFilePath();
|
|
5320
|
+
if (!fs8.existsSync(p)) return { schema: 1, sources: [] };
|
|
5321
|
+
try {
|
|
5322
|
+
const raw = JSON.parse(fs8.readFileSync(p, "utf-8"));
|
|
5323
|
+
if (!raw || typeof raw !== "object") return { schema: 1, sources: [] };
|
|
5324
|
+
const sources = Array.isArray(raw.sources) ? raw.sources.filter(isValidSource) : [];
|
|
5325
|
+
return { schema: 1, sources };
|
|
5326
|
+
} catch {
|
|
5327
|
+
return { schema: 1, sources: [] };
|
|
5328
|
+
}
|
|
5329
|
+
}
|
|
5330
|
+
function saveExternalSources(file) {
|
|
5331
|
+
ensureAdhdevDir();
|
|
5332
|
+
const tmp = sourcesFilePath() + ".tmp";
|
|
5333
|
+
fs8.writeFileSync(tmp, JSON.stringify(file, null, 2) + "\n", "utf-8");
|
|
5334
|
+
fs8.renameSync(tmp, sourcesFilePath());
|
|
5335
|
+
}
|
|
5336
|
+
function loadProvidersActive() {
|
|
5337
|
+
const p = activeFilePath();
|
|
5338
|
+
if (!fs8.existsSync(p)) return { schema: 1, active: {} };
|
|
5339
|
+
try {
|
|
5340
|
+
const raw = JSON.parse(fs8.readFileSync(p, "utf-8"));
|
|
5341
|
+
if (!raw || typeof raw !== "object") return { schema: 1, active: {} };
|
|
5342
|
+
const active = raw.active && typeof raw.active === "object" ? raw.active : {};
|
|
5343
|
+
return { schema: 1, active };
|
|
5344
|
+
} catch {
|
|
5345
|
+
return { schema: 1, active: {} };
|
|
5346
|
+
}
|
|
5347
|
+
}
|
|
5348
|
+
function saveProvidersActive(file) {
|
|
5349
|
+
ensureAdhdevDir();
|
|
5350
|
+
const tmp = activeFilePath() + ".tmp";
|
|
5351
|
+
fs8.writeFileSync(tmp, JSON.stringify(file, null, 2) + "\n", "utf-8");
|
|
5352
|
+
fs8.renameSync(tmp, activeFilePath());
|
|
5353
|
+
}
|
|
5354
|
+
function isValidSource(x) {
|
|
5355
|
+
if (!x || typeof x !== "object") return false;
|
|
5356
|
+
const s = x;
|
|
5357
|
+
return typeof s.name === "string" && s.name.length > 0 && typeof s.url === "string" && s.url.length > 0 && typeof s.ref === "string" && s.ref.length > 0 && typeof s.addedAt === "string";
|
|
5358
|
+
}
|
|
5359
|
+
function deriveSourceName(url) {
|
|
5360
|
+
const m = url.match(/[/:]([^/:]+)\/([^/]+?)(?:\.git)?$/);
|
|
5361
|
+
if (!m) return "@source";
|
|
5362
|
+
const owner = m[1].toLowerCase().replace(/[^a-z0-9_-]/g, "-");
|
|
5363
|
+
const repo = m[2].toLowerCase().replace(/[^a-z0-9_-]/g, "-");
|
|
5364
|
+
return `@${owner}-${repo}`;
|
|
5365
|
+
}
|
|
5366
|
+
function inventoryExternalSources() {
|
|
5367
|
+
const root = externalRoot();
|
|
5368
|
+
if (!fs8.existsSync(root)) return [];
|
|
5369
|
+
const out = [];
|
|
5370
|
+
let entries;
|
|
5371
|
+
try {
|
|
5372
|
+
entries = fs8.readdirSync(root, { withFileTypes: true });
|
|
5373
|
+
} catch {
|
|
5374
|
+
return [];
|
|
5375
|
+
}
|
|
5376
|
+
for (const sourceEntry of entries) {
|
|
5377
|
+
if (!sourceEntry.isDirectory()) continue;
|
|
5378
|
+
const sourceName = sourceEntry.name;
|
|
5379
|
+
const sourceDir = path15.join(root, sourceName);
|
|
5380
|
+
const providers = {};
|
|
5381
|
+
let categoryEntries;
|
|
5382
|
+
try {
|
|
5383
|
+
categoryEntries = fs8.readdirSync(sourceDir, { withFileTypes: true });
|
|
5384
|
+
} catch {
|
|
5385
|
+
continue;
|
|
5386
|
+
}
|
|
5387
|
+
for (const categoryEntry of categoryEntries) {
|
|
5388
|
+
if (!categoryEntry.isDirectory()) continue;
|
|
5389
|
+
const category = categoryEntry.name;
|
|
5390
|
+
const categoryDir = path15.join(sourceDir, category);
|
|
5391
|
+
let typeEntries;
|
|
5392
|
+
try {
|
|
5393
|
+
typeEntries = fs8.readdirSync(categoryDir, { withFileTypes: true });
|
|
5394
|
+
} catch {
|
|
5395
|
+
continue;
|
|
5396
|
+
}
|
|
5397
|
+
const types = [];
|
|
5398
|
+
for (const typeEntry of typeEntries) {
|
|
5399
|
+
if (!typeEntry.isDirectory()) continue;
|
|
5400
|
+
const typeDir = path15.join(categoryDir, typeEntry.name);
|
|
5401
|
+
const hasV1 = fs8.existsSync(path15.join(typeDir, "provider.v1.json"));
|
|
5402
|
+
const hasV0 = fs8.existsSync(path15.join(typeDir, "provider.json"));
|
|
5403
|
+
if (hasV1 || hasV0) types.push(typeEntry.name);
|
|
5404
|
+
}
|
|
5405
|
+
if (types.length > 0) providers[category] = types;
|
|
5406
|
+
}
|
|
5407
|
+
out.push({ sourceName, providers });
|
|
5408
|
+
}
|
|
5409
|
+
return out;
|
|
5410
|
+
}
|
|
5411
|
+
function sourcesProviding(category, type) {
|
|
5412
|
+
const inventory = inventoryExternalSources();
|
|
5413
|
+
return inventory.filter((s) => (s.providers[category] || []).includes(type)).map((s) => s.sourceName);
|
|
5414
|
+
}
|
|
5415
|
+
function resolveActiveSource(category, type, activeFile) {
|
|
5416
|
+
const candidates = sourcesProviding(category, type);
|
|
5417
|
+
if (candidates.length === 0) return { source: null, ambiguous: false, candidates };
|
|
5418
|
+
if (candidates.length === 1) return { source: candidates[0], ambiguous: false, candidates };
|
|
5419
|
+
const explicit = (activeFile ?? loadProvidersActive()).active[type];
|
|
5420
|
+
if (explicit && candidates.includes(explicit)) {
|
|
5421
|
+
return { source: explicit, ambiguous: false, candidates };
|
|
5422
|
+
}
|
|
5423
|
+
return { source: candidates[0], ambiguous: true, candidates };
|
|
5424
|
+
}
|
|
5425
|
+
var SOURCES_FILENAME, ACTIVE_FILENAME;
|
|
5426
|
+
var init_external_sources = __esm({
|
|
5427
|
+
"src/providers/external-sources.ts"() {
|
|
5428
|
+
"use strict";
|
|
5429
|
+
SOURCES_FILENAME = "providers-sources.json";
|
|
5430
|
+
ACTIVE_FILENAME = "providers-active.json";
|
|
5431
|
+
}
|
|
5432
|
+
});
|
|
5433
|
+
|
|
5233
5434
|
// src/cli-adapters/terminal-backends/ghostty-vt-backend.ts
|
|
5234
5435
|
function isModuleNotFoundError(error, ref) {
|
|
5235
5436
|
if (!(error instanceof Error)) return false;
|
|
@@ -5518,7 +5719,7 @@ var init_spawn_env = __esm({
|
|
|
5518
5719
|
});
|
|
5519
5720
|
|
|
5520
5721
|
// src/cli-adapters/pty-transport.ts
|
|
5521
|
-
import * as
|
|
5722
|
+
import * as os11 from "os";
|
|
5522
5723
|
function loadNodePty() {
|
|
5523
5724
|
if (cachedPty !== void 0) return cachedPty;
|
|
5524
5725
|
try {
|
|
@@ -5569,11 +5770,11 @@ var init_pty_transport = __esm({
|
|
|
5569
5770
|
let cwd = options.cwd;
|
|
5570
5771
|
if (cwd) {
|
|
5571
5772
|
try {
|
|
5572
|
-
const
|
|
5573
|
-
const stat2 =
|
|
5574
|
-
if (!stat2.isDirectory()) cwd =
|
|
5773
|
+
const fs28 = __require("fs");
|
|
5774
|
+
const stat2 = fs28.statSync(cwd);
|
|
5775
|
+
if (!stat2.isDirectory()) cwd = os11.homedir();
|
|
5575
5776
|
} catch {
|
|
5576
|
-
cwd =
|
|
5777
|
+
cwd = os11.homedir();
|
|
5577
5778
|
}
|
|
5578
5779
|
}
|
|
5579
5780
|
const handle = pty.spawn(command, args, {
|
|
@@ -5590,8 +5791,8 @@ var init_pty_transport = __esm({
|
|
|
5590
5791
|
});
|
|
5591
5792
|
|
|
5592
5793
|
// src/cli-adapters/provider-cli-shared.ts
|
|
5593
|
-
import * as
|
|
5594
|
-
import * as
|
|
5794
|
+
import * as os12 from "os";
|
|
5795
|
+
import * as path16 from "path";
|
|
5595
5796
|
function stripAnsi(str) {
|
|
5596
5797
|
return str.replace(/\x1B\][^\x07]*(?:\x07|\x1B\\)/g, "").replace(/\x1B[P^_X][\s\S]*?(?:\x07|\x1B\\)/g, "").replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "");
|
|
5597
5798
|
}
|
|
@@ -5667,21 +5868,21 @@ function buildCliScreenSnapshot(text) {
|
|
|
5667
5868
|
function findBinary(name) {
|
|
5668
5869
|
const trimmed = String(name || "").trim();
|
|
5669
5870
|
if (!trimmed) return trimmed;
|
|
5670
|
-
const expanded = trimmed.startsWith("~") ?
|
|
5671
|
-
if (
|
|
5672
|
-
return
|
|
5871
|
+
const expanded = trimmed.startsWith("~") ? path16.join(os12.homedir(), trimmed.slice(1)) : trimmed;
|
|
5872
|
+
if (path16.isAbsolute(expanded) || expanded.includes("/") || expanded.includes("\\")) {
|
|
5873
|
+
return path16.isAbsolute(expanded) ? expanded : path16.resolve(expanded);
|
|
5673
5874
|
}
|
|
5674
|
-
const isWin =
|
|
5675
|
-
const paths = (process.env.PATH || "").split(
|
|
5875
|
+
const isWin = os12.platform() === "win32";
|
|
5876
|
+
const paths = (process.env.PATH || "").split(path16.delimiter);
|
|
5676
5877
|
const exes = isWin ? [".exe", ".cmd", ".bat", ""] : [""];
|
|
5677
5878
|
for (const p of paths) {
|
|
5678
5879
|
if (!p) continue;
|
|
5679
5880
|
for (const ext of exes) {
|
|
5680
|
-
const fullPath =
|
|
5881
|
+
const fullPath = path16.join(p, trimmed + ext);
|
|
5681
5882
|
try {
|
|
5682
|
-
const
|
|
5683
|
-
if (
|
|
5684
|
-
const stat2 =
|
|
5883
|
+
const fs28 = __require("fs");
|
|
5884
|
+
if (fs28.existsSync(fullPath)) {
|
|
5885
|
+
const stat2 = fs28.statSync(fullPath);
|
|
5685
5886
|
if (stat2.isFile() && (isWin || stat2.mode & 73)) {
|
|
5686
5887
|
return fullPath;
|
|
5687
5888
|
}
|
|
@@ -5693,14 +5894,14 @@ function findBinary(name) {
|
|
|
5693
5894
|
return isWin ? `${trimmed}.cmd` : trimmed;
|
|
5694
5895
|
}
|
|
5695
5896
|
function isScriptBinary(binaryPath) {
|
|
5696
|
-
if (!
|
|
5897
|
+
if (!path16.isAbsolute(binaryPath)) return false;
|
|
5697
5898
|
try {
|
|
5698
|
-
const
|
|
5699
|
-
const resolved =
|
|
5899
|
+
const fs28 = __require("fs");
|
|
5900
|
+
const resolved = fs28.realpathSync(binaryPath);
|
|
5700
5901
|
const head = Buffer.alloc(8);
|
|
5701
|
-
const fd =
|
|
5702
|
-
|
|
5703
|
-
|
|
5902
|
+
const fd = fs28.openSync(resolved, "r");
|
|
5903
|
+
fs28.readSync(fd, head, 0, 8, 0);
|
|
5904
|
+
fs28.closeSync(fd);
|
|
5704
5905
|
let i = 0;
|
|
5705
5906
|
if (head[0] === 239 && head[1] === 187 && head[2] === 191) i = 3;
|
|
5706
5907
|
return head[i] === 35 && head[i + 1] === 33;
|
|
@@ -5709,14 +5910,14 @@ function isScriptBinary(binaryPath) {
|
|
|
5709
5910
|
}
|
|
5710
5911
|
}
|
|
5711
5912
|
function looksLikeMachOOrElf(filePath) {
|
|
5712
|
-
if (!
|
|
5913
|
+
if (!path16.isAbsolute(filePath)) return false;
|
|
5713
5914
|
try {
|
|
5714
|
-
const
|
|
5715
|
-
const resolved =
|
|
5915
|
+
const fs28 = __require("fs");
|
|
5916
|
+
const resolved = fs28.realpathSync(filePath);
|
|
5716
5917
|
const buf = Buffer.alloc(8);
|
|
5717
|
-
const fd =
|
|
5718
|
-
|
|
5719
|
-
|
|
5918
|
+
const fd = fs28.openSync(resolved, "r");
|
|
5919
|
+
fs28.readSync(fd, buf, 0, 8, 0);
|
|
5920
|
+
fs28.closeSync(fd);
|
|
5720
5921
|
let i = 0;
|
|
5721
5922
|
if (buf[0] === 239 && buf[1] === 187 && buf[2] === 191) i = 3;
|
|
5722
5923
|
const b = buf.subarray(i);
|
|
@@ -5732,7 +5933,7 @@ function looksLikeMachOOrElf(filePath) {
|
|
|
5732
5933
|
}
|
|
5733
5934
|
function shSingleQuote(arg) {
|
|
5734
5935
|
if (/^[a-zA-Z0-9@%_+=:,./-]+$/.test(arg)) return arg;
|
|
5735
|
-
if (
|
|
5936
|
+
if (os12.platform() === "win32") {
|
|
5736
5937
|
return `"${arg.replace(/"/g, '""')}"`;
|
|
5737
5938
|
}
|
|
5738
5939
|
return `'${arg.replace(/'/g, `'\\''`)}'`;
|
|
@@ -7685,23 +7886,23 @@ var init_provider_cli_config = __esm({
|
|
|
7685
7886
|
});
|
|
7686
7887
|
|
|
7687
7888
|
// src/cli-adapters/provider-cli-runtime.ts
|
|
7688
|
-
import * as
|
|
7689
|
-
import * as
|
|
7889
|
+
import * as os13 from "os";
|
|
7890
|
+
import * as path17 from "path";
|
|
7690
7891
|
import { DEFAULT_SESSION_HOST_COLS, DEFAULT_SESSION_HOST_ROWS } from "@adhdev/session-host-core";
|
|
7691
7892
|
function resolveCliSpawnPlan(options) {
|
|
7692
7893
|
const { provider, runtimeSettings, workingDir, extraArgs, extraEnv } = options;
|
|
7693
7894
|
const { spawn: spawnConfig } = provider;
|
|
7694
7895
|
const configuredCommand = typeof runtimeSettings.executablePath === "string" && runtimeSettings.executablePath.trim() ? runtimeSettings.executablePath.trim() : spawnConfig.command;
|
|
7695
7896
|
const binaryPath = findBinary(configuredCommand);
|
|
7696
|
-
const isWin =
|
|
7897
|
+
const isWin = os13.platform() === "win32";
|
|
7697
7898
|
const allArgs = [...spawnConfig.args, ...extraArgs].map(
|
|
7698
7899
|
(arg) => typeof arg === "string" ? arg.replace(/\{\{workingDir\}\}/g, workingDir) : arg
|
|
7699
7900
|
);
|
|
7700
7901
|
let shellCmd;
|
|
7701
7902
|
let shellArgs;
|
|
7702
|
-
const useShellUnix = !isWin && (!!spawnConfig.shell || !
|
|
7903
|
+
const useShellUnix = !isWin && (!!spawnConfig.shell || !path17.isAbsolute(binaryPath) || isScriptBinary(binaryPath) || !looksLikeMachOOrElf(binaryPath));
|
|
7703
7904
|
const isCmdShim = isWin && /\.(cmd|bat)$/i.test(binaryPath);
|
|
7704
|
-
const useShellWin = !!spawnConfig.shell || isCmdShim || !
|
|
7905
|
+
const useShellWin = !!spawnConfig.shell || isCmdShim || !path17.isAbsolute(binaryPath) || isScriptBinary(binaryPath);
|
|
7705
7906
|
const useShell = isWin ? useShellWin : useShellUnix;
|
|
7706
7907
|
if (useShell) {
|
|
7707
7908
|
shellCmd = isWin ? "cmd.exe" : process.env.SHELL || "/bin/zsh";
|
|
@@ -7791,7 +7992,7 @@ __export(provider_cli_adapter_exports, {
|
|
|
7791
7992
|
appendBoundedText: () => appendBoundedText,
|
|
7792
7993
|
normalizeCliProviderForRuntime: () => normalizeCliProviderForRuntime
|
|
7793
7994
|
});
|
|
7794
|
-
import * as
|
|
7995
|
+
import * as os14 from "os";
|
|
7795
7996
|
function appendBoundedText(current, chunk, maxChars) {
|
|
7796
7997
|
if (!chunk) return current.length <= maxChars ? current : current.slice(-maxChars);
|
|
7797
7998
|
if (maxChars <= 0) return "";
|
|
@@ -7824,7 +8025,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
7824
8025
|
this.transportFactory = transportFactory;
|
|
7825
8026
|
this.cliType = provider.type;
|
|
7826
8027
|
this.cliName = provider.name;
|
|
7827
|
-
this.workingDir = workingDir.startsWith("~") ? workingDir.replace(/^~/,
|
|
8028
|
+
this.workingDir = workingDir.startsWith("~") ? workingDir.replace(/^~/, os14.homedir()) : workingDir;
|
|
7828
8029
|
const resolvedConfig = resolveCliAdapterConfig(provider);
|
|
7829
8030
|
this.timeouts = resolvedConfig.timeouts;
|
|
7830
8031
|
this.approvalKeys = resolvedConfig.approvalKeys;
|
|
@@ -9968,13 +10169,13 @@ __export(loader_exports, {
|
|
|
9968
10169
|
loadSpec: () => loadSpec,
|
|
9969
10170
|
resolveSpecPath: () => resolveSpecPath
|
|
9970
10171
|
});
|
|
9971
|
-
import * as
|
|
9972
|
-
import * as
|
|
10172
|
+
import * as fs9 from "fs";
|
|
10173
|
+
import * as path18 from "path";
|
|
9973
10174
|
import Ajv from "ajv";
|
|
9974
10175
|
function loadSpec(sourcePath) {
|
|
9975
10176
|
let raw;
|
|
9976
10177
|
try {
|
|
9977
|
-
const text =
|
|
10178
|
+
const text = fs9.readFileSync(sourcePath, "utf8");
|
|
9978
10179
|
raw = JSON.parse(text);
|
|
9979
10180
|
} catch (err) {
|
|
9980
10181
|
return { ok: false, errors: [`Failed to read spec: ${err.message}`], sourcePath };
|
|
@@ -10050,7 +10251,7 @@ function compileRegex2(source, flags, where, errs) {
|
|
|
10050
10251
|
}
|
|
10051
10252
|
}
|
|
10052
10253
|
function resolveSpecPath(providerDir) {
|
|
10053
|
-
return
|
|
10254
|
+
return path18.join(providerDir, "spec.json");
|
|
10054
10255
|
}
|
|
10055
10256
|
var ajv, validate;
|
|
10056
10257
|
var init_loader = __esm({
|
|
@@ -10073,7 +10274,7 @@ __export(require_whitelist_exports, {
|
|
|
10073
10274
|
registerProviderScriptRoot: () => registerProviderScriptRoot,
|
|
10074
10275
|
unregisterProviderScriptRoot: () => unregisterProviderScriptRoot
|
|
10075
10276
|
});
|
|
10076
|
-
import * as
|
|
10277
|
+
import * as path24 from "path";
|
|
10077
10278
|
import { createRequire as createRequire3 } from "module";
|
|
10078
10279
|
import * as nodeFs from "fs";
|
|
10079
10280
|
import * as nodeChildProcess from "child_process";
|
|
@@ -10214,7 +10415,7 @@ function _getRegisteredRoots() {
|
|
|
10214
10415
|
}
|
|
10215
10416
|
function canonicalize(p) {
|
|
10216
10417
|
try {
|
|
10217
|
-
const resolved =
|
|
10418
|
+
const resolved = path24.resolve(p);
|
|
10218
10419
|
try {
|
|
10219
10420
|
return nodeFs.realpathSync.native ? nodeFs.realpathSync.native(resolved) : nodeFs.realpathSync(resolved);
|
|
10220
10421
|
} catch {
|
|
@@ -10234,7 +10435,7 @@ function isCallerInsideGatedRoot(callerFilename) {
|
|
|
10234
10435
|
}
|
|
10235
10436
|
for (const root of _gatedRoots) {
|
|
10236
10437
|
if (normalized === root.rootPath) return root;
|
|
10237
|
-
if (normalized.startsWith(root.rootPath +
|
|
10438
|
+
if (normalized.startsWith(root.rootPath + path24.sep)) return root;
|
|
10238
10439
|
}
|
|
10239
10440
|
return null;
|
|
10240
10441
|
}
|
|
@@ -10253,16 +10454,16 @@ function ensureInstalled() {
|
|
|
10253
10454
|
};
|
|
10254
10455
|
}
|
|
10255
10456
|
function gatedRequire(request, parent, isMain, gated, originalLoad) {
|
|
10256
|
-
if (request.startsWith("./") || request.startsWith("../") ||
|
|
10457
|
+
if (request.startsWith("./") || request.startsWith("../") || path24.isAbsolute(request)) {
|
|
10257
10458
|
let resolved;
|
|
10258
10459
|
try {
|
|
10259
|
-
const callerRequire = parent?.filename ? createRequire3(parent.filename) : createRequire3(
|
|
10460
|
+
const callerRequire = parent?.filename ? createRequire3(parent.filename) : createRequire3(path24.join(gated.rootPath, "__entry__.js"));
|
|
10260
10461
|
resolved = callerRequire.resolve(request);
|
|
10261
10462
|
} catch {
|
|
10262
10463
|
return originalLoad.call(this, request, parent, isMain);
|
|
10263
10464
|
}
|
|
10264
10465
|
const resolvedCanon = canonicalize(resolved) || resolved;
|
|
10265
|
-
if (!(resolvedCanon === gated.rootPath || resolvedCanon.startsWith(gated.rootPath +
|
|
10466
|
+
if (!(resolvedCanon === gated.rootPath || resolvedCanon.startsWith(gated.rootPath + path24.sep))) {
|
|
10266
10467
|
denyRequire(request, parent, `relative path escapes provider root (resolved to ${resolvedCanon})`);
|
|
10267
10468
|
}
|
|
10268
10469
|
return originalLoad.call(this, request, parent, isMain);
|
|
@@ -10378,9 +10579,9 @@ var native_history_executor_exports = {};
|
|
|
10378
10579
|
__export(native_history_executor_exports, {
|
|
10379
10580
|
executeNativeHistory: () => executeNativeHistory
|
|
10380
10581
|
});
|
|
10381
|
-
import * as
|
|
10382
|
-
import * as
|
|
10383
|
-
import * as
|
|
10582
|
+
import * as fs13 from "fs";
|
|
10583
|
+
import * as os18 from "os";
|
|
10584
|
+
import * as path25 from "path";
|
|
10384
10585
|
function executeNativeHistory(cfg, input) {
|
|
10385
10586
|
if (!cfg?.source) return null;
|
|
10386
10587
|
if (cfg.source.kind === "jsonl") return executeJsonl(cfg.source, input);
|
|
@@ -10399,7 +10600,7 @@ function executeJsonl(src, input) {
|
|
|
10399
10600
|
} else {
|
|
10400
10601
|
let stat2 = null;
|
|
10401
10602
|
try {
|
|
10402
|
-
stat2 =
|
|
10603
|
+
stat2 = fs13.statSync(resolved);
|
|
10403
10604
|
} catch {
|
|
10404
10605
|
return null;
|
|
10405
10606
|
}
|
|
@@ -10418,7 +10619,7 @@ function executeJsonl(src, input) {
|
|
|
10418
10619
|
const v = jsonPathGet(lines[0], src.session_id_path);
|
|
10419
10620
|
if (typeof v === "string" && v) providerSessionId = v;
|
|
10420
10621
|
} else if (src.session_id_from === "filename_uuid" || !src.session_id_from) {
|
|
10421
|
-
const m =
|
|
10622
|
+
const m = path25.basename(sourcePath).match(UUID_RE);
|
|
10422
10623
|
if (m) providerSessionId = m[1];
|
|
10423
10624
|
}
|
|
10424
10625
|
const requested = input.providerSessionId || "";
|
|
@@ -10443,7 +10644,7 @@ function executeJsonl(src, input) {
|
|
|
10443
10644
|
function readJsonlLines(p) {
|
|
10444
10645
|
let text;
|
|
10445
10646
|
try {
|
|
10446
|
-
text =
|
|
10647
|
+
text = fs13.readFileSync(p, "utf8");
|
|
10447
10648
|
} catch {
|
|
10448
10649
|
return [];
|
|
10449
10650
|
}
|
|
@@ -10460,7 +10661,7 @@ function readJsonlLines(p) {
|
|
|
10460
10661
|
}
|
|
10461
10662
|
function executeSqlite(src, input) {
|
|
10462
10663
|
const resolved = expandPath2(src.path, input);
|
|
10463
|
-
if (!resolved || !
|
|
10664
|
+
if (!resolved || !fs13.existsSync(resolved)) return null;
|
|
10464
10665
|
let Database;
|
|
10465
10666
|
try {
|
|
10466
10667
|
Database = __require("better-sqlite3");
|
|
@@ -10519,17 +10720,25 @@ function expandPath2(template, input) {
|
|
|
10519
10720
|
if (!template) return null;
|
|
10520
10721
|
let out = template;
|
|
10521
10722
|
if (out.startsWith("~/") || out === "~") {
|
|
10522
|
-
out =
|
|
10723
|
+
out = path25.join(os18.homedir(), out.slice(2));
|
|
10523
10724
|
}
|
|
10524
10725
|
out = out.replace(/\$\{([A-Z_][A-Z0-9_]*)(?::-(.*?))?\}/g, (_m, name, fallback) => {
|
|
10525
10726
|
const v = input.envOverrides?.[name] ?? process.env[name];
|
|
10526
10727
|
return v != null && v !== "" ? v : fallback ?? "";
|
|
10527
10728
|
});
|
|
10528
|
-
if (out.startsWith("~/")) out =
|
|
10729
|
+
if (out.startsWith("~/")) out = path25.join(os18.homedir(), out.slice(2));
|
|
10529
10730
|
const now = /* @__PURE__ */ new Date();
|
|
10731
|
+
const workspaceRaw = input.workspace ?? "";
|
|
10732
|
+
let workspaceResolved = workspaceRaw;
|
|
10733
|
+
if (workspaceRaw) {
|
|
10734
|
+
try {
|
|
10735
|
+
workspaceResolved = fs13.realpathSync(workspaceRaw);
|
|
10736
|
+
} catch {
|
|
10737
|
+
}
|
|
10738
|
+
}
|
|
10530
10739
|
const vars = {
|
|
10531
|
-
cwd:
|
|
10532
|
-
cwd_dashed:
|
|
10740
|
+
cwd: workspaceResolved,
|
|
10741
|
+
cwd_dashed: workspaceResolved.replace(/\//g, "-"),
|
|
10533
10742
|
session_id: input.providerSessionId || input.sessionId || input.historySessionId || "",
|
|
10534
10743
|
yyyy: String(now.getUTCFullYear()),
|
|
10535
10744
|
mm: String(now.getUTCMonth() + 1).padStart(2, "0"),
|
|
@@ -10565,20 +10774,20 @@ function expandDirGlob(template) {
|
|
|
10565
10774
|
for (const d of dirs) {
|
|
10566
10775
|
let entries;
|
|
10567
10776
|
try {
|
|
10568
|
-
entries =
|
|
10777
|
+
entries = fs13.readdirSync(d, { withFileTypes: true });
|
|
10569
10778
|
} catch {
|
|
10570
10779
|
continue;
|
|
10571
10780
|
}
|
|
10572
10781
|
for (const e of entries) {
|
|
10573
|
-
if (e.isDirectory() && re.test(e.name)) next.push(
|
|
10782
|
+
if (e.isDirectory() && re.test(e.name)) next.push(path25.join(d, e.name));
|
|
10574
10783
|
}
|
|
10575
10784
|
}
|
|
10576
10785
|
} else {
|
|
10577
10786
|
for (const d of dirs) {
|
|
10578
|
-
const candidate =
|
|
10787
|
+
const candidate = path25.join(d, seg);
|
|
10579
10788
|
let stat2 = null;
|
|
10580
10789
|
try {
|
|
10581
|
-
stat2 =
|
|
10790
|
+
stat2 = fs13.statSync(candidate);
|
|
10582
10791
|
} catch {
|
|
10583
10792
|
continue;
|
|
10584
10793
|
}
|
|
@@ -10592,13 +10801,13 @@ function expandDirGlob(template) {
|
|
|
10592
10801
|
function walkAllDirs(root, out) {
|
|
10593
10802
|
let entries;
|
|
10594
10803
|
try {
|
|
10595
|
-
entries =
|
|
10804
|
+
entries = fs13.readdirSync(root, { withFileTypes: true });
|
|
10596
10805
|
} catch {
|
|
10597
10806
|
return;
|
|
10598
10807
|
}
|
|
10599
10808
|
out.push(root);
|
|
10600
10809
|
for (const e of entries) {
|
|
10601
|
-
if (e.isDirectory()) walkAllDirs(
|
|
10810
|
+
if (e.isDirectory()) walkAllDirs(path25.join(root, e.name), out);
|
|
10602
10811
|
}
|
|
10603
10812
|
}
|
|
10604
10813
|
function newestRecentFileAcrossGlob(template, pattern, windowMs, sessionFloorMs = 0) {
|
|
@@ -10608,13 +10817,13 @@ function newestRecentFileAcrossGlob(template, pattern, windowMs, sessionFloorMs
|
|
|
10608
10817
|
for (const d of dirs) {
|
|
10609
10818
|
let entries;
|
|
10610
10819
|
try {
|
|
10611
|
-
entries =
|
|
10820
|
+
entries = fs13.readdirSync(d, { withFileTypes: true });
|
|
10612
10821
|
} catch {
|
|
10613
10822
|
continue;
|
|
10614
10823
|
}
|
|
10615
10824
|
for (const e of entries) {
|
|
10616
10825
|
if (!e.isFile() || !pattern.test(e.name)) continue;
|
|
10617
|
-
const p =
|
|
10826
|
+
const p = path25.join(d, e.name);
|
|
10618
10827
|
const mtime = safeMtimeMs(p);
|
|
10619
10828
|
if (mtime < cutoff) continue;
|
|
10620
10829
|
if (!best || mtime > best.mtime) best = { p, mtime };
|
|
@@ -10625,7 +10834,7 @@ function newestRecentFileAcrossGlob(template, pattern, windowMs, sessionFloorMs
|
|
|
10625
10834
|
function newestRecentFile(dir, pattern, windowMs, sessionFloorMs = 0) {
|
|
10626
10835
|
let entries;
|
|
10627
10836
|
try {
|
|
10628
|
-
entries =
|
|
10837
|
+
entries = fs13.readdirSync(dir, { withFileTypes: true });
|
|
10629
10838
|
} catch {
|
|
10630
10839
|
return null;
|
|
10631
10840
|
}
|
|
@@ -10633,7 +10842,7 @@ function newestRecentFile(dir, pattern, windowMs, sessionFloorMs = 0) {
|
|
|
10633
10842
|
let best = null;
|
|
10634
10843
|
for (const e of entries) {
|
|
10635
10844
|
if (!e.isFile() || !pattern.test(e.name)) continue;
|
|
10636
|
-
const p =
|
|
10845
|
+
const p = path25.join(dir, e.name);
|
|
10637
10846
|
const mtime = safeMtimeMs(p);
|
|
10638
10847
|
if (mtime < cutoff) continue;
|
|
10639
10848
|
if (!best || mtime > best.mtime) best = { p, mtime };
|
|
@@ -10642,7 +10851,7 @@ function newestRecentFile(dir, pattern, windowMs, sessionFloorMs = 0) {
|
|
|
10642
10851
|
}
|
|
10643
10852
|
function safeMtimeMs(p) {
|
|
10644
10853
|
try {
|
|
10645
|
-
return Math.floor(
|
|
10854
|
+
return Math.floor(fs13.statSync(p).mtimeMs);
|
|
10646
10855
|
} catch {
|
|
10647
10856
|
return 0;
|
|
10648
10857
|
}
|
|
@@ -10855,8 +11064,8 @@ var init_native_history_executor = __esm({
|
|
|
10855
11064
|
});
|
|
10856
11065
|
|
|
10857
11066
|
// src/providers/native-history/claude-cli-transcript.ts
|
|
10858
|
-
import * as
|
|
10859
|
-
import * as
|
|
11067
|
+
import * as fs14 from "fs";
|
|
11068
|
+
import * as path26 from "path";
|
|
10860
11069
|
function extractTimestampValue(value) {
|
|
10861
11070
|
if (typeof value === "number" && Number.isFinite(value) && value > 0) return value;
|
|
10862
11071
|
if (typeof value === "string") {
|
|
@@ -10869,7 +11078,7 @@ function extractTimestampValue(value) {
|
|
|
10869
11078
|
}
|
|
10870
11079
|
function statMtimeMs(filePath) {
|
|
10871
11080
|
try {
|
|
10872
|
-
return
|
|
11081
|
+
return fs14.statSync(filePath).mtimeMs;
|
|
10873
11082
|
} catch {
|
|
10874
11083
|
return 0;
|
|
10875
11084
|
}
|
|
@@ -10939,7 +11148,7 @@ function extractUserContentParts(content) {
|
|
|
10939
11148
|
function parseTranscriptFile(filePath, sessionId, workspaceFallback) {
|
|
10940
11149
|
let raw;
|
|
10941
11150
|
try {
|
|
10942
|
-
raw =
|
|
11151
|
+
raw = fs14.readFileSync(filePath, "utf-8");
|
|
10943
11152
|
} catch {
|
|
10944
11153
|
return [];
|
|
10945
11154
|
}
|
|
@@ -11012,10 +11221,10 @@ function parseTranscriptFile(filePath, sessionId, workspaceFallback) {
|
|
|
11012
11221
|
return records;
|
|
11013
11222
|
}
|
|
11014
11223
|
function readSession(sessionPath) {
|
|
11015
|
-
if (!sessionPath || !
|
|
11016
|
-
const basename12 =
|
|
11224
|
+
if (!sessionPath || !path26.isAbsolute(sessionPath)) return null;
|
|
11225
|
+
const basename12 = path26.basename(sessionPath, ".jsonl");
|
|
11017
11226
|
if (!isSafeSessionId(basename12)) return null;
|
|
11018
|
-
if (!
|
|
11227
|
+
if (!fs14.existsSync(sessionPath)) return null;
|
|
11019
11228
|
const sourceMtimeMs = statMtimeMs(sessionPath);
|
|
11020
11229
|
const messages = parseTranscriptFile(sessionPath, basename12);
|
|
11021
11230
|
if (messages.length === 0) return null;
|
|
@@ -11038,8 +11247,8 @@ var init_claude_cli_transcript = __esm({
|
|
|
11038
11247
|
});
|
|
11039
11248
|
|
|
11040
11249
|
// src/providers/native-history/codex-cli-transcript.ts
|
|
11041
|
-
import * as
|
|
11042
|
-
import * as
|
|
11250
|
+
import * as fs15 from "fs";
|
|
11251
|
+
import * as path27 from "path";
|
|
11043
11252
|
function extractTimestampValue2(value) {
|
|
11044
11253
|
if (typeof value === "number" && Number.isFinite(value) && value > 0) return value;
|
|
11045
11254
|
if (typeof value === "string") {
|
|
@@ -11052,7 +11261,7 @@ function extractTimestampValue2(value) {
|
|
|
11052
11261
|
}
|
|
11053
11262
|
function statMtimeMs2(filePath) {
|
|
11054
11263
|
try {
|
|
11055
|
-
return
|
|
11264
|
+
return fs15.statSync(filePath).mtimeMs;
|
|
11056
11265
|
} catch {
|
|
11057
11266
|
return 0;
|
|
11058
11267
|
}
|
|
@@ -11120,7 +11329,7 @@ function extractToolOutputContent(payload) {
|
|
|
11120
11329
|
}
|
|
11121
11330
|
function readSessionMeta(filePath) {
|
|
11122
11331
|
try {
|
|
11123
|
-
const firstLine =
|
|
11332
|
+
const firstLine = fs15.readFileSync(filePath, "utf-8").split("\n").find(Boolean);
|
|
11124
11333
|
if (!firstLine) return null;
|
|
11125
11334
|
const parsed = JSON.parse(firstLine);
|
|
11126
11335
|
if (String(parsed.type ?? "") !== "session_meta") return null;
|
|
@@ -11132,7 +11341,7 @@ function readSessionMeta(filePath) {
|
|
|
11132
11341
|
function parseSessionFile(filePath, sessionId, workspaceFallback) {
|
|
11133
11342
|
let raw;
|
|
11134
11343
|
try {
|
|
11135
|
-
raw =
|
|
11344
|
+
raw = fs15.readFileSync(filePath, "utf-8");
|
|
11136
11345
|
} catch {
|
|
11137
11346
|
return [];
|
|
11138
11347
|
}
|
|
@@ -11226,11 +11435,11 @@ function parseSessionFile(filePath, sessionId, workspaceFallback) {
|
|
|
11226
11435
|
return records;
|
|
11227
11436
|
}
|
|
11228
11437
|
function readSession2(sessionPath) {
|
|
11229
|
-
if (!sessionPath || !
|
|
11230
|
-
if (!
|
|
11438
|
+
if (!sessionPath || !path27.isAbsolute(sessionPath)) return null;
|
|
11439
|
+
if (!fs15.existsSync(sessionPath)) return null;
|
|
11231
11440
|
const meta = readSessionMeta(sessionPath);
|
|
11232
11441
|
const metaId = String(meta?.id ?? "").trim();
|
|
11233
|
-
const basename12 =
|
|
11442
|
+
const basename12 = path27.basename(sessionPath, ".jsonl");
|
|
11234
11443
|
const uuidMatch = basename12.match(/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/i);
|
|
11235
11444
|
const filenameUuid = uuidMatch ? uuidMatch[1] : "";
|
|
11236
11445
|
if (metaId && filenameUuid && metaId !== filenameUuid) return null;
|
|
@@ -11259,9 +11468,9 @@ var init_codex_cli_transcript = __esm({
|
|
|
11259
11468
|
});
|
|
11260
11469
|
|
|
11261
11470
|
// src/providers/native-history/antigravity-cli-transcript.ts
|
|
11262
|
-
import * as
|
|
11263
|
-
import * as
|
|
11264
|
-
import * as
|
|
11471
|
+
import * as fs16 from "fs";
|
|
11472
|
+
import * as path28 from "path";
|
|
11473
|
+
import * as os19 from "os";
|
|
11265
11474
|
function extractTimestampValue3(value) {
|
|
11266
11475
|
if (typeof value === "number" && Number.isFinite(value) && value > 0) return value;
|
|
11267
11476
|
if (typeof value === "string") {
|
|
@@ -11274,7 +11483,7 @@ function extractTimestampValue3(value) {
|
|
|
11274
11483
|
}
|
|
11275
11484
|
function statMtimeMs3(filePath) {
|
|
11276
11485
|
try {
|
|
11277
|
-
return
|
|
11486
|
+
return fs16.statSync(filePath).mtimeMs;
|
|
11278
11487
|
} catch {
|
|
11279
11488
|
return 0;
|
|
11280
11489
|
}
|
|
@@ -11283,13 +11492,13 @@ function isUuidLike(value) {
|
|
|
11283
11492
|
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value);
|
|
11284
11493
|
}
|
|
11285
11494
|
function antigravityRoot() {
|
|
11286
|
-
return
|
|
11495
|
+
return path28.join(os19.homedir(), ".gemini", "antigravity-cli");
|
|
11287
11496
|
}
|
|
11288
11497
|
function historyJsonlPath() {
|
|
11289
|
-
return
|
|
11498
|
+
return path28.join(antigravityRoot(), "history.jsonl");
|
|
11290
11499
|
}
|
|
11291
11500
|
function brainRoot() {
|
|
11292
|
-
return
|
|
11501
|
+
return path28.join(antigravityRoot(), "brain");
|
|
11293
11502
|
}
|
|
11294
11503
|
function extractUserRequestContent(content) {
|
|
11295
11504
|
const raw = content.trim();
|
|
@@ -11305,7 +11514,7 @@ function antigravityRowKind(rowType) {
|
|
|
11305
11514
|
function parseBrainTranscript(filePath, sessionId, workspace) {
|
|
11306
11515
|
let raw;
|
|
11307
11516
|
try {
|
|
11308
|
-
raw =
|
|
11517
|
+
raw = fs16.readFileSync(filePath, "utf-8");
|
|
11309
11518
|
} catch {
|
|
11310
11519
|
return null;
|
|
11311
11520
|
}
|
|
@@ -11365,7 +11574,7 @@ function readHistoryRows() {
|
|
|
11365
11574
|
const sourcePath = historyJsonlPath();
|
|
11366
11575
|
let lines = [];
|
|
11367
11576
|
try {
|
|
11368
|
-
lines =
|
|
11577
|
+
lines = fs16.readFileSync(sourcePath, "utf-8").split("\n").filter(Boolean);
|
|
11369
11578
|
} catch {
|
|
11370
11579
|
return [];
|
|
11371
11580
|
}
|
|
@@ -11412,7 +11621,7 @@ function extractStringsFromBuffer(buf) {
|
|
|
11412
11621
|
function parsePbFile(filePath, sessionId) {
|
|
11413
11622
|
let buf;
|
|
11414
11623
|
try {
|
|
11415
|
-
buf =
|
|
11624
|
+
buf = fs16.readFileSync(filePath);
|
|
11416
11625
|
} catch {
|
|
11417
11626
|
return null;
|
|
11418
11627
|
}
|
|
@@ -11435,13 +11644,13 @@ function parsePbFile(filePath, sessionId) {
|
|
|
11435
11644
|
];
|
|
11436
11645
|
}
|
|
11437
11646
|
function readSession3(sessionPath, sessionId, workspace) {
|
|
11438
|
-
if (!sessionPath || !
|
|
11439
|
-
if (!
|
|
11647
|
+
if (!sessionPath || !path28.isAbsolute(sessionPath)) return null;
|
|
11648
|
+
if (!fs16.existsSync(sessionPath)) return null;
|
|
11440
11649
|
const sourceMtimeMs = statMtimeMs3(sessionPath);
|
|
11441
11650
|
const brainRootPath = brainRoot();
|
|
11442
|
-
if (sessionPath.startsWith(brainRootPath +
|
|
11443
|
-
const
|
|
11444
|
-
const uuidFromPath =
|
|
11651
|
+
if (sessionPath.startsWith(brainRootPath + path28.sep) && sessionPath.endsWith(".jsonl")) {
|
|
11652
|
+
const relative5 = sessionPath.slice(brainRootPath.length + 1);
|
|
11653
|
+
const uuidFromPath = relative5.split(path28.sep)[0];
|
|
11445
11654
|
const resolvedSessionId = sessionId || (isUuidLike(uuidFromPath) ? uuidFromPath : "");
|
|
11446
11655
|
if (!resolvedSessionId) return null;
|
|
11447
11656
|
const messages = parseBrainTranscript(sessionPath, resolvedSessionId, workspace);
|
|
@@ -11457,7 +11666,7 @@ function readSession3(sessionPath, sessionId, workspace) {
|
|
|
11457
11666
|
};
|
|
11458
11667
|
}
|
|
11459
11668
|
if (sessionPath.endsWith(".pb")) {
|
|
11460
|
-
const pbSessionId = sessionId ||
|
|
11669
|
+
const pbSessionId = sessionId || path28.basename(sessionPath, ".pb");
|
|
11461
11670
|
if (!isUuidLike(pbSessionId)) return null;
|
|
11462
11671
|
const messages = parsePbFile(sessionPath, pbSessionId);
|
|
11463
11672
|
if (!messages || messages.length === 0) return null;
|
|
@@ -11471,7 +11680,7 @@ function readSession3(sessionPath, sessionId, workspace) {
|
|
|
11471
11680
|
partialReason: "antigravity_cli_pb_raw_text_extraction"
|
|
11472
11681
|
};
|
|
11473
11682
|
}
|
|
11474
|
-
if (
|
|
11683
|
+
if (path28.basename(sessionPath) === "history.jsonl") {
|
|
11475
11684
|
const resolvedSessionId = sessionId || "";
|
|
11476
11685
|
if (!resolvedSessionId || !isUuidLike(resolvedSessionId)) return null;
|
|
11477
11686
|
const rows = readHistoryRows().filter((r) => r.conversationId === resolvedSessionId);
|
|
@@ -11525,18 +11734,18 @@ var init_antigravity_cli_transcript = __esm({
|
|
|
11525
11734
|
});
|
|
11526
11735
|
|
|
11527
11736
|
// src/providers/native-history/hermes-cli-transcript.ts
|
|
11528
|
-
import * as
|
|
11529
|
-
import * as
|
|
11530
|
-
import * as
|
|
11737
|
+
import * as fs17 from "fs";
|
|
11738
|
+
import * as path29 from "path";
|
|
11739
|
+
import * as os20 from "os";
|
|
11531
11740
|
function statMtimeMs4(p) {
|
|
11532
11741
|
try {
|
|
11533
|
-
return Math.floor(
|
|
11742
|
+
return Math.floor(fs17.statSync(p).mtimeMs);
|
|
11534
11743
|
} catch {
|
|
11535
11744
|
return 0;
|
|
11536
11745
|
}
|
|
11537
11746
|
}
|
|
11538
11747
|
function openDb() {
|
|
11539
|
-
if (!
|
|
11748
|
+
if (!fs17.existsSync(HERMES_STATE_DB)) return null;
|
|
11540
11749
|
try {
|
|
11541
11750
|
const Database = __require("better-sqlite3");
|
|
11542
11751
|
return new Database(HERMES_STATE_DB, { readonly: true, fileMustExist: true });
|
|
@@ -11593,10 +11802,10 @@ function readSession4(sessionPath) {
|
|
|
11593
11802
|
}
|
|
11594
11803
|
}
|
|
11595
11804
|
}
|
|
11596
|
-
if (!
|
|
11805
|
+
if (!path29.isAbsolute(sessionPath) || !fs17.existsSync(sessionPath)) return null;
|
|
11597
11806
|
let raw;
|
|
11598
11807
|
try {
|
|
11599
|
-
raw = JSON.parse(
|
|
11808
|
+
raw = JSON.parse(fs17.readFileSync(sessionPath, "utf8"));
|
|
11600
11809
|
} catch {
|
|
11601
11810
|
return null;
|
|
11602
11811
|
}
|
|
@@ -11619,7 +11828,7 @@ function readSession4(sessionPath) {
|
|
|
11619
11828
|
});
|
|
11620
11829
|
}
|
|
11621
11830
|
if (messages.length === 0) return null;
|
|
11622
|
-
const sessionId = typeof raw.session_id === "string" && raw.session_id ? raw.session_id :
|
|
11831
|
+
const sessionId = typeof raw.session_id === "string" && raw.session_id ? raw.session_id : path29.basename(sessionPath, ".json").replace(/^session_/, "");
|
|
11623
11832
|
return {
|
|
11624
11833
|
messages,
|
|
11625
11834
|
providerSessionId: sessionId,
|
|
@@ -11640,8 +11849,8 @@ var HERMES_STATE_DB, HERMES_LEGACY_SESSIONS_DIR;
|
|
|
11640
11849
|
var init_hermes_cli_transcript = __esm({
|
|
11641
11850
|
"src/providers/native-history/hermes-cli-transcript.ts"() {
|
|
11642
11851
|
"use strict";
|
|
11643
|
-
HERMES_STATE_DB =
|
|
11644
|
-
HERMES_LEGACY_SESSIONS_DIR =
|
|
11852
|
+
HERMES_STATE_DB = path29.join(os20.homedir(), ".hermes", "state.db");
|
|
11853
|
+
HERMES_LEGACY_SESSIONS_DIR = path29.join(os20.homedir(), ".hermes", "sessions");
|
|
11645
11854
|
}
|
|
11646
11855
|
});
|
|
11647
11856
|
|
|
@@ -11650,9 +11859,9 @@ var dispatcher_exports = {};
|
|
|
11650
11859
|
__export(dispatcher_exports, {
|
|
11651
11860
|
createNativeHistoryDispatcher: () => createNativeHistoryDispatcher
|
|
11652
11861
|
});
|
|
11653
|
-
import * as
|
|
11654
|
-
import * as
|
|
11655
|
-
import * as
|
|
11862
|
+
import * as fs18 from "fs";
|
|
11863
|
+
import * as os21 from "os";
|
|
11864
|
+
import * as path30 from "path";
|
|
11656
11865
|
function createNativeHistoryDispatcher(reader) {
|
|
11657
11866
|
return (input) => {
|
|
11658
11867
|
const workspace = input.workspace || "";
|
|
@@ -11692,26 +11901,26 @@ function resolveSourcePath(reader, workspace, sessionId) {
|
|
|
11692
11901
|
}
|
|
11693
11902
|
}
|
|
11694
11903
|
function resolveClaudePath(workspace, sessionId) {
|
|
11695
|
-
const dir =
|
|
11696
|
-
if (!
|
|
11904
|
+
const dir = path30.join(os21.homedir(), ".claude", "projects", cwdAsDashes(workspace));
|
|
11905
|
+
if (!fs18.existsSync(dir)) return null;
|
|
11697
11906
|
if (sessionId) {
|
|
11698
|
-
const candidate =
|
|
11699
|
-
if (
|
|
11907
|
+
const candidate = path30.join(dir, `${sessionId}.jsonl`);
|
|
11908
|
+
if (fs18.existsSync(candidate)) return candidate;
|
|
11700
11909
|
}
|
|
11701
11910
|
return null;
|
|
11702
11911
|
}
|
|
11703
11912
|
function resolveCodexPath(workspace) {
|
|
11704
11913
|
void workspace;
|
|
11705
11914
|
const now = /* @__PURE__ */ new Date();
|
|
11706
|
-
const dir =
|
|
11707
|
-
|
|
11915
|
+
const dir = path30.join(
|
|
11916
|
+
os21.homedir(),
|
|
11708
11917
|
".codex",
|
|
11709
11918
|
"sessions",
|
|
11710
11919
|
String(now.getUTCFullYear()),
|
|
11711
11920
|
String(now.getUTCMonth() + 1).padStart(2, "0"),
|
|
11712
11921
|
String(now.getUTCDate()).padStart(2, "0")
|
|
11713
11922
|
);
|
|
11714
|
-
if (
|
|
11923
|
+
if (fs18.existsSync(dir)) {
|
|
11715
11924
|
const f = newestRecentFile2(dir, /\.jsonl$/);
|
|
11716
11925
|
if (f) return f;
|
|
11717
11926
|
}
|
|
@@ -11719,23 +11928,23 @@ function resolveCodexPath(workspace) {
|
|
|
11719
11928
|
}
|
|
11720
11929
|
function resolveAntigravityPath(workspace) {
|
|
11721
11930
|
void workspace;
|
|
11722
|
-
const brainRoot2 =
|
|
11723
|
-
if (!
|
|
11931
|
+
const brainRoot2 = path30.join(os21.homedir(), ".gemini", "antigravity-cli", "brain");
|
|
11932
|
+
if (!fs18.existsSync(brainRoot2)) return null;
|
|
11724
11933
|
const cutoff = Date.now() - RECENT_WINDOW_MS;
|
|
11725
|
-
const entries =
|
|
11934
|
+
const entries = fs18.readdirSync(brainRoot2, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => ({ p: path30.join(brainRoot2, e.name), mtime: safeMtime(path30.join(brainRoot2, e.name)) })).filter((e) => e.mtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
|
|
11726
11935
|
for (const e of entries) {
|
|
11727
|
-
const t =
|
|
11728
|
-
if (
|
|
11936
|
+
const t = path30.join(e.p, ".system_generated", "logs", "transcript.jsonl");
|
|
11937
|
+
if (fs18.existsSync(t)) return t;
|
|
11729
11938
|
}
|
|
11730
11939
|
return null;
|
|
11731
11940
|
}
|
|
11732
11941
|
function resolveHermesPath(workspace, sessionId) {
|
|
11733
11942
|
void workspace;
|
|
11734
11943
|
void sessionId;
|
|
11735
|
-
const dbPath =
|
|
11736
|
-
if (
|
|
11737
|
-
const dir =
|
|
11738
|
-
if (!
|
|
11944
|
+
const dbPath = path30.join(os21.homedir(), ".hermes", "state.db");
|
|
11945
|
+
if (fs18.existsSync(dbPath)) return dbPath;
|
|
11946
|
+
const dir = path30.join(os21.homedir(), ".hermes", "sessions");
|
|
11947
|
+
if (!fs18.existsSync(dir)) return null;
|
|
11739
11948
|
return newestRecentFile2(dir, /^session_.*\.json$/);
|
|
11740
11949
|
}
|
|
11741
11950
|
function readByReader(reader, sourcePath, sessionId, workspace) {
|
|
@@ -11757,7 +11966,7 @@ function cwdAsDashes(cwd) {
|
|
|
11757
11966
|
function newestRecentFile2(dir, pattern) {
|
|
11758
11967
|
try {
|
|
11759
11968
|
const cutoff = Date.now() - RECENT_WINDOW_MS;
|
|
11760
|
-
const entries =
|
|
11969
|
+
const entries = fs18.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && pattern.test(e.name)).map((e) => ({ p: path30.join(dir, e.name), mtime: safeMtime(path30.join(dir, e.name)) })).filter((e) => e.mtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
|
|
11761
11970
|
return entries[0]?.p ?? null;
|
|
11762
11971
|
} catch {
|
|
11763
11972
|
return null;
|
|
@@ -11765,7 +11974,7 @@ function newestRecentFile2(dir, pattern) {
|
|
|
11765
11974
|
}
|
|
11766
11975
|
function safeMtime(p) {
|
|
11767
11976
|
try {
|
|
11768
|
-
return Math.floor(
|
|
11977
|
+
return Math.floor(fs18.statSync(p).mtimeMs);
|
|
11769
11978
|
} catch {
|
|
11770
11979
|
return 0;
|
|
11771
11980
|
}
|
|
@@ -12033,12 +12242,12 @@ function parseSubmoduleStatusOutput(output, repoRoot, ignorePaths) {
|
|
|
12033
12242
|
if (!match) continue;
|
|
12034
12243
|
const prefix = match[1];
|
|
12035
12244
|
const commit = match[2];
|
|
12036
|
-
const
|
|
12037
|
-
if (ignoreSet.has(
|
|
12245
|
+
const path40 = match[3];
|
|
12246
|
+
if (ignoreSet.has(path40)) continue;
|
|
12038
12247
|
submodules.push({
|
|
12039
|
-
path:
|
|
12248
|
+
path: path40,
|
|
12040
12249
|
commit,
|
|
12041
|
-
repoPath: repoRoot + "/" +
|
|
12250
|
+
repoPath: repoRoot + "/" + path40,
|
|
12042
12251
|
dirty: prefix === "+",
|
|
12043
12252
|
outOfSync: prefix === "-",
|
|
12044
12253
|
lastCheckedAt: Date.now()
|
|
@@ -13542,10 +13751,10 @@ function getRegistryPath() {
|
|
|
13542
13751
|
return join8(getDaemonDataDir(), "mesh-coordinators.json");
|
|
13543
13752
|
}
|
|
13544
13753
|
function loadMeshCoordinatorRegistry() {
|
|
13545
|
-
const
|
|
13546
|
-
if (!existsSync7(
|
|
13754
|
+
const path40 = getRegistryPath();
|
|
13755
|
+
if (!existsSync7(path40)) return;
|
|
13547
13756
|
try {
|
|
13548
|
-
const raw = JSON.parse(readFileSync5(
|
|
13757
|
+
const raw = JSON.parse(readFileSync5(path40, "utf-8"));
|
|
13549
13758
|
if (!Array.isArray(raw)) return;
|
|
13550
13759
|
_registry.clear();
|
|
13551
13760
|
for (const entry of raw) {
|
|
@@ -13764,8 +13973,8 @@ function validateMeshRefineConfig(config, source = "inline") {
|
|
|
13764
13973
|
if (rejectedCommands.length) errors.push("one or more validation commands are invalid");
|
|
13765
13974
|
return { valid: errors.length === 0, errors, bootstrapCommands, commands, rejectedCommands };
|
|
13766
13975
|
}
|
|
13767
|
-
function parseConfigText(
|
|
13768
|
-
if (/\.json$/i.test(
|
|
13976
|
+
function parseConfigText(path40, text) {
|
|
13977
|
+
if (/\.json$/i.test(path40)) return JSON.parse(text);
|
|
13769
13978
|
return yaml.load(text);
|
|
13770
13979
|
}
|
|
13771
13980
|
function loadMeshRefineConfig(mesh, workspace) {
|
|
@@ -13776,16 +13985,16 @@ function loadMeshRefineConfig(mesh, workspace) {
|
|
|
13776
13985
|
if (!validation.valid) return { source: "mesh.policy.refineConfig", sourceType: "invalid", error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
|
|
13777
13986
|
return { config: inline, source: "mesh.policy.refineConfig", sourceType: "mesh_policy" };
|
|
13778
13987
|
}
|
|
13779
|
-
for (const
|
|
13780
|
-
const configPath = join9(workspace,
|
|
13988
|
+
for (const relative5 of MESH_REFINE_CONFIG_LOCATIONS) {
|
|
13989
|
+
const configPath = join9(workspace, relative5);
|
|
13781
13990
|
if (!existsSync8(configPath)) continue;
|
|
13782
13991
|
try {
|
|
13783
13992
|
const parsed = parseConfigText(configPath, readFileSync6(configPath, "utf-8"));
|
|
13784
|
-
const validation = validateMeshRefineConfig(parsed,
|
|
13785
|
-
if (!validation.valid) return { source:
|
|
13786
|
-
return { config: parsed, source:
|
|
13993
|
+
const validation = validateMeshRefineConfig(parsed, relative5);
|
|
13994
|
+
if (!validation.valid) return { source: relative5, sourceType: "invalid", path: configPath, error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
|
|
13995
|
+
return { config: parsed, source: relative5, sourceType: "repo_file", path: configPath };
|
|
13787
13996
|
} catch (error) {
|
|
13788
|
-
return { source:
|
|
13997
|
+
return { source: relative5, sourceType: "invalid", path: configPath, error: error?.message || String(error) };
|
|
13789
13998
|
}
|
|
13790
13999
|
}
|
|
13791
14000
|
return {
|
|
@@ -13918,8 +14127,8 @@ var MESH_WORKTREE_BOOTSTRAP_CONFIG_SCHEMA = {
|
|
|
13918
14127
|
var DEFAULT_TIMEOUT_MS2 = 12e4;
|
|
13919
14128
|
var DEFAULT_OUTPUT_LIMIT_BYTES = 128 * 1024;
|
|
13920
14129
|
var OUTPUT_SUMMARY_CHARS = 2e3;
|
|
13921
|
-
function parseConfigText2(
|
|
13922
|
-
if (/\.json$/i.test(
|
|
14130
|
+
function parseConfigText2(path40, text) {
|
|
14131
|
+
if (/\.json$/i.test(path40)) return JSON.parse(text);
|
|
13923
14132
|
return yaml2.load(text);
|
|
13924
14133
|
}
|
|
13925
14134
|
function truncateOutput(value) {
|
|
@@ -13959,16 +14168,16 @@ function loadMeshWorktreeBootstrapConfig(mesh, workspace) {
|
|
|
13959
14168
|
if (!validation.valid) return { source: "mesh.policy.worktreeBootstrapConfig", sourceType: "invalid", error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
|
|
13960
14169
|
return { config: inline, source: "mesh.policy.worktreeBootstrapConfig", sourceType: "mesh_policy" };
|
|
13961
14170
|
}
|
|
13962
|
-
for (const
|
|
13963
|
-
const configPath = join10(workspace,
|
|
14171
|
+
for (const relative5 of MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS) {
|
|
14172
|
+
const configPath = join10(workspace, relative5);
|
|
13964
14173
|
if (!existsSync9(configPath)) continue;
|
|
13965
14174
|
try {
|
|
13966
14175
|
const parsed = parseConfigText2(configPath, readFileSync7(configPath, "utf-8"));
|
|
13967
|
-
const validation = validateMeshWorktreeBootstrapConfig(parsed,
|
|
13968
|
-
if (!validation.valid) return { source:
|
|
13969
|
-
return { config: parsed, source:
|
|
14176
|
+
const validation = validateMeshWorktreeBootstrapConfig(parsed, relative5);
|
|
14177
|
+
if (!validation.valid) return { source: relative5, sourceType: "invalid", path: configPath, error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
|
|
14178
|
+
return { config: parsed, source: relative5, sourceType: "repo_file", path: configPath };
|
|
13970
14179
|
} catch (error) {
|
|
13971
|
-
return { source:
|
|
14180
|
+
return { source: relative5, sourceType: "invalid", path: configPath, error: error?.message || String(error) };
|
|
13972
14181
|
}
|
|
13973
14182
|
}
|
|
13974
14183
|
return { source: "unavailable", sourceType: "unavailable", error: `No worktree bootstrap config found. Checked: ${MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS.join(", ")}` };
|
|
@@ -15209,17 +15418,17 @@ function checkPathExists(paths) {
|
|
|
15209
15418
|
return null;
|
|
15210
15419
|
}
|
|
15211
15420
|
async function detectIDEs(providerLoader) {
|
|
15212
|
-
const
|
|
15421
|
+
const os29 = platform2();
|
|
15213
15422
|
const results = [];
|
|
15214
15423
|
for (const def of getMergedDefinitions()) {
|
|
15215
15424
|
const cliPath = findCliCommand(providerLoader?.getIdeCliCommand(def.id, def.cli) || def.cli);
|
|
15216
|
-
const appPath = checkPathExists(providerLoader?.getIdePathCandidates(def.id, def.paths[
|
|
15425
|
+
const appPath = checkPathExists(providerLoader?.getIdePathCandidates(def.id, def.paths[os29] || []) || []);
|
|
15217
15426
|
let resolvedCli = cliPath;
|
|
15218
|
-
if (!resolvedCli && appPath &&
|
|
15427
|
+
if (!resolvedCli && appPath && os29 === "darwin") {
|
|
15219
15428
|
const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
|
|
15220
15429
|
if (existsSync15(bundledCli)) resolvedCli = bundledCli;
|
|
15221
15430
|
}
|
|
15222
|
-
if (!resolvedCli && appPath &&
|
|
15431
|
+
if (!resolvedCli && appPath && os29 === "win32") {
|
|
15223
15432
|
const { dirname: dirname11 } = await import("path");
|
|
15224
15433
|
const appDir = dirname11(appPath);
|
|
15225
15434
|
const candidates = [
|
|
@@ -15236,7 +15445,7 @@ async function detectIDEs(providerLoader) {
|
|
|
15236
15445
|
}
|
|
15237
15446
|
}
|
|
15238
15447
|
}
|
|
15239
|
-
const installed =
|
|
15448
|
+
const installed = os29 === "darwin" ? !!(resolvedCli || appPath) : !!resolvedCli;
|
|
15240
15449
|
const version = resolvedCli ? await getIdeVersion(resolvedCli) : null;
|
|
15241
15450
|
results.push({
|
|
15242
15451
|
id: def.id,
|
|
@@ -25618,6 +25827,14 @@ var DaemonCommandHandler = class {
|
|
|
25618
25827
|
return this.handleCheckProviderUpdates(args);
|
|
25619
25828
|
case "list_installed_providers":
|
|
25620
25829
|
return this.handleListInstalledProviders(args);
|
|
25830
|
+
case "add_provider_source":
|
|
25831
|
+
return this.handleAddProviderSource(args);
|
|
25832
|
+
case "remove_provider_source":
|
|
25833
|
+
return this.handleRemoveProviderSource(args);
|
|
25834
|
+
case "list_provider_sources":
|
|
25835
|
+
return this.handleListProviderSources(args);
|
|
25836
|
+
case "set_active_provider_source":
|
|
25837
|
+
return this.handleSetActiveProviderSource(args);
|
|
25621
25838
|
// ─── Stream commands (stream-commands.ts) ───────────
|
|
25622
25839
|
case "select_session":
|
|
25623
25840
|
return handleSelectSession(this, args);
|
|
@@ -25681,49 +25898,62 @@ var DaemonCommandHandler = class {
|
|
|
25681
25898
|
return { success: false, error: "ProviderLoader not initialized" };
|
|
25682
25899
|
}
|
|
25683
25900
|
/**
|
|
25684
|
-
* Return per-provider availability so
|
|
25685
|
-
* "Installed" badges. Reuses the existing detection state from
|
|
25901
|
+
* Return per-provider availability so the dashboard's provider catalog
|
|
25902
|
+
* can show "Installed" badges. Reuses the existing detection state from
|
|
25686
25903
|
* ProviderLoader.getMachineProviderStatus() — no probing is triggered.
|
|
25687
25904
|
*/
|
|
25688
25905
|
handleListProviderAvailability(_args) {
|
|
25689
25906
|
if (!this._ctx.providerLoader) {
|
|
25690
25907
|
return { success: false, error: "ProviderLoader not initialized" };
|
|
25691
25908
|
}
|
|
25909
|
+
const { describeTrust: describeTrust2, requiresConfirmation: requiresConfirmation2 } = (init_provider_trust(), __toCommonJS(provider_trust_exports));
|
|
25692
25910
|
const loader = this._ctx.providerLoader;
|
|
25693
25911
|
const items = loader.getAll().map((provider) => {
|
|
25694
25912
|
const machineConfig = loader.getMachineProviderConfig(provider.type);
|
|
25695
25913
|
const lastDetection = machineConfig.lastDetection;
|
|
25914
|
+
const trust = provider._sourceTrust ?? "trusted";
|
|
25915
|
+
const layer = provider._sourceLayer ?? "upstream";
|
|
25916
|
+
const sourceName = provider._sourceName ?? null;
|
|
25696
25917
|
return {
|
|
25697
25918
|
type: provider.type,
|
|
25698
25919
|
category: provider.category,
|
|
25699
25920
|
status: loader.getMachineProviderStatus(provider.type),
|
|
25700
25921
|
installed: lastDetection?.ok === true,
|
|
25701
25922
|
detectedPath: lastDetection?.path ?? null,
|
|
25702
|
-
checkedAt: lastDetection?.checkedAt ?? null
|
|
25923
|
+
checkedAt: lastDetection?.checkedAt ?? null,
|
|
25924
|
+
trust,
|
|
25925
|
+
trustDescription: describeTrust2(trust),
|
|
25926
|
+
requiresConfirmation: requiresConfirmation2(trust),
|
|
25927
|
+
sourceLayer: layer,
|
|
25928
|
+
sourceName
|
|
25703
25929
|
};
|
|
25704
25930
|
});
|
|
25705
25931
|
return { success: true, providers: items };
|
|
25706
25932
|
}
|
|
25707
25933
|
/**
|
|
25708
|
-
* Compute the *
|
|
25709
|
-
*
|
|
25710
|
-
*
|
|
25711
|
-
*
|
|
25712
|
-
*
|
|
25713
|
-
*
|
|
25934
|
+
* Compute the *upstream cache root*. install_provider_manifest writes
|
|
25935
|
+
* official-registry manifests here so the daemon's standard upstream
|
|
25936
|
+
* layer picks them up — no special handling needed at load time, and
|
|
25937
|
+
* the manifests inherit the official-trust badge instead of the
|
|
25938
|
+
* untrusted-external one.
|
|
25939
|
+
*
|
|
25940
|
+
* Path matches ProviderLoader.upstreamDir but we recompute it from
|
|
25941
|
+
* homedir() so this method stays usable in dev where userDir can
|
|
25942
|
+
* point at a sibling git checkout.
|
|
25714
25943
|
*/
|
|
25715
|
-
|
|
25716
|
-
const
|
|
25717
|
-
const
|
|
25718
|
-
return
|
|
25944
|
+
getUpstreamInstallRoot() {
|
|
25945
|
+
const os29 = __require("os");
|
|
25946
|
+
const path40 = __require("path");
|
|
25947
|
+
return path40.join(os29.homedir(), ".adhdev", "providers", ".upstream");
|
|
25719
25948
|
}
|
|
25720
25949
|
/**
|
|
25721
25950
|
* Download a single provider manifest from the registry and write it to
|
|
25722
|
-
* ~/.adhdev/
|
|
25951
|
+
* ~/.adhdev/providers/.upstream/{category}/{type}/provider.json.
|
|
25723
25952
|
*
|
|
25724
|
-
* Used by
|
|
25725
|
-
*
|
|
25726
|
-
* the
|
|
25953
|
+
* Used by standalone onboarding to seed the upstream cache with the
|
|
25954
|
+
* default provider set on first launch. Verifies SHA-256 checksum
|
|
25955
|
+
* against the registry meta before persisting. Refuses to write
|
|
25956
|
+
* outside the upstream root.
|
|
25727
25957
|
*
|
|
25728
25958
|
* Args: { type: string, category?: string, version?: string }
|
|
25729
25959
|
* If category/version are omitted, looks up the latest from the registry.
|
|
@@ -25738,8 +25968,8 @@ var DaemonCommandHandler = class {
|
|
|
25738
25968
|
return { success: false, error: "invalid type" };
|
|
25739
25969
|
}
|
|
25740
25970
|
const https = __require("https");
|
|
25741
|
-
const
|
|
25742
|
-
const
|
|
25971
|
+
const fs28 = __require("fs");
|
|
25972
|
+
const path40 = __require("path");
|
|
25743
25973
|
const crypto6 = __require("crypto");
|
|
25744
25974
|
const REGISTRY = "https://api.adhf.dev/api/v1/registry";
|
|
25745
25975
|
function fetchText(url, timeoutMs) {
|
|
@@ -25776,13 +26006,13 @@ var DaemonCommandHandler = class {
|
|
|
25776
26006
|
if (actualChecksum !== meta.checksum) {
|
|
25777
26007
|
return { success: false, error: `checksum mismatch: expected ${meta.checksum}, got ${actualChecksum}` };
|
|
25778
26008
|
}
|
|
25779
|
-
const installRoot = this.
|
|
25780
|
-
const installRootResolved =
|
|
25781
|
-
const targetDir =
|
|
25782
|
-
if (!targetDir.startsWith(installRootResolved +
|
|
25783
|
-
return { success: false, error: "install path escaped
|
|
26009
|
+
const installRoot = this.getUpstreamInstallRoot();
|
|
26010
|
+
const installRootResolved = path40.resolve(installRoot);
|
|
26011
|
+
const targetDir = path40.resolve(path40.join(installRoot, category, type));
|
|
26012
|
+
if (!targetDir.startsWith(installRootResolved + path40.sep)) {
|
|
26013
|
+
return { success: false, error: "install path escaped upstream root" };
|
|
25784
26014
|
}
|
|
25785
|
-
|
|
26015
|
+
fs28.mkdirSync(targetDir, { recursive: true });
|
|
25786
26016
|
let manifestProbe = {};
|
|
25787
26017
|
try {
|
|
25788
26018
|
manifestProbe = JSON.parse(manifestBody);
|
|
@@ -25806,8 +26036,8 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
25806
26036
|
}
|
|
25807
26037
|
}
|
|
25808
26038
|
const targetFile = isV1 ? "provider.v1.json" : "provider.json";
|
|
25809
|
-
const targetPath =
|
|
25810
|
-
|
|
26039
|
+
const targetPath = path40.join(targetDir, targetFile);
|
|
26040
|
+
fs28.writeFileSync(targetPath, manifestBody, "utf-8");
|
|
25811
26041
|
const manifestJson = JSON.parse(manifestBody);
|
|
25812
26042
|
const scriptFetch = await this.fetchProviderSources(
|
|
25813
26043
|
manifestJson,
|
|
@@ -25855,6 +26085,10 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
25855
26085
|
if (Array.isArray(manifest.compatibility)) {
|
|
25856
26086
|
for (const c of manifest.compatibility) {
|
|
25857
26087
|
if (typeof c?.scriptDir === "string") scriptDirs.add(c.scriptDir);
|
|
26088
|
+
if (typeof c?.spec === "string" && c.spec.includes("/")) {
|
|
26089
|
+
const dir = c.spec.substring(0, c.spec.lastIndexOf("/"));
|
|
26090
|
+
if (dir) scriptDirs.add(dir);
|
|
26091
|
+
}
|
|
25858
26092
|
}
|
|
25859
26093
|
}
|
|
25860
26094
|
if (manifest.overrides && typeof manifest.overrides === "object" && !Array.isArray(manifest.overrides)) {
|
|
@@ -25873,8 +26107,8 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
25873
26107
|
const repo = source.repo;
|
|
25874
26108
|
const ref = source.ref;
|
|
25875
26109
|
const https = __require("https");
|
|
25876
|
-
const
|
|
25877
|
-
const
|
|
26110
|
+
const fs28 = __require("fs");
|
|
26111
|
+
const path40 = __require("path");
|
|
25878
26112
|
function fetchJson(url, timeoutMs) {
|
|
25879
26113
|
return new Promise((resolve23, reject) => {
|
|
25880
26114
|
const req = https.get(url, {
|
|
@@ -25930,9 +26164,9 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
25930
26164
|
}
|
|
25931
26165
|
let fetchedCount = 0;
|
|
25932
26166
|
const sharedDirRel = `${category}/_shared`;
|
|
25933
|
-
const sharedTargetDir =
|
|
25934
|
-
const installRootResolved =
|
|
25935
|
-
if (sharedTargetDir.startsWith(installRootResolved +
|
|
26167
|
+
const sharedTargetDir = path40.resolve(path40.join(targetDir, "../_shared"));
|
|
26168
|
+
const installRootResolved = path40.resolve(path40.join(targetDir, "../.."));
|
|
26169
|
+
if (sharedTargetDir.startsWith(installRootResolved + path40.sep)) {
|
|
25936
26170
|
const sharedStack = [sharedDirRel];
|
|
25937
26171
|
while (sharedStack.length) {
|
|
25938
26172
|
const relDir = sharedStack.pop();
|
|
@@ -25955,10 +26189,10 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
25955
26189
|
try {
|
|
25956
26190
|
const body = await fetchBinary(entry.download_url, 3e4);
|
|
25957
26191
|
const relInside = entry.path.startsWith(sharedDirRel + "/") ? entry.path.slice(sharedDirRel.length + 1) : entry.path;
|
|
25958
|
-
const outPath =
|
|
25959
|
-
if (!outPath.startsWith(
|
|
25960
|
-
|
|
25961
|
-
|
|
26192
|
+
const outPath = path40.resolve(path40.join(sharedTargetDir, relInside));
|
|
26193
|
+
if (!outPath.startsWith(path40.resolve(sharedTargetDir) + path40.sep)) continue;
|
|
26194
|
+
fs28.mkdirSync(path40.dirname(outPath), { recursive: true });
|
|
26195
|
+
fs28.writeFileSync(outPath, body);
|
|
25962
26196
|
fetchedCount++;
|
|
25963
26197
|
} catch (e) {
|
|
25964
26198
|
errors.push(`fetch shared ${entry.path}: ${e?.message ?? e}`);
|
|
@@ -25991,13 +26225,13 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
25991
26225
|
try {
|
|
25992
26226
|
const body = await fetchBinary(entry.download_url, 3e4);
|
|
25993
26227
|
const relInsideProvider = entry.path.startsWith(subdir + "/") ? entry.path.slice(subdir.length + 1) : entry.path;
|
|
25994
|
-
const outPath =
|
|
25995
|
-
if (!outPath.startsWith(
|
|
26228
|
+
const outPath = path40.resolve(path40.join(targetDir, relInsideProvider));
|
|
26229
|
+
if (!outPath.startsWith(path40.resolve(targetDir) + path40.sep)) {
|
|
25996
26230
|
errors.push(`refusing to write outside targetDir: ${entry.path}`);
|
|
25997
26231
|
continue;
|
|
25998
26232
|
}
|
|
25999
|
-
|
|
26000
|
-
|
|
26233
|
+
fs28.mkdirSync(path40.dirname(outPath), { recursive: true });
|
|
26234
|
+
fs28.writeFileSync(outPath, body);
|
|
26001
26235
|
fetchedCount++;
|
|
26002
26236
|
} catch (e) {
|
|
26003
26237
|
errors.push(`fetch ${entry.path}: ${e?.message ?? e}`);
|
|
@@ -26008,9 +26242,12 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26008
26242
|
return { fetchedCount, source: `${repo}@${ref}`, errors };
|
|
26009
26243
|
}
|
|
26010
26244
|
/**
|
|
26011
|
-
* Remove a provider manifest from the
|
|
26012
|
-
* (~/.adhdev/
|
|
26013
|
-
* outside that root.
|
|
26245
|
+
* Remove a provider manifest from the upstream cache root
|
|
26246
|
+
* (~/.adhdev/providers/.upstream/{category}/{type}/). Refuses to touch
|
|
26247
|
+
* anything outside that root. Used by onboarding to opt out of a
|
|
26248
|
+
* provider the user doesn't want; the dashboard no longer exposes a
|
|
26249
|
+
* per-provider uninstall button (external sources are removed as a
|
|
26250
|
+
* whole via remove_provider_source).
|
|
26014
26251
|
*/
|
|
26015
26252
|
async handleUninstallProviderManifest(args) {
|
|
26016
26253
|
const type = typeof args?.type === "string" ? args.type : "";
|
|
@@ -26022,19 +26259,19 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26022
26259
|
if (!["cli", "ide", "extension", "acp"].includes(category)) {
|
|
26023
26260
|
return { success: false, error: `unknown category: ${category}` };
|
|
26024
26261
|
}
|
|
26025
|
-
const
|
|
26026
|
-
const
|
|
26262
|
+
const fs28 = __require("fs");
|
|
26263
|
+
const path40 = __require("path");
|
|
26027
26264
|
try {
|
|
26028
|
-
const installRoot = this.
|
|
26029
|
-
const installRootResolved =
|
|
26030
|
-
const targetDir =
|
|
26031
|
-
if (!targetDir.startsWith(installRootResolved +
|
|
26032
|
-
return { success: false, error: "refusing to delete outside
|
|
26265
|
+
const installRoot = this.getUpstreamInstallRoot();
|
|
26266
|
+
const installRootResolved = path40.resolve(installRoot);
|
|
26267
|
+
const targetDir = path40.resolve(path40.join(installRoot, category, type));
|
|
26268
|
+
if (!targetDir.startsWith(installRootResolved + path40.sep)) {
|
|
26269
|
+
return { success: false, error: "refusing to delete outside upstream root" };
|
|
26033
26270
|
}
|
|
26034
|
-
if (!
|
|
26271
|
+
if (!fs28.existsSync(targetDir)) {
|
|
26035
26272
|
return { success: false, error: "not installed" };
|
|
26036
26273
|
}
|
|
26037
|
-
|
|
26274
|
+
fs28.rmSync(targetDir, { recursive: true, force: true });
|
|
26038
26275
|
if (this._ctx.providerLoader) {
|
|
26039
26276
|
this._ctx.providerLoader.reload();
|
|
26040
26277
|
this._ctx.providerLoader.registerToDetector();
|
|
@@ -26045,33 +26282,33 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26045
26282
|
}
|
|
26046
26283
|
}
|
|
26047
26284
|
/**
|
|
26048
|
-
* Return everything currently installed in
|
|
26285
|
+
* Return everything currently installed in the upstream cache with its
|
|
26049
26286
|
* version. This is the "what does this daemon have" answer used both by
|
|
26050
26287
|
* the UI and by the update checker.
|
|
26051
26288
|
*/
|
|
26052
26289
|
handleListInstalledProviders(_args) {
|
|
26053
|
-
const
|
|
26054
|
-
const
|
|
26055
|
-
const installRoot = this.
|
|
26056
|
-
if (!
|
|
26290
|
+
const fs28 = __require("fs");
|
|
26291
|
+
const path40 = __require("path");
|
|
26292
|
+
const installRoot = this.getUpstreamInstallRoot();
|
|
26293
|
+
if (!fs28.existsSync(installRoot)) return { success: true, providers: [] };
|
|
26057
26294
|
const CATEGORIES = ["cli", "ide", "extension", "acp"];
|
|
26058
26295
|
const items = [];
|
|
26059
26296
|
for (const category of CATEGORIES) {
|
|
26060
|
-
const categoryDir =
|
|
26061
|
-
if (!
|
|
26297
|
+
const categoryDir = path40.join(installRoot, category);
|
|
26298
|
+
if (!fs28.existsSync(categoryDir)) continue;
|
|
26062
26299
|
let entries;
|
|
26063
26300
|
try {
|
|
26064
|
-
entries =
|
|
26301
|
+
entries = fs28.readdirSync(categoryDir);
|
|
26065
26302
|
} catch {
|
|
26066
26303
|
continue;
|
|
26067
26304
|
}
|
|
26068
26305
|
for (const type of entries) {
|
|
26069
|
-
const v1Path =
|
|
26070
|
-
const v0Path =
|
|
26071
|
-
const manifestPath =
|
|
26306
|
+
const v1Path = path40.join(categoryDir, type, "provider.v1.json");
|
|
26307
|
+
const v0Path = path40.join(categoryDir, type, "provider.json");
|
|
26308
|
+
const manifestPath = fs28.existsSync(v1Path) ? v1Path : fs28.existsSync(v0Path) ? v0Path : null;
|
|
26072
26309
|
if (!manifestPath) continue;
|
|
26073
26310
|
try {
|
|
26074
|
-
const m = JSON.parse(
|
|
26311
|
+
const m = JSON.parse(fs28.readFileSync(manifestPath, "utf-8"));
|
|
26075
26312
|
items.push({
|
|
26076
26313
|
type,
|
|
26077
26314
|
category,
|
|
@@ -26148,6 +26385,196 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26148
26385
|
);
|
|
26149
26386
|
return { success: true, providers: checks };
|
|
26150
26387
|
}
|
|
26388
|
+
// ─── External provider sources (3rd-party git URLs) ──────────────
|
|
26389
|
+
/**
|
|
26390
|
+
* Register a new external provider source. The daemon clones the repo
|
|
26391
|
+
* to ~/.adhdev/external/<name>/, walks it once to detect provided
|
|
26392
|
+
* types, and surfaces any conflicts with already-installed types so
|
|
26393
|
+
* the dashboard can ask the user how to resolve them.
|
|
26394
|
+
*
|
|
26395
|
+
* Args: { url: string, ref?: string, name?: string }
|
|
26396
|
+
* - url: https://, git@, or any git-cloneable URL
|
|
26397
|
+
* - ref: branch/tag/commit (default "main")
|
|
26398
|
+
* - name: short identifier (default derived from URL)
|
|
26399
|
+
*
|
|
26400
|
+
* Returns: { source, providers, conflicts }
|
|
26401
|
+
* - conflicts: list of types this new source provides that another
|
|
26402
|
+
* source already exposes. UI uses this to prompt for active-source
|
|
26403
|
+
* selection before the load takes effect.
|
|
26404
|
+
*/
|
|
26405
|
+
async handleAddProviderSource(args) {
|
|
26406
|
+
const url = typeof args?.url === "string" ? args.url.trim() : "";
|
|
26407
|
+
if (!url) return { success: false, error: "url is required" };
|
|
26408
|
+
const ref = typeof args?.ref === "string" && args.ref.trim() ? args.ref.trim() : "main";
|
|
26409
|
+
if (url.startsWith("-")) return { success: false, error: 'url must not start with "-"' };
|
|
26410
|
+
if (ref.startsWith("-")) return { success: false, error: 'ref must not start with "-"' };
|
|
26411
|
+
if (!/^(https?:\/\/|git@[a-z0-9._-]+:)[a-z0-9._@:/~\-]+$/i.test(url)) {
|
|
26412
|
+
return { success: false, error: "url must be https://\u2026 or git@host:\u2026 and contain only URL-safe characters" };
|
|
26413
|
+
}
|
|
26414
|
+
if (!/^[A-Za-z0-9._/-]+$/.test(ref)) {
|
|
26415
|
+
return { success: false, error: "ref must contain only [A-Za-z0-9._/-]" };
|
|
26416
|
+
}
|
|
26417
|
+
const ext = (init_external_sources(), __toCommonJS(external_sources_exports));
|
|
26418
|
+
const requestedName = typeof args?.name === "string" && args.name.trim() ? args.name.trim() : ext.deriveSourceName(url);
|
|
26419
|
+
if (!/^@[a-z0-9_-]+$/i.test(requestedName)) {
|
|
26420
|
+
return { success: false, error: "name must match @[a-z0-9_-]+" };
|
|
26421
|
+
}
|
|
26422
|
+
const fs28 = __require("fs");
|
|
26423
|
+
const path40 = __require("path");
|
|
26424
|
+
const { spawnSync: spawnSync2 } = __require("child_process");
|
|
26425
|
+
const file = ext.loadExternalSources();
|
|
26426
|
+
if (file.sources.some((s) => s.name === requestedName)) {
|
|
26427
|
+
return { success: false, error: `source name "${requestedName}" is already registered` };
|
|
26428
|
+
}
|
|
26429
|
+
if (file.sources.some((s) => s.url === url && s.ref === ref)) {
|
|
26430
|
+
return { success: false, error: `source url+ref already registered (use a different name to track another ref)` };
|
|
26431
|
+
}
|
|
26432
|
+
const sourceDir = path40.join(ext.externalRoot(), requestedName);
|
|
26433
|
+
if (!fs28.existsSync(ext.externalRoot())) fs28.mkdirSync(ext.externalRoot(), { recursive: true });
|
|
26434
|
+
if (fs28.existsSync(sourceDir)) {
|
|
26435
|
+
return { success: false, error: `directory already exists: ${sourceDir} (rename or remove first)` };
|
|
26436
|
+
}
|
|
26437
|
+
const clone = spawnSync2("git", ["clone", "--depth=1", "--branch", ref, "--", url, sourceDir], {
|
|
26438
|
+
encoding: "utf-8",
|
|
26439
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
26440
|
+
timeout: 6e4
|
|
26441
|
+
});
|
|
26442
|
+
if (clone.status !== 0) {
|
|
26443
|
+
try {
|
|
26444
|
+
fs28.rmSync(sourceDir, { recursive: true, force: true });
|
|
26445
|
+
} catch {
|
|
26446
|
+
}
|
|
26447
|
+
return { success: false, error: `git clone failed: ${(clone.stderr || clone.stdout || "").trim() || "unknown error"}` };
|
|
26448
|
+
}
|
|
26449
|
+
const source = {
|
|
26450
|
+
name: requestedName,
|
|
26451
|
+
url,
|
|
26452
|
+
ref,
|
|
26453
|
+
addedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
26454
|
+
};
|
|
26455
|
+
ext.saveExternalSources({ schema: 1, sources: [...file.sources, source] });
|
|
26456
|
+
const inventory = ext.inventoryExternalSources();
|
|
26457
|
+
const conflicts = [];
|
|
26458
|
+
const newEntry = inventory.find((e) => e.sourceName === requestedName);
|
|
26459
|
+
if (newEntry) {
|
|
26460
|
+
for (const [category, types] of Object.entries(newEntry.providers)) {
|
|
26461
|
+
for (const type of types) {
|
|
26462
|
+
const sources = ext.sourcesProviding(category, type);
|
|
26463
|
+
if (sources.length > 1) conflicts.push({ category, type, sources });
|
|
26464
|
+
}
|
|
26465
|
+
}
|
|
26466
|
+
}
|
|
26467
|
+
if (this._ctx.providerLoader) {
|
|
26468
|
+
this._ctx.providerLoader.reload();
|
|
26469
|
+
this._ctx.providerLoader.registerToDetector();
|
|
26470
|
+
}
|
|
26471
|
+
return {
|
|
26472
|
+
success: true,
|
|
26473
|
+
source,
|
|
26474
|
+
providers: newEntry?.providers ?? {},
|
|
26475
|
+
conflicts
|
|
26476
|
+
};
|
|
26477
|
+
}
|
|
26478
|
+
/**
|
|
26479
|
+
* Remove a registered external source. Deletes the clone directory and
|
|
26480
|
+
* any active-source entry pointing to it.
|
|
26481
|
+
*
|
|
26482
|
+
* Args: { name: string }
|
|
26483
|
+
*/
|
|
26484
|
+
async handleRemoveProviderSource(args) {
|
|
26485
|
+
const name = typeof args?.name === "string" ? args.name.trim() : "";
|
|
26486
|
+
if (!name) return { success: false, error: "name is required" };
|
|
26487
|
+
const ext = (init_external_sources(), __toCommonJS(external_sources_exports));
|
|
26488
|
+
const fs28 = __require("fs");
|
|
26489
|
+
const path40 = __require("path");
|
|
26490
|
+
const file = ext.loadExternalSources();
|
|
26491
|
+
const match = file.sources.find((s) => s.name === name);
|
|
26492
|
+
if (!match) return { success: false, error: `source "${name}" not registered` };
|
|
26493
|
+
const sourceDir = path40.join(ext.externalRoot(), name);
|
|
26494
|
+
if (fs28.existsSync(sourceDir)) {
|
|
26495
|
+
try {
|
|
26496
|
+
fs28.rmSync(sourceDir, { recursive: true, force: true });
|
|
26497
|
+
} catch (e) {
|
|
26498
|
+
return { success: false, error: `failed to delete ${sourceDir}: ${e?.message || e}` };
|
|
26499
|
+
}
|
|
26500
|
+
}
|
|
26501
|
+
ext.saveExternalSources({
|
|
26502
|
+
schema: 1,
|
|
26503
|
+
sources: file.sources.filter((s) => s.name !== name)
|
|
26504
|
+
});
|
|
26505
|
+
const active = ext.loadProvidersActive();
|
|
26506
|
+
const filteredActive = {};
|
|
26507
|
+
for (const [type, src] of Object.entries(active.active)) {
|
|
26508
|
+
if (src !== name) filteredActive[type] = src;
|
|
26509
|
+
}
|
|
26510
|
+
ext.saveProvidersActive({ schema: 1, active: filteredActive });
|
|
26511
|
+
if (this._ctx.providerLoader) {
|
|
26512
|
+
this._ctx.providerLoader.reload();
|
|
26513
|
+
this._ctx.providerLoader.registerToDetector();
|
|
26514
|
+
}
|
|
26515
|
+
return { success: true, removed: { name } };
|
|
26516
|
+
}
|
|
26517
|
+
/**
|
|
26518
|
+
* List registered external sources + each source's currently installed
|
|
26519
|
+
* providers + the active selection for any conflicting types. Used by
|
|
26520
|
+
* the dashboard's "Sources" tab.
|
|
26521
|
+
*/
|
|
26522
|
+
handleListProviderSources(_args) {
|
|
26523
|
+
const ext = (init_external_sources(), __toCommonJS(external_sources_exports));
|
|
26524
|
+
const file = ext.loadExternalSources();
|
|
26525
|
+
const inventory = ext.inventoryExternalSources();
|
|
26526
|
+
const active = ext.loadProvidersActive();
|
|
26527
|
+
const sources = file.sources.map((s) => {
|
|
26528
|
+
const inv = inventory.find((e) => e.sourceName === s.name);
|
|
26529
|
+
return {
|
|
26530
|
+
...s,
|
|
26531
|
+
providers: inv?.providers ?? {}
|
|
26532
|
+
};
|
|
26533
|
+
});
|
|
26534
|
+
const conflictMap = /* @__PURE__ */ new Map();
|
|
26535
|
+
for (const inv of inventory) {
|
|
26536
|
+
for (const [category, types] of Object.entries(inv.providers)) {
|
|
26537
|
+
for (const type of types) {
|
|
26538
|
+
const candidates = ext.sourcesProviding(category, type);
|
|
26539
|
+
if (candidates.length > 1 && !conflictMap.has(type)) {
|
|
26540
|
+
conflictMap.set(type, { category, sources: candidates });
|
|
26541
|
+
}
|
|
26542
|
+
}
|
|
26543
|
+
}
|
|
26544
|
+
}
|
|
26545
|
+
const conflicts = [...conflictMap.entries()].map(([type, info]) => ({
|
|
26546
|
+
type,
|
|
26547
|
+
category: info.category,
|
|
26548
|
+
candidates: info.sources,
|
|
26549
|
+
active: active.active[type] ?? null
|
|
26550
|
+
}));
|
|
26551
|
+
return { success: true, sources, conflicts };
|
|
26552
|
+
}
|
|
26553
|
+
/**
|
|
26554
|
+
* Pick which source's copy of a conflicting provider type is active.
|
|
26555
|
+
* Other sources' copies stay on disk but the loader ignores them.
|
|
26556
|
+
*
|
|
26557
|
+
* Args: { type: string, sourceName: string }
|
|
26558
|
+
*/
|
|
26559
|
+
handleSetActiveProviderSource(args) {
|
|
26560
|
+
const type = typeof args?.type === "string" ? args.type.trim() : "";
|
|
26561
|
+
const sourceName = typeof args?.sourceName === "string" ? args.sourceName.trim() : "";
|
|
26562
|
+
if (!type || !sourceName) return { success: false, error: "type and sourceName are required" };
|
|
26563
|
+
const ext = (init_external_sources(), __toCommonJS(external_sources_exports));
|
|
26564
|
+
const inventory = ext.inventoryExternalSources();
|
|
26565
|
+
const entry = inventory.find((e) => e.sourceName === sourceName);
|
|
26566
|
+
if (!entry) return { success: false, error: `source "${sourceName}" not found` };
|
|
26567
|
+
const provided = Object.values(entry.providers).some((types) => types.includes(type));
|
|
26568
|
+
if (!provided) return { success: false, error: `source "${sourceName}" does not provide type "${type}"` };
|
|
26569
|
+
const active = ext.loadProvidersActive();
|
|
26570
|
+
active.active[type] = sourceName;
|
|
26571
|
+
ext.saveProvidersActive(active);
|
|
26572
|
+
if (this._ctx.providerLoader) {
|
|
26573
|
+
this._ctx.providerLoader.reload();
|
|
26574
|
+
this._ctx.providerLoader.registerToDetector();
|
|
26575
|
+
}
|
|
26576
|
+
return { success: true, type, sourceName };
|
|
26577
|
+
}
|
|
26151
26578
|
// ─── DevServer HTTP proxy helpers ─────────────────
|
|
26152
26579
|
// These bridge WS commands to the DevServer REST API (localhost:19280)
|
|
26153
26580
|
async proxyDevServerPost(args, endpoint) {
|
|
@@ -26243,29 +26670,29 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26243
26670
|
init_provider_cli_adapter();
|
|
26244
26671
|
init_cli_detector();
|
|
26245
26672
|
init_config();
|
|
26246
|
-
import * as
|
|
26247
|
-
import * as
|
|
26673
|
+
import * as os17 from "os";
|
|
26674
|
+
import * as path23 from "path";
|
|
26248
26675
|
import * as crypto5 from "crypto";
|
|
26249
|
-
import { existsSync as
|
|
26676
|
+
import { existsSync as existsSync21, mkdirSync as mkdirSync11, writeFileSync as writeFileSync14 } from "fs";
|
|
26250
26677
|
import { execFileSync } from "child_process";
|
|
26251
26678
|
import chalk from "chalk";
|
|
26252
26679
|
|
|
26253
26680
|
// src/providers/cli-provider-instance.ts
|
|
26254
|
-
import * as
|
|
26255
|
-
import * as
|
|
26681
|
+
import * as os16 from "os";
|
|
26682
|
+
import * as path21 from "path";
|
|
26256
26683
|
import * as crypto4 from "crypto";
|
|
26257
|
-
import * as
|
|
26684
|
+
import * as fs12 from "fs";
|
|
26258
26685
|
import { createRequire as createRequire2 } from "module";
|
|
26259
26686
|
|
|
26260
26687
|
// src/providers/spec/route.ts
|
|
26261
26688
|
init_provider_cli_adapter();
|
|
26262
|
-
import * as
|
|
26263
|
-
import * as
|
|
26689
|
+
import * as fs11 from "fs";
|
|
26690
|
+
import * as path20 from "path";
|
|
26264
26691
|
|
|
26265
26692
|
// src/providers/spec/driver.ts
|
|
26266
|
-
import * as
|
|
26267
|
-
import * as
|
|
26268
|
-
import * as
|
|
26693
|
+
import * as fs10 from "fs";
|
|
26694
|
+
import * as os15 from "os";
|
|
26695
|
+
import * as path19 from "path";
|
|
26269
26696
|
|
|
26270
26697
|
// src/providers/spec/adapter.ts
|
|
26271
26698
|
init_pty_transport();
|
|
@@ -26642,7 +27069,7 @@ var SpecDriver = class {
|
|
|
26642
27069
|
}
|
|
26643
27070
|
armSpecWatcher() {
|
|
26644
27071
|
try {
|
|
26645
|
-
this.specWatcher =
|
|
27072
|
+
this.specWatcher = fs10.watch(this.opts.specPath, { persistent: false }, () => {
|
|
26646
27073
|
const res = loadSpec(this.opts.specPath);
|
|
26647
27074
|
if (!res.ok) {
|
|
26648
27075
|
this.emit({ kind: "spec_error", errors: res.errors });
|
|
@@ -26735,7 +27162,7 @@ var SpecDriver = class {
|
|
|
26735
27162
|
}
|
|
26736
27163
|
fireDelegate(d) {
|
|
26737
27164
|
const ev = this.currentEval;
|
|
26738
|
-
const task = d.task_template.replace(/\{node\}/g,
|
|
27165
|
+
const task = d.task_template.replace(/\{node\}/g, os15.hostname()).replace(/\{state\.label\}/g, ev?.state.label ?? "").replace(/\{state\.title\}/g, ev?.state.title ?? "").replace(/\{duration_ms\}/g, String(d.after_duration_ms ?? 0));
|
|
26739
27166
|
this.emit({ kind: "delegate", id: d.id, task });
|
|
26740
27167
|
}
|
|
26741
27168
|
// ────────────────────────────────────────────────────────────────────
|
|
@@ -26804,9 +27231,9 @@ var SpecDriver = class {
|
|
|
26804
27231
|
const ctl = (this.spec.control_bar ?? []).find((c) => c.action.type === "attach_image");
|
|
26805
27232
|
if (!ctl || ctl.action.type !== "attach_image") return;
|
|
26806
27233
|
const ext = guessExt(mime);
|
|
26807
|
-
const tmp =
|
|
27234
|
+
const tmp = path19.join(os15.tmpdir(), `adhdev-attach-${Date.now()}${ext}`);
|
|
26808
27235
|
try {
|
|
26809
|
-
|
|
27236
|
+
fs10.writeFileSync(tmp, Buffer.from(blob, "base64"));
|
|
26810
27237
|
} catch {
|
|
26811
27238
|
return;
|
|
26812
27239
|
}
|
|
@@ -26875,6 +27302,15 @@ var SpecCliAdapter = class {
|
|
|
26875
27302
|
cliType;
|
|
26876
27303
|
cliName;
|
|
26877
27304
|
workingDir;
|
|
27305
|
+
/**
|
|
27306
|
+
* Marker the daemon's finalization gate checks: `getStatus()` returns
|
|
27307
|
+
* `messages: []` by design here (chat history lives in the daemon's
|
|
27308
|
+
* native-history pipeline, not the adapter). Without this flag,
|
|
27309
|
+
* cli-provider-instance's `missing_final_assistant` gate would stall
|
|
27310
|
+
* every turn until the 30s safety timeout because it expects the
|
|
27311
|
+
* adapter to surface the final assistant message.
|
|
27312
|
+
*/
|
|
27313
|
+
chatMessagesOwnedExternally = true;
|
|
26878
27314
|
driver;
|
|
26879
27315
|
spec;
|
|
26880
27316
|
lastEvent = null;
|
|
@@ -27125,14 +27561,14 @@ init_logger();
|
|
|
27125
27561
|
function createCliAdapter(provider, workingDir, cliArgs, extraEnv, transportFactory) {
|
|
27126
27562
|
const resolvedSpecPath = provider._resolvedSpecPath;
|
|
27127
27563
|
const dir = provider._resolvedProviderDir;
|
|
27128
|
-
let specPath = resolvedSpecPath &&
|
|
27564
|
+
let specPath = resolvedSpecPath && fs11.existsSync(resolvedSpecPath) ? resolvedSpecPath : void 0;
|
|
27129
27565
|
if (!specPath && dir) {
|
|
27130
|
-
const legacy =
|
|
27131
|
-
if (
|
|
27566
|
+
const legacy = path20.join(dir, "spec.json");
|
|
27567
|
+
if (fs11.existsSync(legacy)) specPath = legacy;
|
|
27132
27568
|
}
|
|
27133
27569
|
if (specPath) {
|
|
27134
27570
|
try {
|
|
27135
|
-
LOG.info("spec-route", `[${provider.type}] routing through SpecCliAdapter (${
|
|
27571
|
+
LOG.info("spec-route", `[${provider.type}] routing through SpecCliAdapter (${path20.relative(dir || "", specPath) || specPath})`);
|
|
27136
27572
|
return new SpecCliAdapter(specPath, workingDir, cliArgs, extraEnv, transportFactory);
|
|
27137
27573
|
} catch (err) {
|
|
27138
27574
|
LOG.warn("spec-route", `[${provider.type}] spec invalid, falling back to ProviderCliAdapter: ${err.message}`);
|
|
@@ -27193,7 +27629,7 @@ function filePathFromUri(uri) {
|
|
|
27193
27629
|
return uri.slice("file://".length);
|
|
27194
27630
|
}
|
|
27195
27631
|
}
|
|
27196
|
-
if (
|
|
27632
|
+
if (path21.isAbsolute(uri)) return uri;
|
|
27197
27633
|
return null;
|
|
27198
27634
|
}
|
|
27199
27635
|
function extensionForImageMime(mimeType) {
|
|
@@ -27208,9 +27644,9 @@ function materializeImageDataPart(part, index, dir) {
|
|
|
27208
27644
|
if (!part.data) return null;
|
|
27209
27645
|
const rawData = part.data.includes(",") ? part.data.split(",").pop() || "" : part.data;
|
|
27210
27646
|
if (!rawData) return null;
|
|
27211
|
-
|
|
27212
|
-
const filePath =
|
|
27213
|
-
|
|
27647
|
+
fs12.mkdirSync(dir, { recursive: true });
|
|
27648
|
+
const filePath = path21.join(dir, safeInputImageBasename(index, part.mimeType));
|
|
27649
|
+
fs12.writeFileSync(filePath, Buffer.from(rawData, "base64"));
|
|
27214
27650
|
cleanupStaleMaterializedImages(dir);
|
|
27215
27651
|
return filePath;
|
|
27216
27652
|
}
|
|
@@ -27222,14 +27658,14 @@ function cleanupStaleMaterializedImages(dir) {
|
|
|
27222
27658
|
if (now - lastMaterializedImageCleanupAt < MATERIALIZED_IMAGE_CLEANUP_INTERVAL_MS) return;
|
|
27223
27659
|
lastMaterializedImageCleanupAt = now;
|
|
27224
27660
|
try {
|
|
27225
|
-
const entries =
|
|
27661
|
+
const entries = fs12.readdirSync(dir);
|
|
27226
27662
|
for (const entry of entries) {
|
|
27227
27663
|
if (!entry.startsWith("adhdev-input-image-")) continue;
|
|
27228
|
-
const fullPath =
|
|
27664
|
+
const fullPath = path21.join(dir, entry);
|
|
27229
27665
|
try {
|
|
27230
|
-
const stat2 =
|
|
27666
|
+
const stat2 = fs12.statSync(fullPath);
|
|
27231
27667
|
if (now - stat2.mtimeMs > MATERIALIZED_IMAGE_MAX_AGE_MS) {
|
|
27232
|
-
|
|
27668
|
+
fs12.unlinkSync(fullPath);
|
|
27233
27669
|
}
|
|
27234
27670
|
} catch {
|
|
27235
27671
|
}
|
|
@@ -27248,7 +27684,7 @@ function buildCliStructuredInputPrompt(input, options = {}) {
|
|
|
27248
27684
|
const promptParts = [];
|
|
27249
27685
|
const imageRefs = [];
|
|
27250
27686
|
const resourceRefs = [];
|
|
27251
|
-
const materializeDir = options.materializeDir ||
|
|
27687
|
+
const materializeDir = options.materializeDir || path21.join(os16.tmpdir(), "adhdev-input-media");
|
|
27252
27688
|
input.parts.forEach((part, index) => {
|
|
27253
27689
|
if (part.type === "text" && part.text.trim()) {
|
|
27254
27690
|
promptParts.push(part.text.trim());
|
|
@@ -27315,7 +27751,7 @@ function buildIncrementalHistoryAppendMessages(previousMessages, currentMessages
|
|
|
27315
27751
|
var CachedDatabaseSync = null;
|
|
27316
27752
|
function getDatabaseSync() {
|
|
27317
27753
|
if (CachedDatabaseSync) return CachedDatabaseSync;
|
|
27318
|
-
const requireFn = typeof __require === "function" ? __require : createRequire2(
|
|
27754
|
+
const requireFn = typeof __require === "function" ? __require : createRequire2(path21.join(process.cwd(), "__adhdev_sqlite_loader__.js"));
|
|
27319
27755
|
const sqliteModule = requireFn(`node:${"sqlite"}`);
|
|
27320
27756
|
CachedDatabaseSync = sqliteModule.DatabaseSync;
|
|
27321
27757
|
if (!CachedDatabaseSync) {
|
|
@@ -27469,10 +27905,10 @@ var CliProviderInstance = class {
|
|
|
27469
27905
|
* Replaces the previously duplicated probeOpenCode/Codex/Goose functions.
|
|
27470
27906
|
*/
|
|
27471
27907
|
probeSessionIdFromConfig(probe) {
|
|
27472
|
-
const resolvedDbPath = probe.dbPath.replace(/^~/,
|
|
27908
|
+
const resolvedDbPath = probe.dbPath.replace(/^~/, os16.homedir());
|
|
27473
27909
|
const now = Date.now();
|
|
27474
27910
|
if (this.cachedSqliteDbMissingUntil > now) return null;
|
|
27475
|
-
if (!
|
|
27911
|
+
if (!fs12.existsSync(resolvedDbPath)) {
|
|
27476
27912
|
this.cachedSqliteDbMissingUntil = now + 1e4;
|
|
27477
27913
|
return null;
|
|
27478
27914
|
}
|
|
@@ -27858,7 +28294,10 @@ var CliProviderInstance = class {
|
|
|
27858
28294
|
return { reason: `parsed_status:${parsedStatus}`, terminal: isCliGeneratingLikeStatus(parsedStatus) };
|
|
27859
28295
|
}
|
|
27860
28296
|
if (parsed?.activeModal || parsed?.modal) return { reason: "parsed_modal_active", terminal: true };
|
|
27861
|
-
|
|
28297
|
+
const adapterOwnsMessagesElsewhere = this.adapter?.chatMessagesOwnedExternally === true;
|
|
28298
|
+
if (!adapterOwnsMessagesElsewhere && !this.completionHasFinalAssistantMessage(parsed?.messages)) {
|
|
28299
|
+
return { reason: "missing_final_assistant" };
|
|
28300
|
+
}
|
|
27862
28301
|
try {
|
|
27863
28302
|
const screenText = typeof this.adapter.getScreenText === "function" ? String(this.adapter.getScreenText() || "") : "";
|
|
27864
28303
|
if (screenText) {
|
|
@@ -28571,7 +29010,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
28571
29010
|
};
|
|
28572
29011
|
addDir(this.workingDir);
|
|
28573
29012
|
try {
|
|
28574
|
-
addDir(
|
|
29013
|
+
addDir(fs12.realpathSync.native(this.workingDir));
|
|
28575
29014
|
} catch {
|
|
28576
29015
|
}
|
|
28577
29016
|
return Array.from(dirs);
|
|
@@ -28608,7 +29047,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
28608
29047
|
};
|
|
28609
29048
|
|
|
28610
29049
|
// src/providers/acp-provider-instance.ts
|
|
28611
|
-
import * as
|
|
29050
|
+
import * as path22 from "path";
|
|
28612
29051
|
import { Readable, Writable } from "stream";
|
|
28613
29052
|
import { spawn } from "child_process";
|
|
28614
29053
|
import {
|
|
@@ -29388,7 +29827,7 @@ var AcpProviderInstance = class {
|
|
|
29388
29827
|
return b.uri ? {
|
|
29389
29828
|
type: "resource_link",
|
|
29390
29829
|
uri: b.uri,
|
|
29391
|
-
name:
|
|
29830
|
+
name: path22.basename(b.uri),
|
|
29392
29831
|
mimeType: b.mimeType,
|
|
29393
29832
|
...b.transcript ? { description: b.transcript } : {}
|
|
29394
29833
|
} : { type: "text", text: b.transcript || `[Video attachment: ${b.mimeType}]` };
|
|
@@ -29846,17 +30285,17 @@ function shouldRestoreHostedRuntime(record, managerTag) {
|
|
|
29846
30285
|
// src/commands/cli-manager.ts
|
|
29847
30286
|
function isExplicitCommand(command) {
|
|
29848
30287
|
const trimmed = command.trim();
|
|
29849
|
-
return
|
|
30288
|
+
return path23.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
|
|
29850
30289
|
}
|
|
29851
30290
|
function expandExecutable(command) {
|
|
29852
30291
|
const trimmed = command.trim();
|
|
29853
|
-
return trimmed.startsWith("~") ?
|
|
30292
|
+
return trimmed.startsWith("~") ? path23.join(os17.homedir(), trimmed.slice(1)) : trimmed;
|
|
29854
30293
|
}
|
|
29855
30294
|
function commandExists(command) {
|
|
29856
30295
|
const trimmed = command.trim();
|
|
29857
30296
|
if (!trimmed) return false;
|
|
29858
30297
|
if (isExplicitCommand(trimmed)) {
|
|
29859
|
-
return
|
|
30298
|
+
return existsSync21(expandExecutable(trimmed));
|
|
29860
30299
|
}
|
|
29861
30300
|
try {
|
|
29862
30301
|
execFileSync(process.platform === "win32" ? "where" : "which", [trimmed], {
|
|
@@ -29977,11 +30416,11 @@ function hasCliArg(args, flag) {
|
|
|
29977
30416
|
return args.some((arg) => arg === flag || arg.startsWith(`${flag}=`));
|
|
29978
30417
|
}
|
|
29979
30418
|
function ensureEmptyDelegatedMcpConfig(workspace) {
|
|
29980
|
-
const baseDir =
|
|
29981
|
-
|
|
29982
|
-
const workspaceHash = crypto5.createHash("sha256").update(
|
|
29983
|
-
const filePath =
|
|
29984
|
-
|
|
30419
|
+
const baseDir = path23.join(os17.tmpdir(), "adhdev-delegated-agent-empty-mcp");
|
|
30420
|
+
mkdirSync11(baseDir, { recursive: true });
|
|
30421
|
+
const workspaceHash = crypto5.createHash("sha256").update(path23.resolve(workspace || os17.tmpdir())).digest("hex").slice(0, 16);
|
|
30422
|
+
const filePath = path23.join(baseDir, `${workspaceHash}.json`);
|
|
30423
|
+
writeFileSync14(filePath, JSON.stringify({ mcpServers: {} }, null, 2), "utf-8");
|
|
29985
30424
|
return filePath;
|
|
29986
30425
|
}
|
|
29987
30426
|
function buildCoordinatorDelegatedCliLaunchOptions(input) {
|
|
@@ -30274,7 +30713,7 @@ var DaemonCliManager = class {
|
|
|
30274
30713
|
async startSession(cliType, workingDir, cliArgs, initialModel, options) {
|
|
30275
30714
|
const trimmed = (workingDir || "").trim();
|
|
30276
30715
|
if (!trimmed) throw new Error("working directory required");
|
|
30277
|
-
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/,
|
|
30716
|
+
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os17.homedir()) : path23.resolve(trimmed);
|
|
30278
30717
|
const normalizedType = this.providerLoader.resolveAlias(cliType);
|
|
30279
30718
|
const rawProvider = this.providerLoader.getByAlias(cliType);
|
|
30280
30719
|
const provider = rawProvider ? this.providerLoader.resolve(normalizedType) || rawProvider : void 0;
|
|
@@ -30659,6 +31098,20 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
30659
31098
|
cliArgs: args?.cliArgs,
|
|
30660
31099
|
env: args?.env
|
|
30661
31100
|
}) : null;
|
|
31101
|
+
const provLookup = this.providerLoader.getMeta(this.providerLoader.resolveAlias(cliType));
|
|
31102
|
+
const provTrust = provLookup?._sourceTrust;
|
|
31103
|
+
if (provTrust === "external-untrusted" && args?.confirmExternalUntrusted !== true) {
|
|
31104
|
+
return {
|
|
31105
|
+
success: false,
|
|
31106
|
+
error: "untrusted_external_provider",
|
|
31107
|
+
provider: {
|
|
31108
|
+
type: provLookup?.type ?? cliType,
|
|
31109
|
+
sourceName: provLookup?._sourceName ?? null,
|
|
31110
|
+
trust: provTrust
|
|
31111
|
+
},
|
|
31112
|
+
hint: "Resend launch_cli with confirmExternalUntrusted=true after the user explicitly approves running JavaScript from this 3rd-party source."
|
|
31113
|
+
};
|
|
31114
|
+
}
|
|
30662
31115
|
const started = await this.startSession(
|
|
30663
31116
|
cliType,
|
|
30664
31117
|
dir,
|
|
@@ -30845,13 +31298,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
30845
31298
|
// src/launch.ts
|
|
30846
31299
|
import { exec as exec4, spawn as spawn2 } from "child_process";
|
|
30847
31300
|
import * as net from "net";
|
|
30848
|
-
import * as
|
|
30849
|
-
import * as
|
|
31301
|
+
import * as os23 from "os";
|
|
31302
|
+
import * as path32 from "path";
|
|
30850
31303
|
|
|
30851
31304
|
// src/providers/provider-loader.ts
|
|
30852
|
-
import * as
|
|
30853
|
-
import * as
|
|
30854
|
-
import * as
|
|
31305
|
+
import * as fs19 from "fs";
|
|
31306
|
+
import * as path31 from "path";
|
|
31307
|
+
import * as os22 from "os";
|
|
30855
31308
|
import * as chokidar from "chokidar";
|
|
30856
31309
|
init_logger();
|
|
30857
31310
|
|
|
@@ -31224,9 +31677,9 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31224
31677
|
static siblingStderrLogged = /* @__PURE__ */ new Set();
|
|
31225
31678
|
static looksLikeProviderRoot(candidate) {
|
|
31226
31679
|
try {
|
|
31227
|
-
if (!
|
|
31680
|
+
if (!fs19.existsSync(candidate) || !fs19.statSync(candidate).isDirectory()) return false;
|
|
31228
31681
|
return ["ide", "extension", "cli", "acp"].some(
|
|
31229
|
-
(category) =>
|
|
31682
|
+
(category) => fs19.existsSync(path31.join(candidate, category))
|
|
31230
31683
|
);
|
|
31231
31684
|
} catch {
|
|
31232
31685
|
return false;
|
|
@@ -31234,20 +31687,20 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31234
31687
|
}
|
|
31235
31688
|
static hasProviderRootMarker(candidate) {
|
|
31236
31689
|
try {
|
|
31237
|
-
return
|
|
31690
|
+
return fs19.existsSync(path31.join(candidate, _ProviderLoader.SIBLING_MARKER_FILE));
|
|
31238
31691
|
} catch {
|
|
31239
31692
|
return false;
|
|
31240
31693
|
}
|
|
31241
31694
|
}
|
|
31242
31695
|
detectDefaultUserDir() {
|
|
31243
|
-
const fallback =
|
|
31696
|
+
const fallback = path31.join(os22.homedir(), ".adhdev", "providers");
|
|
31244
31697
|
const envOptIn = process.env[_ProviderLoader.SIBLING_ENV_VAR] === "1";
|
|
31245
31698
|
const visited = /* @__PURE__ */ new Set();
|
|
31246
31699
|
for (const start of this.probeStarts) {
|
|
31247
|
-
let current =
|
|
31700
|
+
let current = path31.resolve(start);
|
|
31248
31701
|
while (!visited.has(current)) {
|
|
31249
31702
|
visited.add(current);
|
|
31250
|
-
const siblingCandidate =
|
|
31703
|
+
const siblingCandidate = path31.join(path31.dirname(current), _ProviderLoader.REPO_PROVIDER_DIRNAME);
|
|
31251
31704
|
if (_ProviderLoader.looksLikeProviderRoot(siblingCandidate)) {
|
|
31252
31705
|
const hasMarker = _ProviderLoader.hasProviderRootMarker(siblingCandidate);
|
|
31253
31706
|
if (envOptIn || hasMarker) {
|
|
@@ -31269,7 +31722,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31269
31722
|
return { path: siblingCandidate, source };
|
|
31270
31723
|
}
|
|
31271
31724
|
}
|
|
31272
|
-
const parent =
|
|
31725
|
+
const parent = path31.dirname(current);
|
|
31273
31726
|
if (parent === current) break;
|
|
31274
31727
|
current = parent;
|
|
31275
31728
|
}
|
|
@@ -31279,17 +31732,34 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31279
31732
|
constructor(options) {
|
|
31280
31733
|
this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
|
|
31281
31734
|
this.probeStarts = options?.probeStarts ?? [process.cwd(), __dirname];
|
|
31282
|
-
this.defaultProvidersDir =
|
|
31735
|
+
this.defaultProvidersDir = path31.join(os22.homedir(), ".adhdev", "providers");
|
|
31283
31736
|
const detected = this.detectDefaultUserDir();
|
|
31284
31737
|
this.userDir = detected.path;
|
|
31285
31738
|
this.userDirSource = detected.source;
|
|
31286
|
-
this.upstreamDir =
|
|
31739
|
+
this.upstreamDir = path31.join(this.defaultProvidersDir, ".upstream");
|
|
31287
31740
|
this.disableUpstream = false;
|
|
31288
31741
|
this.applySourceConfig({
|
|
31289
31742
|
userDir: options?.userDir,
|
|
31290
31743
|
sourceMode: options?.sourceMode,
|
|
31291
31744
|
disableUpstream: options?.disableUpstream
|
|
31292
31745
|
});
|
|
31746
|
+
this.migrateMarketplaceDirToExternal();
|
|
31747
|
+
}
|
|
31748
|
+
migrateMarketplaceDirToExternal() {
|
|
31749
|
+
try {
|
|
31750
|
+
const home = os22.homedir();
|
|
31751
|
+
const oldDir = path31.join(home, ".adhdev", "marketplace");
|
|
31752
|
+
const newDir = path31.join(home, ".adhdev", "external");
|
|
31753
|
+
if (!fs19.existsSync(oldDir)) return;
|
|
31754
|
+
if (fs19.existsSync(newDir)) {
|
|
31755
|
+
this.log(`Migration skipped: both ~/.adhdev/marketplace and ~/.adhdev/external exist (marketplace dir is now inert and can be removed manually).`);
|
|
31756
|
+
return;
|
|
31757
|
+
}
|
|
31758
|
+
fs19.renameSync(oldDir, newDir);
|
|
31759
|
+
this.log(`Migrated ~/.adhdev/marketplace \u2192 ~/.adhdev/external (one-time rename after provider source-layer cleanup).`);
|
|
31760
|
+
} catch (e) {
|
|
31761
|
+
this.log(`Marketplace\u2192external migration failed: ${e?.message || e}`);
|
|
31762
|
+
}
|
|
31293
31763
|
}
|
|
31294
31764
|
log(msg) {
|
|
31295
31765
|
this.logFn(`[ProviderLoader] ${msg}`);
|
|
@@ -31315,8 +31785,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31315
31785
|
* Highest-priority editable overrides come first.
|
|
31316
31786
|
*/
|
|
31317
31787
|
getProviderRoots() {
|
|
31318
|
-
const
|
|
31319
|
-
return [this.userDir,
|
|
31788
|
+
const externalDir = path31.join(os22.homedir(), ".adhdev", "external");
|
|
31789
|
+
return [this.userDir, externalDir, this.upstreamDir];
|
|
31320
31790
|
}
|
|
31321
31791
|
getSourceConfig() {
|
|
31322
31792
|
return {
|
|
@@ -31343,7 +31813,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31343
31813
|
this.userDir = detected.path;
|
|
31344
31814
|
this.userDirSource = detected.source;
|
|
31345
31815
|
}
|
|
31346
|
-
this.upstreamDir =
|
|
31816
|
+
this.upstreamDir = path31.join(this.defaultProvidersDir, ".upstream");
|
|
31347
31817
|
this.disableUpstream = this.sourceMode === "no-upstream";
|
|
31348
31818
|
if (this.explicitProviderDir) {
|
|
31349
31819
|
this.log(`Config 'providerDir' applied: ${this.userDir}`);
|
|
@@ -31357,7 +31827,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31357
31827
|
* Canonical provider directory shape for a given root.
|
|
31358
31828
|
*/
|
|
31359
31829
|
getProviderDir(root, category, type) {
|
|
31360
|
-
return
|
|
31830
|
+
return path31.join(root, category, type);
|
|
31361
31831
|
}
|
|
31362
31832
|
/**
|
|
31363
31833
|
* Canonical user override directory for a provider.
|
|
@@ -31384,20 +31854,23 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31384
31854
|
resolveProviderFile(type, ...segments) {
|
|
31385
31855
|
const dir = this.findProviderDirInternal(type);
|
|
31386
31856
|
if (!dir) return null;
|
|
31387
|
-
return
|
|
31857
|
+
return path31.join(dir, ...segments);
|
|
31388
31858
|
}
|
|
31389
31859
|
/**
|
|
31390
31860
|
* Load all providers (3-tier priority)
|
|
31391
|
-
* 1.
|
|
31392
|
-
* 2.
|
|
31393
|
-
*
|
|
31861
|
+
* 1. ~/.adhdev/providers/.upstream/ — official git, auto-synced
|
|
31862
|
+
* 2. ~/.adhdev/external/ — 3rd-party git sources, user-added,
|
|
31863
|
+
* bundled providers may include arbitrary JS (untrusted by default)
|
|
31864
|
+
* 3. ~/.adhdev/providers/ (excluding .upstream) — user-authored customs,
|
|
31865
|
+
* always wins
|
|
31866
|
+
* Highest priority listed last (overwrites earlier loads).
|
|
31394
31867
|
* If .upstream/ is empty, call fetchLatest() before loadAll().
|
|
31395
31868
|
*/
|
|
31396
31869
|
loadAll() {
|
|
31397
31870
|
this.providers.clear();
|
|
31398
31871
|
this.providerAvailability.clear();
|
|
31399
31872
|
let upstreamCount = 0;
|
|
31400
|
-
if (!this.disableUpstream &&
|
|
31873
|
+
if (!this.disableUpstream && fs19.existsSync(this.upstreamDir)) {
|
|
31401
31874
|
upstreamCount = this.loadDir(this.upstreamDir);
|
|
31402
31875
|
if (upstreamCount > 0) {
|
|
31403
31876
|
this.log(`Loaded ${upstreamCount} upstream providers (auto-updated)`);
|
|
@@ -31405,14 +31878,64 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31405
31878
|
} else if (this.disableUpstream) {
|
|
31406
31879
|
this.log("Upstream loading disabled (sourceMode=no-upstream)");
|
|
31407
31880
|
}
|
|
31408
|
-
const
|
|
31409
|
-
if (
|
|
31410
|
-
const
|
|
31411
|
-
|
|
31412
|
-
|
|
31881
|
+
const externalDir = path31.join(os22.homedir(), ".adhdev", "external");
|
|
31882
|
+
if (fs19.existsSync(externalDir)) {
|
|
31883
|
+
const rootEntries = (() => {
|
|
31884
|
+
try {
|
|
31885
|
+
return fs19.readdirSync(externalDir, { withFileTypes: true });
|
|
31886
|
+
} catch {
|
|
31887
|
+
return [];
|
|
31888
|
+
}
|
|
31889
|
+
})();
|
|
31890
|
+
const KNOWN_CATEGORIES = /* @__PURE__ */ new Set(["cli", "ide", "extension", "acp"]);
|
|
31891
|
+
const looksLegacy = rootEntries.some((e) => e.isDirectory() && KNOWN_CATEGORIES.has(e.name));
|
|
31892
|
+
if (looksLegacy) {
|
|
31893
|
+
const externalCount = this.loadDir(externalDir);
|
|
31894
|
+
if (externalCount > 0) {
|
|
31895
|
+
this.log(`Loaded ${externalCount} external providers (legacy unnamed source)`);
|
|
31896
|
+
}
|
|
31897
|
+
} else {
|
|
31898
|
+
const {
|
|
31899
|
+
loadProvidersActive: loadProvidersActive2,
|
|
31900
|
+
resolveActiveSource: resolveActiveSource2
|
|
31901
|
+
} = (init_external_sources(), __toCommonJS(external_sources_exports));
|
|
31902
|
+
const activeFile = loadProvidersActive2();
|
|
31903
|
+
let totalLoaded = 0;
|
|
31904
|
+
const ambiguousTypes = [];
|
|
31905
|
+
for (const sourceEntry of rootEntries) {
|
|
31906
|
+
if (!sourceEntry.isDirectory()) continue;
|
|
31907
|
+
const sourceDir = path31.join(externalDir, sourceEntry.name);
|
|
31908
|
+
const sourceLoaded = this.loadDir(sourceDir);
|
|
31909
|
+
if (sourceLoaded > 0) {
|
|
31910
|
+
totalLoaded += sourceLoaded;
|
|
31911
|
+
this.log(`Loaded ${sourceLoaded} providers from external source "${sourceEntry.name}"`);
|
|
31912
|
+
}
|
|
31913
|
+
}
|
|
31914
|
+
for (const [type] of this.providers) {
|
|
31915
|
+
const prov = this.providers.get(type);
|
|
31916
|
+
if (!prov) continue;
|
|
31917
|
+
const resolved = resolveActiveSource2(prov.category, type, activeFile);
|
|
31918
|
+
if (resolved.candidates.length <= 1) continue;
|
|
31919
|
+
if (resolved.ambiguous) {
|
|
31920
|
+
ambiguousTypes.push({ type, chosen: resolved.source ?? "?", candidates: resolved.candidates });
|
|
31921
|
+
}
|
|
31922
|
+
if (resolved.source && resolved.source !== "?") {
|
|
31923
|
+
const sourceDir = path31.join(externalDir, resolved.source);
|
|
31924
|
+
const reloadCount = this.loadDir(sourceDir);
|
|
31925
|
+
if (reloadCount === 0) {
|
|
31926
|
+
this.log(`Active source "${resolved.source}" no longer provides ${type}`);
|
|
31927
|
+
}
|
|
31928
|
+
}
|
|
31929
|
+
}
|
|
31930
|
+
if (totalLoaded > 0) {
|
|
31931
|
+
this.log(`Loaded ${totalLoaded} external providers (3rd-party sources)`);
|
|
31932
|
+
}
|
|
31933
|
+
for (const a of ambiguousTypes) {
|
|
31934
|
+
this.log(`Ambiguous provider "${a.type}" \u2014 provided by [${a.candidates.join(", ")}], defaulted to "${a.chosen}". Set the active source from the dashboard to silence this warning.`);
|
|
31935
|
+
}
|
|
31413
31936
|
}
|
|
31414
31937
|
}
|
|
31415
|
-
if (
|
|
31938
|
+
if (fs19.existsSync(this.userDir)) {
|
|
31416
31939
|
const userCount = this.loadDir(this.userDir, [".upstream"]);
|
|
31417
31940
|
if (userCount > 0) {
|
|
31418
31941
|
this.log(`Loaded ${userCount} user custom providers (never auto-updated)`);
|
|
@@ -31427,10 +31950,10 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31427
31950
|
* Check if upstream directory exists and has providers.
|
|
31428
31951
|
*/
|
|
31429
31952
|
hasUpstream() {
|
|
31430
|
-
if (!
|
|
31953
|
+
if (!fs19.existsSync(this.upstreamDir)) return false;
|
|
31431
31954
|
try {
|
|
31432
|
-
return
|
|
31433
|
-
(d) =>
|
|
31955
|
+
return fs19.readdirSync(this.upstreamDir).some(
|
|
31956
|
+
(d) => fs19.statSync(path31.join(this.upstreamDir, d)).isDirectory()
|
|
31434
31957
|
);
|
|
31435
31958
|
} catch {
|
|
31436
31959
|
return false;
|
|
@@ -31920,16 +32443,20 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31920
32443
|
let matched = false;
|
|
31921
32444
|
for (const entry of compat) {
|
|
31922
32445
|
if (this.matchesVersion(currentVersion, entry.ideVersion)) {
|
|
31923
|
-
|
|
31924
|
-
|
|
31925
|
-
|
|
31926
|
-
|
|
31927
|
-
|
|
31928
|
-
|
|
31929
|
-
|
|
31930
|
-
|
|
31931
|
-
|
|
32446
|
+
if (entry.scriptDir) {
|
|
32447
|
+
const loaded = this.loadScriptsFromDir(type, entry.scriptDir);
|
|
32448
|
+
if (loaded) {
|
|
32449
|
+
resolved.scripts = loaded;
|
|
32450
|
+
this.debugLog(` [compatibility] ${type} v${currentVersion} \u2192 ${entry.scriptDir}`);
|
|
32451
|
+
resolved._resolvedScriptDir = entry.scriptDir;
|
|
32452
|
+
resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
|
|
32453
|
+
if (providerDir) {
|
|
32454
|
+
const fullDir = path31.join(providerDir, entry.scriptDir);
|
|
32455
|
+
resolved._resolvedScriptsPath = fs19.existsSync(path31.join(fullDir, "scripts.js")) ? path31.join(fullDir, "scripts.js") : fullDir;
|
|
32456
|
+
}
|
|
32457
|
+
matched = true;
|
|
31932
32458
|
}
|
|
32459
|
+
} else {
|
|
31933
32460
|
matched = true;
|
|
31934
32461
|
}
|
|
31935
32462
|
break;
|
|
@@ -31943,8 +32470,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31943
32470
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
31944
32471
|
resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
|
|
31945
32472
|
if (providerDir) {
|
|
31946
|
-
const fullDir =
|
|
31947
|
-
resolved._resolvedScriptsPath =
|
|
32473
|
+
const fullDir = path31.join(providerDir, base.defaultScriptDir);
|
|
32474
|
+
resolved._resolvedScriptsPath = fs19.existsSync(path31.join(fullDir, "scripts.js")) ? path31.join(fullDir, "scripts.js") : fullDir;
|
|
31948
32475
|
}
|
|
31949
32476
|
}
|
|
31950
32477
|
resolved._versionWarning = `Version ${currentVersion} not in compatibility matrix. Using default scripts.`;
|
|
@@ -31961,8 +32488,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31961
32488
|
resolved._resolvedScriptDir = dirOverride;
|
|
31962
32489
|
resolved._resolvedScriptsSource = `versions:${range}`;
|
|
31963
32490
|
if (providerDir) {
|
|
31964
|
-
const fullDir =
|
|
31965
|
-
resolved._resolvedScriptsPath =
|
|
32491
|
+
const fullDir = path31.join(providerDir, dirOverride);
|
|
32492
|
+
resolved._resolvedScriptsPath = fs19.existsSync(path31.join(fullDir, "scripts.js")) ? path31.join(fullDir, "scripts.js") : fullDir;
|
|
31966
32493
|
}
|
|
31967
32494
|
}
|
|
31968
32495
|
} else if (override.scripts) {
|
|
@@ -31978,8 +32505,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31978
32505
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
31979
32506
|
resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
|
|
31980
32507
|
if (providerDir) {
|
|
31981
|
-
const fullDir =
|
|
31982
|
-
resolved._resolvedScriptsPath =
|
|
32508
|
+
const fullDir = path31.join(providerDir, base.defaultScriptDir);
|
|
32509
|
+
resolved._resolvedScriptsPath = fs19.existsSync(path31.join(fullDir, "scripts.js")) ? path31.join(fullDir, "scripts.js") : fullDir;
|
|
31983
32510
|
}
|
|
31984
32511
|
}
|
|
31985
32512
|
}
|
|
@@ -31996,13 +32523,13 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31996
32523
|
if (providerDir2) {
|
|
31997
32524
|
for (const [scriptName, override] of Object.entries(base.overrides)) {
|
|
31998
32525
|
if (!override || typeof override.path !== "string") continue;
|
|
31999
|
-
const fullPath =
|
|
32000
|
-
if (!
|
|
32526
|
+
const fullPath = path31.join(providerDir2, override.path);
|
|
32527
|
+
if (!fs19.existsSync(fullPath)) {
|
|
32001
32528
|
this.log(` [overrides] ${base.type}: ${scriptName} path not found: ${fullPath}`);
|
|
32002
32529
|
continue;
|
|
32003
32530
|
}
|
|
32004
32531
|
try {
|
|
32005
|
-
registerProviderScriptRootSafely(
|
|
32532
|
+
registerProviderScriptRootSafely(path31.dirname(path31.dirname(providerDir2)));
|
|
32006
32533
|
delete __require.cache[__require.resolve(fullPath)];
|
|
32007
32534
|
const fn = __require(fullPath);
|
|
32008
32535
|
const target = typeof fn === "function" ? fn : fn && fn[scriptName];
|
|
@@ -32027,19 +32554,19 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32027
32554
|
}
|
|
32028
32555
|
if (providerDir) {
|
|
32029
32556
|
try {
|
|
32030
|
-
const
|
|
32031
|
-
const
|
|
32557
|
+
const fs28 = __require("fs");
|
|
32558
|
+
const path40 = __require("path");
|
|
32032
32559
|
const candidates = [];
|
|
32033
32560
|
if (Array.isArray(base.compatibility)) {
|
|
32034
32561
|
for (const entry of base.compatibility) {
|
|
32035
32562
|
if (typeof entry?.spec !== "string") continue;
|
|
32036
32563
|
const matches = !entry.ideVersion || currentVersion && this.matchesVersion(currentVersion, entry.ideVersion) || !currentVersion;
|
|
32037
|
-
if (matches) candidates.push(
|
|
32564
|
+
if (matches) candidates.push(path40.join(providerDir, entry.spec));
|
|
32038
32565
|
}
|
|
32039
32566
|
}
|
|
32040
|
-
candidates.push(
|
|
32041
|
-
candidates.push(
|
|
32042
|
-
const specPath = candidates.find((p) =>
|
|
32567
|
+
candidates.push(path40.join(providerDir, "specs", "default.json"));
|
|
32568
|
+
candidates.push(path40.join(providerDir, "spec.json"));
|
|
32569
|
+
const specPath = candidates.find((p) => fs28.existsSync(p));
|
|
32043
32570
|
if (specPath) {
|
|
32044
32571
|
resolved._resolvedSpecPath = specPath;
|
|
32045
32572
|
const { loadSpec: loadSpec2 } = (init_loader(), __toCommonJS(loader_exports));
|
|
@@ -32068,10 +32595,10 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32068
32595
|
format = `spec-${nh.source.kind}`;
|
|
32069
32596
|
reader = (input) => executeNativeHistory2(nh, input);
|
|
32070
32597
|
} else if (nh.override_path) {
|
|
32071
|
-
const overrideFile =
|
|
32072
|
-
if (
|
|
32598
|
+
const overrideFile = path40.resolve(providerDir, nh.override_path);
|
|
32599
|
+
if (fs28.existsSync(overrideFile)) {
|
|
32073
32600
|
try {
|
|
32074
|
-
registerProviderScriptRootSafely(
|
|
32601
|
+
registerProviderScriptRootSafely(path40.dirname(path40.dirname(providerDir)));
|
|
32075
32602
|
delete __require.cache[__require.resolve(overrideFile)];
|
|
32076
32603
|
const mod = __require(overrideFile);
|
|
32077
32604
|
const fn = typeof mod === "function" ? mod : mod && typeof mod.default === "function" ? mod.default : null;
|
|
@@ -32115,16 +32642,16 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32115
32642
|
this.debugLog(`[loadScriptsFromDir] ${type}: providerDir not found`);
|
|
32116
32643
|
return null;
|
|
32117
32644
|
}
|
|
32118
|
-
const dir =
|
|
32119
|
-
if (!
|
|
32645
|
+
const dir = path31.join(providerDir, scriptDir);
|
|
32646
|
+
if (!fs19.existsSync(dir)) {
|
|
32120
32647
|
this.debugLog(`[loadScriptsFromDir] ${type}: dir not found: ${dir}`);
|
|
32121
32648
|
return null;
|
|
32122
32649
|
}
|
|
32123
|
-
registerProviderScriptRootSafely(
|
|
32650
|
+
registerProviderScriptRootSafely(path31.dirname(path31.dirname(providerDir)));
|
|
32124
32651
|
const cached = this.scriptsCache.get(dir);
|
|
32125
32652
|
if (cached) return cached;
|
|
32126
|
-
const scriptsJs =
|
|
32127
|
-
if (
|
|
32653
|
+
const scriptsJs = path31.join(dir, "scripts.js");
|
|
32654
|
+
if (fs19.existsSync(scriptsJs)) {
|
|
32128
32655
|
try {
|
|
32129
32656
|
delete __require.cache[__require.resolve(scriptsJs)];
|
|
32130
32657
|
const loaded = __require(scriptsJs);
|
|
@@ -32145,9 +32672,9 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32145
32672
|
watch() {
|
|
32146
32673
|
this.stopWatch();
|
|
32147
32674
|
const watchDir = (dir) => {
|
|
32148
|
-
if (!
|
|
32675
|
+
if (!fs19.existsSync(dir)) {
|
|
32149
32676
|
try {
|
|
32150
|
-
|
|
32677
|
+
fs19.mkdirSync(dir, { recursive: true });
|
|
32151
32678
|
} catch {
|
|
32152
32679
|
return;
|
|
32153
32680
|
}
|
|
@@ -32168,7 +32695,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32168
32695
|
if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
|
|
32169
32696
|
if (reloadTimer) clearTimeout(reloadTimer);
|
|
32170
32697
|
reloadTimer = setTimeout(() => {
|
|
32171
|
-
this.log(`File changed: ${
|
|
32698
|
+
this.log(`File changed: ${path31.basename(filePath)}, reloading...`);
|
|
32172
32699
|
this.reload();
|
|
32173
32700
|
}, 300);
|
|
32174
32701
|
}
|
|
@@ -32236,11 +32763,11 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32236
32763
|
}
|
|
32237
32764
|
this.log(`Registry sync starting (${_ProviderLoader.REGISTRY_BASE_URL})...`);
|
|
32238
32765
|
const https = __require("https");
|
|
32239
|
-
const regMetaPath =
|
|
32766
|
+
const regMetaPath = path31.join(this.upstreamDir, _ProviderLoader.REGISTRY_META_FILE);
|
|
32240
32767
|
let cachedChecksums = {};
|
|
32241
32768
|
try {
|
|
32242
|
-
if (
|
|
32243
|
-
cachedChecksums = JSON.parse(
|
|
32769
|
+
if (fs19.existsSync(regMetaPath)) {
|
|
32770
|
+
cachedChecksums = JSON.parse(fs19.readFileSync(regMetaPath, "utf-8")).checksums ?? {};
|
|
32244
32771
|
}
|
|
32245
32772
|
} catch {
|
|
32246
32773
|
}
|
|
@@ -32294,15 +32821,15 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32294
32821
|
this.log(`\u26A0 Registry checksum mismatch for ${type}@${version} \u2014 skipping`);
|
|
32295
32822
|
continue;
|
|
32296
32823
|
}
|
|
32297
|
-
const providerDir =
|
|
32298
|
-
|
|
32299
|
-
|
|
32824
|
+
const providerDir = path31.join(this.upstreamDir, category, type);
|
|
32825
|
+
fs19.mkdirSync(providerDir, { recursive: true });
|
|
32826
|
+
fs19.writeFileSync(path31.join(providerDir, "provider.json"), manifestBody, "utf-8");
|
|
32300
32827
|
cachedChecksums[cacheKey] = checksum;
|
|
32301
32828
|
updatedCount++;
|
|
32302
32829
|
this.log(`\u2713 Registry updated: ${category}/${type}@${version}`);
|
|
32303
32830
|
}
|
|
32304
|
-
|
|
32305
|
-
|
|
32831
|
+
fs19.mkdirSync(this.upstreamDir, { recursive: true });
|
|
32832
|
+
fs19.writeFileSync(regMetaPath, JSON.stringify({
|
|
32306
32833
|
checksums: cachedChecksums,
|
|
32307
32834
|
syncedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
32308
32835
|
providerCount: list.providers.length
|
|
@@ -32323,12 +32850,12 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32323
32850
|
const { exec: exec7 } = __require("child_process");
|
|
32324
32851
|
const { promisify: promisify7 } = __require("util");
|
|
32325
32852
|
const execAsync5 = promisify7(exec7);
|
|
32326
|
-
const metaPath =
|
|
32853
|
+
const metaPath = path31.join(this.upstreamDir, _ProviderLoader.META_FILE);
|
|
32327
32854
|
let prevEtag = "";
|
|
32328
32855
|
let prevTimestamp = 0;
|
|
32329
32856
|
try {
|
|
32330
|
-
if (
|
|
32331
|
-
const meta = JSON.parse(
|
|
32857
|
+
if (fs19.existsSync(metaPath)) {
|
|
32858
|
+
const meta = JSON.parse(fs19.readFileSync(metaPath, "utf-8"));
|
|
32332
32859
|
prevEtag = meta.etag || "";
|
|
32333
32860
|
prevTimestamp = meta.timestamp || 0;
|
|
32334
32861
|
}
|
|
@@ -32383,39 +32910,39 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32383
32910
|
return { updated: false };
|
|
32384
32911
|
}
|
|
32385
32912
|
this.log("Downloading latest providers from GitHub...");
|
|
32386
|
-
const tmpTar =
|
|
32387
|
-
const tmpExtract =
|
|
32913
|
+
const tmpTar = path31.join(os22.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
|
|
32914
|
+
const tmpExtract = path31.join(os22.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
|
|
32388
32915
|
await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
|
|
32389
|
-
|
|
32916
|
+
fs19.mkdirSync(tmpExtract, { recursive: true });
|
|
32390
32917
|
await execAsync5(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
|
|
32391
|
-
const extracted =
|
|
32918
|
+
const extracted = fs19.readdirSync(tmpExtract);
|
|
32392
32919
|
const rootDir = extracted.find(
|
|
32393
|
-
(d) =>
|
|
32920
|
+
(d) => fs19.statSync(path31.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
|
|
32394
32921
|
);
|
|
32395
32922
|
if (!rootDir) throw new Error("Unexpected tarball structure");
|
|
32396
|
-
const sourceDir =
|
|
32923
|
+
const sourceDir = path31.join(tmpExtract, rootDir);
|
|
32397
32924
|
const backupDir = this.upstreamDir + ".bak";
|
|
32398
|
-
if (
|
|
32399
|
-
if (
|
|
32400
|
-
|
|
32925
|
+
if (fs19.existsSync(this.upstreamDir)) {
|
|
32926
|
+
if (fs19.existsSync(backupDir)) fs19.rmSync(backupDir, { recursive: true, force: true });
|
|
32927
|
+
fs19.renameSync(this.upstreamDir, backupDir);
|
|
32401
32928
|
}
|
|
32402
32929
|
try {
|
|
32403
32930
|
this.copyDirRecursive(sourceDir, this.upstreamDir);
|
|
32404
32931
|
this.writeMeta(metaPath, etag || `ts-${Date.now()}`, Date.now());
|
|
32405
|
-
if (
|
|
32932
|
+
if (fs19.existsSync(backupDir)) fs19.rmSync(backupDir, { recursive: true, force: true });
|
|
32406
32933
|
} catch (e) {
|
|
32407
|
-
if (
|
|
32408
|
-
if (
|
|
32409
|
-
|
|
32934
|
+
if (fs19.existsSync(backupDir)) {
|
|
32935
|
+
if (fs19.existsSync(this.upstreamDir)) fs19.rmSync(this.upstreamDir, { recursive: true, force: true });
|
|
32936
|
+
fs19.renameSync(backupDir, this.upstreamDir);
|
|
32410
32937
|
}
|
|
32411
32938
|
throw e;
|
|
32412
32939
|
}
|
|
32413
32940
|
try {
|
|
32414
|
-
|
|
32941
|
+
fs19.rmSync(tmpTar, { force: true });
|
|
32415
32942
|
} catch {
|
|
32416
32943
|
}
|
|
32417
32944
|
try {
|
|
32418
|
-
|
|
32945
|
+
fs19.rmSync(tmpExtract, { recursive: true, force: true });
|
|
32419
32946
|
} catch {
|
|
32420
32947
|
}
|
|
32421
32948
|
const upstreamCount = this.countProviders(this.upstreamDir);
|
|
@@ -32447,7 +32974,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32447
32974
|
reject(new Error(`HTTP ${res.statusCode}`));
|
|
32448
32975
|
return;
|
|
32449
32976
|
}
|
|
32450
|
-
const ws =
|
|
32977
|
+
const ws = fs19.createWriteStream(destPath);
|
|
32451
32978
|
res.pipe(ws);
|
|
32452
32979
|
ws.on("finish", () => {
|
|
32453
32980
|
ws.close();
|
|
@@ -32466,22 +32993,22 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32466
32993
|
}
|
|
32467
32994
|
/** Recursive directory copy */
|
|
32468
32995
|
copyDirRecursive(src, dest) {
|
|
32469
|
-
|
|
32470
|
-
for (const entry of
|
|
32471
|
-
const srcPath =
|
|
32472
|
-
const destPath =
|
|
32996
|
+
fs19.mkdirSync(dest, { recursive: true });
|
|
32997
|
+
for (const entry of fs19.readdirSync(src, { withFileTypes: true })) {
|
|
32998
|
+
const srcPath = path31.join(src, entry.name);
|
|
32999
|
+
const destPath = path31.join(dest, entry.name);
|
|
32473
33000
|
if (entry.isDirectory()) {
|
|
32474
33001
|
this.copyDirRecursive(srcPath, destPath);
|
|
32475
33002
|
} else {
|
|
32476
|
-
|
|
33003
|
+
fs19.copyFileSync(srcPath, destPath);
|
|
32477
33004
|
}
|
|
32478
33005
|
}
|
|
32479
33006
|
}
|
|
32480
33007
|
/** .meta.json save */
|
|
32481
33008
|
writeMeta(metaPath, etag, timestamp) {
|
|
32482
33009
|
try {
|
|
32483
|
-
|
|
32484
|
-
|
|
33010
|
+
fs19.mkdirSync(path31.dirname(metaPath), { recursive: true });
|
|
33011
|
+
fs19.writeFileSync(metaPath, JSON.stringify({
|
|
32485
33012
|
etag,
|
|
32486
33013
|
timestamp,
|
|
32487
33014
|
lastCheck: new Date(timestamp).toISOString(),
|
|
@@ -32492,15 +33019,15 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32492
33019
|
}
|
|
32493
33020
|
/** Count provider files (provider.v1.json or provider.json — at most one per dir). */
|
|
32494
33021
|
countProviders(dir) {
|
|
32495
|
-
if (!
|
|
33022
|
+
if (!fs19.existsSync(dir)) return 0;
|
|
32496
33023
|
let count = 0;
|
|
32497
33024
|
const scan = (d) => {
|
|
32498
33025
|
try {
|
|
32499
|
-
const entries =
|
|
33026
|
+
const entries = fs19.readdirSync(d, { withFileTypes: true });
|
|
32500
33027
|
const hasManifest = entries.some((e) => e.name === "provider.v1.json" || e.name === "provider.json");
|
|
32501
33028
|
if (hasManifest) count++;
|
|
32502
33029
|
for (const entry of entries) {
|
|
32503
|
-
if (entry.isDirectory()) scan(
|
|
33030
|
+
if (entry.isDirectory()) scan(path31.join(d, entry.name));
|
|
32504
33031
|
}
|
|
32505
33032
|
} catch {
|
|
32506
33033
|
}
|
|
@@ -32726,13 +33253,13 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32726
33253
|
if (!provider) return null;
|
|
32727
33254
|
const cat = provider.category;
|
|
32728
33255
|
const searchRoots = this.getProviderRoots();
|
|
32729
|
-
const hasManifest = (dir) =>
|
|
33256
|
+
const hasManifest = (dir) => fs19.existsSync(path31.join(dir, "provider.v1.json")) || fs19.existsSync(path31.join(dir, "provider.json"));
|
|
32730
33257
|
const readManifestType = (dir) => {
|
|
32731
33258
|
for (const file of ["provider.v1.json", "provider.json"]) {
|
|
32732
|
-
const p =
|
|
32733
|
-
if (!
|
|
33259
|
+
const p = path31.join(dir, file);
|
|
33260
|
+
if (!fs19.existsSync(p)) continue;
|
|
32734
33261
|
try {
|
|
32735
|
-
const data = JSON.parse(
|
|
33262
|
+
const data = JSON.parse(fs19.readFileSync(p, "utf-8"));
|
|
32736
33263
|
if (typeof data?.type === "string") return data.type;
|
|
32737
33264
|
} catch {
|
|
32738
33265
|
}
|
|
@@ -32740,15 +33267,15 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32740
33267
|
return null;
|
|
32741
33268
|
};
|
|
32742
33269
|
for (const root of searchRoots) {
|
|
32743
|
-
if (!
|
|
33270
|
+
if (!fs19.existsSync(root)) continue;
|
|
32744
33271
|
const candidate = this.getProviderDir(root, cat, type);
|
|
32745
33272
|
if (hasManifest(candidate)) return candidate;
|
|
32746
|
-
const catDir =
|
|
32747
|
-
if (
|
|
33273
|
+
const catDir = path31.join(root, cat);
|
|
33274
|
+
if (fs19.existsSync(catDir)) {
|
|
32748
33275
|
try {
|
|
32749
|
-
for (const entry of
|
|
33276
|
+
for (const entry of fs19.readdirSync(catDir, { withFileTypes: true })) {
|
|
32750
33277
|
if (!entry.isDirectory()) continue;
|
|
32751
|
-
const entryDir =
|
|
33278
|
+
const entryDir = path31.join(catDir, entry.name);
|
|
32752
33279
|
const manifestType = readManifestType(entryDir);
|
|
32753
33280
|
if (manifestType === type) return entryDir;
|
|
32754
33281
|
}
|
|
@@ -32764,8 +33291,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32764
33291
|
* (template substitution is NOT applied here — scripts.js handles that)
|
|
32765
33292
|
*/
|
|
32766
33293
|
buildScriptWrappersFromDir(dir) {
|
|
32767
|
-
const scriptsJs =
|
|
32768
|
-
if (
|
|
33294
|
+
const scriptsJs = path31.join(dir, "scripts.js");
|
|
33295
|
+
if (fs19.existsSync(scriptsJs)) {
|
|
32769
33296
|
try {
|
|
32770
33297
|
delete __require.cache[__require.resolve(scriptsJs)];
|
|
32771
33298
|
return __require(scriptsJs);
|
|
@@ -32775,13 +33302,13 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32775
33302
|
const toCamel = (name) => name.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
|
|
32776
33303
|
const result = {};
|
|
32777
33304
|
try {
|
|
32778
|
-
for (const file of
|
|
33305
|
+
for (const file of fs19.readdirSync(dir)) {
|
|
32779
33306
|
if (!file.endsWith(".js")) continue;
|
|
32780
33307
|
const scriptName = toCamel(file.replace(".js", ""));
|
|
32781
|
-
const filePath =
|
|
33308
|
+
const filePath = path31.join(dir, file);
|
|
32782
33309
|
result[scriptName] = (...args) => {
|
|
32783
33310
|
try {
|
|
32784
|
-
let content =
|
|
33311
|
+
let content = fs19.readFileSync(filePath, "utf-8");
|
|
32785
33312
|
if (args[0] && typeof args[0] === "object") {
|
|
32786
33313
|
for (const [key, val] of Object.entries(args[0])) {
|
|
32787
33314
|
let v = val;
|
|
@@ -32827,12 +33354,12 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32827
33354
|
* Structure: dir/category/agent-name/provider.{json,js}
|
|
32828
33355
|
*/
|
|
32829
33356
|
loadDir(dir, excludeDirs) {
|
|
32830
|
-
if (!
|
|
33357
|
+
if (!fs19.existsSync(dir)) return 0;
|
|
32831
33358
|
let count = 0;
|
|
32832
33359
|
const scan = (d) => {
|
|
32833
33360
|
let entries;
|
|
32834
33361
|
try {
|
|
32835
|
-
entries =
|
|
33362
|
+
entries = fs19.readdirSync(d, { withFileTypes: true });
|
|
32836
33363
|
} catch {
|
|
32837
33364
|
return;
|
|
32838
33365
|
}
|
|
@@ -32840,9 +33367,9 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32840
33367
|
const hasJson = entries.some((e) => e.name === "provider.json");
|
|
32841
33368
|
if (hasV1 || hasJson) {
|
|
32842
33369
|
const manifestFile = hasV1 ? "provider.v1.json" : "provider.json";
|
|
32843
|
-
const jsonPath =
|
|
33370
|
+
const jsonPath = path31.join(d, manifestFile);
|
|
32844
33371
|
try {
|
|
32845
|
-
const raw =
|
|
33372
|
+
const raw = fs19.readFileSync(jsonPath, "utf-8");
|
|
32846
33373
|
const mod = JSON.parse(raw);
|
|
32847
33374
|
if (hasV1 && mod?.category === "cli") {
|
|
32848
33375
|
try {
|
|
@@ -32880,10 +33407,10 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
32880
33407
|
this.log(`\u26A0 Invalid provider at ${jsonPath}: ${validation.errors.join("; ")}`);
|
|
32881
33408
|
} else {
|
|
32882
33409
|
const hasCompatibility = Array.isArray(normalizedProvider.compatibility);
|
|
32883
|
-
const scriptsPath =
|
|
32884
|
-
if (!hasCompatibility &&
|
|
33410
|
+
const scriptsPath = path31.join(d, "scripts.js");
|
|
33411
|
+
if (!hasCompatibility && fs19.existsSync(scriptsPath)) {
|
|
32885
33412
|
try {
|
|
32886
|
-
registerProviderScriptRootSafely(
|
|
33413
|
+
registerProviderScriptRootSafely(path31.dirname(path31.dirname(d)));
|
|
32887
33414
|
delete __require.cache[__require.resolve(scriptsPath)];
|
|
32888
33415
|
const scripts = __require(scriptsPath);
|
|
32889
33416
|
normalizedProvider.scripts = scripts;
|
|
@@ -32891,12 +33418,30 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
32891
33418
|
this.log(`\u26A0 Failed to load scripts: ${scriptsPath}: ${e.message}`);
|
|
32892
33419
|
}
|
|
32893
33420
|
}
|
|
33421
|
+
const externalDirAbs = path31.join(os22.homedir(), ".adhdev", "external");
|
|
33422
|
+
const layer = d.startsWith(externalDirAbs) ? "external" : d.startsWith(this.userDir) && !d.includes(".upstream") ? "user" : "upstream";
|
|
33423
|
+
try {
|
|
33424
|
+
const { inspectManifestShape: inspectManifestShape2, classifyTrust: classifyTrust2 } = (init_provider_trust(), __toCommonJS(provider_trust_exports));
|
|
33425
|
+
const shape = inspectManifestShape2(mod);
|
|
33426
|
+
const trust = classifyTrust2(layer, shape);
|
|
33427
|
+
normalizedProvider._sourceLayer = layer;
|
|
33428
|
+
normalizedProvider._sourceTrust = trust;
|
|
33429
|
+
normalizedProvider._manifestShape = shape;
|
|
33430
|
+
if (layer === "external") {
|
|
33431
|
+
const rel = path31.relative(externalDirAbs, d);
|
|
33432
|
+
const firstSeg = rel.split(path31.sep)[0];
|
|
33433
|
+
if (firstSeg && firstSeg !== "..") normalizedProvider._sourceName = firstSeg;
|
|
33434
|
+
}
|
|
33435
|
+
} catch {
|
|
33436
|
+
}
|
|
32894
33437
|
const existed = this.providers.has(normalizedProvider.type);
|
|
32895
33438
|
this.providers.set(normalizedProvider.type, normalizedProvider);
|
|
32896
33439
|
count++;
|
|
32897
|
-
const source =
|
|
33440
|
+
const source = normalizedProvider._sourceLayer ?? "upstream";
|
|
32898
33441
|
const overrideWarning = existed && source === "user" ? " \u26A0 OVERRIDES upstream" : "";
|
|
32899
|
-
|
|
33442
|
+
const sourceName = normalizedProvider._sourceName;
|
|
33443
|
+
const sourceLabel = sourceName ? `${source}/${sourceName}` : source;
|
|
33444
|
+
this.log(` ${existed ? "\u{1F504}" : "\u2705"} ${normalizedProvider.type} (${normalizedProvider.category}) \u2014 ${normalizedProvider.name} [${sourceLabel}]${overrideWarning}`);
|
|
32900
33445
|
}
|
|
32901
33446
|
} catch (e) {
|
|
32902
33447
|
this.log(`\u26A0 Failed to load ${jsonPath}: ${e.message}`);
|
|
@@ -32906,8 +33451,9 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
32906
33451
|
for (const entry of entries) {
|
|
32907
33452
|
if (!entry.isDirectory()) continue;
|
|
32908
33453
|
if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
|
|
33454
|
+
if (d === dir && entry.name === "examples") continue;
|
|
32909
33455
|
if (excludeDirs && d === dir && excludeDirs.includes(entry.name)) continue;
|
|
32910
|
-
scan(
|
|
33456
|
+
scan(path31.join(d, entry.name));
|
|
32911
33457
|
}
|
|
32912
33458
|
}
|
|
32913
33459
|
};
|
|
@@ -33105,7 +33651,7 @@ async function isCdpActive(port) {
|
|
|
33105
33651
|
});
|
|
33106
33652
|
}
|
|
33107
33653
|
async function killIdeProcess(ideId) {
|
|
33108
|
-
const plat =
|
|
33654
|
+
const plat = os23.platform();
|
|
33109
33655
|
const appName = getMacAppIdentifiers()[ideId];
|
|
33110
33656
|
const winProcesses = getWinProcessNames()[ideId];
|
|
33111
33657
|
try {
|
|
@@ -33166,7 +33712,7 @@ async function killIdeProcess(ideId) {
|
|
|
33166
33712
|
}
|
|
33167
33713
|
}
|
|
33168
33714
|
async function isIdeRunning(ideId) {
|
|
33169
|
-
const plat =
|
|
33715
|
+
const plat = os23.platform();
|
|
33170
33716
|
try {
|
|
33171
33717
|
if (plat === "darwin") {
|
|
33172
33718
|
const appName = getMacAppIdentifiers()[ideId];
|
|
@@ -33221,7 +33767,7 @@ async function isIdeRunning(ideId) {
|
|
|
33221
33767
|
}
|
|
33222
33768
|
}
|
|
33223
33769
|
async function detectCurrentWorkspace(ideId) {
|
|
33224
|
-
const plat =
|
|
33770
|
+
const plat = os23.platform();
|
|
33225
33771
|
if (plat === "darwin") {
|
|
33226
33772
|
try {
|
|
33227
33773
|
const appName = getMacAppIdentifiers()[ideId];
|
|
@@ -33236,17 +33782,17 @@ async function detectCurrentWorkspace(ideId) {
|
|
|
33236
33782
|
}
|
|
33237
33783
|
} else if (plat === "win32") {
|
|
33238
33784
|
try {
|
|
33239
|
-
const
|
|
33785
|
+
const fs28 = __require("fs");
|
|
33240
33786
|
const appNameMap = getMacAppIdentifiers();
|
|
33241
33787
|
const appName = appNameMap[ideId];
|
|
33242
33788
|
if (appName) {
|
|
33243
|
-
const storagePath =
|
|
33244
|
-
process.env.APPDATA ||
|
|
33789
|
+
const storagePath = path32.join(
|
|
33790
|
+
process.env.APPDATA || path32.join(os23.homedir(), "AppData", "Roaming"),
|
|
33245
33791
|
appName,
|
|
33246
33792
|
"storage.json"
|
|
33247
33793
|
);
|
|
33248
|
-
if (
|
|
33249
|
-
const data = JSON.parse(
|
|
33794
|
+
if (fs28.existsSync(storagePath)) {
|
|
33795
|
+
const data = JSON.parse(fs28.readFileSync(storagePath, "utf-8"));
|
|
33250
33796
|
const workspaces = data?.openedPathsList?.workspaces3 || data?.openedPathsList?.entries || [];
|
|
33251
33797
|
if (workspaces.length > 0) {
|
|
33252
33798
|
const recent = workspaces[0];
|
|
@@ -33263,7 +33809,7 @@ async function detectCurrentWorkspace(ideId) {
|
|
|
33263
33809
|
return void 0;
|
|
33264
33810
|
}
|
|
33265
33811
|
async function launchWithCdp(options = {}) {
|
|
33266
|
-
const platform10 =
|
|
33812
|
+
const platform10 = os23.platform();
|
|
33267
33813
|
let targetIde;
|
|
33268
33814
|
const ides = await detectIDEs(getProviderLoader());
|
|
33269
33815
|
if (options.ideId) {
|
|
@@ -33430,14 +33976,14 @@ init_cli_detector();
|
|
|
33430
33976
|
init_logger();
|
|
33431
33977
|
|
|
33432
33978
|
// src/logging/command-log.ts
|
|
33433
|
-
import * as
|
|
33434
|
-
import * as
|
|
33435
|
-
import * as
|
|
33436
|
-
var LOG_DIR2 = process.platform === "win32" ?
|
|
33979
|
+
import * as fs20 from "fs";
|
|
33980
|
+
import * as path33 from "path";
|
|
33981
|
+
import * as os24 from "os";
|
|
33982
|
+
var LOG_DIR2 = process.platform === "win32" ? path33.join(process.env.LOCALAPPDATA || process.env.APPDATA || path33.join(os24.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path33.join(os24.homedir(), "Library", "Logs", "adhdev") : path33.join(os24.homedir(), ".local", "share", "adhdev", "logs");
|
|
33437
33983
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
33438
33984
|
var MAX_DAYS = 7;
|
|
33439
33985
|
try {
|
|
33440
|
-
|
|
33986
|
+
fs20.mkdirSync(LOG_DIR2, { recursive: true });
|
|
33441
33987
|
} catch {
|
|
33442
33988
|
}
|
|
33443
33989
|
var SENSITIVE_KEYS = /* @__PURE__ */ new Set([
|
|
@@ -33471,19 +34017,19 @@ function getDateStr2() {
|
|
|
33471
34017
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
33472
34018
|
}
|
|
33473
34019
|
var currentDate2 = getDateStr2();
|
|
33474
|
-
var currentFile =
|
|
34020
|
+
var currentFile = path33.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
33475
34021
|
var writeCount2 = 0;
|
|
33476
34022
|
function checkRotation() {
|
|
33477
34023
|
const today = getDateStr2();
|
|
33478
34024
|
if (today !== currentDate2) {
|
|
33479
34025
|
currentDate2 = today;
|
|
33480
|
-
currentFile =
|
|
34026
|
+
currentFile = path33.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
33481
34027
|
cleanOldFiles();
|
|
33482
34028
|
}
|
|
33483
34029
|
}
|
|
33484
34030
|
function cleanOldFiles() {
|
|
33485
34031
|
try {
|
|
33486
|
-
const files =
|
|
34032
|
+
const files = fs20.readdirSync(LOG_DIR2).filter((f) => f.startsWith("commands-") && f.endsWith(".jsonl"));
|
|
33487
34033
|
const cutoff = /* @__PURE__ */ new Date();
|
|
33488
34034
|
cutoff.setDate(cutoff.getDate() - MAX_DAYS);
|
|
33489
34035
|
const cutoffStr = cutoff.toISOString().slice(0, 10);
|
|
@@ -33491,7 +34037,7 @@ function cleanOldFiles() {
|
|
|
33491
34037
|
const dateMatch = file.match(/commands-(\d{4}-\d{2}-\d{2})/);
|
|
33492
34038
|
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
33493
34039
|
try {
|
|
33494
|
-
|
|
34040
|
+
fs20.unlinkSync(path33.join(LOG_DIR2, file));
|
|
33495
34041
|
} catch {
|
|
33496
34042
|
}
|
|
33497
34043
|
}
|
|
@@ -33501,14 +34047,14 @@ function cleanOldFiles() {
|
|
|
33501
34047
|
}
|
|
33502
34048
|
function checkSize() {
|
|
33503
34049
|
try {
|
|
33504
|
-
const stat2 =
|
|
34050
|
+
const stat2 = fs20.statSync(currentFile);
|
|
33505
34051
|
if (stat2.size > MAX_FILE_SIZE) {
|
|
33506
34052
|
const backup = currentFile.replace(".jsonl", ".1.jsonl");
|
|
33507
34053
|
try {
|
|
33508
|
-
|
|
34054
|
+
fs20.unlinkSync(backup);
|
|
33509
34055
|
} catch {
|
|
33510
34056
|
}
|
|
33511
|
-
|
|
34057
|
+
fs20.renameSync(currentFile, backup);
|
|
33512
34058
|
}
|
|
33513
34059
|
} catch {
|
|
33514
34060
|
}
|
|
@@ -33541,14 +34087,14 @@ function logCommand(entry) {
|
|
|
33541
34087
|
...entry.error ? { err: entry.error } : {},
|
|
33542
34088
|
...entry.durationMs !== void 0 ? { ms: entry.durationMs } : {}
|
|
33543
34089
|
});
|
|
33544
|
-
|
|
34090
|
+
fs20.appendFileSync(currentFile, line + "\n");
|
|
33545
34091
|
} catch {
|
|
33546
34092
|
}
|
|
33547
34093
|
}
|
|
33548
34094
|
function getRecentCommands(count = 50) {
|
|
33549
34095
|
try {
|
|
33550
|
-
if (!
|
|
33551
|
-
const content =
|
|
34096
|
+
if (!fs20.existsSync(currentFile)) return [];
|
|
34097
|
+
const content = fs20.readFileSync(currentFile, "utf-8");
|
|
33552
34098
|
const lines = content.trim().split("\n").filter(Boolean);
|
|
33553
34099
|
return lines.slice(-count).map((line) => {
|
|
33554
34100
|
try {
|
|
@@ -33582,7 +34128,7 @@ init_mesh_host_ownership();
|
|
|
33582
34128
|
|
|
33583
34129
|
// src/mesh/preview-freshness.ts
|
|
33584
34130
|
import { execFileSync as execFileSync3 } from "child_process";
|
|
33585
|
-
import { existsSync as
|
|
34131
|
+
import { existsSync as existsSync30, readFileSync as readFileSync23 } from "fs";
|
|
33586
34132
|
import { resolve as resolve18 } from "path";
|
|
33587
34133
|
var PREVIEW_DEPLOY_RECORD = ".adhdev/preview-deploy.json";
|
|
33588
34134
|
function runGit2(repoRoot, args) {
|
|
@@ -33598,10 +34144,10 @@ function runGit2(repoRoot, args) {
|
|
|
33598
34144
|
}
|
|
33599
34145
|
}
|
|
33600
34146
|
function readRecord3(repoRoot) {
|
|
33601
|
-
const
|
|
33602
|
-
if (!
|
|
34147
|
+
const path40 = resolve18(repoRoot, PREVIEW_DEPLOY_RECORD);
|
|
34148
|
+
if (!existsSync30(path40)) return null;
|
|
33603
34149
|
try {
|
|
33604
|
-
const parsed = JSON.parse(
|
|
34150
|
+
const parsed = JSON.parse(readFileSync23(path40, "utf8"));
|
|
33605
34151
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
33606
34152
|
} catch {
|
|
33607
34153
|
return null;
|
|
@@ -33664,7 +34210,7 @@ function buildPreviewFreshness(repoRoot) {
|
|
|
33664
34210
|
|
|
33665
34211
|
// src/status/snapshot.ts
|
|
33666
34212
|
init_config();
|
|
33667
|
-
import * as
|
|
34213
|
+
import * as os25 from "os";
|
|
33668
34214
|
init_terminal_screen();
|
|
33669
34215
|
init_logger();
|
|
33670
34216
|
var READ_DEBUG_ENABLED = process.argv.includes("--dev") || process.env.ADHDEV_READ_DEBUG === "1";
|
|
@@ -33702,25 +34248,50 @@ function buildDetectedIdeInfos(detectedIdes, cdpManagers) {
|
|
|
33702
34248
|
}
|
|
33703
34249
|
function buildAvailableProviders(providerLoader) {
|
|
33704
34250
|
const providers = providerLoader.getAvailableProviderInfos?.() || providerLoader.getAll();
|
|
33705
|
-
|
|
33706
|
-
|
|
33707
|
-
|
|
33708
|
-
|
|
33709
|
-
|
|
33710
|
-
|
|
33711
|
-
|
|
33712
|
-
|
|
33713
|
-
|
|
33714
|
-
|
|
33715
|
-
|
|
33716
|
-
|
|
33717
|
-
|
|
33718
|
-
|
|
34251
|
+
let describeTrust2 = () => "";
|
|
34252
|
+
let requiresConfirmation2 = () => false;
|
|
34253
|
+
try {
|
|
34254
|
+
const mod = (init_provider_trust(), __toCommonJS(provider_trust_exports));
|
|
34255
|
+
describeTrust2 = mod.describeTrust;
|
|
34256
|
+
requiresConfirmation2 = mod.requiresConfirmation;
|
|
34257
|
+
} catch {
|
|
34258
|
+
}
|
|
34259
|
+
return providers.map((provider) => {
|
|
34260
|
+
const trust = provider._sourceTrust;
|
|
34261
|
+
const sourceLayer = provider._sourceLayer;
|
|
34262
|
+
const sourceName = provider._sourceName;
|
|
34263
|
+
return {
|
|
34264
|
+
type: provider.type,
|
|
34265
|
+
name: provider.displayName || provider.type,
|
|
34266
|
+
displayName: provider.displayName || provider.type,
|
|
34267
|
+
icon: provider.icon || "\u{1F4BB}",
|
|
34268
|
+
category: provider.category,
|
|
34269
|
+
...provider.installed !== void 0 ? { installed: provider.installed } : {},
|
|
34270
|
+
...provider.detectedPath !== void 0 ? { detectedPath: provider.detectedPath } : {},
|
|
34271
|
+
...provider.enabled !== void 0 ? { enabled: provider.enabled } : {},
|
|
34272
|
+
...provider.machineStatus !== void 0 ? { machineStatus: provider.machineStatus } : {},
|
|
34273
|
+
...provider.lastDetection !== void 0 ? { lastDetection: provider.lastDetection } : {},
|
|
34274
|
+
...provider.lastVerification !== void 0 ? { lastVerification: provider.lastVerification } : {},
|
|
34275
|
+
...provider.meshCoordinator !== void 0 ? { meshCoordinator: provider.meshCoordinator } : {},
|
|
34276
|
+
...trust ? {
|
|
34277
|
+
trust,
|
|
34278
|
+
trustDescription: describeTrust2(trust),
|
|
34279
|
+
requiresConfirmation: requiresConfirmation2(trust)
|
|
34280
|
+
} : {},
|
|
34281
|
+
...sourceLayer ? { sourceLayer } : {},
|
|
34282
|
+
...sourceName ? { sourceName } : {},
|
|
34283
|
+
...provider.providerVersion ? { providerVersion: provider.providerVersion } : {},
|
|
34284
|
+
...provider.binary ? { binary: provider.binary } : {},
|
|
34285
|
+
...provider.status ? { status: provider.status } : {},
|
|
34286
|
+
...provider.details ? { details: provider.details } : {},
|
|
34287
|
+
...provider.links ? { links: provider.links } : {}
|
|
34288
|
+
};
|
|
34289
|
+
});
|
|
33719
34290
|
}
|
|
33720
34291
|
function buildMachineInfo(profile = "full") {
|
|
33721
34292
|
const base = {
|
|
33722
|
-
hostname:
|
|
33723
|
-
platform:
|
|
34293
|
+
hostname: os25.hostname(),
|
|
34294
|
+
platform: os25.platform()
|
|
33724
34295
|
};
|
|
33725
34296
|
if (profile === "live") {
|
|
33726
34297
|
return base;
|
|
@@ -33729,23 +34300,23 @@ function buildMachineInfo(profile = "full") {
|
|
|
33729
34300
|
const memSnap2 = getHostMemorySnapshot();
|
|
33730
34301
|
return {
|
|
33731
34302
|
...base,
|
|
33732
|
-
arch:
|
|
33733
|
-
cpus:
|
|
34303
|
+
arch: os25.arch(),
|
|
34304
|
+
cpus: os25.cpus().length,
|
|
33734
34305
|
totalMem: memSnap2.totalMem,
|
|
33735
|
-
release:
|
|
34306
|
+
release: os25.release()
|
|
33736
34307
|
};
|
|
33737
34308
|
}
|
|
33738
34309
|
const memSnap = getHostMemorySnapshot();
|
|
33739
34310
|
return {
|
|
33740
34311
|
...base,
|
|
33741
|
-
arch:
|
|
33742
|
-
cpus:
|
|
34312
|
+
arch: os25.arch(),
|
|
34313
|
+
cpus: os25.cpus().length,
|
|
33743
34314
|
totalMem: memSnap.totalMem,
|
|
33744
34315
|
freeMem: memSnap.freeMem,
|
|
33745
34316
|
availableMem: memSnap.availableMem,
|
|
33746
|
-
loadavg:
|
|
33747
|
-
uptime:
|
|
33748
|
-
release:
|
|
34317
|
+
loadavg: os25.loadavg(),
|
|
34318
|
+
uptime: os25.uptime(),
|
|
34319
|
+
release: os25.release()
|
|
33749
34320
|
};
|
|
33750
34321
|
}
|
|
33751
34322
|
function parseMessageTime(value) {
|
|
@@ -33986,42 +34557,42 @@ function buildStatusSnapshot(options) {
|
|
|
33986
34557
|
// src/commands/upgrade-helper.ts
|
|
33987
34558
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
33988
34559
|
import { spawn as spawn3 } from "child_process";
|
|
33989
|
-
import * as
|
|
33990
|
-
import * as
|
|
33991
|
-
import * as
|
|
34560
|
+
import * as fs21 from "fs";
|
|
34561
|
+
import * as os26 from "os";
|
|
34562
|
+
import * as path34 from "path";
|
|
33992
34563
|
var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
|
|
33993
34564
|
function getUpgradeLogPath() {
|
|
33994
|
-
const home =
|
|
33995
|
-
const dir =
|
|
33996
|
-
|
|
33997
|
-
return
|
|
34565
|
+
const home = os26.homedir();
|
|
34566
|
+
const dir = path34.join(home, ".adhdev");
|
|
34567
|
+
fs21.mkdirSync(dir, { recursive: true });
|
|
34568
|
+
return path34.join(dir, "daemon-upgrade.log");
|
|
33998
34569
|
}
|
|
33999
34570
|
function appendUpgradeLog(message) {
|
|
34000
34571
|
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
|
|
34001
34572
|
`;
|
|
34002
34573
|
try {
|
|
34003
|
-
|
|
34574
|
+
fs21.appendFileSync(getUpgradeLogPath(), line, "utf8");
|
|
34004
34575
|
} catch {
|
|
34005
34576
|
}
|
|
34006
34577
|
}
|
|
34007
34578
|
function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platform) {
|
|
34008
|
-
const binDir =
|
|
34579
|
+
const binDir = path34.dirname(nodeExecutable);
|
|
34009
34580
|
if (platform10 === "win32") {
|
|
34010
|
-
const npmCliPath =
|
|
34011
|
-
if (
|
|
34581
|
+
const npmCliPath = path34.join(binDir, "node_modules", "npm", "bin", "npm-cli.js");
|
|
34582
|
+
if (fs21.existsSync(npmCliPath)) {
|
|
34012
34583
|
return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
|
|
34013
34584
|
}
|
|
34014
34585
|
for (const candidate of ["npm.exe", "npm"]) {
|
|
34015
|
-
const candidatePath =
|
|
34016
|
-
if (
|
|
34586
|
+
const candidatePath = path34.join(binDir, candidate);
|
|
34587
|
+
if (fs21.existsSync(candidatePath)) {
|
|
34017
34588
|
return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
|
|
34018
34589
|
}
|
|
34019
34590
|
}
|
|
34020
34591
|
return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
|
|
34021
34592
|
}
|
|
34022
34593
|
for (const candidate of ["npm"]) {
|
|
34023
|
-
const candidatePath =
|
|
34024
|
-
if (
|
|
34594
|
+
const candidatePath = path34.join(binDir, candidate);
|
|
34595
|
+
if (fs21.existsSync(candidatePath)) {
|
|
34025
34596
|
return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
|
|
34026
34597
|
}
|
|
34027
34598
|
}
|
|
@@ -34031,22 +34602,22 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
34031
34602
|
if (!currentCliPath) return null;
|
|
34032
34603
|
let resolvedPath = currentCliPath;
|
|
34033
34604
|
try {
|
|
34034
|
-
resolvedPath =
|
|
34605
|
+
resolvedPath = fs21.realpathSync.native(currentCliPath);
|
|
34035
34606
|
} catch {
|
|
34036
34607
|
}
|
|
34037
34608
|
let currentDir = resolvedPath;
|
|
34038
34609
|
try {
|
|
34039
|
-
if (
|
|
34040
|
-
currentDir =
|
|
34610
|
+
if (fs21.statSync(resolvedPath).isFile()) {
|
|
34611
|
+
currentDir = path34.dirname(resolvedPath);
|
|
34041
34612
|
}
|
|
34042
34613
|
} catch {
|
|
34043
|
-
currentDir =
|
|
34614
|
+
currentDir = path34.dirname(resolvedPath);
|
|
34044
34615
|
}
|
|
34045
34616
|
while (true) {
|
|
34046
|
-
const packageJsonPath =
|
|
34617
|
+
const packageJsonPath = path34.join(currentDir, "package.json");
|
|
34047
34618
|
try {
|
|
34048
|
-
if (
|
|
34049
|
-
const parsed = JSON.parse(
|
|
34619
|
+
if (fs21.existsSync(packageJsonPath)) {
|
|
34620
|
+
const parsed = JSON.parse(fs21.readFileSync(packageJsonPath, "utf8"));
|
|
34050
34621
|
if (parsed?.name === packageName) {
|
|
34051
34622
|
const normalized = currentDir.replace(/\\/g, "/");
|
|
34052
34623
|
return normalized.includes("/node_modules/") ? currentDir : null;
|
|
@@ -34054,7 +34625,7 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
34054
34625
|
}
|
|
34055
34626
|
} catch {
|
|
34056
34627
|
}
|
|
34057
|
-
const parentDir =
|
|
34628
|
+
const parentDir = path34.dirname(currentDir);
|
|
34058
34629
|
if (parentDir === currentDir) {
|
|
34059
34630
|
return null;
|
|
34060
34631
|
}
|
|
@@ -34062,13 +34633,13 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
34062
34633
|
}
|
|
34063
34634
|
}
|
|
34064
34635
|
function resolveInstallPrefixFromPackageRoot(packageRoot, packageName) {
|
|
34065
|
-
const nodeModulesDir = packageName.startsWith("@") ?
|
|
34066
|
-
if (
|
|
34636
|
+
const nodeModulesDir = packageName.startsWith("@") ? path34.dirname(path34.dirname(packageRoot)) : path34.dirname(packageRoot);
|
|
34637
|
+
if (path34.basename(nodeModulesDir) !== "node_modules") {
|
|
34067
34638
|
return null;
|
|
34068
34639
|
}
|
|
34069
|
-
const maybeLibDir =
|
|
34070
|
-
if (
|
|
34071
|
-
return
|
|
34640
|
+
const maybeLibDir = path34.dirname(nodeModulesDir);
|
|
34641
|
+
if (path34.basename(maybeLibDir) === "lib") {
|
|
34642
|
+
return path34.dirname(maybeLibDir);
|
|
34072
34643
|
}
|
|
34073
34644
|
return maybeLibDir;
|
|
34074
34645
|
}
|
|
@@ -34183,10 +34754,10 @@ async function waitForPidExit(pid, timeoutMs) {
|
|
|
34183
34754
|
}
|
|
34184
34755
|
}
|
|
34185
34756
|
function stopSessionHostProcesses(appName) {
|
|
34186
|
-
const pidFile =
|
|
34757
|
+
const pidFile = path34.join(os26.homedir(), ".adhdev", `${appName}-session-host.pid`);
|
|
34187
34758
|
try {
|
|
34188
|
-
if (
|
|
34189
|
-
const pid = Number.parseInt(
|
|
34759
|
+
if (fs21.existsSync(pidFile)) {
|
|
34760
|
+
const pid = Number.parseInt(fs21.readFileSync(pidFile, "utf8").trim(), 10);
|
|
34190
34761
|
if (Number.isFinite(pid) && pid !== process.pid && isManagedSessionHostPid(pid)) {
|
|
34191
34762
|
killPid(pid);
|
|
34192
34763
|
}
|
|
@@ -34194,15 +34765,15 @@ function stopSessionHostProcesses(appName) {
|
|
|
34194
34765
|
} catch {
|
|
34195
34766
|
} finally {
|
|
34196
34767
|
try {
|
|
34197
|
-
|
|
34768
|
+
fs21.unlinkSync(pidFile);
|
|
34198
34769
|
} catch {
|
|
34199
34770
|
}
|
|
34200
34771
|
}
|
|
34201
34772
|
}
|
|
34202
34773
|
function removeDaemonPidFile() {
|
|
34203
|
-
const pidFile =
|
|
34774
|
+
const pidFile = path34.join(os26.homedir(), ".adhdev", "daemon.pid");
|
|
34204
34775
|
try {
|
|
34205
|
-
|
|
34776
|
+
fs21.unlinkSync(pidFile);
|
|
34206
34777
|
} catch {
|
|
34207
34778
|
}
|
|
34208
34779
|
}
|
|
@@ -34211,7 +34782,7 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
|
|
|
34211
34782
|
const npmRoot = String(execNpmCommandSync(["root", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
|
|
34212
34783
|
if (!npmRoot) return;
|
|
34213
34784
|
const npmPrefix = surface.installPrefix || String(execNpmCommandSync(["prefix", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
|
|
34214
|
-
const binDir = process.platform === "win32" ? npmPrefix :
|
|
34785
|
+
const binDir = process.platform === "win32" ? npmPrefix : path34.join(npmPrefix, "bin");
|
|
34215
34786
|
const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
|
|
34216
34787
|
const binNames = /* @__PURE__ */ new Set([packageBaseName]);
|
|
34217
34788
|
if (pkgName === "@adhdev/daemon-standalone") {
|
|
@@ -34219,25 +34790,25 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
|
|
|
34219
34790
|
}
|
|
34220
34791
|
if (pkgName.startsWith("@")) {
|
|
34221
34792
|
const [scope, name] = pkgName.split("/");
|
|
34222
|
-
const scopeDir =
|
|
34223
|
-
if (!
|
|
34224
|
-
for (const entry of
|
|
34793
|
+
const scopeDir = path34.join(npmRoot, scope);
|
|
34794
|
+
if (!fs21.existsSync(scopeDir)) return;
|
|
34795
|
+
for (const entry of fs21.readdirSync(scopeDir)) {
|
|
34225
34796
|
if (!entry.startsWith(`.${name}-`)) continue;
|
|
34226
|
-
|
|
34227
|
-
appendUpgradeLog(`Removed stale scoped staging dir: ${
|
|
34797
|
+
fs21.rmSync(path34.join(scopeDir, entry), { recursive: true, force: true });
|
|
34798
|
+
appendUpgradeLog(`Removed stale scoped staging dir: ${path34.join(scopeDir, entry)}`);
|
|
34228
34799
|
}
|
|
34229
34800
|
} else {
|
|
34230
|
-
for (const entry of
|
|
34801
|
+
for (const entry of fs21.readdirSync(npmRoot)) {
|
|
34231
34802
|
if (!entry.startsWith(`.${pkgName}-`)) continue;
|
|
34232
|
-
|
|
34233
|
-
appendUpgradeLog(`Removed stale staging dir: ${
|
|
34803
|
+
fs21.rmSync(path34.join(npmRoot, entry), { recursive: true, force: true });
|
|
34804
|
+
appendUpgradeLog(`Removed stale staging dir: ${path34.join(npmRoot, entry)}`);
|
|
34234
34805
|
}
|
|
34235
34806
|
}
|
|
34236
|
-
if (
|
|
34237
|
-
for (const entry of
|
|
34807
|
+
if (fs21.existsSync(binDir)) {
|
|
34808
|
+
for (const entry of fs21.readdirSync(binDir)) {
|
|
34238
34809
|
if (!Array.from(binNames).some((name) => entry.startsWith(`.${name}-`))) continue;
|
|
34239
|
-
|
|
34240
|
-
appendUpgradeLog(`Removed stale bin staging entry: ${
|
|
34810
|
+
fs21.rmSync(path34.join(binDir, entry), { recursive: true, force: true });
|
|
34811
|
+
appendUpgradeLog(`Removed stale bin staging entry: ${path34.join(binDir, entry)}`);
|
|
34241
34812
|
}
|
|
34242
34813
|
}
|
|
34243
34814
|
}
|
|
@@ -34323,9 +34894,9 @@ async function maybeRunDaemonUpgradeHelperFromEnv() {
|
|
|
34323
34894
|
|
|
34324
34895
|
// src/commands/router.ts
|
|
34325
34896
|
init_mesh_work_queue();
|
|
34326
|
-
import { homedir as
|
|
34897
|
+
import { homedir as homedir25, hostname as osHostname } from "os";
|
|
34327
34898
|
import { basename as pathBasename, join as pathJoin, resolve as pathResolve2 } from "path";
|
|
34328
|
-
import * as
|
|
34899
|
+
import * as fs22 from "fs";
|
|
34329
34900
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
34330
34901
|
var CHANNEL_NPM_TAG = { stable: "latest", preview: "next" };
|
|
34331
34902
|
var CHANNEL_SERVER_URL = {
|
|
@@ -34452,12 +35023,12 @@ function readGitSubmodules(value, parentRepoRoot) {
|
|
|
34452
35023
|
if (!Array.isArray(value)) return void 0;
|
|
34453
35024
|
const submodules = value.map((entry) => {
|
|
34454
35025
|
const submodule = readObjectRecord(entry);
|
|
34455
|
-
const
|
|
35026
|
+
const path40 = readStringValue(submodule.path);
|
|
34456
35027
|
const commit = readStringValue(submodule.commit);
|
|
34457
|
-
const repoPath = readStringValue(submodule.repoPath, submodule.repo_root) ?? joinRepoPath(parentRepoRoot,
|
|
34458
|
-
if (!
|
|
35028
|
+
const repoPath = readStringValue(submodule.repoPath, submodule.repo_root) ?? joinRepoPath(parentRepoRoot, path40);
|
|
35029
|
+
if (!path40 || !commit || !repoPath) return null;
|
|
34459
35030
|
return {
|
|
34460
|
-
path:
|
|
35031
|
+
path: path40,
|
|
34461
35032
|
commit,
|
|
34462
35033
|
repoPath,
|
|
34463
35034
|
dirty: readBooleanValue(submodule.dirty) ?? false,
|
|
@@ -35099,7 +35670,7 @@ async function hydrateInlineMeshDirectTruth(args) {
|
|
|
35099
35670
|
if (!isSelfNode && daemonId) unavailableNodeIds.push(nodeId);
|
|
35100
35671
|
continue;
|
|
35101
35672
|
}
|
|
35102
|
-
if (
|
|
35673
|
+
if (fs22.existsSync(workspace)) {
|
|
35103
35674
|
try {
|
|
35104
35675
|
const localGit = await getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
|
|
35105
35676
|
if (localGit?.isGitRepo) {
|
|
@@ -35184,7 +35755,7 @@ function readLiveMeshNodeWorkspace(args) {
|
|
|
35184
35755
|
}
|
|
35185
35756
|
function collectLiveMeshSessionRecords(args) {
|
|
35186
35757
|
const nodeWorkspace = readStringValue(args.node?.workspace);
|
|
35187
|
-
const nodeIsMissingLocalWorktree = args.node?.isLocalWorktree === true && !!nodeWorkspace && !
|
|
35758
|
+
const nodeIsMissingLocalWorktree = args.node?.isLocalWorktree === true && !!nodeWorkspace && !fs22.existsSync(nodeWorkspace);
|
|
35188
35759
|
const matches = args.liveSessionRecords.filter((record) => {
|
|
35189
35760
|
const recordNodeId = readStringValue(record?.meta?.meshNodeId);
|
|
35190
35761
|
if (recordNodeId && recordNodeId !== args.nodeId) return false;
|
|
@@ -35211,7 +35782,7 @@ function buildHistoricalMeshSessions(args) {
|
|
|
35211
35782
|
const workspace = readStringValue(node?.workspace);
|
|
35212
35783
|
if (nodeId) liveNodeIds.add(nodeId);
|
|
35213
35784
|
if (workspace) liveWorkspaces.add(workspace);
|
|
35214
|
-
if (nodeId && node?.isLocalWorktree === true && workspace && !
|
|
35785
|
+
if (nodeId && node?.isLocalWorktree === true && workspace && !fs22.existsSync(workspace)) {
|
|
35215
35786
|
missingLocalWorktreeNodeIds.add(nodeId);
|
|
35216
35787
|
}
|
|
35217
35788
|
}
|
|
@@ -35410,10 +35981,10 @@ ${e?.stderr || ""}`
|
|
|
35410
35981
|
}
|
|
35411
35982
|
function buildPatchEquivalenceSubmoduleConflictHint(repoRoot, baseHead, branchHead, output) {
|
|
35412
35983
|
if (!/(submodule|160000)/i.test(output) || !/(conflict|failed to merge)/i.test(output)) return void 0;
|
|
35413
|
-
const conflicts = readChangedGitlinkPaths(repoRoot, baseHead, branchHead).map((
|
|
35414
|
-
path:
|
|
35415
|
-
baseCommit: readTreeObject(repoRoot, baseHead,
|
|
35416
|
-
branchCommit: readTreeObject(repoRoot, branchHead,
|
|
35984
|
+
const conflicts = readChangedGitlinkPaths(repoRoot, baseHead, branchHead).map((path40) => ({
|
|
35985
|
+
path: path40,
|
|
35986
|
+
baseCommit: readTreeObject(repoRoot, baseHead, path40),
|
|
35987
|
+
branchCommit: readTreeObject(repoRoot, branchHead, path40)
|
|
35417
35988
|
}));
|
|
35418
35989
|
if (conflicts.length === 0) return void 0;
|
|
35419
35990
|
return {
|
|
@@ -35439,11 +36010,11 @@ function readChangedGitlinkPaths(repoRoot, fromRef, toRef) {
|
|
|
35439
36010
|
if (!line.trim()) continue;
|
|
35440
36011
|
const metaAndPath = line.split(" ");
|
|
35441
36012
|
const meta = metaAndPath[0] || "";
|
|
35442
|
-
const
|
|
35443
|
-
if (!
|
|
36013
|
+
const path40 = metaAndPath[metaAndPath.length - 1]?.trim();
|
|
36014
|
+
if (!path40) continue;
|
|
35444
36015
|
const parts = meta.split(/\s+/);
|
|
35445
36016
|
if (parts[0]?.includes("160000") || parts[1]?.includes("160000")) {
|
|
35446
|
-
paths.add(
|
|
36017
|
+
paths.add(path40);
|
|
35447
36018
|
}
|
|
35448
36019
|
}
|
|
35449
36020
|
return [...paths].sort();
|
|
@@ -35451,9 +36022,9 @@ function readChangedGitlinkPaths(repoRoot, fromRef, toRef) {
|
|
|
35451
36022
|
return [];
|
|
35452
36023
|
}
|
|
35453
36024
|
}
|
|
35454
|
-
function readTreeObject(repoRoot, ref,
|
|
36025
|
+
function readTreeObject(repoRoot, ref, path40) {
|
|
35455
36026
|
try {
|
|
35456
|
-
const output = execFileSync5("git", ["ls-tree", ref, "--",
|
|
36027
|
+
const output = execFileSync5("git", ["ls-tree", ref, "--", path40], {
|
|
35457
36028
|
cwd: repoRoot,
|
|
35458
36029
|
encoding: "utf8",
|
|
35459
36030
|
maxBuffer: 1024 * 1024
|
|
@@ -35466,7 +36037,7 @@ function readTreeObject(repoRoot, ref, path39) {
|
|
|
35466
36037
|
}
|
|
35467
36038
|
async function alignRefinerySubmodulesAfterMerge(repoRoot, previousBaseHead, currentHead, options = {}) {
|
|
35468
36039
|
const startedAt = Date.now();
|
|
35469
|
-
const changedGitlinkPaths = readChangedGitlinkPaths(repoRoot, previousBaseHead, currentHead).filter((
|
|
36040
|
+
const changedGitlinkPaths = readChangedGitlinkPaths(repoRoot, previousBaseHead, currentHead).filter((path40) => !(options.submoduleIgnorePaths || []).includes(path40));
|
|
35470
36041
|
const preStatus = await getGitRepoStatus(repoRoot, {
|
|
35471
36042
|
includeSubmodules: true,
|
|
35472
36043
|
submoduleIgnorePaths: options.submoduleIgnorePaths,
|
|
@@ -35507,7 +36078,7 @@ async function alignRefinerySubmodulesAfterMerge(repoRoot, previousBaseHead, cur
|
|
|
35507
36078
|
changedGitlinkPaths,
|
|
35508
36079
|
outOfSyncPaths,
|
|
35509
36080
|
updatedPaths: updatePaths,
|
|
35510
|
-
verifiedPaths: updatePaths.filter((
|
|
36081
|
+
verifiedPaths: updatePaths.filter((path40) => !remaining.some((submodule) => submodule.path === path40)),
|
|
35511
36082
|
durationMs: Date.now() - startedAt,
|
|
35512
36083
|
command: `git ${commandArgs.join(" ")}`,
|
|
35513
36084
|
stdout: truncateValidationOutput(result.stdout),
|
|
@@ -35562,7 +36133,7 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
35562
36133
|
return { stdout: String(stdout || ""), stderr: String(stderr || ""), refspec };
|
|
35563
36134
|
};
|
|
35564
36135
|
const importCommitFromWorktreeSubmodule = async (submodulePath, worktreeSubmodulePath, commit) => {
|
|
35565
|
-
if (!
|
|
36136
|
+
if (!fs22.existsSync(worktreeSubmodulePath)) return false;
|
|
35566
36137
|
try {
|
|
35567
36138
|
await runGit3(worktreeSubmodulePath, ["cat-file", "-e", `${commit}^{commit}`]);
|
|
35568
36139
|
} catch {
|
|
@@ -35585,7 +36156,7 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
35585
36156
|
reachable: false
|
|
35586
36157
|
};
|
|
35587
36158
|
try {
|
|
35588
|
-
if (!
|
|
36159
|
+
if (!fs22.existsSync(submodulePath)) {
|
|
35589
36160
|
entry.error = `Submodule checkout missing at ${gitlink.path}`;
|
|
35590
36161
|
entry.publishRequired = true;
|
|
35591
36162
|
if (options.allowAutoPublishSubmoduleMainCommits === true) {
|
|
@@ -35777,9 +36348,9 @@ async function runMeshRefineValidationGate(mesh, workspace) {
|
|
|
35777
36348
|
return ["npm", "pnpm", "yarn", "bun"].includes(command) && candidate.args.some((arg) => arg === "run" || arg === "test" || arg === "exec");
|
|
35778
36349
|
};
|
|
35779
36350
|
const dependenciesLikelyMissing = (cwd) => {
|
|
35780
|
-
if (!
|
|
35781
|
-
if (
|
|
35782
|
-
return ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"].some((lock) =>
|
|
36351
|
+
if (!fs22.existsSync(pathJoin(cwd, "package.json"))) return false;
|
|
36352
|
+
if (fs22.existsSync(pathJoin(cwd, "node_modules"))) return false;
|
|
36353
|
+
return ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"].some((lock) => fs22.existsSync(pathJoin(cwd, lock)));
|
|
35783
36354
|
};
|
|
35784
36355
|
for (const candidate of selection.bootstrapCommands) {
|
|
35785
36356
|
const startedAt = Date.now();
|
|
@@ -35871,14 +36442,14 @@ function serializeMeshCoordinatorMcpConfig(config, format) {
|
|
|
35871
36442
|
}
|
|
35872
36443
|
function resolveHermesUserHome() {
|
|
35873
36444
|
const explicitHome = process.env.HERMES_HOME?.trim();
|
|
35874
|
-
return explicitHome || pathJoin(
|
|
36445
|
+
return explicitHome || pathJoin(homedir25(), ".hermes");
|
|
35875
36446
|
}
|
|
35876
36447
|
function loadHermesCoordinatorBaseConfig(targetConfigPath) {
|
|
35877
36448
|
const sourceHome = resolveHermesUserHome();
|
|
35878
36449
|
const sourceConfigPath = pathJoin(sourceHome, "config.yaml");
|
|
35879
|
-
if (!
|
|
36450
|
+
if (!fs22.existsSync(sourceConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
35880
36451
|
if (pathResolve2(sourceConfigPath) === pathResolve2(targetConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
35881
|
-
const parsed = parseMeshCoordinatorMcpConfig(
|
|
36452
|
+
const parsed = parseMeshCoordinatorMcpConfig(fs22.readFileSync(sourceConfigPath, "utf-8"), "hermes_config_yaml");
|
|
35882
36453
|
const { mcp_servers: _mcpServers, ...baseConfig } = parsed;
|
|
35883
36454
|
return { config: baseConfig, sourceHome, sourceConfigPath };
|
|
35884
36455
|
}
|
|
@@ -35915,9 +36486,9 @@ function copyHermesCoordinatorCredentialFiles(sourceHome, targetHome) {
|
|
|
35915
36486
|
for (const fileName of [".env", "auth.json"]) {
|
|
35916
36487
|
const sourcePath = pathJoin(sourceHome, fileName);
|
|
35917
36488
|
const targetPath = pathJoin(targetHome, fileName);
|
|
35918
|
-
if (!
|
|
36489
|
+
if (!fs22.existsSync(sourcePath)) continue;
|
|
35919
36490
|
try {
|
|
35920
|
-
|
|
36491
|
+
fs22.copyFileSync(sourcePath, targetPath);
|
|
35921
36492
|
} catch (error) {
|
|
35922
36493
|
LOG.warn("MeshCoordinator", `Could not copy Hermes ${fileName} into isolated coordinator home: ${error?.message || error}`);
|
|
35923
36494
|
}
|
|
@@ -36272,13 +36843,13 @@ var DaemonCommandRouter = class {
|
|
|
36272
36843
|
recoveryHint: "Inspect the mesh node record before removing it, or remove stale metadata manually only after confirming no managed worktree remains."
|
|
36273
36844
|
};
|
|
36274
36845
|
}
|
|
36275
|
-
const worktreeExists =
|
|
36846
|
+
const worktreeExists = fs22.existsSync(workspace);
|
|
36276
36847
|
const sourceNode = args.node?.clonedFromNodeId ? args.mesh?.nodes?.find((n) => n.id === args.node.clonedFromNodeId || n.nodeId === args.node.clonedFromNodeId) : args.mesh?.nodes?.find((n) => !n.isLocalWorktree);
|
|
36277
36848
|
const repoRoot = typeof sourceNode?.repoRoot === "string" && sourceNode.repoRoot.trim() ? sourceNode.repoRoot.trim() : typeof sourceNode?.workspace === "string" && sourceNode.workspace.trim() ? sourceNode.workspace.trim() : "";
|
|
36278
36849
|
if (!worktreeExists) {
|
|
36279
36850
|
return { success: true, skipped: true, removedPath: workspace, repoRoot: repoRoot || void 0, reason: "worktree_path_missing" };
|
|
36280
36851
|
}
|
|
36281
|
-
if (!repoRoot || !
|
|
36852
|
+
if (!repoRoot || !fs22.existsSync(repoRoot)) {
|
|
36282
36853
|
return {
|
|
36283
36854
|
success: false,
|
|
36284
36855
|
code: "mesh_worktree_cleanup_missing_source_repo",
|
|
@@ -36298,7 +36869,7 @@ var DaemonCommandRouter = class {
|
|
|
36298
36869
|
const normalizePath = (value) => {
|
|
36299
36870
|
const resolved = pathResolve2(value);
|
|
36300
36871
|
try {
|
|
36301
|
-
return
|
|
36872
|
+
return fs22.realpathSync(resolved);
|
|
36302
36873
|
} catch {
|
|
36303
36874
|
return resolved;
|
|
36304
36875
|
}
|
|
@@ -37237,8 +37808,8 @@ var DaemonCommandRouter = class {
|
|
|
37237
37808
|
if (sinceTs > 0) {
|
|
37238
37809
|
return { success: true, logs: [], totalBuffered: 0 };
|
|
37239
37810
|
}
|
|
37240
|
-
if (
|
|
37241
|
-
const content =
|
|
37811
|
+
if (fs22.existsSync(LOG_PATH)) {
|
|
37812
|
+
const content = fs22.readFileSync(LOG_PATH, "utf-8");
|
|
37242
37813
|
const allLines = content.split("\n");
|
|
37243
37814
|
const recent = allLines.slice(-count).join("\n");
|
|
37244
37815
|
return { success: true, logs: recent, totalLines: allLines.length };
|
|
@@ -37628,24 +38199,24 @@ var DaemonCommandRouter = class {
|
|
|
37628
38199
|
// Settings page in the dashboard reads/writes via these two
|
|
37629
38200
|
// commands instead of going through fs from the browser.
|
|
37630
38201
|
case "list_coordinator_prompts": {
|
|
37631
|
-
const
|
|
37632
|
-
const
|
|
37633
|
-
const
|
|
37634
|
-
const dir =
|
|
38202
|
+
const fs28 = await import("fs");
|
|
38203
|
+
const path40 = await import("path");
|
|
38204
|
+
const os29 = await import("os");
|
|
38205
|
+
const dir = path40.join(os29.homedir(), ".adhdev", "coordinator-prompts");
|
|
37635
38206
|
const entries = {};
|
|
37636
38207
|
try {
|
|
37637
|
-
if (
|
|
37638
|
-
for (const name of
|
|
38208
|
+
if (fs28.existsSync(dir)) {
|
|
38209
|
+
for (const name of fs28.readdirSync(dir)) {
|
|
37639
38210
|
const matchOverride = name.match(/^([a-zA-Z0-9_.-]+)\.md$/);
|
|
37640
38211
|
const matchAppend = name.match(/^([a-zA-Z0-9_.-]+)\.append\.md$/);
|
|
37641
38212
|
const m = matchAppend || matchOverride;
|
|
37642
38213
|
if (!m) continue;
|
|
37643
38214
|
const isAppend = !!matchAppend;
|
|
37644
38215
|
const key = m[1];
|
|
37645
|
-
const full =
|
|
38216
|
+
const full = path40.join(dir, name);
|
|
37646
38217
|
let content = "";
|
|
37647
38218
|
try {
|
|
37648
|
-
content =
|
|
38219
|
+
content = fs28.readFileSync(full, "utf8");
|
|
37649
38220
|
} catch {
|
|
37650
38221
|
}
|
|
37651
38222
|
if (!entries[key]) entries[key] = { override: "", append: "" };
|
|
@@ -37659,24 +38230,24 @@ var DaemonCommandRouter = class {
|
|
|
37659
38230
|
return { success: true, dir, entries };
|
|
37660
38231
|
}
|
|
37661
38232
|
case "write_coordinator_prompt": {
|
|
37662
|
-
const
|
|
37663
|
-
const
|
|
37664
|
-
const
|
|
38233
|
+
const fs28 = await import("fs");
|
|
38234
|
+
const path40 = await import("path");
|
|
38235
|
+
const os29 = await import("os");
|
|
37665
38236
|
const key = typeof args?.key === "string" ? args.key.trim() : "";
|
|
37666
38237
|
const kind = args?.kind === "append" ? "append" : "override";
|
|
37667
38238
|
const content = typeof args?.content === "string" ? args.content : "";
|
|
37668
38239
|
if (!key || !/^[a-zA-Z0-9_.-]+$/.test(key)) {
|
|
37669
38240
|
return { success: false, error: "key must match [a-zA-Z0-9_.-]+" };
|
|
37670
38241
|
}
|
|
37671
|
-
const dir =
|
|
38242
|
+
const dir = path40.join(os29.homedir(), ".adhdev", "coordinator-prompts");
|
|
37672
38243
|
const filename = kind === "append" ? `${key}.append.md` : `${key}.md`;
|
|
37673
|
-
const full =
|
|
38244
|
+
const full = path40.join(dir, filename);
|
|
37674
38245
|
try {
|
|
37675
|
-
|
|
38246
|
+
fs28.mkdirSync(dir, { recursive: true });
|
|
37676
38247
|
if (content.trim()) {
|
|
37677
|
-
|
|
37678
|
-
} else if (
|
|
37679
|
-
|
|
38248
|
+
fs28.writeFileSync(full, content, { encoding: "utf8", mode: 384 });
|
|
38249
|
+
} else if (fs28.existsSync(full)) {
|
|
38250
|
+
fs28.unlinkSync(full);
|
|
37680
38251
|
}
|
|
37681
38252
|
return { success: true, path: full, kind, key };
|
|
37682
38253
|
} catch (error) {
|
|
@@ -38885,7 +39456,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
38885
39456
|
workspace
|
|
38886
39457
|
};
|
|
38887
39458
|
}
|
|
38888
|
-
const { existsSync:
|
|
39459
|
+
const { existsSync: existsSync39, readFileSync: readFileSync33, writeFileSync: writeFileSync20, copyFileSync: copyFileSync4, mkdirSync: mkdirSync19 } = await import("fs");
|
|
38889
39460
|
const { dirname: dirname11 } = await import("path");
|
|
38890
39461
|
const mcpConfigPath = coordinatorSetup.configPath;
|
|
38891
39462
|
const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
|
|
@@ -38921,21 +39492,21 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
38921
39492
|
};
|
|
38922
39493
|
}
|
|
38923
39494
|
try {
|
|
38924
|
-
|
|
39495
|
+
mkdirSync19(dirname11(mcpConfigPath), { recursive: true });
|
|
38925
39496
|
} catch (error) {
|
|
38926
39497
|
const message = `Could not prepare MCP config path for automatic setup: ${error?.message || error}`;
|
|
38927
39498
|
LOG.error("MeshCoordinator", message);
|
|
38928
39499
|
if (hermesManualFallback) return returnManualFallback(message);
|
|
38929
39500
|
return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
|
|
38930
39501
|
}
|
|
38931
|
-
const hadExistingMcpConfig =
|
|
39502
|
+
const hadExistingMcpConfig = existsSync39(mcpConfigPath);
|
|
38932
39503
|
let existingMcpConfig = hermesBaseConfig?.config || {};
|
|
38933
39504
|
if (hermesBaseConfig) {
|
|
38934
39505
|
copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname11(mcpConfigPath));
|
|
38935
39506
|
}
|
|
38936
39507
|
if (hadExistingMcpConfig) {
|
|
38937
39508
|
try {
|
|
38938
|
-
const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(
|
|
39509
|
+
const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync33(mcpConfigPath, "utf-8"), configFormat);
|
|
38939
39510
|
const existingCoordinatorConfig = hermesManualFallback ? stripHermesCoordinatorTempModelProviderOverrides(parsedExistingMcpConfig) : parsedExistingMcpConfig;
|
|
38940
39511
|
existingMcpConfig = { ...existingMcpConfig, ...existingCoordinatorConfig };
|
|
38941
39512
|
copyFileSync4(mcpConfigPath, mcpConfigPath + ".backup");
|
|
@@ -38958,7 +39529,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
38958
39529
|
}
|
|
38959
39530
|
};
|
|
38960
39531
|
try {
|
|
38961
|
-
|
|
39532
|
+
writeFileSync20(mcpConfigPath, serializeMeshCoordinatorMcpConfig(mcpConfig, configFormat), "utf-8");
|
|
38962
39533
|
} catch (error) {
|
|
38963
39534
|
const message = `Could not write MCP config for automatic setup: ${error?.message || error}`;
|
|
38964
39535
|
LOG.error("MeshCoordinator", message);
|
|
@@ -39237,7 +39808,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
39237
39808
|
}
|
|
39238
39809
|
}
|
|
39239
39810
|
if (workspace) {
|
|
39240
|
-
if (!
|
|
39811
|
+
if (!fs22.existsSync(workspace)) {
|
|
39241
39812
|
const inlineTransitGit = buildInlineMeshTransitGitStatus(node);
|
|
39242
39813
|
let remoteProbeApplied = false;
|
|
39243
39814
|
if (inlineTransitGit) {
|
|
@@ -39350,7 +39921,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
39350
39921
|
const callerCoordinatorDaemonId = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : this.deps.statusInstanceId || void 0;
|
|
39351
39922
|
const pendingCoordinatorEvents = drainPendingMeshCoordinatorEvents(meshId, callerCoordinatorDaemonId);
|
|
39352
39923
|
const previewFreshness = (() => {
|
|
39353
|
-
const localRepoRoot = nodeStatuses.map((node) => readStringValue(node?.git?.repoRoot, node?.repoRoot, node?.workspace)).find((candidate) => !!candidate &&
|
|
39924
|
+
const localRepoRoot = nodeStatuses.map((node) => readStringValue(node?.git?.repoRoot, node?.repoRoot, node?.workspace)).find((candidate) => !!candidate && fs22.existsSync(candidate));
|
|
39354
39925
|
return localRepoRoot ? buildPreviewFreshness(localRepoRoot) : void 0;
|
|
39355
39926
|
})();
|
|
39356
39927
|
const asyncRefineJobs = buildMeshAsyncRefineJobs({
|
|
@@ -41097,12 +41668,12 @@ var ProviderInstanceManager = class {
|
|
|
41097
41668
|
};
|
|
41098
41669
|
|
|
41099
41670
|
// src/providers/version-archive.ts
|
|
41100
|
-
import * as
|
|
41101
|
-
import * as
|
|
41102
|
-
import * as
|
|
41671
|
+
import * as fs23 from "fs";
|
|
41672
|
+
import * as path35 from "path";
|
|
41673
|
+
import * as os27 from "os";
|
|
41103
41674
|
import { platform as platform8 } from "os";
|
|
41104
41675
|
import { exec as exec5 } from "child_process";
|
|
41105
|
-
var ARCHIVE_PATH =
|
|
41676
|
+
var ARCHIVE_PATH = path35.join(os27.homedir(), ".adhdev", "version-history.json");
|
|
41106
41677
|
var MAX_ENTRIES_PER_PROVIDER = 20;
|
|
41107
41678
|
var VersionArchive = class {
|
|
41108
41679
|
history = {};
|
|
@@ -41111,8 +41682,8 @@ var VersionArchive = class {
|
|
|
41111
41682
|
}
|
|
41112
41683
|
load() {
|
|
41113
41684
|
try {
|
|
41114
|
-
if (
|
|
41115
|
-
this.history = JSON.parse(
|
|
41685
|
+
if (fs23.existsSync(ARCHIVE_PATH)) {
|
|
41686
|
+
this.history = JSON.parse(fs23.readFileSync(ARCHIVE_PATH, "utf-8"));
|
|
41116
41687
|
}
|
|
41117
41688
|
} catch {
|
|
41118
41689
|
this.history = {};
|
|
@@ -41149,8 +41720,8 @@ var VersionArchive = class {
|
|
|
41149
41720
|
}
|
|
41150
41721
|
save() {
|
|
41151
41722
|
try {
|
|
41152
|
-
|
|
41153
|
-
|
|
41723
|
+
fs23.mkdirSync(path35.dirname(ARCHIVE_PATH), { recursive: true });
|
|
41724
|
+
fs23.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
|
|
41154
41725
|
} catch {
|
|
41155
41726
|
}
|
|
41156
41727
|
}
|
|
@@ -41173,10 +41744,10 @@ function findBinary2(name) {
|
|
|
41173
41744
|
for (const p of paths) {
|
|
41174
41745
|
if (!p) continue;
|
|
41175
41746
|
for (const ext of exes) {
|
|
41176
|
-
const fullPath =
|
|
41747
|
+
const fullPath = path35.join(p, name + ext);
|
|
41177
41748
|
try {
|
|
41178
|
-
if (
|
|
41179
|
-
const stat2 =
|
|
41749
|
+
if (fs23.existsSync(fullPath)) {
|
|
41750
|
+
const stat2 = fs23.statSync(fullPath);
|
|
41180
41751
|
if (stat2.isFile() && (isWin || stat2.mode & 73)) {
|
|
41181
41752
|
return fullPath;
|
|
41182
41753
|
}
|
|
@@ -41221,19 +41792,19 @@ async function getVersion(binary, versionCommand) {
|
|
|
41221
41792
|
function checkPathExists2(paths) {
|
|
41222
41793
|
for (const p of paths) {
|
|
41223
41794
|
if (p.includes("*")) {
|
|
41224
|
-
const home =
|
|
41225
|
-
const resolved = p.replace(/\*/g, home.split(
|
|
41226
|
-
if (
|
|
41795
|
+
const home = os27.homedir();
|
|
41796
|
+
const resolved = p.replace(/\*/g, home.split(path35.sep).pop() || "");
|
|
41797
|
+
if (fs23.existsSync(resolved)) return resolved;
|
|
41227
41798
|
} else {
|
|
41228
|
-
if (
|
|
41799
|
+
if (fs23.existsSync(p)) return p;
|
|
41229
41800
|
}
|
|
41230
41801
|
}
|
|
41231
41802
|
return null;
|
|
41232
41803
|
}
|
|
41233
41804
|
async function getMacAppVersion(appPath) {
|
|
41234
41805
|
if (platform8() !== "darwin" || !appPath.endsWith(".app")) return null;
|
|
41235
|
-
const plistPath =
|
|
41236
|
-
if (!
|
|
41806
|
+
const plistPath = path35.join(appPath, "Contents", "Info.plist");
|
|
41807
|
+
if (!fs23.existsSync(plistPath)) return null;
|
|
41237
41808
|
const raw = await runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
|
|
41238
41809
|
return raw || null;
|
|
41239
41810
|
}
|
|
@@ -41258,8 +41829,8 @@ async function detectAllVersions(loader, archive) {
|
|
|
41258
41829
|
const cliBin = provider.cli ? findBinary2(provider.cli) : null;
|
|
41259
41830
|
let resolvedBin = cliBin;
|
|
41260
41831
|
if (!resolvedBin && appPath && currentOs === "darwin") {
|
|
41261
|
-
const bundled =
|
|
41262
|
-
if (provider.cli &&
|
|
41832
|
+
const bundled = path35.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
|
|
41833
|
+
if (provider.cli && fs23.existsSync(bundled)) resolvedBin = bundled;
|
|
41263
41834
|
}
|
|
41264
41835
|
info.installed = !!(appPath || resolvedBin);
|
|
41265
41836
|
info.path = appPath || null;
|
|
@@ -41298,8 +41869,8 @@ async function detectAllVersions(loader, archive) {
|
|
|
41298
41869
|
|
|
41299
41870
|
// src/daemon/dev-server.ts
|
|
41300
41871
|
import * as http2 from "http";
|
|
41301
|
-
import * as
|
|
41302
|
-
import * as
|
|
41872
|
+
import * as fs27 from "fs";
|
|
41873
|
+
import * as path39 from "path";
|
|
41303
41874
|
init_config();
|
|
41304
41875
|
|
|
41305
41876
|
// src/daemon/scaffold-template.ts
|
|
@@ -41650,8 +42221,8 @@ init_logger();
|
|
|
41650
42221
|
|
|
41651
42222
|
// src/daemon/dev-cdp-handlers.ts
|
|
41652
42223
|
init_logger();
|
|
41653
|
-
import * as
|
|
41654
|
-
import * as
|
|
42224
|
+
import * as fs24 from "fs";
|
|
42225
|
+
import * as path36 from "path";
|
|
41655
42226
|
async function handleCdpEvaluate(ctx, req, res) {
|
|
41656
42227
|
const body = await ctx.readBody(req);
|
|
41657
42228
|
const { expression, timeout, ideType } = body;
|
|
@@ -41829,18 +42400,18 @@ async function handleScriptHints(ctx, type, _req, res) {
|
|
|
41829
42400
|
return;
|
|
41830
42401
|
}
|
|
41831
42402
|
let scriptsPath = "";
|
|
41832
|
-
const directScripts =
|
|
41833
|
-
if (
|
|
42403
|
+
const directScripts = path36.join(dir, "scripts.js");
|
|
42404
|
+
if (fs24.existsSync(directScripts)) {
|
|
41834
42405
|
scriptsPath = directScripts;
|
|
41835
42406
|
} else {
|
|
41836
|
-
const scriptsDir =
|
|
41837
|
-
if (
|
|
41838
|
-
const versions =
|
|
41839
|
-
return
|
|
42407
|
+
const scriptsDir = path36.join(dir, "scripts");
|
|
42408
|
+
if (fs24.existsSync(scriptsDir)) {
|
|
42409
|
+
const versions = fs24.readdirSync(scriptsDir).filter((d) => {
|
|
42410
|
+
return fs24.statSync(path36.join(scriptsDir, d)).isDirectory();
|
|
41840
42411
|
}).sort().reverse();
|
|
41841
42412
|
for (const ver of versions) {
|
|
41842
|
-
const p =
|
|
41843
|
-
if (
|
|
42413
|
+
const p = path36.join(scriptsDir, ver, "scripts.js");
|
|
42414
|
+
if (fs24.existsSync(p)) {
|
|
41844
42415
|
scriptsPath = p;
|
|
41845
42416
|
break;
|
|
41846
42417
|
}
|
|
@@ -41852,7 +42423,7 @@ async function handleScriptHints(ctx, type, _req, res) {
|
|
|
41852
42423
|
return;
|
|
41853
42424
|
}
|
|
41854
42425
|
try {
|
|
41855
|
-
const source =
|
|
42426
|
+
const source = fs24.readFileSync(scriptsPath, "utf-8");
|
|
41856
42427
|
const hints = {};
|
|
41857
42428
|
const funcRegex = /module\.exports\.(\w+)\s*=\s*function\s+\w+\s*\(params\)/g;
|
|
41858
42429
|
let match;
|
|
@@ -42667,8 +43238,8 @@ async function handleDomContext(ctx, type, req, res) {
|
|
|
42667
43238
|
}
|
|
42668
43239
|
|
|
42669
43240
|
// src/daemon/dev-cli-debug.ts
|
|
42670
|
-
import * as
|
|
42671
|
-
import * as
|
|
43241
|
+
import * as fs25 from "fs";
|
|
43242
|
+
import * as path37 from "path";
|
|
42672
43243
|
function slugifyFixtureName(value) {
|
|
42673
43244
|
const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
42674
43245
|
return normalized || `fixture-${Date.now()}`;
|
|
@@ -42678,15 +43249,15 @@ function getCliFixtureDir(ctx, type) {
|
|
|
42678
43249
|
if (!providerDir) {
|
|
42679
43250
|
throw new Error(`Provider directory not found for '${type}'`);
|
|
42680
43251
|
}
|
|
42681
|
-
return
|
|
43252
|
+
return path37.join(providerDir, "fixtures");
|
|
42682
43253
|
}
|
|
42683
43254
|
function readCliFixture(ctx, type, name) {
|
|
42684
43255
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
42685
|
-
const filePath =
|
|
42686
|
-
if (!
|
|
43256
|
+
const filePath = path37.join(fixtureDir, `${name}.json`);
|
|
43257
|
+
if (!fs25.existsSync(filePath)) {
|
|
42687
43258
|
throw new Error(`Fixture not found: ${filePath}`);
|
|
42688
43259
|
}
|
|
42689
|
-
return JSON.parse(
|
|
43260
|
+
return JSON.parse(fs25.readFileSync(filePath, "utf-8"));
|
|
42690
43261
|
}
|
|
42691
43262
|
function getExerciseTranscriptText(result) {
|
|
42692
43263
|
const parts = [];
|
|
@@ -43431,7 +44002,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
43431
44002
|
return;
|
|
43432
44003
|
}
|
|
43433
44004
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
43434
|
-
|
|
44005
|
+
fs25.mkdirSync(fixtureDir, { recursive: true });
|
|
43435
44006
|
const name = slugifyFixtureName(String(body?.name || `${type}-${Date.now()}`));
|
|
43436
44007
|
const result = await runCliExerciseInternal(ctx, { ...request, type });
|
|
43437
44008
|
const fixture = {
|
|
@@ -43458,8 +44029,8 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
43458
44029
|
},
|
|
43459
44030
|
notes: typeof body?.notes === "string" ? body.notes : void 0
|
|
43460
44031
|
};
|
|
43461
|
-
const filePath =
|
|
43462
|
-
|
|
44032
|
+
const filePath = path37.join(fixtureDir, `${name}.json`);
|
|
44033
|
+
fs25.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
|
|
43463
44034
|
ctx.json(res, 200, {
|
|
43464
44035
|
saved: true,
|
|
43465
44036
|
name,
|
|
@@ -43477,14 +44048,14 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
43477
44048
|
async function handleCliFixtureList(ctx, type, _req, res) {
|
|
43478
44049
|
try {
|
|
43479
44050
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
43480
|
-
if (!
|
|
44051
|
+
if (!fs25.existsSync(fixtureDir)) {
|
|
43481
44052
|
ctx.json(res, 200, { fixtures: [], count: 0 });
|
|
43482
44053
|
return;
|
|
43483
44054
|
}
|
|
43484
|
-
const fixtures =
|
|
43485
|
-
const fullPath =
|
|
44055
|
+
const fixtures = fs25.readdirSync(fixtureDir).filter((file) => file.endsWith(".json")).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file) => {
|
|
44056
|
+
const fullPath = path37.join(fixtureDir, file);
|
|
43486
44057
|
try {
|
|
43487
|
-
const raw = JSON.parse(
|
|
44058
|
+
const raw = JSON.parse(fs25.readFileSync(fullPath, "utf-8"));
|
|
43488
44059
|
return {
|
|
43489
44060
|
name: raw.name || file.replace(/\.json$/i, ""),
|
|
43490
44061
|
path: fullPath,
|
|
@@ -43617,9 +44188,9 @@ async function handleCliRaw(ctx, req, res) {
|
|
|
43617
44188
|
}
|
|
43618
44189
|
|
|
43619
44190
|
// src/daemon/dev-auto-implement.ts
|
|
43620
|
-
import * as
|
|
43621
|
-
import * as
|
|
43622
|
-
import * as
|
|
44191
|
+
import * as fs26 from "fs";
|
|
44192
|
+
import * as path38 from "path";
|
|
44193
|
+
import * as os28 from "os";
|
|
43623
44194
|
function getAutoImplPid(ctx) {
|
|
43624
44195
|
const pid = ctx.autoImplProcess?.pid;
|
|
43625
44196
|
return typeof pid === "number" && pid > 0 ? pid : null;
|
|
@@ -43665,38 +44236,38 @@ function resolveAutoImplReference(ctx, category, requestedReference, targetType)
|
|
|
43665
44236
|
return fallback?.type || null;
|
|
43666
44237
|
}
|
|
43667
44238
|
function getLatestScriptVersionDir(scriptsDir) {
|
|
43668
|
-
if (!
|
|
43669
|
-
const versions =
|
|
44239
|
+
if (!fs26.existsSync(scriptsDir)) return null;
|
|
44240
|
+
const versions = fs26.readdirSync(scriptsDir).filter((d) => {
|
|
43670
44241
|
try {
|
|
43671
|
-
return
|
|
44242
|
+
return fs26.statSync(path38.join(scriptsDir, d)).isDirectory();
|
|
43672
44243
|
} catch {
|
|
43673
44244
|
return false;
|
|
43674
44245
|
}
|
|
43675
44246
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
43676
44247
|
if (versions.length === 0) return null;
|
|
43677
|
-
return
|
|
44248
|
+
return path38.join(scriptsDir, versions[0]);
|
|
43678
44249
|
}
|
|
43679
44250
|
function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
43680
|
-
const canonicalUserDir =
|
|
43681
|
-
const desiredDir = requestedDir ?
|
|
43682
|
-
const upstreamRoot =
|
|
43683
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
44251
|
+
const canonicalUserDir = path38.resolve(ctx.providerLoader.getUserProviderDir(category, type));
|
|
44252
|
+
const desiredDir = requestedDir ? path38.resolve(requestedDir) : canonicalUserDir;
|
|
44253
|
+
const upstreamRoot = path38.resolve(ctx.providerLoader.getUpstreamDir());
|
|
44254
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path38.sep}`)) {
|
|
43684
44255
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
43685
44256
|
}
|
|
43686
|
-
if (
|
|
44257
|
+
if (path38.basename(desiredDir) !== type) {
|
|
43687
44258
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
43688
44259
|
}
|
|
43689
44260
|
const sourceDir = ctx.findProviderDir(type);
|
|
43690
44261
|
if (!sourceDir) {
|
|
43691
44262
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
43692
44263
|
}
|
|
43693
|
-
if (!
|
|
43694
|
-
|
|
43695
|
-
|
|
44264
|
+
if (!fs26.existsSync(desiredDir)) {
|
|
44265
|
+
fs26.mkdirSync(path38.dirname(desiredDir), { recursive: true });
|
|
44266
|
+
fs26.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
43696
44267
|
ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
43697
44268
|
}
|
|
43698
|
-
const providerJson =
|
|
43699
|
-
if (!
|
|
44269
|
+
const providerJson = path38.join(desiredDir, "provider.json");
|
|
44270
|
+
if (!fs26.existsSync(providerJson)) {
|
|
43700
44271
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
43701
44272
|
}
|
|
43702
44273
|
return { dir: desiredDir };
|
|
@@ -43704,15 +44275,15 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
|
43704
44275
|
function loadAutoImplReferenceScripts(ctx, referenceType) {
|
|
43705
44276
|
if (!referenceType) return {};
|
|
43706
44277
|
const refDir = ctx.findProviderDir(referenceType);
|
|
43707
|
-
if (!refDir || !
|
|
44278
|
+
if (!refDir || !fs26.existsSync(refDir)) return {};
|
|
43708
44279
|
const referenceScripts = {};
|
|
43709
|
-
const scriptsDir =
|
|
44280
|
+
const scriptsDir = path38.join(refDir, "scripts");
|
|
43710
44281
|
const latestDir = getLatestScriptVersionDir(scriptsDir);
|
|
43711
44282
|
if (!latestDir) return referenceScripts;
|
|
43712
|
-
for (const file of
|
|
44283
|
+
for (const file of fs26.readdirSync(latestDir)) {
|
|
43713
44284
|
if (!file.endsWith(".js")) continue;
|
|
43714
44285
|
try {
|
|
43715
|
-
referenceScripts[file] =
|
|
44286
|
+
referenceScripts[file] = fs26.readFileSync(path38.join(latestDir, file), "utf-8");
|
|
43716
44287
|
} catch {
|
|
43717
44288
|
}
|
|
43718
44289
|
}
|
|
@@ -43820,16 +44391,16 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
43820
44391
|
});
|
|
43821
44392
|
const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
|
|
43822
44393
|
const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
|
|
43823
|
-
const tmpDir =
|
|
43824
|
-
if (!
|
|
43825
|
-
const promptFile =
|
|
43826
|
-
|
|
44394
|
+
const tmpDir = path38.join(os28.tmpdir(), "adhdev-autoimpl");
|
|
44395
|
+
if (!fs26.existsSync(tmpDir)) fs26.mkdirSync(tmpDir, { recursive: true });
|
|
44396
|
+
const promptFile = path38.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
|
|
44397
|
+
fs26.writeFileSync(promptFile, prompt, "utf-8");
|
|
43827
44398
|
ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
|
|
43828
44399
|
const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
|
|
43829
44400
|
const spawn4 = agentProvider?.spawn;
|
|
43830
44401
|
if (!spawn4?.command) {
|
|
43831
44402
|
try {
|
|
43832
|
-
|
|
44403
|
+
fs26.unlinkSync(promptFile);
|
|
43833
44404
|
} catch {
|
|
43834
44405
|
}
|
|
43835
44406
|
ctx.json(res, 400, { error: `Agent '${agent}' has no spawn config. Select a CLI provider with a spawn configuration.` });
|
|
@@ -43931,7 +44502,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
43931
44502
|
} catch {
|
|
43932
44503
|
}
|
|
43933
44504
|
try {
|
|
43934
|
-
|
|
44505
|
+
fs26.unlinkSync(promptFile);
|
|
43935
44506
|
} catch {
|
|
43936
44507
|
}
|
|
43937
44508
|
ctx.log(`Auto-implement (ACP) ${success ? "completed" : "failed"}: ${type} (exit: ${code})`);
|
|
@@ -43975,7 +44546,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
43975
44546
|
const interactiveFlags = ["--yolo", "--interactive", "-i"];
|
|
43976
44547
|
const baseArgs = [...spawn4.args || []].filter((a) => !interactiveFlags.includes(a));
|
|
43977
44548
|
let shellCmd;
|
|
43978
|
-
const isWin =
|
|
44549
|
+
const isWin = os28.platform() === "win32";
|
|
43979
44550
|
const escapeArg = (a) => isWin ? `"${a.replace(/"/g, '""')}"` : `'${a.replace(/'/g, "'\\''")}'`;
|
|
43980
44551
|
const promptMode = autoImpl?.promptMode ?? "stdin";
|
|
43981
44552
|
const extraArgs = autoImpl?.extraArgs ?? [];
|
|
@@ -44014,7 +44585,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
44014
44585
|
try {
|
|
44015
44586
|
const pty = __require("node-pty");
|
|
44016
44587
|
ctx.log(`Auto-implement spawn (PTY): ${shellCmd}`);
|
|
44017
|
-
const isWin2 =
|
|
44588
|
+
const isWin2 = os28.platform() === "win32";
|
|
44018
44589
|
child = pty.spawn(isWin2 ? "cmd.exe" : process.env.SHELL || "/bin/zsh", [isWin2 ? "/c" : "-c", shellCmd], {
|
|
44019
44590
|
name: "xterm-256color",
|
|
44020
44591
|
cols: 120,
|
|
@@ -44157,7 +44728,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
44157
44728
|
}
|
|
44158
44729
|
});
|
|
44159
44730
|
try {
|
|
44160
|
-
|
|
44731
|
+
fs26.unlinkSync(promptFile);
|
|
44161
44732
|
} catch {
|
|
44162
44733
|
}
|
|
44163
44734
|
ctx.log(`Auto-implement ${success ? "completed" : "failed"}: ${type} (exit: ${code})${verificationSummary ? ` verify=${verificationSummary.pass ? "pass" : "fail"}` : ""}`);
|
|
@@ -44254,7 +44825,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
44254
44825
|
setMode: "set_mode.js"
|
|
44255
44826
|
};
|
|
44256
44827
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
44257
|
-
const scriptsDir =
|
|
44828
|
+
const scriptsDir = path38.join(providerDir, "scripts");
|
|
44258
44829
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
44259
44830
|
if (latestScriptsDir) {
|
|
44260
44831
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -44262,10 +44833,10 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
44262
44833
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
44263
44834
|
lines.push("These are the ONLY files you are allowed to modify. Replace the TODO stubs with working implementations.");
|
|
44264
44835
|
lines.push("");
|
|
44265
|
-
for (const file of
|
|
44836
|
+
for (const file of fs26.readdirSync(latestScriptsDir)) {
|
|
44266
44837
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
44267
44838
|
try {
|
|
44268
|
-
const content =
|
|
44839
|
+
const content = fs26.readFileSync(path38.join(latestScriptsDir, file), "utf-8");
|
|
44269
44840
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
44270
44841
|
lines.push("```javascript");
|
|
44271
44842
|
lines.push(content);
|
|
@@ -44275,14 +44846,14 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
44275
44846
|
}
|
|
44276
44847
|
}
|
|
44277
44848
|
}
|
|
44278
|
-
const refFiles =
|
|
44849
|
+
const refFiles = fs26.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
44279
44850
|
if (refFiles.length > 0) {
|
|
44280
44851
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
44281
44852
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
44282
44853
|
lines.push("");
|
|
44283
44854
|
for (const file of refFiles) {
|
|
44284
44855
|
try {
|
|
44285
|
-
const content =
|
|
44856
|
+
const content = fs26.readFileSync(path38.join(latestScriptsDir, file), "utf-8");
|
|
44286
44857
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
44287
44858
|
lines.push("```javascript");
|
|
44288
44859
|
lines.push(content);
|
|
@@ -44323,11 +44894,11 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
44323
44894
|
lines.push("");
|
|
44324
44895
|
}
|
|
44325
44896
|
}
|
|
44326
|
-
const docsDir =
|
|
44897
|
+
const docsDir = path38.join(providerDir, "../../docs");
|
|
44327
44898
|
const loadGuide = (name) => {
|
|
44328
44899
|
try {
|
|
44329
|
-
const p =
|
|
44330
|
-
if (
|
|
44900
|
+
const p = path38.join(docsDir, name);
|
|
44901
|
+
if (fs26.existsSync(p)) return fs26.readFileSync(p, "utf-8");
|
|
44331
44902
|
} catch {
|
|
44332
44903
|
}
|
|
44333
44904
|
return null;
|
|
@@ -44563,7 +45134,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
44563
45134
|
parseApproval: "parse_approval.js"
|
|
44564
45135
|
};
|
|
44565
45136
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
44566
|
-
const scriptsDir =
|
|
45137
|
+
const scriptsDir = path38.join(providerDir, "scripts");
|
|
44567
45138
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
44568
45139
|
if (latestScriptsDir) {
|
|
44569
45140
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -44571,11 +45142,11 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
44571
45142
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
44572
45143
|
lines.push("These are the ONLY files you are allowed to modify. Replace TODO or heuristic-only logic with working PTY-aware implementations.");
|
|
44573
45144
|
lines.push("");
|
|
44574
|
-
for (const file of
|
|
45145
|
+
for (const file of fs26.readdirSync(latestScriptsDir)) {
|
|
44575
45146
|
if (!file.endsWith(".js")) continue;
|
|
44576
45147
|
if (!targetFileNames.has(file)) continue;
|
|
44577
45148
|
try {
|
|
44578
|
-
const content =
|
|
45149
|
+
const content = fs26.readFileSync(path38.join(latestScriptsDir, file), "utf-8");
|
|
44579
45150
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
44580
45151
|
lines.push("```javascript");
|
|
44581
45152
|
lines.push(content);
|
|
@@ -44584,14 +45155,14 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
44584
45155
|
} catch {
|
|
44585
45156
|
}
|
|
44586
45157
|
}
|
|
44587
|
-
const refFiles =
|
|
45158
|
+
const refFiles = fs26.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
44588
45159
|
if (refFiles.length > 0) {
|
|
44589
45160
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
44590
45161
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
44591
45162
|
lines.push("");
|
|
44592
45163
|
for (const file of refFiles) {
|
|
44593
45164
|
try {
|
|
44594
|
-
const content =
|
|
45165
|
+
const content = fs26.readFileSync(path38.join(latestScriptsDir, file), "utf-8");
|
|
44595
45166
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
44596
45167
|
lines.push("```javascript");
|
|
44597
45168
|
lines.push(content);
|
|
@@ -44624,11 +45195,11 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
44624
45195
|
lines.push("");
|
|
44625
45196
|
}
|
|
44626
45197
|
}
|
|
44627
|
-
const docsDir =
|
|
45198
|
+
const docsDir = path38.join(providerDir, "../../docs");
|
|
44628
45199
|
const loadGuide = (name) => {
|
|
44629
45200
|
try {
|
|
44630
|
-
const p =
|
|
44631
|
-
if (
|
|
45201
|
+
const p = path38.join(docsDir, name);
|
|
45202
|
+
if (fs26.existsSync(p)) return fs26.readFileSync(p, "utf-8");
|
|
44632
45203
|
} catch {
|
|
44633
45204
|
}
|
|
44634
45205
|
return null;
|
|
@@ -45074,8 +45645,8 @@ var DevServer = class _DevServer {
|
|
|
45074
45645
|
}
|
|
45075
45646
|
getEndpointList() {
|
|
45076
45647
|
return this.routes.map((r) => {
|
|
45077
|
-
const
|
|
45078
|
-
return `${r.method.padEnd(5)} ${
|
|
45648
|
+
const path40 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
|
|
45649
|
+
return `${r.method.padEnd(5)} ${path40}`;
|
|
45079
45650
|
});
|
|
45080
45651
|
}
|
|
45081
45652
|
async start(port = DEV_SERVER_PORT) {
|
|
@@ -45363,12 +45934,12 @@ var DevServer = class _DevServer {
|
|
|
45363
45934
|
// ─── DevConsole SPA ───
|
|
45364
45935
|
getConsoleDistDir() {
|
|
45365
45936
|
const candidates = [
|
|
45366
|
-
|
|
45367
|
-
|
|
45368
|
-
|
|
45937
|
+
path39.resolve(__dirname, "../../web-devconsole/dist"),
|
|
45938
|
+
path39.resolve(__dirname, "../../../web-devconsole/dist"),
|
|
45939
|
+
path39.join(process.cwd(), "packages/web-devconsole/dist")
|
|
45369
45940
|
];
|
|
45370
45941
|
for (const dir of candidates) {
|
|
45371
|
-
if (
|
|
45942
|
+
if (fs27.existsSync(path39.join(dir, "index.html"))) return dir;
|
|
45372
45943
|
}
|
|
45373
45944
|
return null;
|
|
45374
45945
|
}
|
|
@@ -45378,9 +45949,9 @@ var DevServer = class _DevServer {
|
|
|
45378
45949
|
this.json(res, 500, { error: "DevConsole not found. Run: npm run build -w packages/web-devconsole" });
|
|
45379
45950
|
return;
|
|
45380
45951
|
}
|
|
45381
|
-
const htmlPath =
|
|
45952
|
+
const htmlPath = path39.join(distDir, "index.html");
|
|
45382
45953
|
try {
|
|
45383
|
-
const html =
|
|
45954
|
+
const html = fs27.readFileSync(htmlPath, "utf-8");
|
|
45384
45955
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
45385
45956
|
res.end(html);
|
|
45386
45957
|
} catch (e) {
|
|
@@ -45403,15 +45974,15 @@ var DevServer = class _DevServer {
|
|
|
45403
45974
|
this.json(res, 404, { error: "Not found" });
|
|
45404
45975
|
return;
|
|
45405
45976
|
}
|
|
45406
|
-
const safePath =
|
|
45407
|
-
const filePath =
|
|
45977
|
+
const safePath = path39.normalize(pathname).replace(/^\.\.\//, "");
|
|
45978
|
+
const filePath = path39.join(distDir, safePath);
|
|
45408
45979
|
if (!filePath.startsWith(distDir)) {
|
|
45409
45980
|
this.json(res, 403, { error: "Forbidden" });
|
|
45410
45981
|
return;
|
|
45411
45982
|
}
|
|
45412
45983
|
try {
|
|
45413
|
-
const content =
|
|
45414
|
-
const ext =
|
|
45984
|
+
const content = fs27.readFileSync(filePath);
|
|
45985
|
+
const ext = path39.extname(filePath);
|
|
45415
45986
|
const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
|
|
45416
45987
|
res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
|
|
45417
45988
|
res.end(content);
|
|
@@ -45519,14 +46090,14 @@ var DevServer = class _DevServer {
|
|
|
45519
46090
|
const files = [];
|
|
45520
46091
|
const scan = (d, prefix) => {
|
|
45521
46092
|
try {
|
|
45522
|
-
for (const entry of
|
|
46093
|
+
for (const entry of fs27.readdirSync(d, { withFileTypes: true })) {
|
|
45523
46094
|
if (entry.name.startsWith(".") || entry.name.endsWith(".bak")) continue;
|
|
45524
46095
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
45525
46096
|
if (entry.isDirectory()) {
|
|
45526
46097
|
files.push({ path: rel, size: 0, type: "dir" });
|
|
45527
|
-
scan(
|
|
46098
|
+
scan(path39.join(d, entry.name), rel);
|
|
45528
46099
|
} else {
|
|
45529
|
-
const stat2 =
|
|
46100
|
+
const stat2 = fs27.statSync(path39.join(d, entry.name));
|
|
45530
46101
|
files.push({ path: rel, size: stat2.size, type: "file" });
|
|
45531
46102
|
}
|
|
45532
46103
|
}
|
|
@@ -45549,16 +46120,16 @@ var DevServer = class _DevServer {
|
|
|
45549
46120
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
45550
46121
|
return;
|
|
45551
46122
|
}
|
|
45552
|
-
const fullPath =
|
|
46123
|
+
const fullPath = path39.resolve(dir, path39.normalize(filePath));
|
|
45553
46124
|
if (!fullPath.startsWith(dir)) {
|
|
45554
46125
|
this.json(res, 403, { error: "Forbidden" });
|
|
45555
46126
|
return;
|
|
45556
46127
|
}
|
|
45557
|
-
if (!
|
|
46128
|
+
if (!fs27.existsSync(fullPath) || fs27.statSync(fullPath).isDirectory()) {
|
|
45558
46129
|
this.json(res, 404, { error: `File not found: ${filePath}` });
|
|
45559
46130
|
return;
|
|
45560
46131
|
}
|
|
45561
|
-
const content =
|
|
46132
|
+
const content = fs27.readFileSync(fullPath, "utf-8");
|
|
45562
46133
|
this.json(res, 200, { type, path: filePath, content, lines: content.split("\n").length });
|
|
45563
46134
|
}
|
|
45564
46135
|
/** POST /api/providers/:type/file — write a file { path, content } */
|
|
@@ -45574,15 +46145,15 @@ var DevServer = class _DevServer {
|
|
|
45574
46145
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
45575
46146
|
return;
|
|
45576
46147
|
}
|
|
45577
|
-
const fullPath =
|
|
46148
|
+
const fullPath = path39.resolve(dir, path39.normalize(filePath));
|
|
45578
46149
|
if (!fullPath.startsWith(dir)) {
|
|
45579
46150
|
this.json(res, 403, { error: "Forbidden" });
|
|
45580
46151
|
return;
|
|
45581
46152
|
}
|
|
45582
46153
|
try {
|
|
45583
|
-
if (
|
|
45584
|
-
|
|
45585
|
-
|
|
46154
|
+
if (fs27.existsSync(fullPath)) fs27.copyFileSync(fullPath, fullPath + ".bak");
|
|
46155
|
+
fs27.mkdirSync(path39.dirname(fullPath), { recursive: true });
|
|
46156
|
+
fs27.writeFileSync(fullPath, content, "utf-8");
|
|
45586
46157
|
this.log(`File saved: ${fullPath} (${content.length} chars)`);
|
|
45587
46158
|
this.providerLoader.reload();
|
|
45588
46159
|
this.json(res, 200, { saved: true, path: filePath, chars: content.length });
|
|
@@ -45598,9 +46169,9 @@ var DevServer = class _DevServer {
|
|
|
45598
46169
|
return;
|
|
45599
46170
|
}
|
|
45600
46171
|
for (const name of ["scripts.js", "provider.json"]) {
|
|
45601
|
-
const p =
|
|
45602
|
-
if (
|
|
45603
|
-
const source =
|
|
46172
|
+
const p = path39.join(dir, name);
|
|
46173
|
+
if (fs27.existsSync(p)) {
|
|
46174
|
+
const source = fs27.readFileSync(p, "utf-8");
|
|
45604
46175
|
this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
|
|
45605
46176
|
return;
|
|
45606
46177
|
}
|
|
@@ -45619,11 +46190,11 @@ var DevServer = class _DevServer {
|
|
|
45619
46190
|
this.json(res, 404, { error: `Provider not found: ${type}` });
|
|
45620
46191
|
return;
|
|
45621
46192
|
}
|
|
45622
|
-
const target =
|
|
45623
|
-
const targetPath =
|
|
46193
|
+
const target = fs27.existsSync(path39.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
|
|
46194
|
+
const targetPath = path39.join(dir, target);
|
|
45624
46195
|
try {
|
|
45625
|
-
if (
|
|
45626
|
-
|
|
46196
|
+
if (fs27.existsSync(targetPath)) fs27.copyFileSync(targetPath, targetPath + ".bak");
|
|
46197
|
+
fs27.writeFileSync(targetPath, source, "utf-8");
|
|
45627
46198
|
this.log(`Saved provider: ${targetPath} (${source.length} chars)`);
|
|
45628
46199
|
this.providerLoader.reload();
|
|
45629
46200
|
this.json(res, 200, { saved: true, path: targetPath, chars: source.length });
|
|
@@ -45767,21 +46338,21 @@ var DevServer = class _DevServer {
|
|
|
45767
46338
|
}
|
|
45768
46339
|
let targetDir;
|
|
45769
46340
|
targetDir = this.providerLoader.getUserProviderDir(category, type);
|
|
45770
|
-
const jsonPath =
|
|
45771
|
-
if (
|
|
46341
|
+
const jsonPath = path39.join(targetDir, "provider.json");
|
|
46342
|
+
if (fs27.existsSync(jsonPath)) {
|
|
45772
46343
|
this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
|
|
45773
46344
|
return;
|
|
45774
46345
|
}
|
|
45775
46346
|
try {
|
|
45776
46347
|
const result = generateFiles(type, name, category, { cdpPorts, cli, processName, installPath, binary, extensionId, version, osPaths, processNames });
|
|
45777
|
-
|
|
45778
|
-
|
|
46348
|
+
fs27.mkdirSync(targetDir, { recursive: true });
|
|
46349
|
+
fs27.writeFileSync(jsonPath, result["provider.json"], "utf-8");
|
|
45779
46350
|
const createdFiles = ["provider.json"];
|
|
45780
46351
|
if (result.files) {
|
|
45781
46352
|
for (const [relPath, content] of Object.entries(result.files)) {
|
|
45782
|
-
const fullPath =
|
|
45783
|
-
|
|
45784
|
-
|
|
46353
|
+
const fullPath = path39.join(targetDir, relPath);
|
|
46354
|
+
fs27.mkdirSync(path39.dirname(fullPath), { recursive: true });
|
|
46355
|
+
fs27.writeFileSync(fullPath, content, "utf-8");
|
|
45785
46356
|
createdFiles.push(relPath);
|
|
45786
46357
|
}
|
|
45787
46358
|
}
|
|
@@ -45830,38 +46401,38 @@ var DevServer = class _DevServer {
|
|
|
45830
46401
|
}
|
|
45831
46402
|
// ─── Phase 2: Auto-Implement Backend ───
|
|
45832
46403
|
getLatestScriptVersionDir(scriptsDir) {
|
|
45833
|
-
if (!
|
|
45834
|
-
const versions =
|
|
46404
|
+
if (!fs27.existsSync(scriptsDir)) return null;
|
|
46405
|
+
const versions = fs27.readdirSync(scriptsDir).filter((d) => {
|
|
45835
46406
|
try {
|
|
45836
|
-
return
|
|
46407
|
+
return fs27.statSync(path39.join(scriptsDir, d)).isDirectory();
|
|
45837
46408
|
} catch {
|
|
45838
46409
|
return false;
|
|
45839
46410
|
}
|
|
45840
46411
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
45841
46412
|
if (versions.length === 0) return null;
|
|
45842
|
-
return
|
|
46413
|
+
return path39.join(scriptsDir, versions[0]);
|
|
45843
46414
|
}
|
|
45844
46415
|
resolveAutoImplWritableProviderDir(category, type, requestedDir) {
|
|
45845
|
-
const canonicalUserDir =
|
|
45846
|
-
const desiredDir = requestedDir ?
|
|
45847
|
-
const upstreamRoot =
|
|
45848
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
46416
|
+
const canonicalUserDir = path39.resolve(this.providerLoader.getUserProviderDir(category, type));
|
|
46417
|
+
const desiredDir = requestedDir ? path39.resolve(requestedDir) : canonicalUserDir;
|
|
46418
|
+
const upstreamRoot = path39.resolve(this.providerLoader.getUpstreamDir());
|
|
46419
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path39.sep}`)) {
|
|
45849
46420
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
45850
46421
|
}
|
|
45851
|
-
if (
|
|
46422
|
+
if (path39.basename(desiredDir) !== type) {
|
|
45852
46423
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
45853
46424
|
}
|
|
45854
46425
|
const sourceDir = this.findProviderDir(type);
|
|
45855
46426
|
if (!sourceDir) {
|
|
45856
46427
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
45857
46428
|
}
|
|
45858
|
-
if (!
|
|
45859
|
-
|
|
45860
|
-
|
|
46429
|
+
if (!fs27.existsSync(desiredDir)) {
|
|
46430
|
+
fs27.mkdirSync(path39.dirname(desiredDir), { recursive: true });
|
|
46431
|
+
fs27.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
45861
46432
|
this.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
45862
46433
|
}
|
|
45863
|
-
const providerJson =
|
|
45864
|
-
if (!
|
|
46434
|
+
const providerJson = path39.join(desiredDir, "provider.json");
|
|
46435
|
+
if (!fs27.existsSync(providerJson)) {
|
|
45865
46436
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
45866
46437
|
}
|
|
45867
46438
|
return { dir: desiredDir };
|
|
@@ -45896,7 +46467,7 @@ var DevServer = class _DevServer {
|
|
|
45896
46467
|
setMode: "set_mode.js"
|
|
45897
46468
|
};
|
|
45898
46469
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
45899
|
-
const scriptsDir =
|
|
46470
|
+
const scriptsDir = path39.join(providerDir, "scripts");
|
|
45900
46471
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
45901
46472
|
if (latestScriptsDir) {
|
|
45902
46473
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -45904,10 +46475,10 @@ var DevServer = class _DevServer {
|
|
|
45904
46475
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
45905
46476
|
lines.push("These are the ONLY files you are allowed to modify. Replace the TODO stubs with working implementations.");
|
|
45906
46477
|
lines.push("");
|
|
45907
|
-
for (const file of
|
|
46478
|
+
for (const file of fs27.readdirSync(latestScriptsDir)) {
|
|
45908
46479
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
45909
46480
|
try {
|
|
45910
|
-
const content =
|
|
46481
|
+
const content = fs27.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
|
|
45911
46482
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
45912
46483
|
lines.push("```javascript");
|
|
45913
46484
|
lines.push(content);
|
|
@@ -45917,14 +46488,14 @@ var DevServer = class _DevServer {
|
|
|
45917
46488
|
}
|
|
45918
46489
|
}
|
|
45919
46490
|
}
|
|
45920
|
-
const refFiles =
|
|
46491
|
+
const refFiles = fs27.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
45921
46492
|
if (refFiles.length > 0) {
|
|
45922
46493
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
45923
46494
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
45924
46495
|
lines.push("");
|
|
45925
46496
|
for (const file of refFiles) {
|
|
45926
46497
|
try {
|
|
45927
|
-
const content =
|
|
46498
|
+
const content = fs27.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
|
|
45928
46499
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
45929
46500
|
lines.push("```javascript");
|
|
45930
46501
|
lines.push(content);
|
|
@@ -45965,11 +46536,11 @@ var DevServer = class _DevServer {
|
|
|
45965
46536
|
lines.push("");
|
|
45966
46537
|
}
|
|
45967
46538
|
}
|
|
45968
|
-
const docsDir =
|
|
46539
|
+
const docsDir = path39.join(providerDir, "../../docs");
|
|
45969
46540
|
const loadGuide = (name) => {
|
|
45970
46541
|
try {
|
|
45971
|
-
const p =
|
|
45972
|
-
if (
|
|
46542
|
+
const p = path39.join(docsDir, name);
|
|
46543
|
+
if (fs27.existsSync(p)) return fs27.readFileSync(p, "utf-8");
|
|
45973
46544
|
} catch {
|
|
45974
46545
|
}
|
|
45975
46546
|
return null;
|
|
@@ -46142,7 +46713,7 @@ var DevServer = class _DevServer {
|
|
|
46142
46713
|
parseApproval: "parse_approval.js"
|
|
46143
46714
|
};
|
|
46144
46715
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
46145
|
-
const scriptsDir =
|
|
46716
|
+
const scriptsDir = path39.join(providerDir, "scripts");
|
|
46146
46717
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
46147
46718
|
if (latestScriptsDir) {
|
|
46148
46719
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -46150,11 +46721,11 @@ var DevServer = class _DevServer {
|
|
|
46150
46721
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
46151
46722
|
lines.push("These are the ONLY files you are allowed to modify. Replace TODO or heuristic-only logic with working PTY-aware implementations.");
|
|
46152
46723
|
lines.push("");
|
|
46153
|
-
for (const file of
|
|
46724
|
+
for (const file of fs27.readdirSync(latestScriptsDir)) {
|
|
46154
46725
|
if (!file.endsWith(".js")) continue;
|
|
46155
46726
|
if (!targetFileNames.has(file)) continue;
|
|
46156
46727
|
try {
|
|
46157
|
-
const content =
|
|
46728
|
+
const content = fs27.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
|
|
46158
46729
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
46159
46730
|
lines.push("```javascript");
|
|
46160
46731
|
lines.push(content);
|
|
@@ -46163,14 +46734,14 @@ var DevServer = class _DevServer {
|
|
|
46163
46734
|
} catch {
|
|
46164
46735
|
}
|
|
46165
46736
|
}
|
|
46166
|
-
const refFiles =
|
|
46737
|
+
const refFiles = fs27.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
46167
46738
|
if (refFiles.length > 0) {
|
|
46168
46739
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
46169
46740
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
46170
46741
|
lines.push("");
|
|
46171
46742
|
for (const file of refFiles) {
|
|
46172
46743
|
try {
|
|
46173
|
-
const content =
|
|
46744
|
+
const content = fs27.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
|
|
46174
46745
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
46175
46746
|
lines.push("```javascript");
|
|
46176
46747
|
lines.push(content);
|
|
@@ -46203,11 +46774,11 @@ var DevServer = class _DevServer {
|
|
|
46203
46774
|
lines.push("");
|
|
46204
46775
|
}
|
|
46205
46776
|
}
|
|
46206
|
-
const docsDir =
|
|
46777
|
+
const docsDir = path39.join(providerDir, "../../docs");
|
|
46207
46778
|
const loadGuide = (name) => {
|
|
46208
46779
|
try {
|
|
46209
|
-
const p =
|
|
46210
|
-
if (
|
|
46780
|
+
const p = path39.join(docsDir, name);
|
|
46781
|
+
if (fs27.existsSync(p)) return fs27.readFileSync(p, "utf-8");
|
|
46211
46782
|
} catch {
|
|
46212
46783
|
}
|
|
46213
46784
|
return null;
|
|
@@ -47117,8 +47688,8 @@ async function installExtension(ide, extension) {
|
|
|
47117
47688
|
const res = await fetch(extension.vsixUrl);
|
|
47118
47689
|
if (res.ok) {
|
|
47119
47690
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
47120
|
-
const
|
|
47121
|
-
|
|
47691
|
+
const fs28 = await import("fs");
|
|
47692
|
+
fs28.writeFileSync(vsixPath, buffer);
|
|
47122
47693
|
return new Promise((resolve23) => {
|
|
47123
47694
|
const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
|
|
47124
47695
|
exec6(cmd, { timeout: 6e4 }, (error, _stdout, stderr) => {
|
|
@@ -47689,12 +48260,12 @@ init_parse_session();
|
|
|
47689
48260
|
|
|
47690
48261
|
// src/providers/sdk/v1/fixture-tooling/replay.ts
|
|
47691
48262
|
init_provider_cli_shared();
|
|
47692
|
-
import { readFileSync as
|
|
48263
|
+
import { readFileSync as readFileSync31 } from "fs";
|
|
47693
48264
|
import { dirname as dirname9, resolve as resolve21 } from "path";
|
|
47694
48265
|
|
|
47695
48266
|
// src/providers/sdk/v1/validators/taint.ts
|
|
47696
|
-
import { readFileSync as
|
|
47697
|
-
import { resolve as resolve22, dirname as dirname10, join as
|
|
48267
|
+
import { readFileSync as readFileSync32, existsSync as existsSync38 } from "fs";
|
|
48268
|
+
import { resolve as resolve22, dirname as dirname10, join as join43 } from "path";
|
|
47698
48269
|
|
|
47699
48270
|
// src/providers/sdk/v1/validators/index.ts
|
|
47700
48271
|
init_manifest();
|