@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.js
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")) {
|
|
@@ -770,10 +770,10 @@ function getMeshConfigPath() {
|
|
|
770
770
|
return (0, import_path2.join)(getConfigDir(), "meshes.json");
|
|
771
771
|
}
|
|
772
772
|
function loadMeshConfig() {
|
|
773
|
-
const
|
|
774
|
-
if (!(0, import_fs2.existsSync)(
|
|
773
|
+
const path40 = getMeshConfigPath();
|
|
774
|
+
if (!(0, import_fs2.existsSync)(path40)) return { meshes: [] };
|
|
775
775
|
try {
|
|
776
|
-
const raw = JSON.parse((0, import_fs2.readFileSync)(
|
|
776
|
+
const raw = JSON.parse((0, import_fs2.readFileSync)(path40, "utf-8"));
|
|
777
777
|
if (!raw || !Array.isArray(raw.meshes)) return { meshes: [] };
|
|
778
778
|
return raw;
|
|
779
779
|
} catch {
|
|
@@ -781,16 +781,16 @@ function loadMeshConfig() {
|
|
|
781
781
|
}
|
|
782
782
|
}
|
|
783
783
|
function saveMeshConfig(config) {
|
|
784
|
-
const
|
|
785
|
-
(0, import_fs2.writeFileSync)(
|
|
784
|
+
const path40 = getMeshConfigPath();
|
|
785
|
+
(0, import_fs2.writeFileSync)(path40, JSON.stringify(config, null, 2), { encoding: "utf-8", mode: 384 });
|
|
786
786
|
}
|
|
787
787
|
function normalizeRepoIdentity(remoteUrl) {
|
|
788
788
|
let identity = remoteUrl.trim();
|
|
789
789
|
if (identity.startsWith("http://") || identity.startsWith("https://")) {
|
|
790
790
|
try {
|
|
791
791
|
const url = new URL(identity);
|
|
792
|
-
const
|
|
793
|
-
return `${url.hostname}/${
|
|
792
|
+
const path40 = url.pathname.replace(/^\//, "").replace(/\.git$/, "");
|
|
793
|
+
return `${url.hostname}/${path40}`;
|
|
794
794
|
} catch {
|
|
795
795
|
}
|
|
796
796
|
}
|
|
@@ -1718,8 +1718,8 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
1718
1718
|
}
|
|
1719
1719
|
const serverName = mcpConfig.serverName?.trim() || DEFAULT_SERVER_NAME;
|
|
1720
1720
|
if (mcpConfig.mode === "auto_import") {
|
|
1721
|
-
const
|
|
1722
|
-
if (!
|
|
1721
|
+
const path40 = mcpConfig.path?.trim();
|
|
1722
|
+
if (!path40) {
|
|
1723
1723
|
return { kind: "unsupported", reason: "Provider auto-import MCP config is missing a config path" };
|
|
1724
1724
|
}
|
|
1725
1725
|
const mcpServer = resolveAdhdevMcpServerLaunch({
|
|
@@ -1737,7 +1737,7 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
1737
1737
|
return {
|
|
1738
1738
|
kind: "auto_import",
|
|
1739
1739
|
serverName,
|
|
1740
|
-
configPath: resolveMcpConfigPath(
|
|
1740
|
+
configPath: resolveMcpConfigPath(path40, workspace),
|
|
1741
1741
|
configFormat: mcpConfig.format,
|
|
1742
1742
|
mcpServer
|
|
1743
1743
|
};
|
|
@@ -1894,8 +1894,8 @@ function stripCoordinatorWrapperFile(filePath) {
|
|
|
1894
1894
|
const remaining = (existing.slice(0, openIdx) + existing.slice(closeIdx + CLOSE.length)).replace(/^\s*\n+/, "").replace(/\n+\s*$/, "");
|
|
1895
1895
|
if (!remaining.trim()) {
|
|
1896
1896
|
try {
|
|
1897
|
-
const
|
|
1898
|
-
|
|
1897
|
+
const fs28 = require("fs");
|
|
1898
|
+
fs28.unlinkSync(filePath);
|
|
1899
1899
|
} catch {
|
|
1900
1900
|
}
|
|
1901
1901
|
} else {
|
|
@@ -2033,10 +2033,10 @@ function rotateArchiveFile(meshId, archivePath) {
|
|
|
2033
2033
|
}
|
|
2034
2034
|
}
|
|
2035
2035
|
function readArchivedCounts(meshId) {
|
|
2036
|
-
const
|
|
2037
|
-
if (!(0, import_fs6.existsSync)(
|
|
2036
|
+
const path40 = getArchivedCountsPath(meshId);
|
|
2037
|
+
if (!(0, import_fs6.existsSync)(path40)) return { taskCompleted: 0, taskFailed: 0, taskStalled: 0, recoveryAttempted: 0, totalArchived: 0, lastArchivedAt: "" };
|
|
2038
2038
|
try {
|
|
2039
|
-
return JSON.parse((0, import_fs6.readFileSync)(
|
|
2039
|
+
return JSON.parse((0, import_fs6.readFileSync)(path40, "utf-8"));
|
|
2040
2040
|
} catch {
|
|
2041
2041
|
return { taskCompleted: 0, taskFailed: 0, taskStalled: 0, recoveryAttempted: 0, totalArchived: 0, lastArchivedAt: "" };
|
|
2042
2042
|
}
|
|
@@ -2691,10 +2691,10 @@ var init_beads_db = __esm({
|
|
|
2691
2691
|
this.migratedMeshIds.add(meshId);
|
|
2692
2692
|
const count = this.db.prepare("SELECT COUNT(*) AS count FROM mesh_queue WHERE mesh_id = ?").get(meshId);
|
|
2693
2693
|
if (count.count > 0) return;
|
|
2694
|
-
const
|
|
2695
|
-
if (!(0, import_fs7.existsSync)(
|
|
2694
|
+
const path40 = legacyQueuePath(meshId);
|
|
2695
|
+
if (!(0, import_fs7.existsSync)(path40)) return;
|
|
2696
2696
|
try {
|
|
2697
|
-
const entries = JSON.parse((0, import_fs7.readFileSync)(
|
|
2697
|
+
const entries = JSON.parse((0, import_fs7.readFileSync)(path40, "utf-8"));
|
|
2698
2698
|
if (!Array.isArray(entries)) return;
|
|
2699
2699
|
const insert = this.db.prepare(`
|
|
2700
2700
|
INSERT OR REPLACE INTO mesh_queue (
|
|
@@ -3404,10 +3404,10 @@ function readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId) {
|
|
|
3404
3404
|
if (!meshId) return [];
|
|
3405
3405
|
const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
|
|
3406
3406
|
const events = [];
|
|
3407
|
-
for (const
|
|
3408
|
-
if (!(0, import_fs9.existsSync)(
|
|
3407
|
+
for (const path40 of paths) {
|
|
3408
|
+
if (!(0, import_fs9.existsSync)(path40)) continue;
|
|
3409
3409
|
try {
|
|
3410
|
-
const raw = (0, import_fs9.readFileSync)(
|
|
3410
|
+
const raw = (0, import_fs9.readFileSync)(path40, "utf-8");
|
|
3411
3411
|
const parsed = raw.split("\n").filter(Boolean).flatMap((line) => {
|
|
3412
3412
|
try {
|
|
3413
3413
|
return [JSON.parse(line)];
|
|
@@ -3415,7 +3415,7 @@ function readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId) {
|
|
|
3415
3415
|
return [];
|
|
3416
3416
|
}
|
|
3417
3417
|
});
|
|
3418
|
-
const filtered = coordinatorDaemonId &&
|
|
3418
|
+
const filtered = coordinatorDaemonId && path40 === getPendingEventsPath(meshId) ? parsed.filter((e) => !e.targetCoordinatorDaemonId || e.targetCoordinatorDaemonId === coordinatorDaemonId) : parsed;
|
|
3419
3419
|
events.push(...filtered);
|
|
3420
3420
|
} catch {
|
|
3421
3421
|
}
|
|
@@ -3484,13 +3484,13 @@ function reconcilePendingMeshCoordinatorEvents(meshId, events) {
|
|
|
3484
3484
|
...backfilled
|
|
3485
3485
|
];
|
|
3486
3486
|
}
|
|
3487
|
-
function trimPendingEventsIfNeeded(
|
|
3487
|
+
function trimPendingEventsIfNeeded(path40) {
|
|
3488
3488
|
try {
|
|
3489
|
-
if (!(0, import_fs9.existsSync)(
|
|
3490
|
-
if ((0, import_fs9.statSync)(
|
|
3491
|
-
const lines = (0, import_fs9.readFileSync)(
|
|
3489
|
+
if (!(0, import_fs9.existsSync)(path40)) return;
|
|
3490
|
+
if ((0, import_fs9.statSync)(path40).size <= MAX_PENDING_EVENTS_BYTES) return;
|
|
3491
|
+
const lines = (0, import_fs9.readFileSync)(path40, "utf-8").split("\n").filter(Boolean);
|
|
3492
3492
|
if (lines.length <= MAX_PENDING_EVENTS_KEEP) return;
|
|
3493
|
-
(0, import_fs9.writeFileSync)(
|
|
3493
|
+
(0, import_fs9.writeFileSync)(path40, lines.slice(-MAX_PENDING_EVENTS_KEEP).join("\n") + "\n", "utf-8");
|
|
3494
3494
|
} catch {
|
|
3495
3495
|
}
|
|
3496
3496
|
}
|
|
@@ -3504,19 +3504,19 @@ function queuePendingMeshCoordinatorEvent(event) {
|
|
|
3504
3504
|
LOG.info("MeshEvents", `Suppressed duplicate pending ${event.event} for mesh ${event.meshId}`);
|
|
3505
3505
|
return true;
|
|
3506
3506
|
}
|
|
3507
|
-
const
|
|
3508
|
-
trimPendingEventsIfNeeded(
|
|
3509
|
-
(0, import_fs9.appendFileSync)(
|
|
3507
|
+
const path40 = getPendingEventsPath(event.meshId, event.targetCoordinatorDaemonId);
|
|
3508
|
+
trimPendingEventsIfNeeded(path40);
|
|
3509
|
+
(0, import_fs9.appendFileSync)(path40, JSON.stringify(event) + "\n", "utf-8");
|
|
3510
3510
|
return true;
|
|
3511
3511
|
} catch (e) {
|
|
3512
3512
|
LOG.warn("MeshEvents", `Failed to persist pending coordinator event: ${e?.message || e}`);
|
|
3513
3513
|
return false;
|
|
3514
3514
|
}
|
|
3515
3515
|
}
|
|
3516
|
-
function atomicDrainFile(
|
|
3517
|
-
const tmpPath = `${
|
|
3516
|
+
function atomicDrainFile(path40) {
|
|
3517
|
+
const tmpPath = `${path40}.draining`;
|
|
3518
3518
|
try {
|
|
3519
|
-
(0, import_fs9.renameSync)(
|
|
3519
|
+
(0, import_fs9.renameSync)(path40, tmpPath);
|
|
3520
3520
|
} catch {
|
|
3521
3521
|
return null;
|
|
3522
3522
|
}
|
|
@@ -3539,8 +3539,8 @@ function drainPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
3539
3539
|
if (!meshId) return [];
|
|
3540
3540
|
const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
|
|
3541
3541
|
const all = [];
|
|
3542
|
-
for (const
|
|
3543
|
-
const content = atomicDrainFile(
|
|
3542
|
+
for (const path40 of paths) {
|
|
3543
|
+
const content = atomicDrainFile(path40);
|
|
3544
3544
|
if (!content) continue;
|
|
3545
3545
|
const parsed = content.split("\n").filter(Boolean).flatMap((line) => {
|
|
3546
3546
|
try {
|
|
@@ -3549,7 +3549,7 @@ function drainPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
3549
3549
|
return [];
|
|
3550
3550
|
}
|
|
3551
3551
|
});
|
|
3552
|
-
const filtered = coordinatorDaemonId &&
|
|
3552
|
+
const filtered = coordinatorDaemonId && path40 === getPendingEventsPath(meshId) ? parsed.filter((e) => !e.targetCoordinatorDaemonId || e.targetCoordinatorDaemonId === coordinatorDaemonId) : parsed;
|
|
3553
3553
|
all.push(...filtered);
|
|
3554
3554
|
}
|
|
3555
3555
|
if (all.length === 0) return [];
|
|
@@ -3562,9 +3562,9 @@ function getPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
3562
3562
|
function clearPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
3563
3563
|
if (!meshId) return;
|
|
3564
3564
|
const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
|
|
3565
|
-
for (const
|
|
3566
|
-
if ((0, import_fs9.existsSync)(
|
|
3567
|
-
(0, import_fs9.unlinkSync)(
|
|
3565
|
+
for (const path40 of paths) {
|
|
3566
|
+
if ((0, import_fs9.existsSync)(path40)) try {
|
|
3567
|
+
(0, import_fs9.unlinkSync)(path40);
|
|
3568
3568
|
} catch {
|
|
3569
3569
|
}
|
|
3570
3570
|
}
|
|
@@ -4690,6 +4690,56 @@ var init_debug_config = __esm({
|
|
|
4690
4690
|
}
|
|
4691
4691
|
});
|
|
4692
4692
|
|
|
4693
|
+
// src/providers/provider-trust.ts
|
|
4694
|
+
var provider_trust_exports = {};
|
|
4695
|
+
__export(provider_trust_exports, {
|
|
4696
|
+
classifyTrust: () => classifyTrust,
|
|
4697
|
+
describeTrust: () => describeTrust,
|
|
4698
|
+
inspectManifestShape: () => inspectManifestShape,
|
|
4699
|
+
requiresConfirmation: () => requiresConfirmation
|
|
4700
|
+
});
|
|
4701
|
+
function inspectManifestShape(manifest) {
|
|
4702
|
+
const hasTui = !!manifest.tui && typeof manifest.tui === "object" && Object.keys(manifest.tui).length > 0;
|
|
4703
|
+
const hasOverrides = !!manifest.overrides && typeof manifest.overrides === "object" && !Array.isArray(manifest.overrides) && Object.keys(manifest.overrides).length > 0;
|
|
4704
|
+
const compat = Array.isArray(manifest.compatibility) ? manifest.compatibility : [];
|
|
4705
|
+
const compatHasScriptDir = compat.some((entry) => typeof entry?.scriptDir === "string");
|
|
4706
|
+
const hasScriptDir = compatHasScriptDir || typeof manifest.defaultScriptDir === "string";
|
|
4707
|
+
return { hasTui, hasOverrides, hasScriptDir };
|
|
4708
|
+
}
|
|
4709
|
+
function classifyTrust(layer, shape) {
|
|
4710
|
+
const isSpecOnly = !shape.hasTui && !shape.hasOverrides && !shape.hasScriptDir;
|
|
4711
|
+
switch (layer) {
|
|
4712
|
+
case "user":
|
|
4713
|
+
return "user-custom";
|
|
4714
|
+
case "upstream":
|
|
4715
|
+
return isSpecOnly ? "trusted" : "trusted-with-scripts";
|
|
4716
|
+
case "external":
|
|
4717
|
+
return isSpecOnly ? "external-safe" : "external-untrusted";
|
|
4718
|
+
}
|
|
4719
|
+
}
|
|
4720
|
+
function requiresConfirmation(trust) {
|
|
4721
|
+
return trust === "external-untrusted";
|
|
4722
|
+
}
|
|
4723
|
+
function describeTrust(trust) {
|
|
4724
|
+
switch (trust) {
|
|
4725
|
+
case "user-custom":
|
|
4726
|
+
return "Hand-authored in ~/.adhdev/providers/. Runs your own code.";
|
|
4727
|
+
case "trusted":
|
|
4728
|
+
return "Official, declarative-only manifest from the ADHDev registry.";
|
|
4729
|
+
case "trusted-with-scripts":
|
|
4730
|
+
return "Official manifest from the ADHDev registry. Ships JavaScript hooks executed by the daemon.";
|
|
4731
|
+
case "external-safe":
|
|
4732
|
+
return "Manifest from a 3rd-party git source you added. Declarative-only \u2014 the daemon never runs JS from this source.";
|
|
4733
|
+
case "external-untrusted":
|
|
4734
|
+
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.";
|
|
4735
|
+
}
|
|
4736
|
+
}
|
|
4737
|
+
var init_provider_trust = __esm({
|
|
4738
|
+
"src/providers/provider-trust.ts"() {
|
|
4739
|
+
"use strict";
|
|
4740
|
+
}
|
|
4741
|
+
});
|
|
4742
|
+
|
|
4693
4743
|
// src/providers/sdk/v1/schemas/cli/provider.schema.json
|
|
4694
4744
|
var provider_schema_default;
|
|
4695
4745
|
var init_provider_schema = __esm({
|
|
@@ -4933,14 +4983,15 @@ var init_provider_schema = __esm({
|
|
|
4933
4983
|
minItems: 1,
|
|
4934
4984
|
items: {
|
|
4935
4985
|
type: "object",
|
|
4936
|
-
required: ["
|
|
4986
|
+
required: ["ideVersion"],
|
|
4937
4987
|
additionalProperties: false,
|
|
4938
4988
|
properties: {
|
|
4939
4989
|
ideVersion: { type: "string", description: "SemVer range." },
|
|
4940
|
-
scriptDir: { type: "string", pattern: "^scripts/[^/]+$" }
|
|
4990
|
+
scriptDir: { type: "string", pattern: "^scripts/[^/]+$" },
|
|
4991
|
+
spec: { type: "string", pattern: "^specs/[^/]+\\.json$", description: "Path to declarative spec.json driving SpecCliAdapter for this version range." }
|
|
4941
4992
|
}
|
|
4942
4993
|
},
|
|
4943
|
-
description: "Maps installed agent versions to script subdirectories."
|
|
4994
|
+
description: "Maps installed agent versions to script subdirectories and/or declarative specs."
|
|
4944
4995
|
},
|
|
4945
4996
|
defaultScriptDir: {
|
|
4946
4997
|
type: "string",
|
|
@@ -5192,7 +5243,7 @@ function getCliValidator() {
|
|
|
5192
5243
|
return _cliValidator;
|
|
5193
5244
|
}
|
|
5194
5245
|
function formatIssue(err) {
|
|
5195
|
-
const
|
|
5246
|
+
const path40 = err.instancePath || "";
|
|
5196
5247
|
const params = err.params;
|
|
5197
5248
|
let message = err.message || "validation failed";
|
|
5198
5249
|
let allowed;
|
|
@@ -5210,7 +5261,7 @@ function formatIssue(err) {
|
|
|
5210
5261
|
} else if (err.keyword === "type") {
|
|
5211
5262
|
message = `must be ${params.type}`;
|
|
5212
5263
|
}
|
|
5213
|
-
return { path:
|
|
5264
|
+
return { path: path40, keyword: err.keyword, message, ...allowed !== void 0 ? { allowed } : {} };
|
|
5214
5265
|
}
|
|
5215
5266
|
function validateCliProviderManifest(manifest) {
|
|
5216
5267
|
const validator = getCliValidator();
|
|
@@ -5237,6 +5288,156 @@ var init_manifest = __esm({
|
|
|
5237
5288
|
}
|
|
5238
5289
|
});
|
|
5239
5290
|
|
|
5291
|
+
// src/providers/external-sources.ts
|
|
5292
|
+
var external_sources_exports = {};
|
|
5293
|
+
__export(external_sources_exports, {
|
|
5294
|
+
activeFilePath: () => activeFilePath,
|
|
5295
|
+
deriveSourceName: () => deriveSourceName,
|
|
5296
|
+
externalRoot: () => externalRoot,
|
|
5297
|
+
inventoryExternalSources: () => inventoryExternalSources,
|
|
5298
|
+
loadExternalSources: () => loadExternalSources,
|
|
5299
|
+
loadProvidersActive: () => loadProvidersActive,
|
|
5300
|
+
resolveActiveSource: () => resolveActiveSource,
|
|
5301
|
+
saveExternalSources: () => saveExternalSources,
|
|
5302
|
+
saveProvidersActive: () => saveProvidersActive,
|
|
5303
|
+
sourcesFilePath: () => sourcesFilePath,
|
|
5304
|
+
sourcesProviding: () => sourcesProviding
|
|
5305
|
+
});
|
|
5306
|
+
function adhdevDir() {
|
|
5307
|
+
return path15.join(os10.homedir(), ".adhdev");
|
|
5308
|
+
}
|
|
5309
|
+
function externalRoot() {
|
|
5310
|
+
return path15.join(adhdevDir(), "external");
|
|
5311
|
+
}
|
|
5312
|
+
function sourcesFilePath() {
|
|
5313
|
+
return path15.join(adhdevDir(), SOURCES_FILENAME);
|
|
5314
|
+
}
|
|
5315
|
+
function activeFilePath() {
|
|
5316
|
+
return path15.join(adhdevDir(), ACTIVE_FILENAME);
|
|
5317
|
+
}
|
|
5318
|
+
function ensureAdhdevDir() {
|
|
5319
|
+
const d = adhdevDir();
|
|
5320
|
+
if (!fs8.existsSync(d)) fs8.mkdirSync(d, { recursive: true });
|
|
5321
|
+
}
|
|
5322
|
+
function loadExternalSources() {
|
|
5323
|
+
const p = sourcesFilePath();
|
|
5324
|
+
if (!fs8.existsSync(p)) return { schema: 1, sources: [] };
|
|
5325
|
+
try {
|
|
5326
|
+
const raw = JSON.parse(fs8.readFileSync(p, "utf-8"));
|
|
5327
|
+
if (!raw || typeof raw !== "object") return { schema: 1, sources: [] };
|
|
5328
|
+
const sources = Array.isArray(raw.sources) ? raw.sources.filter(isValidSource) : [];
|
|
5329
|
+
return { schema: 1, sources };
|
|
5330
|
+
} catch {
|
|
5331
|
+
return { schema: 1, sources: [] };
|
|
5332
|
+
}
|
|
5333
|
+
}
|
|
5334
|
+
function saveExternalSources(file) {
|
|
5335
|
+
ensureAdhdevDir();
|
|
5336
|
+
const tmp = sourcesFilePath() + ".tmp";
|
|
5337
|
+
fs8.writeFileSync(tmp, JSON.stringify(file, null, 2) + "\n", "utf-8");
|
|
5338
|
+
fs8.renameSync(tmp, sourcesFilePath());
|
|
5339
|
+
}
|
|
5340
|
+
function loadProvidersActive() {
|
|
5341
|
+
const p = activeFilePath();
|
|
5342
|
+
if (!fs8.existsSync(p)) return { schema: 1, active: {} };
|
|
5343
|
+
try {
|
|
5344
|
+
const raw = JSON.parse(fs8.readFileSync(p, "utf-8"));
|
|
5345
|
+
if (!raw || typeof raw !== "object") return { schema: 1, active: {} };
|
|
5346
|
+
const active = raw.active && typeof raw.active === "object" ? raw.active : {};
|
|
5347
|
+
return { schema: 1, active };
|
|
5348
|
+
} catch {
|
|
5349
|
+
return { schema: 1, active: {} };
|
|
5350
|
+
}
|
|
5351
|
+
}
|
|
5352
|
+
function saveProvidersActive(file) {
|
|
5353
|
+
ensureAdhdevDir();
|
|
5354
|
+
const tmp = activeFilePath() + ".tmp";
|
|
5355
|
+
fs8.writeFileSync(tmp, JSON.stringify(file, null, 2) + "\n", "utf-8");
|
|
5356
|
+
fs8.renameSync(tmp, activeFilePath());
|
|
5357
|
+
}
|
|
5358
|
+
function isValidSource(x) {
|
|
5359
|
+
if (!x || typeof x !== "object") return false;
|
|
5360
|
+
const s = x;
|
|
5361
|
+
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";
|
|
5362
|
+
}
|
|
5363
|
+
function deriveSourceName(url) {
|
|
5364
|
+
const m = url.match(/[/:]([^/:]+)\/([^/]+?)(?:\.git)?$/);
|
|
5365
|
+
if (!m) return "@source";
|
|
5366
|
+
const owner = m[1].toLowerCase().replace(/[^a-z0-9_-]/g, "-");
|
|
5367
|
+
const repo = m[2].toLowerCase().replace(/[^a-z0-9_-]/g, "-");
|
|
5368
|
+
return `@${owner}-${repo}`;
|
|
5369
|
+
}
|
|
5370
|
+
function inventoryExternalSources() {
|
|
5371
|
+
const root = externalRoot();
|
|
5372
|
+
if (!fs8.existsSync(root)) return [];
|
|
5373
|
+
const out = [];
|
|
5374
|
+
let entries;
|
|
5375
|
+
try {
|
|
5376
|
+
entries = fs8.readdirSync(root, { withFileTypes: true });
|
|
5377
|
+
} catch {
|
|
5378
|
+
return [];
|
|
5379
|
+
}
|
|
5380
|
+
for (const sourceEntry of entries) {
|
|
5381
|
+
if (!sourceEntry.isDirectory()) continue;
|
|
5382
|
+
const sourceName = sourceEntry.name;
|
|
5383
|
+
const sourceDir = path15.join(root, sourceName);
|
|
5384
|
+
const providers = {};
|
|
5385
|
+
let categoryEntries;
|
|
5386
|
+
try {
|
|
5387
|
+
categoryEntries = fs8.readdirSync(sourceDir, { withFileTypes: true });
|
|
5388
|
+
} catch {
|
|
5389
|
+
continue;
|
|
5390
|
+
}
|
|
5391
|
+
for (const categoryEntry of categoryEntries) {
|
|
5392
|
+
if (!categoryEntry.isDirectory()) continue;
|
|
5393
|
+
const category = categoryEntry.name;
|
|
5394
|
+
const categoryDir = path15.join(sourceDir, category);
|
|
5395
|
+
let typeEntries;
|
|
5396
|
+
try {
|
|
5397
|
+
typeEntries = fs8.readdirSync(categoryDir, { withFileTypes: true });
|
|
5398
|
+
} catch {
|
|
5399
|
+
continue;
|
|
5400
|
+
}
|
|
5401
|
+
const types = [];
|
|
5402
|
+
for (const typeEntry of typeEntries) {
|
|
5403
|
+
if (!typeEntry.isDirectory()) continue;
|
|
5404
|
+
const typeDir = path15.join(categoryDir, typeEntry.name);
|
|
5405
|
+
const hasV1 = fs8.existsSync(path15.join(typeDir, "provider.v1.json"));
|
|
5406
|
+
const hasV0 = fs8.existsSync(path15.join(typeDir, "provider.json"));
|
|
5407
|
+
if (hasV1 || hasV0) types.push(typeEntry.name);
|
|
5408
|
+
}
|
|
5409
|
+
if (types.length > 0) providers[category] = types;
|
|
5410
|
+
}
|
|
5411
|
+
out.push({ sourceName, providers });
|
|
5412
|
+
}
|
|
5413
|
+
return out;
|
|
5414
|
+
}
|
|
5415
|
+
function sourcesProviding(category, type) {
|
|
5416
|
+
const inventory = inventoryExternalSources();
|
|
5417
|
+
return inventory.filter((s) => (s.providers[category] || []).includes(type)).map((s) => s.sourceName);
|
|
5418
|
+
}
|
|
5419
|
+
function resolveActiveSource(category, type, activeFile) {
|
|
5420
|
+
const candidates = sourcesProviding(category, type);
|
|
5421
|
+
if (candidates.length === 0) return { source: null, ambiguous: false, candidates };
|
|
5422
|
+
if (candidates.length === 1) return { source: candidates[0], ambiguous: false, candidates };
|
|
5423
|
+
const explicit = (activeFile ?? loadProvidersActive()).active[type];
|
|
5424
|
+
if (explicit && candidates.includes(explicit)) {
|
|
5425
|
+
return { source: explicit, ambiguous: false, candidates };
|
|
5426
|
+
}
|
|
5427
|
+
return { source: candidates[0], ambiguous: true, candidates };
|
|
5428
|
+
}
|
|
5429
|
+
var fs8, os10, path15, SOURCES_FILENAME, ACTIVE_FILENAME;
|
|
5430
|
+
var init_external_sources = __esm({
|
|
5431
|
+
"src/providers/external-sources.ts"() {
|
|
5432
|
+
"use strict";
|
|
5433
|
+
fs8 = __toESM(require("fs"));
|
|
5434
|
+
os10 = __toESM(require("os"));
|
|
5435
|
+
path15 = __toESM(require("path"));
|
|
5436
|
+
SOURCES_FILENAME = "providers-sources.json";
|
|
5437
|
+
ACTIVE_FILENAME = "providers-active.json";
|
|
5438
|
+
}
|
|
5439
|
+
});
|
|
5440
|
+
|
|
5240
5441
|
// src/cli-adapters/terminal-backends/ghostty-vt-backend.ts
|
|
5241
5442
|
function isModuleNotFoundError(error, ref) {
|
|
5242
5443
|
if (!(error instanceof Error)) return false;
|
|
@@ -5532,11 +5733,11 @@ function loadNodePty() {
|
|
|
5532
5733
|
}
|
|
5533
5734
|
return cachedPty;
|
|
5534
5735
|
}
|
|
5535
|
-
var
|
|
5736
|
+
var os11, cachedPty, NodePtyRuntimeTransport, NodePtyTransportFactory;
|
|
5536
5737
|
var init_pty_transport = __esm({
|
|
5537
5738
|
"src/cli-adapters/pty-transport.ts"() {
|
|
5538
5739
|
"use strict";
|
|
5539
|
-
|
|
5740
|
+
os11 = __toESM(require("os"));
|
|
5540
5741
|
init_spawn_env();
|
|
5541
5742
|
NodePtyRuntimeTransport = class {
|
|
5542
5743
|
constructor(handle) {
|
|
@@ -5573,11 +5774,11 @@ var init_pty_transport = __esm({
|
|
|
5573
5774
|
let cwd = options.cwd;
|
|
5574
5775
|
if (cwd) {
|
|
5575
5776
|
try {
|
|
5576
|
-
const
|
|
5577
|
-
const stat2 =
|
|
5578
|
-
if (!stat2.isDirectory()) cwd =
|
|
5777
|
+
const fs28 = require("fs");
|
|
5778
|
+
const stat2 = fs28.statSync(cwd);
|
|
5779
|
+
if (!stat2.isDirectory()) cwd = os11.homedir();
|
|
5579
5780
|
} catch {
|
|
5580
|
-
cwd =
|
|
5781
|
+
cwd = os11.homedir();
|
|
5581
5782
|
}
|
|
5582
5783
|
}
|
|
5583
5784
|
const handle = pty.spawn(command, args, {
|
|
@@ -5669,21 +5870,21 @@ function buildCliScreenSnapshot(text) {
|
|
|
5669
5870
|
function findBinary(name) {
|
|
5670
5871
|
const trimmed = String(name || "").trim();
|
|
5671
5872
|
if (!trimmed) return trimmed;
|
|
5672
|
-
const expanded = trimmed.startsWith("~") ?
|
|
5673
|
-
if (
|
|
5674
|
-
return
|
|
5873
|
+
const expanded = trimmed.startsWith("~") ? path16.join(os12.homedir(), trimmed.slice(1)) : trimmed;
|
|
5874
|
+
if (path16.isAbsolute(expanded) || expanded.includes("/") || expanded.includes("\\")) {
|
|
5875
|
+
return path16.isAbsolute(expanded) ? expanded : path16.resolve(expanded);
|
|
5675
5876
|
}
|
|
5676
|
-
const isWin =
|
|
5677
|
-
const paths = (process.env.PATH || "").split(
|
|
5877
|
+
const isWin = os12.platform() === "win32";
|
|
5878
|
+
const paths = (process.env.PATH || "").split(path16.delimiter);
|
|
5678
5879
|
const exes = isWin ? [".exe", ".cmd", ".bat", ""] : [""];
|
|
5679
5880
|
for (const p of paths) {
|
|
5680
5881
|
if (!p) continue;
|
|
5681
5882
|
for (const ext of exes) {
|
|
5682
|
-
const fullPath =
|
|
5883
|
+
const fullPath = path16.join(p, trimmed + ext);
|
|
5683
5884
|
try {
|
|
5684
|
-
const
|
|
5685
|
-
if (
|
|
5686
|
-
const stat2 =
|
|
5885
|
+
const fs28 = require("fs");
|
|
5886
|
+
if (fs28.existsSync(fullPath)) {
|
|
5887
|
+
const stat2 = fs28.statSync(fullPath);
|
|
5687
5888
|
if (stat2.isFile() && (isWin || stat2.mode & 73)) {
|
|
5688
5889
|
return fullPath;
|
|
5689
5890
|
}
|
|
@@ -5695,14 +5896,14 @@ function findBinary(name) {
|
|
|
5695
5896
|
return isWin ? `${trimmed}.cmd` : trimmed;
|
|
5696
5897
|
}
|
|
5697
5898
|
function isScriptBinary(binaryPath) {
|
|
5698
|
-
if (!
|
|
5899
|
+
if (!path16.isAbsolute(binaryPath)) return false;
|
|
5699
5900
|
try {
|
|
5700
|
-
const
|
|
5701
|
-
const resolved =
|
|
5901
|
+
const fs28 = require("fs");
|
|
5902
|
+
const resolved = fs28.realpathSync(binaryPath);
|
|
5702
5903
|
const head = Buffer.alloc(8);
|
|
5703
|
-
const fd =
|
|
5704
|
-
|
|
5705
|
-
|
|
5904
|
+
const fd = fs28.openSync(resolved, "r");
|
|
5905
|
+
fs28.readSync(fd, head, 0, 8, 0);
|
|
5906
|
+
fs28.closeSync(fd);
|
|
5706
5907
|
let i = 0;
|
|
5707
5908
|
if (head[0] === 239 && head[1] === 187 && head[2] === 191) i = 3;
|
|
5708
5909
|
return head[i] === 35 && head[i + 1] === 33;
|
|
@@ -5711,14 +5912,14 @@ function isScriptBinary(binaryPath) {
|
|
|
5711
5912
|
}
|
|
5712
5913
|
}
|
|
5713
5914
|
function looksLikeMachOOrElf(filePath) {
|
|
5714
|
-
if (!
|
|
5915
|
+
if (!path16.isAbsolute(filePath)) return false;
|
|
5715
5916
|
try {
|
|
5716
|
-
const
|
|
5717
|
-
const resolved =
|
|
5917
|
+
const fs28 = require("fs");
|
|
5918
|
+
const resolved = fs28.realpathSync(filePath);
|
|
5718
5919
|
const buf = Buffer.alloc(8);
|
|
5719
|
-
const fd =
|
|
5720
|
-
|
|
5721
|
-
|
|
5920
|
+
const fd = fs28.openSync(resolved, "r");
|
|
5921
|
+
fs28.readSync(fd, buf, 0, 8, 0);
|
|
5922
|
+
fs28.closeSync(fd);
|
|
5722
5923
|
let i = 0;
|
|
5723
5924
|
if (buf[0] === 239 && buf[1] === 187 && buf[2] === 191) i = 3;
|
|
5724
5925
|
const b = buf.subarray(i);
|
|
@@ -5734,7 +5935,7 @@ function looksLikeMachOOrElf(filePath) {
|
|
|
5734
5935
|
}
|
|
5735
5936
|
function shSingleQuote(arg) {
|
|
5736
5937
|
if (/^[a-zA-Z0-9@%_+=:,./-]+$/.test(arg)) return arg;
|
|
5737
|
-
if (
|
|
5938
|
+
if (os12.platform() === "win32") {
|
|
5738
5939
|
return `"${arg.replace(/"/g, '""')}"`;
|
|
5739
5940
|
}
|
|
5740
5941
|
return `'${arg.replace(/'/g, `'\\''`)}'`;
|
|
@@ -5800,12 +6001,12 @@ function normalizeCliProviderForRuntime(raw) {
|
|
|
5800
6001
|
}
|
|
5801
6002
|
};
|
|
5802
6003
|
}
|
|
5803
|
-
var
|
|
6004
|
+
var os12, path16, TerminalTranscriptAccumulator, buildCliSpawnEnv;
|
|
5804
6005
|
var init_provider_cli_shared = __esm({
|
|
5805
6006
|
"src/cli-adapters/provider-cli-shared.ts"() {
|
|
5806
6007
|
"use strict";
|
|
5807
|
-
|
|
5808
|
-
|
|
6008
|
+
os12 = __toESM(require("os"));
|
|
6009
|
+
path16 = __toESM(require("path"));
|
|
5809
6010
|
init_spawn_env();
|
|
5810
6011
|
TerminalTranscriptAccumulator = class {
|
|
5811
6012
|
lines = [[]];
|
|
@@ -7694,15 +7895,15 @@ function resolveCliSpawnPlan(options) {
|
|
|
7694
7895
|
const { spawn: spawnConfig } = provider;
|
|
7695
7896
|
const configuredCommand = typeof runtimeSettings.executablePath === "string" && runtimeSettings.executablePath.trim() ? runtimeSettings.executablePath.trim() : spawnConfig.command;
|
|
7696
7897
|
const binaryPath = findBinary(configuredCommand);
|
|
7697
|
-
const isWin =
|
|
7898
|
+
const isWin = os13.platform() === "win32";
|
|
7698
7899
|
const allArgs = [...spawnConfig.args, ...extraArgs].map(
|
|
7699
7900
|
(arg) => typeof arg === "string" ? arg.replace(/\{\{workingDir\}\}/g, workingDir) : arg
|
|
7700
7901
|
);
|
|
7701
7902
|
let shellCmd;
|
|
7702
7903
|
let shellArgs;
|
|
7703
|
-
const useShellUnix = !isWin && (!!spawnConfig.shell || !
|
|
7904
|
+
const useShellUnix = !isWin && (!!spawnConfig.shell || !path17.isAbsolute(binaryPath) || isScriptBinary(binaryPath) || !looksLikeMachOOrElf(binaryPath));
|
|
7704
7905
|
const isCmdShim = isWin && /\.(cmd|bat)$/i.test(binaryPath);
|
|
7705
|
-
const useShellWin = !!spawnConfig.shell || isCmdShim || !
|
|
7906
|
+
const useShellWin = !!spawnConfig.shell || isCmdShim || !path17.isAbsolute(binaryPath) || isScriptBinary(binaryPath);
|
|
7706
7907
|
const useShell = isWin ? useShellWin : useShellUnix;
|
|
7707
7908
|
if (useShell) {
|
|
7708
7909
|
shellCmd = isWin ? "cmd.exe" : process.env.SHELL || "/bin/zsh";
|
|
@@ -7778,12 +7979,12 @@ function respondToCliTerminalQueries(options) {
|
|
|
7778
7979
|
}
|
|
7779
7980
|
return "";
|
|
7780
7981
|
}
|
|
7781
|
-
var
|
|
7982
|
+
var os13, path17, import_session_host_core2;
|
|
7782
7983
|
var init_provider_cli_runtime = __esm({
|
|
7783
7984
|
"src/cli-adapters/provider-cli-runtime.ts"() {
|
|
7784
7985
|
"use strict";
|
|
7785
|
-
|
|
7786
|
-
|
|
7986
|
+
os13 = __toESM(require("os"));
|
|
7987
|
+
path17 = __toESM(require("path"));
|
|
7787
7988
|
import_session_host_core2 = require("@adhdev/session-host-core");
|
|
7788
7989
|
init_provider_cli_shared();
|
|
7789
7990
|
}
|
|
@@ -7804,11 +8005,11 @@ function appendBoundedText(current, chunk, maxChars) {
|
|
|
7804
8005
|
if (current.length <= keepFromCurrent) return current + chunk;
|
|
7805
8006
|
return current.slice(-keepFromCurrent) + chunk;
|
|
7806
8007
|
}
|
|
7807
|
-
var
|
|
8008
|
+
var os14, ProviderCliAdapter;
|
|
7808
8009
|
var init_provider_cli_adapter = __esm({
|
|
7809
8010
|
"src/cli-adapters/provider-cli-adapter.ts"() {
|
|
7810
8011
|
"use strict";
|
|
7811
|
-
|
|
8012
|
+
os14 = __toESM(require("os"));
|
|
7812
8013
|
init_logger();
|
|
7813
8014
|
init_debug_config();
|
|
7814
8015
|
init_terminal_screen();
|
|
@@ -7829,7 +8030,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
7829
8030
|
this.transportFactory = transportFactory;
|
|
7830
8031
|
this.cliType = provider.type;
|
|
7831
8032
|
this.cliName = provider.name;
|
|
7832
|
-
this.workingDir = workingDir.startsWith("~") ? workingDir.replace(/^~/,
|
|
8033
|
+
this.workingDir = workingDir.startsWith("~") ? workingDir.replace(/^~/, os14.homedir()) : workingDir;
|
|
7833
8034
|
const resolvedConfig = resolveCliAdapterConfig(provider);
|
|
7834
8035
|
this.timeouts = resolvedConfig.timeouts;
|
|
7835
8036
|
this.approvalKeys = resolvedConfig.approvalKeys;
|
|
@@ -9976,7 +10177,7 @@ __export(loader_exports, {
|
|
|
9976
10177
|
function loadSpec(sourcePath) {
|
|
9977
10178
|
let raw;
|
|
9978
10179
|
try {
|
|
9979
|
-
const text =
|
|
10180
|
+
const text = fs9.readFileSync(sourcePath, "utf8");
|
|
9980
10181
|
raw = JSON.parse(text);
|
|
9981
10182
|
} catch (err) {
|
|
9982
10183
|
return { ok: false, errors: [`Failed to read spec: ${err.message}`], sourcePath };
|
|
@@ -10052,14 +10253,14 @@ function compileRegex2(source, flags, where, errs) {
|
|
|
10052
10253
|
}
|
|
10053
10254
|
}
|
|
10054
10255
|
function resolveSpecPath(providerDir) {
|
|
10055
|
-
return
|
|
10256
|
+
return path18.join(providerDir, "spec.json");
|
|
10056
10257
|
}
|
|
10057
|
-
var
|
|
10258
|
+
var fs9, path18, import_ajv, ajv, validate;
|
|
10058
10259
|
var init_loader = __esm({
|
|
10059
10260
|
"src/providers/spec/loader.ts"() {
|
|
10060
10261
|
"use strict";
|
|
10061
|
-
|
|
10062
|
-
|
|
10262
|
+
fs9 = __toESM(require("fs"));
|
|
10263
|
+
path18 = __toESM(require("path"));
|
|
10063
10264
|
import_ajv = __toESM(require("ajv"));
|
|
10064
10265
|
init_schema_gen();
|
|
10065
10266
|
ajv = new import_ajv.default({ allErrors: true, strict: false });
|
|
@@ -10215,7 +10416,7 @@ function _getRegisteredRoots() {
|
|
|
10215
10416
|
}
|
|
10216
10417
|
function canonicalize(p) {
|
|
10217
10418
|
try {
|
|
10218
|
-
const resolved =
|
|
10419
|
+
const resolved = path24.resolve(p);
|
|
10219
10420
|
try {
|
|
10220
10421
|
return nodeFs.realpathSync.native ? nodeFs.realpathSync.native(resolved) : nodeFs.realpathSync(resolved);
|
|
10221
10422
|
} catch {
|
|
@@ -10235,7 +10436,7 @@ function isCallerInsideGatedRoot(callerFilename) {
|
|
|
10235
10436
|
}
|
|
10236
10437
|
for (const root of _gatedRoots) {
|
|
10237
10438
|
if (normalized === root.rootPath) return root;
|
|
10238
|
-
if (normalized.startsWith(root.rootPath +
|
|
10439
|
+
if (normalized.startsWith(root.rootPath + path24.sep)) return root;
|
|
10239
10440
|
}
|
|
10240
10441
|
return null;
|
|
10241
10442
|
}
|
|
@@ -10254,16 +10455,16 @@ function ensureInstalled() {
|
|
|
10254
10455
|
};
|
|
10255
10456
|
}
|
|
10256
10457
|
function gatedRequire(request, parent, isMain, gated, originalLoad) {
|
|
10257
|
-
if (request.startsWith("./") || request.startsWith("../") ||
|
|
10458
|
+
if (request.startsWith("./") || request.startsWith("../") || path24.isAbsolute(request)) {
|
|
10258
10459
|
let resolved;
|
|
10259
10460
|
try {
|
|
10260
|
-
const callerRequire = parent?.filename ? (0, import_node_module2.createRequire)(parent.filename) : (0, import_node_module2.createRequire)(
|
|
10461
|
+
const callerRequire = parent?.filename ? (0, import_node_module2.createRequire)(parent.filename) : (0, import_node_module2.createRequire)(path24.join(gated.rootPath, "__entry__.js"));
|
|
10261
10462
|
resolved = callerRequire.resolve(request);
|
|
10262
10463
|
} catch {
|
|
10263
10464
|
return originalLoad.call(this, request, parent, isMain);
|
|
10264
10465
|
}
|
|
10265
10466
|
const resolvedCanon = canonicalize(resolved) || resolved;
|
|
10266
|
-
if (!(resolvedCanon === gated.rootPath || resolvedCanon.startsWith(gated.rootPath +
|
|
10467
|
+
if (!(resolvedCanon === gated.rootPath || resolvedCanon.startsWith(gated.rootPath + path24.sep))) {
|
|
10267
10468
|
denyRequire(request, parent, `relative path escapes provider root (resolved to ${resolvedCanon})`);
|
|
10268
10469
|
}
|
|
10269
10470
|
return originalLoad.call(this, request, parent, isMain);
|
|
@@ -10287,11 +10488,11 @@ function denyRequire(request, parent, reason) {
|
|
|
10287
10488
|
err.callerFilename = caller;
|
|
10288
10489
|
throw err;
|
|
10289
10490
|
}
|
|
10290
|
-
var
|
|
10491
|
+
var path24, import_node_module2, nodeFs, nodeChildProcess, SAFE_STDLIB, SHIMMED_STDLIB, ALL_GATED_STDLIB, FS_READ_ONLY_MEMBERS, FS_PROMISES_READ_ONLY_MEMBERS, FS_SHIM, CHILD_PROCESS_SHIM, DANGEROUS_PROCESS_METHODS, _processGloballyHardened, _originalProcessMethods, PROCESS_SHIM, _gatedRoots, _installed, PROVIDER_REQUIRE_POLICY;
|
|
10291
10492
|
var init_require_whitelist = __esm({
|
|
10292
10493
|
"src/providers/sdk/v1/sandbox/require-whitelist.ts"() {
|
|
10293
10494
|
"use strict";
|
|
10294
|
-
|
|
10495
|
+
path24 = __toESM(require("path"));
|
|
10295
10496
|
import_node_module2 = require("module");
|
|
10296
10497
|
nodeFs = __toESM(require("fs"));
|
|
10297
10498
|
nodeChildProcess = __toESM(require("child_process"));
|
|
@@ -10401,7 +10602,7 @@ function executeJsonl(src, input) {
|
|
|
10401
10602
|
} else {
|
|
10402
10603
|
let stat2 = null;
|
|
10403
10604
|
try {
|
|
10404
|
-
stat2 =
|
|
10605
|
+
stat2 = fs13.statSync(resolved);
|
|
10405
10606
|
} catch {
|
|
10406
10607
|
return null;
|
|
10407
10608
|
}
|
|
@@ -10420,7 +10621,7 @@ function executeJsonl(src, input) {
|
|
|
10420
10621
|
const v = jsonPathGet(lines[0], src.session_id_path);
|
|
10421
10622
|
if (typeof v === "string" && v) providerSessionId = v;
|
|
10422
10623
|
} else if (src.session_id_from === "filename_uuid" || !src.session_id_from) {
|
|
10423
|
-
const m =
|
|
10624
|
+
const m = path25.basename(sourcePath).match(UUID_RE);
|
|
10424
10625
|
if (m) providerSessionId = m[1];
|
|
10425
10626
|
}
|
|
10426
10627
|
const requested = input.providerSessionId || "";
|
|
@@ -10445,7 +10646,7 @@ function executeJsonl(src, input) {
|
|
|
10445
10646
|
function readJsonlLines(p) {
|
|
10446
10647
|
let text;
|
|
10447
10648
|
try {
|
|
10448
|
-
text =
|
|
10649
|
+
text = fs13.readFileSync(p, "utf8");
|
|
10449
10650
|
} catch {
|
|
10450
10651
|
return [];
|
|
10451
10652
|
}
|
|
@@ -10462,7 +10663,7 @@ function readJsonlLines(p) {
|
|
|
10462
10663
|
}
|
|
10463
10664
|
function executeSqlite(src, input) {
|
|
10464
10665
|
const resolved = expandPath2(src.path, input);
|
|
10465
|
-
if (!resolved || !
|
|
10666
|
+
if (!resolved || !fs13.existsSync(resolved)) return null;
|
|
10466
10667
|
let Database;
|
|
10467
10668
|
try {
|
|
10468
10669
|
Database = require("better-sqlite3");
|
|
@@ -10521,17 +10722,25 @@ function expandPath2(template, input) {
|
|
|
10521
10722
|
if (!template) return null;
|
|
10522
10723
|
let out = template;
|
|
10523
10724
|
if (out.startsWith("~/") || out === "~") {
|
|
10524
|
-
out =
|
|
10725
|
+
out = path25.join(os18.homedir(), out.slice(2));
|
|
10525
10726
|
}
|
|
10526
10727
|
out = out.replace(/\$\{([A-Z_][A-Z0-9_]*)(?::-(.*?))?\}/g, (_m, name, fallback) => {
|
|
10527
10728
|
const v = input.envOverrides?.[name] ?? process.env[name];
|
|
10528
10729
|
return v != null && v !== "" ? v : fallback ?? "";
|
|
10529
10730
|
});
|
|
10530
|
-
if (out.startsWith("~/")) out =
|
|
10731
|
+
if (out.startsWith("~/")) out = path25.join(os18.homedir(), out.slice(2));
|
|
10531
10732
|
const now = /* @__PURE__ */ new Date();
|
|
10733
|
+
const workspaceRaw = input.workspace ?? "";
|
|
10734
|
+
let workspaceResolved = workspaceRaw;
|
|
10735
|
+
if (workspaceRaw) {
|
|
10736
|
+
try {
|
|
10737
|
+
workspaceResolved = fs13.realpathSync(workspaceRaw);
|
|
10738
|
+
} catch {
|
|
10739
|
+
}
|
|
10740
|
+
}
|
|
10532
10741
|
const vars = {
|
|
10533
|
-
cwd:
|
|
10534
|
-
cwd_dashed:
|
|
10742
|
+
cwd: workspaceResolved,
|
|
10743
|
+
cwd_dashed: workspaceResolved.replace(/\//g, "-"),
|
|
10535
10744
|
session_id: input.providerSessionId || input.sessionId || input.historySessionId || "",
|
|
10536
10745
|
yyyy: String(now.getUTCFullYear()),
|
|
10537
10746
|
mm: String(now.getUTCMonth() + 1).padStart(2, "0"),
|
|
@@ -10567,20 +10776,20 @@ function expandDirGlob(template) {
|
|
|
10567
10776
|
for (const d of dirs) {
|
|
10568
10777
|
let entries;
|
|
10569
10778
|
try {
|
|
10570
|
-
entries =
|
|
10779
|
+
entries = fs13.readdirSync(d, { withFileTypes: true });
|
|
10571
10780
|
} catch {
|
|
10572
10781
|
continue;
|
|
10573
10782
|
}
|
|
10574
10783
|
for (const e of entries) {
|
|
10575
|
-
if (e.isDirectory() && re.test(e.name)) next.push(
|
|
10784
|
+
if (e.isDirectory() && re.test(e.name)) next.push(path25.join(d, e.name));
|
|
10576
10785
|
}
|
|
10577
10786
|
}
|
|
10578
10787
|
} else {
|
|
10579
10788
|
for (const d of dirs) {
|
|
10580
|
-
const candidate =
|
|
10789
|
+
const candidate = path25.join(d, seg);
|
|
10581
10790
|
let stat2 = null;
|
|
10582
10791
|
try {
|
|
10583
|
-
stat2 =
|
|
10792
|
+
stat2 = fs13.statSync(candidate);
|
|
10584
10793
|
} catch {
|
|
10585
10794
|
continue;
|
|
10586
10795
|
}
|
|
@@ -10594,13 +10803,13 @@ function expandDirGlob(template) {
|
|
|
10594
10803
|
function walkAllDirs(root, out) {
|
|
10595
10804
|
let entries;
|
|
10596
10805
|
try {
|
|
10597
|
-
entries =
|
|
10806
|
+
entries = fs13.readdirSync(root, { withFileTypes: true });
|
|
10598
10807
|
} catch {
|
|
10599
10808
|
return;
|
|
10600
10809
|
}
|
|
10601
10810
|
out.push(root);
|
|
10602
10811
|
for (const e of entries) {
|
|
10603
|
-
if (e.isDirectory()) walkAllDirs(
|
|
10812
|
+
if (e.isDirectory()) walkAllDirs(path25.join(root, e.name), out);
|
|
10604
10813
|
}
|
|
10605
10814
|
}
|
|
10606
10815
|
function newestRecentFileAcrossGlob(template, pattern, windowMs, sessionFloorMs = 0) {
|
|
@@ -10610,13 +10819,13 @@ function newestRecentFileAcrossGlob(template, pattern, windowMs, sessionFloorMs
|
|
|
10610
10819
|
for (const d of dirs) {
|
|
10611
10820
|
let entries;
|
|
10612
10821
|
try {
|
|
10613
|
-
entries =
|
|
10822
|
+
entries = fs13.readdirSync(d, { withFileTypes: true });
|
|
10614
10823
|
} catch {
|
|
10615
10824
|
continue;
|
|
10616
10825
|
}
|
|
10617
10826
|
for (const e of entries) {
|
|
10618
10827
|
if (!e.isFile() || !pattern.test(e.name)) continue;
|
|
10619
|
-
const p =
|
|
10828
|
+
const p = path25.join(d, e.name);
|
|
10620
10829
|
const mtime = safeMtimeMs(p);
|
|
10621
10830
|
if (mtime < cutoff) continue;
|
|
10622
10831
|
if (!best || mtime > best.mtime) best = { p, mtime };
|
|
@@ -10627,7 +10836,7 @@ function newestRecentFileAcrossGlob(template, pattern, windowMs, sessionFloorMs
|
|
|
10627
10836
|
function newestRecentFile(dir, pattern, windowMs, sessionFloorMs = 0) {
|
|
10628
10837
|
let entries;
|
|
10629
10838
|
try {
|
|
10630
|
-
entries =
|
|
10839
|
+
entries = fs13.readdirSync(dir, { withFileTypes: true });
|
|
10631
10840
|
} catch {
|
|
10632
10841
|
return null;
|
|
10633
10842
|
}
|
|
@@ -10635,7 +10844,7 @@ function newestRecentFile(dir, pattern, windowMs, sessionFloorMs = 0) {
|
|
|
10635
10844
|
let best = null;
|
|
10636
10845
|
for (const e of entries) {
|
|
10637
10846
|
if (!e.isFile() || !pattern.test(e.name)) continue;
|
|
10638
|
-
const p =
|
|
10847
|
+
const p = path25.join(dir, e.name);
|
|
10639
10848
|
const mtime = safeMtimeMs(p);
|
|
10640
10849
|
if (mtime < cutoff) continue;
|
|
10641
10850
|
if (!best || mtime > best.mtime) best = { p, mtime };
|
|
@@ -10644,7 +10853,7 @@ function newestRecentFile(dir, pattern, windowMs, sessionFloorMs = 0) {
|
|
|
10644
10853
|
}
|
|
10645
10854
|
function safeMtimeMs(p) {
|
|
10646
10855
|
try {
|
|
10647
|
-
return Math.floor(
|
|
10856
|
+
return Math.floor(fs13.statSync(p).mtimeMs);
|
|
10648
10857
|
} catch {
|
|
10649
10858
|
return 0;
|
|
10650
10859
|
}
|
|
@@ -10848,13 +11057,13 @@ function evalTerm(t, record) {
|
|
|
10848
11057
|
}
|
|
10849
11058
|
return t.negate ? !result : result;
|
|
10850
11059
|
}
|
|
10851
|
-
var
|
|
11060
|
+
var fs13, os18, path25, UUID_RE;
|
|
10852
11061
|
var init_native_history_executor = __esm({
|
|
10853
11062
|
"src/providers/spec/native-history-executor.ts"() {
|
|
10854
11063
|
"use strict";
|
|
10855
|
-
|
|
10856
|
-
|
|
10857
|
-
|
|
11064
|
+
fs13 = __toESM(require("fs"));
|
|
11065
|
+
os18 = __toESM(require("os"));
|
|
11066
|
+
path25 = __toESM(require("path"));
|
|
10858
11067
|
UUID_RE = /([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/i;
|
|
10859
11068
|
}
|
|
10860
11069
|
});
|
|
@@ -10872,7 +11081,7 @@ function extractTimestampValue(value) {
|
|
|
10872
11081
|
}
|
|
10873
11082
|
function statMtimeMs(filePath) {
|
|
10874
11083
|
try {
|
|
10875
|
-
return
|
|
11084
|
+
return fs14.statSync(filePath).mtimeMs;
|
|
10876
11085
|
} catch {
|
|
10877
11086
|
return 0;
|
|
10878
11087
|
}
|
|
@@ -10942,7 +11151,7 @@ function extractUserContentParts(content) {
|
|
|
10942
11151
|
function parseTranscriptFile(filePath, sessionId, workspaceFallback) {
|
|
10943
11152
|
let raw;
|
|
10944
11153
|
try {
|
|
10945
|
-
raw =
|
|
11154
|
+
raw = fs14.readFileSync(filePath, "utf-8");
|
|
10946
11155
|
} catch {
|
|
10947
11156
|
return [];
|
|
10948
11157
|
}
|
|
@@ -11015,10 +11224,10 @@ function parseTranscriptFile(filePath, sessionId, workspaceFallback) {
|
|
|
11015
11224
|
return records;
|
|
11016
11225
|
}
|
|
11017
11226
|
function readSession(sessionPath) {
|
|
11018
|
-
if (!sessionPath || !
|
|
11019
|
-
const basename12 =
|
|
11227
|
+
if (!sessionPath || !path26.isAbsolute(sessionPath)) return null;
|
|
11228
|
+
const basename12 = path26.basename(sessionPath, ".jsonl");
|
|
11020
11229
|
if (!isSafeSessionId(basename12)) return null;
|
|
11021
|
-
if (!
|
|
11230
|
+
if (!fs14.existsSync(sessionPath)) return null;
|
|
11022
11231
|
const sourceMtimeMs = statMtimeMs(sessionPath);
|
|
11023
11232
|
const messages = parseTranscriptFile(sessionPath, basename12);
|
|
11024
11233
|
if (messages.length === 0) return null;
|
|
@@ -11034,12 +11243,12 @@ function readSession(sessionPath) {
|
|
|
11034
11243
|
workspace
|
|
11035
11244
|
};
|
|
11036
11245
|
}
|
|
11037
|
-
var
|
|
11246
|
+
var fs14, path26;
|
|
11038
11247
|
var init_claude_cli_transcript = __esm({
|
|
11039
11248
|
"src/providers/native-history/claude-cli-transcript.ts"() {
|
|
11040
11249
|
"use strict";
|
|
11041
|
-
|
|
11042
|
-
|
|
11250
|
+
fs14 = __toESM(require("fs"));
|
|
11251
|
+
path26 = __toESM(require("path"));
|
|
11043
11252
|
}
|
|
11044
11253
|
});
|
|
11045
11254
|
|
|
@@ -11056,7 +11265,7 @@ function extractTimestampValue2(value) {
|
|
|
11056
11265
|
}
|
|
11057
11266
|
function statMtimeMs2(filePath) {
|
|
11058
11267
|
try {
|
|
11059
|
-
return
|
|
11268
|
+
return fs15.statSync(filePath).mtimeMs;
|
|
11060
11269
|
} catch {
|
|
11061
11270
|
return 0;
|
|
11062
11271
|
}
|
|
@@ -11124,7 +11333,7 @@ function extractToolOutputContent(payload) {
|
|
|
11124
11333
|
}
|
|
11125
11334
|
function readSessionMeta(filePath) {
|
|
11126
11335
|
try {
|
|
11127
|
-
const firstLine =
|
|
11336
|
+
const firstLine = fs15.readFileSync(filePath, "utf-8").split("\n").find(Boolean);
|
|
11128
11337
|
if (!firstLine) return null;
|
|
11129
11338
|
const parsed = JSON.parse(firstLine);
|
|
11130
11339
|
if (String(parsed.type ?? "") !== "session_meta") return null;
|
|
@@ -11136,7 +11345,7 @@ function readSessionMeta(filePath) {
|
|
|
11136
11345
|
function parseSessionFile(filePath, sessionId, workspaceFallback) {
|
|
11137
11346
|
let raw;
|
|
11138
11347
|
try {
|
|
11139
|
-
raw =
|
|
11348
|
+
raw = fs15.readFileSync(filePath, "utf-8");
|
|
11140
11349
|
} catch {
|
|
11141
11350
|
return [];
|
|
11142
11351
|
}
|
|
@@ -11230,11 +11439,11 @@ function parseSessionFile(filePath, sessionId, workspaceFallback) {
|
|
|
11230
11439
|
return records;
|
|
11231
11440
|
}
|
|
11232
11441
|
function readSession2(sessionPath) {
|
|
11233
|
-
if (!sessionPath || !
|
|
11234
|
-
if (!
|
|
11442
|
+
if (!sessionPath || !path27.isAbsolute(sessionPath)) return null;
|
|
11443
|
+
if (!fs15.existsSync(sessionPath)) return null;
|
|
11235
11444
|
const meta = readSessionMeta(sessionPath);
|
|
11236
11445
|
const metaId = String(meta?.id ?? "").trim();
|
|
11237
|
-
const basename12 =
|
|
11446
|
+
const basename12 = path27.basename(sessionPath, ".jsonl");
|
|
11238
11447
|
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);
|
|
11239
11448
|
const filenameUuid = uuidMatch ? uuidMatch[1] : "";
|
|
11240
11449
|
if (metaId && filenameUuid && metaId !== filenameUuid) return null;
|
|
@@ -11256,12 +11465,12 @@ function readSession2(sessionPath) {
|
|
|
11256
11465
|
workspace
|
|
11257
11466
|
};
|
|
11258
11467
|
}
|
|
11259
|
-
var
|
|
11468
|
+
var fs15, path27;
|
|
11260
11469
|
var init_codex_cli_transcript = __esm({
|
|
11261
11470
|
"src/providers/native-history/codex-cli-transcript.ts"() {
|
|
11262
11471
|
"use strict";
|
|
11263
|
-
|
|
11264
|
-
|
|
11472
|
+
fs15 = __toESM(require("fs"));
|
|
11473
|
+
path27 = __toESM(require("path"));
|
|
11265
11474
|
}
|
|
11266
11475
|
});
|
|
11267
11476
|
|
|
@@ -11278,7 +11487,7 @@ function extractTimestampValue3(value) {
|
|
|
11278
11487
|
}
|
|
11279
11488
|
function statMtimeMs3(filePath) {
|
|
11280
11489
|
try {
|
|
11281
|
-
return
|
|
11490
|
+
return fs16.statSync(filePath).mtimeMs;
|
|
11282
11491
|
} catch {
|
|
11283
11492
|
return 0;
|
|
11284
11493
|
}
|
|
@@ -11287,13 +11496,13 @@ function isUuidLike(value) {
|
|
|
11287
11496
|
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value);
|
|
11288
11497
|
}
|
|
11289
11498
|
function antigravityRoot() {
|
|
11290
|
-
return
|
|
11499
|
+
return path28.join(os19.homedir(), ".gemini", "antigravity-cli");
|
|
11291
11500
|
}
|
|
11292
11501
|
function historyJsonlPath() {
|
|
11293
|
-
return
|
|
11502
|
+
return path28.join(antigravityRoot(), "history.jsonl");
|
|
11294
11503
|
}
|
|
11295
11504
|
function brainRoot() {
|
|
11296
|
-
return
|
|
11505
|
+
return path28.join(antigravityRoot(), "brain");
|
|
11297
11506
|
}
|
|
11298
11507
|
function extractUserRequestContent(content) {
|
|
11299
11508
|
const raw = content.trim();
|
|
@@ -11309,7 +11518,7 @@ function antigravityRowKind(rowType) {
|
|
|
11309
11518
|
function parseBrainTranscript(filePath, sessionId, workspace) {
|
|
11310
11519
|
let raw;
|
|
11311
11520
|
try {
|
|
11312
|
-
raw =
|
|
11521
|
+
raw = fs16.readFileSync(filePath, "utf-8");
|
|
11313
11522
|
} catch {
|
|
11314
11523
|
return null;
|
|
11315
11524
|
}
|
|
@@ -11369,7 +11578,7 @@ function readHistoryRows() {
|
|
|
11369
11578
|
const sourcePath = historyJsonlPath();
|
|
11370
11579
|
let lines = [];
|
|
11371
11580
|
try {
|
|
11372
|
-
lines =
|
|
11581
|
+
lines = fs16.readFileSync(sourcePath, "utf-8").split("\n").filter(Boolean);
|
|
11373
11582
|
} catch {
|
|
11374
11583
|
return [];
|
|
11375
11584
|
}
|
|
@@ -11416,7 +11625,7 @@ function extractStringsFromBuffer(buf) {
|
|
|
11416
11625
|
function parsePbFile(filePath, sessionId) {
|
|
11417
11626
|
let buf;
|
|
11418
11627
|
try {
|
|
11419
|
-
buf =
|
|
11628
|
+
buf = fs16.readFileSync(filePath);
|
|
11420
11629
|
} catch {
|
|
11421
11630
|
return null;
|
|
11422
11631
|
}
|
|
@@ -11439,13 +11648,13 @@ function parsePbFile(filePath, sessionId) {
|
|
|
11439
11648
|
];
|
|
11440
11649
|
}
|
|
11441
11650
|
function readSession3(sessionPath, sessionId, workspace) {
|
|
11442
|
-
if (!sessionPath || !
|
|
11443
|
-
if (!
|
|
11651
|
+
if (!sessionPath || !path28.isAbsolute(sessionPath)) return null;
|
|
11652
|
+
if (!fs16.existsSync(sessionPath)) return null;
|
|
11444
11653
|
const sourceMtimeMs = statMtimeMs3(sessionPath);
|
|
11445
11654
|
const brainRootPath = brainRoot();
|
|
11446
|
-
if (sessionPath.startsWith(brainRootPath +
|
|
11447
|
-
const
|
|
11448
|
-
const uuidFromPath =
|
|
11655
|
+
if (sessionPath.startsWith(brainRootPath + path28.sep) && sessionPath.endsWith(".jsonl")) {
|
|
11656
|
+
const relative5 = sessionPath.slice(brainRootPath.length + 1);
|
|
11657
|
+
const uuidFromPath = relative5.split(path28.sep)[0];
|
|
11449
11658
|
const resolvedSessionId = sessionId || (isUuidLike(uuidFromPath) ? uuidFromPath : "");
|
|
11450
11659
|
if (!resolvedSessionId) return null;
|
|
11451
11660
|
const messages = parseBrainTranscript(sessionPath, resolvedSessionId, workspace);
|
|
@@ -11461,7 +11670,7 @@ function readSession3(sessionPath, sessionId, workspace) {
|
|
|
11461
11670
|
};
|
|
11462
11671
|
}
|
|
11463
11672
|
if (sessionPath.endsWith(".pb")) {
|
|
11464
|
-
const pbSessionId = sessionId ||
|
|
11673
|
+
const pbSessionId = sessionId || path28.basename(sessionPath, ".pb");
|
|
11465
11674
|
if (!isUuidLike(pbSessionId)) return null;
|
|
11466
11675
|
const messages = parsePbFile(sessionPath, pbSessionId);
|
|
11467
11676
|
if (!messages || messages.length === 0) return null;
|
|
@@ -11475,7 +11684,7 @@ function readSession3(sessionPath, sessionId, workspace) {
|
|
|
11475
11684
|
partialReason: "antigravity_cli_pb_raw_text_extraction"
|
|
11476
11685
|
};
|
|
11477
11686
|
}
|
|
11478
|
-
if (
|
|
11687
|
+
if (path28.basename(sessionPath) === "history.jsonl") {
|
|
11479
11688
|
const resolvedSessionId = sessionId || "";
|
|
11480
11689
|
if (!resolvedSessionId || !isUuidLike(resolvedSessionId)) return null;
|
|
11481
11690
|
const rows = readHistoryRows().filter((r) => r.conversationId === resolvedSessionId);
|
|
@@ -11520,13 +11729,13 @@ function readSession3(sessionPath, sessionId, workspace) {
|
|
|
11520
11729
|
}
|
|
11521
11730
|
return null;
|
|
11522
11731
|
}
|
|
11523
|
-
var
|
|
11732
|
+
var fs16, path28, os19, MIN_PRINTABLE_RUN;
|
|
11524
11733
|
var init_antigravity_cli_transcript = __esm({
|
|
11525
11734
|
"src/providers/native-history/antigravity-cli-transcript.ts"() {
|
|
11526
11735
|
"use strict";
|
|
11527
|
-
|
|
11528
|
-
|
|
11529
|
-
|
|
11736
|
+
fs16 = __toESM(require("fs"));
|
|
11737
|
+
path28 = __toESM(require("path"));
|
|
11738
|
+
os19 = __toESM(require("os"));
|
|
11530
11739
|
MIN_PRINTABLE_RUN = 8;
|
|
11531
11740
|
}
|
|
11532
11741
|
});
|
|
@@ -11534,13 +11743,13 @@ var init_antigravity_cli_transcript = __esm({
|
|
|
11534
11743
|
// src/providers/native-history/hermes-cli-transcript.ts
|
|
11535
11744
|
function statMtimeMs4(p) {
|
|
11536
11745
|
try {
|
|
11537
|
-
return Math.floor(
|
|
11746
|
+
return Math.floor(fs17.statSync(p).mtimeMs);
|
|
11538
11747
|
} catch {
|
|
11539
11748
|
return 0;
|
|
11540
11749
|
}
|
|
11541
11750
|
}
|
|
11542
11751
|
function openDb() {
|
|
11543
|
-
if (!
|
|
11752
|
+
if (!fs17.existsSync(HERMES_STATE_DB)) return null;
|
|
11544
11753
|
try {
|
|
11545
11754
|
const Database = require("better-sqlite3");
|
|
11546
11755
|
return new Database(HERMES_STATE_DB, { readonly: true, fileMustExist: true });
|
|
@@ -11597,10 +11806,10 @@ function readSession4(sessionPath) {
|
|
|
11597
11806
|
}
|
|
11598
11807
|
}
|
|
11599
11808
|
}
|
|
11600
|
-
if (!
|
|
11809
|
+
if (!path29.isAbsolute(sessionPath) || !fs17.existsSync(sessionPath)) return null;
|
|
11601
11810
|
let raw;
|
|
11602
11811
|
try {
|
|
11603
|
-
raw = JSON.parse(
|
|
11812
|
+
raw = JSON.parse(fs17.readFileSync(sessionPath, "utf8"));
|
|
11604
11813
|
} catch {
|
|
11605
11814
|
return null;
|
|
11606
11815
|
}
|
|
@@ -11623,7 +11832,7 @@ function readSession4(sessionPath) {
|
|
|
11623
11832
|
});
|
|
11624
11833
|
}
|
|
11625
11834
|
if (messages.length === 0) return null;
|
|
11626
|
-
const sessionId = typeof raw.session_id === "string" && raw.session_id ? raw.session_id :
|
|
11835
|
+
const sessionId = typeof raw.session_id === "string" && raw.session_id ? raw.session_id : path29.basename(sessionPath, ".json").replace(/^session_/, "");
|
|
11627
11836
|
return {
|
|
11628
11837
|
messages,
|
|
11629
11838
|
providerSessionId: sessionId,
|
|
@@ -11640,15 +11849,15 @@ function normalizeHermesRole(r) {
|
|
|
11640
11849
|
if (s === "tool" || s === "tool_result" || s === "function") return "assistant";
|
|
11641
11850
|
return "system";
|
|
11642
11851
|
}
|
|
11643
|
-
var
|
|
11852
|
+
var fs17, path29, os20, HERMES_STATE_DB, HERMES_LEGACY_SESSIONS_DIR;
|
|
11644
11853
|
var init_hermes_cli_transcript = __esm({
|
|
11645
11854
|
"src/providers/native-history/hermes-cli-transcript.ts"() {
|
|
11646
11855
|
"use strict";
|
|
11647
|
-
|
|
11648
|
-
|
|
11649
|
-
|
|
11650
|
-
HERMES_STATE_DB =
|
|
11651
|
-
HERMES_LEGACY_SESSIONS_DIR =
|
|
11856
|
+
fs17 = __toESM(require("fs"));
|
|
11857
|
+
path29 = __toESM(require("path"));
|
|
11858
|
+
os20 = __toESM(require("os"));
|
|
11859
|
+
HERMES_STATE_DB = path29.join(os20.homedir(), ".hermes", "state.db");
|
|
11860
|
+
HERMES_LEGACY_SESSIONS_DIR = path29.join(os20.homedir(), ".hermes", "sessions");
|
|
11652
11861
|
}
|
|
11653
11862
|
});
|
|
11654
11863
|
|
|
@@ -11696,26 +11905,26 @@ function resolveSourcePath(reader, workspace, sessionId) {
|
|
|
11696
11905
|
}
|
|
11697
11906
|
}
|
|
11698
11907
|
function resolveClaudePath(workspace, sessionId) {
|
|
11699
|
-
const dir =
|
|
11700
|
-
if (!
|
|
11908
|
+
const dir = path30.join(os21.homedir(), ".claude", "projects", cwdAsDashes(workspace));
|
|
11909
|
+
if (!fs18.existsSync(dir)) return null;
|
|
11701
11910
|
if (sessionId) {
|
|
11702
|
-
const candidate =
|
|
11703
|
-
if (
|
|
11911
|
+
const candidate = path30.join(dir, `${sessionId}.jsonl`);
|
|
11912
|
+
if (fs18.existsSync(candidate)) return candidate;
|
|
11704
11913
|
}
|
|
11705
11914
|
return null;
|
|
11706
11915
|
}
|
|
11707
11916
|
function resolveCodexPath(workspace) {
|
|
11708
11917
|
void workspace;
|
|
11709
11918
|
const now = /* @__PURE__ */ new Date();
|
|
11710
|
-
const dir =
|
|
11711
|
-
|
|
11919
|
+
const dir = path30.join(
|
|
11920
|
+
os21.homedir(),
|
|
11712
11921
|
".codex",
|
|
11713
11922
|
"sessions",
|
|
11714
11923
|
String(now.getUTCFullYear()),
|
|
11715
11924
|
String(now.getUTCMonth() + 1).padStart(2, "0"),
|
|
11716
11925
|
String(now.getUTCDate()).padStart(2, "0")
|
|
11717
11926
|
);
|
|
11718
|
-
if (
|
|
11927
|
+
if (fs18.existsSync(dir)) {
|
|
11719
11928
|
const f = newestRecentFile2(dir, /\.jsonl$/);
|
|
11720
11929
|
if (f) return f;
|
|
11721
11930
|
}
|
|
@@ -11723,23 +11932,23 @@ function resolveCodexPath(workspace) {
|
|
|
11723
11932
|
}
|
|
11724
11933
|
function resolveAntigravityPath(workspace) {
|
|
11725
11934
|
void workspace;
|
|
11726
|
-
const brainRoot2 =
|
|
11727
|
-
if (!
|
|
11935
|
+
const brainRoot2 = path30.join(os21.homedir(), ".gemini", "antigravity-cli", "brain");
|
|
11936
|
+
if (!fs18.existsSync(brainRoot2)) return null;
|
|
11728
11937
|
const cutoff = Date.now() - RECENT_WINDOW_MS;
|
|
11729
|
-
const entries =
|
|
11938
|
+
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);
|
|
11730
11939
|
for (const e of entries) {
|
|
11731
|
-
const t =
|
|
11732
|
-
if (
|
|
11940
|
+
const t = path30.join(e.p, ".system_generated", "logs", "transcript.jsonl");
|
|
11941
|
+
if (fs18.existsSync(t)) return t;
|
|
11733
11942
|
}
|
|
11734
11943
|
return null;
|
|
11735
11944
|
}
|
|
11736
11945
|
function resolveHermesPath(workspace, sessionId) {
|
|
11737
11946
|
void workspace;
|
|
11738
11947
|
void sessionId;
|
|
11739
|
-
const dbPath =
|
|
11740
|
-
if (
|
|
11741
|
-
const dir =
|
|
11742
|
-
if (!
|
|
11948
|
+
const dbPath = path30.join(os21.homedir(), ".hermes", "state.db");
|
|
11949
|
+
if (fs18.existsSync(dbPath)) return dbPath;
|
|
11950
|
+
const dir = path30.join(os21.homedir(), ".hermes", "sessions");
|
|
11951
|
+
if (!fs18.existsSync(dir)) return null;
|
|
11743
11952
|
return newestRecentFile2(dir, /^session_.*\.json$/);
|
|
11744
11953
|
}
|
|
11745
11954
|
function readByReader(reader, sourcePath, sessionId, workspace) {
|
|
@@ -11761,7 +11970,7 @@ function cwdAsDashes(cwd) {
|
|
|
11761
11970
|
function newestRecentFile2(dir, pattern) {
|
|
11762
11971
|
try {
|
|
11763
11972
|
const cutoff = Date.now() - RECENT_WINDOW_MS;
|
|
11764
|
-
const entries =
|
|
11973
|
+
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);
|
|
11765
11974
|
return entries[0]?.p ?? null;
|
|
11766
11975
|
} catch {
|
|
11767
11976
|
return null;
|
|
@@ -11769,7 +11978,7 @@ function newestRecentFile2(dir, pattern) {
|
|
|
11769
11978
|
}
|
|
11770
11979
|
function safeMtime(p) {
|
|
11771
11980
|
try {
|
|
11772
|
-
return Math.floor(
|
|
11981
|
+
return Math.floor(fs18.statSync(p).mtimeMs);
|
|
11773
11982
|
} catch {
|
|
11774
11983
|
return 0;
|
|
11775
11984
|
}
|
|
@@ -11781,13 +11990,13 @@ function normalizeRole2(r) {
|
|
|
11781
11990
|
if (s === "tool" || s === "tool_result" || s === "function") return "assistant";
|
|
11782
11991
|
return "system";
|
|
11783
11992
|
}
|
|
11784
|
-
var
|
|
11993
|
+
var fs18, os21, path30, RECENT_WINDOW_MS;
|
|
11785
11994
|
var init_dispatcher = __esm({
|
|
11786
11995
|
"src/providers/native-history/dispatcher.ts"() {
|
|
11787
11996
|
"use strict";
|
|
11788
|
-
|
|
11789
|
-
|
|
11790
|
-
|
|
11997
|
+
fs18 = __toESM(require("fs"));
|
|
11998
|
+
os21 = __toESM(require("os"));
|
|
11999
|
+
path30 = __toESM(require("path"));
|
|
11791
12000
|
init_claude_cli_transcript();
|
|
11792
12001
|
init_codex_cli_transcript();
|
|
11793
12002
|
init_antigravity_cli_transcript();
|
|
@@ -12330,12 +12539,12 @@ function parseSubmoduleStatusOutput(output, repoRoot, ignorePaths) {
|
|
|
12330
12539
|
if (!match) continue;
|
|
12331
12540
|
const prefix = match[1];
|
|
12332
12541
|
const commit = match[2];
|
|
12333
|
-
const
|
|
12334
|
-
if (ignoreSet.has(
|
|
12542
|
+
const path40 = match[3];
|
|
12543
|
+
if (ignoreSet.has(path40)) continue;
|
|
12335
12544
|
submodules.push({
|
|
12336
|
-
path:
|
|
12545
|
+
path: path40,
|
|
12337
12546
|
commit,
|
|
12338
|
-
repoPath: repoRoot + "/" +
|
|
12547
|
+
repoPath: repoRoot + "/" + path40,
|
|
12339
12548
|
dirty: prefix === "+",
|
|
12340
12549
|
outOfSync: prefix === "-",
|
|
12341
12550
|
lastCheckedAt: Date.now()
|
|
@@ -13839,10 +14048,10 @@ function getRegistryPath() {
|
|
|
13839
14048
|
return (0, import_path3.join)(getDaemonDataDir(), "mesh-coordinators.json");
|
|
13840
14049
|
}
|
|
13841
14050
|
function loadMeshCoordinatorRegistry() {
|
|
13842
|
-
const
|
|
13843
|
-
if (!(0, import_fs3.existsSync)(
|
|
14051
|
+
const path40 = getRegistryPath();
|
|
14052
|
+
if (!(0, import_fs3.existsSync)(path40)) return;
|
|
13844
14053
|
try {
|
|
13845
|
-
const raw = JSON.parse((0, import_fs3.readFileSync)(
|
|
14054
|
+
const raw = JSON.parse((0, import_fs3.readFileSync)(path40, "utf-8"));
|
|
13846
14055
|
if (!Array.isArray(raw)) return;
|
|
13847
14056
|
_registry.clear();
|
|
13848
14057
|
for (const entry of raw) {
|
|
@@ -14061,8 +14270,8 @@ function validateMeshRefineConfig(config, source = "inline") {
|
|
|
14061
14270
|
if (rejectedCommands.length) errors.push("one or more validation commands are invalid");
|
|
14062
14271
|
return { valid: errors.length === 0, errors, bootstrapCommands, commands, rejectedCommands };
|
|
14063
14272
|
}
|
|
14064
|
-
function parseConfigText(
|
|
14065
|
-
if (/\.json$/i.test(
|
|
14273
|
+
function parseConfigText(path40, text) {
|
|
14274
|
+
if (/\.json$/i.test(path40)) return JSON.parse(text);
|
|
14066
14275
|
return yaml.load(text);
|
|
14067
14276
|
}
|
|
14068
14277
|
function loadMeshRefineConfig(mesh, workspace) {
|
|
@@ -14073,16 +14282,16 @@ function loadMeshRefineConfig(mesh, workspace) {
|
|
|
14073
14282
|
if (!validation.valid) return { source: "mesh.policy.refineConfig", sourceType: "invalid", error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
|
|
14074
14283
|
return { config: inline, source: "mesh.policy.refineConfig", sourceType: "mesh_policy" };
|
|
14075
14284
|
}
|
|
14076
|
-
for (const
|
|
14077
|
-
const configPath = (0, import_path4.join)(workspace,
|
|
14285
|
+
for (const relative5 of MESH_REFINE_CONFIG_LOCATIONS) {
|
|
14286
|
+
const configPath = (0, import_path4.join)(workspace, relative5);
|
|
14078
14287
|
if (!(0, import_fs4.existsSync)(configPath)) continue;
|
|
14079
14288
|
try {
|
|
14080
14289
|
const parsed = parseConfigText(configPath, (0, import_fs4.readFileSync)(configPath, "utf-8"));
|
|
14081
|
-
const validation = validateMeshRefineConfig(parsed,
|
|
14082
|
-
if (!validation.valid) return { source:
|
|
14083
|
-
return { config: parsed, source:
|
|
14290
|
+
const validation = validateMeshRefineConfig(parsed, relative5);
|
|
14291
|
+
if (!validation.valid) return { source: relative5, sourceType: "invalid", path: configPath, error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
|
|
14292
|
+
return { config: parsed, source: relative5, sourceType: "repo_file", path: configPath };
|
|
14084
14293
|
} catch (error) {
|
|
14085
|
-
return { source:
|
|
14294
|
+
return { source: relative5, sourceType: "invalid", path: configPath, error: error?.message || String(error) };
|
|
14086
14295
|
}
|
|
14087
14296
|
}
|
|
14088
14297
|
return {
|
|
@@ -14215,8 +14424,8 @@ var MESH_WORKTREE_BOOTSTRAP_CONFIG_SCHEMA = {
|
|
|
14215
14424
|
var DEFAULT_TIMEOUT_MS2 = 12e4;
|
|
14216
14425
|
var DEFAULT_OUTPUT_LIMIT_BYTES = 128 * 1024;
|
|
14217
14426
|
var OUTPUT_SUMMARY_CHARS = 2e3;
|
|
14218
|
-
function parseConfigText2(
|
|
14219
|
-
if (/\.json$/i.test(
|
|
14427
|
+
function parseConfigText2(path40, text) {
|
|
14428
|
+
if (/\.json$/i.test(path40)) return JSON.parse(text);
|
|
14220
14429
|
return yaml2.load(text);
|
|
14221
14430
|
}
|
|
14222
14431
|
function truncateOutput(value) {
|
|
@@ -14256,16 +14465,16 @@ function loadMeshWorktreeBootstrapConfig(mesh, workspace) {
|
|
|
14256
14465
|
if (!validation.valid) return { source: "mesh.policy.worktreeBootstrapConfig", sourceType: "invalid", error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
|
|
14257
14466
|
return { config: inline, source: "mesh.policy.worktreeBootstrapConfig", sourceType: "mesh_policy" };
|
|
14258
14467
|
}
|
|
14259
|
-
for (const
|
|
14260
|
-
const configPath = (0, import_path5.join)(workspace,
|
|
14468
|
+
for (const relative5 of MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS) {
|
|
14469
|
+
const configPath = (0, import_path5.join)(workspace, relative5);
|
|
14261
14470
|
if (!(0, import_fs5.existsSync)(configPath)) continue;
|
|
14262
14471
|
try {
|
|
14263
14472
|
const parsed = parseConfigText2(configPath, (0, import_fs5.readFileSync)(configPath, "utf-8"));
|
|
14264
|
-
const validation = validateMeshWorktreeBootstrapConfig(parsed,
|
|
14265
|
-
if (!validation.valid) return { source:
|
|
14266
|
-
return { config: parsed, source:
|
|
14473
|
+
const validation = validateMeshWorktreeBootstrapConfig(parsed, relative5);
|
|
14474
|
+
if (!validation.valid) return { source: relative5, sourceType: "invalid", path: configPath, error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
|
|
14475
|
+
return { config: parsed, source: relative5, sourceType: "repo_file", path: configPath };
|
|
14267
14476
|
} catch (error) {
|
|
14268
|
-
return { source:
|
|
14477
|
+
return { source: relative5, sourceType: "invalid", path: configPath, error: error?.message || String(error) };
|
|
14269
14478
|
}
|
|
14270
14479
|
}
|
|
14271
14480
|
return { source: "unavailable", sourceType: "unavailable", error: `No worktree bootstrap config found. Checked: ${MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS.join(", ")}` };
|
|
@@ -15506,17 +15715,17 @@ function checkPathExists(paths) {
|
|
|
15506
15715
|
return null;
|
|
15507
15716
|
}
|
|
15508
15717
|
async function detectIDEs(providerLoader) {
|
|
15509
|
-
const
|
|
15718
|
+
const os29 = (0, import_os2.platform)();
|
|
15510
15719
|
const results = [];
|
|
15511
15720
|
for (const def of getMergedDefinitions()) {
|
|
15512
15721
|
const cliPath = findCliCommand(providerLoader?.getIdeCliCommand(def.id, def.cli) || def.cli);
|
|
15513
|
-
const appPath = checkPathExists(providerLoader?.getIdePathCandidates(def.id, def.paths[
|
|
15722
|
+
const appPath = checkPathExists(providerLoader?.getIdePathCandidates(def.id, def.paths[os29] || []) || []);
|
|
15514
15723
|
let resolvedCli = cliPath;
|
|
15515
|
-
if (!resolvedCli && appPath &&
|
|
15724
|
+
if (!resolvedCli && appPath && os29 === "darwin") {
|
|
15516
15725
|
const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
|
|
15517
15726
|
if ((0, import_fs11.existsSync)(bundledCli)) resolvedCli = bundledCli;
|
|
15518
15727
|
}
|
|
15519
|
-
if (!resolvedCli && appPath &&
|
|
15728
|
+
if (!resolvedCli && appPath && os29 === "win32") {
|
|
15520
15729
|
const { dirname: dirname11 } = await import("path");
|
|
15521
15730
|
const appDir = dirname11(appPath);
|
|
15522
15731
|
const candidates = [
|
|
@@ -15533,7 +15742,7 @@ async function detectIDEs(providerLoader) {
|
|
|
15533
15742
|
}
|
|
15534
15743
|
}
|
|
15535
15744
|
}
|
|
15536
|
-
const installed =
|
|
15745
|
+
const installed = os29 === "darwin" ? !!(resolvedCli || appPath) : !!resolvedCli;
|
|
15537
15746
|
const version = resolvedCli ? await getIdeVersion(resolvedCli) : null;
|
|
15538
15747
|
results.push({
|
|
15539
15748
|
id: def.id,
|
|
@@ -25915,6 +26124,14 @@ var DaemonCommandHandler = class {
|
|
|
25915
26124
|
return this.handleCheckProviderUpdates(args);
|
|
25916
26125
|
case "list_installed_providers":
|
|
25917
26126
|
return this.handleListInstalledProviders(args);
|
|
26127
|
+
case "add_provider_source":
|
|
26128
|
+
return this.handleAddProviderSource(args);
|
|
26129
|
+
case "remove_provider_source":
|
|
26130
|
+
return this.handleRemoveProviderSource(args);
|
|
26131
|
+
case "list_provider_sources":
|
|
26132
|
+
return this.handleListProviderSources(args);
|
|
26133
|
+
case "set_active_provider_source":
|
|
26134
|
+
return this.handleSetActiveProviderSource(args);
|
|
25918
26135
|
// ─── Stream commands (stream-commands.ts) ───────────
|
|
25919
26136
|
case "select_session":
|
|
25920
26137
|
return handleSelectSession(this, args);
|
|
@@ -25978,49 +26195,62 @@ var DaemonCommandHandler = class {
|
|
|
25978
26195
|
return { success: false, error: "ProviderLoader not initialized" };
|
|
25979
26196
|
}
|
|
25980
26197
|
/**
|
|
25981
|
-
* Return per-provider availability so
|
|
25982
|
-
* "Installed" badges. Reuses the existing detection state from
|
|
26198
|
+
* Return per-provider availability so the dashboard's provider catalog
|
|
26199
|
+
* can show "Installed" badges. Reuses the existing detection state from
|
|
25983
26200
|
* ProviderLoader.getMachineProviderStatus() — no probing is triggered.
|
|
25984
26201
|
*/
|
|
25985
26202
|
handleListProviderAvailability(_args) {
|
|
25986
26203
|
if (!this._ctx.providerLoader) {
|
|
25987
26204
|
return { success: false, error: "ProviderLoader not initialized" };
|
|
25988
26205
|
}
|
|
26206
|
+
const { describeTrust: describeTrust2, requiresConfirmation: requiresConfirmation2 } = (init_provider_trust(), __toCommonJS(provider_trust_exports));
|
|
25989
26207
|
const loader = this._ctx.providerLoader;
|
|
25990
26208
|
const items = loader.getAll().map((provider) => {
|
|
25991
26209
|
const machineConfig = loader.getMachineProviderConfig(provider.type);
|
|
25992
26210
|
const lastDetection = machineConfig.lastDetection;
|
|
26211
|
+
const trust = provider._sourceTrust ?? "trusted";
|
|
26212
|
+
const layer = provider._sourceLayer ?? "upstream";
|
|
26213
|
+
const sourceName = provider._sourceName ?? null;
|
|
25993
26214
|
return {
|
|
25994
26215
|
type: provider.type,
|
|
25995
26216
|
category: provider.category,
|
|
25996
26217
|
status: loader.getMachineProviderStatus(provider.type),
|
|
25997
26218
|
installed: lastDetection?.ok === true,
|
|
25998
26219
|
detectedPath: lastDetection?.path ?? null,
|
|
25999
|
-
checkedAt: lastDetection?.checkedAt ?? null
|
|
26220
|
+
checkedAt: lastDetection?.checkedAt ?? null,
|
|
26221
|
+
trust,
|
|
26222
|
+
trustDescription: describeTrust2(trust),
|
|
26223
|
+
requiresConfirmation: requiresConfirmation2(trust),
|
|
26224
|
+
sourceLayer: layer,
|
|
26225
|
+
sourceName
|
|
26000
26226
|
};
|
|
26001
26227
|
});
|
|
26002
26228
|
return { success: true, providers: items };
|
|
26003
26229
|
}
|
|
26004
26230
|
/**
|
|
26005
|
-
* Compute the *
|
|
26006
|
-
*
|
|
26007
|
-
*
|
|
26008
|
-
*
|
|
26009
|
-
*
|
|
26010
|
-
*
|
|
26231
|
+
* Compute the *upstream cache root*. install_provider_manifest writes
|
|
26232
|
+
* official-registry manifests here so the daemon's standard upstream
|
|
26233
|
+
* layer picks them up — no special handling needed at load time, and
|
|
26234
|
+
* the manifests inherit the official-trust badge instead of the
|
|
26235
|
+
* untrusted-external one.
|
|
26236
|
+
*
|
|
26237
|
+
* Path matches ProviderLoader.upstreamDir but we recompute it from
|
|
26238
|
+
* homedir() so this method stays usable in dev where userDir can
|
|
26239
|
+
* point at a sibling git checkout.
|
|
26011
26240
|
*/
|
|
26012
|
-
|
|
26013
|
-
const
|
|
26014
|
-
const
|
|
26015
|
-
return
|
|
26241
|
+
getUpstreamInstallRoot() {
|
|
26242
|
+
const os29 = require("os");
|
|
26243
|
+
const path40 = require("path");
|
|
26244
|
+
return path40.join(os29.homedir(), ".adhdev", "providers", ".upstream");
|
|
26016
26245
|
}
|
|
26017
26246
|
/**
|
|
26018
26247
|
* Download a single provider manifest from the registry and write it to
|
|
26019
|
-
* ~/.adhdev/
|
|
26248
|
+
* ~/.adhdev/providers/.upstream/{category}/{type}/provider.json.
|
|
26020
26249
|
*
|
|
26021
|
-
* Used by
|
|
26022
|
-
*
|
|
26023
|
-
* the
|
|
26250
|
+
* Used by standalone onboarding to seed the upstream cache with the
|
|
26251
|
+
* default provider set on first launch. Verifies SHA-256 checksum
|
|
26252
|
+
* against the registry meta before persisting. Refuses to write
|
|
26253
|
+
* outside the upstream root.
|
|
26024
26254
|
*
|
|
26025
26255
|
* Args: { type: string, category?: string, version?: string }
|
|
26026
26256
|
* If category/version are omitted, looks up the latest from the registry.
|
|
@@ -26035,8 +26265,8 @@ var DaemonCommandHandler = class {
|
|
|
26035
26265
|
return { success: false, error: "invalid type" };
|
|
26036
26266
|
}
|
|
26037
26267
|
const https = require("https");
|
|
26038
|
-
const
|
|
26039
|
-
const
|
|
26268
|
+
const fs28 = require("fs");
|
|
26269
|
+
const path40 = require("path");
|
|
26040
26270
|
const crypto6 = require("crypto");
|
|
26041
26271
|
const REGISTRY = "https://api.adhf.dev/api/v1/registry";
|
|
26042
26272
|
function fetchText(url, timeoutMs) {
|
|
@@ -26073,13 +26303,13 @@ var DaemonCommandHandler = class {
|
|
|
26073
26303
|
if (actualChecksum !== meta.checksum) {
|
|
26074
26304
|
return { success: false, error: `checksum mismatch: expected ${meta.checksum}, got ${actualChecksum}` };
|
|
26075
26305
|
}
|
|
26076
|
-
const installRoot = this.
|
|
26077
|
-
const installRootResolved =
|
|
26078
|
-
const targetDir =
|
|
26079
|
-
if (!targetDir.startsWith(installRootResolved +
|
|
26080
|
-
return { success: false, error: "install path escaped
|
|
26306
|
+
const installRoot = this.getUpstreamInstallRoot();
|
|
26307
|
+
const installRootResolved = path40.resolve(installRoot);
|
|
26308
|
+
const targetDir = path40.resolve(path40.join(installRoot, category, type));
|
|
26309
|
+
if (!targetDir.startsWith(installRootResolved + path40.sep)) {
|
|
26310
|
+
return { success: false, error: "install path escaped upstream root" };
|
|
26081
26311
|
}
|
|
26082
|
-
|
|
26312
|
+
fs28.mkdirSync(targetDir, { recursive: true });
|
|
26083
26313
|
let manifestProbe = {};
|
|
26084
26314
|
try {
|
|
26085
26315
|
manifestProbe = JSON.parse(manifestBody);
|
|
@@ -26103,8 +26333,8 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26103
26333
|
}
|
|
26104
26334
|
}
|
|
26105
26335
|
const targetFile = isV1 ? "provider.v1.json" : "provider.json";
|
|
26106
|
-
const targetPath =
|
|
26107
|
-
|
|
26336
|
+
const targetPath = path40.join(targetDir, targetFile);
|
|
26337
|
+
fs28.writeFileSync(targetPath, manifestBody, "utf-8");
|
|
26108
26338
|
const manifestJson = JSON.parse(manifestBody);
|
|
26109
26339
|
const scriptFetch = await this.fetchProviderSources(
|
|
26110
26340
|
manifestJson,
|
|
@@ -26152,6 +26382,10 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26152
26382
|
if (Array.isArray(manifest.compatibility)) {
|
|
26153
26383
|
for (const c of manifest.compatibility) {
|
|
26154
26384
|
if (typeof c?.scriptDir === "string") scriptDirs.add(c.scriptDir);
|
|
26385
|
+
if (typeof c?.spec === "string" && c.spec.includes("/")) {
|
|
26386
|
+
const dir = c.spec.substring(0, c.spec.lastIndexOf("/"));
|
|
26387
|
+
if (dir) scriptDirs.add(dir);
|
|
26388
|
+
}
|
|
26155
26389
|
}
|
|
26156
26390
|
}
|
|
26157
26391
|
if (manifest.overrides && typeof manifest.overrides === "object" && !Array.isArray(manifest.overrides)) {
|
|
@@ -26170,8 +26404,8 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26170
26404
|
const repo = source.repo;
|
|
26171
26405
|
const ref = source.ref;
|
|
26172
26406
|
const https = require("https");
|
|
26173
|
-
const
|
|
26174
|
-
const
|
|
26407
|
+
const fs28 = require("fs");
|
|
26408
|
+
const path40 = require("path");
|
|
26175
26409
|
function fetchJson(url, timeoutMs) {
|
|
26176
26410
|
return new Promise((resolve23, reject) => {
|
|
26177
26411
|
const req = https.get(url, {
|
|
@@ -26227,9 +26461,9 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26227
26461
|
}
|
|
26228
26462
|
let fetchedCount = 0;
|
|
26229
26463
|
const sharedDirRel = `${category}/_shared`;
|
|
26230
|
-
const sharedTargetDir =
|
|
26231
|
-
const installRootResolved =
|
|
26232
|
-
if (sharedTargetDir.startsWith(installRootResolved +
|
|
26464
|
+
const sharedTargetDir = path40.resolve(path40.join(targetDir, "../_shared"));
|
|
26465
|
+
const installRootResolved = path40.resolve(path40.join(targetDir, "../.."));
|
|
26466
|
+
if (sharedTargetDir.startsWith(installRootResolved + path40.sep)) {
|
|
26233
26467
|
const sharedStack = [sharedDirRel];
|
|
26234
26468
|
while (sharedStack.length) {
|
|
26235
26469
|
const relDir = sharedStack.pop();
|
|
@@ -26252,10 +26486,10 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26252
26486
|
try {
|
|
26253
26487
|
const body = await fetchBinary(entry.download_url, 3e4);
|
|
26254
26488
|
const relInside = entry.path.startsWith(sharedDirRel + "/") ? entry.path.slice(sharedDirRel.length + 1) : entry.path;
|
|
26255
|
-
const outPath =
|
|
26256
|
-
if (!outPath.startsWith(
|
|
26257
|
-
|
|
26258
|
-
|
|
26489
|
+
const outPath = path40.resolve(path40.join(sharedTargetDir, relInside));
|
|
26490
|
+
if (!outPath.startsWith(path40.resolve(sharedTargetDir) + path40.sep)) continue;
|
|
26491
|
+
fs28.mkdirSync(path40.dirname(outPath), { recursive: true });
|
|
26492
|
+
fs28.writeFileSync(outPath, body);
|
|
26259
26493
|
fetchedCount++;
|
|
26260
26494
|
} catch (e) {
|
|
26261
26495
|
errors.push(`fetch shared ${entry.path}: ${e?.message ?? e}`);
|
|
@@ -26288,13 +26522,13 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26288
26522
|
try {
|
|
26289
26523
|
const body = await fetchBinary(entry.download_url, 3e4);
|
|
26290
26524
|
const relInsideProvider = entry.path.startsWith(subdir + "/") ? entry.path.slice(subdir.length + 1) : entry.path;
|
|
26291
|
-
const outPath =
|
|
26292
|
-
if (!outPath.startsWith(
|
|
26525
|
+
const outPath = path40.resolve(path40.join(targetDir, relInsideProvider));
|
|
26526
|
+
if (!outPath.startsWith(path40.resolve(targetDir) + path40.sep)) {
|
|
26293
26527
|
errors.push(`refusing to write outside targetDir: ${entry.path}`);
|
|
26294
26528
|
continue;
|
|
26295
26529
|
}
|
|
26296
|
-
|
|
26297
|
-
|
|
26530
|
+
fs28.mkdirSync(path40.dirname(outPath), { recursive: true });
|
|
26531
|
+
fs28.writeFileSync(outPath, body);
|
|
26298
26532
|
fetchedCount++;
|
|
26299
26533
|
} catch (e) {
|
|
26300
26534
|
errors.push(`fetch ${entry.path}: ${e?.message ?? e}`);
|
|
@@ -26305,9 +26539,12 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26305
26539
|
return { fetchedCount, source: `${repo}@${ref}`, errors };
|
|
26306
26540
|
}
|
|
26307
26541
|
/**
|
|
26308
|
-
* Remove a provider manifest from the
|
|
26309
|
-
* (~/.adhdev/
|
|
26310
|
-
* outside that root.
|
|
26542
|
+
* Remove a provider manifest from the upstream cache root
|
|
26543
|
+
* (~/.adhdev/providers/.upstream/{category}/{type}/). Refuses to touch
|
|
26544
|
+
* anything outside that root. Used by onboarding to opt out of a
|
|
26545
|
+
* provider the user doesn't want; the dashboard no longer exposes a
|
|
26546
|
+
* per-provider uninstall button (external sources are removed as a
|
|
26547
|
+
* whole via remove_provider_source).
|
|
26311
26548
|
*/
|
|
26312
26549
|
async handleUninstallProviderManifest(args) {
|
|
26313
26550
|
const type = typeof args?.type === "string" ? args.type : "";
|
|
@@ -26319,19 +26556,19 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26319
26556
|
if (!["cli", "ide", "extension", "acp"].includes(category)) {
|
|
26320
26557
|
return { success: false, error: `unknown category: ${category}` };
|
|
26321
26558
|
}
|
|
26322
|
-
const
|
|
26323
|
-
const
|
|
26559
|
+
const fs28 = require("fs");
|
|
26560
|
+
const path40 = require("path");
|
|
26324
26561
|
try {
|
|
26325
|
-
const installRoot = this.
|
|
26326
|
-
const installRootResolved =
|
|
26327
|
-
const targetDir =
|
|
26328
|
-
if (!targetDir.startsWith(installRootResolved +
|
|
26329
|
-
return { success: false, error: "refusing to delete outside
|
|
26562
|
+
const installRoot = this.getUpstreamInstallRoot();
|
|
26563
|
+
const installRootResolved = path40.resolve(installRoot);
|
|
26564
|
+
const targetDir = path40.resolve(path40.join(installRoot, category, type));
|
|
26565
|
+
if (!targetDir.startsWith(installRootResolved + path40.sep)) {
|
|
26566
|
+
return { success: false, error: "refusing to delete outside upstream root" };
|
|
26330
26567
|
}
|
|
26331
|
-
if (!
|
|
26568
|
+
if (!fs28.existsSync(targetDir)) {
|
|
26332
26569
|
return { success: false, error: "not installed" };
|
|
26333
26570
|
}
|
|
26334
|
-
|
|
26571
|
+
fs28.rmSync(targetDir, { recursive: true, force: true });
|
|
26335
26572
|
if (this._ctx.providerLoader) {
|
|
26336
26573
|
this._ctx.providerLoader.reload();
|
|
26337
26574
|
this._ctx.providerLoader.registerToDetector();
|
|
@@ -26342,33 +26579,33 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26342
26579
|
}
|
|
26343
26580
|
}
|
|
26344
26581
|
/**
|
|
26345
|
-
* Return everything currently installed in
|
|
26582
|
+
* Return everything currently installed in the upstream cache with its
|
|
26346
26583
|
* version. This is the "what does this daemon have" answer used both by
|
|
26347
26584
|
* the UI and by the update checker.
|
|
26348
26585
|
*/
|
|
26349
26586
|
handleListInstalledProviders(_args) {
|
|
26350
|
-
const
|
|
26351
|
-
const
|
|
26352
|
-
const installRoot = this.
|
|
26353
|
-
if (!
|
|
26587
|
+
const fs28 = require("fs");
|
|
26588
|
+
const path40 = require("path");
|
|
26589
|
+
const installRoot = this.getUpstreamInstallRoot();
|
|
26590
|
+
if (!fs28.existsSync(installRoot)) return { success: true, providers: [] };
|
|
26354
26591
|
const CATEGORIES = ["cli", "ide", "extension", "acp"];
|
|
26355
26592
|
const items = [];
|
|
26356
26593
|
for (const category of CATEGORIES) {
|
|
26357
|
-
const categoryDir =
|
|
26358
|
-
if (!
|
|
26594
|
+
const categoryDir = path40.join(installRoot, category);
|
|
26595
|
+
if (!fs28.existsSync(categoryDir)) continue;
|
|
26359
26596
|
let entries;
|
|
26360
26597
|
try {
|
|
26361
|
-
entries =
|
|
26598
|
+
entries = fs28.readdirSync(categoryDir);
|
|
26362
26599
|
} catch {
|
|
26363
26600
|
continue;
|
|
26364
26601
|
}
|
|
26365
26602
|
for (const type of entries) {
|
|
26366
|
-
const v1Path =
|
|
26367
|
-
const v0Path =
|
|
26368
|
-
const manifestPath =
|
|
26603
|
+
const v1Path = path40.join(categoryDir, type, "provider.v1.json");
|
|
26604
|
+
const v0Path = path40.join(categoryDir, type, "provider.json");
|
|
26605
|
+
const manifestPath = fs28.existsSync(v1Path) ? v1Path : fs28.existsSync(v0Path) ? v0Path : null;
|
|
26369
26606
|
if (!manifestPath) continue;
|
|
26370
26607
|
try {
|
|
26371
|
-
const m = JSON.parse(
|
|
26608
|
+
const m = JSON.parse(fs28.readFileSync(manifestPath, "utf-8"));
|
|
26372
26609
|
items.push({
|
|
26373
26610
|
type,
|
|
26374
26611
|
category,
|
|
@@ -26445,6 +26682,196 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26445
26682
|
);
|
|
26446
26683
|
return { success: true, providers: checks };
|
|
26447
26684
|
}
|
|
26685
|
+
// ─── External provider sources (3rd-party git URLs) ──────────────
|
|
26686
|
+
/**
|
|
26687
|
+
* Register a new external provider source. The daemon clones the repo
|
|
26688
|
+
* to ~/.adhdev/external/<name>/, walks it once to detect provided
|
|
26689
|
+
* types, and surfaces any conflicts with already-installed types so
|
|
26690
|
+
* the dashboard can ask the user how to resolve them.
|
|
26691
|
+
*
|
|
26692
|
+
* Args: { url: string, ref?: string, name?: string }
|
|
26693
|
+
* - url: https://, git@, or any git-cloneable URL
|
|
26694
|
+
* - ref: branch/tag/commit (default "main")
|
|
26695
|
+
* - name: short identifier (default derived from URL)
|
|
26696
|
+
*
|
|
26697
|
+
* Returns: { source, providers, conflicts }
|
|
26698
|
+
* - conflicts: list of types this new source provides that another
|
|
26699
|
+
* source already exposes. UI uses this to prompt for active-source
|
|
26700
|
+
* selection before the load takes effect.
|
|
26701
|
+
*/
|
|
26702
|
+
async handleAddProviderSource(args) {
|
|
26703
|
+
const url = typeof args?.url === "string" ? args.url.trim() : "";
|
|
26704
|
+
if (!url) return { success: false, error: "url is required" };
|
|
26705
|
+
const ref = typeof args?.ref === "string" && args.ref.trim() ? args.ref.trim() : "main";
|
|
26706
|
+
if (url.startsWith("-")) return { success: false, error: 'url must not start with "-"' };
|
|
26707
|
+
if (ref.startsWith("-")) return { success: false, error: 'ref must not start with "-"' };
|
|
26708
|
+
if (!/^(https?:\/\/|git@[a-z0-9._-]+:)[a-z0-9._@:/~\-]+$/i.test(url)) {
|
|
26709
|
+
return { success: false, error: "url must be https://\u2026 or git@host:\u2026 and contain only URL-safe characters" };
|
|
26710
|
+
}
|
|
26711
|
+
if (!/^[A-Za-z0-9._/-]+$/.test(ref)) {
|
|
26712
|
+
return { success: false, error: "ref must contain only [A-Za-z0-9._/-]" };
|
|
26713
|
+
}
|
|
26714
|
+
const ext = (init_external_sources(), __toCommonJS(external_sources_exports));
|
|
26715
|
+
const requestedName = typeof args?.name === "string" && args.name.trim() ? args.name.trim() : ext.deriveSourceName(url);
|
|
26716
|
+
if (!/^@[a-z0-9_-]+$/i.test(requestedName)) {
|
|
26717
|
+
return { success: false, error: "name must match @[a-z0-9_-]+" };
|
|
26718
|
+
}
|
|
26719
|
+
const fs28 = require("fs");
|
|
26720
|
+
const path40 = require("path");
|
|
26721
|
+
const { spawnSync: spawnSync2 } = require("child_process");
|
|
26722
|
+
const file = ext.loadExternalSources();
|
|
26723
|
+
if (file.sources.some((s) => s.name === requestedName)) {
|
|
26724
|
+
return { success: false, error: `source name "${requestedName}" is already registered` };
|
|
26725
|
+
}
|
|
26726
|
+
if (file.sources.some((s) => s.url === url && s.ref === ref)) {
|
|
26727
|
+
return { success: false, error: `source url+ref already registered (use a different name to track another ref)` };
|
|
26728
|
+
}
|
|
26729
|
+
const sourceDir = path40.join(ext.externalRoot(), requestedName);
|
|
26730
|
+
if (!fs28.existsSync(ext.externalRoot())) fs28.mkdirSync(ext.externalRoot(), { recursive: true });
|
|
26731
|
+
if (fs28.existsSync(sourceDir)) {
|
|
26732
|
+
return { success: false, error: `directory already exists: ${sourceDir} (rename or remove first)` };
|
|
26733
|
+
}
|
|
26734
|
+
const clone = spawnSync2("git", ["clone", "--depth=1", "--branch", ref, "--", url, sourceDir], {
|
|
26735
|
+
encoding: "utf-8",
|
|
26736
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
26737
|
+
timeout: 6e4
|
|
26738
|
+
});
|
|
26739
|
+
if (clone.status !== 0) {
|
|
26740
|
+
try {
|
|
26741
|
+
fs28.rmSync(sourceDir, { recursive: true, force: true });
|
|
26742
|
+
} catch {
|
|
26743
|
+
}
|
|
26744
|
+
return { success: false, error: `git clone failed: ${(clone.stderr || clone.stdout || "").trim() || "unknown error"}` };
|
|
26745
|
+
}
|
|
26746
|
+
const source = {
|
|
26747
|
+
name: requestedName,
|
|
26748
|
+
url,
|
|
26749
|
+
ref,
|
|
26750
|
+
addedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
26751
|
+
};
|
|
26752
|
+
ext.saveExternalSources({ schema: 1, sources: [...file.sources, source] });
|
|
26753
|
+
const inventory = ext.inventoryExternalSources();
|
|
26754
|
+
const conflicts = [];
|
|
26755
|
+
const newEntry = inventory.find((e) => e.sourceName === requestedName);
|
|
26756
|
+
if (newEntry) {
|
|
26757
|
+
for (const [category, types] of Object.entries(newEntry.providers)) {
|
|
26758
|
+
for (const type of types) {
|
|
26759
|
+
const sources = ext.sourcesProviding(category, type);
|
|
26760
|
+
if (sources.length > 1) conflicts.push({ category, type, sources });
|
|
26761
|
+
}
|
|
26762
|
+
}
|
|
26763
|
+
}
|
|
26764
|
+
if (this._ctx.providerLoader) {
|
|
26765
|
+
this._ctx.providerLoader.reload();
|
|
26766
|
+
this._ctx.providerLoader.registerToDetector();
|
|
26767
|
+
}
|
|
26768
|
+
return {
|
|
26769
|
+
success: true,
|
|
26770
|
+
source,
|
|
26771
|
+
providers: newEntry?.providers ?? {},
|
|
26772
|
+
conflicts
|
|
26773
|
+
};
|
|
26774
|
+
}
|
|
26775
|
+
/**
|
|
26776
|
+
* Remove a registered external source. Deletes the clone directory and
|
|
26777
|
+
* any active-source entry pointing to it.
|
|
26778
|
+
*
|
|
26779
|
+
* Args: { name: string }
|
|
26780
|
+
*/
|
|
26781
|
+
async handleRemoveProviderSource(args) {
|
|
26782
|
+
const name = typeof args?.name === "string" ? args.name.trim() : "";
|
|
26783
|
+
if (!name) return { success: false, error: "name is required" };
|
|
26784
|
+
const ext = (init_external_sources(), __toCommonJS(external_sources_exports));
|
|
26785
|
+
const fs28 = require("fs");
|
|
26786
|
+
const path40 = require("path");
|
|
26787
|
+
const file = ext.loadExternalSources();
|
|
26788
|
+
const match = file.sources.find((s) => s.name === name);
|
|
26789
|
+
if (!match) return { success: false, error: `source "${name}" not registered` };
|
|
26790
|
+
const sourceDir = path40.join(ext.externalRoot(), name);
|
|
26791
|
+
if (fs28.existsSync(sourceDir)) {
|
|
26792
|
+
try {
|
|
26793
|
+
fs28.rmSync(sourceDir, { recursive: true, force: true });
|
|
26794
|
+
} catch (e) {
|
|
26795
|
+
return { success: false, error: `failed to delete ${sourceDir}: ${e?.message || e}` };
|
|
26796
|
+
}
|
|
26797
|
+
}
|
|
26798
|
+
ext.saveExternalSources({
|
|
26799
|
+
schema: 1,
|
|
26800
|
+
sources: file.sources.filter((s) => s.name !== name)
|
|
26801
|
+
});
|
|
26802
|
+
const active = ext.loadProvidersActive();
|
|
26803
|
+
const filteredActive = {};
|
|
26804
|
+
for (const [type, src] of Object.entries(active.active)) {
|
|
26805
|
+
if (src !== name) filteredActive[type] = src;
|
|
26806
|
+
}
|
|
26807
|
+
ext.saveProvidersActive({ schema: 1, active: filteredActive });
|
|
26808
|
+
if (this._ctx.providerLoader) {
|
|
26809
|
+
this._ctx.providerLoader.reload();
|
|
26810
|
+
this._ctx.providerLoader.registerToDetector();
|
|
26811
|
+
}
|
|
26812
|
+
return { success: true, removed: { name } };
|
|
26813
|
+
}
|
|
26814
|
+
/**
|
|
26815
|
+
* List registered external sources + each source's currently installed
|
|
26816
|
+
* providers + the active selection for any conflicting types. Used by
|
|
26817
|
+
* the dashboard's "Sources" tab.
|
|
26818
|
+
*/
|
|
26819
|
+
handleListProviderSources(_args) {
|
|
26820
|
+
const ext = (init_external_sources(), __toCommonJS(external_sources_exports));
|
|
26821
|
+
const file = ext.loadExternalSources();
|
|
26822
|
+
const inventory = ext.inventoryExternalSources();
|
|
26823
|
+
const active = ext.loadProvidersActive();
|
|
26824
|
+
const sources = file.sources.map((s) => {
|
|
26825
|
+
const inv = inventory.find((e) => e.sourceName === s.name);
|
|
26826
|
+
return {
|
|
26827
|
+
...s,
|
|
26828
|
+
providers: inv?.providers ?? {}
|
|
26829
|
+
};
|
|
26830
|
+
});
|
|
26831
|
+
const conflictMap = /* @__PURE__ */ new Map();
|
|
26832
|
+
for (const inv of inventory) {
|
|
26833
|
+
for (const [category, types] of Object.entries(inv.providers)) {
|
|
26834
|
+
for (const type of types) {
|
|
26835
|
+
const candidates = ext.sourcesProviding(category, type);
|
|
26836
|
+
if (candidates.length > 1 && !conflictMap.has(type)) {
|
|
26837
|
+
conflictMap.set(type, { category, sources: candidates });
|
|
26838
|
+
}
|
|
26839
|
+
}
|
|
26840
|
+
}
|
|
26841
|
+
}
|
|
26842
|
+
const conflicts = [...conflictMap.entries()].map(([type, info]) => ({
|
|
26843
|
+
type,
|
|
26844
|
+
category: info.category,
|
|
26845
|
+
candidates: info.sources,
|
|
26846
|
+
active: active.active[type] ?? null
|
|
26847
|
+
}));
|
|
26848
|
+
return { success: true, sources, conflicts };
|
|
26849
|
+
}
|
|
26850
|
+
/**
|
|
26851
|
+
* Pick which source's copy of a conflicting provider type is active.
|
|
26852
|
+
* Other sources' copies stay on disk but the loader ignores them.
|
|
26853
|
+
*
|
|
26854
|
+
* Args: { type: string, sourceName: string }
|
|
26855
|
+
*/
|
|
26856
|
+
handleSetActiveProviderSource(args) {
|
|
26857
|
+
const type = typeof args?.type === "string" ? args.type.trim() : "";
|
|
26858
|
+
const sourceName = typeof args?.sourceName === "string" ? args.sourceName.trim() : "";
|
|
26859
|
+
if (!type || !sourceName) return { success: false, error: "type and sourceName are required" };
|
|
26860
|
+
const ext = (init_external_sources(), __toCommonJS(external_sources_exports));
|
|
26861
|
+
const inventory = ext.inventoryExternalSources();
|
|
26862
|
+
const entry = inventory.find((e) => e.sourceName === sourceName);
|
|
26863
|
+
if (!entry) return { success: false, error: `source "${sourceName}" not found` };
|
|
26864
|
+
const provided = Object.values(entry.providers).some((types) => types.includes(type));
|
|
26865
|
+
if (!provided) return { success: false, error: `source "${sourceName}" does not provide type "${type}"` };
|
|
26866
|
+
const active = ext.loadProvidersActive();
|
|
26867
|
+
active.active[type] = sourceName;
|
|
26868
|
+
ext.saveProvidersActive(active);
|
|
26869
|
+
if (this._ctx.providerLoader) {
|
|
26870
|
+
this._ctx.providerLoader.reload();
|
|
26871
|
+
this._ctx.providerLoader.registerToDetector();
|
|
26872
|
+
}
|
|
26873
|
+
return { success: true, type, sourceName };
|
|
26874
|
+
}
|
|
26448
26875
|
// ─── DevServer HTTP proxy helpers ─────────────────
|
|
26449
26876
|
// These bridge WS commands to the DevServer REST API (localhost:19280)
|
|
26450
26877
|
async proxyDevServerPost(args, endpoint) {
|
|
@@ -26537,8 +26964,8 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26537
26964
|
};
|
|
26538
26965
|
|
|
26539
26966
|
// src/commands/cli-manager.ts
|
|
26540
|
-
var
|
|
26541
|
-
var
|
|
26967
|
+
var os17 = __toESM(require("os"));
|
|
26968
|
+
var path23 = __toESM(require("path"));
|
|
26542
26969
|
var crypto5 = __toESM(require("crypto"));
|
|
26543
26970
|
var import_fs12 = require("fs");
|
|
26544
26971
|
var import_child_process5 = require("child_process");
|
|
@@ -26548,21 +26975,21 @@ init_cli_detector();
|
|
|
26548
26975
|
init_config();
|
|
26549
26976
|
|
|
26550
26977
|
// src/providers/cli-provider-instance.ts
|
|
26551
|
-
var
|
|
26552
|
-
var
|
|
26978
|
+
var os16 = __toESM(require("os"));
|
|
26979
|
+
var path21 = __toESM(require("path"));
|
|
26553
26980
|
var crypto4 = __toESM(require("crypto"));
|
|
26554
|
-
var
|
|
26981
|
+
var fs12 = __toESM(require("fs"));
|
|
26555
26982
|
var import_node_module = require("module");
|
|
26556
26983
|
|
|
26557
26984
|
// src/providers/spec/route.ts
|
|
26558
|
-
var
|
|
26559
|
-
var
|
|
26985
|
+
var fs11 = __toESM(require("fs"));
|
|
26986
|
+
var path20 = __toESM(require("path"));
|
|
26560
26987
|
init_provider_cli_adapter();
|
|
26561
26988
|
|
|
26562
26989
|
// src/providers/spec/driver.ts
|
|
26563
|
-
var
|
|
26564
|
-
var
|
|
26565
|
-
var
|
|
26990
|
+
var fs10 = __toESM(require("fs"));
|
|
26991
|
+
var os15 = __toESM(require("os"));
|
|
26992
|
+
var path19 = __toESM(require("path"));
|
|
26566
26993
|
|
|
26567
26994
|
// src/providers/spec/adapter.ts
|
|
26568
26995
|
var xtermHeadlessNs = __toESM(require("@xterm/headless"));
|
|
@@ -26939,7 +27366,7 @@ var SpecDriver = class {
|
|
|
26939
27366
|
}
|
|
26940
27367
|
armSpecWatcher() {
|
|
26941
27368
|
try {
|
|
26942
|
-
this.specWatcher =
|
|
27369
|
+
this.specWatcher = fs10.watch(this.opts.specPath, { persistent: false }, () => {
|
|
26943
27370
|
const res = loadSpec(this.opts.specPath);
|
|
26944
27371
|
if (!res.ok) {
|
|
26945
27372
|
this.emit({ kind: "spec_error", errors: res.errors });
|
|
@@ -27032,7 +27459,7 @@ var SpecDriver = class {
|
|
|
27032
27459
|
}
|
|
27033
27460
|
fireDelegate(d) {
|
|
27034
27461
|
const ev = this.currentEval;
|
|
27035
|
-
const task = d.task_template.replace(/\{node\}/g,
|
|
27462
|
+
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));
|
|
27036
27463
|
this.emit({ kind: "delegate", id: d.id, task });
|
|
27037
27464
|
}
|
|
27038
27465
|
// ────────────────────────────────────────────────────────────────────
|
|
@@ -27101,9 +27528,9 @@ var SpecDriver = class {
|
|
|
27101
27528
|
const ctl = (this.spec.control_bar ?? []).find((c) => c.action.type === "attach_image");
|
|
27102
27529
|
if (!ctl || ctl.action.type !== "attach_image") return;
|
|
27103
27530
|
const ext = guessExt(mime);
|
|
27104
|
-
const tmp =
|
|
27531
|
+
const tmp = path19.join(os15.tmpdir(), `adhdev-attach-${Date.now()}${ext}`);
|
|
27105
27532
|
try {
|
|
27106
|
-
|
|
27533
|
+
fs10.writeFileSync(tmp, Buffer.from(blob, "base64"));
|
|
27107
27534
|
} catch {
|
|
27108
27535
|
return;
|
|
27109
27536
|
}
|
|
@@ -27172,6 +27599,15 @@ var SpecCliAdapter = class {
|
|
|
27172
27599
|
cliType;
|
|
27173
27600
|
cliName;
|
|
27174
27601
|
workingDir;
|
|
27602
|
+
/**
|
|
27603
|
+
* Marker the daemon's finalization gate checks: `getStatus()` returns
|
|
27604
|
+
* `messages: []` by design here (chat history lives in the daemon's
|
|
27605
|
+
* native-history pipeline, not the adapter). Without this flag,
|
|
27606
|
+
* cli-provider-instance's `missing_final_assistant` gate would stall
|
|
27607
|
+
* every turn until the 30s safety timeout because it expects the
|
|
27608
|
+
* adapter to surface the final assistant message.
|
|
27609
|
+
*/
|
|
27610
|
+
chatMessagesOwnedExternally = true;
|
|
27175
27611
|
driver;
|
|
27176
27612
|
spec;
|
|
27177
27613
|
lastEvent = null;
|
|
@@ -27422,14 +27858,14 @@ init_logger();
|
|
|
27422
27858
|
function createCliAdapter(provider, workingDir, cliArgs, extraEnv, transportFactory) {
|
|
27423
27859
|
const resolvedSpecPath = provider._resolvedSpecPath;
|
|
27424
27860
|
const dir = provider._resolvedProviderDir;
|
|
27425
|
-
let specPath = resolvedSpecPath &&
|
|
27861
|
+
let specPath = resolvedSpecPath && fs11.existsSync(resolvedSpecPath) ? resolvedSpecPath : void 0;
|
|
27426
27862
|
if (!specPath && dir) {
|
|
27427
|
-
const legacy =
|
|
27428
|
-
if (
|
|
27863
|
+
const legacy = path20.join(dir, "spec.json");
|
|
27864
|
+
if (fs11.existsSync(legacy)) specPath = legacy;
|
|
27429
27865
|
}
|
|
27430
27866
|
if (specPath) {
|
|
27431
27867
|
try {
|
|
27432
|
-
LOG.info("spec-route", `[${provider.type}] routing through SpecCliAdapter (${
|
|
27868
|
+
LOG.info("spec-route", `[${provider.type}] routing through SpecCliAdapter (${path20.relative(dir || "", specPath) || specPath})`);
|
|
27433
27869
|
return new SpecCliAdapter(specPath, workingDir, cliArgs, extraEnv, transportFactory);
|
|
27434
27870
|
} catch (err) {
|
|
27435
27871
|
LOG.warn("spec-route", `[${provider.type}] spec invalid, falling back to ProviderCliAdapter: ${err.message}`);
|
|
@@ -27490,7 +27926,7 @@ function filePathFromUri(uri) {
|
|
|
27490
27926
|
return uri.slice("file://".length);
|
|
27491
27927
|
}
|
|
27492
27928
|
}
|
|
27493
|
-
if (
|
|
27929
|
+
if (path21.isAbsolute(uri)) return uri;
|
|
27494
27930
|
return null;
|
|
27495
27931
|
}
|
|
27496
27932
|
function extensionForImageMime(mimeType) {
|
|
@@ -27505,9 +27941,9 @@ function materializeImageDataPart(part, index, dir) {
|
|
|
27505
27941
|
if (!part.data) return null;
|
|
27506
27942
|
const rawData = part.data.includes(",") ? part.data.split(",").pop() || "" : part.data;
|
|
27507
27943
|
if (!rawData) return null;
|
|
27508
|
-
|
|
27509
|
-
const filePath =
|
|
27510
|
-
|
|
27944
|
+
fs12.mkdirSync(dir, { recursive: true });
|
|
27945
|
+
const filePath = path21.join(dir, safeInputImageBasename(index, part.mimeType));
|
|
27946
|
+
fs12.writeFileSync(filePath, Buffer.from(rawData, "base64"));
|
|
27511
27947
|
cleanupStaleMaterializedImages(dir);
|
|
27512
27948
|
return filePath;
|
|
27513
27949
|
}
|
|
@@ -27519,14 +27955,14 @@ function cleanupStaleMaterializedImages(dir) {
|
|
|
27519
27955
|
if (now - lastMaterializedImageCleanupAt < MATERIALIZED_IMAGE_CLEANUP_INTERVAL_MS) return;
|
|
27520
27956
|
lastMaterializedImageCleanupAt = now;
|
|
27521
27957
|
try {
|
|
27522
|
-
const entries =
|
|
27958
|
+
const entries = fs12.readdirSync(dir);
|
|
27523
27959
|
for (const entry of entries) {
|
|
27524
27960
|
if (!entry.startsWith("adhdev-input-image-")) continue;
|
|
27525
|
-
const fullPath =
|
|
27961
|
+
const fullPath = path21.join(dir, entry);
|
|
27526
27962
|
try {
|
|
27527
|
-
const stat2 =
|
|
27963
|
+
const stat2 = fs12.statSync(fullPath);
|
|
27528
27964
|
if (now - stat2.mtimeMs > MATERIALIZED_IMAGE_MAX_AGE_MS) {
|
|
27529
|
-
|
|
27965
|
+
fs12.unlinkSync(fullPath);
|
|
27530
27966
|
}
|
|
27531
27967
|
} catch {
|
|
27532
27968
|
}
|
|
@@ -27545,7 +27981,7 @@ function buildCliStructuredInputPrompt(input, options = {}) {
|
|
|
27545
27981
|
const promptParts = [];
|
|
27546
27982
|
const imageRefs = [];
|
|
27547
27983
|
const resourceRefs = [];
|
|
27548
|
-
const materializeDir = options.materializeDir ||
|
|
27984
|
+
const materializeDir = options.materializeDir || path21.join(os16.tmpdir(), "adhdev-input-media");
|
|
27549
27985
|
input.parts.forEach((part, index) => {
|
|
27550
27986
|
if (part.type === "text" && part.text.trim()) {
|
|
27551
27987
|
promptParts.push(part.text.trim());
|
|
@@ -27612,7 +28048,7 @@ function buildIncrementalHistoryAppendMessages(previousMessages, currentMessages
|
|
|
27612
28048
|
var CachedDatabaseSync = null;
|
|
27613
28049
|
function getDatabaseSync() {
|
|
27614
28050
|
if (CachedDatabaseSync) return CachedDatabaseSync;
|
|
27615
|
-
const requireFn = typeof require === "function" ? require : (0, import_node_module.createRequire)(
|
|
28051
|
+
const requireFn = typeof require === "function" ? require : (0, import_node_module.createRequire)(path21.join(process.cwd(), "__adhdev_sqlite_loader__.js"));
|
|
27616
28052
|
const sqliteModule = requireFn(`node:${"sqlite"}`);
|
|
27617
28053
|
CachedDatabaseSync = sqliteModule.DatabaseSync;
|
|
27618
28054
|
if (!CachedDatabaseSync) {
|
|
@@ -27766,10 +28202,10 @@ var CliProviderInstance = class {
|
|
|
27766
28202
|
* Replaces the previously duplicated probeOpenCode/Codex/Goose functions.
|
|
27767
28203
|
*/
|
|
27768
28204
|
probeSessionIdFromConfig(probe) {
|
|
27769
|
-
const resolvedDbPath = probe.dbPath.replace(/^~/,
|
|
28205
|
+
const resolvedDbPath = probe.dbPath.replace(/^~/, os16.homedir());
|
|
27770
28206
|
const now = Date.now();
|
|
27771
28207
|
if (this.cachedSqliteDbMissingUntil > now) return null;
|
|
27772
|
-
if (!
|
|
28208
|
+
if (!fs12.existsSync(resolvedDbPath)) {
|
|
27773
28209
|
this.cachedSqliteDbMissingUntil = now + 1e4;
|
|
27774
28210
|
return null;
|
|
27775
28211
|
}
|
|
@@ -28155,7 +28591,10 @@ var CliProviderInstance = class {
|
|
|
28155
28591
|
return { reason: `parsed_status:${parsedStatus}`, terminal: isCliGeneratingLikeStatus(parsedStatus) };
|
|
28156
28592
|
}
|
|
28157
28593
|
if (parsed?.activeModal || parsed?.modal) return { reason: "parsed_modal_active", terminal: true };
|
|
28158
|
-
|
|
28594
|
+
const adapterOwnsMessagesElsewhere = this.adapter?.chatMessagesOwnedExternally === true;
|
|
28595
|
+
if (!adapterOwnsMessagesElsewhere && !this.completionHasFinalAssistantMessage(parsed?.messages)) {
|
|
28596
|
+
return { reason: "missing_final_assistant" };
|
|
28597
|
+
}
|
|
28159
28598
|
try {
|
|
28160
28599
|
const screenText = typeof this.adapter.getScreenText === "function" ? String(this.adapter.getScreenText() || "") : "";
|
|
28161
28600
|
if (screenText) {
|
|
@@ -28868,7 +29307,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
28868
29307
|
};
|
|
28869
29308
|
addDir(this.workingDir);
|
|
28870
29309
|
try {
|
|
28871
|
-
addDir(
|
|
29310
|
+
addDir(fs12.realpathSync.native(this.workingDir));
|
|
28872
29311
|
} catch {
|
|
28873
29312
|
}
|
|
28874
29313
|
return Array.from(dirs);
|
|
@@ -28905,7 +29344,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
28905
29344
|
};
|
|
28906
29345
|
|
|
28907
29346
|
// src/providers/acp-provider-instance.ts
|
|
28908
|
-
var
|
|
29347
|
+
var path22 = __toESM(require("path"));
|
|
28909
29348
|
var import_stream = require("stream");
|
|
28910
29349
|
var import_child_process4 = require("child_process");
|
|
28911
29350
|
var import_sdk = require("@agentclientprotocol/sdk");
|
|
@@ -29680,7 +30119,7 @@ var AcpProviderInstance = class {
|
|
|
29680
30119
|
return b.uri ? {
|
|
29681
30120
|
type: "resource_link",
|
|
29682
30121
|
uri: b.uri,
|
|
29683
|
-
name:
|
|
30122
|
+
name: path22.basename(b.uri),
|
|
29684
30123
|
mimeType: b.mimeType,
|
|
29685
30124
|
...b.transcript ? { description: b.transcript } : {}
|
|
29686
30125
|
} : { type: "text", text: b.transcript || `[Video attachment: ${b.mimeType}]` };
|
|
@@ -30138,11 +30577,11 @@ function shouldRestoreHostedRuntime(record, managerTag) {
|
|
|
30138
30577
|
// src/commands/cli-manager.ts
|
|
30139
30578
|
function isExplicitCommand(command) {
|
|
30140
30579
|
const trimmed = command.trim();
|
|
30141
|
-
return
|
|
30580
|
+
return path23.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
|
|
30142
30581
|
}
|
|
30143
30582
|
function expandExecutable(command) {
|
|
30144
30583
|
const trimmed = command.trim();
|
|
30145
|
-
return trimmed.startsWith("~") ?
|
|
30584
|
+
return trimmed.startsWith("~") ? path23.join(os17.homedir(), trimmed.slice(1)) : trimmed;
|
|
30146
30585
|
}
|
|
30147
30586
|
function commandExists(command) {
|
|
30148
30587
|
const trimmed = command.trim();
|
|
@@ -30269,10 +30708,10 @@ function hasCliArg(args, flag) {
|
|
|
30269
30708
|
return args.some((arg) => arg === flag || arg.startsWith(`${flag}=`));
|
|
30270
30709
|
}
|
|
30271
30710
|
function ensureEmptyDelegatedMcpConfig(workspace) {
|
|
30272
|
-
const baseDir =
|
|
30711
|
+
const baseDir = path23.join(os17.tmpdir(), "adhdev-delegated-agent-empty-mcp");
|
|
30273
30712
|
(0, import_fs12.mkdirSync)(baseDir, { recursive: true });
|
|
30274
|
-
const workspaceHash = crypto5.createHash("sha256").update(
|
|
30275
|
-
const filePath =
|
|
30713
|
+
const workspaceHash = crypto5.createHash("sha256").update(path23.resolve(workspace || os17.tmpdir())).digest("hex").slice(0, 16);
|
|
30714
|
+
const filePath = path23.join(baseDir, `${workspaceHash}.json`);
|
|
30276
30715
|
(0, import_fs12.writeFileSync)(filePath, JSON.stringify({ mcpServers: {} }, null, 2), "utf-8");
|
|
30277
30716
|
return filePath;
|
|
30278
30717
|
}
|
|
@@ -30566,7 +31005,7 @@ var DaemonCliManager = class {
|
|
|
30566
31005
|
async startSession(cliType, workingDir, cliArgs, initialModel, options) {
|
|
30567
31006
|
const trimmed = (workingDir || "").trim();
|
|
30568
31007
|
if (!trimmed) throw new Error("working directory required");
|
|
30569
|
-
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/,
|
|
31008
|
+
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os17.homedir()) : path23.resolve(trimmed);
|
|
30570
31009
|
const normalizedType = this.providerLoader.resolveAlias(cliType);
|
|
30571
31010
|
const rawProvider = this.providerLoader.getByAlias(cliType);
|
|
30572
31011
|
const provider = rawProvider ? this.providerLoader.resolve(normalizedType) || rawProvider : void 0;
|
|
@@ -30951,6 +31390,20 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
30951
31390
|
cliArgs: args?.cliArgs,
|
|
30952
31391
|
env: args?.env
|
|
30953
31392
|
}) : null;
|
|
31393
|
+
const provLookup = this.providerLoader.getMeta(this.providerLoader.resolveAlias(cliType));
|
|
31394
|
+
const provTrust = provLookup?._sourceTrust;
|
|
31395
|
+
if (provTrust === "external-untrusted" && args?.confirmExternalUntrusted !== true) {
|
|
31396
|
+
return {
|
|
31397
|
+
success: false,
|
|
31398
|
+
error: "untrusted_external_provider",
|
|
31399
|
+
provider: {
|
|
31400
|
+
type: provLookup?.type ?? cliType,
|
|
31401
|
+
sourceName: provLookup?._sourceName ?? null,
|
|
31402
|
+
trust: provTrust
|
|
31403
|
+
},
|
|
31404
|
+
hint: "Resend launch_cli with confirmExternalUntrusted=true after the user explicitly approves running JavaScript from this 3rd-party source."
|
|
31405
|
+
};
|
|
31406
|
+
}
|
|
30954
31407
|
const started = await this.startSession(
|
|
30955
31408
|
cliType,
|
|
30956
31409
|
dir,
|
|
@@ -31137,13 +31590,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
31137
31590
|
// src/launch.ts
|
|
31138
31591
|
var import_child_process6 = require("child_process");
|
|
31139
31592
|
var net = __toESM(require("net"));
|
|
31140
|
-
var
|
|
31141
|
-
var
|
|
31593
|
+
var os23 = __toESM(require("os"));
|
|
31594
|
+
var path32 = __toESM(require("path"));
|
|
31142
31595
|
|
|
31143
31596
|
// src/providers/provider-loader.ts
|
|
31144
|
-
var
|
|
31145
|
-
var
|
|
31146
|
-
var
|
|
31597
|
+
var fs19 = __toESM(require("fs"));
|
|
31598
|
+
var path31 = __toESM(require("path"));
|
|
31599
|
+
var os22 = __toESM(require("os"));
|
|
31147
31600
|
var chokidar = __toESM(require("chokidar"));
|
|
31148
31601
|
init_logger();
|
|
31149
31602
|
|
|
@@ -31516,9 +31969,9 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31516
31969
|
static siblingStderrLogged = /* @__PURE__ */ new Set();
|
|
31517
31970
|
static looksLikeProviderRoot(candidate) {
|
|
31518
31971
|
try {
|
|
31519
|
-
if (!
|
|
31972
|
+
if (!fs19.existsSync(candidate) || !fs19.statSync(candidate).isDirectory()) return false;
|
|
31520
31973
|
return ["ide", "extension", "cli", "acp"].some(
|
|
31521
|
-
(category) =>
|
|
31974
|
+
(category) => fs19.existsSync(path31.join(candidate, category))
|
|
31522
31975
|
);
|
|
31523
31976
|
} catch {
|
|
31524
31977
|
return false;
|
|
@@ -31526,20 +31979,20 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31526
31979
|
}
|
|
31527
31980
|
static hasProviderRootMarker(candidate) {
|
|
31528
31981
|
try {
|
|
31529
|
-
return
|
|
31982
|
+
return fs19.existsSync(path31.join(candidate, _ProviderLoader.SIBLING_MARKER_FILE));
|
|
31530
31983
|
} catch {
|
|
31531
31984
|
return false;
|
|
31532
31985
|
}
|
|
31533
31986
|
}
|
|
31534
31987
|
detectDefaultUserDir() {
|
|
31535
|
-
const fallback =
|
|
31988
|
+
const fallback = path31.join(os22.homedir(), ".adhdev", "providers");
|
|
31536
31989
|
const envOptIn = process.env[_ProviderLoader.SIBLING_ENV_VAR] === "1";
|
|
31537
31990
|
const visited = /* @__PURE__ */ new Set();
|
|
31538
31991
|
for (const start of this.probeStarts) {
|
|
31539
|
-
let current =
|
|
31992
|
+
let current = path31.resolve(start);
|
|
31540
31993
|
while (!visited.has(current)) {
|
|
31541
31994
|
visited.add(current);
|
|
31542
|
-
const siblingCandidate =
|
|
31995
|
+
const siblingCandidate = path31.join(path31.dirname(current), _ProviderLoader.REPO_PROVIDER_DIRNAME);
|
|
31543
31996
|
if (_ProviderLoader.looksLikeProviderRoot(siblingCandidate)) {
|
|
31544
31997
|
const hasMarker = _ProviderLoader.hasProviderRootMarker(siblingCandidate);
|
|
31545
31998
|
if (envOptIn || hasMarker) {
|
|
@@ -31561,7 +32014,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31561
32014
|
return { path: siblingCandidate, source };
|
|
31562
32015
|
}
|
|
31563
32016
|
}
|
|
31564
|
-
const parent =
|
|
32017
|
+
const parent = path31.dirname(current);
|
|
31565
32018
|
if (parent === current) break;
|
|
31566
32019
|
current = parent;
|
|
31567
32020
|
}
|
|
@@ -31571,17 +32024,34 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31571
32024
|
constructor(options) {
|
|
31572
32025
|
this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
|
|
31573
32026
|
this.probeStarts = options?.probeStarts ?? [process.cwd(), __dirname];
|
|
31574
|
-
this.defaultProvidersDir =
|
|
32027
|
+
this.defaultProvidersDir = path31.join(os22.homedir(), ".adhdev", "providers");
|
|
31575
32028
|
const detected = this.detectDefaultUserDir();
|
|
31576
32029
|
this.userDir = detected.path;
|
|
31577
32030
|
this.userDirSource = detected.source;
|
|
31578
|
-
this.upstreamDir =
|
|
32031
|
+
this.upstreamDir = path31.join(this.defaultProvidersDir, ".upstream");
|
|
31579
32032
|
this.disableUpstream = false;
|
|
31580
32033
|
this.applySourceConfig({
|
|
31581
32034
|
userDir: options?.userDir,
|
|
31582
32035
|
sourceMode: options?.sourceMode,
|
|
31583
32036
|
disableUpstream: options?.disableUpstream
|
|
31584
32037
|
});
|
|
32038
|
+
this.migrateMarketplaceDirToExternal();
|
|
32039
|
+
}
|
|
32040
|
+
migrateMarketplaceDirToExternal() {
|
|
32041
|
+
try {
|
|
32042
|
+
const home = os22.homedir();
|
|
32043
|
+
const oldDir = path31.join(home, ".adhdev", "marketplace");
|
|
32044
|
+
const newDir = path31.join(home, ".adhdev", "external");
|
|
32045
|
+
if (!fs19.existsSync(oldDir)) return;
|
|
32046
|
+
if (fs19.existsSync(newDir)) {
|
|
32047
|
+
this.log(`Migration skipped: both ~/.adhdev/marketplace and ~/.adhdev/external exist (marketplace dir is now inert and can be removed manually).`);
|
|
32048
|
+
return;
|
|
32049
|
+
}
|
|
32050
|
+
fs19.renameSync(oldDir, newDir);
|
|
32051
|
+
this.log(`Migrated ~/.adhdev/marketplace \u2192 ~/.adhdev/external (one-time rename after provider source-layer cleanup).`);
|
|
32052
|
+
} catch (e) {
|
|
32053
|
+
this.log(`Marketplace\u2192external migration failed: ${e?.message || e}`);
|
|
32054
|
+
}
|
|
31585
32055
|
}
|
|
31586
32056
|
log(msg) {
|
|
31587
32057
|
this.logFn(`[ProviderLoader] ${msg}`);
|
|
@@ -31607,8 +32077,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31607
32077
|
* Highest-priority editable overrides come first.
|
|
31608
32078
|
*/
|
|
31609
32079
|
getProviderRoots() {
|
|
31610
|
-
const
|
|
31611
|
-
return [this.userDir,
|
|
32080
|
+
const externalDir = path31.join(os22.homedir(), ".adhdev", "external");
|
|
32081
|
+
return [this.userDir, externalDir, this.upstreamDir];
|
|
31612
32082
|
}
|
|
31613
32083
|
getSourceConfig() {
|
|
31614
32084
|
return {
|
|
@@ -31635,7 +32105,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31635
32105
|
this.userDir = detected.path;
|
|
31636
32106
|
this.userDirSource = detected.source;
|
|
31637
32107
|
}
|
|
31638
|
-
this.upstreamDir =
|
|
32108
|
+
this.upstreamDir = path31.join(this.defaultProvidersDir, ".upstream");
|
|
31639
32109
|
this.disableUpstream = this.sourceMode === "no-upstream";
|
|
31640
32110
|
if (this.explicitProviderDir) {
|
|
31641
32111
|
this.log(`Config 'providerDir' applied: ${this.userDir}`);
|
|
@@ -31649,7 +32119,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31649
32119
|
* Canonical provider directory shape for a given root.
|
|
31650
32120
|
*/
|
|
31651
32121
|
getProviderDir(root, category, type) {
|
|
31652
|
-
return
|
|
32122
|
+
return path31.join(root, category, type);
|
|
31653
32123
|
}
|
|
31654
32124
|
/**
|
|
31655
32125
|
* Canonical user override directory for a provider.
|
|
@@ -31676,20 +32146,23 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31676
32146
|
resolveProviderFile(type, ...segments) {
|
|
31677
32147
|
const dir = this.findProviderDirInternal(type);
|
|
31678
32148
|
if (!dir) return null;
|
|
31679
|
-
return
|
|
32149
|
+
return path31.join(dir, ...segments);
|
|
31680
32150
|
}
|
|
31681
32151
|
/**
|
|
31682
32152
|
* Load all providers (3-tier priority)
|
|
31683
|
-
* 1.
|
|
31684
|
-
* 2.
|
|
31685
|
-
*
|
|
32153
|
+
* 1. ~/.adhdev/providers/.upstream/ — official git, auto-synced
|
|
32154
|
+
* 2. ~/.adhdev/external/ — 3rd-party git sources, user-added,
|
|
32155
|
+
* bundled providers may include arbitrary JS (untrusted by default)
|
|
32156
|
+
* 3. ~/.adhdev/providers/ (excluding .upstream) — user-authored customs,
|
|
32157
|
+
* always wins
|
|
32158
|
+
* Highest priority listed last (overwrites earlier loads).
|
|
31686
32159
|
* If .upstream/ is empty, call fetchLatest() before loadAll().
|
|
31687
32160
|
*/
|
|
31688
32161
|
loadAll() {
|
|
31689
32162
|
this.providers.clear();
|
|
31690
32163
|
this.providerAvailability.clear();
|
|
31691
32164
|
let upstreamCount = 0;
|
|
31692
|
-
if (!this.disableUpstream &&
|
|
32165
|
+
if (!this.disableUpstream && fs19.existsSync(this.upstreamDir)) {
|
|
31693
32166
|
upstreamCount = this.loadDir(this.upstreamDir);
|
|
31694
32167
|
if (upstreamCount > 0) {
|
|
31695
32168
|
this.log(`Loaded ${upstreamCount} upstream providers (auto-updated)`);
|
|
@@ -31697,14 +32170,64 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31697
32170
|
} else if (this.disableUpstream) {
|
|
31698
32171
|
this.log("Upstream loading disabled (sourceMode=no-upstream)");
|
|
31699
32172
|
}
|
|
31700
|
-
const
|
|
31701
|
-
if (
|
|
31702
|
-
const
|
|
31703
|
-
|
|
31704
|
-
|
|
32173
|
+
const externalDir = path31.join(os22.homedir(), ".adhdev", "external");
|
|
32174
|
+
if (fs19.existsSync(externalDir)) {
|
|
32175
|
+
const rootEntries = (() => {
|
|
32176
|
+
try {
|
|
32177
|
+
return fs19.readdirSync(externalDir, { withFileTypes: true });
|
|
32178
|
+
} catch {
|
|
32179
|
+
return [];
|
|
32180
|
+
}
|
|
32181
|
+
})();
|
|
32182
|
+
const KNOWN_CATEGORIES = /* @__PURE__ */ new Set(["cli", "ide", "extension", "acp"]);
|
|
32183
|
+
const looksLegacy = rootEntries.some((e) => e.isDirectory() && KNOWN_CATEGORIES.has(e.name));
|
|
32184
|
+
if (looksLegacy) {
|
|
32185
|
+
const externalCount = this.loadDir(externalDir);
|
|
32186
|
+
if (externalCount > 0) {
|
|
32187
|
+
this.log(`Loaded ${externalCount} external providers (legacy unnamed source)`);
|
|
32188
|
+
}
|
|
32189
|
+
} else {
|
|
32190
|
+
const {
|
|
32191
|
+
loadProvidersActive: loadProvidersActive2,
|
|
32192
|
+
resolveActiveSource: resolveActiveSource2
|
|
32193
|
+
} = (init_external_sources(), __toCommonJS(external_sources_exports));
|
|
32194
|
+
const activeFile = loadProvidersActive2();
|
|
32195
|
+
let totalLoaded = 0;
|
|
32196
|
+
const ambiguousTypes = [];
|
|
32197
|
+
for (const sourceEntry of rootEntries) {
|
|
32198
|
+
if (!sourceEntry.isDirectory()) continue;
|
|
32199
|
+
const sourceDir = path31.join(externalDir, sourceEntry.name);
|
|
32200
|
+
const sourceLoaded = this.loadDir(sourceDir);
|
|
32201
|
+
if (sourceLoaded > 0) {
|
|
32202
|
+
totalLoaded += sourceLoaded;
|
|
32203
|
+
this.log(`Loaded ${sourceLoaded} providers from external source "${sourceEntry.name}"`);
|
|
32204
|
+
}
|
|
32205
|
+
}
|
|
32206
|
+
for (const [type] of this.providers) {
|
|
32207
|
+
const prov = this.providers.get(type);
|
|
32208
|
+
if (!prov) continue;
|
|
32209
|
+
const resolved = resolveActiveSource2(prov.category, type, activeFile);
|
|
32210
|
+
if (resolved.candidates.length <= 1) continue;
|
|
32211
|
+
if (resolved.ambiguous) {
|
|
32212
|
+
ambiguousTypes.push({ type, chosen: resolved.source ?? "?", candidates: resolved.candidates });
|
|
32213
|
+
}
|
|
32214
|
+
if (resolved.source && resolved.source !== "?") {
|
|
32215
|
+
const sourceDir = path31.join(externalDir, resolved.source);
|
|
32216
|
+
const reloadCount = this.loadDir(sourceDir);
|
|
32217
|
+
if (reloadCount === 0) {
|
|
32218
|
+
this.log(`Active source "${resolved.source}" no longer provides ${type}`);
|
|
32219
|
+
}
|
|
32220
|
+
}
|
|
32221
|
+
}
|
|
32222
|
+
if (totalLoaded > 0) {
|
|
32223
|
+
this.log(`Loaded ${totalLoaded} external providers (3rd-party sources)`);
|
|
32224
|
+
}
|
|
32225
|
+
for (const a of ambiguousTypes) {
|
|
32226
|
+
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.`);
|
|
32227
|
+
}
|
|
31705
32228
|
}
|
|
31706
32229
|
}
|
|
31707
|
-
if (
|
|
32230
|
+
if (fs19.existsSync(this.userDir)) {
|
|
31708
32231
|
const userCount = this.loadDir(this.userDir, [".upstream"]);
|
|
31709
32232
|
if (userCount > 0) {
|
|
31710
32233
|
this.log(`Loaded ${userCount} user custom providers (never auto-updated)`);
|
|
@@ -31719,10 +32242,10 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31719
32242
|
* Check if upstream directory exists and has providers.
|
|
31720
32243
|
*/
|
|
31721
32244
|
hasUpstream() {
|
|
31722
|
-
if (!
|
|
32245
|
+
if (!fs19.existsSync(this.upstreamDir)) return false;
|
|
31723
32246
|
try {
|
|
31724
|
-
return
|
|
31725
|
-
(d) =>
|
|
32247
|
+
return fs19.readdirSync(this.upstreamDir).some(
|
|
32248
|
+
(d) => fs19.statSync(path31.join(this.upstreamDir, d)).isDirectory()
|
|
31726
32249
|
);
|
|
31727
32250
|
} catch {
|
|
31728
32251
|
return false;
|
|
@@ -32212,16 +32735,20 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32212
32735
|
let matched = false;
|
|
32213
32736
|
for (const entry of compat) {
|
|
32214
32737
|
if (this.matchesVersion(currentVersion, entry.ideVersion)) {
|
|
32215
|
-
|
|
32216
|
-
|
|
32217
|
-
|
|
32218
|
-
|
|
32219
|
-
|
|
32220
|
-
|
|
32221
|
-
|
|
32222
|
-
|
|
32223
|
-
|
|
32738
|
+
if (entry.scriptDir) {
|
|
32739
|
+
const loaded = this.loadScriptsFromDir(type, entry.scriptDir);
|
|
32740
|
+
if (loaded) {
|
|
32741
|
+
resolved.scripts = loaded;
|
|
32742
|
+
this.debugLog(` [compatibility] ${type} v${currentVersion} \u2192 ${entry.scriptDir}`);
|
|
32743
|
+
resolved._resolvedScriptDir = entry.scriptDir;
|
|
32744
|
+
resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
|
|
32745
|
+
if (providerDir) {
|
|
32746
|
+
const fullDir = path31.join(providerDir, entry.scriptDir);
|
|
32747
|
+
resolved._resolvedScriptsPath = fs19.existsSync(path31.join(fullDir, "scripts.js")) ? path31.join(fullDir, "scripts.js") : fullDir;
|
|
32748
|
+
}
|
|
32749
|
+
matched = true;
|
|
32224
32750
|
}
|
|
32751
|
+
} else {
|
|
32225
32752
|
matched = true;
|
|
32226
32753
|
}
|
|
32227
32754
|
break;
|
|
@@ -32235,8 +32762,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32235
32762
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
32236
32763
|
resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
|
|
32237
32764
|
if (providerDir) {
|
|
32238
|
-
const fullDir =
|
|
32239
|
-
resolved._resolvedScriptsPath =
|
|
32765
|
+
const fullDir = path31.join(providerDir, base.defaultScriptDir);
|
|
32766
|
+
resolved._resolvedScriptsPath = fs19.existsSync(path31.join(fullDir, "scripts.js")) ? path31.join(fullDir, "scripts.js") : fullDir;
|
|
32240
32767
|
}
|
|
32241
32768
|
}
|
|
32242
32769
|
resolved._versionWarning = `Version ${currentVersion} not in compatibility matrix. Using default scripts.`;
|
|
@@ -32253,8 +32780,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32253
32780
|
resolved._resolvedScriptDir = dirOverride;
|
|
32254
32781
|
resolved._resolvedScriptsSource = `versions:${range}`;
|
|
32255
32782
|
if (providerDir) {
|
|
32256
|
-
const fullDir =
|
|
32257
|
-
resolved._resolvedScriptsPath =
|
|
32783
|
+
const fullDir = path31.join(providerDir, dirOverride);
|
|
32784
|
+
resolved._resolvedScriptsPath = fs19.existsSync(path31.join(fullDir, "scripts.js")) ? path31.join(fullDir, "scripts.js") : fullDir;
|
|
32258
32785
|
}
|
|
32259
32786
|
}
|
|
32260
32787
|
} else if (override.scripts) {
|
|
@@ -32270,8 +32797,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32270
32797
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
32271
32798
|
resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
|
|
32272
32799
|
if (providerDir) {
|
|
32273
|
-
const fullDir =
|
|
32274
|
-
resolved._resolvedScriptsPath =
|
|
32800
|
+
const fullDir = path31.join(providerDir, base.defaultScriptDir);
|
|
32801
|
+
resolved._resolvedScriptsPath = fs19.existsSync(path31.join(fullDir, "scripts.js")) ? path31.join(fullDir, "scripts.js") : fullDir;
|
|
32275
32802
|
}
|
|
32276
32803
|
}
|
|
32277
32804
|
}
|
|
@@ -32288,13 +32815,13 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32288
32815
|
if (providerDir2) {
|
|
32289
32816
|
for (const [scriptName, override] of Object.entries(base.overrides)) {
|
|
32290
32817
|
if (!override || typeof override.path !== "string") continue;
|
|
32291
|
-
const fullPath =
|
|
32292
|
-
if (!
|
|
32818
|
+
const fullPath = path31.join(providerDir2, override.path);
|
|
32819
|
+
if (!fs19.existsSync(fullPath)) {
|
|
32293
32820
|
this.log(` [overrides] ${base.type}: ${scriptName} path not found: ${fullPath}`);
|
|
32294
32821
|
continue;
|
|
32295
32822
|
}
|
|
32296
32823
|
try {
|
|
32297
|
-
registerProviderScriptRootSafely(
|
|
32824
|
+
registerProviderScriptRootSafely(path31.dirname(path31.dirname(providerDir2)));
|
|
32298
32825
|
delete require.cache[require.resolve(fullPath)];
|
|
32299
32826
|
const fn = require(fullPath);
|
|
32300
32827
|
const target = typeof fn === "function" ? fn : fn && fn[scriptName];
|
|
@@ -32319,19 +32846,19 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32319
32846
|
}
|
|
32320
32847
|
if (providerDir) {
|
|
32321
32848
|
try {
|
|
32322
|
-
const
|
|
32323
|
-
const
|
|
32849
|
+
const fs28 = require("fs");
|
|
32850
|
+
const path40 = require("path");
|
|
32324
32851
|
const candidates = [];
|
|
32325
32852
|
if (Array.isArray(base.compatibility)) {
|
|
32326
32853
|
for (const entry of base.compatibility) {
|
|
32327
32854
|
if (typeof entry?.spec !== "string") continue;
|
|
32328
32855
|
const matches = !entry.ideVersion || currentVersion && this.matchesVersion(currentVersion, entry.ideVersion) || !currentVersion;
|
|
32329
|
-
if (matches) candidates.push(
|
|
32856
|
+
if (matches) candidates.push(path40.join(providerDir, entry.spec));
|
|
32330
32857
|
}
|
|
32331
32858
|
}
|
|
32332
|
-
candidates.push(
|
|
32333
|
-
candidates.push(
|
|
32334
|
-
const specPath = candidates.find((p) =>
|
|
32859
|
+
candidates.push(path40.join(providerDir, "specs", "default.json"));
|
|
32860
|
+
candidates.push(path40.join(providerDir, "spec.json"));
|
|
32861
|
+
const specPath = candidates.find((p) => fs28.existsSync(p));
|
|
32335
32862
|
if (specPath) {
|
|
32336
32863
|
resolved._resolvedSpecPath = specPath;
|
|
32337
32864
|
const { loadSpec: loadSpec2 } = (init_loader(), __toCommonJS(loader_exports));
|
|
@@ -32360,10 +32887,10 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32360
32887
|
format = `spec-${nh.source.kind}`;
|
|
32361
32888
|
reader = (input) => executeNativeHistory2(nh, input);
|
|
32362
32889
|
} else if (nh.override_path) {
|
|
32363
|
-
const overrideFile =
|
|
32364
|
-
if (
|
|
32890
|
+
const overrideFile = path40.resolve(providerDir, nh.override_path);
|
|
32891
|
+
if (fs28.existsSync(overrideFile)) {
|
|
32365
32892
|
try {
|
|
32366
|
-
registerProviderScriptRootSafely(
|
|
32893
|
+
registerProviderScriptRootSafely(path40.dirname(path40.dirname(providerDir)));
|
|
32367
32894
|
delete require.cache[require.resolve(overrideFile)];
|
|
32368
32895
|
const mod = require(overrideFile);
|
|
32369
32896
|
const fn = typeof mod === "function" ? mod : mod && typeof mod.default === "function" ? mod.default : null;
|
|
@@ -32407,16 +32934,16 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32407
32934
|
this.debugLog(`[loadScriptsFromDir] ${type}: providerDir not found`);
|
|
32408
32935
|
return null;
|
|
32409
32936
|
}
|
|
32410
|
-
const dir =
|
|
32411
|
-
if (!
|
|
32937
|
+
const dir = path31.join(providerDir, scriptDir);
|
|
32938
|
+
if (!fs19.existsSync(dir)) {
|
|
32412
32939
|
this.debugLog(`[loadScriptsFromDir] ${type}: dir not found: ${dir}`);
|
|
32413
32940
|
return null;
|
|
32414
32941
|
}
|
|
32415
|
-
registerProviderScriptRootSafely(
|
|
32942
|
+
registerProviderScriptRootSafely(path31.dirname(path31.dirname(providerDir)));
|
|
32416
32943
|
const cached = this.scriptsCache.get(dir);
|
|
32417
32944
|
if (cached) return cached;
|
|
32418
|
-
const scriptsJs =
|
|
32419
|
-
if (
|
|
32945
|
+
const scriptsJs = path31.join(dir, "scripts.js");
|
|
32946
|
+
if (fs19.existsSync(scriptsJs)) {
|
|
32420
32947
|
try {
|
|
32421
32948
|
delete require.cache[require.resolve(scriptsJs)];
|
|
32422
32949
|
const loaded = require(scriptsJs);
|
|
@@ -32437,9 +32964,9 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32437
32964
|
watch() {
|
|
32438
32965
|
this.stopWatch();
|
|
32439
32966
|
const watchDir = (dir) => {
|
|
32440
|
-
if (!
|
|
32967
|
+
if (!fs19.existsSync(dir)) {
|
|
32441
32968
|
try {
|
|
32442
|
-
|
|
32969
|
+
fs19.mkdirSync(dir, { recursive: true });
|
|
32443
32970
|
} catch {
|
|
32444
32971
|
return;
|
|
32445
32972
|
}
|
|
@@ -32460,7 +32987,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32460
32987
|
if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
|
|
32461
32988
|
if (reloadTimer) clearTimeout(reloadTimer);
|
|
32462
32989
|
reloadTimer = setTimeout(() => {
|
|
32463
|
-
this.log(`File changed: ${
|
|
32990
|
+
this.log(`File changed: ${path31.basename(filePath)}, reloading...`);
|
|
32464
32991
|
this.reload();
|
|
32465
32992
|
}, 300);
|
|
32466
32993
|
}
|
|
@@ -32528,11 +33055,11 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32528
33055
|
}
|
|
32529
33056
|
this.log(`Registry sync starting (${_ProviderLoader.REGISTRY_BASE_URL})...`);
|
|
32530
33057
|
const https = require("https");
|
|
32531
|
-
const regMetaPath =
|
|
33058
|
+
const regMetaPath = path31.join(this.upstreamDir, _ProviderLoader.REGISTRY_META_FILE);
|
|
32532
33059
|
let cachedChecksums = {};
|
|
32533
33060
|
try {
|
|
32534
|
-
if (
|
|
32535
|
-
cachedChecksums = JSON.parse(
|
|
33061
|
+
if (fs19.existsSync(regMetaPath)) {
|
|
33062
|
+
cachedChecksums = JSON.parse(fs19.readFileSync(regMetaPath, "utf-8")).checksums ?? {};
|
|
32536
33063
|
}
|
|
32537
33064
|
} catch {
|
|
32538
33065
|
}
|
|
@@ -32586,15 +33113,15 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32586
33113
|
this.log(`\u26A0 Registry checksum mismatch for ${type}@${version} \u2014 skipping`);
|
|
32587
33114
|
continue;
|
|
32588
33115
|
}
|
|
32589
|
-
const providerDir =
|
|
32590
|
-
|
|
32591
|
-
|
|
33116
|
+
const providerDir = path31.join(this.upstreamDir, category, type);
|
|
33117
|
+
fs19.mkdirSync(providerDir, { recursive: true });
|
|
33118
|
+
fs19.writeFileSync(path31.join(providerDir, "provider.json"), manifestBody, "utf-8");
|
|
32592
33119
|
cachedChecksums[cacheKey] = checksum;
|
|
32593
33120
|
updatedCount++;
|
|
32594
33121
|
this.log(`\u2713 Registry updated: ${category}/${type}@${version}`);
|
|
32595
33122
|
}
|
|
32596
|
-
|
|
32597
|
-
|
|
33123
|
+
fs19.mkdirSync(this.upstreamDir, { recursive: true });
|
|
33124
|
+
fs19.writeFileSync(regMetaPath, JSON.stringify({
|
|
32598
33125
|
checksums: cachedChecksums,
|
|
32599
33126
|
syncedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
32600
33127
|
providerCount: list.providers.length
|
|
@@ -32615,12 +33142,12 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32615
33142
|
const { exec: exec7 } = require("child_process");
|
|
32616
33143
|
const { promisify: promisify7 } = require("util");
|
|
32617
33144
|
const execAsync5 = promisify7(exec7);
|
|
32618
|
-
const metaPath =
|
|
33145
|
+
const metaPath = path31.join(this.upstreamDir, _ProviderLoader.META_FILE);
|
|
32619
33146
|
let prevEtag = "";
|
|
32620
33147
|
let prevTimestamp = 0;
|
|
32621
33148
|
try {
|
|
32622
|
-
if (
|
|
32623
|
-
const meta = JSON.parse(
|
|
33149
|
+
if (fs19.existsSync(metaPath)) {
|
|
33150
|
+
const meta = JSON.parse(fs19.readFileSync(metaPath, "utf-8"));
|
|
32624
33151
|
prevEtag = meta.etag || "";
|
|
32625
33152
|
prevTimestamp = meta.timestamp || 0;
|
|
32626
33153
|
}
|
|
@@ -32675,39 +33202,39 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32675
33202
|
return { updated: false };
|
|
32676
33203
|
}
|
|
32677
33204
|
this.log("Downloading latest providers from GitHub...");
|
|
32678
|
-
const tmpTar =
|
|
32679
|
-
const tmpExtract =
|
|
33205
|
+
const tmpTar = path31.join(os22.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
|
|
33206
|
+
const tmpExtract = path31.join(os22.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
|
|
32680
33207
|
await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
|
|
32681
|
-
|
|
33208
|
+
fs19.mkdirSync(tmpExtract, { recursive: true });
|
|
32682
33209
|
await execAsync5(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
|
|
32683
|
-
const extracted =
|
|
33210
|
+
const extracted = fs19.readdirSync(tmpExtract);
|
|
32684
33211
|
const rootDir = extracted.find(
|
|
32685
|
-
(d) =>
|
|
33212
|
+
(d) => fs19.statSync(path31.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
|
|
32686
33213
|
);
|
|
32687
33214
|
if (!rootDir) throw new Error("Unexpected tarball structure");
|
|
32688
|
-
const sourceDir =
|
|
33215
|
+
const sourceDir = path31.join(tmpExtract, rootDir);
|
|
32689
33216
|
const backupDir = this.upstreamDir + ".bak";
|
|
32690
|
-
if (
|
|
32691
|
-
if (
|
|
32692
|
-
|
|
33217
|
+
if (fs19.existsSync(this.upstreamDir)) {
|
|
33218
|
+
if (fs19.existsSync(backupDir)) fs19.rmSync(backupDir, { recursive: true, force: true });
|
|
33219
|
+
fs19.renameSync(this.upstreamDir, backupDir);
|
|
32693
33220
|
}
|
|
32694
33221
|
try {
|
|
32695
33222
|
this.copyDirRecursive(sourceDir, this.upstreamDir);
|
|
32696
33223
|
this.writeMeta(metaPath, etag || `ts-${Date.now()}`, Date.now());
|
|
32697
|
-
if (
|
|
33224
|
+
if (fs19.existsSync(backupDir)) fs19.rmSync(backupDir, { recursive: true, force: true });
|
|
32698
33225
|
} catch (e) {
|
|
32699
|
-
if (
|
|
32700
|
-
if (
|
|
32701
|
-
|
|
33226
|
+
if (fs19.existsSync(backupDir)) {
|
|
33227
|
+
if (fs19.existsSync(this.upstreamDir)) fs19.rmSync(this.upstreamDir, { recursive: true, force: true });
|
|
33228
|
+
fs19.renameSync(backupDir, this.upstreamDir);
|
|
32702
33229
|
}
|
|
32703
33230
|
throw e;
|
|
32704
33231
|
}
|
|
32705
33232
|
try {
|
|
32706
|
-
|
|
33233
|
+
fs19.rmSync(tmpTar, { force: true });
|
|
32707
33234
|
} catch {
|
|
32708
33235
|
}
|
|
32709
33236
|
try {
|
|
32710
|
-
|
|
33237
|
+
fs19.rmSync(tmpExtract, { recursive: true, force: true });
|
|
32711
33238
|
} catch {
|
|
32712
33239
|
}
|
|
32713
33240
|
const upstreamCount = this.countProviders(this.upstreamDir);
|
|
@@ -32739,7 +33266,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32739
33266
|
reject(new Error(`HTTP ${res.statusCode}`));
|
|
32740
33267
|
return;
|
|
32741
33268
|
}
|
|
32742
|
-
const ws =
|
|
33269
|
+
const ws = fs19.createWriteStream(destPath);
|
|
32743
33270
|
res.pipe(ws);
|
|
32744
33271
|
ws.on("finish", () => {
|
|
32745
33272
|
ws.close();
|
|
@@ -32758,22 +33285,22 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32758
33285
|
}
|
|
32759
33286
|
/** Recursive directory copy */
|
|
32760
33287
|
copyDirRecursive(src, dest) {
|
|
32761
|
-
|
|
32762
|
-
for (const entry of
|
|
32763
|
-
const srcPath =
|
|
32764
|
-
const destPath =
|
|
33288
|
+
fs19.mkdirSync(dest, { recursive: true });
|
|
33289
|
+
for (const entry of fs19.readdirSync(src, { withFileTypes: true })) {
|
|
33290
|
+
const srcPath = path31.join(src, entry.name);
|
|
33291
|
+
const destPath = path31.join(dest, entry.name);
|
|
32765
33292
|
if (entry.isDirectory()) {
|
|
32766
33293
|
this.copyDirRecursive(srcPath, destPath);
|
|
32767
33294
|
} else {
|
|
32768
|
-
|
|
33295
|
+
fs19.copyFileSync(srcPath, destPath);
|
|
32769
33296
|
}
|
|
32770
33297
|
}
|
|
32771
33298
|
}
|
|
32772
33299
|
/** .meta.json save */
|
|
32773
33300
|
writeMeta(metaPath, etag, timestamp) {
|
|
32774
33301
|
try {
|
|
32775
|
-
|
|
32776
|
-
|
|
33302
|
+
fs19.mkdirSync(path31.dirname(metaPath), { recursive: true });
|
|
33303
|
+
fs19.writeFileSync(metaPath, JSON.stringify({
|
|
32777
33304
|
etag,
|
|
32778
33305
|
timestamp,
|
|
32779
33306
|
lastCheck: new Date(timestamp).toISOString(),
|
|
@@ -32784,15 +33311,15 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32784
33311
|
}
|
|
32785
33312
|
/** Count provider files (provider.v1.json or provider.json — at most one per dir). */
|
|
32786
33313
|
countProviders(dir) {
|
|
32787
|
-
if (!
|
|
33314
|
+
if (!fs19.existsSync(dir)) return 0;
|
|
32788
33315
|
let count = 0;
|
|
32789
33316
|
const scan = (d) => {
|
|
32790
33317
|
try {
|
|
32791
|
-
const entries =
|
|
33318
|
+
const entries = fs19.readdirSync(d, { withFileTypes: true });
|
|
32792
33319
|
const hasManifest = entries.some((e) => e.name === "provider.v1.json" || e.name === "provider.json");
|
|
32793
33320
|
if (hasManifest) count++;
|
|
32794
33321
|
for (const entry of entries) {
|
|
32795
|
-
if (entry.isDirectory()) scan(
|
|
33322
|
+
if (entry.isDirectory()) scan(path31.join(d, entry.name));
|
|
32796
33323
|
}
|
|
32797
33324
|
} catch {
|
|
32798
33325
|
}
|
|
@@ -33018,13 +33545,13 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
33018
33545
|
if (!provider) return null;
|
|
33019
33546
|
const cat = provider.category;
|
|
33020
33547
|
const searchRoots = this.getProviderRoots();
|
|
33021
|
-
const hasManifest = (dir) =>
|
|
33548
|
+
const hasManifest = (dir) => fs19.existsSync(path31.join(dir, "provider.v1.json")) || fs19.existsSync(path31.join(dir, "provider.json"));
|
|
33022
33549
|
const readManifestType = (dir) => {
|
|
33023
33550
|
for (const file of ["provider.v1.json", "provider.json"]) {
|
|
33024
|
-
const p =
|
|
33025
|
-
if (!
|
|
33551
|
+
const p = path31.join(dir, file);
|
|
33552
|
+
if (!fs19.existsSync(p)) continue;
|
|
33026
33553
|
try {
|
|
33027
|
-
const data = JSON.parse(
|
|
33554
|
+
const data = JSON.parse(fs19.readFileSync(p, "utf-8"));
|
|
33028
33555
|
if (typeof data?.type === "string") return data.type;
|
|
33029
33556
|
} catch {
|
|
33030
33557
|
}
|
|
@@ -33032,15 +33559,15 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
33032
33559
|
return null;
|
|
33033
33560
|
};
|
|
33034
33561
|
for (const root of searchRoots) {
|
|
33035
|
-
if (!
|
|
33562
|
+
if (!fs19.existsSync(root)) continue;
|
|
33036
33563
|
const candidate = this.getProviderDir(root, cat, type);
|
|
33037
33564
|
if (hasManifest(candidate)) return candidate;
|
|
33038
|
-
const catDir =
|
|
33039
|
-
if (
|
|
33565
|
+
const catDir = path31.join(root, cat);
|
|
33566
|
+
if (fs19.existsSync(catDir)) {
|
|
33040
33567
|
try {
|
|
33041
|
-
for (const entry of
|
|
33568
|
+
for (const entry of fs19.readdirSync(catDir, { withFileTypes: true })) {
|
|
33042
33569
|
if (!entry.isDirectory()) continue;
|
|
33043
|
-
const entryDir =
|
|
33570
|
+
const entryDir = path31.join(catDir, entry.name);
|
|
33044
33571
|
const manifestType = readManifestType(entryDir);
|
|
33045
33572
|
if (manifestType === type) return entryDir;
|
|
33046
33573
|
}
|
|
@@ -33056,8 +33583,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
33056
33583
|
* (template substitution is NOT applied here — scripts.js handles that)
|
|
33057
33584
|
*/
|
|
33058
33585
|
buildScriptWrappersFromDir(dir) {
|
|
33059
|
-
const scriptsJs =
|
|
33060
|
-
if (
|
|
33586
|
+
const scriptsJs = path31.join(dir, "scripts.js");
|
|
33587
|
+
if (fs19.existsSync(scriptsJs)) {
|
|
33061
33588
|
try {
|
|
33062
33589
|
delete require.cache[require.resolve(scriptsJs)];
|
|
33063
33590
|
return require(scriptsJs);
|
|
@@ -33067,13 +33594,13 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
33067
33594
|
const toCamel = (name) => name.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
|
|
33068
33595
|
const result = {};
|
|
33069
33596
|
try {
|
|
33070
|
-
for (const file of
|
|
33597
|
+
for (const file of fs19.readdirSync(dir)) {
|
|
33071
33598
|
if (!file.endsWith(".js")) continue;
|
|
33072
33599
|
const scriptName = toCamel(file.replace(".js", ""));
|
|
33073
|
-
const filePath =
|
|
33600
|
+
const filePath = path31.join(dir, file);
|
|
33074
33601
|
result[scriptName] = (...args) => {
|
|
33075
33602
|
try {
|
|
33076
|
-
let content =
|
|
33603
|
+
let content = fs19.readFileSync(filePath, "utf-8");
|
|
33077
33604
|
if (args[0] && typeof args[0] === "object") {
|
|
33078
33605
|
for (const [key, val] of Object.entries(args[0])) {
|
|
33079
33606
|
let v = val;
|
|
@@ -33119,12 +33646,12 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
33119
33646
|
* Structure: dir/category/agent-name/provider.{json,js}
|
|
33120
33647
|
*/
|
|
33121
33648
|
loadDir(dir, excludeDirs) {
|
|
33122
|
-
if (!
|
|
33649
|
+
if (!fs19.existsSync(dir)) return 0;
|
|
33123
33650
|
let count = 0;
|
|
33124
33651
|
const scan = (d) => {
|
|
33125
33652
|
let entries;
|
|
33126
33653
|
try {
|
|
33127
|
-
entries =
|
|
33654
|
+
entries = fs19.readdirSync(d, { withFileTypes: true });
|
|
33128
33655
|
} catch {
|
|
33129
33656
|
return;
|
|
33130
33657
|
}
|
|
@@ -33132,9 +33659,9 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
33132
33659
|
const hasJson = entries.some((e) => e.name === "provider.json");
|
|
33133
33660
|
if (hasV1 || hasJson) {
|
|
33134
33661
|
const manifestFile = hasV1 ? "provider.v1.json" : "provider.json";
|
|
33135
|
-
const jsonPath =
|
|
33662
|
+
const jsonPath = path31.join(d, manifestFile);
|
|
33136
33663
|
try {
|
|
33137
|
-
const raw =
|
|
33664
|
+
const raw = fs19.readFileSync(jsonPath, "utf-8");
|
|
33138
33665
|
const mod = JSON.parse(raw);
|
|
33139
33666
|
if (hasV1 && mod?.category === "cli") {
|
|
33140
33667
|
try {
|
|
@@ -33172,10 +33699,10 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
33172
33699
|
this.log(`\u26A0 Invalid provider at ${jsonPath}: ${validation.errors.join("; ")}`);
|
|
33173
33700
|
} else {
|
|
33174
33701
|
const hasCompatibility = Array.isArray(normalizedProvider.compatibility);
|
|
33175
|
-
const scriptsPath =
|
|
33176
|
-
if (!hasCompatibility &&
|
|
33702
|
+
const scriptsPath = path31.join(d, "scripts.js");
|
|
33703
|
+
if (!hasCompatibility && fs19.existsSync(scriptsPath)) {
|
|
33177
33704
|
try {
|
|
33178
|
-
registerProviderScriptRootSafely(
|
|
33705
|
+
registerProviderScriptRootSafely(path31.dirname(path31.dirname(d)));
|
|
33179
33706
|
delete require.cache[require.resolve(scriptsPath)];
|
|
33180
33707
|
const scripts = require(scriptsPath);
|
|
33181
33708
|
normalizedProvider.scripts = scripts;
|
|
@@ -33183,12 +33710,30 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
33183
33710
|
this.log(`\u26A0 Failed to load scripts: ${scriptsPath}: ${e.message}`);
|
|
33184
33711
|
}
|
|
33185
33712
|
}
|
|
33713
|
+
const externalDirAbs = path31.join(os22.homedir(), ".adhdev", "external");
|
|
33714
|
+
const layer = d.startsWith(externalDirAbs) ? "external" : d.startsWith(this.userDir) && !d.includes(".upstream") ? "user" : "upstream";
|
|
33715
|
+
try {
|
|
33716
|
+
const { inspectManifestShape: inspectManifestShape2, classifyTrust: classifyTrust2 } = (init_provider_trust(), __toCommonJS(provider_trust_exports));
|
|
33717
|
+
const shape = inspectManifestShape2(mod);
|
|
33718
|
+
const trust = classifyTrust2(layer, shape);
|
|
33719
|
+
normalizedProvider._sourceLayer = layer;
|
|
33720
|
+
normalizedProvider._sourceTrust = trust;
|
|
33721
|
+
normalizedProvider._manifestShape = shape;
|
|
33722
|
+
if (layer === "external") {
|
|
33723
|
+
const rel = path31.relative(externalDirAbs, d);
|
|
33724
|
+
const firstSeg = rel.split(path31.sep)[0];
|
|
33725
|
+
if (firstSeg && firstSeg !== "..") normalizedProvider._sourceName = firstSeg;
|
|
33726
|
+
}
|
|
33727
|
+
} catch {
|
|
33728
|
+
}
|
|
33186
33729
|
const existed = this.providers.has(normalizedProvider.type);
|
|
33187
33730
|
this.providers.set(normalizedProvider.type, normalizedProvider);
|
|
33188
33731
|
count++;
|
|
33189
|
-
const source =
|
|
33732
|
+
const source = normalizedProvider._sourceLayer ?? "upstream";
|
|
33190
33733
|
const overrideWarning = existed && source === "user" ? " \u26A0 OVERRIDES upstream" : "";
|
|
33191
|
-
|
|
33734
|
+
const sourceName = normalizedProvider._sourceName;
|
|
33735
|
+
const sourceLabel = sourceName ? `${source}/${sourceName}` : source;
|
|
33736
|
+
this.log(` ${existed ? "\u{1F504}" : "\u2705"} ${normalizedProvider.type} (${normalizedProvider.category}) \u2014 ${normalizedProvider.name} [${sourceLabel}]${overrideWarning}`);
|
|
33192
33737
|
}
|
|
33193
33738
|
} catch (e) {
|
|
33194
33739
|
this.log(`\u26A0 Failed to load ${jsonPath}: ${e.message}`);
|
|
@@ -33198,8 +33743,9 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
33198
33743
|
for (const entry of entries) {
|
|
33199
33744
|
if (!entry.isDirectory()) continue;
|
|
33200
33745
|
if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
|
|
33746
|
+
if (d === dir && entry.name === "examples") continue;
|
|
33201
33747
|
if (excludeDirs && d === dir && excludeDirs.includes(entry.name)) continue;
|
|
33202
|
-
scan(
|
|
33748
|
+
scan(path31.join(d, entry.name));
|
|
33203
33749
|
}
|
|
33204
33750
|
}
|
|
33205
33751
|
};
|
|
@@ -33397,7 +33943,7 @@ async function isCdpActive(port) {
|
|
|
33397
33943
|
});
|
|
33398
33944
|
}
|
|
33399
33945
|
async function killIdeProcess(ideId) {
|
|
33400
|
-
const plat =
|
|
33946
|
+
const plat = os23.platform();
|
|
33401
33947
|
const appName = getMacAppIdentifiers()[ideId];
|
|
33402
33948
|
const winProcesses = getWinProcessNames()[ideId];
|
|
33403
33949
|
try {
|
|
@@ -33458,7 +34004,7 @@ async function killIdeProcess(ideId) {
|
|
|
33458
34004
|
}
|
|
33459
34005
|
}
|
|
33460
34006
|
async function isIdeRunning(ideId) {
|
|
33461
|
-
const plat =
|
|
34007
|
+
const plat = os23.platform();
|
|
33462
34008
|
try {
|
|
33463
34009
|
if (plat === "darwin") {
|
|
33464
34010
|
const appName = getMacAppIdentifiers()[ideId];
|
|
@@ -33513,7 +34059,7 @@ async function isIdeRunning(ideId) {
|
|
|
33513
34059
|
}
|
|
33514
34060
|
}
|
|
33515
34061
|
async function detectCurrentWorkspace(ideId) {
|
|
33516
|
-
const plat =
|
|
34062
|
+
const plat = os23.platform();
|
|
33517
34063
|
if (plat === "darwin") {
|
|
33518
34064
|
try {
|
|
33519
34065
|
const appName = getMacAppIdentifiers()[ideId];
|
|
@@ -33528,17 +34074,17 @@ async function detectCurrentWorkspace(ideId) {
|
|
|
33528
34074
|
}
|
|
33529
34075
|
} else if (plat === "win32") {
|
|
33530
34076
|
try {
|
|
33531
|
-
const
|
|
34077
|
+
const fs28 = require("fs");
|
|
33532
34078
|
const appNameMap = getMacAppIdentifiers();
|
|
33533
34079
|
const appName = appNameMap[ideId];
|
|
33534
34080
|
if (appName) {
|
|
33535
|
-
const storagePath =
|
|
33536
|
-
process.env.APPDATA ||
|
|
34081
|
+
const storagePath = path32.join(
|
|
34082
|
+
process.env.APPDATA || path32.join(os23.homedir(), "AppData", "Roaming"),
|
|
33537
34083
|
appName,
|
|
33538
34084
|
"storage.json"
|
|
33539
34085
|
);
|
|
33540
|
-
if (
|
|
33541
|
-
const data = JSON.parse(
|
|
34086
|
+
if (fs28.existsSync(storagePath)) {
|
|
34087
|
+
const data = JSON.parse(fs28.readFileSync(storagePath, "utf-8"));
|
|
33542
34088
|
const workspaces = data?.openedPathsList?.workspaces3 || data?.openedPathsList?.entries || [];
|
|
33543
34089
|
if (workspaces.length > 0) {
|
|
33544
34090
|
const recent = workspaces[0];
|
|
@@ -33555,7 +34101,7 @@ async function detectCurrentWorkspace(ideId) {
|
|
|
33555
34101
|
return void 0;
|
|
33556
34102
|
}
|
|
33557
34103
|
async function launchWithCdp(options = {}) {
|
|
33558
|
-
const platform10 =
|
|
34104
|
+
const platform10 = os23.platform();
|
|
33559
34105
|
let targetIde;
|
|
33560
34106
|
const ides = await detectIDEs(getProviderLoader());
|
|
33561
34107
|
if (options.ideId) {
|
|
@@ -33722,14 +34268,14 @@ init_cli_detector();
|
|
|
33722
34268
|
init_logger();
|
|
33723
34269
|
|
|
33724
34270
|
// src/logging/command-log.ts
|
|
33725
|
-
var
|
|
33726
|
-
var
|
|
33727
|
-
var
|
|
33728
|
-
var LOG_DIR2 = process.platform === "win32" ?
|
|
34271
|
+
var fs20 = __toESM(require("fs"));
|
|
34272
|
+
var path33 = __toESM(require("path"));
|
|
34273
|
+
var os24 = __toESM(require("os"));
|
|
34274
|
+
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");
|
|
33729
34275
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
33730
34276
|
var MAX_DAYS = 7;
|
|
33731
34277
|
try {
|
|
33732
|
-
|
|
34278
|
+
fs20.mkdirSync(LOG_DIR2, { recursive: true });
|
|
33733
34279
|
} catch {
|
|
33734
34280
|
}
|
|
33735
34281
|
var SENSITIVE_KEYS = /* @__PURE__ */ new Set([
|
|
@@ -33763,19 +34309,19 @@ function getDateStr2() {
|
|
|
33763
34309
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
33764
34310
|
}
|
|
33765
34311
|
var currentDate2 = getDateStr2();
|
|
33766
|
-
var currentFile =
|
|
34312
|
+
var currentFile = path33.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
33767
34313
|
var writeCount2 = 0;
|
|
33768
34314
|
function checkRotation() {
|
|
33769
34315
|
const today = getDateStr2();
|
|
33770
34316
|
if (today !== currentDate2) {
|
|
33771
34317
|
currentDate2 = today;
|
|
33772
|
-
currentFile =
|
|
34318
|
+
currentFile = path33.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
33773
34319
|
cleanOldFiles();
|
|
33774
34320
|
}
|
|
33775
34321
|
}
|
|
33776
34322
|
function cleanOldFiles() {
|
|
33777
34323
|
try {
|
|
33778
|
-
const files =
|
|
34324
|
+
const files = fs20.readdirSync(LOG_DIR2).filter((f) => f.startsWith("commands-") && f.endsWith(".jsonl"));
|
|
33779
34325
|
const cutoff = /* @__PURE__ */ new Date();
|
|
33780
34326
|
cutoff.setDate(cutoff.getDate() - MAX_DAYS);
|
|
33781
34327
|
const cutoffStr = cutoff.toISOString().slice(0, 10);
|
|
@@ -33783,7 +34329,7 @@ function cleanOldFiles() {
|
|
|
33783
34329
|
const dateMatch = file.match(/commands-(\d{4}-\d{2}-\d{2})/);
|
|
33784
34330
|
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
33785
34331
|
try {
|
|
33786
|
-
|
|
34332
|
+
fs20.unlinkSync(path33.join(LOG_DIR2, file));
|
|
33787
34333
|
} catch {
|
|
33788
34334
|
}
|
|
33789
34335
|
}
|
|
@@ -33793,14 +34339,14 @@ function cleanOldFiles() {
|
|
|
33793
34339
|
}
|
|
33794
34340
|
function checkSize() {
|
|
33795
34341
|
try {
|
|
33796
|
-
const stat2 =
|
|
34342
|
+
const stat2 = fs20.statSync(currentFile);
|
|
33797
34343
|
if (stat2.size > MAX_FILE_SIZE) {
|
|
33798
34344
|
const backup = currentFile.replace(".jsonl", ".1.jsonl");
|
|
33799
34345
|
try {
|
|
33800
|
-
|
|
34346
|
+
fs20.unlinkSync(backup);
|
|
33801
34347
|
} catch {
|
|
33802
34348
|
}
|
|
33803
|
-
|
|
34349
|
+
fs20.renameSync(currentFile, backup);
|
|
33804
34350
|
}
|
|
33805
34351
|
} catch {
|
|
33806
34352
|
}
|
|
@@ -33833,14 +34379,14 @@ function logCommand(entry) {
|
|
|
33833
34379
|
...entry.error ? { err: entry.error } : {},
|
|
33834
34380
|
...entry.durationMs !== void 0 ? { ms: entry.durationMs } : {}
|
|
33835
34381
|
});
|
|
33836
|
-
|
|
34382
|
+
fs20.appendFileSync(currentFile, line + "\n");
|
|
33837
34383
|
} catch {
|
|
33838
34384
|
}
|
|
33839
34385
|
}
|
|
33840
34386
|
function getRecentCommands(count = 50) {
|
|
33841
34387
|
try {
|
|
33842
|
-
if (!
|
|
33843
|
-
const content =
|
|
34388
|
+
if (!fs20.existsSync(currentFile)) return [];
|
|
34389
|
+
const content = fs20.readFileSync(currentFile, "utf-8");
|
|
33844
34390
|
const lines = content.trim().split("\n").filter(Boolean);
|
|
33845
34391
|
return lines.slice(-count).map((line) => {
|
|
33846
34392
|
try {
|
|
@@ -33890,10 +34436,10 @@ function runGit2(repoRoot, args) {
|
|
|
33890
34436
|
}
|
|
33891
34437
|
}
|
|
33892
34438
|
function readRecord3(repoRoot) {
|
|
33893
|
-
const
|
|
33894
|
-
if (!(0, import_node_fs4.existsSync)(
|
|
34439
|
+
const path40 = (0, import_node_path2.resolve)(repoRoot, PREVIEW_DEPLOY_RECORD);
|
|
34440
|
+
if (!(0, import_node_fs4.existsSync)(path40)) return null;
|
|
33895
34441
|
try {
|
|
33896
|
-
const parsed = JSON.parse((0, import_node_fs4.readFileSync)(
|
|
34442
|
+
const parsed = JSON.parse((0, import_node_fs4.readFileSync)(path40, "utf8"));
|
|
33897
34443
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
33898
34444
|
} catch {
|
|
33899
34445
|
return null;
|
|
@@ -33955,7 +34501,7 @@ function buildPreviewFreshness(repoRoot) {
|
|
|
33955
34501
|
}
|
|
33956
34502
|
|
|
33957
34503
|
// src/status/snapshot.ts
|
|
33958
|
-
var
|
|
34504
|
+
var os25 = __toESM(require("os"));
|
|
33959
34505
|
init_config();
|
|
33960
34506
|
init_terminal_screen();
|
|
33961
34507
|
init_logger();
|
|
@@ -33994,25 +34540,50 @@ function buildDetectedIdeInfos(detectedIdes, cdpManagers) {
|
|
|
33994
34540
|
}
|
|
33995
34541
|
function buildAvailableProviders(providerLoader) {
|
|
33996
34542
|
const providers = providerLoader.getAvailableProviderInfos?.() || providerLoader.getAll();
|
|
33997
|
-
|
|
33998
|
-
|
|
33999
|
-
|
|
34000
|
-
|
|
34001
|
-
|
|
34002
|
-
|
|
34003
|
-
|
|
34004
|
-
|
|
34005
|
-
|
|
34006
|
-
|
|
34007
|
-
|
|
34008
|
-
|
|
34009
|
-
|
|
34010
|
-
|
|
34543
|
+
let describeTrust2 = () => "";
|
|
34544
|
+
let requiresConfirmation2 = () => false;
|
|
34545
|
+
try {
|
|
34546
|
+
const mod = (init_provider_trust(), __toCommonJS(provider_trust_exports));
|
|
34547
|
+
describeTrust2 = mod.describeTrust;
|
|
34548
|
+
requiresConfirmation2 = mod.requiresConfirmation;
|
|
34549
|
+
} catch {
|
|
34550
|
+
}
|
|
34551
|
+
return providers.map((provider) => {
|
|
34552
|
+
const trust = provider._sourceTrust;
|
|
34553
|
+
const sourceLayer = provider._sourceLayer;
|
|
34554
|
+
const sourceName = provider._sourceName;
|
|
34555
|
+
return {
|
|
34556
|
+
type: provider.type,
|
|
34557
|
+
name: provider.displayName || provider.type,
|
|
34558
|
+
displayName: provider.displayName || provider.type,
|
|
34559
|
+
icon: provider.icon || "\u{1F4BB}",
|
|
34560
|
+
category: provider.category,
|
|
34561
|
+
...provider.installed !== void 0 ? { installed: provider.installed } : {},
|
|
34562
|
+
...provider.detectedPath !== void 0 ? { detectedPath: provider.detectedPath } : {},
|
|
34563
|
+
...provider.enabled !== void 0 ? { enabled: provider.enabled } : {},
|
|
34564
|
+
...provider.machineStatus !== void 0 ? { machineStatus: provider.machineStatus } : {},
|
|
34565
|
+
...provider.lastDetection !== void 0 ? { lastDetection: provider.lastDetection } : {},
|
|
34566
|
+
...provider.lastVerification !== void 0 ? { lastVerification: provider.lastVerification } : {},
|
|
34567
|
+
...provider.meshCoordinator !== void 0 ? { meshCoordinator: provider.meshCoordinator } : {},
|
|
34568
|
+
...trust ? {
|
|
34569
|
+
trust,
|
|
34570
|
+
trustDescription: describeTrust2(trust),
|
|
34571
|
+
requiresConfirmation: requiresConfirmation2(trust)
|
|
34572
|
+
} : {},
|
|
34573
|
+
...sourceLayer ? { sourceLayer } : {},
|
|
34574
|
+
...sourceName ? { sourceName } : {},
|
|
34575
|
+
...provider.providerVersion ? { providerVersion: provider.providerVersion } : {},
|
|
34576
|
+
...provider.binary ? { binary: provider.binary } : {},
|
|
34577
|
+
...provider.status ? { status: provider.status } : {},
|
|
34578
|
+
...provider.details ? { details: provider.details } : {},
|
|
34579
|
+
...provider.links ? { links: provider.links } : {}
|
|
34580
|
+
};
|
|
34581
|
+
});
|
|
34011
34582
|
}
|
|
34012
34583
|
function buildMachineInfo(profile = "full") {
|
|
34013
34584
|
const base = {
|
|
34014
|
-
hostname:
|
|
34015
|
-
platform:
|
|
34585
|
+
hostname: os25.hostname(),
|
|
34586
|
+
platform: os25.platform()
|
|
34016
34587
|
};
|
|
34017
34588
|
if (profile === "live") {
|
|
34018
34589
|
return base;
|
|
@@ -34021,23 +34592,23 @@ function buildMachineInfo(profile = "full") {
|
|
|
34021
34592
|
const memSnap2 = getHostMemorySnapshot();
|
|
34022
34593
|
return {
|
|
34023
34594
|
...base,
|
|
34024
|
-
arch:
|
|
34025
|
-
cpus:
|
|
34595
|
+
arch: os25.arch(),
|
|
34596
|
+
cpus: os25.cpus().length,
|
|
34026
34597
|
totalMem: memSnap2.totalMem,
|
|
34027
|
-
release:
|
|
34598
|
+
release: os25.release()
|
|
34028
34599
|
};
|
|
34029
34600
|
}
|
|
34030
34601
|
const memSnap = getHostMemorySnapshot();
|
|
34031
34602
|
return {
|
|
34032
34603
|
...base,
|
|
34033
|
-
arch:
|
|
34034
|
-
cpus:
|
|
34604
|
+
arch: os25.arch(),
|
|
34605
|
+
cpus: os25.cpus().length,
|
|
34035
34606
|
totalMem: memSnap.totalMem,
|
|
34036
34607
|
freeMem: memSnap.freeMem,
|
|
34037
34608
|
availableMem: memSnap.availableMem,
|
|
34038
|
-
loadavg:
|
|
34039
|
-
uptime:
|
|
34040
|
-
release:
|
|
34609
|
+
loadavg: os25.loadavg(),
|
|
34610
|
+
uptime: os25.uptime(),
|
|
34611
|
+
release: os25.release()
|
|
34041
34612
|
};
|
|
34042
34613
|
}
|
|
34043
34614
|
function parseMessageTime(value) {
|
|
@@ -34278,42 +34849,42 @@ function buildStatusSnapshot(options) {
|
|
|
34278
34849
|
// src/commands/upgrade-helper.ts
|
|
34279
34850
|
var import_child_process7 = require("child_process");
|
|
34280
34851
|
var import_child_process8 = require("child_process");
|
|
34281
|
-
var
|
|
34282
|
-
var
|
|
34283
|
-
var
|
|
34852
|
+
var fs21 = __toESM(require("fs"));
|
|
34853
|
+
var os26 = __toESM(require("os"));
|
|
34854
|
+
var path34 = __toESM(require("path"));
|
|
34284
34855
|
var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
|
|
34285
34856
|
function getUpgradeLogPath() {
|
|
34286
|
-
const home =
|
|
34287
|
-
const dir =
|
|
34288
|
-
|
|
34289
|
-
return
|
|
34857
|
+
const home = os26.homedir();
|
|
34858
|
+
const dir = path34.join(home, ".adhdev");
|
|
34859
|
+
fs21.mkdirSync(dir, { recursive: true });
|
|
34860
|
+
return path34.join(dir, "daemon-upgrade.log");
|
|
34290
34861
|
}
|
|
34291
34862
|
function appendUpgradeLog(message) {
|
|
34292
34863
|
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
|
|
34293
34864
|
`;
|
|
34294
34865
|
try {
|
|
34295
|
-
|
|
34866
|
+
fs21.appendFileSync(getUpgradeLogPath(), line, "utf8");
|
|
34296
34867
|
} catch {
|
|
34297
34868
|
}
|
|
34298
34869
|
}
|
|
34299
34870
|
function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platform) {
|
|
34300
|
-
const binDir =
|
|
34871
|
+
const binDir = path34.dirname(nodeExecutable);
|
|
34301
34872
|
if (platform10 === "win32") {
|
|
34302
|
-
const npmCliPath =
|
|
34303
|
-
if (
|
|
34873
|
+
const npmCliPath = path34.join(binDir, "node_modules", "npm", "bin", "npm-cli.js");
|
|
34874
|
+
if (fs21.existsSync(npmCliPath)) {
|
|
34304
34875
|
return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
|
|
34305
34876
|
}
|
|
34306
34877
|
for (const candidate of ["npm.exe", "npm"]) {
|
|
34307
|
-
const candidatePath =
|
|
34308
|
-
if (
|
|
34878
|
+
const candidatePath = path34.join(binDir, candidate);
|
|
34879
|
+
if (fs21.existsSync(candidatePath)) {
|
|
34309
34880
|
return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
|
|
34310
34881
|
}
|
|
34311
34882
|
}
|
|
34312
34883
|
return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
|
|
34313
34884
|
}
|
|
34314
34885
|
for (const candidate of ["npm"]) {
|
|
34315
|
-
const candidatePath =
|
|
34316
|
-
if (
|
|
34886
|
+
const candidatePath = path34.join(binDir, candidate);
|
|
34887
|
+
if (fs21.existsSync(candidatePath)) {
|
|
34317
34888
|
return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
|
|
34318
34889
|
}
|
|
34319
34890
|
}
|
|
@@ -34323,22 +34894,22 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
34323
34894
|
if (!currentCliPath) return null;
|
|
34324
34895
|
let resolvedPath = currentCliPath;
|
|
34325
34896
|
try {
|
|
34326
|
-
resolvedPath =
|
|
34897
|
+
resolvedPath = fs21.realpathSync.native(currentCliPath);
|
|
34327
34898
|
} catch {
|
|
34328
34899
|
}
|
|
34329
34900
|
let currentDir = resolvedPath;
|
|
34330
34901
|
try {
|
|
34331
|
-
if (
|
|
34332
|
-
currentDir =
|
|
34902
|
+
if (fs21.statSync(resolvedPath).isFile()) {
|
|
34903
|
+
currentDir = path34.dirname(resolvedPath);
|
|
34333
34904
|
}
|
|
34334
34905
|
} catch {
|
|
34335
|
-
currentDir =
|
|
34906
|
+
currentDir = path34.dirname(resolvedPath);
|
|
34336
34907
|
}
|
|
34337
34908
|
while (true) {
|
|
34338
|
-
const packageJsonPath =
|
|
34909
|
+
const packageJsonPath = path34.join(currentDir, "package.json");
|
|
34339
34910
|
try {
|
|
34340
|
-
if (
|
|
34341
|
-
const parsed = JSON.parse(
|
|
34911
|
+
if (fs21.existsSync(packageJsonPath)) {
|
|
34912
|
+
const parsed = JSON.parse(fs21.readFileSync(packageJsonPath, "utf8"));
|
|
34342
34913
|
if (parsed?.name === packageName) {
|
|
34343
34914
|
const normalized = currentDir.replace(/\\/g, "/");
|
|
34344
34915
|
return normalized.includes("/node_modules/") ? currentDir : null;
|
|
@@ -34346,7 +34917,7 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
34346
34917
|
}
|
|
34347
34918
|
} catch {
|
|
34348
34919
|
}
|
|
34349
|
-
const parentDir =
|
|
34920
|
+
const parentDir = path34.dirname(currentDir);
|
|
34350
34921
|
if (parentDir === currentDir) {
|
|
34351
34922
|
return null;
|
|
34352
34923
|
}
|
|
@@ -34354,13 +34925,13 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
34354
34925
|
}
|
|
34355
34926
|
}
|
|
34356
34927
|
function resolveInstallPrefixFromPackageRoot(packageRoot, packageName) {
|
|
34357
|
-
const nodeModulesDir = packageName.startsWith("@") ?
|
|
34358
|
-
if (
|
|
34928
|
+
const nodeModulesDir = packageName.startsWith("@") ? path34.dirname(path34.dirname(packageRoot)) : path34.dirname(packageRoot);
|
|
34929
|
+
if (path34.basename(nodeModulesDir) !== "node_modules") {
|
|
34359
34930
|
return null;
|
|
34360
34931
|
}
|
|
34361
|
-
const maybeLibDir =
|
|
34362
|
-
if (
|
|
34363
|
-
return
|
|
34932
|
+
const maybeLibDir = path34.dirname(nodeModulesDir);
|
|
34933
|
+
if (path34.basename(maybeLibDir) === "lib") {
|
|
34934
|
+
return path34.dirname(maybeLibDir);
|
|
34364
34935
|
}
|
|
34365
34936
|
return maybeLibDir;
|
|
34366
34937
|
}
|
|
@@ -34475,10 +35046,10 @@ async function waitForPidExit(pid, timeoutMs) {
|
|
|
34475
35046
|
}
|
|
34476
35047
|
}
|
|
34477
35048
|
function stopSessionHostProcesses(appName) {
|
|
34478
|
-
const pidFile =
|
|
35049
|
+
const pidFile = path34.join(os26.homedir(), ".adhdev", `${appName}-session-host.pid`);
|
|
34479
35050
|
try {
|
|
34480
|
-
if (
|
|
34481
|
-
const pid = Number.parseInt(
|
|
35051
|
+
if (fs21.existsSync(pidFile)) {
|
|
35052
|
+
const pid = Number.parseInt(fs21.readFileSync(pidFile, "utf8").trim(), 10);
|
|
34482
35053
|
if (Number.isFinite(pid) && pid !== process.pid && isManagedSessionHostPid(pid)) {
|
|
34483
35054
|
killPid(pid);
|
|
34484
35055
|
}
|
|
@@ -34486,15 +35057,15 @@ function stopSessionHostProcesses(appName) {
|
|
|
34486
35057
|
} catch {
|
|
34487
35058
|
} finally {
|
|
34488
35059
|
try {
|
|
34489
|
-
|
|
35060
|
+
fs21.unlinkSync(pidFile);
|
|
34490
35061
|
} catch {
|
|
34491
35062
|
}
|
|
34492
35063
|
}
|
|
34493
35064
|
}
|
|
34494
35065
|
function removeDaemonPidFile() {
|
|
34495
|
-
const pidFile =
|
|
35066
|
+
const pidFile = path34.join(os26.homedir(), ".adhdev", "daemon.pid");
|
|
34496
35067
|
try {
|
|
34497
|
-
|
|
35068
|
+
fs21.unlinkSync(pidFile);
|
|
34498
35069
|
} catch {
|
|
34499
35070
|
}
|
|
34500
35071
|
}
|
|
@@ -34503,7 +35074,7 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
|
|
|
34503
35074
|
const npmRoot = String(execNpmCommandSync(["root", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
|
|
34504
35075
|
if (!npmRoot) return;
|
|
34505
35076
|
const npmPrefix = surface.installPrefix || String(execNpmCommandSync(["prefix", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
|
|
34506
|
-
const binDir = process.platform === "win32" ? npmPrefix :
|
|
35077
|
+
const binDir = process.platform === "win32" ? npmPrefix : path34.join(npmPrefix, "bin");
|
|
34507
35078
|
const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
|
|
34508
35079
|
const binNames = /* @__PURE__ */ new Set([packageBaseName]);
|
|
34509
35080
|
if (pkgName === "@adhdev/daemon-standalone") {
|
|
@@ -34511,25 +35082,25 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
|
|
|
34511
35082
|
}
|
|
34512
35083
|
if (pkgName.startsWith("@")) {
|
|
34513
35084
|
const [scope, name] = pkgName.split("/");
|
|
34514
|
-
const scopeDir =
|
|
34515
|
-
if (!
|
|
34516
|
-
for (const entry of
|
|
35085
|
+
const scopeDir = path34.join(npmRoot, scope);
|
|
35086
|
+
if (!fs21.existsSync(scopeDir)) return;
|
|
35087
|
+
for (const entry of fs21.readdirSync(scopeDir)) {
|
|
34517
35088
|
if (!entry.startsWith(`.${name}-`)) continue;
|
|
34518
|
-
|
|
34519
|
-
appendUpgradeLog(`Removed stale scoped staging dir: ${
|
|
35089
|
+
fs21.rmSync(path34.join(scopeDir, entry), { recursive: true, force: true });
|
|
35090
|
+
appendUpgradeLog(`Removed stale scoped staging dir: ${path34.join(scopeDir, entry)}`);
|
|
34520
35091
|
}
|
|
34521
35092
|
} else {
|
|
34522
|
-
for (const entry of
|
|
35093
|
+
for (const entry of fs21.readdirSync(npmRoot)) {
|
|
34523
35094
|
if (!entry.startsWith(`.${pkgName}-`)) continue;
|
|
34524
|
-
|
|
34525
|
-
appendUpgradeLog(`Removed stale staging dir: ${
|
|
35095
|
+
fs21.rmSync(path34.join(npmRoot, entry), { recursive: true, force: true });
|
|
35096
|
+
appendUpgradeLog(`Removed stale staging dir: ${path34.join(npmRoot, entry)}`);
|
|
34526
35097
|
}
|
|
34527
35098
|
}
|
|
34528
|
-
if (
|
|
34529
|
-
for (const entry of
|
|
35099
|
+
if (fs21.existsSync(binDir)) {
|
|
35100
|
+
for (const entry of fs21.readdirSync(binDir)) {
|
|
34530
35101
|
if (!Array.from(binNames).some((name) => entry.startsWith(`.${name}-`))) continue;
|
|
34531
|
-
|
|
34532
|
-
appendUpgradeLog(`Removed stale bin staging entry: ${
|
|
35102
|
+
fs21.rmSync(path34.join(binDir, entry), { recursive: true, force: true });
|
|
35103
|
+
appendUpgradeLog(`Removed stale bin staging entry: ${path34.join(binDir, entry)}`);
|
|
34533
35104
|
}
|
|
34534
35105
|
}
|
|
34535
35106
|
}
|
|
@@ -34617,7 +35188,7 @@ async function maybeRunDaemonUpgradeHelperFromEnv() {
|
|
|
34617
35188
|
init_mesh_work_queue();
|
|
34618
35189
|
var import_os3 = require("os");
|
|
34619
35190
|
var import_path10 = require("path");
|
|
34620
|
-
var
|
|
35191
|
+
var fs22 = __toESM(require("fs"));
|
|
34621
35192
|
var import_node_child_process5 = require("child_process");
|
|
34622
35193
|
var CHANNEL_NPM_TAG = { stable: "latest", preview: "next" };
|
|
34623
35194
|
var CHANNEL_SERVER_URL = {
|
|
@@ -34744,12 +35315,12 @@ function readGitSubmodules(value, parentRepoRoot) {
|
|
|
34744
35315
|
if (!Array.isArray(value)) return void 0;
|
|
34745
35316
|
const submodules = value.map((entry) => {
|
|
34746
35317
|
const submodule = readObjectRecord(entry);
|
|
34747
|
-
const
|
|
35318
|
+
const path40 = readStringValue(submodule.path);
|
|
34748
35319
|
const commit = readStringValue(submodule.commit);
|
|
34749
|
-
const repoPath = readStringValue(submodule.repoPath, submodule.repo_root) ?? joinRepoPath(parentRepoRoot,
|
|
34750
|
-
if (!
|
|
35320
|
+
const repoPath = readStringValue(submodule.repoPath, submodule.repo_root) ?? joinRepoPath(parentRepoRoot, path40);
|
|
35321
|
+
if (!path40 || !commit || !repoPath) return null;
|
|
34751
35322
|
return {
|
|
34752
|
-
path:
|
|
35323
|
+
path: path40,
|
|
34753
35324
|
commit,
|
|
34754
35325
|
repoPath,
|
|
34755
35326
|
dirty: readBooleanValue(submodule.dirty) ?? false,
|
|
@@ -35391,7 +35962,7 @@ async function hydrateInlineMeshDirectTruth(args) {
|
|
|
35391
35962
|
if (!isSelfNode && daemonId) unavailableNodeIds.push(nodeId);
|
|
35392
35963
|
continue;
|
|
35393
35964
|
}
|
|
35394
|
-
if (
|
|
35965
|
+
if (fs22.existsSync(workspace)) {
|
|
35395
35966
|
try {
|
|
35396
35967
|
const localGit = await getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
|
|
35397
35968
|
if (localGit?.isGitRepo) {
|
|
@@ -35476,7 +36047,7 @@ function readLiveMeshNodeWorkspace(args) {
|
|
|
35476
36047
|
}
|
|
35477
36048
|
function collectLiveMeshSessionRecords(args) {
|
|
35478
36049
|
const nodeWorkspace = readStringValue(args.node?.workspace);
|
|
35479
|
-
const nodeIsMissingLocalWorktree = args.node?.isLocalWorktree === true && !!nodeWorkspace && !
|
|
36050
|
+
const nodeIsMissingLocalWorktree = args.node?.isLocalWorktree === true && !!nodeWorkspace && !fs22.existsSync(nodeWorkspace);
|
|
35480
36051
|
const matches = args.liveSessionRecords.filter((record) => {
|
|
35481
36052
|
const recordNodeId = readStringValue(record?.meta?.meshNodeId);
|
|
35482
36053
|
if (recordNodeId && recordNodeId !== args.nodeId) return false;
|
|
@@ -35503,7 +36074,7 @@ function buildHistoricalMeshSessions(args) {
|
|
|
35503
36074
|
const workspace = readStringValue(node?.workspace);
|
|
35504
36075
|
if (nodeId) liveNodeIds.add(nodeId);
|
|
35505
36076
|
if (workspace) liveWorkspaces.add(workspace);
|
|
35506
|
-
if (nodeId && node?.isLocalWorktree === true && workspace && !
|
|
36077
|
+
if (nodeId && node?.isLocalWorktree === true && workspace && !fs22.existsSync(workspace)) {
|
|
35507
36078
|
missingLocalWorktreeNodeIds.add(nodeId);
|
|
35508
36079
|
}
|
|
35509
36080
|
}
|
|
@@ -35702,10 +36273,10 @@ ${e?.stderr || ""}`
|
|
|
35702
36273
|
}
|
|
35703
36274
|
function buildPatchEquivalenceSubmoduleConflictHint(repoRoot, baseHead, branchHead, output) {
|
|
35704
36275
|
if (!/(submodule|160000)/i.test(output) || !/(conflict|failed to merge)/i.test(output)) return void 0;
|
|
35705
|
-
const conflicts = readChangedGitlinkPaths(repoRoot, baseHead, branchHead).map((
|
|
35706
|
-
path:
|
|
35707
|
-
baseCommit: readTreeObject(repoRoot, baseHead,
|
|
35708
|
-
branchCommit: readTreeObject(repoRoot, branchHead,
|
|
36276
|
+
const conflicts = readChangedGitlinkPaths(repoRoot, baseHead, branchHead).map((path40) => ({
|
|
36277
|
+
path: path40,
|
|
36278
|
+
baseCommit: readTreeObject(repoRoot, baseHead, path40),
|
|
36279
|
+
branchCommit: readTreeObject(repoRoot, branchHead, path40)
|
|
35709
36280
|
}));
|
|
35710
36281
|
if (conflicts.length === 0) return void 0;
|
|
35711
36282
|
return {
|
|
@@ -35731,11 +36302,11 @@ function readChangedGitlinkPaths(repoRoot, fromRef, toRef) {
|
|
|
35731
36302
|
if (!line.trim()) continue;
|
|
35732
36303
|
const metaAndPath = line.split(" ");
|
|
35733
36304
|
const meta = metaAndPath[0] || "";
|
|
35734
|
-
const
|
|
35735
|
-
if (!
|
|
36305
|
+
const path40 = metaAndPath[metaAndPath.length - 1]?.trim();
|
|
36306
|
+
if (!path40) continue;
|
|
35736
36307
|
const parts = meta.split(/\s+/);
|
|
35737
36308
|
if (parts[0]?.includes("160000") || parts[1]?.includes("160000")) {
|
|
35738
|
-
paths.add(
|
|
36309
|
+
paths.add(path40);
|
|
35739
36310
|
}
|
|
35740
36311
|
}
|
|
35741
36312
|
return [...paths].sort();
|
|
@@ -35743,9 +36314,9 @@ function readChangedGitlinkPaths(repoRoot, fromRef, toRef) {
|
|
|
35743
36314
|
return [];
|
|
35744
36315
|
}
|
|
35745
36316
|
}
|
|
35746
|
-
function readTreeObject(repoRoot, ref,
|
|
36317
|
+
function readTreeObject(repoRoot, ref, path40) {
|
|
35747
36318
|
try {
|
|
35748
|
-
const output = (0, import_node_child_process5.execFileSync)("git", ["ls-tree", ref, "--",
|
|
36319
|
+
const output = (0, import_node_child_process5.execFileSync)("git", ["ls-tree", ref, "--", path40], {
|
|
35749
36320
|
cwd: repoRoot,
|
|
35750
36321
|
encoding: "utf8",
|
|
35751
36322
|
maxBuffer: 1024 * 1024
|
|
@@ -35758,7 +36329,7 @@ function readTreeObject(repoRoot, ref, path39) {
|
|
|
35758
36329
|
}
|
|
35759
36330
|
async function alignRefinerySubmodulesAfterMerge(repoRoot, previousBaseHead, currentHead, options = {}) {
|
|
35760
36331
|
const startedAt = Date.now();
|
|
35761
|
-
const changedGitlinkPaths = readChangedGitlinkPaths(repoRoot, previousBaseHead, currentHead).filter((
|
|
36332
|
+
const changedGitlinkPaths = readChangedGitlinkPaths(repoRoot, previousBaseHead, currentHead).filter((path40) => !(options.submoduleIgnorePaths || []).includes(path40));
|
|
35762
36333
|
const preStatus = await getGitRepoStatus(repoRoot, {
|
|
35763
36334
|
includeSubmodules: true,
|
|
35764
36335
|
submoduleIgnorePaths: options.submoduleIgnorePaths,
|
|
@@ -35799,7 +36370,7 @@ async function alignRefinerySubmodulesAfterMerge(repoRoot, previousBaseHead, cur
|
|
|
35799
36370
|
changedGitlinkPaths,
|
|
35800
36371
|
outOfSyncPaths,
|
|
35801
36372
|
updatedPaths: updatePaths,
|
|
35802
|
-
verifiedPaths: updatePaths.filter((
|
|
36373
|
+
verifiedPaths: updatePaths.filter((path40) => !remaining.some((submodule) => submodule.path === path40)),
|
|
35803
36374
|
durationMs: Date.now() - startedAt,
|
|
35804
36375
|
command: `git ${commandArgs.join(" ")}`,
|
|
35805
36376
|
stdout: truncateValidationOutput(result.stdout),
|
|
@@ -35854,7 +36425,7 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
35854
36425
|
return { stdout: String(stdout || ""), stderr: String(stderr || ""), refspec };
|
|
35855
36426
|
};
|
|
35856
36427
|
const importCommitFromWorktreeSubmodule = async (submodulePath, worktreeSubmodulePath, commit) => {
|
|
35857
|
-
if (!
|
|
36428
|
+
if (!fs22.existsSync(worktreeSubmodulePath)) return false;
|
|
35858
36429
|
try {
|
|
35859
36430
|
await runGit3(worktreeSubmodulePath, ["cat-file", "-e", `${commit}^{commit}`]);
|
|
35860
36431
|
} catch {
|
|
@@ -35877,7 +36448,7 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
35877
36448
|
reachable: false
|
|
35878
36449
|
};
|
|
35879
36450
|
try {
|
|
35880
|
-
if (!
|
|
36451
|
+
if (!fs22.existsSync(submodulePath)) {
|
|
35881
36452
|
entry.error = `Submodule checkout missing at ${gitlink.path}`;
|
|
35882
36453
|
entry.publishRequired = true;
|
|
35883
36454
|
if (options.allowAutoPublishSubmoduleMainCommits === true) {
|
|
@@ -36069,9 +36640,9 @@ async function runMeshRefineValidationGate(mesh, workspace) {
|
|
|
36069
36640
|
return ["npm", "pnpm", "yarn", "bun"].includes(command) && candidate.args.some((arg) => arg === "run" || arg === "test" || arg === "exec");
|
|
36070
36641
|
};
|
|
36071
36642
|
const dependenciesLikelyMissing = (cwd) => {
|
|
36072
|
-
if (!
|
|
36073
|
-
if (
|
|
36074
|
-
return ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"].some((lock) =>
|
|
36643
|
+
if (!fs22.existsSync((0, import_path10.join)(cwd, "package.json"))) return false;
|
|
36644
|
+
if (fs22.existsSync((0, import_path10.join)(cwd, "node_modules"))) return false;
|
|
36645
|
+
return ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"].some((lock) => fs22.existsSync((0, import_path10.join)(cwd, lock)));
|
|
36075
36646
|
};
|
|
36076
36647
|
for (const candidate of selection.bootstrapCommands) {
|
|
36077
36648
|
const startedAt = Date.now();
|
|
@@ -36168,9 +36739,9 @@ function resolveHermesUserHome() {
|
|
|
36168
36739
|
function loadHermesCoordinatorBaseConfig(targetConfigPath) {
|
|
36169
36740
|
const sourceHome = resolveHermesUserHome();
|
|
36170
36741
|
const sourceConfigPath = (0, import_path10.join)(sourceHome, "config.yaml");
|
|
36171
|
-
if (!
|
|
36742
|
+
if (!fs22.existsSync(sourceConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
36172
36743
|
if ((0, import_path10.resolve)(sourceConfigPath) === (0, import_path10.resolve)(targetConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
36173
|
-
const parsed = parseMeshCoordinatorMcpConfig(
|
|
36744
|
+
const parsed = parseMeshCoordinatorMcpConfig(fs22.readFileSync(sourceConfigPath, "utf-8"), "hermes_config_yaml");
|
|
36174
36745
|
const { mcp_servers: _mcpServers, ...baseConfig } = parsed;
|
|
36175
36746
|
return { config: baseConfig, sourceHome, sourceConfigPath };
|
|
36176
36747
|
}
|
|
@@ -36207,9 +36778,9 @@ function copyHermesCoordinatorCredentialFiles(sourceHome, targetHome) {
|
|
|
36207
36778
|
for (const fileName of [".env", "auth.json"]) {
|
|
36208
36779
|
const sourcePath = (0, import_path10.join)(sourceHome, fileName);
|
|
36209
36780
|
const targetPath = (0, import_path10.join)(targetHome, fileName);
|
|
36210
|
-
if (!
|
|
36781
|
+
if (!fs22.existsSync(sourcePath)) continue;
|
|
36211
36782
|
try {
|
|
36212
|
-
|
|
36783
|
+
fs22.copyFileSync(sourcePath, targetPath);
|
|
36213
36784
|
} catch (error) {
|
|
36214
36785
|
LOG.warn("MeshCoordinator", `Could not copy Hermes ${fileName} into isolated coordinator home: ${error?.message || error}`);
|
|
36215
36786
|
}
|
|
@@ -36564,13 +37135,13 @@ var DaemonCommandRouter = class {
|
|
|
36564
37135
|
recoveryHint: "Inspect the mesh node record before removing it, or remove stale metadata manually only after confirming no managed worktree remains."
|
|
36565
37136
|
};
|
|
36566
37137
|
}
|
|
36567
|
-
const worktreeExists =
|
|
37138
|
+
const worktreeExists = fs22.existsSync(workspace);
|
|
36568
37139
|
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);
|
|
36569
37140
|
const repoRoot = typeof sourceNode?.repoRoot === "string" && sourceNode.repoRoot.trim() ? sourceNode.repoRoot.trim() : typeof sourceNode?.workspace === "string" && sourceNode.workspace.trim() ? sourceNode.workspace.trim() : "";
|
|
36570
37141
|
if (!worktreeExists) {
|
|
36571
37142
|
return { success: true, skipped: true, removedPath: workspace, repoRoot: repoRoot || void 0, reason: "worktree_path_missing" };
|
|
36572
37143
|
}
|
|
36573
|
-
if (!repoRoot || !
|
|
37144
|
+
if (!repoRoot || !fs22.existsSync(repoRoot)) {
|
|
36574
37145
|
return {
|
|
36575
37146
|
success: false,
|
|
36576
37147
|
code: "mesh_worktree_cleanup_missing_source_repo",
|
|
@@ -36590,7 +37161,7 @@ var DaemonCommandRouter = class {
|
|
|
36590
37161
|
const normalizePath = (value) => {
|
|
36591
37162
|
const resolved = (0, import_path10.resolve)(value);
|
|
36592
37163
|
try {
|
|
36593
|
-
return
|
|
37164
|
+
return fs22.realpathSync(resolved);
|
|
36594
37165
|
} catch {
|
|
36595
37166
|
return resolved;
|
|
36596
37167
|
}
|
|
@@ -37529,8 +38100,8 @@ var DaemonCommandRouter = class {
|
|
|
37529
38100
|
if (sinceTs > 0) {
|
|
37530
38101
|
return { success: true, logs: [], totalBuffered: 0 };
|
|
37531
38102
|
}
|
|
37532
|
-
if (
|
|
37533
|
-
const content =
|
|
38103
|
+
if (fs22.existsSync(LOG_PATH)) {
|
|
38104
|
+
const content = fs22.readFileSync(LOG_PATH, "utf-8");
|
|
37534
38105
|
const allLines = content.split("\n");
|
|
37535
38106
|
const recent = allLines.slice(-count).join("\n");
|
|
37536
38107
|
return { success: true, logs: recent, totalLines: allLines.length };
|
|
@@ -37920,24 +38491,24 @@ var DaemonCommandRouter = class {
|
|
|
37920
38491
|
// Settings page in the dashboard reads/writes via these two
|
|
37921
38492
|
// commands instead of going through fs from the browser.
|
|
37922
38493
|
case "list_coordinator_prompts": {
|
|
37923
|
-
const
|
|
37924
|
-
const
|
|
37925
|
-
const
|
|
37926
|
-
const dir =
|
|
38494
|
+
const fs28 = await import("fs");
|
|
38495
|
+
const path40 = await import("path");
|
|
38496
|
+
const os29 = await import("os");
|
|
38497
|
+
const dir = path40.join(os29.homedir(), ".adhdev", "coordinator-prompts");
|
|
37927
38498
|
const entries = {};
|
|
37928
38499
|
try {
|
|
37929
|
-
if (
|
|
37930
|
-
for (const name of
|
|
38500
|
+
if (fs28.existsSync(dir)) {
|
|
38501
|
+
for (const name of fs28.readdirSync(dir)) {
|
|
37931
38502
|
const matchOverride = name.match(/^([a-zA-Z0-9_.-]+)\.md$/);
|
|
37932
38503
|
const matchAppend = name.match(/^([a-zA-Z0-9_.-]+)\.append\.md$/);
|
|
37933
38504
|
const m = matchAppend || matchOverride;
|
|
37934
38505
|
if (!m) continue;
|
|
37935
38506
|
const isAppend = !!matchAppend;
|
|
37936
38507
|
const key = m[1];
|
|
37937
|
-
const full =
|
|
38508
|
+
const full = path40.join(dir, name);
|
|
37938
38509
|
let content = "";
|
|
37939
38510
|
try {
|
|
37940
|
-
content =
|
|
38511
|
+
content = fs28.readFileSync(full, "utf8");
|
|
37941
38512
|
} catch {
|
|
37942
38513
|
}
|
|
37943
38514
|
if (!entries[key]) entries[key] = { override: "", append: "" };
|
|
@@ -37951,24 +38522,24 @@ var DaemonCommandRouter = class {
|
|
|
37951
38522
|
return { success: true, dir, entries };
|
|
37952
38523
|
}
|
|
37953
38524
|
case "write_coordinator_prompt": {
|
|
37954
|
-
const
|
|
37955
|
-
const
|
|
37956
|
-
const
|
|
38525
|
+
const fs28 = await import("fs");
|
|
38526
|
+
const path40 = await import("path");
|
|
38527
|
+
const os29 = await import("os");
|
|
37957
38528
|
const key = typeof args?.key === "string" ? args.key.trim() : "";
|
|
37958
38529
|
const kind = args?.kind === "append" ? "append" : "override";
|
|
37959
38530
|
const content = typeof args?.content === "string" ? args.content : "";
|
|
37960
38531
|
if (!key || !/^[a-zA-Z0-9_.-]+$/.test(key)) {
|
|
37961
38532
|
return { success: false, error: "key must match [a-zA-Z0-9_.-]+" };
|
|
37962
38533
|
}
|
|
37963
|
-
const dir =
|
|
38534
|
+
const dir = path40.join(os29.homedir(), ".adhdev", "coordinator-prompts");
|
|
37964
38535
|
const filename = kind === "append" ? `${key}.append.md` : `${key}.md`;
|
|
37965
|
-
const full =
|
|
38536
|
+
const full = path40.join(dir, filename);
|
|
37966
38537
|
try {
|
|
37967
|
-
|
|
38538
|
+
fs28.mkdirSync(dir, { recursive: true });
|
|
37968
38539
|
if (content.trim()) {
|
|
37969
|
-
|
|
37970
|
-
} else if (
|
|
37971
|
-
|
|
38540
|
+
fs28.writeFileSync(full, content, { encoding: "utf8", mode: 384 });
|
|
38541
|
+
} else if (fs28.existsSync(full)) {
|
|
38542
|
+
fs28.unlinkSync(full);
|
|
37972
38543
|
}
|
|
37973
38544
|
return { success: true, path: full, kind, key };
|
|
37974
38545
|
} catch (error) {
|
|
@@ -39177,7 +39748,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
39177
39748
|
workspace
|
|
39178
39749
|
};
|
|
39179
39750
|
}
|
|
39180
|
-
const { existsSync:
|
|
39751
|
+
const { existsSync: existsSync39, readFileSync: readFileSync33, writeFileSync: writeFileSync20, copyFileSync: copyFileSync4, mkdirSync: mkdirSync19 } = await import("fs");
|
|
39181
39752
|
const { dirname: dirname11 } = await import("path");
|
|
39182
39753
|
const mcpConfigPath = coordinatorSetup.configPath;
|
|
39183
39754
|
const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
|
|
@@ -39213,21 +39784,21 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
39213
39784
|
};
|
|
39214
39785
|
}
|
|
39215
39786
|
try {
|
|
39216
|
-
|
|
39787
|
+
mkdirSync19(dirname11(mcpConfigPath), { recursive: true });
|
|
39217
39788
|
} catch (error) {
|
|
39218
39789
|
const message = `Could not prepare MCP config path for automatic setup: ${error?.message || error}`;
|
|
39219
39790
|
LOG.error("MeshCoordinator", message);
|
|
39220
39791
|
if (hermesManualFallback) return returnManualFallback(message);
|
|
39221
39792
|
return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
|
|
39222
39793
|
}
|
|
39223
|
-
const hadExistingMcpConfig =
|
|
39794
|
+
const hadExistingMcpConfig = existsSync39(mcpConfigPath);
|
|
39224
39795
|
let existingMcpConfig = hermesBaseConfig?.config || {};
|
|
39225
39796
|
if (hermesBaseConfig) {
|
|
39226
39797
|
copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname11(mcpConfigPath));
|
|
39227
39798
|
}
|
|
39228
39799
|
if (hadExistingMcpConfig) {
|
|
39229
39800
|
try {
|
|
39230
|
-
const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(
|
|
39801
|
+
const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync33(mcpConfigPath, "utf-8"), configFormat);
|
|
39231
39802
|
const existingCoordinatorConfig = hermesManualFallback ? stripHermesCoordinatorTempModelProviderOverrides(parsedExistingMcpConfig) : parsedExistingMcpConfig;
|
|
39232
39803
|
existingMcpConfig = { ...existingMcpConfig, ...existingCoordinatorConfig };
|
|
39233
39804
|
copyFileSync4(mcpConfigPath, mcpConfigPath + ".backup");
|
|
@@ -39250,7 +39821,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
39250
39821
|
}
|
|
39251
39822
|
};
|
|
39252
39823
|
try {
|
|
39253
|
-
|
|
39824
|
+
writeFileSync20(mcpConfigPath, serializeMeshCoordinatorMcpConfig(mcpConfig, configFormat), "utf-8");
|
|
39254
39825
|
} catch (error) {
|
|
39255
39826
|
const message = `Could not write MCP config for automatic setup: ${error?.message || error}`;
|
|
39256
39827
|
LOG.error("MeshCoordinator", message);
|
|
@@ -39529,7 +40100,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
39529
40100
|
}
|
|
39530
40101
|
}
|
|
39531
40102
|
if (workspace) {
|
|
39532
|
-
if (!
|
|
40103
|
+
if (!fs22.existsSync(workspace)) {
|
|
39533
40104
|
const inlineTransitGit = buildInlineMeshTransitGitStatus(node);
|
|
39534
40105
|
let remoteProbeApplied = false;
|
|
39535
40106
|
if (inlineTransitGit) {
|
|
@@ -39642,7 +40213,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
39642
40213
|
const callerCoordinatorDaemonId = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : this.deps.statusInstanceId || void 0;
|
|
39643
40214
|
const pendingCoordinatorEvents = drainPendingMeshCoordinatorEvents(meshId, callerCoordinatorDaemonId);
|
|
39644
40215
|
const previewFreshness = (() => {
|
|
39645
|
-
const localRepoRoot = nodeStatuses.map((node) => readStringValue(node?.git?.repoRoot, node?.repoRoot, node?.workspace)).find((candidate) => !!candidate &&
|
|
40216
|
+
const localRepoRoot = nodeStatuses.map((node) => readStringValue(node?.git?.repoRoot, node?.repoRoot, node?.workspace)).find((candidate) => !!candidate && fs22.existsSync(candidate));
|
|
39646
40217
|
return localRepoRoot ? buildPreviewFreshness(localRepoRoot) : void 0;
|
|
39647
40218
|
})();
|
|
39648
40219
|
const asyncRefineJobs = buildMeshAsyncRefineJobs({
|
|
@@ -41389,12 +41960,12 @@ var ProviderInstanceManager = class {
|
|
|
41389
41960
|
};
|
|
41390
41961
|
|
|
41391
41962
|
// src/providers/version-archive.ts
|
|
41392
|
-
var
|
|
41393
|
-
var
|
|
41394
|
-
var
|
|
41963
|
+
var fs23 = __toESM(require("fs"));
|
|
41964
|
+
var path35 = __toESM(require("path"));
|
|
41965
|
+
var os27 = __toESM(require("os"));
|
|
41395
41966
|
var import_os4 = require("os");
|
|
41396
41967
|
var import_child_process9 = require("child_process");
|
|
41397
|
-
var ARCHIVE_PATH =
|
|
41968
|
+
var ARCHIVE_PATH = path35.join(os27.homedir(), ".adhdev", "version-history.json");
|
|
41398
41969
|
var MAX_ENTRIES_PER_PROVIDER = 20;
|
|
41399
41970
|
var VersionArchive = class {
|
|
41400
41971
|
history = {};
|
|
@@ -41403,8 +41974,8 @@ var VersionArchive = class {
|
|
|
41403
41974
|
}
|
|
41404
41975
|
load() {
|
|
41405
41976
|
try {
|
|
41406
|
-
if (
|
|
41407
|
-
this.history = JSON.parse(
|
|
41977
|
+
if (fs23.existsSync(ARCHIVE_PATH)) {
|
|
41978
|
+
this.history = JSON.parse(fs23.readFileSync(ARCHIVE_PATH, "utf-8"));
|
|
41408
41979
|
}
|
|
41409
41980
|
} catch {
|
|
41410
41981
|
this.history = {};
|
|
@@ -41441,8 +42012,8 @@ var VersionArchive = class {
|
|
|
41441
42012
|
}
|
|
41442
42013
|
save() {
|
|
41443
42014
|
try {
|
|
41444
|
-
|
|
41445
|
-
|
|
42015
|
+
fs23.mkdirSync(path35.dirname(ARCHIVE_PATH), { recursive: true });
|
|
42016
|
+
fs23.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
|
|
41446
42017
|
} catch {
|
|
41447
42018
|
}
|
|
41448
42019
|
}
|
|
@@ -41465,10 +42036,10 @@ function findBinary2(name) {
|
|
|
41465
42036
|
for (const p of paths) {
|
|
41466
42037
|
if (!p) continue;
|
|
41467
42038
|
for (const ext of exes) {
|
|
41468
|
-
const fullPath =
|
|
42039
|
+
const fullPath = path35.join(p, name + ext);
|
|
41469
42040
|
try {
|
|
41470
|
-
if (
|
|
41471
|
-
const stat2 =
|
|
42041
|
+
if (fs23.existsSync(fullPath)) {
|
|
42042
|
+
const stat2 = fs23.statSync(fullPath);
|
|
41472
42043
|
if (stat2.isFile() && (isWin || stat2.mode & 73)) {
|
|
41473
42044
|
return fullPath;
|
|
41474
42045
|
}
|
|
@@ -41513,19 +42084,19 @@ async function getVersion(binary, versionCommand) {
|
|
|
41513
42084
|
function checkPathExists2(paths) {
|
|
41514
42085
|
for (const p of paths) {
|
|
41515
42086
|
if (p.includes("*")) {
|
|
41516
|
-
const home =
|
|
41517
|
-
const resolved = p.replace(/\*/g, home.split(
|
|
41518
|
-
if (
|
|
42087
|
+
const home = os27.homedir();
|
|
42088
|
+
const resolved = p.replace(/\*/g, home.split(path35.sep).pop() || "");
|
|
42089
|
+
if (fs23.existsSync(resolved)) return resolved;
|
|
41519
42090
|
} else {
|
|
41520
|
-
if (
|
|
42091
|
+
if (fs23.existsSync(p)) return p;
|
|
41521
42092
|
}
|
|
41522
42093
|
}
|
|
41523
42094
|
return null;
|
|
41524
42095
|
}
|
|
41525
42096
|
async function getMacAppVersion(appPath) {
|
|
41526
42097
|
if ((0, import_os4.platform)() !== "darwin" || !appPath.endsWith(".app")) return null;
|
|
41527
|
-
const plistPath =
|
|
41528
|
-
if (!
|
|
42098
|
+
const plistPath = path35.join(appPath, "Contents", "Info.plist");
|
|
42099
|
+
if (!fs23.existsSync(plistPath)) return null;
|
|
41529
42100
|
const raw = await runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
|
|
41530
42101
|
return raw || null;
|
|
41531
42102
|
}
|
|
@@ -41550,8 +42121,8 @@ async function detectAllVersions(loader, archive) {
|
|
|
41550
42121
|
const cliBin = provider.cli ? findBinary2(provider.cli) : null;
|
|
41551
42122
|
let resolvedBin = cliBin;
|
|
41552
42123
|
if (!resolvedBin && appPath && currentOs === "darwin") {
|
|
41553
|
-
const bundled =
|
|
41554
|
-
if (provider.cli &&
|
|
42124
|
+
const bundled = path35.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
|
|
42125
|
+
if (provider.cli && fs23.existsSync(bundled)) resolvedBin = bundled;
|
|
41555
42126
|
}
|
|
41556
42127
|
info.installed = !!(appPath || resolvedBin);
|
|
41557
42128
|
info.path = appPath || null;
|
|
@@ -41590,8 +42161,8 @@ async function detectAllVersions(loader, archive) {
|
|
|
41590
42161
|
|
|
41591
42162
|
// src/daemon/dev-server.ts
|
|
41592
42163
|
var http2 = __toESM(require("http"));
|
|
41593
|
-
var
|
|
41594
|
-
var
|
|
42164
|
+
var fs27 = __toESM(require("fs"));
|
|
42165
|
+
var path39 = __toESM(require("path"));
|
|
41595
42166
|
init_config();
|
|
41596
42167
|
|
|
41597
42168
|
// src/daemon/scaffold-template.ts
|
|
@@ -41941,8 +42512,8 @@ async (params) => {
|
|
|
41941
42512
|
init_logger();
|
|
41942
42513
|
|
|
41943
42514
|
// src/daemon/dev-cdp-handlers.ts
|
|
41944
|
-
var
|
|
41945
|
-
var
|
|
42515
|
+
var fs24 = __toESM(require("fs"));
|
|
42516
|
+
var path36 = __toESM(require("path"));
|
|
41946
42517
|
init_logger();
|
|
41947
42518
|
async function handleCdpEvaluate(ctx, req, res) {
|
|
41948
42519
|
const body = await ctx.readBody(req);
|
|
@@ -42121,18 +42692,18 @@ async function handleScriptHints(ctx, type, _req, res) {
|
|
|
42121
42692
|
return;
|
|
42122
42693
|
}
|
|
42123
42694
|
let scriptsPath = "";
|
|
42124
|
-
const directScripts =
|
|
42125
|
-
if (
|
|
42695
|
+
const directScripts = path36.join(dir, "scripts.js");
|
|
42696
|
+
if (fs24.existsSync(directScripts)) {
|
|
42126
42697
|
scriptsPath = directScripts;
|
|
42127
42698
|
} else {
|
|
42128
|
-
const scriptsDir =
|
|
42129
|
-
if (
|
|
42130
|
-
const versions =
|
|
42131
|
-
return
|
|
42699
|
+
const scriptsDir = path36.join(dir, "scripts");
|
|
42700
|
+
if (fs24.existsSync(scriptsDir)) {
|
|
42701
|
+
const versions = fs24.readdirSync(scriptsDir).filter((d) => {
|
|
42702
|
+
return fs24.statSync(path36.join(scriptsDir, d)).isDirectory();
|
|
42132
42703
|
}).sort().reverse();
|
|
42133
42704
|
for (const ver of versions) {
|
|
42134
|
-
const p =
|
|
42135
|
-
if (
|
|
42705
|
+
const p = path36.join(scriptsDir, ver, "scripts.js");
|
|
42706
|
+
if (fs24.existsSync(p)) {
|
|
42136
42707
|
scriptsPath = p;
|
|
42137
42708
|
break;
|
|
42138
42709
|
}
|
|
@@ -42144,7 +42715,7 @@ async function handleScriptHints(ctx, type, _req, res) {
|
|
|
42144
42715
|
return;
|
|
42145
42716
|
}
|
|
42146
42717
|
try {
|
|
42147
|
-
const source =
|
|
42718
|
+
const source = fs24.readFileSync(scriptsPath, "utf-8");
|
|
42148
42719
|
const hints = {};
|
|
42149
42720
|
const funcRegex = /module\.exports\.(\w+)\s*=\s*function\s+\w+\s*\(params\)/g;
|
|
42150
42721
|
let match;
|
|
@@ -42959,8 +43530,8 @@ async function handleDomContext(ctx, type, req, res) {
|
|
|
42959
43530
|
}
|
|
42960
43531
|
|
|
42961
43532
|
// src/daemon/dev-cli-debug.ts
|
|
42962
|
-
var
|
|
42963
|
-
var
|
|
43533
|
+
var fs25 = __toESM(require("fs"));
|
|
43534
|
+
var path37 = __toESM(require("path"));
|
|
42964
43535
|
function slugifyFixtureName(value) {
|
|
42965
43536
|
const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
42966
43537
|
return normalized || `fixture-${Date.now()}`;
|
|
@@ -42970,15 +43541,15 @@ function getCliFixtureDir(ctx, type) {
|
|
|
42970
43541
|
if (!providerDir) {
|
|
42971
43542
|
throw new Error(`Provider directory not found for '${type}'`);
|
|
42972
43543
|
}
|
|
42973
|
-
return
|
|
43544
|
+
return path37.join(providerDir, "fixtures");
|
|
42974
43545
|
}
|
|
42975
43546
|
function readCliFixture(ctx, type, name) {
|
|
42976
43547
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
42977
|
-
const filePath =
|
|
42978
|
-
if (!
|
|
43548
|
+
const filePath = path37.join(fixtureDir, `${name}.json`);
|
|
43549
|
+
if (!fs25.existsSync(filePath)) {
|
|
42979
43550
|
throw new Error(`Fixture not found: ${filePath}`);
|
|
42980
43551
|
}
|
|
42981
|
-
return JSON.parse(
|
|
43552
|
+
return JSON.parse(fs25.readFileSync(filePath, "utf-8"));
|
|
42982
43553
|
}
|
|
42983
43554
|
function getExerciseTranscriptText(result) {
|
|
42984
43555
|
const parts = [];
|
|
@@ -43723,7 +44294,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
43723
44294
|
return;
|
|
43724
44295
|
}
|
|
43725
44296
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
43726
|
-
|
|
44297
|
+
fs25.mkdirSync(fixtureDir, { recursive: true });
|
|
43727
44298
|
const name = slugifyFixtureName(String(body?.name || `${type}-${Date.now()}`));
|
|
43728
44299
|
const result = await runCliExerciseInternal(ctx, { ...request, type });
|
|
43729
44300
|
const fixture = {
|
|
@@ -43750,8 +44321,8 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
43750
44321
|
},
|
|
43751
44322
|
notes: typeof body?.notes === "string" ? body.notes : void 0
|
|
43752
44323
|
};
|
|
43753
|
-
const filePath =
|
|
43754
|
-
|
|
44324
|
+
const filePath = path37.join(fixtureDir, `${name}.json`);
|
|
44325
|
+
fs25.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
|
|
43755
44326
|
ctx.json(res, 200, {
|
|
43756
44327
|
saved: true,
|
|
43757
44328
|
name,
|
|
@@ -43769,14 +44340,14 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
43769
44340
|
async function handleCliFixtureList(ctx, type, _req, res) {
|
|
43770
44341
|
try {
|
|
43771
44342
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
43772
|
-
if (!
|
|
44343
|
+
if (!fs25.existsSync(fixtureDir)) {
|
|
43773
44344
|
ctx.json(res, 200, { fixtures: [], count: 0 });
|
|
43774
44345
|
return;
|
|
43775
44346
|
}
|
|
43776
|
-
const fixtures =
|
|
43777
|
-
const fullPath =
|
|
44347
|
+
const fixtures = fs25.readdirSync(fixtureDir).filter((file) => file.endsWith(".json")).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file) => {
|
|
44348
|
+
const fullPath = path37.join(fixtureDir, file);
|
|
43778
44349
|
try {
|
|
43779
|
-
const raw = JSON.parse(
|
|
44350
|
+
const raw = JSON.parse(fs25.readFileSync(fullPath, "utf-8"));
|
|
43780
44351
|
return {
|
|
43781
44352
|
name: raw.name || file.replace(/\.json$/i, ""),
|
|
43782
44353
|
path: fullPath,
|
|
@@ -43909,9 +44480,9 @@ async function handleCliRaw(ctx, req, res) {
|
|
|
43909
44480
|
}
|
|
43910
44481
|
|
|
43911
44482
|
// src/daemon/dev-auto-implement.ts
|
|
43912
|
-
var
|
|
43913
|
-
var
|
|
43914
|
-
var
|
|
44483
|
+
var fs26 = __toESM(require("fs"));
|
|
44484
|
+
var path38 = __toESM(require("path"));
|
|
44485
|
+
var os28 = __toESM(require("os"));
|
|
43915
44486
|
function getAutoImplPid(ctx) {
|
|
43916
44487
|
const pid = ctx.autoImplProcess?.pid;
|
|
43917
44488
|
return typeof pid === "number" && pid > 0 ? pid : null;
|
|
@@ -43957,38 +44528,38 @@ function resolveAutoImplReference(ctx, category, requestedReference, targetType)
|
|
|
43957
44528
|
return fallback?.type || null;
|
|
43958
44529
|
}
|
|
43959
44530
|
function getLatestScriptVersionDir(scriptsDir) {
|
|
43960
|
-
if (!
|
|
43961
|
-
const versions =
|
|
44531
|
+
if (!fs26.existsSync(scriptsDir)) return null;
|
|
44532
|
+
const versions = fs26.readdirSync(scriptsDir).filter((d) => {
|
|
43962
44533
|
try {
|
|
43963
|
-
return
|
|
44534
|
+
return fs26.statSync(path38.join(scriptsDir, d)).isDirectory();
|
|
43964
44535
|
} catch {
|
|
43965
44536
|
return false;
|
|
43966
44537
|
}
|
|
43967
44538
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
43968
44539
|
if (versions.length === 0) return null;
|
|
43969
|
-
return
|
|
44540
|
+
return path38.join(scriptsDir, versions[0]);
|
|
43970
44541
|
}
|
|
43971
44542
|
function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
43972
|
-
const canonicalUserDir =
|
|
43973
|
-
const desiredDir = requestedDir ?
|
|
43974
|
-
const upstreamRoot =
|
|
43975
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
44543
|
+
const canonicalUserDir = path38.resolve(ctx.providerLoader.getUserProviderDir(category, type));
|
|
44544
|
+
const desiredDir = requestedDir ? path38.resolve(requestedDir) : canonicalUserDir;
|
|
44545
|
+
const upstreamRoot = path38.resolve(ctx.providerLoader.getUpstreamDir());
|
|
44546
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path38.sep}`)) {
|
|
43976
44547
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
43977
44548
|
}
|
|
43978
|
-
if (
|
|
44549
|
+
if (path38.basename(desiredDir) !== type) {
|
|
43979
44550
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
43980
44551
|
}
|
|
43981
44552
|
const sourceDir = ctx.findProviderDir(type);
|
|
43982
44553
|
if (!sourceDir) {
|
|
43983
44554
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
43984
44555
|
}
|
|
43985
|
-
if (!
|
|
43986
|
-
|
|
43987
|
-
|
|
44556
|
+
if (!fs26.existsSync(desiredDir)) {
|
|
44557
|
+
fs26.mkdirSync(path38.dirname(desiredDir), { recursive: true });
|
|
44558
|
+
fs26.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
43988
44559
|
ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
43989
44560
|
}
|
|
43990
|
-
const providerJson =
|
|
43991
|
-
if (!
|
|
44561
|
+
const providerJson = path38.join(desiredDir, "provider.json");
|
|
44562
|
+
if (!fs26.existsSync(providerJson)) {
|
|
43992
44563
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
43993
44564
|
}
|
|
43994
44565
|
return { dir: desiredDir };
|
|
@@ -43996,15 +44567,15 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
|
43996
44567
|
function loadAutoImplReferenceScripts(ctx, referenceType) {
|
|
43997
44568
|
if (!referenceType) return {};
|
|
43998
44569
|
const refDir = ctx.findProviderDir(referenceType);
|
|
43999
|
-
if (!refDir || !
|
|
44570
|
+
if (!refDir || !fs26.existsSync(refDir)) return {};
|
|
44000
44571
|
const referenceScripts = {};
|
|
44001
|
-
const scriptsDir =
|
|
44572
|
+
const scriptsDir = path38.join(refDir, "scripts");
|
|
44002
44573
|
const latestDir = getLatestScriptVersionDir(scriptsDir);
|
|
44003
44574
|
if (!latestDir) return referenceScripts;
|
|
44004
|
-
for (const file of
|
|
44575
|
+
for (const file of fs26.readdirSync(latestDir)) {
|
|
44005
44576
|
if (!file.endsWith(".js")) continue;
|
|
44006
44577
|
try {
|
|
44007
|
-
referenceScripts[file] =
|
|
44578
|
+
referenceScripts[file] = fs26.readFileSync(path38.join(latestDir, file), "utf-8");
|
|
44008
44579
|
} catch {
|
|
44009
44580
|
}
|
|
44010
44581
|
}
|
|
@@ -44112,16 +44683,16 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
44112
44683
|
});
|
|
44113
44684
|
const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
|
|
44114
44685
|
const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
|
|
44115
|
-
const tmpDir =
|
|
44116
|
-
if (!
|
|
44117
|
-
const promptFile =
|
|
44118
|
-
|
|
44686
|
+
const tmpDir = path38.join(os28.tmpdir(), "adhdev-autoimpl");
|
|
44687
|
+
if (!fs26.existsSync(tmpDir)) fs26.mkdirSync(tmpDir, { recursive: true });
|
|
44688
|
+
const promptFile = path38.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
|
|
44689
|
+
fs26.writeFileSync(promptFile, prompt, "utf-8");
|
|
44119
44690
|
ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
|
|
44120
44691
|
const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
|
|
44121
44692
|
const spawn4 = agentProvider?.spawn;
|
|
44122
44693
|
if (!spawn4?.command) {
|
|
44123
44694
|
try {
|
|
44124
|
-
|
|
44695
|
+
fs26.unlinkSync(promptFile);
|
|
44125
44696
|
} catch {
|
|
44126
44697
|
}
|
|
44127
44698
|
ctx.json(res, 400, { error: `Agent '${agent}' has no spawn config. Select a CLI provider with a spawn configuration.` });
|
|
@@ -44223,7 +44794,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
44223
44794
|
} catch {
|
|
44224
44795
|
}
|
|
44225
44796
|
try {
|
|
44226
|
-
|
|
44797
|
+
fs26.unlinkSync(promptFile);
|
|
44227
44798
|
} catch {
|
|
44228
44799
|
}
|
|
44229
44800
|
ctx.log(`Auto-implement (ACP) ${success ? "completed" : "failed"}: ${type} (exit: ${code})`);
|
|
@@ -44267,7 +44838,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
44267
44838
|
const interactiveFlags = ["--yolo", "--interactive", "-i"];
|
|
44268
44839
|
const baseArgs = [...spawn4.args || []].filter((a) => !interactiveFlags.includes(a));
|
|
44269
44840
|
let shellCmd;
|
|
44270
|
-
const isWin =
|
|
44841
|
+
const isWin = os28.platform() === "win32";
|
|
44271
44842
|
const escapeArg = (a) => isWin ? `"${a.replace(/"/g, '""')}"` : `'${a.replace(/'/g, "'\\''")}'`;
|
|
44272
44843
|
const promptMode = autoImpl?.promptMode ?? "stdin";
|
|
44273
44844
|
const extraArgs = autoImpl?.extraArgs ?? [];
|
|
@@ -44306,7 +44877,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
44306
44877
|
try {
|
|
44307
44878
|
const pty = require("node-pty");
|
|
44308
44879
|
ctx.log(`Auto-implement spawn (PTY): ${shellCmd}`);
|
|
44309
|
-
const isWin2 =
|
|
44880
|
+
const isWin2 = os28.platform() === "win32";
|
|
44310
44881
|
child = pty.spawn(isWin2 ? "cmd.exe" : process.env.SHELL || "/bin/zsh", [isWin2 ? "/c" : "-c", shellCmd], {
|
|
44311
44882
|
name: "xterm-256color",
|
|
44312
44883
|
cols: 120,
|
|
@@ -44449,7 +45020,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
44449
45020
|
}
|
|
44450
45021
|
});
|
|
44451
45022
|
try {
|
|
44452
|
-
|
|
45023
|
+
fs26.unlinkSync(promptFile);
|
|
44453
45024
|
} catch {
|
|
44454
45025
|
}
|
|
44455
45026
|
ctx.log(`Auto-implement ${success ? "completed" : "failed"}: ${type} (exit: ${code})${verificationSummary ? ` verify=${verificationSummary.pass ? "pass" : "fail"}` : ""}`);
|
|
@@ -44546,7 +45117,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
44546
45117
|
setMode: "set_mode.js"
|
|
44547
45118
|
};
|
|
44548
45119
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
44549
|
-
const scriptsDir =
|
|
45120
|
+
const scriptsDir = path38.join(providerDir, "scripts");
|
|
44550
45121
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
44551
45122
|
if (latestScriptsDir) {
|
|
44552
45123
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -44554,10 +45125,10 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
44554
45125
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
44555
45126
|
lines.push("These are the ONLY files you are allowed to modify. Replace the TODO stubs with working implementations.");
|
|
44556
45127
|
lines.push("");
|
|
44557
|
-
for (const file of
|
|
45128
|
+
for (const file of fs26.readdirSync(latestScriptsDir)) {
|
|
44558
45129
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
44559
45130
|
try {
|
|
44560
|
-
const content =
|
|
45131
|
+
const content = fs26.readFileSync(path38.join(latestScriptsDir, file), "utf-8");
|
|
44561
45132
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
44562
45133
|
lines.push("```javascript");
|
|
44563
45134
|
lines.push(content);
|
|
@@ -44567,14 +45138,14 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
44567
45138
|
}
|
|
44568
45139
|
}
|
|
44569
45140
|
}
|
|
44570
|
-
const refFiles =
|
|
45141
|
+
const refFiles = fs26.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
44571
45142
|
if (refFiles.length > 0) {
|
|
44572
45143
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
44573
45144
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
44574
45145
|
lines.push("");
|
|
44575
45146
|
for (const file of refFiles) {
|
|
44576
45147
|
try {
|
|
44577
|
-
const content =
|
|
45148
|
+
const content = fs26.readFileSync(path38.join(latestScriptsDir, file), "utf-8");
|
|
44578
45149
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
44579
45150
|
lines.push("```javascript");
|
|
44580
45151
|
lines.push(content);
|
|
@@ -44615,11 +45186,11 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
44615
45186
|
lines.push("");
|
|
44616
45187
|
}
|
|
44617
45188
|
}
|
|
44618
|
-
const docsDir =
|
|
45189
|
+
const docsDir = path38.join(providerDir, "../../docs");
|
|
44619
45190
|
const loadGuide = (name) => {
|
|
44620
45191
|
try {
|
|
44621
|
-
const p =
|
|
44622
|
-
if (
|
|
45192
|
+
const p = path38.join(docsDir, name);
|
|
45193
|
+
if (fs26.existsSync(p)) return fs26.readFileSync(p, "utf-8");
|
|
44623
45194
|
} catch {
|
|
44624
45195
|
}
|
|
44625
45196
|
return null;
|
|
@@ -44855,7 +45426,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
44855
45426
|
parseApproval: "parse_approval.js"
|
|
44856
45427
|
};
|
|
44857
45428
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
44858
|
-
const scriptsDir =
|
|
45429
|
+
const scriptsDir = path38.join(providerDir, "scripts");
|
|
44859
45430
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
44860
45431
|
if (latestScriptsDir) {
|
|
44861
45432
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -44863,11 +45434,11 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
44863
45434
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
44864
45435
|
lines.push("These are the ONLY files you are allowed to modify. Replace TODO or heuristic-only logic with working PTY-aware implementations.");
|
|
44865
45436
|
lines.push("");
|
|
44866
|
-
for (const file of
|
|
45437
|
+
for (const file of fs26.readdirSync(latestScriptsDir)) {
|
|
44867
45438
|
if (!file.endsWith(".js")) continue;
|
|
44868
45439
|
if (!targetFileNames.has(file)) continue;
|
|
44869
45440
|
try {
|
|
44870
|
-
const content =
|
|
45441
|
+
const content = fs26.readFileSync(path38.join(latestScriptsDir, file), "utf-8");
|
|
44871
45442
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
44872
45443
|
lines.push("```javascript");
|
|
44873
45444
|
lines.push(content);
|
|
@@ -44876,14 +45447,14 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
44876
45447
|
} catch {
|
|
44877
45448
|
}
|
|
44878
45449
|
}
|
|
44879
|
-
const refFiles =
|
|
45450
|
+
const refFiles = fs26.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
44880
45451
|
if (refFiles.length > 0) {
|
|
44881
45452
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
44882
45453
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
44883
45454
|
lines.push("");
|
|
44884
45455
|
for (const file of refFiles) {
|
|
44885
45456
|
try {
|
|
44886
|
-
const content =
|
|
45457
|
+
const content = fs26.readFileSync(path38.join(latestScriptsDir, file), "utf-8");
|
|
44887
45458
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
44888
45459
|
lines.push("```javascript");
|
|
44889
45460
|
lines.push(content);
|
|
@@ -44916,11 +45487,11 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
44916
45487
|
lines.push("");
|
|
44917
45488
|
}
|
|
44918
45489
|
}
|
|
44919
|
-
const docsDir =
|
|
45490
|
+
const docsDir = path38.join(providerDir, "../../docs");
|
|
44920
45491
|
const loadGuide = (name) => {
|
|
44921
45492
|
try {
|
|
44922
|
-
const p =
|
|
44923
|
-
if (
|
|
45493
|
+
const p = path38.join(docsDir, name);
|
|
45494
|
+
if (fs26.existsSync(p)) return fs26.readFileSync(p, "utf-8");
|
|
44924
45495
|
} catch {
|
|
44925
45496
|
}
|
|
44926
45497
|
return null;
|
|
@@ -45366,8 +45937,8 @@ var DevServer = class _DevServer {
|
|
|
45366
45937
|
}
|
|
45367
45938
|
getEndpointList() {
|
|
45368
45939
|
return this.routes.map((r) => {
|
|
45369
|
-
const
|
|
45370
|
-
return `${r.method.padEnd(5)} ${
|
|
45940
|
+
const path40 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
|
|
45941
|
+
return `${r.method.padEnd(5)} ${path40}`;
|
|
45371
45942
|
});
|
|
45372
45943
|
}
|
|
45373
45944
|
async start(port = DEV_SERVER_PORT) {
|
|
@@ -45655,12 +46226,12 @@ var DevServer = class _DevServer {
|
|
|
45655
46226
|
// ─── DevConsole SPA ───
|
|
45656
46227
|
getConsoleDistDir() {
|
|
45657
46228
|
const candidates = [
|
|
45658
|
-
|
|
45659
|
-
|
|
45660
|
-
|
|
46229
|
+
path39.resolve(__dirname, "../../web-devconsole/dist"),
|
|
46230
|
+
path39.resolve(__dirname, "../../../web-devconsole/dist"),
|
|
46231
|
+
path39.join(process.cwd(), "packages/web-devconsole/dist")
|
|
45661
46232
|
];
|
|
45662
46233
|
for (const dir of candidates) {
|
|
45663
|
-
if (
|
|
46234
|
+
if (fs27.existsSync(path39.join(dir, "index.html"))) return dir;
|
|
45664
46235
|
}
|
|
45665
46236
|
return null;
|
|
45666
46237
|
}
|
|
@@ -45670,9 +46241,9 @@ var DevServer = class _DevServer {
|
|
|
45670
46241
|
this.json(res, 500, { error: "DevConsole not found. Run: npm run build -w packages/web-devconsole" });
|
|
45671
46242
|
return;
|
|
45672
46243
|
}
|
|
45673
|
-
const htmlPath =
|
|
46244
|
+
const htmlPath = path39.join(distDir, "index.html");
|
|
45674
46245
|
try {
|
|
45675
|
-
const html =
|
|
46246
|
+
const html = fs27.readFileSync(htmlPath, "utf-8");
|
|
45676
46247
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
45677
46248
|
res.end(html);
|
|
45678
46249
|
} catch (e) {
|
|
@@ -45695,15 +46266,15 @@ var DevServer = class _DevServer {
|
|
|
45695
46266
|
this.json(res, 404, { error: "Not found" });
|
|
45696
46267
|
return;
|
|
45697
46268
|
}
|
|
45698
|
-
const safePath =
|
|
45699
|
-
const filePath =
|
|
46269
|
+
const safePath = path39.normalize(pathname).replace(/^\.\.\//, "");
|
|
46270
|
+
const filePath = path39.join(distDir, safePath);
|
|
45700
46271
|
if (!filePath.startsWith(distDir)) {
|
|
45701
46272
|
this.json(res, 403, { error: "Forbidden" });
|
|
45702
46273
|
return;
|
|
45703
46274
|
}
|
|
45704
46275
|
try {
|
|
45705
|
-
const content =
|
|
45706
|
-
const ext =
|
|
46276
|
+
const content = fs27.readFileSync(filePath);
|
|
46277
|
+
const ext = path39.extname(filePath);
|
|
45707
46278
|
const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
|
|
45708
46279
|
res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
|
|
45709
46280
|
res.end(content);
|
|
@@ -45811,14 +46382,14 @@ var DevServer = class _DevServer {
|
|
|
45811
46382
|
const files = [];
|
|
45812
46383
|
const scan = (d, prefix) => {
|
|
45813
46384
|
try {
|
|
45814
|
-
for (const entry of
|
|
46385
|
+
for (const entry of fs27.readdirSync(d, { withFileTypes: true })) {
|
|
45815
46386
|
if (entry.name.startsWith(".") || entry.name.endsWith(".bak")) continue;
|
|
45816
46387
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
45817
46388
|
if (entry.isDirectory()) {
|
|
45818
46389
|
files.push({ path: rel, size: 0, type: "dir" });
|
|
45819
|
-
scan(
|
|
46390
|
+
scan(path39.join(d, entry.name), rel);
|
|
45820
46391
|
} else {
|
|
45821
|
-
const stat2 =
|
|
46392
|
+
const stat2 = fs27.statSync(path39.join(d, entry.name));
|
|
45822
46393
|
files.push({ path: rel, size: stat2.size, type: "file" });
|
|
45823
46394
|
}
|
|
45824
46395
|
}
|
|
@@ -45841,16 +46412,16 @@ var DevServer = class _DevServer {
|
|
|
45841
46412
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
45842
46413
|
return;
|
|
45843
46414
|
}
|
|
45844
|
-
const fullPath =
|
|
46415
|
+
const fullPath = path39.resolve(dir, path39.normalize(filePath));
|
|
45845
46416
|
if (!fullPath.startsWith(dir)) {
|
|
45846
46417
|
this.json(res, 403, { error: "Forbidden" });
|
|
45847
46418
|
return;
|
|
45848
46419
|
}
|
|
45849
|
-
if (!
|
|
46420
|
+
if (!fs27.existsSync(fullPath) || fs27.statSync(fullPath).isDirectory()) {
|
|
45850
46421
|
this.json(res, 404, { error: `File not found: ${filePath}` });
|
|
45851
46422
|
return;
|
|
45852
46423
|
}
|
|
45853
|
-
const content =
|
|
46424
|
+
const content = fs27.readFileSync(fullPath, "utf-8");
|
|
45854
46425
|
this.json(res, 200, { type, path: filePath, content, lines: content.split("\n").length });
|
|
45855
46426
|
}
|
|
45856
46427
|
/** POST /api/providers/:type/file — write a file { path, content } */
|
|
@@ -45866,15 +46437,15 @@ var DevServer = class _DevServer {
|
|
|
45866
46437
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
45867
46438
|
return;
|
|
45868
46439
|
}
|
|
45869
|
-
const fullPath =
|
|
46440
|
+
const fullPath = path39.resolve(dir, path39.normalize(filePath));
|
|
45870
46441
|
if (!fullPath.startsWith(dir)) {
|
|
45871
46442
|
this.json(res, 403, { error: "Forbidden" });
|
|
45872
46443
|
return;
|
|
45873
46444
|
}
|
|
45874
46445
|
try {
|
|
45875
|
-
if (
|
|
45876
|
-
|
|
45877
|
-
|
|
46446
|
+
if (fs27.existsSync(fullPath)) fs27.copyFileSync(fullPath, fullPath + ".bak");
|
|
46447
|
+
fs27.mkdirSync(path39.dirname(fullPath), { recursive: true });
|
|
46448
|
+
fs27.writeFileSync(fullPath, content, "utf-8");
|
|
45878
46449
|
this.log(`File saved: ${fullPath} (${content.length} chars)`);
|
|
45879
46450
|
this.providerLoader.reload();
|
|
45880
46451
|
this.json(res, 200, { saved: true, path: filePath, chars: content.length });
|
|
@@ -45890,9 +46461,9 @@ var DevServer = class _DevServer {
|
|
|
45890
46461
|
return;
|
|
45891
46462
|
}
|
|
45892
46463
|
for (const name of ["scripts.js", "provider.json"]) {
|
|
45893
|
-
const p =
|
|
45894
|
-
if (
|
|
45895
|
-
const source =
|
|
46464
|
+
const p = path39.join(dir, name);
|
|
46465
|
+
if (fs27.existsSync(p)) {
|
|
46466
|
+
const source = fs27.readFileSync(p, "utf-8");
|
|
45896
46467
|
this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
|
|
45897
46468
|
return;
|
|
45898
46469
|
}
|
|
@@ -45911,11 +46482,11 @@ var DevServer = class _DevServer {
|
|
|
45911
46482
|
this.json(res, 404, { error: `Provider not found: ${type}` });
|
|
45912
46483
|
return;
|
|
45913
46484
|
}
|
|
45914
|
-
const target =
|
|
45915
|
-
const targetPath =
|
|
46485
|
+
const target = fs27.existsSync(path39.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
|
|
46486
|
+
const targetPath = path39.join(dir, target);
|
|
45916
46487
|
try {
|
|
45917
|
-
if (
|
|
45918
|
-
|
|
46488
|
+
if (fs27.existsSync(targetPath)) fs27.copyFileSync(targetPath, targetPath + ".bak");
|
|
46489
|
+
fs27.writeFileSync(targetPath, source, "utf-8");
|
|
45919
46490
|
this.log(`Saved provider: ${targetPath} (${source.length} chars)`);
|
|
45920
46491
|
this.providerLoader.reload();
|
|
45921
46492
|
this.json(res, 200, { saved: true, path: targetPath, chars: source.length });
|
|
@@ -46059,21 +46630,21 @@ var DevServer = class _DevServer {
|
|
|
46059
46630
|
}
|
|
46060
46631
|
let targetDir;
|
|
46061
46632
|
targetDir = this.providerLoader.getUserProviderDir(category, type);
|
|
46062
|
-
const jsonPath =
|
|
46063
|
-
if (
|
|
46633
|
+
const jsonPath = path39.join(targetDir, "provider.json");
|
|
46634
|
+
if (fs27.existsSync(jsonPath)) {
|
|
46064
46635
|
this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
|
|
46065
46636
|
return;
|
|
46066
46637
|
}
|
|
46067
46638
|
try {
|
|
46068
46639
|
const result = generateFiles(type, name, category, { cdpPorts, cli, processName, installPath, binary, extensionId, version, osPaths, processNames });
|
|
46069
|
-
|
|
46070
|
-
|
|
46640
|
+
fs27.mkdirSync(targetDir, { recursive: true });
|
|
46641
|
+
fs27.writeFileSync(jsonPath, result["provider.json"], "utf-8");
|
|
46071
46642
|
const createdFiles = ["provider.json"];
|
|
46072
46643
|
if (result.files) {
|
|
46073
46644
|
for (const [relPath, content] of Object.entries(result.files)) {
|
|
46074
|
-
const fullPath =
|
|
46075
|
-
|
|
46076
|
-
|
|
46645
|
+
const fullPath = path39.join(targetDir, relPath);
|
|
46646
|
+
fs27.mkdirSync(path39.dirname(fullPath), { recursive: true });
|
|
46647
|
+
fs27.writeFileSync(fullPath, content, "utf-8");
|
|
46077
46648
|
createdFiles.push(relPath);
|
|
46078
46649
|
}
|
|
46079
46650
|
}
|
|
@@ -46122,38 +46693,38 @@ var DevServer = class _DevServer {
|
|
|
46122
46693
|
}
|
|
46123
46694
|
// ─── Phase 2: Auto-Implement Backend ───
|
|
46124
46695
|
getLatestScriptVersionDir(scriptsDir) {
|
|
46125
|
-
if (!
|
|
46126
|
-
const versions =
|
|
46696
|
+
if (!fs27.existsSync(scriptsDir)) return null;
|
|
46697
|
+
const versions = fs27.readdirSync(scriptsDir).filter((d) => {
|
|
46127
46698
|
try {
|
|
46128
|
-
return
|
|
46699
|
+
return fs27.statSync(path39.join(scriptsDir, d)).isDirectory();
|
|
46129
46700
|
} catch {
|
|
46130
46701
|
return false;
|
|
46131
46702
|
}
|
|
46132
46703
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
46133
46704
|
if (versions.length === 0) return null;
|
|
46134
|
-
return
|
|
46705
|
+
return path39.join(scriptsDir, versions[0]);
|
|
46135
46706
|
}
|
|
46136
46707
|
resolveAutoImplWritableProviderDir(category, type, requestedDir) {
|
|
46137
|
-
const canonicalUserDir =
|
|
46138
|
-
const desiredDir = requestedDir ?
|
|
46139
|
-
const upstreamRoot =
|
|
46140
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
46708
|
+
const canonicalUserDir = path39.resolve(this.providerLoader.getUserProviderDir(category, type));
|
|
46709
|
+
const desiredDir = requestedDir ? path39.resolve(requestedDir) : canonicalUserDir;
|
|
46710
|
+
const upstreamRoot = path39.resolve(this.providerLoader.getUpstreamDir());
|
|
46711
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path39.sep}`)) {
|
|
46141
46712
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
46142
46713
|
}
|
|
46143
|
-
if (
|
|
46714
|
+
if (path39.basename(desiredDir) !== type) {
|
|
46144
46715
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
46145
46716
|
}
|
|
46146
46717
|
const sourceDir = this.findProviderDir(type);
|
|
46147
46718
|
if (!sourceDir) {
|
|
46148
46719
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
46149
46720
|
}
|
|
46150
|
-
if (!
|
|
46151
|
-
|
|
46152
|
-
|
|
46721
|
+
if (!fs27.existsSync(desiredDir)) {
|
|
46722
|
+
fs27.mkdirSync(path39.dirname(desiredDir), { recursive: true });
|
|
46723
|
+
fs27.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
46153
46724
|
this.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
46154
46725
|
}
|
|
46155
|
-
const providerJson =
|
|
46156
|
-
if (!
|
|
46726
|
+
const providerJson = path39.join(desiredDir, "provider.json");
|
|
46727
|
+
if (!fs27.existsSync(providerJson)) {
|
|
46157
46728
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
46158
46729
|
}
|
|
46159
46730
|
return { dir: desiredDir };
|
|
@@ -46188,7 +46759,7 @@ var DevServer = class _DevServer {
|
|
|
46188
46759
|
setMode: "set_mode.js"
|
|
46189
46760
|
};
|
|
46190
46761
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
46191
|
-
const scriptsDir =
|
|
46762
|
+
const scriptsDir = path39.join(providerDir, "scripts");
|
|
46192
46763
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
46193
46764
|
if (latestScriptsDir) {
|
|
46194
46765
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -46196,10 +46767,10 @@ var DevServer = class _DevServer {
|
|
|
46196
46767
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
46197
46768
|
lines.push("These are the ONLY files you are allowed to modify. Replace the TODO stubs with working implementations.");
|
|
46198
46769
|
lines.push("");
|
|
46199
|
-
for (const file of
|
|
46770
|
+
for (const file of fs27.readdirSync(latestScriptsDir)) {
|
|
46200
46771
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
46201
46772
|
try {
|
|
46202
|
-
const content =
|
|
46773
|
+
const content = fs27.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
|
|
46203
46774
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
46204
46775
|
lines.push("```javascript");
|
|
46205
46776
|
lines.push(content);
|
|
@@ -46209,14 +46780,14 @@ var DevServer = class _DevServer {
|
|
|
46209
46780
|
}
|
|
46210
46781
|
}
|
|
46211
46782
|
}
|
|
46212
|
-
const refFiles =
|
|
46783
|
+
const refFiles = fs27.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
46213
46784
|
if (refFiles.length > 0) {
|
|
46214
46785
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
46215
46786
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
46216
46787
|
lines.push("");
|
|
46217
46788
|
for (const file of refFiles) {
|
|
46218
46789
|
try {
|
|
46219
|
-
const content =
|
|
46790
|
+
const content = fs27.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
|
|
46220
46791
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
46221
46792
|
lines.push("```javascript");
|
|
46222
46793
|
lines.push(content);
|
|
@@ -46257,11 +46828,11 @@ var DevServer = class _DevServer {
|
|
|
46257
46828
|
lines.push("");
|
|
46258
46829
|
}
|
|
46259
46830
|
}
|
|
46260
|
-
const docsDir =
|
|
46831
|
+
const docsDir = path39.join(providerDir, "../../docs");
|
|
46261
46832
|
const loadGuide = (name) => {
|
|
46262
46833
|
try {
|
|
46263
|
-
const p =
|
|
46264
|
-
if (
|
|
46834
|
+
const p = path39.join(docsDir, name);
|
|
46835
|
+
if (fs27.existsSync(p)) return fs27.readFileSync(p, "utf-8");
|
|
46265
46836
|
} catch {
|
|
46266
46837
|
}
|
|
46267
46838
|
return null;
|
|
@@ -46434,7 +47005,7 @@ var DevServer = class _DevServer {
|
|
|
46434
47005
|
parseApproval: "parse_approval.js"
|
|
46435
47006
|
};
|
|
46436
47007
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
46437
|
-
const scriptsDir =
|
|
47008
|
+
const scriptsDir = path39.join(providerDir, "scripts");
|
|
46438
47009
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
46439
47010
|
if (latestScriptsDir) {
|
|
46440
47011
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -46442,11 +47013,11 @@ var DevServer = class _DevServer {
|
|
|
46442
47013
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
46443
47014
|
lines.push("These are the ONLY files you are allowed to modify. Replace TODO or heuristic-only logic with working PTY-aware implementations.");
|
|
46444
47015
|
lines.push("");
|
|
46445
|
-
for (const file of
|
|
47016
|
+
for (const file of fs27.readdirSync(latestScriptsDir)) {
|
|
46446
47017
|
if (!file.endsWith(".js")) continue;
|
|
46447
47018
|
if (!targetFileNames.has(file)) continue;
|
|
46448
47019
|
try {
|
|
46449
|
-
const content =
|
|
47020
|
+
const content = fs27.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
|
|
46450
47021
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
46451
47022
|
lines.push("```javascript");
|
|
46452
47023
|
lines.push(content);
|
|
@@ -46455,14 +47026,14 @@ var DevServer = class _DevServer {
|
|
|
46455
47026
|
} catch {
|
|
46456
47027
|
}
|
|
46457
47028
|
}
|
|
46458
|
-
const refFiles =
|
|
47029
|
+
const refFiles = fs27.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
46459
47030
|
if (refFiles.length > 0) {
|
|
46460
47031
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
46461
47032
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
46462
47033
|
lines.push("");
|
|
46463
47034
|
for (const file of refFiles) {
|
|
46464
47035
|
try {
|
|
46465
|
-
const content =
|
|
47036
|
+
const content = fs27.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
|
|
46466
47037
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
46467
47038
|
lines.push("```javascript");
|
|
46468
47039
|
lines.push(content);
|
|
@@ -46495,11 +47066,11 @@ var DevServer = class _DevServer {
|
|
|
46495
47066
|
lines.push("");
|
|
46496
47067
|
}
|
|
46497
47068
|
}
|
|
46498
|
-
const docsDir =
|
|
47069
|
+
const docsDir = path39.join(providerDir, "../../docs");
|
|
46499
47070
|
const loadGuide = (name) => {
|
|
46500
47071
|
try {
|
|
46501
|
-
const p =
|
|
46502
|
-
if (
|
|
47072
|
+
const p = path39.join(docsDir, name);
|
|
47073
|
+
if (fs27.existsSync(p)) return fs27.readFileSync(p, "utf-8");
|
|
46503
47074
|
} catch {
|
|
46504
47075
|
}
|
|
46505
47076
|
return null;
|
|
@@ -47404,8 +47975,8 @@ async function installExtension(ide, extension) {
|
|
|
47404
47975
|
const res = await fetch(extension.vsixUrl);
|
|
47405
47976
|
if (res.ok) {
|
|
47406
47977
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
47407
|
-
const
|
|
47408
|
-
|
|
47978
|
+
const fs28 = await import("fs");
|
|
47979
|
+
fs28.writeFileSync(vsixPath, buffer);
|
|
47409
47980
|
return new Promise((resolve23) => {
|
|
47410
47981
|
const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
|
|
47411
47982
|
(0, import_child_process10.exec)(cmd, { timeout: 6e4 }, (error, _stdout, stderr) => {
|