@adhdev/daemon-core 0.9.82-rc.165 → 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 +1298 -752
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1296 -750
- 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/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/external-sources.ts +218 -0
- package/src/providers/provider-loader.ts +159 -23
- 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/validators/manifest.ts +1 -1
- package/src/providers/sdk/v1/validators/taint.ts +1 -1
- package/src/shared-types.ts +33 -1
- package/src/status/snapshot.ts +49 -14
package/dist/index.mjs
CHANGED
|
@@ -106,8 +106,8 @@ function normalizeGitOutput(value) {
|
|
|
106
106
|
return String(value).replace(/\r\n/g, "\n");
|
|
107
107
|
}
|
|
108
108
|
function isPathInside(parent, child) {
|
|
109
|
-
const
|
|
110
|
-
return
|
|
109
|
+
const relative5 = path.relative(path.resolve(parent), path.resolve(child));
|
|
110
|
+
return relative5 === "" || !relative5.startsWith("..") && !path.isAbsolute(relative5);
|
|
111
111
|
}
|
|
112
112
|
async function validateWorkspace(workspace) {
|
|
113
113
|
if (typeof workspace !== "string" || workspace.length === 0 || workspace.includes("\0")) {
|
|
@@ -768,10 +768,10 @@ function getMeshConfigPath() {
|
|
|
768
768
|
return join4(getConfigDir(), "meshes.json");
|
|
769
769
|
}
|
|
770
770
|
function loadMeshConfig() {
|
|
771
|
-
const
|
|
772
|
-
if (!existsSync4(
|
|
771
|
+
const path40 = getMeshConfigPath();
|
|
772
|
+
if (!existsSync4(path40)) return { meshes: [] };
|
|
773
773
|
try {
|
|
774
|
-
const raw = JSON.parse(readFileSync2(
|
|
774
|
+
const raw = JSON.parse(readFileSync2(path40, "utf-8"));
|
|
775
775
|
if (!raw || !Array.isArray(raw.meshes)) return { meshes: [] };
|
|
776
776
|
return raw;
|
|
777
777
|
} catch {
|
|
@@ -779,16 +779,16 @@ function loadMeshConfig() {
|
|
|
779
779
|
}
|
|
780
780
|
}
|
|
781
781
|
function saveMeshConfig(config) {
|
|
782
|
-
const
|
|
783
|
-
writeFileSync2(
|
|
782
|
+
const path40 = getMeshConfigPath();
|
|
783
|
+
writeFileSync2(path40, JSON.stringify(config, null, 2), { encoding: "utf-8", mode: 384 });
|
|
784
784
|
}
|
|
785
785
|
function normalizeRepoIdentity(remoteUrl) {
|
|
786
786
|
let identity = remoteUrl.trim();
|
|
787
787
|
if (identity.startsWith("http://") || identity.startsWith("https://")) {
|
|
788
788
|
try {
|
|
789
789
|
const url = new URL(identity);
|
|
790
|
-
const
|
|
791
|
-
return `${url.hostname}/${
|
|
790
|
+
const path40 = url.pathname.replace(/^\//, "").replace(/\.git$/, "");
|
|
791
|
+
return `${url.hostname}/${path40}`;
|
|
792
792
|
} catch {
|
|
793
793
|
}
|
|
794
794
|
}
|
|
@@ -1717,8 +1717,8 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
1717
1717
|
}
|
|
1718
1718
|
const serverName = mcpConfig.serverName?.trim() || DEFAULT_SERVER_NAME;
|
|
1719
1719
|
if (mcpConfig.mode === "auto_import") {
|
|
1720
|
-
const
|
|
1721
|
-
if (!
|
|
1720
|
+
const path40 = mcpConfig.path?.trim();
|
|
1721
|
+
if (!path40) {
|
|
1722
1722
|
return { kind: "unsupported", reason: "Provider auto-import MCP config is missing a config path" };
|
|
1723
1723
|
}
|
|
1724
1724
|
const mcpServer = resolveAdhdevMcpServerLaunch({
|
|
@@ -1736,7 +1736,7 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
1736
1736
|
return {
|
|
1737
1737
|
kind: "auto_import",
|
|
1738
1738
|
serverName,
|
|
1739
|
-
configPath: resolveMcpConfigPath(
|
|
1739
|
+
configPath: resolveMcpConfigPath(path40, workspace),
|
|
1740
1740
|
configFormat: mcpConfig.format,
|
|
1741
1741
|
mcpServer
|
|
1742
1742
|
};
|
|
@@ -1893,8 +1893,8 @@ function stripCoordinatorWrapperFile(filePath) {
|
|
|
1893
1893
|
const remaining = (existing.slice(0, openIdx) + existing.slice(closeIdx + CLOSE.length)).replace(/^\s*\n+/, "").replace(/\n+\s*$/, "");
|
|
1894
1894
|
if (!remaining.trim()) {
|
|
1895
1895
|
try {
|
|
1896
|
-
const
|
|
1897
|
-
|
|
1896
|
+
const fs28 = __require("fs");
|
|
1897
|
+
fs28.unlinkSync(filePath);
|
|
1898
1898
|
} catch {
|
|
1899
1899
|
}
|
|
1900
1900
|
} else {
|
|
@@ -2032,10 +2032,10 @@ function rotateArchiveFile(meshId, archivePath) {
|
|
|
2032
2032
|
}
|
|
2033
2033
|
}
|
|
2034
2034
|
function readArchivedCounts(meshId) {
|
|
2035
|
-
const
|
|
2036
|
-
if (!existsSync10(
|
|
2035
|
+
const path40 = getArchivedCountsPath(meshId);
|
|
2036
|
+
if (!existsSync10(path40)) return { taskCompleted: 0, taskFailed: 0, taskStalled: 0, recoveryAttempted: 0, totalArchived: 0, lastArchivedAt: "" };
|
|
2037
2037
|
try {
|
|
2038
|
-
return JSON.parse(readFileSync8(
|
|
2038
|
+
return JSON.parse(readFileSync8(path40, "utf-8"));
|
|
2039
2039
|
} catch {
|
|
2040
2040
|
return { taskCompleted: 0, taskFailed: 0, taskStalled: 0, recoveryAttempted: 0, totalArchived: 0, lastArchivedAt: "" };
|
|
2041
2041
|
}
|
|
@@ -2685,10 +2685,10 @@ var init_beads_db = __esm({
|
|
|
2685
2685
|
this.migratedMeshIds.add(meshId);
|
|
2686
2686
|
const count = this.db.prepare("SELECT COUNT(*) AS count FROM mesh_queue WHERE mesh_id = ?").get(meshId);
|
|
2687
2687
|
if (count.count > 0) return;
|
|
2688
|
-
const
|
|
2689
|
-
if (!existsSync11(
|
|
2688
|
+
const path40 = legacyQueuePath(meshId);
|
|
2689
|
+
if (!existsSync11(path40)) return;
|
|
2690
2690
|
try {
|
|
2691
|
-
const entries = JSON.parse(readFileSync9(
|
|
2691
|
+
const entries = JSON.parse(readFileSync9(path40, "utf-8"));
|
|
2692
2692
|
if (!Array.isArray(entries)) return;
|
|
2693
2693
|
const insert = this.db.prepare(`
|
|
2694
2694
|
INSERT OR REPLACE INTO mesh_queue (
|
|
@@ -3399,10 +3399,10 @@ function readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId) {
|
|
|
3399
3399
|
if (!meshId) return [];
|
|
3400
3400
|
const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
|
|
3401
3401
|
const events = [];
|
|
3402
|
-
for (const
|
|
3403
|
-
if (!existsSync13(
|
|
3402
|
+
for (const path40 of paths) {
|
|
3403
|
+
if (!existsSync13(path40)) continue;
|
|
3404
3404
|
try {
|
|
3405
|
-
const raw = readFileSync10(
|
|
3405
|
+
const raw = readFileSync10(path40, "utf-8");
|
|
3406
3406
|
const parsed = raw.split("\n").filter(Boolean).flatMap((line) => {
|
|
3407
3407
|
try {
|
|
3408
3408
|
return [JSON.parse(line)];
|
|
@@ -3410,7 +3410,7 @@ function readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId) {
|
|
|
3410
3410
|
return [];
|
|
3411
3411
|
}
|
|
3412
3412
|
});
|
|
3413
|
-
const filtered = coordinatorDaemonId &&
|
|
3413
|
+
const filtered = coordinatorDaemonId && path40 === getPendingEventsPath(meshId) ? parsed.filter((e) => !e.targetCoordinatorDaemonId || e.targetCoordinatorDaemonId === coordinatorDaemonId) : parsed;
|
|
3414
3414
|
events.push(...filtered);
|
|
3415
3415
|
} catch {
|
|
3416
3416
|
}
|
|
@@ -3479,13 +3479,13 @@ function reconcilePendingMeshCoordinatorEvents(meshId, events) {
|
|
|
3479
3479
|
...backfilled
|
|
3480
3480
|
];
|
|
3481
3481
|
}
|
|
3482
|
-
function trimPendingEventsIfNeeded(
|
|
3482
|
+
function trimPendingEventsIfNeeded(path40) {
|
|
3483
3483
|
try {
|
|
3484
|
-
if (!existsSync13(
|
|
3485
|
-
if (statSync5(
|
|
3486
|
-
const lines = readFileSync10(
|
|
3484
|
+
if (!existsSync13(path40)) return;
|
|
3485
|
+
if (statSync5(path40).size <= MAX_PENDING_EVENTS_BYTES) return;
|
|
3486
|
+
const lines = readFileSync10(path40, "utf-8").split("\n").filter(Boolean);
|
|
3487
3487
|
if (lines.length <= MAX_PENDING_EVENTS_KEEP) return;
|
|
3488
|
-
writeFileSync6(
|
|
3488
|
+
writeFileSync6(path40, lines.slice(-MAX_PENDING_EVENTS_KEEP).join("\n") + "\n", "utf-8");
|
|
3489
3489
|
} catch {
|
|
3490
3490
|
}
|
|
3491
3491
|
}
|
|
@@ -3499,19 +3499,19 @@ function queuePendingMeshCoordinatorEvent(event) {
|
|
|
3499
3499
|
LOG.info("MeshEvents", `Suppressed duplicate pending ${event.event} for mesh ${event.meshId}`);
|
|
3500
3500
|
return true;
|
|
3501
3501
|
}
|
|
3502
|
-
const
|
|
3503
|
-
trimPendingEventsIfNeeded(
|
|
3504
|
-
appendFileSync2(
|
|
3502
|
+
const path40 = getPendingEventsPath(event.meshId, event.targetCoordinatorDaemonId);
|
|
3503
|
+
trimPendingEventsIfNeeded(path40);
|
|
3504
|
+
appendFileSync2(path40, JSON.stringify(event) + "\n", "utf-8");
|
|
3505
3505
|
return true;
|
|
3506
3506
|
} catch (e) {
|
|
3507
3507
|
LOG.warn("MeshEvents", `Failed to persist pending coordinator event: ${e?.message || e}`);
|
|
3508
3508
|
return false;
|
|
3509
3509
|
}
|
|
3510
3510
|
}
|
|
3511
|
-
function atomicDrainFile(
|
|
3512
|
-
const tmpPath = `${
|
|
3511
|
+
function atomicDrainFile(path40) {
|
|
3512
|
+
const tmpPath = `${path40}.draining`;
|
|
3513
3513
|
try {
|
|
3514
|
-
renameSync3(
|
|
3514
|
+
renameSync3(path40, tmpPath);
|
|
3515
3515
|
} catch {
|
|
3516
3516
|
return null;
|
|
3517
3517
|
}
|
|
@@ -3534,8 +3534,8 @@ function drainPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
3534
3534
|
if (!meshId) return [];
|
|
3535
3535
|
const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
|
|
3536
3536
|
const all = [];
|
|
3537
|
-
for (const
|
|
3538
|
-
const content = atomicDrainFile(
|
|
3537
|
+
for (const path40 of paths) {
|
|
3538
|
+
const content = atomicDrainFile(path40);
|
|
3539
3539
|
if (!content) continue;
|
|
3540
3540
|
const parsed = content.split("\n").filter(Boolean).flatMap((line) => {
|
|
3541
3541
|
try {
|
|
@@ -3544,7 +3544,7 @@ function drainPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
3544
3544
|
return [];
|
|
3545
3545
|
}
|
|
3546
3546
|
});
|
|
3547
|
-
const filtered = coordinatorDaemonId &&
|
|
3547
|
+
const filtered = coordinatorDaemonId && path40 === getPendingEventsPath(meshId) ? parsed.filter((e) => !e.targetCoordinatorDaemonId || e.targetCoordinatorDaemonId === coordinatorDaemonId) : parsed;
|
|
3548
3548
|
all.push(...filtered);
|
|
3549
3549
|
}
|
|
3550
3550
|
if (all.length === 0) return [];
|
|
@@ -3557,9 +3557,9 @@ function getPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
3557
3557
|
function clearPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
3558
3558
|
if (!meshId) return;
|
|
3559
3559
|
const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
|
|
3560
|
-
for (const
|
|
3561
|
-
if (existsSync13(
|
|
3562
|
-
unlinkSync2(
|
|
3560
|
+
for (const path40 of paths) {
|
|
3561
|
+
if (existsSync13(path40)) try {
|
|
3562
|
+
unlinkSync2(path40);
|
|
3563
3563
|
} catch {
|
|
3564
3564
|
}
|
|
3565
3565
|
}
|
|
@@ -4683,6 +4683,56 @@ var init_debug_config = __esm({
|
|
|
4683
4683
|
}
|
|
4684
4684
|
});
|
|
4685
4685
|
|
|
4686
|
+
// src/providers/provider-trust.ts
|
|
4687
|
+
var provider_trust_exports = {};
|
|
4688
|
+
__export(provider_trust_exports, {
|
|
4689
|
+
classifyTrust: () => classifyTrust,
|
|
4690
|
+
describeTrust: () => describeTrust,
|
|
4691
|
+
inspectManifestShape: () => inspectManifestShape,
|
|
4692
|
+
requiresConfirmation: () => requiresConfirmation
|
|
4693
|
+
});
|
|
4694
|
+
function inspectManifestShape(manifest) {
|
|
4695
|
+
const hasTui = !!manifest.tui && typeof manifest.tui === "object" && Object.keys(manifest.tui).length > 0;
|
|
4696
|
+
const hasOverrides = !!manifest.overrides && typeof manifest.overrides === "object" && !Array.isArray(manifest.overrides) && Object.keys(manifest.overrides).length > 0;
|
|
4697
|
+
const compat = Array.isArray(manifest.compatibility) ? manifest.compatibility : [];
|
|
4698
|
+
const compatHasScriptDir = compat.some((entry) => typeof entry?.scriptDir === "string");
|
|
4699
|
+
const hasScriptDir = compatHasScriptDir || typeof manifest.defaultScriptDir === "string";
|
|
4700
|
+
return { hasTui, hasOverrides, hasScriptDir };
|
|
4701
|
+
}
|
|
4702
|
+
function classifyTrust(layer, shape) {
|
|
4703
|
+
const isSpecOnly = !shape.hasTui && !shape.hasOverrides && !shape.hasScriptDir;
|
|
4704
|
+
switch (layer) {
|
|
4705
|
+
case "user":
|
|
4706
|
+
return "user-custom";
|
|
4707
|
+
case "upstream":
|
|
4708
|
+
return isSpecOnly ? "trusted" : "trusted-with-scripts";
|
|
4709
|
+
case "external":
|
|
4710
|
+
return isSpecOnly ? "external-safe" : "external-untrusted";
|
|
4711
|
+
}
|
|
4712
|
+
}
|
|
4713
|
+
function requiresConfirmation(trust) {
|
|
4714
|
+
return trust === "external-untrusted";
|
|
4715
|
+
}
|
|
4716
|
+
function describeTrust(trust) {
|
|
4717
|
+
switch (trust) {
|
|
4718
|
+
case "user-custom":
|
|
4719
|
+
return "Hand-authored in ~/.adhdev/providers/. Runs your own code.";
|
|
4720
|
+
case "trusted":
|
|
4721
|
+
return "Official, declarative-only manifest from the ADHDev registry.";
|
|
4722
|
+
case "trusted-with-scripts":
|
|
4723
|
+
return "Official manifest from the ADHDev registry. Ships JavaScript hooks executed by the daemon.";
|
|
4724
|
+
case "external-safe":
|
|
4725
|
+
return "Manifest from a 3rd-party git source you added. Declarative-only \u2014 the daemon never runs JS from this source.";
|
|
4726
|
+
case "external-untrusted":
|
|
4727
|
+
return "Manifest from a 3rd-party git source you added. Ships JavaScript that the daemon will execute. Treat as untrusted code \u2014 review the source before enabling.";
|
|
4728
|
+
}
|
|
4729
|
+
}
|
|
4730
|
+
var init_provider_trust = __esm({
|
|
4731
|
+
"src/providers/provider-trust.ts"() {
|
|
4732
|
+
"use strict";
|
|
4733
|
+
}
|
|
4734
|
+
});
|
|
4735
|
+
|
|
4686
4736
|
// src/providers/sdk/v1/schemas/cli/provider.schema.json
|
|
4687
4737
|
var provider_schema_default;
|
|
4688
4738
|
var init_provider_schema = __esm({
|
|
@@ -5188,7 +5238,7 @@ function getCliValidator() {
|
|
|
5188
5238
|
return _cliValidator;
|
|
5189
5239
|
}
|
|
5190
5240
|
function formatIssue(err) {
|
|
5191
|
-
const
|
|
5241
|
+
const path40 = err.instancePath || "";
|
|
5192
5242
|
const params = err.params;
|
|
5193
5243
|
let message = err.message || "validation failed";
|
|
5194
5244
|
let allowed;
|
|
@@ -5206,7 +5256,7 @@ function formatIssue(err) {
|
|
|
5206
5256
|
} else if (err.keyword === "type") {
|
|
5207
5257
|
message = `must be ${params.type}`;
|
|
5208
5258
|
}
|
|
5209
|
-
return { path:
|
|
5259
|
+
return { path: path40, keyword: err.keyword, message, ...allowed !== void 0 ? { allowed } : {} };
|
|
5210
5260
|
}
|
|
5211
5261
|
function validateCliProviderManifest(manifest) {
|
|
5212
5262
|
const validator = getCliValidator();
|
|
@@ -5231,6 +5281,156 @@ var init_manifest = __esm({
|
|
|
5231
5281
|
}
|
|
5232
5282
|
});
|
|
5233
5283
|
|
|
5284
|
+
// src/providers/external-sources.ts
|
|
5285
|
+
var external_sources_exports = {};
|
|
5286
|
+
__export(external_sources_exports, {
|
|
5287
|
+
activeFilePath: () => activeFilePath,
|
|
5288
|
+
deriveSourceName: () => deriveSourceName,
|
|
5289
|
+
externalRoot: () => externalRoot,
|
|
5290
|
+
inventoryExternalSources: () => inventoryExternalSources,
|
|
5291
|
+
loadExternalSources: () => loadExternalSources,
|
|
5292
|
+
loadProvidersActive: () => loadProvidersActive,
|
|
5293
|
+
resolveActiveSource: () => resolveActiveSource,
|
|
5294
|
+
saveExternalSources: () => saveExternalSources,
|
|
5295
|
+
saveProvidersActive: () => saveProvidersActive,
|
|
5296
|
+
sourcesFilePath: () => sourcesFilePath,
|
|
5297
|
+
sourcesProviding: () => sourcesProviding
|
|
5298
|
+
});
|
|
5299
|
+
import * as fs8 from "fs";
|
|
5300
|
+
import * as os10 from "os";
|
|
5301
|
+
import * as path15 from "path";
|
|
5302
|
+
function adhdevDir() {
|
|
5303
|
+
return path15.join(os10.homedir(), ".adhdev");
|
|
5304
|
+
}
|
|
5305
|
+
function externalRoot() {
|
|
5306
|
+
return path15.join(adhdevDir(), "external");
|
|
5307
|
+
}
|
|
5308
|
+
function sourcesFilePath() {
|
|
5309
|
+
return path15.join(adhdevDir(), SOURCES_FILENAME);
|
|
5310
|
+
}
|
|
5311
|
+
function activeFilePath() {
|
|
5312
|
+
return path15.join(adhdevDir(), ACTIVE_FILENAME);
|
|
5313
|
+
}
|
|
5314
|
+
function ensureAdhdevDir() {
|
|
5315
|
+
const d = adhdevDir();
|
|
5316
|
+
if (!fs8.existsSync(d)) fs8.mkdirSync(d, { recursive: true });
|
|
5317
|
+
}
|
|
5318
|
+
function loadExternalSources() {
|
|
5319
|
+
const p = sourcesFilePath();
|
|
5320
|
+
if (!fs8.existsSync(p)) return { schema: 1, sources: [] };
|
|
5321
|
+
try {
|
|
5322
|
+
const raw = JSON.parse(fs8.readFileSync(p, "utf-8"));
|
|
5323
|
+
if (!raw || typeof raw !== "object") return { schema: 1, sources: [] };
|
|
5324
|
+
const sources = Array.isArray(raw.sources) ? raw.sources.filter(isValidSource) : [];
|
|
5325
|
+
return { schema: 1, sources };
|
|
5326
|
+
} catch {
|
|
5327
|
+
return { schema: 1, sources: [] };
|
|
5328
|
+
}
|
|
5329
|
+
}
|
|
5330
|
+
function saveExternalSources(file) {
|
|
5331
|
+
ensureAdhdevDir();
|
|
5332
|
+
const tmp = sourcesFilePath() + ".tmp";
|
|
5333
|
+
fs8.writeFileSync(tmp, JSON.stringify(file, null, 2) + "\n", "utf-8");
|
|
5334
|
+
fs8.renameSync(tmp, sourcesFilePath());
|
|
5335
|
+
}
|
|
5336
|
+
function loadProvidersActive() {
|
|
5337
|
+
const p = activeFilePath();
|
|
5338
|
+
if (!fs8.existsSync(p)) return { schema: 1, active: {} };
|
|
5339
|
+
try {
|
|
5340
|
+
const raw = JSON.parse(fs8.readFileSync(p, "utf-8"));
|
|
5341
|
+
if (!raw || typeof raw !== "object") return { schema: 1, active: {} };
|
|
5342
|
+
const active = raw.active && typeof raw.active === "object" ? raw.active : {};
|
|
5343
|
+
return { schema: 1, active };
|
|
5344
|
+
} catch {
|
|
5345
|
+
return { schema: 1, active: {} };
|
|
5346
|
+
}
|
|
5347
|
+
}
|
|
5348
|
+
function saveProvidersActive(file) {
|
|
5349
|
+
ensureAdhdevDir();
|
|
5350
|
+
const tmp = activeFilePath() + ".tmp";
|
|
5351
|
+
fs8.writeFileSync(tmp, JSON.stringify(file, null, 2) + "\n", "utf-8");
|
|
5352
|
+
fs8.renameSync(tmp, activeFilePath());
|
|
5353
|
+
}
|
|
5354
|
+
function isValidSource(x) {
|
|
5355
|
+
if (!x || typeof x !== "object") return false;
|
|
5356
|
+
const s = x;
|
|
5357
|
+
return typeof s.name === "string" && s.name.length > 0 && typeof s.url === "string" && s.url.length > 0 && typeof s.ref === "string" && s.ref.length > 0 && typeof s.addedAt === "string";
|
|
5358
|
+
}
|
|
5359
|
+
function deriveSourceName(url) {
|
|
5360
|
+
const m = url.match(/[/:]([^/:]+)\/([^/]+?)(?:\.git)?$/);
|
|
5361
|
+
if (!m) return "@source";
|
|
5362
|
+
const owner = m[1].toLowerCase().replace(/[^a-z0-9_-]/g, "-");
|
|
5363
|
+
const repo = m[2].toLowerCase().replace(/[^a-z0-9_-]/g, "-");
|
|
5364
|
+
return `@${owner}-${repo}`;
|
|
5365
|
+
}
|
|
5366
|
+
function inventoryExternalSources() {
|
|
5367
|
+
const root = externalRoot();
|
|
5368
|
+
if (!fs8.existsSync(root)) return [];
|
|
5369
|
+
const out = [];
|
|
5370
|
+
let entries;
|
|
5371
|
+
try {
|
|
5372
|
+
entries = fs8.readdirSync(root, { withFileTypes: true });
|
|
5373
|
+
} catch {
|
|
5374
|
+
return [];
|
|
5375
|
+
}
|
|
5376
|
+
for (const sourceEntry of entries) {
|
|
5377
|
+
if (!sourceEntry.isDirectory()) continue;
|
|
5378
|
+
const sourceName = sourceEntry.name;
|
|
5379
|
+
const sourceDir = path15.join(root, sourceName);
|
|
5380
|
+
const providers = {};
|
|
5381
|
+
let categoryEntries;
|
|
5382
|
+
try {
|
|
5383
|
+
categoryEntries = fs8.readdirSync(sourceDir, { withFileTypes: true });
|
|
5384
|
+
} catch {
|
|
5385
|
+
continue;
|
|
5386
|
+
}
|
|
5387
|
+
for (const categoryEntry of categoryEntries) {
|
|
5388
|
+
if (!categoryEntry.isDirectory()) continue;
|
|
5389
|
+
const category = categoryEntry.name;
|
|
5390
|
+
const categoryDir = path15.join(sourceDir, category);
|
|
5391
|
+
let typeEntries;
|
|
5392
|
+
try {
|
|
5393
|
+
typeEntries = fs8.readdirSync(categoryDir, { withFileTypes: true });
|
|
5394
|
+
} catch {
|
|
5395
|
+
continue;
|
|
5396
|
+
}
|
|
5397
|
+
const types = [];
|
|
5398
|
+
for (const typeEntry of typeEntries) {
|
|
5399
|
+
if (!typeEntry.isDirectory()) continue;
|
|
5400
|
+
const typeDir = path15.join(categoryDir, typeEntry.name);
|
|
5401
|
+
const hasV1 = fs8.existsSync(path15.join(typeDir, "provider.v1.json"));
|
|
5402
|
+
const hasV0 = fs8.existsSync(path15.join(typeDir, "provider.json"));
|
|
5403
|
+
if (hasV1 || hasV0) types.push(typeEntry.name);
|
|
5404
|
+
}
|
|
5405
|
+
if (types.length > 0) providers[category] = types;
|
|
5406
|
+
}
|
|
5407
|
+
out.push({ sourceName, providers });
|
|
5408
|
+
}
|
|
5409
|
+
return out;
|
|
5410
|
+
}
|
|
5411
|
+
function sourcesProviding(category, type) {
|
|
5412
|
+
const inventory = inventoryExternalSources();
|
|
5413
|
+
return inventory.filter((s) => (s.providers[category] || []).includes(type)).map((s) => s.sourceName);
|
|
5414
|
+
}
|
|
5415
|
+
function resolveActiveSource(category, type, activeFile) {
|
|
5416
|
+
const candidates = sourcesProviding(category, type);
|
|
5417
|
+
if (candidates.length === 0) return { source: null, ambiguous: false, candidates };
|
|
5418
|
+
if (candidates.length === 1) return { source: candidates[0], ambiguous: false, candidates };
|
|
5419
|
+
const explicit = (activeFile ?? loadProvidersActive()).active[type];
|
|
5420
|
+
if (explicit && candidates.includes(explicit)) {
|
|
5421
|
+
return { source: explicit, ambiguous: false, candidates };
|
|
5422
|
+
}
|
|
5423
|
+
return { source: candidates[0], ambiguous: true, candidates };
|
|
5424
|
+
}
|
|
5425
|
+
var SOURCES_FILENAME, ACTIVE_FILENAME;
|
|
5426
|
+
var init_external_sources = __esm({
|
|
5427
|
+
"src/providers/external-sources.ts"() {
|
|
5428
|
+
"use strict";
|
|
5429
|
+
SOURCES_FILENAME = "providers-sources.json";
|
|
5430
|
+
ACTIVE_FILENAME = "providers-active.json";
|
|
5431
|
+
}
|
|
5432
|
+
});
|
|
5433
|
+
|
|
5234
5434
|
// src/cli-adapters/terminal-backends/ghostty-vt-backend.ts
|
|
5235
5435
|
function isModuleNotFoundError(error, ref) {
|
|
5236
5436
|
if (!(error instanceof Error)) return false;
|
|
@@ -5519,7 +5719,7 @@ var init_spawn_env = __esm({
|
|
|
5519
5719
|
});
|
|
5520
5720
|
|
|
5521
5721
|
// src/cli-adapters/pty-transport.ts
|
|
5522
|
-
import * as
|
|
5722
|
+
import * as os11 from "os";
|
|
5523
5723
|
function loadNodePty() {
|
|
5524
5724
|
if (cachedPty !== void 0) return cachedPty;
|
|
5525
5725
|
try {
|
|
@@ -5570,11 +5770,11 @@ var init_pty_transport = __esm({
|
|
|
5570
5770
|
let cwd = options.cwd;
|
|
5571
5771
|
if (cwd) {
|
|
5572
5772
|
try {
|
|
5573
|
-
const
|
|
5574
|
-
const stat2 =
|
|
5575
|
-
if (!stat2.isDirectory()) cwd =
|
|
5773
|
+
const fs28 = __require("fs");
|
|
5774
|
+
const stat2 = fs28.statSync(cwd);
|
|
5775
|
+
if (!stat2.isDirectory()) cwd = os11.homedir();
|
|
5576
5776
|
} catch {
|
|
5577
|
-
cwd =
|
|
5777
|
+
cwd = os11.homedir();
|
|
5578
5778
|
}
|
|
5579
5779
|
}
|
|
5580
5780
|
const handle = pty.spawn(command, args, {
|
|
@@ -5591,8 +5791,8 @@ var init_pty_transport = __esm({
|
|
|
5591
5791
|
});
|
|
5592
5792
|
|
|
5593
5793
|
// src/cli-adapters/provider-cli-shared.ts
|
|
5594
|
-
import * as
|
|
5595
|
-
import * as
|
|
5794
|
+
import * as os12 from "os";
|
|
5795
|
+
import * as path16 from "path";
|
|
5596
5796
|
function stripAnsi(str) {
|
|
5597
5797
|
return str.replace(/\x1B\][^\x07]*(?:\x07|\x1B\\)/g, "").replace(/\x1B[P^_X][\s\S]*?(?:\x07|\x1B\\)/g, "").replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "");
|
|
5598
5798
|
}
|
|
@@ -5668,21 +5868,21 @@ function buildCliScreenSnapshot(text) {
|
|
|
5668
5868
|
function findBinary(name) {
|
|
5669
5869
|
const trimmed = String(name || "").trim();
|
|
5670
5870
|
if (!trimmed) return trimmed;
|
|
5671
|
-
const expanded = trimmed.startsWith("~") ?
|
|
5672
|
-
if (
|
|
5673
|
-
return
|
|
5871
|
+
const expanded = trimmed.startsWith("~") ? path16.join(os12.homedir(), trimmed.slice(1)) : trimmed;
|
|
5872
|
+
if (path16.isAbsolute(expanded) || expanded.includes("/") || expanded.includes("\\")) {
|
|
5873
|
+
return path16.isAbsolute(expanded) ? expanded : path16.resolve(expanded);
|
|
5674
5874
|
}
|
|
5675
|
-
const isWin =
|
|
5676
|
-
const paths = (process.env.PATH || "").split(
|
|
5875
|
+
const isWin = os12.platform() === "win32";
|
|
5876
|
+
const paths = (process.env.PATH || "").split(path16.delimiter);
|
|
5677
5877
|
const exes = isWin ? [".exe", ".cmd", ".bat", ""] : [""];
|
|
5678
5878
|
for (const p of paths) {
|
|
5679
5879
|
if (!p) continue;
|
|
5680
5880
|
for (const ext of exes) {
|
|
5681
|
-
const fullPath =
|
|
5881
|
+
const fullPath = path16.join(p, trimmed + ext);
|
|
5682
5882
|
try {
|
|
5683
|
-
const
|
|
5684
|
-
if (
|
|
5685
|
-
const stat2 =
|
|
5883
|
+
const fs28 = __require("fs");
|
|
5884
|
+
if (fs28.existsSync(fullPath)) {
|
|
5885
|
+
const stat2 = fs28.statSync(fullPath);
|
|
5686
5886
|
if (stat2.isFile() && (isWin || stat2.mode & 73)) {
|
|
5687
5887
|
return fullPath;
|
|
5688
5888
|
}
|
|
@@ -5694,14 +5894,14 @@ function findBinary(name) {
|
|
|
5694
5894
|
return isWin ? `${trimmed}.cmd` : trimmed;
|
|
5695
5895
|
}
|
|
5696
5896
|
function isScriptBinary(binaryPath) {
|
|
5697
|
-
if (!
|
|
5897
|
+
if (!path16.isAbsolute(binaryPath)) return false;
|
|
5698
5898
|
try {
|
|
5699
|
-
const
|
|
5700
|
-
const resolved =
|
|
5899
|
+
const fs28 = __require("fs");
|
|
5900
|
+
const resolved = fs28.realpathSync(binaryPath);
|
|
5701
5901
|
const head = Buffer.alloc(8);
|
|
5702
|
-
const fd =
|
|
5703
|
-
|
|
5704
|
-
|
|
5902
|
+
const fd = fs28.openSync(resolved, "r");
|
|
5903
|
+
fs28.readSync(fd, head, 0, 8, 0);
|
|
5904
|
+
fs28.closeSync(fd);
|
|
5705
5905
|
let i = 0;
|
|
5706
5906
|
if (head[0] === 239 && head[1] === 187 && head[2] === 191) i = 3;
|
|
5707
5907
|
return head[i] === 35 && head[i + 1] === 33;
|
|
@@ -5710,14 +5910,14 @@ function isScriptBinary(binaryPath) {
|
|
|
5710
5910
|
}
|
|
5711
5911
|
}
|
|
5712
5912
|
function looksLikeMachOOrElf(filePath) {
|
|
5713
|
-
if (!
|
|
5913
|
+
if (!path16.isAbsolute(filePath)) return false;
|
|
5714
5914
|
try {
|
|
5715
|
-
const
|
|
5716
|
-
const resolved =
|
|
5915
|
+
const fs28 = __require("fs");
|
|
5916
|
+
const resolved = fs28.realpathSync(filePath);
|
|
5717
5917
|
const buf = Buffer.alloc(8);
|
|
5718
|
-
const fd =
|
|
5719
|
-
|
|
5720
|
-
|
|
5918
|
+
const fd = fs28.openSync(resolved, "r");
|
|
5919
|
+
fs28.readSync(fd, buf, 0, 8, 0);
|
|
5920
|
+
fs28.closeSync(fd);
|
|
5721
5921
|
let i = 0;
|
|
5722
5922
|
if (buf[0] === 239 && buf[1] === 187 && buf[2] === 191) i = 3;
|
|
5723
5923
|
const b = buf.subarray(i);
|
|
@@ -5733,7 +5933,7 @@ function looksLikeMachOOrElf(filePath) {
|
|
|
5733
5933
|
}
|
|
5734
5934
|
function shSingleQuote(arg) {
|
|
5735
5935
|
if (/^[a-zA-Z0-9@%_+=:,./-]+$/.test(arg)) return arg;
|
|
5736
|
-
if (
|
|
5936
|
+
if (os12.platform() === "win32") {
|
|
5737
5937
|
return `"${arg.replace(/"/g, '""')}"`;
|
|
5738
5938
|
}
|
|
5739
5939
|
return `'${arg.replace(/'/g, `'\\''`)}'`;
|
|
@@ -7686,23 +7886,23 @@ var init_provider_cli_config = __esm({
|
|
|
7686
7886
|
});
|
|
7687
7887
|
|
|
7688
7888
|
// src/cli-adapters/provider-cli-runtime.ts
|
|
7689
|
-
import * as
|
|
7690
|
-
import * as
|
|
7889
|
+
import * as os13 from "os";
|
|
7890
|
+
import * as path17 from "path";
|
|
7691
7891
|
import { DEFAULT_SESSION_HOST_COLS, DEFAULT_SESSION_HOST_ROWS } from "@adhdev/session-host-core";
|
|
7692
7892
|
function resolveCliSpawnPlan(options) {
|
|
7693
7893
|
const { provider, runtimeSettings, workingDir, extraArgs, extraEnv } = options;
|
|
7694
7894
|
const { spawn: spawnConfig } = provider;
|
|
7695
7895
|
const configuredCommand = typeof runtimeSettings.executablePath === "string" && runtimeSettings.executablePath.trim() ? runtimeSettings.executablePath.trim() : spawnConfig.command;
|
|
7696
7896
|
const binaryPath = findBinary(configuredCommand);
|
|
7697
|
-
const isWin =
|
|
7897
|
+
const isWin = os13.platform() === "win32";
|
|
7698
7898
|
const allArgs = [...spawnConfig.args, ...extraArgs].map(
|
|
7699
7899
|
(arg) => typeof arg === "string" ? arg.replace(/\{\{workingDir\}\}/g, workingDir) : arg
|
|
7700
7900
|
);
|
|
7701
7901
|
let shellCmd;
|
|
7702
7902
|
let shellArgs;
|
|
7703
|
-
const useShellUnix = !isWin && (!!spawnConfig.shell || !
|
|
7903
|
+
const useShellUnix = !isWin && (!!spawnConfig.shell || !path17.isAbsolute(binaryPath) || isScriptBinary(binaryPath) || !looksLikeMachOOrElf(binaryPath));
|
|
7704
7904
|
const isCmdShim = isWin && /\.(cmd|bat)$/i.test(binaryPath);
|
|
7705
|
-
const useShellWin = !!spawnConfig.shell || isCmdShim || !
|
|
7905
|
+
const useShellWin = !!spawnConfig.shell || isCmdShim || !path17.isAbsolute(binaryPath) || isScriptBinary(binaryPath);
|
|
7706
7906
|
const useShell = isWin ? useShellWin : useShellUnix;
|
|
7707
7907
|
if (useShell) {
|
|
7708
7908
|
shellCmd = isWin ? "cmd.exe" : process.env.SHELL || "/bin/zsh";
|
|
@@ -7792,7 +7992,7 @@ __export(provider_cli_adapter_exports, {
|
|
|
7792
7992
|
appendBoundedText: () => appendBoundedText,
|
|
7793
7993
|
normalizeCliProviderForRuntime: () => normalizeCliProviderForRuntime
|
|
7794
7994
|
});
|
|
7795
|
-
import * as
|
|
7995
|
+
import * as os14 from "os";
|
|
7796
7996
|
function appendBoundedText(current, chunk, maxChars) {
|
|
7797
7997
|
if (!chunk) return current.length <= maxChars ? current : current.slice(-maxChars);
|
|
7798
7998
|
if (maxChars <= 0) return "";
|
|
@@ -7825,7 +8025,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
7825
8025
|
this.transportFactory = transportFactory;
|
|
7826
8026
|
this.cliType = provider.type;
|
|
7827
8027
|
this.cliName = provider.name;
|
|
7828
|
-
this.workingDir = workingDir.startsWith("~") ? workingDir.replace(/^~/,
|
|
8028
|
+
this.workingDir = workingDir.startsWith("~") ? workingDir.replace(/^~/, os14.homedir()) : workingDir;
|
|
7829
8029
|
const resolvedConfig = resolveCliAdapterConfig(provider);
|
|
7830
8030
|
this.timeouts = resolvedConfig.timeouts;
|
|
7831
8031
|
this.approvalKeys = resolvedConfig.approvalKeys;
|
|
@@ -9969,13 +10169,13 @@ __export(loader_exports, {
|
|
|
9969
10169
|
loadSpec: () => loadSpec,
|
|
9970
10170
|
resolveSpecPath: () => resolveSpecPath
|
|
9971
10171
|
});
|
|
9972
|
-
import * as
|
|
9973
|
-
import * as
|
|
10172
|
+
import * as fs9 from "fs";
|
|
10173
|
+
import * as path18 from "path";
|
|
9974
10174
|
import Ajv from "ajv";
|
|
9975
10175
|
function loadSpec(sourcePath) {
|
|
9976
10176
|
let raw;
|
|
9977
10177
|
try {
|
|
9978
|
-
const text =
|
|
10178
|
+
const text = fs9.readFileSync(sourcePath, "utf8");
|
|
9979
10179
|
raw = JSON.parse(text);
|
|
9980
10180
|
} catch (err) {
|
|
9981
10181
|
return { ok: false, errors: [`Failed to read spec: ${err.message}`], sourcePath };
|
|
@@ -10051,7 +10251,7 @@ function compileRegex2(source, flags, where, errs) {
|
|
|
10051
10251
|
}
|
|
10052
10252
|
}
|
|
10053
10253
|
function resolveSpecPath(providerDir) {
|
|
10054
|
-
return
|
|
10254
|
+
return path18.join(providerDir, "spec.json");
|
|
10055
10255
|
}
|
|
10056
10256
|
var ajv, validate;
|
|
10057
10257
|
var init_loader = __esm({
|
|
@@ -10074,7 +10274,7 @@ __export(require_whitelist_exports, {
|
|
|
10074
10274
|
registerProviderScriptRoot: () => registerProviderScriptRoot,
|
|
10075
10275
|
unregisterProviderScriptRoot: () => unregisterProviderScriptRoot
|
|
10076
10276
|
});
|
|
10077
|
-
import * as
|
|
10277
|
+
import * as path24 from "path";
|
|
10078
10278
|
import { createRequire as createRequire3 } from "module";
|
|
10079
10279
|
import * as nodeFs from "fs";
|
|
10080
10280
|
import * as nodeChildProcess from "child_process";
|
|
@@ -10215,7 +10415,7 @@ function _getRegisteredRoots() {
|
|
|
10215
10415
|
}
|
|
10216
10416
|
function canonicalize(p) {
|
|
10217
10417
|
try {
|
|
10218
|
-
const resolved =
|
|
10418
|
+
const resolved = path24.resolve(p);
|
|
10219
10419
|
try {
|
|
10220
10420
|
return nodeFs.realpathSync.native ? nodeFs.realpathSync.native(resolved) : nodeFs.realpathSync(resolved);
|
|
10221
10421
|
} catch {
|
|
@@ -10235,7 +10435,7 @@ function isCallerInsideGatedRoot(callerFilename) {
|
|
|
10235
10435
|
}
|
|
10236
10436
|
for (const root of _gatedRoots) {
|
|
10237
10437
|
if (normalized === root.rootPath) return root;
|
|
10238
|
-
if (normalized.startsWith(root.rootPath +
|
|
10438
|
+
if (normalized.startsWith(root.rootPath + path24.sep)) return root;
|
|
10239
10439
|
}
|
|
10240
10440
|
return null;
|
|
10241
10441
|
}
|
|
@@ -10254,16 +10454,16 @@ function ensureInstalled() {
|
|
|
10254
10454
|
};
|
|
10255
10455
|
}
|
|
10256
10456
|
function gatedRequire(request, parent, isMain, gated, originalLoad) {
|
|
10257
|
-
if (request.startsWith("./") || request.startsWith("../") ||
|
|
10457
|
+
if (request.startsWith("./") || request.startsWith("../") || path24.isAbsolute(request)) {
|
|
10258
10458
|
let resolved;
|
|
10259
10459
|
try {
|
|
10260
|
-
const callerRequire = parent?.filename ? createRequire3(parent.filename) : createRequire3(
|
|
10460
|
+
const callerRequire = parent?.filename ? createRequire3(parent.filename) : createRequire3(path24.join(gated.rootPath, "__entry__.js"));
|
|
10261
10461
|
resolved = callerRequire.resolve(request);
|
|
10262
10462
|
} catch {
|
|
10263
10463
|
return originalLoad.call(this, request, parent, isMain);
|
|
10264
10464
|
}
|
|
10265
10465
|
const resolvedCanon = canonicalize(resolved) || resolved;
|
|
10266
|
-
if (!(resolvedCanon === gated.rootPath || resolvedCanon.startsWith(gated.rootPath +
|
|
10466
|
+
if (!(resolvedCanon === gated.rootPath || resolvedCanon.startsWith(gated.rootPath + path24.sep))) {
|
|
10267
10467
|
denyRequire(request, parent, `relative path escapes provider root (resolved to ${resolvedCanon})`);
|
|
10268
10468
|
}
|
|
10269
10469
|
return originalLoad.call(this, request, parent, isMain);
|
|
@@ -10379,9 +10579,9 @@ var native_history_executor_exports = {};
|
|
|
10379
10579
|
__export(native_history_executor_exports, {
|
|
10380
10580
|
executeNativeHistory: () => executeNativeHistory
|
|
10381
10581
|
});
|
|
10382
|
-
import * as
|
|
10383
|
-
import * as
|
|
10384
|
-
import * as
|
|
10582
|
+
import * as fs13 from "fs";
|
|
10583
|
+
import * as os18 from "os";
|
|
10584
|
+
import * as path25 from "path";
|
|
10385
10585
|
function executeNativeHistory(cfg, input) {
|
|
10386
10586
|
if (!cfg?.source) return null;
|
|
10387
10587
|
if (cfg.source.kind === "jsonl") return executeJsonl(cfg.source, input);
|
|
@@ -10400,7 +10600,7 @@ function executeJsonl(src, input) {
|
|
|
10400
10600
|
} else {
|
|
10401
10601
|
let stat2 = null;
|
|
10402
10602
|
try {
|
|
10403
|
-
stat2 =
|
|
10603
|
+
stat2 = fs13.statSync(resolved);
|
|
10404
10604
|
} catch {
|
|
10405
10605
|
return null;
|
|
10406
10606
|
}
|
|
@@ -10419,7 +10619,7 @@ function executeJsonl(src, input) {
|
|
|
10419
10619
|
const v = jsonPathGet(lines[0], src.session_id_path);
|
|
10420
10620
|
if (typeof v === "string" && v) providerSessionId = v;
|
|
10421
10621
|
} else if (src.session_id_from === "filename_uuid" || !src.session_id_from) {
|
|
10422
|
-
const m =
|
|
10622
|
+
const m = path25.basename(sourcePath).match(UUID_RE);
|
|
10423
10623
|
if (m) providerSessionId = m[1];
|
|
10424
10624
|
}
|
|
10425
10625
|
const requested = input.providerSessionId || "";
|
|
@@ -10444,7 +10644,7 @@ function executeJsonl(src, input) {
|
|
|
10444
10644
|
function readJsonlLines(p) {
|
|
10445
10645
|
let text;
|
|
10446
10646
|
try {
|
|
10447
|
-
text =
|
|
10647
|
+
text = fs13.readFileSync(p, "utf8");
|
|
10448
10648
|
} catch {
|
|
10449
10649
|
return [];
|
|
10450
10650
|
}
|
|
@@ -10461,7 +10661,7 @@ function readJsonlLines(p) {
|
|
|
10461
10661
|
}
|
|
10462
10662
|
function executeSqlite(src, input) {
|
|
10463
10663
|
const resolved = expandPath2(src.path, input);
|
|
10464
|
-
if (!resolved || !
|
|
10664
|
+
if (!resolved || !fs13.existsSync(resolved)) return null;
|
|
10465
10665
|
let Database;
|
|
10466
10666
|
try {
|
|
10467
10667
|
Database = __require("better-sqlite3");
|
|
@@ -10520,19 +10720,19 @@ function expandPath2(template, input) {
|
|
|
10520
10720
|
if (!template) return null;
|
|
10521
10721
|
let out = template;
|
|
10522
10722
|
if (out.startsWith("~/") || out === "~") {
|
|
10523
|
-
out =
|
|
10723
|
+
out = path25.join(os18.homedir(), out.slice(2));
|
|
10524
10724
|
}
|
|
10525
10725
|
out = out.replace(/\$\{([A-Z_][A-Z0-9_]*)(?::-(.*?))?\}/g, (_m, name, fallback) => {
|
|
10526
10726
|
const v = input.envOverrides?.[name] ?? process.env[name];
|
|
10527
10727
|
return v != null && v !== "" ? v : fallback ?? "";
|
|
10528
10728
|
});
|
|
10529
|
-
if (out.startsWith("~/")) out =
|
|
10729
|
+
if (out.startsWith("~/")) out = path25.join(os18.homedir(), out.slice(2));
|
|
10530
10730
|
const now = /* @__PURE__ */ new Date();
|
|
10531
10731
|
const workspaceRaw = input.workspace ?? "";
|
|
10532
10732
|
let workspaceResolved = workspaceRaw;
|
|
10533
10733
|
if (workspaceRaw) {
|
|
10534
10734
|
try {
|
|
10535
|
-
workspaceResolved =
|
|
10735
|
+
workspaceResolved = fs13.realpathSync(workspaceRaw);
|
|
10536
10736
|
} catch {
|
|
10537
10737
|
}
|
|
10538
10738
|
}
|
|
@@ -10574,20 +10774,20 @@ function expandDirGlob(template) {
|
|
|
10574
10774
|
for (const d of dirs) {
|
|
10575
10775
|
let entries;
|
|
10576
10776
|
try {
|
|
10577
|
-
entries =
|
|
10777
|
+
entries = fs13.readdirSync(d, { withFileTypes: true });
|
|
10578
10778
|
} catch {
|
|
10579
10779
|
continue;
|
|
10580
10780
|
}
|
|
10581
10781
|
for (const e of entries) {
|
|
10582
|
-
if (e.isDirectory() && re.test(e.name)) next.push(
|
|
10782
|
+
if (e.isDirectory() && re.test(e.name)) next.push(path25.join(d, e.name));
|
|
10583
10783
|
}
|
|
10584
10784
|
}
|
|
10585
10785
|
} else {
|
|
10586
10786
|
for (const d of dirs) {
|
|
10587
|
-
const candidate =
|
|
10787
|
+
const candidate = path25.join(d, seg);
|
|
10588
10788
|
let stat2 = null;
|
|
10589
10789
|
try {
|
|
10590
|
-
stat2 =
|
|
10790
|
+
stat2 = fs13.statSync(candidate);
|
|
10591
10791
|
} catch {
|
|
10592
10792
|
continue;
|
|
10593
10793
|
}
|
|
@@ -10601,13 +10801,13 @@ function expandDirGlob(template) {
|
|
|
10601
10801
|
function walkAllDirs(root, out) {
|
|
10602
10802
|
let entries;
|
|
10603
10803
|
try {
|
|
10604
|
-
entries =
|
|
10804
|
+
entries = fs13.readdirSync(root, { withFileTypes: true });
|
|
10605
10805
|
} catch {
|
|
10606
10806
|
return;
|
|
10607
10807
|
}
|
|
10608
10808
|
out.push(root);
|
|
10609
10809
|
for (const e of entries) {
|
|
10610
|
-
if (e.isDirectory()) walkAllDirs(
|
|
10810
|
+
if (e.isDirectory()) walkAllDirs(path25.join(root, e.name), out);
|
|
10611
10811
|
}
|
|
10612
10812
|
}
|
|
10613
10813
|
function newestRecentFileAcrossGlob(template, pattern, windowMs, sessionFloorMs = 0) {
|
|
@@ -10617,13 +10817,13 @@ function newestRecentFileAcrossGlob(template, pattern, windowMs, sessionFloorMs
|
|
|
10617
10817
|
for (const d of dirs) {
|
|
10618
10818
|
let entries;
|
|
10619
10819
|
try {
|
|
10620
|
-
entries =
|
|
10820
|
+
entries = fs13.readdirSync(d, { withFileTypes: true });
|
|
10621
10821
|
} catch {
|
|
10622
10822
|
continue;
|
|
10623
10823
|
}
|
|
10624
10824
|
for (const e of entries) {
|
|
10625
10825
|
if (!e.isFile() || !pattern.test(e.name)) continue;
|
|
10626
|
-
const p =
|
|
10826
|
+
const p = path25.join(d, e.name);
|
|
10627
10827
|
const mtime = safeMtimeMs(p);
|
|
10628
10828
|
if (mtime < cutoff) continue;
|
|
10629
10829
|
if (!best || mtime > best.mtime) best = { p, mtime };
|
|
@@ -10634,7 +10834,7 @@ function newestRecentFileAcrossGlob(template, pattern, windowMs, sessionFloorMs
|
|
|
10634
10834
|
function newestRecentFile(dir, pattern, windowMs, sessionFloorMs = 0) {
|
|
10635
10835
|
let entries;
|
|
10636
10836
|
try {
|
|
10637
|
-
entries =
|
|
10837
|
+
entries = fs13.readdirSync(dir, { withFileTypes: true });
|
|
10638
10838
|
} catch {
|
|
10639
10839
|
return null;
|
|
10640
10840
|
}
|
|
@@ -10642,7 +10842,7 @@ function newestRecentFile(dir, pattern, windowMs, sessionFloorMs = 0) {
|
|
|
10642
10842
|
let best = null;
|
|
10643
10843
|
for (const e of entries) {
|
|
10644
10844
|
if (!e.isFile() || !pattern.test(e.name)) continue;
|
|
10645
|
-
const p =
|
|
10845
|
+
const p = path25.join(dir, e.name);
|
|
10646
10846
|
const mtime = safeMtimeMs(p);
|
|
10647
10847
|
if (mtime < cutoff) continue;
|
|
10648
10848
|
if (!best || mtime > best.mtime) best = { p, mtime };
|
|
@@ -10651,7 +10851,7 @@ function newestRecentFile(dir, pattern, windowMs, sessionFloorMs = 0) {
|
|
|
10651
10851
|
}
|
|
10652
10852
|
function safeMtimeMs(p) {
|
|
10653
10853
|
try {
|
|
10654
|
-
return Math.floor(
|
|
10854
|
+
return Math.floor(fs13.statSync(p).mtimeMs);
|
|
10655
10855
|
} catch {
|
|
10656
10856
|
return 0;
|
|
10657
10857
|
}
|
|
@@ -10864,8 +11064,8 @@ var init_native_history_executor = __esm({
|
|
|
10864
11064
|
});
|
|
10865
11065
|
|
|
10866
11066
|
// src/providers/native-history/claude-cli-transcript.ts
|
|
10867
|
-
import * as
|
|
10868
|
-
import * as
|
|
11067
|
+
import * as fs14 from "fs";
|
|
11068
|
+
import * as path26 from "path";
|
|
10869
11069
|
function extractTimestampValue(value) {
|
|
10870
11070
|
if (typeof value === "number" && Number.isFinite(value) && value > 0) return value;
|
|
10871
11071
|
if (typeof value === "string") {
|
|
@@ -10878,7 +11078,7 @@ function extractTimestampValue(value) {
|
|
|
10878
11078
|
}
|
|
10879
11079
|
function statMtimeMs(filePath) {
|
|
10880
11080
|
try {
|
|
10881
|
-
return
|
|
11081
|
+
return fs14.statSync(filePath).mtimeMs;
|
|
10882
11082
|
} catch {
|
|
10883
11083
|
return 0;
|
|
10884
11084
|
}
|
|
@@ -10948,7 +11148,7 @@ function extractUserContentParts(content) {
|
|
|
10948
11148
|
function parseTranscriptFile(filePath, sessionId, workspaceFallback) {
|
|
10949
11149
|
let raw;
|
|
10950
11150
|
try {
|
|
10951
|
-
raw =
|
|
11151
|
+
raw = fs14.readFileSync(filePath, "utf-8");
|
|
10952
11152
|
} catch {
|
|
10953
11153
|
return [];
|
|
10954
11154
|
}
|
|
@@ -11021,10 +11221,10 @@ function parseTranscriptFile(filePath, sessionId, workspaceFallback) {
|
|
|
11021
11221
|
return records;
|
|
11022
11222
|
}
|
|
11023
11223
|
function readSession(sessionPath) {
|
|
11024
|
-
if (!sessionPath || !
|
|
11025
|
-
const basename12 =
|
|
11224
|
+
if (!sessionPath || !path26.isAbsolute(sessionPath)) return null;
|
|
11225
|
+
const basename12 = path26.basename(sessionPath, ".jsonl");
|
|
11026
11226
|
if (!isSafeSessionId(basename12)) return null;
|
|
11027
|
-
if (!
|
|
11227
|
+
if (!fs14.existsSync(sessionPath)) return null;
|
|
11028
11228
|
const sourceMtimeMs = statMtimeMs(sessionPath);
|
|
11029
11229
|
const messages = parseTranscriptFile(sessionPath, basename12);
|
|
11030
11230
|
if (messages.length === 0) return null;
|
|
@@ -11047,8 +11247,8 @@ var init_claude_cli_transcript = __esm({
|
|
|
11047
11247
|
});
|
|
11048
11248
|
|
|
11049
11249
|
// src/providers/native-history/codex-cli-transcript.ts
|
|
11050
|
-
import * as
|
|
11051
|
-
import * as
|
|
11250
|
+
import * as fs15 from "fs";
|
|
11251
|
+
import * as path27 from "path";
|
|
11052
11252
|
function extractTimestampValue2(value) {
|
|
11053
11253
|
if (typeof value === "number" && Number.isFinite(value) && value > 0) return value;
|
|
11054
11254
|
if (typeof value === "string") {
|
|
@@ -11061,7 +11261,7 @@ function extractTimestampValue2(value) {
|
|
|
11061
11261
|
}
|
|
11062
11262
|
function statMtimeMs2(filePath) {
|
|
11063
11263
|
try {
|
|
11064
|
-
return
|
|
11264
|
+
return fs15.statSync(filePath).mtimeMs;
|
|
11065
11265
|
} catch {
|
|
11066
11266
|
return 0;
|
|
11067
11267
|
}
|
|
@@ -11129,7 +11329,7 @@ function extractToolOutputContent(payload) {
|
|
|
11129
11329
|
}
|
|
11130
11330
|
function readSessionMeta(filePath) {
|
|
11131
11331
|
try {
|
|
11132
|
-
const firstLine =
|
|
11332
|
+
const firstLine = fs15.readFileSync(filePath, "utf-8").split("\n").find(Boolean);
|
|
11133
11333
|
if (!firstLine) return null;
|
|
11134
11334
|
const parsed = JSON.parse(firstLine);
|
|
11135
11335
|
if (String(parsed.type ?? "") !== "session_meta") return null;
|
|
@@ -11141,7 +11341,7 @@ function readSessionMeta(filePath) {
|
|
|
11141
11341
|
function parseSessionFile(filePath, sessionId, workspaceFallback) {
|
|
11142
11342
|
let raw;
|
|
11143
11343
|
try {
|
|
11144
|
-
raw =
|
|
11344
|
+
raw = fs15.readFileSync(filePath, "utf-8");
|
|
11145
11345
|
} catch {
|
|
11146
11346
|
return [];
|
|
11147
11347
|
}
|
|
@@ -11235,11 +11435,11 @@ function parseSessionFile(filePath, sessionId, workspaceFallback) {
|
|
|
11235
11435
|
return records;
|
|
11236
11436
|
}
|
|
11237
11437
|
function readSession2(sessionPath) {
|
|
11238
|
-
if (!sessionPath || !
|
|
11239
|
-
if (!
|
|
11438
|
+
if (!sessionPath || !path27.isAbsolute(sessionPath)) return null;
|
|
11439
|
+
if (!fs15.existsSync(sessionPath)) return null;
|
|
11240
11440
|
const meta = readSessionMeta(sessionPath);
|
|
11241
11441
|
const metaId = String(meta?.id ?? "").trim();
|
|
11242
|
-
const basename12 =
|
|
11442
|
+
const basename12 = path27.basename(sessionPath, ".jsonl");
|
|
11243
11443
|
const uuidMatch = basename12.match(/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/i);
|
|
11244
11444
|
const filenameUuid = uuidMatch ? uuidMatch[1] : "";
|
|
11245
11445
|
if (metaId && filenameUuid && metaId !== filenameUuid) return null;
|
|
@@ -11268,9 +11468,9 @@ var init_codex_cli_transcript = __esm({
|
|
|
11268
11468
|
});
|
|
11269
11469
|
|
|
11270
11470
|
// src/providers/native-history/antigravity-cli-transcript.ts
|
|
11271
|
-
import * as
|
|
11272
|
-
import * as
|
|
11273
|
-
import * as
|
|
11471
|
+
import * as fs16 from "fs";
|
|
11472
|
+
import * as path28 from "path";
|
|
11473
|
+
import * as os19 from "os";
|
|
11274
11474
|
function extractTimestampValue3(value) {
|
|
11275
11475
|
if (typeof value === "number" && Number.isFinite(value) && value > 0) return value;
|
|
11276
11476
|
if (typeof value === "string") {
|
|
@@ -11283,7 +11483,7 @@ function extractTimestampValue3(value) {
|
|
|
11283
11483
|
}
|
|
11284
11484
|
function statMtimeMs3(filePath) {
|
|
11285
11485
|
try {
|
|
11286
|
-
return
|
|
11486
|
+
return fs16.statSync(filePath).mtimeMs;
|
|
11287
11487
|
} catch {
|
|
11288
11488
|
return 0;
|
|
11289
11489
|
}
|
|
@@ -11292,13 +11492,13 @@ function isUuidLike(value) {
|
|
|
11292
11492
|
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value);
|
|
11293
11493
|
}
|
|
11294
11494
|
function antigravityRoot() {
|
|
11295
|
-
return
|
|
11495
|
+
return path28.join(os19.homedir(), ".gemini", "antigravity-cli");
|
|
11296
11496
|
}
|
|
11297
11497
|
function historyJsonlPath() {
|
|
11298
|
-
return
|
|
11498
|
+
return path28.join(antigravityRoot(), "history.jsonl");
|
|
11299
11499
|
}
|
|
11300
11500
|
function brainRoot() {
|
|
11301
|
-
return
|
|
11501
|
+
return path28.join(antigravityRoot(), "brain");
|
|
11302
11502
|
}
|
|
11303
11503
|
function extractUserRequestContent(content) {
|
|
11304
11504
|
const raw = content.trim();
|
|
@@ -11314,7 +11514,7 @@ function antigravityRowKind(rowType) {
|
|
|
11314
11514
|
function parseBrainTranscript(filePath, sessionId, workspace) {
|
|
11315
11515
|
let raw;
|
|
11316
11516
|
try {
|
|
11317
|
-
raw =
|
|
11517
|
+
raw = fs16.readFileSync(filePath, "utf-8");
|
|
11318
11518
|
} catch {
|
|
11319
11519
|
return null;
|
|
11320
11520
|
}
|
|
@@ -11374,7 +11574,7 @@ function readHistoryRows() {
|
|
|
11374
11574
|
const sourcePath = historyJsonlPath();
|
|
11375
11575
|
let lines = [];
|
|
11376
11576
|
try {
|
|
11377
|
-
lines =
|
|
11577
|
+
lines = fs16.readFileSync(sourcePath, "utf-8").split("\n").filter(Boolean);
|
|
11378
11578
|
} catch {
|
|
11379
11579
|
return [];
|
|
11380
11580
|
}
|
|
@@ -11421,7 +11621,7 @@ function extractStringsFromBuffer(buf) {
|
|
|
11421
11621
|
function parsePbFile(filePath, sessionId) {
|
|
11422
11622
|
let buf;
|
|
11423
11623
|
try {
|
|
11424
|
-
buf =
|
|
11624
|
+
buf = fs16.readFileSync(filePath);
|
|
11425
11625
|
} catch {
|
|
11426
11626
|
return null;
|
|
11427
11627
|
}
|
|
@@ -11444,13 +11644,13 @@ function parsePbFile(filePath, sessionId) {
|
|
|
11444
11644
|
];
|
|
11445
11645
|
}
|
|
11446
11646
|
function readSession3(sessionPath, sessionId, workspace) {
|
|
11447
|
-
if (!sessionPath || !
|
|
11448
|
-
if (!
|
|
11647
|
+
if (!sessionPath || !path28.isAbsolute(sessionPath)) return null;
|
|
11648
|
+
if (!fs16.existsSync(sessionPath)) return null;
|
|
11449
11649
|
const sourceMtimeMs = statMtimeMs3(sessionPath);
|
|
11450
11650
|
const brainRootPath = brainRoot();
|
|
11451
|
-
if (sessionPath.startsWith(brainRootPath +
|
|
11452
|
-
const
|
|
11453
|
-
const uuidFromPath =
|
|
11651
|
+
if (sessionPath.startsWith(brainRootPath + path28.sep) && sessionPath.endsWith(".jsonl")) {
|
|
11652
|
+
const relative5 = sessionPath.slice(brainRootPath.length + 1);
|
|
11653
|
+
const uuidFromPath = relative5.split(path28.sep)[0];
|
|
11454
11654
|
const resolvedSessionId = sessionId || (isUuidLike(uuidFromPath) ? uuidFromPath : "");
|
|
11455
11655
|
if (!resolvedSessionId) return null;
|
|
11456
11656
|
const messages = parseBrainTranscript(sessionPath, resolvedSessionId, workspace);
|
|
@@ -11466,7 +11666,7 @@ function readSession3(sessionPath, sessionId, workspace) {
|
|
|
11466
11666
|
};
|
|
11467
11667
|
}
|
|
11468
11668
|
if (sessionPath.endsWith(".pb")) {
|
|
11469
|
-
const pbSessionId = sessionId ||
|
|
11669
|
+
const pbSessionId = sessionId || path28.basename(sessionPath, ".pb");
|
|
11470
11670
|
if (!isUuidLike(pbSessionId)) return null;
|
|
11471
11671
|
const messages = parsePbFile(sessionPath, pbSessionId);
|
|
11472
11672
|
if (!messages || messages.length === 0) return null;
|
|
@@ -11480,7 +11680,7 @@ function readSession3(sessionPath, sessionId, workspace) {
|
|
|
11480
11680
|
partialReason: "antigravity_cli_pb_raw_text_extraction"
|
|
11481
11681
|
};
|
|
11482
11682
|
}
|
|
11483
|
-
if (
|
|
11683
|
+
if (path28.basename(sessionPath) === "history.jsonl") {
|
|
11484
11684
|
const resolvedSessionId = sessionId || "";
|
|
11485
11685
|
if (!resolvedSessionId || !isUuidLike(resolvedSessionId)) return null;
|
|
11486
11686
|
const rows = readHistoryRows().filter((r) => r.conversationId === resolvedSessionId);
|
|
@@ -11534,18 +11734,18 @@ var init_antigravity_cli_transcript = __esm({
|
|
|
11534
11734
|
});
|
|
11535
11735
|
|
|
11536
11736
|
// src/providers/native-history/hermes-cli-transcript.ts
|
|
11537
|
-
import * as
|
|
11538
|
-
import * as
|
|
11539
|
-
import * as
|
|
11737
|
+
import * as fs17 from "fs";
|
|
11738
|
+
import * as path29 from "path";
|
|
11739
|
+
import * as os20 from "os";
|
|
11540
11740
|
function statMtimeMs4(p) {
|
|
11541
11741
|
try {
|
|
11542
|
-
return Math.floor(
|
|
11742
|
+
return Math.floor(fs17.statSync(p).mtimeMs);
|
|
11543
11743
|
} catch {
|
|
11544
11744
|
return 0;
|
|
11545
11745
|
}
|
|
11546
11746
|
}
|
|
11547
11747
|
function openDb() {
|
|
11548
|
-
if (!
|
|
11748
|
+
if (!fs17.existsSync(HERMES_STATE_DB)) return null;
|
|
11549
11749
|
try {
|
|
11550
11750
|
const Database = __require("better-sqlite3");
|
|
11551
11751
|
return new Database(HERMES_STATE_DB, { readonly: true, fileMustExist: true });
|
|
@@ -11602,10 +11802,10 @@ function readSession4(sessionPath) {
|
|
|
11602
11802
|
}
|
|
11603
11803
|
}
|
|
11604
11804
|
}
|
|
11605
|
-
if (!
|
|
11805
|
+
if (!path29.isAbsolute(sessionPath) || !fs17.existsSync(sessionPath)) return null;
|
|
11606
11806
|
let raw;
|
|
11607
11807
|
try {
|
|
11608
|
-
raw = JSON.parse(
|
|
11808
|
+
raw = JSON.parse(fs17.readFileSync(sessionPath, "utf8"));
|
|
11609
11809
|
} catch {
|
|
11610
11810
|
return null;
|
|
11611
11811
|
}
|
|
@@ -11628,7 +11828,7 @@ function readSession4(sessionPath) {
|
|
|
11628
11828
|
});
|
|
11629
11829
|
}
|
|
11630
11830
|
if (messages.length === 0) return null;
|
|
11631
|
-
const sessionId = typeof raw.session_id === "string" && raw.session_id ? raw.session_id :
|
|
11831
|
+
const sessionId = typeof raw.session_id === "string" && raw.session_id ? raw.session_id : path29.basename(sessionPath, ".json").replace(/^session_/, "");
|
|
11632
11832
|
return {
|
|
11633
11833
|
messages,
|
|
11634
11834
|
providerSessionId: sessionId,
|
|
@@ -11649,8 +11849,8 @@ var HERMES_STATE_DB, HERMES_LEGACY_SESSIONS_DIR;
|
|
|
11649
11849
|
var init_hermes_cli_transcript = __esm({
|
|
11650
11850
|
"src/providers/native-history/hermes-cli-transcript.ts"() {
|
|
11651
11851
|
"use strict";
|
|
11652
|
-
HERMES_STATE_DB =
|
|
11653
|
-
HERMES_LEGACY_SESSIONS_DIR =
|
|
11852
|
+
HERMES_STATE_DB = path29.join(os20.homedir(), ".hermes", "state.db");
|
|
11853
|
+
HERMES_LEGACY_SESSIONS_DIR = path29.join(os20.homedir(), ".hermes", "sessions");
|
|
11654
11854
|
}
|
|
11655
11855
|
});
|
|
11656
11856
|
|
|
@@ -11659,9 +11859,9 @@ var dispatcher_exports = {};
|
|
|
11659
11859
|
__export(dispatcher_exports, {
|
|
11660
11860
|
createNativeHistoryDispatcher: () => createNativeHistoryDispatcher
|
|
11661
11861
|
});
|
|
11662
|
-
import * as
|
|
11663
|
-
import * as
|
|
11664
|
-
import * as
|
|
11862
|
+
import * as fs18 from "fs";
|
|
11863
|
+
import * as os21 from "os";
|
|
11864
|
+
import * as path30 from "path";
|
|
11665
11865
|
function createNativeHistoryDispatcher(reader) {
|
|
11666
11866
|
return (input) => {
|
|
11667
11867
|
const workspace = input.workspace || "";
|
|
@@ -11701,26 +11901,26 @@ function resolveSourcePath(reader, workspace, sessionId) {
|
|
|
11701
11901
|
}
|
|
11702
11902
|
}
|
|
11703
11903
|
function resolveClaudePath(workspace, sessionId) {
|
|
11704
|
-
const dir =
|
|
11705
|
-
if (!
|
|
11904
|
+
const dir = path30.join(os21.homedir(), ".claude", "projects", cwdAsDashes(workspace));
|
|
11905
|
+
if (!fs18.existsSync(dir)) return null;
|
|
11706
11906
|
if (sessionId) {
|
|
11707
|
-
const candidate =
|
|
11708
|
-
if (
|
|
11907
|
+
const candidate = path30.join(dir, `${sessionId}.jsonl`);
|
|
11908
|
+
if (fs18.existsSync(candidate)) return candidate;
|
|
11709
11909
|
}
|
|
11710
11910
|
return null;
|
|
11711
11911
|
}
|
|
11712
11912
|
function resolveCodexPath(workspace) {
|
|
11713
11913
|
void workspace;
|
|
11714
11914
|
const now = /* @__PURE__ */ new Date();
|
|
11715
|
-
const dir =
|
|
11716
|
-
|
|
11915
|
+
const dir = path30.join(
|
|
11916
|
+
os21.homedir(),
|
|
11717
11917
|
".codex",
|
|
11718
11918
|
"sessions",
|
|
11719
11919
|
String(now.getUTCFullYear()),
|
|
11720
11920
|
String(now.getUTCMonth() + 1).padStart(2, "0"),
|
|
11721
11921
|
String(now.getUTCDate()).padStart(2, "0")
|
|
11722
11922
|
);
|
|
11723
|
-
if (
|
|
11923
|
+
if (fs18.existsSync(dir)) {
|
|
11724
11924
|
const f = newestRecentFile2(dir, /\.jsonl$/);
|
|
11725
11925
|
if (f) return f;
|
|
11726
11926
|
}
|
|
@@ -11728,23 +11928,23 @@ function resolveCodexPath(workspace) {
|
|
|
11728
11928
|
}
|
|
11729
11929
|
function resolveAntigravityPath(workspace) {
|
|
11730
11930
|
void workspace;
|
|
11731
|
-
const brainRoot2 =
|
|
11732
|
-
if (!
|
|
11931
|
+
const brainRoot2 = path30.join(os21.homedir(), ".gemini", "antigravity-cli", "brain");
|
|
11932
|
+
if (!fs18.existsSync(brainRoot2)) return null;
|
|
11733
11933
|
const cutoff = Date.now() - RECENT_WINDOW_MS;
|
|
11734
|
-
const entries =
|
|
11934
|
+
const entries = fs18.readdirSync(brainRoot2, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => ({ p: path30.join(brainRoot2, e.name), mtime: safeMtime(path30.join(brainRoot2, e.name)) })).filter((e) => e.mtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
|
|
11735
11935
|
for (const e of entries) {
|
|
11736
|
-
const t =
|
|
11737
|
-
if (
|
|
11936
|
+
const t = path30.join(e.p, ".system_generated", "logs", "transcript.jsonl");
|
|
11937
|
+
if (fs18.existsSync(t)) return t;
|
|
11738
11938
|
}
|
|
11739
11939
|
return null;
|
|
11740
11940
|
}
|
|
11741
11941
|
function resolveHermesPath(workspace, sessionId) {
|
|
11742
11942
|
void workspace;
|
|
11743
11943
|
void sessionId;
|
|
11744
|
-
const dbPath =
|
|
11745
|
-
if (
|
|
11746
|
-
const dir =
|
|
11747
|
-
if (!
|
|
11944
|
+
const dbPath = path30.join(os21.homedir(), ".hermes", "state.db");
|
|
11945
|
+
if (fs18.existsSync(dbPath)) return dbPath;
|
|
11946
|
+
const dir = path30.join(os21.homedir(), ".hermes", "sessions");
|
|
11947
|
+
if (!fs18.existsSync(dir)) return null;
|
|
11748
11948
|
return newestRecentFile2(dir, /^session_.*\.json$/);
|
|
11749
11949
|
}
|
|
11750
11950
|
function readByReader(reader, sourcePath, sessionId, workspace) {
|
|
@@ -11766,7 +11966,7 @@ function cwdAsDashes(cwd) {
|
|
|
11766
11966
|
function newestRecentFile2(dir, pattern) {
|
|
11767
11967
|
try {
|
|
11768
11968
|
const cutoff = Date.now() - RECENT_WINDOW_MS;
|
|
11769
|
-
const entries =
|
|
11969
|
+
const entries = fs18.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && pattern.test(e.name)).map((e) => ({ p: path30.join(dir, e.name), mtime: safeMtime(path30.join(dir, e.name)) })).filter((e) => e.mtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
|
|
11770
11970
|
return entries[0]?.p ?? null;
|
|
11771
11971
|
} catch {
|
|
11772
11972
|
return null;
|
|
@@ -11774,7 +11974,7 @@ function newestRecentFile2(dir, pattern) {
|
|
|
11774
11974
|
}
|
|
11775
11975
|
function safeMtime(p) {
|
|
11776
11976
|
try {
|
|
11777
|
-
return Math.floor(
|
|
11977
|
+
return Math.floor(fs18.statSync(p).mtimeMs);
|
|
11778
11978
|
} catch {
|
|
11779
11979
|
return 0;
|
|
11780
11980
|
}
|
|
@@ -12042,12 +12242,12 @@ function parseSubmoduleStatusOutput(output, repoRoot, ignorePaths) {
|
|
|
12042
12242
|
if (!match) continue;
|
|
12043
12243
|
const prefix = match[1];
|
|
12044
12244
|
const commit = match[2];
|
|
12045
|
-
const
|
|
12046
|
-
if (ignoreSet.has(
|
|
12245
|
+
const path40 = match[3];
|
|
12246
|
+
if (ignoreSet.has(path40)) continue;
|
|
12047
12247
|
submodules.push({
|
|
12048
|
-
path:
|
|
12248
|
+
path: path40,
|
|
12049
12249
|
commit,
|
|
12050
|
-
repoPath: repoRoot + "/" +
|
|
12250
|
+
repoPath: repoRoot + "/" + path40,
|
|
12051
12251
|
dirty: prefix === "+",
|
|
12052
12252
|
outOfSync: prefix === "-",
|
|
12053
12253
|
lastCheckedAt: Date.now()
|
|
@@ -13551,10 +13751,10 @@ function getRegistryPath() {
|
|
|
13551
13751
|
return join8(getDaemonDataDir(), "mesh-coordinators.json");
|
|
13552
13752
|
}
|
|
13553
13753
|
function loadMeshCoordinatorRegistry() {
|
|
13554
|
-
const
|
|
13555
|
-
if (!existsSync7(
|
|
13754
|
+
const path40 = getRegistryPath();
|
|
13755
|
+
if (!existsSync7(path40)) return;
|
|
13556
13756
|
try {
|
|
13557
|
-
const raw = JSON.parse(readFileSync5(
|
|
13757
|
+
const raw = JSON.parse(readFileSync5(path40, "utf-8"));
|
|
13558
13758
|
if (!Array.isArray(raw)) return;
|
|
13559
13759
|
_registry.clear();
|
|
13560
13760
|
for (const entry of raw) {
|
|
@@ -13773,8 +13973,8 @@ function validateMeshRefineConfig(config, source = "inline") {
|
|
|
13773
13973
|
if (rejectedCommands.length) errors.push("one or more validation commands are invalid");
|
|
13774
13974
|
return { valid: errors.length === 0, errors, bootstrapCommands, commands, rejectedCommands };
|
|
13775
13975
|
}
|
|
13776
|
-
function parseConfigText(
|
|
13777
|
-
if (/\.json$/i.test(
|
|
13976
|
+
function parseConfigText(path40, text) {
|
|
13977
|
+
if (/\.json$/i.test(path40)) return JSON.parse(text);
|
|
13778
13978
|
return yaml.load(text);
|
|
13779
13979
|
}
|
|
13780
13980
|
function loadMeshRefineConfig(mesh, workspace) {
|
|
@@ -13785,16 +13985,16 @@ function loadMeshRefineConfig(mesh, workspace) {
|
|
|
13785
13985
|
if (!validation.valid) return { source: "mesh.policy.refineConfig", sourceType: "invalid", error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
|
|
13786
13986
|
return { config: inline, source: "mesh.policy.refineConfig", sourceType: "mesh_policy" };
|
|
13787
13987
|
}
|
|
13788
|
-
for (const
|
|
13789
|
-
const configPath = join9(workspace,
|
|
13988
|
+
for (const relative5 of MESH_REFINE_CONFIG_LOCATIONS) {
|
|
13989
|
+
const configPath = join9(workspace, relative5);
|
|
13790
13990
|
if (!existsSync8(configPath)) continue;
|
|
13791
13991
|
try {
|
|
13792
13992
|
const parsed = parseConfigText(configPath, readFileSync6(configPath, "utf-8"));
|
|
13793
|
-
const validation = validateMeshRefineConfig(parsed,
|
|
13794
|
-
if (!validation.valid) return { source:
|
|
13795
|
-
return { config: parsed, source:
|
|
13993
|
+
const validation = validateMeshRefineConfig(parsed, relative5);
|
|
13994
|
+
if (!validation.valid) return { source: relative5, sourceType: "invalid", path: configPath, error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
|
|
13995
|
+
return { config: parsed, source: relative5, sourceType: "repo_file", path: configPath };
|
|
13796
13996
|
} catch (error) {
|
|
13797
|
-
return { source:
|
|
13997
|
+
return { source: relative5, sourceType: "invalid", path: configPath, error: error?.message || String(error) };
|
|
13798
13998
|
}
|
|
13799
13999
|
}
|
|
13800
14000
|
return {
|
|
@@ -13927,8 +14127,8 @@ var MESH_WORKTREE_BOOTSTRAP_CONFIG_SCHEMA = {
|
|
|
13927
14127
|
var DEFAULT_TIMEOUT_MS2 = 12e4;
|
|
13928
14128
|
var DEFAULT_OUTPUT_LIMIT_BYTES = 128 * 1024;
|
|
13929
14129
|
var OUTPUT_SUMMARY_CHARS = 2e3;
|
|
13930
|
-
function parseConfigText2(
|
|
13931
|
-
if (/\.json$/i.test(
|
|
14130
|
+
function parseConfigText2(path40, text) {
|
|
14131
|
+
if (/\.json$/i.test(path40)) return JSON.parse(text);
|
|
13932
14132
|
return yaml2.load(text);
|
|
13933
14133
|
}
|
|
13934
14134
|
function truncateOutput(value) {
|
|
@@ -13968,16 +14168,16 @@ function loadMeshWorktreeBootstrapConfig(mesh, workspace) {
|
|
|
13968
14168
|
if (!validation.valid) return { source: "mesh.policy.worktreeBootstrapConfig", sourceType: "invalid", error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
|
|
13969
14169
|
return { config: inline, source: "mesh.policy.worktreeBootstrapConfig", sourceType: "mesh_policy" };
|
|
13970
14170
|
}
|
|
13971
|
-
for (const
|
|
13972
|
-
const configPath = join10(workspace,
|
|
14171
|
+
for (const relative5 of MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS) {
|
|
14172
|
+
const configPath = join10(workspace, relative5);
|
|
13973
14173
|
if (!existsSync9(configPath)) continue;
|
|
13974
14174
|
try {
|
|
13975
14175
|
const parsed = parseConfigText2(configPath, readFileSync7(configPath, "utf-8"));
|
|
13976
|
-
const validation = validateMeshWorktreeBootstrapConfig(parsed,
|
|
13977
|
-
if (!validation.valid) return { source:
|
|
13978
|
-
return { config: parsed, source:
|
|
14176
|
+
const validation = validateMeshWorktreeBootstrapConfig(parsed, relative5);
|
|
14177
|
+
if (!validation.valid) return { source: relative5, sourceType: "invalid", path: configPath, error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
|
|
14178
|
+
return { config: parsed, source: relative5, sourceType: "repo_file", path: configPath };
|
|
13979
14179
|
} catch (error) {
|
|
13980
|
-
return { source:
|
|
14180
|
+
return { source: relative5, sourceType: "invalid", path: configPath, error: error?.message || String(error) };
|
|
13981
14181
|
}
|
|
13982
14182
|
}
|
|
13983
14183
|
return { source: "unavailable", sourceType: "unavailable", error: `No worktree bootstrap config found. Checked: ${MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS.join(", ")}` };
|
|
@@ -15218,17 +15418,17 @@ function checkPathExists(paths) {
|
|
|
15218
15418
|
return null;
|
|
15219
15419
|
}
|
|
15220
15420
|
async function detectIDEs(providerLoader) {
|
|
15221
|
-
const
|
|
15421
|
+
const os29 = platform2();
|
|
15222
15422
|
const results = [];
|
|
15223
15423
|
for (const def of getMergedDefinitions()) {
|
|
15224
15424
|
const cliPath = findCliCommand(providerLoader?.getIdeCliCommand(def.id, def.cli) || def.cli);
|
|
15225
|
-
const appPath = checkPathExists(providerLoader?.getIdePathCandidates(def.id, def.paths[
|
|
15425
|
+
const appPath = checkPathExists(providerLoader?.getIdePathCandidates(def.id, def.paths[os29] || []) || []);
|
|
15226
15426
|
let resolvedCli = cliPath;
|
|
15227
|
-
if (!resolvedCli && appPath &&
|
|
15427
|
+
if (!resolvedCli && appPath && os29 === "darwin") {
|
|
15228
15428
|
const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
|
|
15229
15429
|
if (existsSync15(bundledCli)) resolvedCli = bundledCli;
|
|
15230
15430
|
}
|
|
15231
|
-
if (!resolvedCli && appPath &&
|
|
15431
|
+
if (!resolvedCli && appPath && os29 === "win32") {
|
|
15232
15432
|
const { dirname: dirname11 } = await import("path");
|
|
15233
15433
|
const appDir = dirname11(appPath);
|
|
15234
15434
|
const candidates = [
|
|
@@ -15245,7 +15445,7 @@ async function detectIDEs(providerLoader) {
|
|
|
15245
15445
|
}
|
|
15246
15446
|
}
|
|
15247
15447
|
}
|
|
15248
|
-
const installed =
|
|
15448
|
+
const installed = os29 === "darwin" ? !!(resolvedCli || appPath) : !!resolvedCli;
|
|
15249
15449
|
const version = resolvedCli ? await getIdeVersion(resolvedCli) : null;
|
|
15250
15450
|
results.push({
|
|
15251
15451
|
id: def.id,
|
|
@@ -25627,6 +25827,14 @@ var DaemonCommandHandler = class {
|
|
|
25627
25827
|
return this.handleCheckProviderUpdates(args);
|
|
25628
25828
|
case "list_installed_providers":
|
|
25629
25829
|
return this.handleListInstalledProviders(args);
|
|
25830
|
+
case "add_provider_source":
|
|
25831
|
+
return this.handleAddProviderSource(args);
|
|
25832
|
+
case "remove_provider_source":
|
|
25833
|
+
return this.handleRemoveProviderSource(args);
|
|
25834
|
+
case "list_provider_sources":
|
|
25835
|
+
return this.handleListProviderSources(args);
|
|
25836
|
+
case "set_active_provider_source":
|
|
25837
|
+
return this.handleSetActiveProviderSource(args);
|
|
25630
25838
|
// ─── Stream commands (stream-commands.ts) ───────────
|
|
25631
25839
|
case "select_session":
|
|
25632
25840
|
return handleSelectSession(this, args);
|
|
@@ -25690,49 +25898,62 @@ var DaemonCommandHandler = class {
|
|
|
25690
25898
|
return { success: false, error: "ProviderLoader not initialized" };
|
|
25691
25899
|
}
|
|
25692
25900
|
/**
|
|
25693
|
-
* Return per-provider availability so
|
|
25694
|
-
* "Installed" badges. Reuses the existing detection state from
|
|
25901
|
+
* Return per-provider availability so the dashboard's provider catalog
|
|
25902
|
+
* can show "Installed" badges. Reuses the existing detection state from
|
|
25695
25903
|
* ProviderLoader.getMachineProviderStatus() — no probing is triggered.
|
|
25696
25904
|
*/
|
|
25697
25905
|
handleListProviderAvailability(_args) {
|
|
25698
25906
|
if (!this._ctx.providerLoader) {
|
|
25699
25907
|
return { success: false, error: "ProviderLoader not initialized" };
|
|
25700
25908
|
}
|
|
25909
|
+
const { describeTrust: describeTrust2, requiresConfirmation: requiresConfirmation2 } = (init_provider_trust(), __toCommonJS(provider_trust_exports));
|
|
25701
25910
|
const loader = this._ctx.providerLoader;
|
|
25702
25911
|
const items = loader.getAll().map((provider) => {
|
|
25703
25912
|
const machineConfig = loader.getMachineProviderConfig(provider.type);
|
|
25704
25913
|
const lastDetection = machineConfig.lastDetection;
|
|
25914
|
+
const trust = provider._sourceTrust ?? "trusted";
|
|
25915
|
+
const layer = provider._sourceLayer ?? "upstream";
|
|
25916
|
+
const sourceName = provider._sourceName ?? null;
|
|
25705
25917
|
return {
|
|
25706
25918
|
type: provider.type,
|
|
25707
25919
|
category: provider.category,
|
|
25708
25920
|
status: loader.getMachineProviderStatus(provider.type),
|
|
25709
25921
|
installed: lastDetection?.ok === true,
|
|
25710
25922
|
detectedPath: lastDetection?.path ?? null,
|
|
25711
|
-
checkedAt: lastDetection?.checkedAt ?? null
|
|
25923
|
+
checkedAt: lastDetection?.checkedAt ?? null,
|
|
25924
|
+
trust,
|
|
25925
|
+
trustDescription: describeTrust2(trust),
|
|
25926
|
+
requiresConfirmation: requiresConfirmation2(trust),
|
|
25927
|
+
sourceLayer: layer,
|
|
25928
|
+
sourceName
|
|
25712
25929
|
};
|
|
25713
25930
|
});
|
|
25714
25931
|
return { success: true, providers: items };
|
|
25715
25932
|
}
|
|
25716
25933
|
/**
|
|
25717
|
-
* Compute the *
|
|
25718
|
-
*
|
|
25719
|
-
*
|
|
25720
|
-
*
|
|
25721
|
-
*
|
|
25722
|
-
*
|
|
25934
|
+
* Compute the *upstream cache root*. install_provider_manifest writes
|
|
25935
|
+
* official-registry manifests here so the daemon's standard upstream
|
|
25936
|
+
* layer picks them up — no special handling needed at load time, and
|
|
25937
|
+
* the manifests inherit the official-trust badge instead of the
|
|
25938
|
+
* untrusted-external one.
|
|
25939
|
+
*
|
|
25940
|
+
* Path matches ProviderLoader.upstreamDir but we recompute it from
|
|
25941
|
+
* homedir() so this method stays usable in dev where userDir can
|
|
25942
|
+
* point at a sibling git checkout.
|
|
25723
25943
|
*/
|
|
25724
|
-
|
|
25725
|
-
const
|
|
25726
|
-
const
|
|
25727
|
-
return
|
|
25944
|
+
getUpstreamInstallRoot() {
|
|
25945
|
+
const os29 = __require("os");
|
|
25946
|
+
const path40 = __require("path");
|
|
25947
|
+
return path40.join(os29.homedir(), ".adhdev", "providers", ".upstream");
|
|
25728
25948
|
}
|
|
25729
25949
|
/**
|
|
25730
25950
|
* Download a single provider manifest from the registry and write it to
|
|
25731
|
-
* ~/.adhdev/
|
|
25951
|
+
* ~/.adhdev/providers/.upstream/{category}/{type}/provider.json.
|
|
25732
25952
|
*
|
|
25733
|
-
* Used by
|
|
25734
|
-
*
|
|
25735
|
-
* the
|
|
25953
|
+
* Used by standalone onboarding to seed the upstream cache with the
|
|
25954
|
+
* default provider set on first launch. Verifies SHA-256 checksum
|
|
25955
|
+
* against the registry meta before persisting. Refuses to write
|
|
25956
|
+
* outside the upstream root.
|
|
25736
25957
|
*
|
|
25737
25958
|
* Args: { type: string, category?: string, version?: string }
|
|
25738
25959
|
* If category/version are omitted, looks up the latest from the registry.
|
|
@@ -25747,8 +25968,8 @@ var DaemonCommandHandler = class {
|
|
|
25747
25968
|
return { success: false, error: "invalid type" };
|
|
25748
25969
|
}
|
|
25749
25970
|
const https = __require("https");
|
|
25750
|
-
const
|
|
25751
|
-
const
|
|
25971
|
+
const fs28 = __require("fs");
|
|
25972
|
+
const path40 = __require("path");
|
|
25752
25973
|
const crypto6 = __require("crypto");
|
|
25753
25974
|
const REGISTRY = "https://api.adhf.dev/api/v1/registry";
|
|
25754
25975
|
function fetchText(url, timeoutMs) {
|
|
@@ -25785,13 +26006,13 @@ var DaemonCommandHandler = class {
|
|
|
25785
26006
|
if (actualChecksum !== meta.checksum) {
|
|
25786
26007
|
return { success: false, error: `checksum mismatch: expected ${meta.checksum}, got ${actualChecksum}` };
|
|
25787
26008
|
}
|
|
25788
|
-
const installRoot = this.
|
|
25789
|
-
const installRootResolved =
|
|
25790
|
-
const targetDir =
|
|
25791
|
-
if (!targetDir.startsWith(installRootResolved +
|
|
25792
|
-
return { success: false, error: "install path escaped
|
|
26009
|
+
const installRoot = this.getUpstreamInstallRoot();
|
|
26010
|
+
const installRootResolved = path40.resolve(installRoot);
|
|
26011
|
+
const targetDir = path40.resolve(path40.join(installRoot, category, type));
|
|
26012
|
+
if (!targetDir.startsWith(installRootResolved + path40.sep)) {
|
|
26013
|
+
return { success: false, error: "install path escaped upstream root" };
|
|
25793
26014
|
}
|
|
25794
|
-
|
|
26015
|
+
fs28.mkdirSync(targetDir, { recursive: true });
|
|
25795
26016
|
let manifestProbe = {};
|
|
25796
26017
|
try {
|
|
25797
26018
|
manifestProbe = JSON.parse(manifestBody);
|
|
@@ -25815,8 +26036,8 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
25815
26036
|
}
|
|
25816
26037
|
}
|
|
25817
26038
|
const targetFile = isV1 ? "provider.v1.json" : "provider.json";
|
|
25818
|
-
const targetPath =
|
|
25819
|
-
|
|
26039
|
+
const targetPath = path40.join(targetDir, targetFile);
|
|
26040
|
+
fs28.writeFileSync(targetPath, manifestBody, "utf-8");
|
|
25820
26041
|
const manifestJson = JSON.parse(manifestBody);
|
|
25821
26042
|
const scriptFetch = await this.fetchProviderSources(
|
|
25822
26043
|
manifestJson,
|
|
@@ -25864,6 +26085,10 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
25864
26085
|
if (Array.isArray(manifest.compatibility)) {
|
|
25865
26086
|
for (const c of manifest.compatibility) {
|
|
25866
26087
|
if (typeof c?.scriptDir === "string") scriptDirs.add(c.scriptDir);
|
|
26088
|
+
if (typeof c?.spec === "string" && c.spec.includes("/")) {
|
|
26089
|
+
const dir = c.spec.substring(0, c.spec.lastIndexOf("/"));
|
|
26090
|
+
if (dir) scriptDirs.add(dir);
|
|
26091
|
+
}
|
|
25867
26092
|
}
|
|
25868
26093
|
}
|
|
25869
26094
|
if (manifest.overrides && typeof manifest.overrides === "object" && !Array.isArray(manifest.overrides)) {
|
|
@@ -25882,8 +26107,8 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
25882
26107
|
const repo = source.repo;
|
|
25883
26108
|
const ref = source.ref;
|
|
25884
26109
|
const https = __require("https");
|
|
25885
|
-
const
|
|
25886
|
-
const
|
|
26110
|
+
const fs28 = __require("fs");
|
|
26111
|
+
const path40 = __require("path");
|
|
25887
26112
|
function fetchJson(url, timeoutMs) {
|
|
25888
26113
|
return new Promise((resolve23, reject) => {
|
|
25889
26114
|
const req = https.get(url, {
|
|
@@ -25939,9 +26164,9 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
25939
26164
|
}
|
|
25940
26165
|
let fetchedCount = 0;
|
|
25941
26166
|
const sharedDirRel = `${category}/_shared`;
|
|
25942
|
-
const sharedTargetDir =
|
|
25943
|
-
const installRootResolved =
|
|
25944
|
-
if (sharedTargetDir.startsWith(installRootResolved +
|
|
26167
|
+
const sharedTargetDir = path40.resolve(path40.join(targetDir, "../_shared"));
|
|
26168
|
+
const installRootResolved = path40.resolve(path40.join(targetDir, "../.."));
|
|
26169
|
+
if (sharedTargetDir.startsWith(installRootResolved + path40.sep)) {
|
|
25945
26170
|
const sharedStack = [sharedDirRel];
|
|
25946
26171
|
while (sharedStack.length) {
|
|
25947
26172
|
const relDir = sharedStack.pop();
|
|
@@ -25964,10 +26189,10 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
25964
26189
|
try {
|
|
25965
26190
|
const body = await fetchBinary(entry.download_url, 3e4);
|
|
25966
26191
|
const relInside = entry.path.startsWith(sharedDirRel + "/") ? entry.path.slice(sharedDirRel.length + 1) : entry.path;
|
|
25967
|
-
const outPath =
|
|
25968
|
-
if (!outPath.startsWith(
|
|
25969
|
-
|
|
25970
|
-
|
|
26192
|
+
const outPath = path40.resolve(path40.join(sharedTargetDir, relInside));
|
|
26193
|
+
if (!outPath.startsWith(path40.resolve(sharedTargetDir) + path40.sep)) continue;
|
|
26194
|
+
fs28.mkdirSync(path40.dirname(outPath), { recursive: true });
|
|
26195
|
+
fs28.writeFileSync(outPath, body);
|
|
25971
26196
|
fetchedCount++;
|
|
25972
26197
|
} catch (e) {
|
|
25973
26198
|
errors.push(`fetch shared ${entry.path}: ${e?.message ?? e}`);
|
|
@@ -26000,13 +26225,13 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26000
26225
|
try {
|
|
26001
26226
|
const body = await fetchBinary(entry.download_url, 3e4);
|
|
26002
26227
|
const relInsideProvider = entry.path.startsWith(subdir + "/") ? entry.path.slice(subdir.length + 1) : entry.path;
|
|
26003
|
-
const outPath =
|
|
26004
|
-
if (!outPath.startsWith(
|
|
26228
|
+
const outPath = path40.resolve(path40.join(targetDir, relInsideProvider));
|
|
26229
|
+
if (!outPath.startsWith(path40.resolve(targetDir) + path40.sep)) {
|
|
26005
26230
|
errors.push(`refusing to write outside targetDir: ${entry.path}`);
|
|
26006
26231
|
continue;
|
|
26007
26232
|
}
|
|
26008
|
-
|
|
26009
|
-
|
|
26233
|
+
fs28.mkdirSync(path40.dirname(outPath), { recursive: true });
|
|
26234
|
+
fs28.writeFileSync(outPath, body);
|
|
26010
26235
|
fetchedCount++;
|
|
26011
26236
|
} catch (e) {
|
|
26012
26237
|
errors.push(`fetch ${entry.path}: ${e?.message ?? e}`);
|
|
@@ -26017,9 +26242,12 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26017
26242
|
return { fetchedCount, source: `${repo}@${ref}`, errors };
|
|
26018
26243
|
}
|
|
26019
26244
|
/**
|
|
26020
|
-
* Remove a provider manifest from the
|
|
26021
|
-
* (~/.adhdev/
|
|
26022
|
-
* outside that root.
|
|
26245
|
+
* Remove a provider manifest from the upstream cache root
|
|
26246
|
+
* (~/.adhdev/providers/.upstream/{category}/{type}/). Refuses to touch
|
|
26247
|
+
* anything outside that root. Used by onboarding to opt out of a
|
|
26248
|
+
* provider the user doesn't want; the dashboard no longer exposes a
|
|
26249
|
+
* per-provider uninstall button (external sources are removed as a
|
|
26250
|
+
* whole via remove_provider_source).
|
|
26023
26251
|
*/
|
|
26024
26252
|
async handleUninstallProviderManifest(args) {
|
|
26025
26253
|
const type = typeof args?.type === "string" ? args.type : "";
|
|
@@ -26031,19 +26259,19 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26031
26259
|
if (!["cli", "ide", "extension", "acp"].includes(category)) {
|
|
26032
26260
|
return { success: false, error: `unknown category: ${category}` };
|
|
26033
26261
|
}
|
|
26034
|
-
const
|
|
26035
|
-
const
|
|
26262
|
+
const fs28 = __require("fs");
|
|
26263
|
+
const path40 = __require("path");
|
|
26036
26264
|
try {
|
|
26037
|
-
const installRoot = this.
|
|
26038
|
-
const installRootResolved =
|
|
26039
|
-
const targetDir =
|
|
26040
|
-
if (!targetDir.startsWith(installRootResolved +
|
|
26041
|
-
return { success: false, error: "refusing to delete outside
|
|
26265
|
+
const installRoot = this.getUpstreamInstallRoot();
|
|
26266
|
+
const installRootResolved = path40.resolve(installRoot);
|
|
26267
|
+
const targetDir = path40.resolve(path40.join(installRoot, category, type));
|
|
26268
|
+
if (!targetDir.startsWith(installRootResolved + path40.sep)) {
|
|
26269
|
+
return { success: false, error: "refusing to delete outside upstream root" };
|
|
26042
26270
|
}
|
|
26043
|
-
if (!
|
|
26271
|
+
if (!fs28.existsSync(targetDir)) {
|
|
26044
26272
|
return { success: false, error: "not installed" };
|
|
26045
26273
|
}
|
|
26046
|
-
|
|
26274
|
+
fs28.rmSync(targetDir, { recursive: true, force: true });
|
|
26047
26275
|
if (this._ctx.providerLoader) {
|
|
26048
26276
|
this._ctx.providerLoader.reload();
|
|
26049
26277
|
this._ctx.providerLoader.registerToDetector();
|
|
@@ -26054,33 +26282,33 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26054
26282
|
}
|
|
26055
26283
|
}
|
|
26056
26284
|
/**
|
|
26057
|
-
* Return everything currently installed in
|
|
26285
|
+
* Return everything currently installed in the upstream cache with its
|
|
26058
26286
|
* version. This is the "what does this daemon have" answer used both by
|
|
26059
26287
|
* the UI and by the update checker.
|
|
26060
26288
|
*/
|
|
26061
26289
|
handleListInstalledProviders(_args) {
|
|
26062
|
-
const
|
|
26063
|
-
const
|
|
26064
|
-
const installRoot = this.
|
|
26065
|
-
if (!
|
|
26290
|
+
const fs28 = __require("fs");
|
|
26291
|
+
const path40 = __require("path");
|
|
26292
|
+
const installRoot = this.getUpstreamInstallRoot();
|
|
26293
|
+
if (!fs28.existsSync(installRoot)) return { success: true, providers: [] };
|
|
26066
26294
|
const CATEGORIES = ["cli", "ide", "extension", "acp"];
|
|
26067
26295
|
const items = [];
|
|
26068
26296
|
for (const category of CATEGORIES) {
|
|
26069
|
-
const categoryDir =
|
|
26070
|
-
if (!
|
|
26297
|
+
const categoryDir = path40.join(installRoot, category);
|
|
26298
|
+
if (!fs28.existsSync(categoryDir)) continue;
|
|
26071
26299
|
let entries;
|
|
26072
26300
|
try {
|
|
26073
|
-
entries =
|
|
26301
|
+
entries = fs28.readdirSync(categoryDir);
|
|
26074
26302
|
} catch {
|
|
26075
26303
|
continue;
|
|
26076
26304
|
}
|
|
26077
26305
|
for (const type of entries) {
|
|
26078
|
-
const v1Path =
|
|
26079
|
-
const v0Path =
|
|
26080
|
-
const manifestPath =
|
|
26306
|
+
const v1Path = path40.join(categoryDir, type, "provider.v1.json");
|
|
26307
|
+
const v0Path = path40.join(categoryDir, type, "provider.json");
|
|
26308
|
+
const manifestPath = fs28.existsSync(v1Path) ? v1Path : fs28.existsSync(v0Path) ? v0Path : null;
|
|
26081
26309
|
if (!manifestPath) continue;
|
|
26082
26310
|
try {
|
|
26083
|
-
const m = JSON.parse(
|
|
26311
|
+
const m = JSON.parse(fs28.readFileSync(manifestPath, "utf-8"));
|
|
26084
26312
|
items.push({
|
|
26085
26313
|
type,
|
|
26086
26314
|
category,
|
|
@@ -26157,6 +26385,196 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26157
26385
|
);
|
|
26158
26386
|
return { success: true, providers: checks };
|
|
26159
26387
|
}
|
|
26388
|
+
// ─── External provider sources (3rd-party git URLs) ──────────────
|
|
26389
|
+
/**
|
|
26390
|
+
* Register a new external provider source. The daemon clones the repo
|
|
26391
|
+
* to ~/.adhdev/external/<name>/, walks it once to detect provided
|
|
26392
|
+
* types, and surfaces any conflicts with already-installed types so
|
|
26393
|
+
* the dashboard can ask the user how to resolve them.
|
|
26394
|
+
*
|
|
26395
|
+
* Args: { url: string, ref?: string, name?: string }
|
|
26396
|
+
* - url: https://, git@, or any git-cloneable URL
|
|
26397
|
+
* - ref: branch/tag/commit (default "main")
|
|
26398
|
+
* - name: short identifier (default derived from URL)
|
|
26399
|
+
*
|
|
26400
|
+
* Returns: { source, providers, conflicts }
|
|
26401
|
+
* - conflicts: list of types this new source provides that another
|
|
26402
|
+
* source already exposes. UI uses this to prompt for active-source
|
|
26403
|
+
* selection before the load takes effect.
|
|
26404
|
+
*/
|
|
26405
|
+
async handleAddProviderSource(args) {
|
|
26406
|
+
const url = typeof args?.url === "string" ? args.url.trim() : "";
|
|
26407
|
+
if (!url) return { success: false, error: "url is required" };
|
|
26408
|
+
const ref = typeof args?.ref === "string" && args.ref.trim() ? args.ref.trim() : "main";
|
|
26409
|
+
if (url.startsWith("-")) return { success: false, error: 'url must not start with "-"' };
|
|
26410
|
+
if (ref.startsWith("-")) return { success: false, error: 'ref must not start with "-"' };
|
|
26411
|
+
if (!/^(https?:\/\/|git@[a-z0-9._-]+:)[a-z0-9._@:/~\-]+$/i.test(url)) {
|
|
26412
|
+
return { success: false, error: "url must be https://\u2026 or git@host:\u2026 and contain only URL-safe characters" };
|
|
26413
|
+
}
|
|
26414
|
+
if (!/^[A-Za-z0-9._/-]+$/.test(ref)) {
|
|
26415
|
+
return { success: false, error: "ref must contain only [A-Za-z0-9._/-]" };
|
|
26416
|
+
}
|
|
26417
|
+
const ext = (init_external_sources(), __toCommonJS(external_sources_exports));
|
|
26418
|
+
const requestedName = typeof args?.name === "string" && args.name.trim() ? args.name.trim() : ext.deriveSourceName(url);
|
|
26419
|
+
if (!/^@[a-z0-9_-]+$/i.test(requestedName)) {
|
|
26420
|
+
return { success: false, error: "name must match @[a-z0-9_-]+" };
|
|
26421
|
+
}
|
|
26422
|
+
const fs28 = __require("fs");
|
|
26423
|
+
const path40 = __require("path");
|
|
26424
|
+
const { spawnSync: spawnSync2 } = __require("child_process");
|
|
26425
|
+
const file = ext.loadExternalSources();
|
|
26426
|
+
if (file.sources.some((s) => s.name === requestedName)) {
|
|
26427
|
+
return { success: false, error: `source name "${requestedName}" is already registered` };
|
|
26428
|
+
}
|
|
26429
|
+
if (file.sources.some((s) => s.url === url && s.ref === ref)) {
|
|
26430
|
+
return { success: false, error: `source url+ref already registered (use a different name to track another ref)` };
|
|
26431
|
+
}
|
|
26432
|
+
const sourceDir = path40.join(ext.externalRoot(), requestedName);
|
|
26433
|
+
if (!fs28.existsSync(ext.externalRoot())) fs28.mkdirSync(ext.externalRoot(), { recursive: true });
|
|
26434
|
+
if (fs28.existsSync(sourceDir)) {
|
|
26435
|
+
return { success: false, error: `directory already exists: ${sourceDir} (rename or remove first)` };
|
|
26436
|
+
}
|
|
26437
|
+
const clone = spawnSync2("git", ["clone", "--depth=1", "--branch", ref, "--", url, sourceDir], {
|
|
26438
|
+
encoding: "utf-8",
|
|
26439
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
26440
|
+
timeout: 6e4
|
|
26441
|
+
});
|
|
26442
|
+
if (clone.status !== 0) {
|
|
26443
|
+
try {
|
|
26444
|
+
fs28.rmSync(sourceDir, { recursive: true, force: true });
|
|
26445
|
+
} catch {
|
|
26446
|
+
}
|
|
26447
|
+
return { success: false, error: `git clone failed: ${(clone.stderr || clone.stdout || "").trim() || "unknown error"}` };
|
|
26448
|
+
}
|
|
26449
|
+
const source = {
|
|
26450
|
+
name: requestedName,
|
|
26451
|
+
url,
|
|
26452
|
+
ref,
|
|
26453
|
+
addedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
26454
|
+
};
|
|
26455
|
+
ext.saveExternalSources({ schema: 1, sources: [...file.sources, source] });
|
|
26456
|
+
const inventory = ext.inventoryExternalSources();
|
|
26457
|
+
const conflicts = [];
|
|
26458
|
+
const newEntry = inventory.find((e) => e.sourceName === requestedName);
|
|
26459
|
+
if (newEntry) {
|
|
26460
|
+
for (const [category, types] of Object.entries(newEntry.providers)) {
|
|
26461
|
+
for (const type of types) {
|
|
26462
|
+
const sources = ext.sourcesProviding(category, type);
|
|
26463
|
+
if (sources.length > 1) conflicts.push({ category, type, sources });
|
|
26464
|
+
}
|
|
26465
|
+
}
|
|
26466
|
+
}
|
|
26467
|
+
if (this._ctx.providerLoader) {
|
|
26468
|
+
this._ctx.providerLoader.reload();
|
|
26469
|
+
this._ctx.providerLoader.registerToDetector();
|
|
26470
|
+
}
|
|
26471
|
+
return {
|
|
26472
|
+
success: true,
|
|
26473
|
+
source,
|
|
26474
|
+
providers: newEntry?.providers ?? {},
|
|
26475
|
+
conflicts
|
|
26476
|
+
};
|
|
26477
|
+
}
|
|
26478
|
+
/**
|
|
26479
|
+
* Remove a registered external source. Deletes the clone directory and
|
|
26480
|
+
* any active-source entry pointing to it.
|
|
26481
|
+
*
|
|
26482
|
+
* Args: { name: string }
|
|
26483
|
+
*/
|
|
26484
|
+
async handleRemoveProviderSource(args) {
|
|
26485
|
+
const name = typeof args?.name === "string" ? args.name.trim() : "";
|
|
26486
|
+
if (!name) return { success: false, error: "name is required" };
|
|
26487
|
+
const ext = (init_external_sources(), __toCommonJS(external_sources_exports));
|
|
26488
|
+
const fs28 = __require("fs");
|
|
26489
|
+
const path40 = __require("path");
|
|
26490
|
+
const file = ext.loadExternalSources();
|
|
26491
|
+
const match = file.sources.find((s) => s.name === name);
|
|
26492
|
+
if (!match) return { success: false, error: `source "${name}" not registered` };
|
|
26493
|
+
const sourceDir = path40.join(ext.externalRoot(), name);
|
|
26494
|
+
if (fs28.existsSync(sourceDir)) {
|
|
26495
|
+
try {
|
|
26496
|
+
fs28.rmSync(sourceDir, { recursive: true, force: true });
|
|
26497
|
+
} catch (e) {
|
|
26498
|
+
return { success: false, error: `failed to delete ${sourceDir}: ${e?.message || e}` };
|
|
26499
|
+
}
|
|
26500
|
+
}
|
|
26501
|
+
ext.saveExternalSources({
|
|
26502
|
+
schema: 1,
|
|
26503
|
+
sources: file.sources.filter((s) => s.name !== name)
|
|
26504
|
+
});
|
|
26505
|
+
const active = ext.loadProvidersActive();
|
|
26506
|
+
const filteredActive = {};
|
|
26507
|
+
for (const [type, src] of Object.entries(active.active)) {
|
|
26508
|
+
if (src !== name) filteredActive[type] = src;
|
|
26509
|
+
}
|
|
26510
|
+
ext.saveProvidersActive({ schema: 1, active: filteredActive });
|
|
26511
|
+
if (this._ctx.providerLoader) {
|
|
26512
|
+
this._ctx.providerLoader.reload();
|
|
26513
|
+
this._ctx.providerLoader.registerToDetector();
|
|
26514
|
+
}
|
|
26515
|
+
return { success: true, removed: { name } };
|
|
26516
|
+
}
|
|
26517
|
+
/**
|
|
26518
|
+
* List registered external sources + each source's currently installed
|
|
26519
|
+
* providers + the active selection for any conflicting types. Used by
|
|
26520
|
+
* the dashboard's "Sources" tab.
|
|
26521
|
+
*/
|
|
26522
|
+
handleListProviderSources(_args) {
|
|
26523
|
+
const ext = (init_external_sources(), __toCommonJS(external_sources_exports));
|
|
26524
|
+
const file = ext.loadExternalSources();
|
|
26525
|
+
const inventory = ext.inventoryExternalSources();
|
|
26526
|
+
const active = ext.loadProvidersActive();
|
|
26527
|
+
const sources = file.sources.map((s) => {
|
|
26528
|
+
const inv = inventory.find((e) => e.sourceName === s.name);
|
|
26529
|
+
return {
|
|
26530
|
+
...s,
|
|
26531
|
+
providers: inv?.providers ?? {}
|
|
26532
|
+
};
|
|
26533
|
+
});
|
|
26534
|
+
const conflictMap = /* @__PURE__ */ new Map();
|
|
26535
|
+
for (const inv of inventory) {
|
|
26536
|
+
for (const [category, types] of Object.entries(inv.providers)) {
|
|
26537
|
+
for (const type of types) {
|
|
26538
|
+
const candidates = ext.sourcesProviding(category, type);
|
|
26539
|
+
if (candidates.length > 1 && !conflictMap.has(type)) {
|
|
26540
|
+
conflictMap.set(type, { category, sources: candidates });
|
|
26541
|
+
}
|
|
26542
|
+
}
|
|
26543
|
+
}
|
|
26544
|
+
}
|
|
26545
|
+
const conflicts = [...conflictMap.entries()].map(([type, info]) => ({
|
|
26546
|
+
type,
|
|
26547
|
+
category: info.category,
|
|
26548
|
+
candidates: info.sources,
|
|
26549
|
+
active: active.active[type] ?? null
|
|
26550
|
+
}));
|
|
26551
|
+
return { success: true, sources, conflicts };
|
|
26552
|
+
}
|
|
26553
|
+
/**
|
|
26554
|
+
* Pick which source's copy of a conflicting provider type is active.
|
|
26555
|
+
* Other sources' copies stay on disk but the loader ignores them.
|
|
26556
|
+
*
|
|
26557
|
+
* Args: { type: string, sourceName: string }
|
|
26558
|
+
*/
|
|
26559
|
+
handleSetActiveProviderSource(args) {
|
|
26560
|
+
const type = typeof args?.type === "string" ? args.type.trim() : "";
|
|
26561
|
+
const sourceName = typeof args?.sourceName === "string" ? args.sourceName.trim() : "";
|
|
26562
|
+
if (!type || !sourceName) return { success: false, error: "type and sourceName are required" };
|
|
26563
|
+
const ext = (init_external_sources(), __toCommonJS(external_sources_exports));
|
|
26564
|
+
const inventory = ext.inventoryExternalSources();
|
|
26565
|
+
const entry = inventory.find((e) => e.sourceName === sourceName);
|
|
26566
|
+
if (!entry) return { success: false, error: `source "${sourceName}" not found` };
|
|
26567
|
+
const provided = Object.values(entry.providers).some((types) => types.includes(type));
|
|
26568
|
+
if (!provided) return { success: false, error: `source "${sourceName}" does not provide type "${type}"` };
|
|
26569
|
+
const active = ext.loadProvidersActive();
|
|
26570
|
+
active.active[type] = sourceName;
|
|
26571
|
+
ext.saveProvidersActive(active);
|
|
26572
|
+
if (this._ctx.providerLoader) {
|
|
26573
|
+
this._ctx.providerLoader.reload();
|
|
26574
|
+
this._ctx.providerLoader.registerToDetector();
|
|
26575
|
+
}
|
|
26576
|
+
return { success: true, type, sourceName };
|
|
26577
|
+
}
|
|
26160
26578
|
// ─── DevServer HTTP proxy helpers ─────────────────
|
|
26161
26579
|
// These bridge WS commands to the DevServer REST API (localhost:19280)
|
|
26162
26580
|
async proxyDevServerPost(args, endpoint) {
|
|
@@ -26252,29 +26670,29 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26252
26670
|
init_provider_cli_adapter();
|
|
26253
26671
|
init_cli_detector();
|
|
26254
26672
|
init_config();
|
|
26255
|
-
import * as
|
|
26256
|
-
import * as
|
|
26673
|
+
import * as os17 from "os";
|
|
26674
|
+
import * as path23 from "path";
|
|
26257
26675
|
import * as crypto5 from "crypto";
|
|
26258
|
-
import { existsSync as
|
|
26676
|
+
import { existsSync as existsSync21, mkdirSync as mkdirSync11, writeFileSync as writeFileSync14 } from "fs";
|
|
26259
26677
|
import { execFileSync } from "child_process";
|
|
26260
26678
|
import chalk from "chalk";
|
|
26261
26679
|
|
|
26262
26680
|
// src/providers/cli-provider-instance.ts
|
|
26263
|
-
import * as
|
|
26264
|
-
import * as
|
|
26681
|
+
import * as os16 from "os";
|
|
26682
|
+
import * as path21 from "path";
|
|
26265
26683
|
import * as crypto4 from "crypto";
|
|
26266
|
-
import * as
|
|
26684
|
+
import * as fs12 from "fs";
|
|
26267
26685
|
import { createRequire as createRequire2 } from "module";
|
|
26268
26686
|
|
|
26269
26687
|
// src/providers/spec/route.ts
|
|
26270
26688
|
init_provider_cli_adapter();
|
|
26271
|
-
import * as
|
|
26272
|
-
import * as
|
|
26689
|
+
import * as fs11 from "fs";
|
|
26690
|
+
import * as path20 from "path";
|
|
26273
26691
|
|
|
26274
26692
|
// src/providers/spec/driver.ts
|
|
26275
|
-
import * as
|
|
26276
|
-
import * as
|
|
26277
|
-
import * as
|
|
26693
|
+
import * as fs10 from "fs";
|
|
26694
|
+
import * as os15 from "os";
|
|
26695
|
+
import * as path19 from "path";
|
|
26278
26696
|
|
|
26279
26697
|
// src/providers/spec/adapter.ts
|
|
26280
26698
|
init_pty_transport();
|
|
@@ -26651,7 +27069,7 @@ var SpecDriver = class {
|
|
|
26651
27069
|
}
|
|
26652
27070
|
armSpecWatcher() {
|
|
26653
27071
|
try {
|
|
26654
|
-
this.specWatcher =
|
|
27072
|
+
this.specWatcher = fs10.watch(this.opts.specPath, { persistent: false }, () => {
|
|
26655
27073
|
const res = loadSpec(this.opts.specPath);
|
|
26656
27074
|
if (!res.ok) {
|
|
26657
27075
|
this.emit({ kind: "spec_error", errors: res.errors });
|
|
@@ -26744,7 +27162,7 @@ var SpecDriver = class {
|
|
|
26744
27162
|
}
|
|
26745
27163
|
fireDelegate(d) {
|
|
26746
27164
|
const ev = this.currentEval;
|
|
26747
|
-
const task = d.task_template.replace(/\{node\}/g,
|
|
27165
|
+
const task = d.task_template.replace(/\{node\}/g, os15.hostname()).replace(/\{state\.label\}/g, ev?.state.label ?? "").replace(/\{state\.title\}/g, ev?.state.title ?? "").replace(/\{duration_ms\}/g, String(d.after_duration_ms ?? 0));
|
|
26748
27166
|
this.emit({ kind: "delegate", id: d.id, task });
|
|
26749
27167
|
}
|
|
26750
27168
|
// ────────────────────────────────────────────────────────────────────
|
|
@@ -26813,9 +27231,9 @@ var SpecDriver = class {
|
|
|
26813
27231
|
const ctl = (this.spec.control_bar ?? []).find((c) => c.action.type === "attach_image");
|
|
26814
27232
|
if (!ctl || ctl.action.type !== "attach_image") return;
|
|
26815
27233
|
const ext = guessExt(mime);
|
|
26816
|
-
const tmp =
|
|
27234
|
+
const tmp = path19.join(os15.tmpdir(), `adhdev-attach-${Date.now()}${ext}`);
|
|
26817
27235
|
try {
|
|
26818
|
-
|
|
27236
|
+
fs10.writeFileSync(tmp, Buffer.from(blob, "base64"));
|
|
26819
27237
|
} catch {
|
|
26820
27238
|
return;
|
|
26821
27239
|
}
|
|
@@ -27143,14 +27561,14 @@ init_logger();
|
|
|
27143
27561
|
function createCliAdapter(provider, workingDir, cliArgs, extraEnv, transportFactory) {
|
|
27144
27562
|
const resolvedSpecPath = provider._resolvedSpecPath;
|
|
27145
27563
|
const dir = provider._resolvedProviderDir;
|
|
27146
|
-
let specPath = resolvedSpecPath &&
|
|
27564
|
+
let specPath = resolvedSpecPath && fs11.existsSync(resolvedSpecPath) ? resolvedSpecPath : void 0;
|
|
27147
27565
|
if (!specPath && dir) {
|
|
27148
|
-
const legacy =
|
|
27149
|
-
if (
|
|
27566
|
+
const legacy = path20.join(dir, "spec.json");
|
|
27567
|
+
if (fs11.existsSync(legacy)) specPath = legacy;
|
|
27150
27568
|
}
|
|
27151
27569
|
if (specPath) {
|
|
27152
27570
|
try {
|
|
27153
|
-
LOG.info("spec-route", `[${provider.type}] routing through SpecCliAdapter (${
|
|
27571
|
+
LOG.info("spec-route", `[${provider.type}] routing through SpecCliAdapter (${path20.relative(dir || "", specPath) || specPath})`);
|
|
27154
27572
|
return new SpecCliAdapter(specPath, workingDir, cliArgs, extraEnv, transportFactory);
|
|
27155
27573
|
} catch (err) {
|
|
27156
27574
|
LOG.warn("spec-route", `[${provider.type}] spec invalid, falling back to ProviderCliAdapter: ${err.message}`);
|
|
@@ -27211,7 +27629,7 @@ function filePathFromUri(uri) {
|
|
|
27211
27629
|
return uri.slice("file://".length);
|
|
27212
27630
|
}
|
|
27213
27631
|
}
|
|
27214
|
-
if (
|
|
27632
|
+
if (path21.isAbsolute(uri)) return uri;
|
|
27215
27633
|
return null;
|
|
27216
27634
|
}
|
|
27217
27635
|
function extensionForImageMime(mimeType) {
|
|
@@ -27226,9 +27644,9 @@ function materializeImageDataPart(part, index, dir) {
|
|
|
27226
27644
|
if (!part.data) return null;
|
|
27227
27645
|
const rawData = part.data.includes(",") ? part.data.split(",").pop() || "" : part.data;
|
|
27228
27646
|
if (!rawData) return null;
|
|
27229
|
-
|
|
27230
|
-
const filePath =
|
|
27231
|
-
|
|
27647
|
+
fs12.mkdirSync(dir, { recursive: true });
|
|
27648
|
+
const filePath = path21.join(dir, safeInputImageBasename(index, part.mimeType));
|
|
27649
|
+
fs12.writeFileSync(filePath, Buffer.from(rawData, "base64"));
|
|
27232
27650
|
cleanupStaleMaterializedImages(dir);
|
|
27233
27651
|
return filePath;
|
|
27234
27652
|
}
|
|
@@ -27240,14 +27658,14 @@ function cleanupStaleMaterializedImages(dir) {
|
|
|
27240
27658
|
if (now - lastMaterializedImageCleanupAt < MATERIALIZED_IMAGE_CLEANUP_INTERVAL_MS) return;
|
|
27241
27659
|
lastMaterializedImageCleanupAt = now;
|
|
27242
27660
|
try {
|
|
27243
|
-
const entries =
|
|
27661
|
+
const entries = fs12.readdirSync(dir);
|
|
27244
27662
|
for (const entry of entries) {
|
|
27245
27663
|
if (!entry.startsWith("adhdev-input-image-")) continue;
|
|
27246
|
-
const fullPath =
|
|
27664
|
+
const fullPath = path21.join(dir, entry);
|
|
27247
27665
|
try {
|
|
27248
|
-
const stat2 =
|
|
27666
|
+
const stat2 = fs12.statSync(fullPath);
|
|
27249
27667
|
if (now - stat2.mtimeMs > MATERIALIZED_IMAGE_MAX_AGE_MS) {
|
|
27250
|
-
|
|
27668
|
+
fs12.unlinkSync(fullPath);
|
|
27251
27669
|
}
|
|
27252
27670
|
} catch {
|
|
27253
27671
|
}
|
|
@@ -27266,7 +27684,7 @@ function buildCliStructuredInputPrompt(input, options = {}) {
|
|
|
27266
27684
|
const promptParts = [];
|
|
27267
27685
|
const imageRefs = [];
|
|
27268
27686
|
const resourceRefs = [];
|
|
27269
|
-
const materializeDir = options.materializeDir ||
|
|
27687
|
+
const materializeDir = options.materializeDir || path21.join(os16.tmpdir(), "adhdev-input-media");
|
|
27270
27688
|
input.parts.forEach((part, index) => {
|
|
27271
27689
|
if (part.type === "text" && part.text.trim()) {
|
|
27272
27690
|
promptParts.push(part.text.trim());
|
|
@@ -27333,7 +27751,7 @@ function buildIncrementalHistoryAppendMessages(previousMessages, currentMessages
|
|
|
27333
27751
|
var CachedDatabaseSync = null;
|
|
27334
27752
|
function getDatabaseSync() {
|
|
27335
27753
|
if (CachedDatabaseSync) return CachedDatabaseSync;
|
|
27336
|
-
const requireFn = typeof __require === "function" ? __require : createRequire2(
|
|
27754
|
+
const requireFn = typeof __require === "function" ? __require : createRequire2(path21.join(process.cwd(), "__adhdev_sqlite_loader__.js"));
|
|
27337
27755
|
const sqliteModule = requireFn(`node:${"sqlite"}`);
|
|
27338
27756
|
CachedDatabaseSync = sqliteModule.DatabaseSync;
|
|
27339
27757
|
if (!CachedDatabaseSync) {
|
|
@@ -27487,10 +27905,10 @@ var CliProviderInstance = class {
|
|
|
27487
27905
|
* Replaces the previously duplicated probeOpenCode/Codex/Goose functions.
|
|
27488
27906
|
*/
|
|
27489
27907
|
probeSessionIdFromConfig(probe) {
|
|
27490
|
-
const resolvedDbPath = probe.dbPath.replace(/^~/,
|
|
27908
|
+
const resolvedDbPath = probe.dbPath.replace(/^~/, os16.homedir());
|
|
27491
27909
|
const now = Date.now();
|
|
27492
27910
|
if (this.cachedSqliteDbMissingUntil > now) return null;
|
|
27493
|
-
if (!
|
|
27911
|
+
if (!fs12.existsSync(resolvedDbPath)) {
|
|
27494
27912
|
this.cachedSqliteDbMissingUntil = now + 1e4;
|
|
27495
27913
|
return null;
|
|
27496
27914
|
}
|
|
@@ -28592,7 +29010,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
28592
29010
|
};
|
|
28593
29011
|
addDir(this.workingDir);
|
|
28594
29012
|
try {
|
|
28595
|
-
addDir(
|
|
29013
|
+
addDir(fs12.realpathSync.native(this.workingDir));
|
|
28596
29014
|
} catch {
|
|
28597
29015
|
}
|
|
28598
29016
|
return Array.from(dirs);
|
|
@@ -28629,7 +29047,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
28629
29047
|
};
|
|
28630
29048
|
|
|
28631
29049
|
// src/providers/acp-provider-instance.ts
|
|
28632
|
-
import * as
|
|
29050
|
+
import * as path22 from "path";
|
|
28633
29051
|
import { Readable, Writable } from "stream";
|
|
28634
29052
|
import { spawn } from "child_process";
|
|
28635
29053
|
import {
|
|
@@ -29409,7 +29827,7 @@ var AcpProviderInstance = class {
|
|
|
29409
29827
|
return b.uri ? {
|
|
29410
29828
|
type: "resource_link",
|
|
29411
29829
|
uri: b.uri,
|
|
29412
|
-
name:
|
|
29830
|
+
name: path22.basename(b.uri),
|
|
29413
29831
|
mimeType: b.mimeType,
|
|
29414
29832
|
...b.transcript ? { description: b.transcript } : {}
|
|
29415
29833
|
} : { type: "text", text: b.transcript || `[Video attachment: ${b.mimeType}]` };
|
|
@@ -29867,17 +30285,17 @@ function shouldRestoreHostedRuntime(record, managerTag) {
|
|
|
29867
30285
|
// src/commands/cli-manager.ts
|
|
29868
30286
|
function isExplicitCommand(command) {
|
|
29869
30287
|
const trimmed = command.trim();
|
|
29870
|
-
return
|
|
30288
|
+
return path23.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
|
|
29871
30289
|
}
|
|
29872
30290
|
function expandExecutable(command) {
|
|
29873
30291
|
const trimmed = command.trim();
|
|
29874
|
-
return trimmed.startsWith("~") ?
|
|
30292
|
+
return trimmed.startsWith("~") ? path23.join(os17.homedir(), trimmed.slice(1)) : trimmed;
|
|
29875
30293
|
}
|
|
29876
30294
|
function commandExists(command) {
|
|
29877
30295
|
const trimmed = command.trim();
|
|
29878
30296
|
if (!trimmed) return false;
|
|
29879
30297
|
if (isExplicitCommand(trimmed)) {
|
|
29880
|
-
return
|
|
30298
|
+
return existsSync21(expandExecutable(trimmed));
|
|
29881
30299
|
}
|
|
29882
30300
|
try {
|
|
29883
30301
|
execFileSync(process.platform === "win32" ? "where" : "which", [trimmed], {
|
|
@@ -29998,11 +30416,11 @@ function hasCliArg(args, flag) {
|
|
|
29998
30416
|
return args.some((arg) => arg === flag || arg.startsWith(`${flag}=`));
|
|
29999
30417
|
}
|
|
30000
30418
|
function ensureEmptyDelegatedMcpConfig(workspace) {
|
|
30001
|
-
const baseDir =
|
|
30002
|
-
|
|
30003
|
-
const workspaceHash = crypto5.createHash("sha256").update(
|
|
30004
|
-
const filePath =
|
|
30005
|
-
|
|
30419
|
+
const baseDir = path23.join(os17.tmpdir(), "adhdev-delegated-agent-empty-mcp");
|
|
30420
|
+
mkdirSync11(baseDir, { recursive: true });
|
|
30421
|
+
const workspaceHash = crypto5.createHash("sha256").update(path23.resolve(workspace || os17.tmpdir())).digest("hex").slice(0, 16);
|
|
30422
|
+
const filePath = path23.join(baseDir, `${workspaceHash}.json`);
|
|
30423
|
+
writeFileSync14(filePath, JSON.stringify({ mcpServers: {} }, null, 2), "utf-8");
|
|
30006
30424
|
return filePath;
|
|
30007
30425
|
}
|
|
30008
30426
|
function buildCoordinatorDelegatedCliLaunchOptions(input) {
|
|
@@ -30295,7 +30713,7 @@ var DaemonCliManager = class {
|
|
|
30295
30713
|
async startSession(cliType, workingDir, cliArgs, initialModel, options) {
|
|
30296
30714
|
const trimmed = (workingDir || "").trim();
|
|
30297
30715
|
if (!trimmed) throw new Error("working directory required");
|
|
30298
|
-
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/,
|
|
30716
|
+
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os17.homedir()) : path23.resolve(trimmed);
|
|
30299
30717
|
const normalizedType = this.providerLoader.resolveAlias(cliType);
|
|
30300
30718
|
const rawProvider = this.providerLoader.getByAlias(cliType);
|
|
30301
30719
|
const provider = rawProvider ? this.providerLoader.resolve(normalizedType) || rawProvider : void 0;
|
|
@@ -30680,6 +31098,20 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
30680
31098
|
cliArgs: args?.cliArgs,
|
|
30681
31099
|
env: args?.env
|
|
30682
31100
|
}) : null;
|
|
31101
|
+
const provLookup = this.providerLoader.getMeta(this.providerLoader.resolveAlias(cliType));
|
|
31102
|
+
const provTrust = provLookup?._sourceTrust;
|
|
31103
|
+
if (provTrust === "external-untrusted" && args?.confirmExternalUntrusted !== true) {
|
|
31104
|
+
return {
|
|
31105
|
+
success: false,
|
|
31106
|
+
error: "untrusted_external_provider",
|
|
31107
|
+
provider: {
|
|
31108
|
+
type: provLookup?.type ?? cliType,
|
|
31109
|
+
sourceName: provLookup?._sourceName ?? null,
|
|
31110
|
+
trust: provTrust
|
|
31111
|
+
},
|
|
31112
|
+
hint: "Resend launch_cli with confirmExternalUntrusted=true after the user explicitly approves running JavaScript from this 3rd-party source."
|
|
31113
|
+
};
|
|
31114
|
+
}
|
|
30683
31115
|
const started = await this.startSession(
|
|
30684
31116
|
cliType,
|
|
30685
31117
|
dir,
|
|
@@ -30866,13 +31298,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
30866
31298
|
// src/launch.ts
|
|
30867
31299
|
import { exec as exec4, spawn as spawn2 } from "child_process";
|
|
30868
31300
|
import * as net from "net";
|
|
30869
|
-
import * as
|
|
30870
|
-
import * as
|
|
31301
|
+
import * as os23 from "os";
|
|
31302
|
+
import * as path32 from "path";
|
|
30871
31303
|
|
|
30872
31304
|
// src/providers/provider-loader.ts
|
|
30873
|
-
import * as
|
|
30874
|
-
import * as
|
|
30875
|
-
import * as
|
|
31305
|
+
import * as fs19 from "fs";
|
|
31306
|
+
import * as path31 from "path";
|
|
31307
|
+
import * as os22 from "os";
|
|
30876
31308
|
import * as chokidar from "chokidar";
|
|
30877
31309
|
init_logger();
|
|
30878
31310
|
|
|
@@ -31245,9 +31677,9 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31245
31677
|
static siblingStderrLogged = /* @__PURE__ */ new Set();
|
|
31246
31678
|
static looksLikeProviderRoot(candidate) {
|
|
31247
31679
|
try {
|
|
31248
|
-
if (!
|
|
31680
|
+
if (!fs19.existsSync(candidate) || !fs19.statSync(candidate).isDirectory()) return false;
|
|
31249
31681
|
return ["ide", "extension", "cli", "acp"].some(
|
|
31250
|
-
(category) =>
|
|
31682
|
+
(category) => fs19.existsSync(path31.join(candidate, category))
|
|
31251
31683
|
);
|
|
31252
31684
|
} catch {
|
|
31253
31685
|
return false;
|
|
@@ -31255,20 +31687,20 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31255
31687
|
}
|
|
31256
31688
|
static hasProviderRootMarker(candidate) {
|
|
31257
31689
|
try {
|
|
31258
|
-
return
|
|
31690
|
+
return fs19.existsSync(path31.join(candidate, _ProviderLoader.SIBLING_MARKER_FILE));
|
|
31259
31691
|
} catch {
|
|
31260
31692
|
return false;
|
|
31261
31693
|
}
|
|
31262
31694
|
}
|
|
31263
31695
|
detectDefaultUserDir() {
|
|
31264
|
-
const fallback =
|
|
31696
|
+
const fallback = path31.join(os22.homedir(), ".adhdev", "providers");
|
|
31265
31697
|
const envOptIn = process.env[_ProviderLoader.SIBLING_ENV_VAR] === "1";
|
|
31266
31698
|
const visited = /* @__PURE__ */ new Set();
|
|
31267
31699
|
for (const start of this.probeStarts) {
|
|
31268
|
-
let current =
|
|
31700
|
+
let current = path31.resolve(start);
|
|
31269
31701
|
while (!visited.has(current)) {
|
|
31270
31702
|
visited.add(current);
|
|
31271
|
-
const siblingCandidate =
|
|
31703
|
+
const siblingCandidate = path31.join(path31.dirname(current), _ProviderLoader.REPO_PROVIDER_DIRNAME);
|
|
31272
31704
|
if (_ProviderLoader.looksLikeProviderRoot(siblingCandidate)) {
|
|
31273
31705
|
const hasMarker = _ProviderLoader.hasProviderRootMarker(siblingCandidate);
|
|
31274
31706
|
if (envOptIn || hasMarker) {
|
|
@@ -31290,7 +31722,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31290
31722
|
return { path: siblingCandidate, source };
|
|
31291
31723
|
}
|
|
31292
31724
|
}
|
|
31293
|
-
const parent =
|
|
31725
|
+
const parent = path31.dirname(current);
|
|
31294
31726
|
if (parent === current) break;
|
|
31295
31727
|
current = parent;
|
|
31296
31728
|
}
|
|
@@ -31300,17 +31732,34 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31300
31732
|
constructor(options) {
|
|
31301
31733
|
this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
|
|
31302
31734
|
this.probeStarts = options?.probeStarts ?? [process.cwd(), __dirname];
|
|
31303
|
-
this.defaultProvidersDir =
|
|
31735
|
+
this.defaultProvidersDir = path31.join(os22.homedir(), ".adhdev", "providers");
|
|
31304
31736
|
const detected = this.detectDefaultUserDir();
|
|
31305
31737
|
this.userDir = detected.path;
|
|
31306
31738
|
this.userDirSource = detected.source;
|
|
31307
|
-
this.upstreamDir =
|
|
31739
|
+
this.upstreamDir = path31.join(this.defaultProvidersDir, ".upstream");
|
|
31308
31740
|
this.disableUpstream = false;
|
|
31309
31741
|
this.applySourceConfig({
|
|
31310
31742
|
userDir: options?.userDir,
|
|
31311
31743
|
sourceMode: options?.sourceMode,
|
|
31312
31744
|
disableUpstream: options?.disableUpstream
|
|
31313
31745
|
});
|
|
31746
|
+
this.migrateMarketplaceDirToExternal();
|
|
31747
|
+
}
|
|
31748
|
+
migrateMarketplaceDirToExternal() {
|
|
31749
|
+
try {
|
|
31750
|
+
const home = os22.homedir();
|
|
31751
|
+
const oldDir = path31.join(home, ".adhdev", "marketplace");
|
|
31752
|
+
const newDir = path31.join(home, ".adhdev", "external");
|
|
31753
|
+
if (!fs19.existsSync(oldDir)) return;
|
|
31754
|
+
if (fs19.existsSync(newDir)) {
|
|
31755
|
+
this.log(`Migration skipped: both ~/.adhdev/marketplace and ~/.adhdev/external exist (marketplace dir is now inert and can be removed manually).`);
|
|
31756
|
+
return;
|
|
31757
|
+
}
|
|
31758
|
+
fs19.renameSync(oldDir, newDir);
|
|
31759
|
+
this.log(`Migrated ~/.adhdev/marketplace \u2192 ~/.adhdev/external (one-time rename after provider source-layer cleanup).`);
|
|
31760
|
+
} catch (e) {
|
|
31761
|
+
this.log(`Marketplace\u2192external migration failed: ${e?.message || e}`);
|
|
31762
|
+
}
|
|
31314
31763
|
}
|
|
31315
31764
|
log(msg) {
|
|
31316
31765
|
this.logFn(`[ProviderLoader] ${msg}`);
|
|
@@ -31336,8 +31785,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31336
31785
|
* Highest-priority editable overrides come first.
|
|
31337
31786
|
*/
|
|
31338
31787
|
getProviderRoots() {
|
|
31339
|
-
const
|
|
31340
|
-
return [this.userDir,
|
|
31788
|
+
const externalDir = path31.join(os22.homedir(), ".adhdev", "external");
|
|
31789
|
+
return [this.userDir, externalDir, this.upstreamDir];
|
|
31341
31790
|
}
|
|
31342
31791
|
getSourceConfig() {
|
|
31343
31792
|
return {
|
|
@@ -31364,7 +31813,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31364
31813
|
this.userDir = detected.path;
|
|
31365
31814
|
this.userDirSource = detected.source;
|
|
31366
31815
|
}
|
|
31367
|
-
this.upstreamDir =
|
|
31816
|
+
this.upstreamDir = path31.join(this.defaultProvidersDir, ".upstream");
|
|
31368
31817
|
this.disableUpstream = this.sourceMode === "no-upstream";
|
|
31369
31818
|
if (this.explicitProviderDir) {
|
|
31370
31819
|
this.log(`Config 'providerDir' applied: ${this.userDir}`);
|
|
@@ -31378,7 +31827,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31378
31827
|
* Canonical provider directory shape for a given root.
|
|
31379
31828
|
*/
|
|
31380
31829
|
getProviderDir(root, category, type) {
|
|
31381
|
-
return
|
|
31830
|
+
return path31.join(root, category, type);
|
|
31382
31831
|
}
|
|
31383
31832
|
/**
|
|
31384
31833
|
* Canonical user override directory for a provider.
|
|
@@ -31405,20 +31854,23 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31405
31854
|
resolveProviderFile(type, ...segments) {
|
|
31406
31855
|
const dir = this.findProviderDirInternal(type);
|
|
31407
31856
|
if (!dir) return null;
|
|
31408
|
-
return
|
|
31857
|
+
return path31.join(dir, ...segments);
|
|
31409
31858
|
}
|
|
31410
31859
|
/**
|
|
31411
31860
|
* Load all providers (3-tier priority)
|
|
31412
|
-
* 1.
|
|
31413
|
-
* 2.
|
|
31414
|
-
*
|
|
31861
|
+
* 1. ~/.adhdev/providers/.upstream/ — official git, auto-synced
|
|
31862
|
+
* 2. ~/.adhdev/external/ — 3rd-party git sources, user-added,
|
|
31863
|
+
* bundled providers may include arbitrary JS (untrusted by default)
|
|
31864
|
+
* 3. ~/.adhdev/providers/ (excluding .upstream) — user-authored customs,
|
|
31865
|
+
* always wins
|
|
31866
|
+
* Highest priority listed last (overwrites earlier loads).
|
|
31415
31867
|
* If .upstream/ is empty, call fetchLatest() before loadAll().
|
|
31416
31868
|
*/
|
|
31417
31869
|
loadAll() {
|
|
31418
31870
|
this.providers.clear();
|
|
31419
31871
|
this.providerAvailability.clear();
|
|
31420
31872
|
let upstreamCount = 0;
|
|
31421
|
-
if (!this.disableUpstream &&
|
|
31873
|
+
if (!this.disableUpstream && fs19.existsSync(this.upstreamDir)) {
|
|
31422
31874
|
upstreamCount = this.loadDir(this.upstreamDir);
|
|
31423
31875
|
if (upstreamCount > 0) {
|
|
31424
31876
|
this.log(`Loaded ${upstreamCount} upstream providers (auto-updated)`);
|
|
@@ -31426,14 +31878,64 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31426
31878
|
} else if (this.disableUpstream) {
|
|
31427
31879
|
this.log("Upstream loading disabled (sourceMode=no-upstream)");
|
|
31428
31880
|
}
|
|
31429
|
-
const
|
|
31430
|
-
if (
|
|
31431
|
-
const
|
|
31432
|
-
|
|
31433
|
-
|
|
31881
|
+
const externalDir = path31.join(os22.homedir(), ".adhdev", "external");
|
|
31882
|
+
if (fs19.existsSync(externalDir)) {
|
|
31883
|
+
const rootEntries = (() => {
|
|
31884
|
+
try {
|
|
31885
|
+
return fs19.readdirSync(externalDir, { withFileTypes: true });
|
|
31886
|
+
} catch {
|
|
31887
|
+
return [];
|
|
31888
|
+
}
|
|
31889
|
+
})();
|
|
31890
|
+
const KNOWN_CATEGORIES = /* @__PURE__ */ new Set(["cli", "ide", "extension", "acp"]);
|
|
31891
|
+
const looksLegacy = rootEntries.some((e) => e.isDirectory() && KNOWN_CATEGORIES.has(e.name));
|
|
31892
|
+
if (looksLegacy) {
|
|
31893
|
+
const externalCount = this.loadDir(externalDir);
|
|
31894
|
+
if (externalCount > 0) {
|
|
31895
|
+
this.log(`Loaded ${externalCount} external providers (legacy unnamed source)`);
|
|
31896
|
+
}
|
|
31897
|
+
} else {
|
|
31898
|
+
const {
|
|
31899
|
+
loadProvidersActive: loadProvidersActive2,
|
|
31900
|
+
resolveActiveSource: resolveActiveSource2
|
|
31901
|
+
} = (init_external_sources(), __toCommonJS(external_sources_exports));
|
|
31902
|
+
const activeFile = loadProvidersActive2();
|
|
31903
|
+
let totalLoaded = 0;
|
|
31904
|
+
const ambiguousTypes = [];
|
|
31905
|
+
for (const sourceEntry of rootEntries) {
|
|
31906
|
+
if (!sourceEntry.isDirectory()) continue;
|
|
31907
|
+
const sourceDir = path31.join(externalDir, sourceEntry.name);
|
|
31908
|
+
const sourceLoaded = this.loadDir(sourceDir);
|
|
31909
|
+
if (sourceLoaded > 0) {
|
|
31910
|
+
totalLoaded += sourceLoaded;
|
|
31911
|
+
this.log(`Loaded ${sourceLoaded} providers from external source "${sourceEntry.name}"`);
|
|
31912
|
+
}
|
|
31913
|
+
}
|
|
31914
|
+
for (const [type] of this.providers) {
|
|
31915
|
+
const prov = this.providers.get(type);
|
|
31916
|
+
if (!prov) continue;
|
|
31917
|
+
const resolved = resolveActiveSource2(prov.category, type, activeFile);
|
|
31918
|
+
if (resolved.candidates.length <= 1) continue;
|
|
31919
|
+
if (resolved.ambiguous) {
|
|
31920
|
+
ambiguousTypes.push({ type, chosen: resolved.source ?? "?", candidates: resolved.candidates });
|
|
31921
|
+
}
|
|
31922
|
+
if (resolved.source && resolved.source !== "?") {
|
|
31923
|
+
const sourceDir = path31.join(externalDir, resolved.source);
|
|
31924
|
+
const reloadCount = this.loadDir(sourceDir);
|
|
31925
|
+
if (reloadCount === 0) {
|
|
31926
|
+
this.log(`Active source "${resolved.source}" no longer provides ${type}`);
|
|
31927
|
+
}
|
|
31928
|
+
}
|
|
31929
|
+
}
|
|
31930
|
+
if (totalLoaded > 0) {
|
|
31931
|
+
this.log(`Loaded ${totalLoaded} external providers (3rd-party sources)`);
|
|
31932
|
+
}
|
|
31933
|
+
for (const a of ambiguousTypes) {
|
|
31934
|
+
this.log(`Ambiguous provider "${a.type}" \u2014 provided by [${a.candidates.join(", ")}], defaulted to "${a.chosen}". Set the active source from the dashboard to silence this warning.`);
|
|
31935
|
+
}
|
|
31434
31936
|
}
|
|
31435
31937
|
}
|
|
31436
|
-
if (
|
|
31938
|
+
if (fs19.existsSync(this.userDir)) {
|
|
31437
31939
|
const userCount = this.loadDir(this.userDir, [".upstream"]);
|
|
31438
31940
|
if (userCount > 0) {
|
|
31439
31941
|
this.log(`Loaded ${userCount} user custom providers (never auto-updated)`);
|
|
@@ -31448,10 +31950,10 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31448
31950
|
* Check if upstream directory exists and has providers.
|
|
31449
31951
|
*/
|
|
31450
31952
|
hasUpstream() {
|
|
31451
|
-
if (!
|
|
31953
|
+
if (!fs19.existsSync(this.upstreamDir)) return false;
|
|
31452
31954
|
try {
|
|
31453
|
-
return
|
|
31454
|
-
(d) =>
|
|
31955
|
+
return fs19.readdirSync(this.upstreamDir).some(
|
|
31956
|
+
(d) => fs19.statSync(path31.join(this.upstreamDir, d)).isDirectory()
|
|
31455
31957
|
);
|
|
31456
31958
|
} catch {
|
|
31457
31959
|
return false;
|
|
@@ -31949,8 +32451,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31949
32451
|
resolved._resolvedScriptDir = entry.scriptDir;
|
|
31950
32452
|
resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
|
|
31951
32453
|
if (providerDir) {
|
|
31952
|
-
const fullDir =
|
|
31953
|
-
resolved._resolvedScriptsPath =
|
|
32454
|
+
const fullDir = path31.join(providerDir, entry.scriptDir);
|
|
32455
|
+
resolved._resolvedScriptsPath = fs19.existsSync(path31.join(fullDir, "scripts.js")) ? path31.join(fullDir, "scripts.js") : fullDir;
|
|
31954
32456
|
}
|
|
31955
32457
|
matched = true;
|
|
31956
32458
|
}
|
|
@@ -31968,8 +32470,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31968
32470
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
31969
32471
|
resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
|
|
31970
32472
|
if (providerDir) {
|
|
31971
|
-
const fullDir =
|
|
31972
|
-
resolved._resolvedScriptsPath =
|
|
32473
|
+
const fullDir = path31.join(providerDir, base.defaultScriptDir);
|
|
32474
|
+
resolved._resolvedScriptsPath = fs19.existsSync(path31.join(fullDir, "scripts.js")) ? path31.join(fullDir, "scripts.js") : fullDir;
|
|
31973
32475
|
}
|
|
31974
32476
|
}
|
|
31975
32477
|
resolved._versionWarning = `Version ${currentVersion} not in compatibility matrix. Using default scripts.`;
|
|
@@ -31986,8 +32488,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31986
32488
|
resolved._resolvedScriptDir = dirOverride;
|
|
31987
32489
|
resolved._resolvedScriptsSource = `versions:${range}`;
|
|
31988
32490
|
if (providerDir) {
|
|
31989
|
-
const fullDir =
|
|
31990
|
-
resolved._resolvedScriptsPath =
|
|
32491
|
+
const fullDir = path31.join(providerDir, dirOverride);
|
|
32492
|
+
resolved._resolvedScriptsPath = fs19.existsSync(path31.join(fullDir, "scripts.js")) ? path31.join(fullDir, "scripts.js") : fullDir;
|
|
31991
32493
|
}
|
|
31992
32494
|
}
|
|
31993
32495
|
} else if (override.scripts) {
|
|
@@ -32003,8 +32505,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32003
32505
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
32004
32506
|
resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
|
|
32005
32507
|
if (providerDir) {
|
|
32006
|
-
const fullDir =
|
|
32007
|
-
resolved._resolvedScriptsPath =
|
|
32508
|
+
const fullDir = path31.join(providerDir, base.defaultScriptDir);
|
|
32509
|
+
resolved._resolvedScriptsPath = fs19.existsSync(path31.join(fullDir, "scripts.js")) ? path31.join(fullDir, "scripts.js") : fullDir;
|
|
32008
32510
|
}
|
|
32009
32511
|
}
|
|
32010
32512
|
}
|
|
@@ -32021,13 +32523,13 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32021
32523
|
if (providerDir2) {
|
|
32022
32524
|
for (const [scriptName, override] of Object.entries(base.overrides)) {
|
|
32023
32525
|
if (!override || typeof override.path !== "string") continue;
|
|
32024
|
-
const fullPath =
|
|
32025
|
-
if (!
|
|
32526
|
+
const fullPath = path31.join(providerDir2, override.path);
|
|
32527
|
+
if (!fs19.existsSync(fullPath)) {
|
|
32026
32528
|
this.log(` [overrides] ${base.type}: ${scriptName} path not found: ${fullPath}`);
|
|
32027
32529
|
continue;
|
|
32028
32530
|
}
|
|
32029
32531
|
try {
|
|
32030
|
-
registerProviderScriptRootSafely(
|
|
32532
|
+
registerProviderScriptRootSafely(path31.dirname(path31.dirname(providerDir2)));
|
|
32031
32533
|
delete __require.cache[__require.resolve(fullPath)];
|
|
32032
32534
|
const fn = __require(fullPath);
|
|
32033
32535
|
const target = typeof fn === "function" ? fn : fn && fn[scriptName];
|
|
@@ -32052,19 +32554,19 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32052
32554
|
}
|
|
32053
32555
|
if (providerDir) {
|
|
32054
32556
|
try {
|
|
32055
|
-
const
|
|
32056
|
-
const
|
|
32557
|
+
const fs28 = __require("fs");
|
|
32558
|
+
const path40 = __require("path");
|
|
32057
32559
|
const candidates = [];
|
|
32058
32560
|
if (Array.isArray(base.compatibility)) {
|
|
32059
32561
|
for (const entry of base.compatibility) {
|
|
32060
32562
|
if (typeof entry?.spec !== "string") continue;
|
|
32061
32563
|
const matches = !entry.ideVersion || currentVersion && this.matchesVersion(currentVersion, entry.ideVersion) || !currentVersion;
|
|
32062
|
-
if (matches) candidates.push(
|
|
32564
|
+
if (matches) candidates.push(path40.join(providerDir, entry.spec));
|
|
32063
32565
|
}
|
|
32064
32566
|
}
|
|
32065
|
-
candidates.push(
|
|
32066
|
-
candidates.push(
|
|
32067
|
-
const specPath = candidates.find((p) =>
|
|
32567
|
+
candidates.push(path40.join(providerDir, "specs", "default.json"));
|
|
32568
|
+
candidates.push(path40.join(providerDir, "spec.json"));
|
|
32569
|
+
const specPath = candidates.find((p) => fs28.existsSync(p));
|
|
32068
32570
|
if (specPath) {
|
|
32069
32571
|
resolved._resolvedSpecPath = specPath;
|
|
32070
32572
|
const { loadSpec: loadSpec2 } = (init_loader(), __toCommonJS(loader_exports));
|
|
@@ -32093,10 +32595,10 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32093
32595
|
format = `spec-${nh.source.kind}`;
|
|
32094
32596
|
reader = (input) => executeNativeHistory2(nh, input);
|
|
32095
32597
|
} else if (nh.override_path) {
|
|
32096
|
-
const overrideFile =
|
|
32097
|
-
if (
|
|
32598
|
+
const overrideFile = path40.resolve(providerDir, nh.override_path);
|
|
32599
|
+
if (fs28.existsSync(overrideFile)) {
|
|
32098
32600
|
try {
|
|
32099
|
-
registerProviderScriptRootSafely(
|
|
32601
|
+
registerProviderScriptRootSafely(path40.dirname(path40.dirname(providerDir)));
|
|
32100
32602
|
delete __require.cache[__require.resolve(overrideFile)];
|
|
32101
32603
|
const mod = __require(overrideFile);
|
|
32102
32604
|
const fn = typeof mod === "function" ? mod : mod && typeof mod.default === "function" ? mod.default : null;
|
|
@@ -32140,16 +32642,16 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32140
32642
|
this.debugLog(`[loadScriptsFromDir] ${type}: providerDir not found`);
|
|
32141
32643
|
return null;
|
|
32142
32644
|
}
|
|
32143
|
-
const dir =
|
|
32144
|
-
if (!
|
|
32645
|
+
const dir = path31.join(providerDir, scriptDir);
|
|
32646
|
+
if (!fs19.existsSync(dir)) {
|
|
32145
32647
|
this.debugLog(`[loadScriptsFromDir] ${type}: dir not found: ${dir}`);
|
|
32146
32648
|
return null;
|
|
32147
32649
|
}
|
|
32148
|
-
registerProviderScriptRootSafely(
|
|
32650
|
+
registerProviderScriptRootSafely(path31.dirname(path31.dirname(providerDir)));
|
|
32149
32651
|
const cached = this.scriptsCache.get(dir);
|
|
32150
32652
|
if (cached) return cached;
|
|
32151
|
-
const scriptsJs =
|
|
32152
|
-
if (
|
|
32653
|
+
const scriptsJs = path31.join(dir, "scripts.js");
|
|
32654
|
+
if (fs19.existsSync(scriptsJs)) {
|
|
32153
32655
|
try {
|
|
32154
32656
|
delete __require.cache[__require.resolve(scriptsJs)];
|
|
32155
32657
|
const loaded = __require(scriptsJs);
|
|
@@ -32170,9 +32672,9 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32170
32672
|
watch() {
|
|
32171
32673
|
this.stopWatch();
|
|
32172
32674
|
const watchDir = (dir) => {
|
|
32173
|
-
if (!
|
|
32675
|
+
if (!fs19.existsSync(dir)) {
|
|
32174
32676
|
try {
|
|
32175
|
-
|
|
32677
|
+
fs19.mkdirSync(dir, { recursive: true });
|
|
32176
32678
|
} catch {
|
|
32177
32679
|
return;
|
|
32178
32680
|
}
|
|
@@ -32193,7 +32695,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32193
32695
|
if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
|
|
32194
32696
|
if (reloadTimer) clearTimeout(reloadTimer);
|
|
32195
32697
|
reloadTimer = setTimeout(() => {
|
|
32196
|
-
this.log(`File changed: ${
|
|
32698
|
+
this.log(`File changed: ${path31.basename(filePath)}, reloading...`);
|
|
32197
32699
|
this.reload();
|
|
32198
32700
|
}, 300);
|
|
32199
32701
|
}
|
|
@@ -32261,11 +32763,11 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32261
32763
|
}
|
|
32262
32764
|
this.log(`Registry sync starting (${_ProviderLoader.REGISTRY_BASE_URL})...`);
|
|
32263
32765
|
const https = __require("https");
|
|
32264
|
-
const regMetaPath =
|
|
32766
|
+
const regMetaPath = path31.join(this.upstreamDir, _ProviderLoader.REGISTRY_META_FILE);
|
|
32265
32767
|
let cachedChecksums = {};
|
|
32266
32768
|
try {
|
|
32267
|
-
if (
|
|
32268
|
-
cachedChecksums = JSON.parse(
|
|
32769
|
+
if (fs19.existsSync(regMetaPath)) {
|
|
32770
|
+
cachedChecksums = JSON.parse(fs19.readFileSync(regMetaPath, "utf-8")).checksums ?? {};
|
|
32269
32771
|
}
|
|
32270
32772
|
} catch {
|
|
32271
32773
|
}
|
|
@@ -32319,15 +32821,15 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32319
32821
|
this.log(`\u26A0 Registry checksum mismatch for ${type}@${version} \u2014 skipping`);
|
|
32320
32822
|
continue;
|
|
32321
32823
|
}
|
|
32322
|
-
const providerDir =
|
|
32323
|
-
|
|
32324
|
-
|
|
32824
|
+
const providerDir = path31.join(this.upstreamDir, category, type);
|
|
32825
|
+
fs19.mkdirSync(providerDir, { recursive: true });
|
|
32826
|
+
fs19.writeFileSync(path31.join(providerDir, "provider.json"), manifestBody, "utf-8");
|
|
32325
32827
|
cachedChecksums[cacheKey] = checksum;
|
|
32326
32828
|
updatedCount++;
|
|
32327
32829
|
this.log(`\u2713 Registry updated: ${category}/${type}@${version}`);
|
|
32328
32830
|
}
|
|
32329
|
-
|
|
32330
|
-
|
|
32831
|
+
fs19.mkdirSync(this.upstreamDir, { recursive: true });
|
|
32832
|
+
fs19.writeFileSync(regMetaPath, JSON.stringify({
|
|
32331
32833
|
checksums: cachedChecksums,
|
|
32332
32834
|
syncedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
32333
32835
|
providerCount: list.providers.length
|
|
@@ -32348,12 +32850,12 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32348
32850
|
const { exec: exec7 } = __require("child_process");
|
|
32349
32851
|
const { promisify: promisify7 } = __require("util");
|
|
32350
32852
|
const execAsync5 = promisify7(exec7);
|
|
32351
|
-
const metaPath =
|
|
32853
|
+
const metaPath = path31.join(this.upstreamDir, _ProviderLoader.META_FILE);
|
|
32352
32854
|
let prevEtag = "";
|
|
32353
32855
|
let prevTimestamp = 0;
|
|
32354
32856
|
try {
|
|
32355
|
-
if (
|
|
32356
|
-
const meta = JSON.parse(
|
|
32857
|
+
if (fs19.existsSync(metaPath)) {
|
|
32858
|
+
const meta = JSON.parse(fs19.readFileSync(metaPath, "utf-8"));
|
|
32357
32859
|
prevEtag = meta.etag || "";
|
|
32358
32860
|
prevTimestamp = meta.timestamp || 0;
|
|
32359
32861
|
}
|
|
@@ -32408,39 +32910,39 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32408
32910
|
return { updated: false };
|
|
32409
32911
|
}
|
|
32410
32912
|
this.log("Downloading latest providers from GitHub...");
|
|
32411
|
-
const tmpTar =
|
|
32412
|
-
const tmpExtract =
|
|
32913
|
+
const tmpTar = path31.join(os22.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
|
|
32914
|
+
const tmpExtract = path31.join(os22.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
|
|
32413
32915
|
await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
|
|
32414
|
-
|
|
32916
|
+
fs19.mkdirSync(tmpExtract, { recursive: true });
|
|
32415
32917
|
await execAsync5(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
|
|
32416
|
-
const extracted =
|
|
32918
|
+
const extracted = fs19.readdirSync(tmpExtract);
|
|
32417
32919
|
const rootDir = extracted.find(
|
|
32418
|
-
(d) =>
|
|
32920
|
+
(d) => fs19.statSync(path31.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
|
|
32419
32921
|
);
|
|
32420
32922
|
if (!rootDir) throw new Error("Unexpected tarball structure");
|
|
32421
|
-
const sourceDir =
|
|
32923
|
+
const sourceDir = path31.join(tmpExtract, rootDir);
|
|
32422
32924
|
const backupDir = this.upstreamDir + ".bak";
|
|
32423
|
-
if (
|
|
32424
|
-
if (
|
|
32425
|
-
|
|
32925
|
+
if (fs19.existsSync(this.upstreamDir)) {
|
|
32926
|
+
if (fs19.existsSync(backupDir)) fs19.rmSync(backupDir, { recursive: true, force: true });
|
|
32927
|
+
fs19.renameSync(this.upstreamDir, backupDir);
|
|
32426
32928
|
}
|
|
32427
32929
|
try {
|
|
32428
32930
|
this.copyDirRecursive(sourceDir, this.upstreamDir);
|
|
32429
32931
|
this.writeMeta(metaPath, etag || `ts-${Date.now()}`, Date.now());
|
|
32430
|
-
if (
|
|
32932
|
+
if (fs19.existsSync(backupDir)) fs19.rmSync(backupDir, { recursive: true, force: true });
|
|
32431
32933
|
} catch (e) {
|
|
32432
|
-
if (
|
|
32433
|
-
if (
|
|
32434
|
-
|
|
32934
|
+
if (fs19.existsSync(backupDir)) {
|
|
32935
|
+
if (fs19.existsSync(this.upstreamDir)) fs19.rmSync(this.upstreamDir, { recursive: true, force: true });
|
|
32936
|
+
fs19.renameSync(backupDir, this.upstreamDir);
|
|
32435
32937
|
}
|
|
32436
32938
|
throw e;
|
|
32437
32939
|
}
|
|
32438
32940
|
try {
|
|
32439
|
-
|
|
32941
|
+
fs19.rmSync(tmpTar, { force: true });
|
|
32440
32942
|
} catch {
|
|
32441
32943
|
}
|
|
32442
32944
|
try {
|
|
32443
|
-
|
|
32945
|
+
fs19.rmSync(tmpExtract, { recursive: true, force: true });
|
|
32444
32946
|
} catch {
|
|
32445
32947
|
}
|
|
32446
32948
|
const upstreamCount = this.countProviders(this.upstreamDir);
|
|
@@ -32472,7 +32974,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32472
32974
|
reject(new Error(`HTTP ${res.statusCode}`));
|
|
32473
32975
|
return;
|
|
32474
32976
|
}
|
|
32475
|
-
const ws =
|
|
32977
|
+
const ws = fs19.createWriteStream(destPath);
|
|
32476
32978
|
res.pipe(ws);
|
|
32477
32979
|
ws.on("finish", () => {
|
|
32478
32980
|
ws.close();
|
|
@@ -32491,22 +32993,22 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32491
32993
|
}
|
|
32492
32994
|
/** Recursive directory copy */
|
|
32493
32995
|
copyDirRecursive(src, dest) {
|
|
32494
|
-
|
|
32495
|
-
for (const entry of
|
|
32496
|
-
const srcPath =
|
|
32497
|
-
const destPath =
|
|
32996
|
+
fs19.mkdirSync(dest, { recursive: true });
|
|
32997
|
+
for (const entry of fs19.readdirSync(src, { withFileTypes: true })) {
|
|
32998
|
+
const srcPath = path31.join(src, entry.name);
|
|
32999
|
+
const destPath = path31.join(dest, entry.name);
|
|
32498
33000
|
if (entry.isDirectory()) {
|
|
32499
33001
|
this.copyDirRecursive(srcPath, destPath);
|
|
32500
33002
|
} else {
|
|
32501
|
-
|
|
33003
|
+
fs19.copyFileSync(srcPath, destPath);
|
|
32502
33004
|
}
|
|
32503
33005
|
}
|
|
32504
33006
|
}
|
|
32505
33007
|
/** .meta.json save */
|
|
32506
33008
|
writeMeta(metaPath, etag, timestamp) {
|
|
32507
33009
|
try {
|
|
32508
|
-
|
|
32509
|
-
|
|
33010
|
+
fs19.mkdirSync(path31.dirname(metaPath), { recursive: true });
|
|
33011
|
+
fs19.writeFileSync(metaPath, JSON.stringify({
|
|
32510
33012
|
etag,
|
|
32511
33013
|
timestamp,
|
|
32512
33014
|
lastCheck: new Date(timestamp).toISOString(),
|
|
@@ -32517,15 +33019,15 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32517
33019
|
}
|
|
32518
33020
|
/** Count provider files (provider.v1.json or provider.json — at most one per dir). */
|
|
32519
33021
|
countProviders(dir) {
|
|
32520
|
-
if (!
|
|
33022
|
+
if (!fs19.existsSync(dir)) return 0;
|
|
32521
33023
|
let count = 0;
|
|
32522
33024
|
const scan = (d) => {
|
|
32523
33025
|
try {
|
|
32524
|
-
const entries =
|
|
33026
|
+
const entries = fs19.readdirSync(d, { withFileTypes: true });
|
|
32525
33027
|
const hasManifest = entries.some((e) => e.name === "provider.v1.json" || e.name === "provider.json");
|
|
32526
33028
|
if (hasManifest) count++;
|
|
32527
33029
|
for (const entry of entries) {
|
|
32528
|
-
if (entry.isDirectory()) scan(
|
|
33030
|
+
if (entry.isDirectory()) scan(path31.join(d, entry.name));
|
|
32529
33031
|
}
|
|
32530
33032
|
} catch {
|
|
32531
33033
|
}
|
|
@@ -32751,13 +33253,13 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32751
33253
|
if (!provider) return null;
|
|
32752
33254
|
const cat = provider.category;
|
|
32753
33255
|
const searchRoots = this.getProviderRoots();
|
|
32754
|
-
const hasManifest = (dir) =>
|
|
33256
|
+
const hasManifest = (dir) => fs19.existsSync(path31.join(dir, "provider.v1.json")) || fs19.existsSync(path31.join(dir, "provider.json"));
|
|
32755
33257
|
const readManifestType = (dir) => {
|
|
32756
33258
|
for (const file of ["provider.v1.json", "provider.json"]) {
|
|
32757
|
-
const p =
|
|
32758
|
-
if (!
|
|
33259
|
+
const p = path31.join(dir, file);
|
|
33260
|
+
if (!fs19.existsSync(p)) continue;
|
|
32759
33261
|
try {
|
|
32760
|
-
const data = JSON.parse(
|
|
33262
|
+
const data = JSON.parse(fs19.readFileSync(p, "utf-8"));
|
|
32761
33263
|
if (typeof data?.type === "string") return data.type;
|
|
32762
33264
|
} catch {
|
|
32763
33265
|
}
|
|
@@ -32765,15 +33267,15 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32765
33267
|
return null;
|
|
32766
33268
|
};
|
|
32767
33269
|
for (const root of searchRoots) {
|
|
32768
|
-
if (!
|
|
33270
|
+
if (!fs19.existsSync(root)) continue;
|
|
32769
33271
|
const candidate = this.getProviderDir(root, cat, type);
|
|
32770
33272
|
if (hasManifest(candidate)) return candidate;
|
|
32771
|
-
const catDir =
|
|
32772
|
-
if (
|
|
33273
|
+
const catDir = path31.join(root, cat);
|
|
33274
|
+
if (fs19.existsSync(catDir)) {
|
|
32773
33275
|
try {
|
|
32774
|
-
for (const entry of
|
|
33276
|
+
for (const entry of fs19.readdirSync(catDir, { withFileTypes: true })) {
|
|
32775
33277
|
if (!entry.isDirectory()) continue;
|
|
32776
|
-
const entryDir =
|
|
33278
|
+
const entryDir = path31.join(catDir, entry.name);
|
|
32777
33279
|
const manifestType = readManifestType(entryDir);
|
|
32778
33280
|
if (manifestType === type) return entryDir;
|
|
32779
33281
|
}
|
|
@@ -32789,8 +33291,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32789
33291
|
* (template substitution is NOT applied here — scripts.js handles that)
|
|
32790
33292
|
*/
|
|
32791
33293
|
buildScriptWrappersFromDir(dir) {
|
|
32792
|
-
const scriptsJs =
|
|
32793
|
-
if (
|
|
33294
|
+
const scriptsJs = path31.join(dir, "scripts.js");
|
|
33295
|
+
if (fs19.existsSync(scriptsJs)) {
|
|
32794
33296
|
try {
|
|
32795
33297
|
delete __require.cache[__require.resolve(scriptsJs)];
|
|
32796
33298
|
return __require(scriptsJs);
|
|
@@ -32800,13 +33302,13 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32800
33302
|
const toCamel = (name) => name.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
|
|
32801
33303
|
const result = {};
|
|
32802
33304
|
try {
|
|
32803
|
-
for (const file of
|
|
33305
|
+
for (const file of fs19.readdirSync(dir)) {
|
|
32804
33306
|
if (!file.endsWith(".js")) continue;
|
|
32805
33307
|
const scriptName = toCamel(file.replace(".js", ""));
|
|
32806
|
-
const filePath =
|
|
33308
|
+
const filePath = path31.join(dir, file);
|
|
32807
33309
|
result[scriptName] = (...args) => {
|
|
32808
33310
|
try {
|
|
32809
|
-
let content =
|
|
33311
|
+
let content = fs19.readFileSync(filePath, "utf-8");
|
|
32810
33312
|
if (args[0] && typeof args[0] === "object") {
|
|
32811
33313
|
for (const [key, val] of Object.entries(args[0])) {
|
|
32812
33314
|
let v = val;
|
|
@@ -32852,12 +33354,12 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32852
33354
|
* Structure: dir/category/agent-name/provider.{json,js}
|
|
32853
33355
|
*/
|
|
32854
33356
|
loadDir(dir, excludeDirs) {
|
|
32855
|
-
if (!
|
|
33357
|
+
if (!fs19.existsSync(dir)) return 0;
|
|
32856
33358
|
let count = 0;
|
|
32857
33359
|
const scan = (d) => {
|
|
32858
33360
|
let entries;
|
|
32859
33361
|
try {
|
|
32860
|
-
entries =
|
|
33362
|
+
entries = fs19.readdirSync(d, { withFileTypes: true });
|
|
32861
33363
|
} catch {
|
|
32862
33364
|
return;
|
|
32863
33365
|
}
|
|
@@ -32865,9 +33367,9 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32865
33367
|
const hasJson = entries.some((e) => e.name === "provider.json");
|
|
32866
33368
|
if (hasV1 || hasJson) {
|
|
32867
33369
|
const manifestFile = hasV1 ? "provider.v1.json" : "provider.json";
|
|
32868
|
-
const jsonPath =
|
|
33370
|
+
const jsonPath = path31.join(d, manifestFile);
|
|
32869
33371
|
try {
|
|
32870
|
-
const raw =
|
|
33372
|
+
const raw = fs19.readFileSync(jsonPath, "utf-8");
|
|
32871
33373
|
const mod = JSON.parse(raw);
|
|
32872
33374
|
if (hasV1 && mod?.category === "cli") {
|
|
32873
33375
|
try {
|
|
@@ -32905,10 +33407,10 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
32905
33407
|
this.log(`\u26A0 Invalid provider at ${jsonPath}: ${validation.errors.join("; ")}`);
|
|
32906
33408
|
} else {
|
|
32907
33409
|
const hasCompatibility = Array.isArray(normalizedProvider.compatibility);
|
|
32908
|
-
const scriptsPath =
|
|
32909
|
-
if (!hasCompatibility &&
|
|
33410
|
+
const scriptsPath = path31.join(d, "scripts.js");
|
|
33411
|
+
if (!hasCompatibility && fs19.existsSync(scriptsPath)) {
|
|
32910
33412
|
try {
|
|
32911
|
-
registerProviderScriptRootSafely(
|
|
33413
|
+
registerProviderScriptRootSafely(path31.dirname(path31.dirname(d)));
|
|
32912
33414
|
delete __require.cache[__require.resolve(scriptsPath)];
|
|
32913
33415
|
const scripts = __require(scriptsPath);
|
|
32914
33416
|
normalizedProvider.scripts = scripts;
|
|
@@ -32916,12 +33418,30 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
32916
33418
|
this.log(`\u26A0 Failed to load scripts: ${scriptsPath}: ${e.message}`);
|
|
32917
33419
|
}
|
|
32918
33420
|
}
|
|
33421
|
+
const externalDirAbs = path31.join(os22.homedir(), ".adhdev", "external");
|
|
33422
|
+
const layer = d.startsWith(externalDirAbs) ? "external" : d.startsWith(this.userDir) && !d.includes(".upstream") ? "user" : "upstream";
|
|
33423
|
+
try {
|
|
33424
|
+
const { inspectManifestShape: inspectManifestShape2, classifyTrust: classifyTrust2 } = (init_provider_trust(), __toCommonJS(provider_trust_exports));
|
|
33425
|
+
const shape = inspectManifestShape2(mod);
|
|
33426
|
+
const trust = classifyTrust2(layer, shape);
|
|
33427
|
+
normalizedProvider._sourceLayer = layer;
|
|
33428
|
+
normalizedProvider._sourceTrust = trust;
|
|
33429
|
+
normalizedProvider._manifestShape = shape;
|
|
33430
|
+
if (layer === "external") {
|
|
33431
|
+
const rel = path31.relative(externalDirAbs, d);
|
|
33432
|
+
const firstSeg = rel.split(path31.sep)[0];
|
|
33433
|
+
if (firstSeg && firstSeg !== "..") normalizedProvider._sourceName = firstSeg;
|
|
33434
|
+
}
|
|
33435
|
+
} catch {
|
|
33436
|
+
}
|
|
32919
33437
|
const existed = this.providers.has(normalizedProvider.type);
|
|
32920
33438
|
this.providers.set(normalizedProvider.type, normalizedProvider);
|
|
32921
33439
|
count++;
|
|
32922
|
-
const source =
|
|
33440
|
+
const source = normalizedProvider._sourceLayer ?? "upstream";
|
|
32923
33441
|
const overrideWarning = existed && source === "user" ? " \u26A0 OVERRIDES upstream" : "";
|
|
32924
|
-
|
|
33442
|
+
const sourceName = normalizedProvider._sourceName;
|
|
33443
|
+
const sourceLabel = sourceName ? `${source}/${sourceName}` : source;
|
|
33444
|
+
this.log(` ${existed ? "\u{1F504}" : "\u2705"} ${normalizedProvider.type} (${normalizedProvider.category}) \u2014 ${normalizedProvider.name} [${sourceLabel}]${overrideWarning}`);
|
|
32925
33445
|
}
|
|
32926
33446
|
} catch (e) {
|
|
32927
33447
|
this.log(`\u26A0 Failed to load ${jsonPath}: ${e.message}`);
|
|
@@ -32931,8 +33451,9 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
32931
33451
|
for (const entry of entries) {
|
|
32932
33452
|
if (!entry.isDirectory()) continue;
|
|
32933
33453
|
if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
|
|
33454
|
+
if (d === dir && entry.name === "examples") continue;
|
|
32934
33455
|
if (excludeDirs && d === dir && excludeDirs.includes(entry.name)) continue;
|
|
32935
|
-
scan(
|
|
33456
|
+
scan(path31.join(d, entry.name));
|
|
32936
33457
|
}
|
|
32937
33458
|
}
|
|
32938
33459
|
};
|
|
@@ -33130,7 +33651,7 @@ async function isCdpActive(port) {
|
|
|
33130
33651
|
});
|
|
33131
33652
|
}
|
|
33132
33653
|
async function killIdeProcess(ideId) {
|
|
33133
|
-
const plat =
|
|
33654
|
+
const plat = os23.platform();
|
|
33134
33655
|
const appName = getMacAppIdentifiers()[ideId];
|
|
33135
33656
|
const winProcesses = getWinProcessNames()[ideId];
|
|
33136
33657
|
try {
|
|
@@ -33191,7 +33712,7 @@ async function killIdeProcess(ideId) {
|
|
|
33191
33712
|
}
|
|
33192
33713
|
}
|
|
33193
33714
|
async function isIdeRunning(ideId) {
|
|
33194
|
-
const plat =
|
|
33715
|
+
const plat = os23.platform();
|
|
33195
33716
|
try {
|
|
33196
33717
|
if (plat === "darwin") {
|
|
33197
33718
|
const appName = getMacAppIdentifiers()[ideId];
|
|
@@ -33246,7 +33767,7 @@ async function isIdeRunning(ideId) {
|
|
|
33246
33767
|
}
|
|
33247
33768
|
}
|
|
33248
33769
|
async function detectCurrentWorkspace(ideId) {
|
|
33249
|
-
const plat =
|
|
33770
|
+
const plat = os23.platform();
|
|
33250
33771
|
if (plat === "darwin") {
|
|
33251
33772
|
try {
|
|
33252
33773
|
const appName = getMacAppIdentifiers()[ideId];
|
|
@@ -33261,17 +33782,17 @@ async function detectCurrentWorkspace(ideId) {
|
|
|
33261
33782
|
}
|
|
33262
33783
|
} else if (plat === "win32") {
|
|
33263
33784
|
try {
|
|
33264
|
-
const
|
|
33785
|
+
const fs28 = __require("fs");
|
|
33265
33786
|
const appNameMap = getMacAppIdentifiers();
|
|
33266
33787
|
const appName = appNameMap[ideId];
|
|
33267
33788
|
if (appName) {
|
|
33268
|
-
const storagePath =
|
|
33269
|
-
process.env.APPDATA ||
|
|
33789
|
+
const storagePath = path32.join(
|
|
33790
|
+
process.env.APPDATA || path32.join(os23.homedir(), "AppData", "Roaming"),
|
|
33270
33791
|
appName,
|
|
33271
33792
|
"storage.json"
|
|
33272
33793
|
);
|
|
33273
|
-
if (
|
|
33274
|
-
const data = JSON.parse(
|
|
33794
|
+
if (fs28.existsSync(storagePath)) {
|
|
33795
|
+
const data = JSON.parse(fs28.readFileSync(storagePath, "utf-8"));
|
|
33275
33796
|
const workspaces = data?.openedPathsList?.workspaces3 || data?.openedPathsList?.entries || [];
|
|
33276
33797
|
if (workspaces.length > 0) {
|
|
33277
33798
|
const recent = workspaces[0];
|
|
@@ -33288,7 +33809,7 @@ async function detectCurrentWorkspace(ideId) {
|
|
|
33288
33809
|
return void 0;
|
|
33289
33810
|
}
|
|
33290
33811
|
async function launchWithCdp(options = {}) {
|
|
33291
|
-
const platform10 =
|
|
33812
|
+
const platform10 = os23.platform();
|
|
33292
33813
|
let targetIde;
|
|
33293
33814
|
const ides = await detectIDEs(getProviderLoader());
|
|
33294
33815
|
if (options.ideId) {
|
|
@@ -33455,14 +33976,14 @@ init_cli_detector();
|
|
|
33455
33976
|
init_logger();
|
|
33456
33977
|
|
|
33457
33978
|
// src/logging/command-log.ts
|
|
33458
|
-
import * as
|
|
33459
|
-
import * as
|
|
33460
|
-
import * as
|
|
33461
|
-
var LOG_DIR2 = process.platform === "win32" ?
|
|
33979
|
+
import * as fs20 from "fs";
|
|
33980
|
+
import * as path33 from "path";
|
|
33981
|
+
import * as os24 from "os";
|
|
33982
|
+
var LOG_DIR2 = process.platform === "win32" ? path33.join(process.env.LOCALAPPDATA || process.env.APPDATA || path33.join(os24.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path33.join(os24.homedir(), "Library", "Logs", "adhdev") : path33.join(os24.homedir(), ".local", "share", "adhdev", "logs");
|
|
33462
33983
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
33463
33984
|
var MAX_DAYS = 7;
|
|
33464
33985
|
try {
|
|
33465
|
-
|
|
33986
|
+
fs20.mkdirSync(LOG_DIR2, { recursive: true });
|
|
33466
33987
|
} catch {
|
|
33467
33988
|
}
|
|
33468
33989
|
var SENSITIVE_KEYS = /* @__PURE__ */ new Set([
|
|
@@ -33496,19 +34017,19 @@ function getDateStr2() {
|
|
|
33496
34017
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
33497
34018
|
}
|
|
33498
34019
|
var currentDate2 = getDateStr2();
|
|
33499
|
-
var currentFile =
|
|
34020
|
+
var currentFile = path33.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
33500
34021
|
var writeCount2 = 0;
|
|
33501
34022
|
function checkRotation() {
|
|
33502
34023
|
const today = getDateStr2();
|
|
33503
34024
|
if (today !== currentDate2) {
|
|
33504
34025
|
currentDate2 = today;
|
|
33505
|
-
currentFile =
|
|
34026
|
+
currentFile = path33.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
33506
34027
|
cleanOldFiles();
|
|
33507
34028
|
}
|
|
33508
34029
|
}
|
|
33509
34030
|
function cleanOldFiles() {
|
|
33510
34031
|
try {
|
|
33511
|
-
const files =
|
|
34032
|
+
const files = fs20.readdirSync(LOG_DIR2).filter((f) => f.startsWith("commands-") && f.endsWith(".jsonl"));
|
|
33512
34033
|
const cutoff = /* @__PURE__ */ new Date();
|
|
33513
34034
|
cutoff.setDate(cutoff.getDate() - MAX_DAYS);
|
|
33514
34035
|
const cutoffStr = cutoff.toISOString().slice(0, 10);
|
|
@@ -33516,7 +34037,7 @@ function cleanOldFiles() {
|
|
|
33516
34037
|
const dateMatch = file.match(/commands-(\d{4}-\d{2}-\d{2})/);
|
|
33517
34038
|
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
33518
34039
|
try {
|
|
33519
|
-
|
|
34040
|
+
fs20.unlinkSync(path33.join(LOG_DIR2, file));
|
|
33520
34041
|
} catch {
|
|
33521
34042
|
}
|
|
33522
34043
|
}
|
|
@@ -33526,14 +34047,14 @@ function cleanOldFiles() {
|
|
|
33526
34047
|
}
|
|
33527
34048
|
function checkSize() {
|
|
33528
34049
|
try {
|
|
33529
|
-
const stat2 =
|
|
34050
|
+
const stat2 = fs20.statSync(currentFile);
|
|
33530
34051
|
if (stat2.size > MAX_FILE_SIZE) {
|
|
33531
34052
|
const backup = currentFile.replace(".jsonl", ".1.jsonl");
|
|
33532
34053
|
try {
|
|
33533
|
-
|
|
34054
|
+
fs20.unlinkSync(backup);
|
|
33534
34055
|
} catch {
|
|
33535
34056
|
}
|
|
33536
|
-
|
|
34057
|
+
fs20.renameSync(currentFile, backup);
|
|
33537
34058
|
}
|
|
33538
34059
|
} catch {
|
|
33539
34060
|
}
|
|
@@ -33566,14 +34087,14 @@ function logCommand(entry) {
|
|
|
33566
34087
|
...entry.error ? { err: entry.error } : {},
|
|
33567
34088
|
...entry.durationMs !== void 0 ? { ms: entry.durationMs } : {}
|
|
33568
34089
|
});
|
|
33569
|
-
|
|
34090
|
+
fs20.appendFileSync(currentFile, line + "\n");
|
|
33570
34091
|
} catch {
|
|
33571
34092
|
}
|
|
33572
34093
|
}
|
|
33573
34094
|
function getRecentCommands(count = 50) {
|
|
33574
34095
|
try {
|
|
33575
|
-
if (!
|
|
33576
|
-
const content =
|
|
34096
|
+
if (!fs20.existsSync(currentFile)) return [];
|
|
34097
|
+
const content = fs20.readFileSync(currentFile, "utf-8");
|
|
33577
34098
|
const lines = content.trim().split("\n").filter(Boolean);
|
|
33578
34099
|
return lines.slice(-count).map((line) => {
|
|
33579
34100
|
try {
|
|
@@ -33607,7 +34128,7 @@ init_mesh_host_ownership();
|
|
|
33607
34128
|
|
|
33608
34129
|
// src/mesh/preview-freshness.ts
|
|
33609
34130
|
import { execFileSync as execFileSync3 } from "child_process";
|
|
33610
|
-
import { existsSync as
|
|
34131
|
+
import { existsSync as existsSync30, readFileSync as readFileSync23 } from "fs";
|
|
33611
34132
|
import { resolve as resolve18 } from "path";
|
|
33612
34133
|
var PREVIEW_DEPLOY_RECORD = ".adhdev/preview-deploy.json";
|
|
33613
34134
|
function runGit2(repoRoot, args) {
|
|
@@ -33623,10 +34144,10 @@ function runGit2(repoRoot, args) {
|
|
|
33623
34144
|
}
|
|
33624
34145
|
}
|
|
33625
34146
|
function readRecord3(repoRoot) {
|
|
33626
|
-
const
|
|
33627
|
-
if (!
|
|
34147
|
+
const path40 = resolve18(repoRoot, PREVIEW_DEPLOY_RECORD);
|
|
34148
|
+
if (!existsSync30(path40)) return null;
|
|
33628
34149
|
try {
|
|
33629
|
-
const parsed = JSON.parse(
|
|
34150
|
+
const parsed = JSON.parse(readFileSync23(path40, "utf8"));
|
|
33630
34151
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
33631
34152
|
} catch {
|
|
33632
34153
|
return null;
|
|
@@ -33689,7 +34210,7 @@ function buildPreviewFreshness(repoRoot) {
|
|
|
33689
34210
|
|
|
33690
34211
|
// src/status/snapshot.ts
|
|
33691
34212
|
init_config();
|
|
33692
|
-
import * as
|
|
34213
|
+
import * as os25 from "os";
|
|
33693
34214
|
init_terminal_screen();
|
|
33694
34215
|
init_logger();
|
|
33695
34216
|
var READ_DEBUG_ENABLED = process.argv.includes("--dev") || process.env.ADHDEV_READ_DEBUG === "1";
|
|
@@ -33727,25 +34248,50 @@ function buildDetectedIdeInfos(detectedIdes, cdpManagers) {
|
|
|
33727
34248
|
}
|
|
33728
34249
|
function buildAvailableProviders(providerLoader) {
|
|
33729
34250
|
const providers = providerLoader.getAvailableProviderInfos?.() || providerLoader.getAll();
|
|
33730
|
-
|
|
33731
|
-
|
|
33732
|
-
|
|
33733
|
-
|
|
33734
|
-
|
|
33735
|
-
|
|
33736
|
-
|
|
33737
|
-
|
|
33738
|
-
|
|
33739
|
-
|
|
33740
|
-
|
|
33741
|
-
|
|
33742
|
-
|
|
33743
|
-
|
|
34251
|
+
let describeTrust2 = () => "";
|
|
34252
|
+
let requiresConfirmation2 = () => false;
|
|
34253
|
+
try {
|
|
34254
|
+
const mod = (init_provider_trust(), __toCommonJS(provider_trust_exports));
|
|
34255
|
+
describeTrust2 = mod.describeTrust;
|
|
34256
|
+
requiresConfirmation2 = mod.requiresConfirmation;
|
|
34257
|
+
} catch {
|
|
34258
|
+
}
|
|
34259
|
+
return providers.map((provider) => {
|
|
34260
|
+
const trust = provider._sourceTrust;
|
|
34261
|
+
const sourceLayer = provider._sourceLayer;
|
|
34262
|
+
const sourceName = provider._sourceName;
|
|
34263
|
+
return {
|
|
34264
|
+
type: provider.type,
|
|
34265
|
+
name: provider.displayName || provider.type,
|
|
34266
|
+
displayName: provider.displayName || provider.type,
|
|
34267
|
+
icon: provider.icon || "\u{1F4BB}",
|
|
34268
|
+
category: provider.category,
|
|
34269
|
+
...provider.installed !== void 0 ? { installed: provider.installed } : {},
|
|
34270
|
+
...provider.detectedPath !== void 0 ? { detectedPath: provider.detectedPath } : {},
|
|
34271
|
+
...provider.enabled !== void 0 ? { enabled: provider.enabled } : {},
|
|
34272
|
+
...provider.machineStatus !== void 0 ? { machineStatus: provider.machineStatus } : {},
|
|
34273
|
+
...provider.lastDetection !== void 0 ? { lastDetection: provider.lastDetection } : {},
|
|
34274
|
+
...provider.lastVerification !== void 0 ? { lastVerification: provider.lastVerification } : {},
|
|
34275
|
+
...provider.meshCoordinator !== void 0 ? { meshCoordinator: provider.meshCoordinator } : {},
|
|
34276
|
+
...trust ? {
|
|
34277
|
+
trust,
|
|
34278
|
+
trustDescription: describeTrust2(trust),
|
|
34279
|
+
requiresConfirmation: requiresConfirmation2(trust)
|
|
34280
|
+
} : {},
|
|
34281
|
+
...sourceLayer ? { sourceLayer } : {},
|
|
34282
|
+
...sourceName ? { sourceName } : {},
|
|
34283
|
+
...provider.providerVersion ? { providerVersion: provider.providerVersion } : {},
|
|
34284
|
+
...provider.binary ? { binary: provider.binary } : {},
|
|
34285
|
+
...provider.status ? { status: provider.status } : {},
|
|
34286
|
+
...provider.details ? { details: provider.details } : {},
|
|
34287
|
+
...provider.links ? { links: provider.links } : {}
|
|
34288
|
+
};
|
|
34289
|
+
});
|
|
33744
34290
|
}
|
|
33745
34291
|
function buildMachineInfo(profile = "full") {
|
|
33746
34292
|
const base = {
|
|
33747
|
-
hostname:
|
|
33748
|
-
platform:
|
|
34293
|
+
hostname: os25.hostname(),
|
|
34294
|
+
platform: os25.platform()
|
|
33749
34295
|
};
|
|
33750
34296
|
if (profile === "live") {
|
|
33751
34297
|
return base;
|
|
@@ -33754,23 +34300,23 @@ function buildMachineInfo(profile = "full") {
|
|
|
33754
34300
|
const memSnap2 = getHostMemorySnapshot();
|
|
33755
34301
|
return {
|
|
33756
34302
|
...base,
|
|
33757
|
-
arch:
|
|
33758
|
-
cpus:
|
|
34303
|
+
arch: os25.arch(),
|
|
34304
|
+
cpus: os25.cpus().length,
|
|
33759
34305
|
totalMem: memSnap2.totalMem,
|
|
33760
|
-
release:
|
|
34306
|
+
release: os25.release()
|
|
33761
34307
|
};
|
|
33762
34308
|
}
|
|
33763
34309
|
const memSnap = getHostMemorySnapshot();
|
|
33764
34310
|
return {
|
|
33765
34311
|
...base,
|
|
33766
|
-
arch:
|
|
33767
|
-
cpus:
|
|
34312
|
+
arch: os25.arch(),
|
|
34313
|
+
cpus: os25.cpus().length,
|
|
33768
34314
|
totalMem: memSnap.totalMem,
|
|
33769
34315
|
freeMem: memSnap.freeMem,
|
|
33770
34316
|
availableMem: memSnap.availableMem,
|
|
33771
|
-
loadavg:
|
|
33772
|
-
uptime:
|
|
33773
|
-
release:
|
|
34317
|
+
loadavg: os25.loadavg(),
|
|
34318
|
+
uptime: os25.uptime(),
|
|
34319
|
+
release: os25.release()
|
|
33774
34320
|
};
|
|
33775
34321
|
}
|
|
33776
34322
|
function parseMessageTime(value) {
|
|
@@ -34011,42 +34557,42 @@ function buildStatusSnapshot(options) {
|
|
|
34011
34557
|
// src/commands/upgrade-helper.ts
|
|
34012
34558
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
34013
34559
|
import { spawn as spawn3 } from "child_process";
|
|
34014
|
-
import * as
|
|
34015
|
-
import * as
|
|
34016
|
-
import * as
|
|
34560
|
+
import * as fs21 from "fs";
|
|
34561
|
+
import * as os26 from "os";
|
|
34562
|
+
import * as path34 from "path";
|
|
34017
34563
|
var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
|
|
34018
34564
|
function getUpgradeLogPath() {
|
|
34019
|
-
const home =
|
|
34020
|
-
const dir =
|
|
34021
|
-
|
|
34022
|
-
return
|
|
34565
|
+
const home = os26.homedir();
|
|
34566
|
+
const dir = path34.join(home, ".adhdev");
|
|
34567
|
+
fs21.mkdirSync(dir, { recursive: true });
|
|
34568
|
+
return path34.join(dir, "daemon-upgrade.log");
|
|
34023
34569
|
}
|
|
34024
34570
|
function appendUpgradeLog(message) {
|
|
34025
34571
|
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
|
|
34026
34572
|
`;
|
|
34027
34573
|
try {
|
|
34028
|
-
|
|
34574
|
+
fs21.appendFileSync(getUpgradeLogPath(), line, "utf8");
|
|
34029
34575
|
} catch {
|
|
34030
34576
|
}
|
|
34031
34577
|
}
|
|
34032
34578
|
function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platform) {
|
|
34033
|
-
const binDir =
|
|
34579
|
+
const binDir = path34.dirname(nodeExecutable);
|
|
34034
34580
|
if (platform10 === "win32") {
|
|
34035
|
-
const npmCliPath =
|
|
34036
|
-
if (
|
|
34581
|
+
const npmCliPath = path34.join(binDir, "node_modules", "npm", "bin", "npm-cli.js");
|
|
34582
|
+
if (fs21.existsSync(npmCliPath)) {
|
|
34037
34583
|
return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
|
|
34038
34584
|
}
|
|
34039
34585
|
for (const candidate of ["npm.exe", "npm"]) {
|
|
34040
|
-
const candidatePath =
|
|
34041
|
-
if (
|
|
34586
|
+
const candidatePath = path34.join(binDir, candidate);
|
|
34587
|
+
if (fs21.existsSync(candidatePath)) {
|
|
34042
34588
|
return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
|
|
34043
34589
|
}
|
|
34044
34590
|
}
|
|
34045
34591
|
return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
|
|
34046
34592
|
}
|
|
34047
34593
|
for (const candidate of ["npm"]) {
|
|
34048
|
-
const candidatePath =
|
|
34049
|
-
if (
|
|
34594
|
+
const candidatePath = path34.join(binDir, candidate);
|
|
34595
|
+
if (fs21.existsSync(candidatePath)) {
|
|
34050
34596
|
return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
|
|
34051
34597
|
}
|
|
34052
34598
|
}
|
|
@@ -34056,22 +34602,22 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
34056
34602
|
if (!currentCliPath) return null;
|
|
34057
34603
|
let resolvedPath = currentCliPath;
|
|
34058
34604
|
try {
|
|
34059
|
-
resolvedPath =
|
|
34605
|
+
resolvedPath = fs21.realpathSync.native(currentCliPath);
|
|
34060
34606
|
} catch {
|
|
34061
34607
|
}
|
|
34062
34608
|
let currentDir = resolvedPath;
|
|
34063
34609
|
try {
|
|
34064
|
-
if (
|
|
34065
|
-
currentDir =
|
|
34610
|
+
if (fs21.statSync(resolvedPath).isFile()) {
|
|
34611
|
+
currentDir = path34.dirname(resolvedPath);
|
|
34066
34612
|
}
|
|
34067
34613
|
} catch {
|
|
34068
|
-
currentDir =
|
|
34614
|
+
currentDir = path34.dirname(resolvedPath);
|
|
34069
34615
|
}
|
|
34070
34616
|
while (true) {
|
|
34071
|
-
const packageJsonPath =
|
|
34617
|
+
const packageJsonPath = path34.join(currentDir, "package.json");
|
|
34072
34618
|
try {
|
|
34073
|
-
if (
|
|
34074
|
-
const parsed = JSON.parse(
|
|
34619
|
+
if (fs21.existsSync(packageJsonPath)) {
|
|
34620
|
+
const parsed = JSON.parse(fs21.readFileSync(packageJsonPath, "utf8"));
|
|
34075
34621
|
if (parsed?.name === packageName) {
|
|
34076
34622
|
const normalized = currentDir.replace(/\\/g, "/");
|
|
34077
34623
|
return normalized.includes("/node_modules/") ? currentDir : null;
|
|
@@ -34079,7 +34625,7 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
34079
34625
|
}
|
|
34080
34626
|
} catch {
|
|
34081
34627
|
}
|
|
34082
|
-
const parentDir =
|
|
34628
|
+
const parentDir = path34.dirname(currentDir);
|
|
34083
34629
|
if (parentDir === currentDir) {
|
|
34084
34630
|
return null;
|
|
34085
34631
|
}
|
|
@@ -34087,13 +34633,13 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
34087
34633
|
}
|
|
34088
34634
|
}
|
|
34089
34635
|
function resolveInstallPrefixFromPackageRoot(packageRoot, packageName) {
|
|
34090
|
-
const nodeModulesDir = packageName.startsWith("@") ?
|
|
34091
|
-
if (
|
|
34636
|
+
const nodeModulesDir = packageName.startsWith("@") ? path34.dirname(path34.dirname(packageRoot)) : path34.dirname(packageRoot);
|
|
34637
|
+
if (path34.basename(nodeModulesDir) !== "node_modules") {
|
|
34092
34638
|
return null;
|
|
34093
34639
|
}
|
|
34094
|
-
const maybeLibDir =
|
|
34095
|
-
if (
|
|
34096
|
-
return
|
|
34640
|
+
const maybeLibDir = path34.dirname(nodeModulesDir);
|
|
34641
|
+
if (path34.basename(maybeLibDir) === "lib") {
|
|
34642
|
+
return path34.dirname(maybeLibDir);
|
|
34097
34643
|
}
|
|
34098
34644
|
return maybeLibDir;
|
|
34099
34645
|
}
|
|
@@ -34208,10 +34754,10 @@ async function waitForPidExit(pid, timeoutMs) {
|
|
|
34208
34754
|
}
|
|
34209
34755
|
}
|
|
34210
34756
|
function stopSessionHostProcesses(appName) {
|
|
34211
|
-
const pidFile =
|
|
34757
|
+
const pidFile = path34.join(os26.homedir(), ".adhdev", `${appName}-session-host.pid`);
|
|
34212
34758
|
try {
|
|
34213
|
-
if (
|
|
34214
|
-
const pid = Number.parseInt(
|
|
34759
|
+
if (fs21.existsSync(pidFile)) {
|
|
34760
|
+
const pid = Number.parseInt(fs21.readFileSync(pidFile, "utf8").trim(), 10);
|
|
34215
34761
|
if (Number.isFinite(pid) && pid !== process.pid && isManagedSessionHostPid(pid)) {
|
|
34216
34762
|
killPid(pid);
|
|
34217
34763
|
}
|
|
@@ -34219,15 +34765,15 @@ function stopSessionHostProcesses(appName) {
|
|
|
34219
34765
|
} catch {
|
|
34220
34766
|
} finally {
|
|
34221
34767
|
try {
|
|
34222
|
-
|
|
34768
|
+
fs21.unlinkSync(pidFile);
|
|
34223
34769
|
} catch {
|
|
34224
34770
|
}
|
|
34225
34771
|
}
|
|
34226
34772
|
}
|
|
34227
34773
|
function removeDaemonPidFile() {
|
|
34228
|
-
const pidFile =
|
|
34774
|
+
const pidFile = path34.join(os26.homedir(), ".adhdev", "daemon.pid");
|
|
34229
34775
|
try {
|
|
34230
|
-
|
|
34776
|
+
fs21.unlinkSync(pidFile);
|
|
34231
34777
|
} catch {
|
|
34232
34778
|
}
|
|
34233
34779
|
}
|
|
@@ -34236,7 +34782,7 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
|
|
|
34236
34782
|
const npmRoot = String(execNpmCommandSync(["root", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
|
|
34237
34783
|
if (!npmRoot) return;
|
|
34238
34784
|
const npmPrefix = surface.installPrefix || String(execNpmCommandSync(["prefix", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
|
|
34239
|
-
const binDir = process.platform === "win32" ? npmPrefix :
|
|
34785
|
+
const binDir = process.platform === "win32" ? npmPrefix : path34.join(npmPrefix, "bin");
|
|
34240
34786
|
const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
|
|
34241
34787
|
const binNames = /* @__PURE__ */ new Set([packageBaseName]);
|
|
34242
34788
|
if (pkgName === "@adhdev/daemon-standalone") {
|
|
@@ -34244,25 +34790,25 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
|
|
|
34244
34790
|
}
|
|
34245
34791
|
if (pkgName.startsWith("@")) {
|
|
34246
34792
|
const [scope, name] = pkgName.split("/");
|
|
34247
|
-
const scopeDir =
|
|
34248
|
-
if (!
|
|
34249
|
-
for (const entry of
|
|
34793
|
+
const scopeDir = path34.join(npmRoot, scope);
|
|
34794
|
+
if (!fs21.existsSync(scopeDir)) return;
|
|
34795
|
+
for (const entry of fs21.readdirSync(scopeDir)) {
|
|
34250
34796
|
if (!entry.startsWith(`.${name}-`)) continue;
|
|
34251
|
-
|
|
34252
|
-
appendUpgradeLog(`Removed stale scoped staging dir: ${
|
|
34797
|
+
fs21.rmSync(path34.join(scopeDir, entry), { recursive: true, force: true });
|
|
34798
|
+
appendUpgradeLog(`Removed stale scoped staging dir: ${path34.join(scopeDir, entry)}`);
|
|
34253
34799
|
}
|
|
34254
34800
|
} else {
|
|
34255
|
-
for (const entry of
|
|
34801
|
+
for (const entry of fs21.readdirSync(npmRoot)) {
|
|
34256
34802
|
if (!entry.startsWith(`.${pkgName}-`)) continue;
|
|
34257
|
-
|
|
34258
|
-
appendUpgradeLog(`Removed stale staging dir: ${
|
|
34803
|
+
fs21.rmSync(path34.join(npmRoot, entry), { recursive: true, force: true });
|
|
34804
|
+
appendUpgradeLog(`Removed stale staging dir: ${path34.join(npmRoot, entry)}`);
|
|
34259
34805
|
}
|
|
34260
34806
|
}
|
|
34261
|
-
if (
|
|
34262
|
-
for (const entry of
|
|
34807
|
+
if (fs21.existsSync(binDir)) {
|
|
34808
|
+
for (const entry of fs21.readdirSync(binDir)) {
|
|
34263
34809
|
if (!Array.from(binNames).some((name) => entry.startsWith(`.${name}-`))) continue;
|
|
34264
|
-
|
|
34265
|
-
appendUpgradeLog(`Removed stale bin staging entry: ${
|
|
34810
|
+
fs21.rmSync(path34.join(binDir, entry), { recursive: true, force: true });
|
|
34811
|
+
appendUpgradeLog(`Removed stale bin staging entry: ${path34.join(binDir, entry)}`);
|
|
34266
34812
|
}
|
|
34267
34813
|
}
|
|
34268
34814
|
}
|
|
@@ -34348,9 +34894,9 @@ async function maybeRunDaemonUpgradeHelperFromEnv() {
|
|
|
34348
34894
|
|
|
34349
34895
|
// src/commands/router.ts
|
|
34350
34896
|
init_mesh_work_queue();
|
|
34351
|
-
import { homedir as
|
|
34897
|
+
import { homedir as homedir25, hostname as osHostname } from "os";
|
|
34352
34898
|
import { basename as pathBasename, join as pathJoin, resolve as pathResolve2 } from "path";
|
|
34353
|
-
import * as
|
|
34899
|
+
import * as fs22 from "fs";
|
|
34354
34900
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
34355
34901
|
var CHANNEL_NPM_TAG = { stable: "latest", preview: "next" };
|
|
34356
34902
|
var CHANNEL_SERVER_URL = {
|
|
@@ -34477,12 +35023,12 @@ function readGitSubmodules(value, parentRepoRoot) {
|
|
|
34477
35023
|
if (!Array.isArray(value)) return void 0;
|
|
34478
35024
|
const submodules = value.map((entry) => {
|
|
34479
35025
|
const submodule = readObjectRecord(entry);
|
|
34480
|
-
const
|
|
35026
|
+
const path40 = readStringValue(submodule.path);
|
|
34481
35027
|
const commit = readStringValue(submodule.commit);
|
|
34482
|
-
const repoPath = readStringValue(submodule.repoPath, submodule.repo_root) ?? joinRepoPath(parentRepoRoot,
|
|
34483
|
-
if (!
|
|
35028
|
+
const repoPath = readStringValue(submodule.repoPath, submodule.repo_root) ?? joinRepoPath(parentRepoRoot, path40);
|
|
35029
|
+
if (!path40 || !commit || !repoPath) return null;
|
|
34484
35030
|
return {
|
|
34485
|
-
path:
|
|
35031
|
+
path: path40,
|
|
34486
35032
|
commit,
|
|
34487
35033
|
repoPath,
|
|
34488
35034
|
dirty: readBooleanValue(submodule.dirty) ?? false,
|
|
@@ -35124,7 +35670,7 @@ async function hydrateInlineMeshDirectTruth(args) {
|
|
|
35124
35670
|
if (!isSelfNode && daemonId) unavailableNodeIds.push(nodeId);
|
|
35125
35671
|
continue;
|
|
35126
35672
|
}
|
|
35127
|
-
if (
|
|
35673
|
+
if (fs22.existsSync(workspace)) {
|
|
35128
35674
|
try {
|
|
35129
35675
|
const localGit = await getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
|
|
35130
35676
|
if (localGit?.isGitRepo) {
|
|
@@ -35209,7 +35755,7 @@ function readLiveMeshNodeWorkspace(args) {
|
|
|
35209
35755
|
}
|
|
35210
35756
|
function collectLiveMeshSessionRecords(args) {
|
|
35211
35757
|
const nodeWorkspace = readStringValue(args.node?.workspace);
|
|
35212
|
-
const nodeIsMissingLocalWorktree = args.node?.isLocalWorktree === true && !!nodeWorkspace && !
|
|
35758
|
+
const nodeIsMissingLocalWorktree = args.node?.isLocalWorktree === true && !!nodeWorkspace && !fs22.existsSync(nodeWorkspace);
|
|
35213
35759
|
const matches = args.liveSessionRecords.filter((record) => {
|
|
35214
35760
|
const recordNodeId = readStringValue(record?.meta?.meshNodeId);
|
|
35215
35761
|
if (recordNodeId && recordNodeId !== args.nodeId) return false;
|
|
@@ -35236,7 +35782,7 @@ function buildHistoricalMeshSessions(args) {
|
|
|
35236
35782
|
const workspace = readStringValue(node?.workspace);
|
|
35237
35783
|
if (nodeId) liveNodeIds.add(nodeId);
|
|
35238
35784
|
if (workspace) liveWorkspaces.add(workspace);
|
|
35239
|
-
if (nodeId && node?.isLocalWorktree === true && workspace && !
|
|
35785
|
+
if (nodeId && node?.isLocalWorktree === true && workspace && !fs22.existsSync(workspace)) {
|
|
35240
35786
|
missingLocalWorktreeNodeIds.add(nodeId);
|
|
35241
35787
|
}
|
|
35242
35788
|
}
|
|
@@ -35435,10 +35981,10 @@ ${e?.stderr || ""}`
|
|
|
35435
35981
|
}
|
|
35436
35982
|
function buildPatchEquivalenceSubmoduleConflictHint(repoRoot, baseHead, branchHead, output) {
|
|
35437
35983
|
if (!/(submodule|160000)/i.test(output) || !/(conflict|failed to merge)/i.test(output)) return void 0;
|
|
35438
|
-
const conflicts = readChangedGitlinkPaths(repoRoot, baseHead, branchHead).map((
|
|
35439
|
-
path:
|
|
35440
|
-
baseCommit: readTreeObject(repoRoot, baseHead,
|
|
35441
|
-
branchCommit: readTreeObject(repoRoot, branchHead,
|
|
35984
|
+
const conflicts = readChangedGitlinkPaths(repoRoot, baseHead, branchHead).map((path40) => ({
|
|
35985
|
+
path: path40,
|
|
35986
|
+
baseCommit: readTreeObject(repoRoot, baseHead, path40),
|
|
35987
|
+
branchCommit: readTreeObject(repoRoot, branchHead, path40)
|
|
35442
35988
|
}));
|
|
35443
35989
|
if (conflicts.length === 0) return void 0;
|
|
35444
35990
|
return {
|
|
@@ -35464,11 +36010,11 @@ function readChangedGitlinkPaths(repoRoot, fromRef, toRef) {
|
|
|
35464
36010
|
if (!line.trim()) continue;
|
|
35465
36011
|
const metaAndPath = line.split(" ");
|
|
35466
36012
|
const meta = metaAndPath[0] || "";
|
|
35467
|
-
const
|
|
35468
|
-
if (!
|
|
36013
|
+
const path40 = metaAndPath[metaAndPath.length - 1]?.trim();
|
|
36014
|
+
if (!path40) continue;
|
|
35469
36015
|
const parts = meta.split(/\s+/);
|
|
35470
36016
|
if (parts[0]?.includes("160000") || parts[1]?.includes("160000")) {
|
|
35471
|
-
paths.add(
|
|
36017
|
+
paths.add(path40);
|
|
35472
36018
|
}
|
|
35473
36019
|
}
|
|
35474
36020
|
return [...paths].sort();
|
|
@@ -35476,9 +36022,9 @@ function readChangedGitlinkPaths(repoRoot, fromRef, toRef) {
|
|
|
35476
36022
|
return [];
|
|
35477
36023
|
}
|
|
35478
36024
|
}
|
|
35479
|
-
function readTreeObject(repoRoot, ref,
|
|
36025
|
+
function readTreeObject(repoRoot, ref, path40) {
|
|
35480
36026
|
try {
|
|
35481
|
-
const output = execFileSync5("git", ["ls-tree", ref, "--",
|
|
36027
|
+
const output = execFileSync5("git", ["ls-tree", ref, "--", path40], {
|
|
35482
36028
|
cwd: repoRoot,
|
|
35483
36029
|
encoding: "utf8",
|
|
35484
36030
|
maxBuffer: 1024 * 1024
|
|
@@ -35491,7 +36037,7 @@ function readTreeObject(repoRoot, ref, path39) {
|
|
|
35491
36037
|
}
|
|
35492
36038
|
async function alignRefinerySubmodulesAfterMerge(repoRoot, previousBaseHead, currentHead, options = {}) {
|
|
35493
36039
|
const startedAt = Date.now();
|
|
35494
|
-
const changedGitlinkPaths = readChangedGitlinkPaths(repoRoot, previousBaseHead, currentHead).filter((
|
|
36040
|
+
const changedGitlinkPaths = readChangedGitlinkPaths(repoRoot, previousBaseHead, currentHead).filter((path40) => !(options.submoduleIgnorePaths || []).includes(path40));
|
|
35495
36041
|
const preStatus = await getGitRepoStatus(repoRoot, {
|
|
35496
36042
|
includeSubmodules: true,
|
|
35497
36043
|
submoduleIgnorePaths: options.submoduleIgnorePaths,
|
|
@@ -35532,7 +36078,7 @@ async function alignRefinerySubmodulesAfterMerge(repoRoot, previousBaseHead, cur
|
|
|
35532
36078
|
changedGitlinkPaths,
|
|
35533
36079
|
outOfSyncPaths,
|
|
35534
36080
|
updatedPaths: updatePaths,
|
|
35535
|
-
verifiedPaths: updatePaths.filter((
|
|
36081
|
+
verifiedPaths: updatePaths.filter((path40) => !remaining.some((submodule) => submodule.path === path40)),
|
|
35536
36082
|
durationMs: Date.now() - startedAt,
|
|
35537
36083
|
command: `git ${commandArgs.join(" ")}`,
|
|
35538
36084
|
stdout: truncateValidationOutput(result.stdout),
|
|
@@ -35587,7 +36133,7 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
35587
36133
|
return { stdout: String(stdout || ""), stderr: String(stderr || ""), refspec };
|
|
35588
36134
|
};
|
|
35589
36135
|
const importCommitFromWorktreeSubmodule = async (submodulePath, worktreeSubmodulePath, commit) => {
|
|
35590
|
-
if (!
|
|
36136
|
+
if (!fs22.existsSync(worktreeSubmodulePath)) return false;
|
|
35591
36137
|
try {
|
|
35592
36138
|
await runGit3(worktreeSubmodulePath, ["cat-file", "-e", `${commit}^{commit}`]);
|
|
35593
36139
|
} catch {
|
|
@@ -35610,7 +36156,7 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
35610
36156
|
reachable: false
|
|
35611
36157
|
};
|
|
35612
36158
|
try {
|
|
35613
|
-
if (!
|
|
36159
|
+
if (!fs22.existsSync(submodulePath)) {
|
|
35614
36160
|
entry.error = `Submodule checkout missing at ${gitlink.path}`;
|
|
35615
36161
|
entry.publishRequired = true;
|
|
35616
36162
|
if (options.allowAutoPublishSubmoduleMainCommits === true) {
|
|
@@ -35802,9 +36348,9 @@ async function runMeshRefineValidationGate(mesh, workspace) {
|
|
|
35802
36348
|
return ["npm", "pnpm", "yarn", "bun"].includes(command) && candidate.args.some((arg) => arg === "run" || arg === "test" || arg === "exec");
|
|
35803
36349
|
};
|
|
35804
36350
|
const dependenciesLikelyMissing = (cwd) => {
|
|
35805
|
-
if (!
|
|
35806
|
-
if (
|
|
35807
|
-
return ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"].some((lock) =>
|
|
36351
|
+
if (!fs22.existsSync(pathJoin(cwd, "package.json"))) return false;
|
|
36352
|
+
if (fs22.existsSync(pathJoin(cwd, "node_modules"))) return false;
|
|
36353
|
+
return ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"].some((lock) => fs22.existsSync(pathJoin(cwd, lock)));
|
|
35808
36354
|
};
|
|
35809
36355
|
for (const candidate of selection.bootstrapCommands) {
|
|
35810
36356
|
const startedAt = Date.now();
|
|
@@ -35896,14 +36442,14 @@ function serializeMeshCoordinatorMcpConfig(config, format) {
|
|
|
35896
36442
|
}
|
|
35897
36443
|
function resolveHermesUserHome() {
|
|
35898
36444
|
const explicitHome = process.env.HERMES_HOME?.trim();
|
|
35899
|
-
return explicitHome || pathJoin(
|
|
36445
|
+
return explicitHome || pathJoin(homedir25(), ".hermes");
|
|
35900
36446
|
}
|
|
35901
36447
|
function loadHermesCoordinatorBaseConfig(targetConfigPath) {
|
|
35902
36448
|
const sourceHome = resolveHermesUserHome();
|
|
35903
36449
|
const sourceConfigPath = pathJoin(sourceHome, "config.yaml");
|
|
35904
|
-
if (!
|
|
36450
|
+
if (!fs22.existsSync(sourceConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
35905
36451
|
if (pathResolve2(sourceConfigPath) === pathResolve2(targetConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
35906
|
-
const parsed = parseMeshCoordinatorMcpConfig(
|
|
36452
|
+
const parsed = parseMeshCoordinatorMcpConfig(fs22.readFileSync(sourceConfigPath, "utf-8"), "hermes_config_yaml");
|
|
35907
36453
|
const { mcp_servers: _mcpServers, ...baseConfig } = parsed;
|
|
35908
36454
|
return { config: baseConfig, sourceHome, sourceConfigPath };
|
|
35909
36455
|
}
|
|
@@ -35940,9 +36486,9 @@ function copyHermesCoordinatorCredentialFiles(sourceHome, targetHome) {
|
|
|
35940
36486
|
for (const fileName of [".env", "auth.json"]) {
|
|
35941
36487
|
const sourcePath = pathJoin(sourceHome, fileName);
|
|
35942
36488
|
const targetPath = pathJoin(targetHome, fileName);
|
|
35943
|
-
if (!
|
|
36489
|
+
if (!fs22.existsSync(sourcePath)) continue;
|
|
35944
36490
|
try {
|
|
35945
|
-
|
|
36491
|
+
fs22.copyFileSync(sourcePath, targetPath);
|
|
35946
36492
|
} catch (error) {
|
|
35947
36493
|
LOG.warn("MeshCoordinator", `Could not copy Hermes ${fileName} into isolated coordinator home: ${error?.message || error}`);
|
|
35948
36494
|
}
|
|
@@ -36297,13 +36843,13 @@ var DaemonCommandRouter = class {
|
|
|
36297
36843
|
recoveryHint: "Inspect the mesh node record before removing it, or remove stale metadata manually only after confirming no managed worktree remains."
|
|
36298
36844
|
};
|
|
36299
36845
|
}
|
|
36300
|
-
const worktreeExists =
|
|
36846
|
+
const worktreeExists = fs22.existsSync(workspace);
|
|
36301
36847
|
const sourceNode = args.node?.clonedFromNodeId ? args.mesh?.nodes?.find((n) => n.id === args.node.clonedFromNodeId || n.nodeId === args.node.clonedFromNodeId) : args.mesh?.nodes?.find((n) => !n.isLocalWorktree);
|
|
36302
36848
|
const repoRoot = typeof sourceNode?.repoRoot === "string" && sourceNode.repoRoot.trim() ? sourceNode.repoRoot.trim() : typeof sourceNode?.workspace === "string" && sourceNode.workspace.trim() ? sourceNode.workspace.trim() : "";
|
|
36303
36849
|
if (!worktreeExists) {
|
|
36304
36850
|
return { success: true, skipped: true, removedPath: workspace, repoRoot: repoRoot || void 0, reason: "worktree_path_missing" };
|
|
36305
36851
|
}
|
|
36306
|
-
if (!repoRoot || !
|
|
36852
|
+
if (!repoRoot || !fs22.existsSync(repoRoot)) {
|
|
36307
36853
|
return {
|
|
36308
36854
|
success: false,
|
|
36309
36855
|
code: "mesh_worktree_cleanup_missing_source_repo",
|
|
@@ -36323,7 +36869,7 @@ var DaemonCommandRouter = class {
|
|
|
36323
36869
|
const normalizePath = (value) => {
|
|
36324
36870
|
const resolved = pathResolve2(value);
|
|
36325
36871
|
try {
|
|
36326
|
-
return
|
|
36872
|
+
return fs22.realpathSync(resolved);
|
|
36327
36873
|
} catch {
|
|
36328
36874
|
return resolved;
|
|
36329
36875
|
}
|
|
@@ -37262,8 +37808,8 @@ var DaemonCommandRouter = class {
|
|
|
37262
37808
|
if (sinceTs > 0) {
|
|
37263
37809
|
return { success: true, logs: [], totalBuffered: 0 };
|
|
37264
37810
|
}
|
|
37265
|
-
if (
|
|
37266
|
-
const content =
|
|
37811
|
+
if (fs22.existsSync(LOG_PATH)) {
|
|
37812
|
+
const content = fs22.readFileSync(LOG_PATH, "utf-8");
|
|
37267
37813
|
const allLines = content.split("\n");
|
|
37268
37814
|
const recent = allLines.slice(-count).join("\n");
|
|
37269
37815
|
return { success: true, logs: recent, totalLines: allLines.length };
|
|
@@ -37653,24 +38199,24 @@ var DaemonCommandRouter = class {
|
|
|
37653
38199
|
// Settings page in the dashboard reads/writes via these two
|
|
37654
38200
|
// commands instead of going through fs from the browser.
|
|
37655
38201
|
case "list_coordinator_prompts": {
|
|
37656
|
-
const
|
|
37657
|
-
const
|
|
37658
|
-
const
|
|
37659
|
-
const dir =
|
|
38202
|
+
const fs28 = await import("fs");
|
|
38203
|
+
const path40 = await import("path");
|
|
38204
|
+
const os29 = await import("os");
|
|
38205
|
+
const dir = path40.join(os29.homedir(), ".adhdev", "coordinator-prompts");
|
|
37660
38206
|
const entries = {};
|
|
37661
38207
|
try {
|
|
37662
|
-
if (
|
|
37663
|
-
for (const name of
|
|
38208
|
+
if (fs28.existsSync(dir)) {
|
|
38209
|
+
for (const name of fs28.readdirSync(dir)) {
|
|
37664
38210
|
const matchOverride = name.match(/^([a-zA-Z0-9_.-]+)\.md$/);
|
|
37665
38211
|
const matchAppend = name.match(/^([a-zA-Z0-9_.-]+)\.append\.md$/);
|
|
37666
38212
|
const m = matchAppend || matchOverride;
|
|
37667
38213
|
if (!m) continue;
|
|
37668
38214
|
const isAppend = !!matchAppend;
|
|
37669
38215
|
const key = m[1];
|
|
37670
|
-
const full =
|
|
38216
|
+
const full = path40.join(dir, name);
|
|
37671
38217
|
let content = "";
|
|
37672
38218
|
try {
|
|
37673
|
-
content =
|
|
38219
|
+
content = fs28.readFileSync(full, "utf8");
|
|
37674
38220
|
} catch {
|
|
37675
38221
|
}
|
|
37676
38222
|
if (!entries[key]) entries[key] = { override: "", append: "" };
|
|
@@ -37684,24 +38230,24 @@ var DaemonCommandRouter = class {
|
|
|
37684
38230
|
return { success: true, dir, entries };
|
|
37685
38231
|
}
|
|
37686
38232
|
case "write_coordinator_prompt": {
|
|
37687
|
-
const
|
|
37688
|
-
const
|
|
37689
|
-
const
|
|
38233
|
+
const fs28 = await import("fs");
|
|
38234
|
+
const path40 = await import("path");
|
|
38235
|
+
const os29 = await import("os");
|
|
37690
38236
|
const key = typeof args?.key === "string" ? args.key.trim() : "";
|
|
37691
38237
|
const kind = args?.kind === "append" ? "append" : "override";
|
|
37692
38238
|
const content = typeof args?.content === "string" ? args.content : "";
|
|
37693
38239
|
if (!key || !/^[a-zA-Z0-9_.-]+$/.test(key)) {
|
|
37694
38240
|
return { success: false, error: "key must match [a-zA-Z0-9_.-]+" };
|
|
37695
38241
|
}
|
|
37696
|
-
const dir =
|
|
38242
|
+
const dir = path40.join(os29.homedir(), ".adhdev", "coordinator-prompts");
|
|
37697
38243
|
const filename = kind === "append" ? `${key}.append.md` : `${key}.md`;
|
|
37698
|
-
const full =
|
|
38244
|
+
const full = path40.join(dir, filename);
|
|
37699
38245
|
try {
|
|
37700
|
-
|
|
38246
|
+
fs28.mkdirSync(dir, { recursive: true });
|
|
37701
38247
|
if (content.trim()) {
|
|
37702
|
-
|
|
37703
|
-
} else if (
|
|
37704
|
-
|
|
38248
|
+
fs28.writeFileSync(full, content, { encoding: "utf8", mode: 384 });
|
|
38249
|
+
} else if (fs28.existsSync(full)) {
|
|
38250
|
+
fs28.unlinkSync(full);
|
|
37705
38251
|
}
|
|
37706
38252
|
return { success: true, path: full, kind, key };
|
|
37707
38253
|
} catch (error) {
|
|
@@ -38910,7 +39456,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
38910
39456
|
workspace
|
|
38911
39457
|
};
|
|
38912
39458
|
}
|
|
38913
|
-
const { existsSync:
|
|
39459
|
+
const { existsSync: existsSync39, readFileSync: readFileSync33, writeFileSync: writeFileSync20, copyFileSync: copyFileSync4, mkdirSync: mkdirSync19 } = await import("fs");
|
|
38914
39460
|
const { dirname: dirname11 } = await import("path");
|
|
38915
39461
|
const mcpConfigPath = coordinatorSetup.configPath;
|
|
38916
39462
|
const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
|
|
@@ -38946,21 +39492,21 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
38946
39492
|
};
|
|
38947
39493
|
}
|
|
38948
39494
|
try {
|
|
38949
|
-
|
|
39495
|
+
mkdirSync19(dirname11(mcpConfigPath), { recursive: true });
|
|
38950
39496
|
} catch (error) {
|
|
38951
39497
|
const message = `Could not prepare MCP config path for automatic setup: ${error?.message || error}`;
|
|
38952
39498
|
LOG.error("MeshCoordinator", message);
|
|
38953
39499
|
if (hermesManualFallback) return returnManualFallback(message);
|
|
38954
39500
|
return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
|
|
38955
39501
|
}
|
|
38956
|
-
const hadExistingMcpConfig =
|
|
39502
|
+
const hadExistingMcpConfig = existsSync39(mcpConfigPath);
|
|
38957
39503
|
let existingMcpConfig = hermesBaseConfig?.config || {};
|
|
38958
39504
|
if (hermesBaseConfig) {
|
|
38959
39505
|
copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname11(mcpConfigPath));
|
|
38960
39506
|
}
|
|
38961
39507
|
if (hadExistingMcpConfig) {
|
|
38962
39508
|
try {
|
|
38963
|
-
const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(
|
|
39509
|
+
const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync33(mcpConfigPath, "utf-8"), configFormat);
|
|
38964
39510
|
const existingCoordinatorConfig = hermesManualFallback ? stripHermesCoordinatorTempModelProviderOverrides(parsedExistingMcpConfig) : parsedExistingMcpConfig;
|
|
38965
39511
|
existingMcpConfig = { ...existingMcpConfig, ...existingCoordinatorConfig };
|
|
38966
39512
|
copyFileSync4(mcpConfigPath, mcpConfigPath + ".backup");
|
|
@@ -38983,7 +39529,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
38983
39529
|
}
|
|
38984
39530
|
};
|
|
38985
39531
|
try {
|
|
38986
|
-
|
|
39532
|
+
writeFileSync20(mcpConfigPath, serializeMeshCoordinatorMcpConfig(mcpConfig, configFormat), "utf-8");
|
|
38987
39533
|
} catch (error) {
|
|
38988
39534
|
const message = `Could not write MCP config for automatic setup: ${error?.message || error}`;
|
|
38989
39535
|
LOG.error("MeshCoordinator", message);
|
|
@@ -39262,7 +39808,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
39262
39808
|
}
|
|
39263
39809
|
}
|
|
39264
39810
|
if (workspace) {
|
|
39265
|
-
if (!
|
|
39811
|
+
if (!fs22.existsSync(workspace)) {
|
|
39266
39812
|
const inlineTransitGit = buildInlineMeshTransitGitStatus(node);
|
|
39267
39813
|
let remoteProbeApplied = false;
|
|
39268
39814
|
if (inlineTransitGit) {
|
|
@@ -39375,7 +39921,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
39375
39921
|
const callerCoordinatorDaemonId = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : this.deps.statusInstanceId || void 0;
|
|
39376
39922
|
const pendingCoordinatorEvents = drainPendingMeshCoordinatorEvents(meshId, callerCoordinatorDaemonId);
|
|
39377
39923
|
const previewFreshness = (() => {
|
|
39378
|
-
const localRepoRoot = nodeStatuses.map((node) => readStringValue(node?.git?.repoRoot, node?.repoRoot, node?.workspace)).find((candidate) => !!candidate &&
|
|
39924
|
+
const localRepoRoot = nodeStatuses.map((node) => readStringValue(node?.git?.repoRoot, node?.repoRoot, node?.workspace)).find((candidate) => !!candidate && fs22.existsSync(candidate));
|
|
39379
39925
|
return localRepoRoot ? buildPreviewFreshness(localRepoRoot) : void 0;
|
|
39380
39926
|
})();
|
|
39381
39927
|
const asyncRefineJobs = buildMeshAsyncRefineJobs({
|
|
@@ -41122,12 +41668,12 @@ var ProviderInstanceManager = class {
|
|
|
41122
41668
|
};
|
|
41123
41669
|
|
|
41124
41670
|
// src/providers/version-archive.ts
|
|
41125
|
-
import * as
|
|
41126
|
-
import * as
|
|
41127
|
-
import * as
|
|
41671
|
+
import * as fs23 from "fs";
|
|
41672
|
+
import * as path35 from "path";
|
|
41673
|
+
import * as os27 from "os";
|
|
41128
41674
|
import { platform as platform8 } from "os";
|
|
41129
41675
|
import { exec as exec5 } from "child_process";
|
|
41130
|
-
var ARCHIVE_PATH =
|
|
41676
|
+
var ARCHIVE_PATH = path35.join(os27.homedir(), ".adhdev", "version-history.json");
|
|
41131
41677
|
var MAX_ENTRIES_PER_PROVIDER = 20;
|
|
41132
41678
|
var VersionArchive = class {
|
|
41133
41679
|
history = {};
|
|
@@ -41136,8 +41682,8 @@ var VersionArchive = class {
|
|
|
41136
41682
|
}
|
|
41137
41683
|
load() {
|
|
41138
41684
|
try {
|
|
41139
|
-
if (
|
|
41140
|
-
this.history = JSON.parse(
|
|
41685
|
+
if (fs23.existsSync(ARCHIVE_PATH)) {
|
|
41686
|
+
this.history = JSON.parse(fs23.readFileSync(ARCHIVE_PATH, "utf-8"));
|
|
41141
41687
|
}
|
|
41142
41688
|
} catch {
|
|
41143
41689
|
this.history = {};
|
|
@@ -41174,8 +41720,8 @@ var VersionArchive = class {
|
|
|
41174
41720
|
}
|
|
41175
41721
|
save() {
|
|
41176
41722
|
try {
|
|
41177
|
-
|
|
41178
|
-
|
|
41723
|
+
fs23.mkdirSync(path35.dirname(ARCHIVE_PATH), { recursive: true });
|
|
41724
|
+
fs23.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
|
|
41179
41725
|
} catch {
|
|
41180
41726
|
}
|
|
41181
41727
|
}
|
|
@@ -41198,10 +41744,10 @@ function findBinary2(name) {
|
|
|
41198
41744
|
for (const p of paths) {
|
|
41199
41745
|
if (!p) continue;
|
|
41200
41746
|
for (const ext of exes) {
|
|
41201
|
-
const fullPath =
|
|
41747
|
+
const fullPath = path35.join(p, name + ext);
|
|
41202
41748
|
try {
|
|
41203
|
-
if (
|
|
41204
|
-
const stat2 =
|
|
41749
|
+
if (fs23.existsSync(fullPath)) {
|
|
41750
|
+
const stat2 = fs23.statSync(fullPath);
|
|
41205
41751
|
if (stat2.isFile() && (isWin || stat2.mode & 73)) {
|
|
41206
41752
|
return fullPath;
|
|
41207
41753
|
}
|
|
@@ -41246,19 +41792,19 @@ async function getVersion(binary, versionCommand) {
|
|
|
41246
41792
|
function checkPathExists2(paths) {
|
|
41247
41793
|
for (const p of paths) {
|
|
41248
41794
|
if (p.includes("*")) {
|
|
41249
|
-
const home =
|
|
41250
|
-
const resolved = p.replace(/\*/g, home.split(
|
|
41251
|
-
if (
|
|
41795
|
+
const home = os27.homedir();
|
|
41796
|
+
const resolved = p.replace(/\*/g, home.split(path35.sep).pop() || "");
|
|
41797
|
+
if (fs23.existsSync(resolved)) return resolved;
|
|
41252
41798
|
} else {
|
|
41253
|
-
if (
|
|
41799
|
+
if (fs23.existsSync(p)) return p;
|
|
41254
41800
|
}
|
|
41255
41801
|
}
|
|
41256
41802
|
return null;
|
|
41257
41803
|
}
|
|
41258
41804
|
async function getMacAppVersion(appPath) {
|
|
41259
41805
|
if (platform8() !== "darwin" || !appPath.endsWith(".app")) return null;
|
|
41260
|
-
const plistPath =
|
|
41261
|
-
if (!
|
|
41806
|
+
const plistPath = path35.join(appPath, "Contents", "Info.plist");
|
|
41807
|
+
if (!fs23.existsSync(plistPath)) return null;
|
|
41262
41808
|
const raw = await runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
|
|
41263
41809
|
return raw || null;
|
|
41264
41810
|
}
|
|
@@ -41283,8 +41829,8 @@ async function detectAllVersions(loader, archive) {
|
|
|
41283
41829
|
const cliBin = provider.cli ? findBinary2(provider.cli) : null;
|
|
41284
41830
|
let resolvedBin = cliBin;
|
|
41285
41831
|
if (!resolvedBin && appPath && currentOs === "darwin") {
|
|
41286
|
-
const bundled =
|
|
41287
|
-
if (provider.cli &&
|
|
41832
|
+
const bundled = path35.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
|
|
41833
|
+
if (provider.cli && fs23.existsSync(bundled)) resolvedBin = bundled;
|
|
41288
41834
|
}
|
|
41289
41835
|
info.installed = !!(appPath || resolvedBin);
|
|
41290
41836
|
info.path = appPath || null;
|
|
@@ -41323,8 +41869,8 @@ async function detectAllVersions(loader, archive) {
|
|
|
41323
41869
|
|
|
41324
41870
|
// src/daemon/dev-server.ts
|
|
41325
41871
|
import * as http2 from "http";
|
|
41326
|
-
import * as
|
|
41327
|
-
import * as
|
|
41872
|
+
import * as fs27 from "fs";
|
|
41873
|
+
import * as path39 from "path";
|
|
41328
41874
|
init_config();
|
|
41329
41875
|
|
|
41330
41876
|
// src/daemon/scaffold-template.ts
|
|
@@ -41675,8 +42221,8 @@ init_logger();
|
|
|
41675
42221
|
|
|
41676
42222
|
// src/daemon/dev-cdp-handlers.ts
|
|
41677
42223
|
init_logger();
|
|
41678
|
-
import * as
|
|
41679
|
-
import * as
|
|
42224
|
+
import * as fs24 from "fs";
|
|
42225
|
+
import * as path36 from "path";
|
|
41680
42226
|
async function handleCdpEvaluate(ctx, req, res) {
|
|
41681
42227
|
const body = await ctx.readBody(req);
|
|
41682
42228
|
const { expression, timeout, ideType } = body;
|
|
@@ -41854,18 +42400,18 @@ async function handleScriptHints(ctx, type, _req, res) {
|
|
|
41854
42400
|
return;
|
|
41855
42401
|
}
|
|
41856
42402
|
let scriptsPath = "";
|
|
41857
|
-
const directScripts =
|
|
41858
|
-
if (
|
|
42403
|
+
const directScripts = path36.join(dir, "scripts.js");
|
|
42404
|
+
if (fs24.existsSync(directScripts)) {
|
|
41859
42405
|
scriptsPath = directScripts;
|
|
41860
42406
|
} else {
|
|
41861
|
-
const scriptsDir =
|
|
41862
|
-
if (
|
|
41863
|
-
const versions =
|
|
41864
|
-
return
|
|
42407
|
+
const scriptsDir = path36.join(dir, "scripts");
|
|
42408
|
+
if (fs24.existsSync(scriptsDir)) {
|
|
42409
|
+
const versions = fs24.readdirSync(scriptsDir).filter((d) => {
|
|
42410
|
+
return fs24.statSync(path36.join(scriptsDir, d)).isDirectory();
|
|
41865
42411
|
}).sort().reverse();
|
|
41866
42412
|
for (const ver of versions) {
|
|
41867
|
-
const p =
|
|
41868
|
-
if (
|
|
42413
|
+
const p = path36.join(scriptsDir, ver, "scripts.js");
|
|
42414
|
+
if (fs24.existsSync(p)) {
|
|
41869
42415
|
scriptsPath = p;
|
|
41870
42416
|
break;
|
|
41871
42417
|
}
|
|
@@ -41877,7 +42423,7 @@ async function handleScriptHints(ctx, type, _req, res) {
|
|
|
41877
42423
|
return;
|
|
41878
42424
|
}
|
|
41879
42425
|
try {
|
|
41880
|
-
const source =
|
|
42426
|
+
const source = fs24.readFileSync(scriptsPath, "utf-8");
|
|
41881
42427
|
const hints = {};
|
|
41882
42428
|
const funcRegex = /module\.exports\.(\w+)\s*=\s*function\s+\w+\s*\(params\)/g;
|
|
41883
42429
|
let match;
|
|
@@ -42692,8 +43238,8 @@ async function handleDomContext(ctx, type, req, res) {
|
|
|
42692
43238
|
}
|
|
42693
43239
|
|
|
42694
43240
|
// src/daemon/dev-cli-debug.ts
|
|
42695
|
-
import * as
|
|
42696
|
-
import * as
|
|
43241
|
+
import * as fs25 from "fs";
|
|
43242
|
+
import * as path37 from "path";
|
|
42697
43243
|
function slugifyFixtureName(value) {
|
|
42698
43244
|
const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
42699
43245
|
return normalized || `fixture-${Date.now()}`;
|
|
@@ -42703,15 +43249,15 @@ function getCliFixtureDir(ctx, type) {
|
|
|
42703
43249
|
if (!providerDir) {
|
|
42704
43250
|
throw new Error(`Provider directory not found for '${type}'`);
|
|
42705
43251
|
}
|
|
42706
|
-
return
|
|
43252
|
+
return path37.join(providerDir, "fixtures");
|
|
42707
43253
|
}
|
|
42708
43254
|
function readCliFixture(ctx, type, name) {
|
|
42709
43255
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
42710
|
-
const filePath =
|
|
42711
|
-
if (!
|
|
43256
|
+
const filePath = path37.join(fixtureDir, `${name}.json`);
|
|
43257
|
+
if (!fs25.existsSync(filePath)) {
|
|
42712
43258
|
throw new Error(`Fixture not found: ${filePath}`);
|
|
42713
43259
|
}
|
|
42714
|
-
return JSON.parse(
|
|
43260
|
+
return JSON.parse(fs25.readFileSync(filePath, "utf-8"));
|
|
42715
43261
|
}
|
|
42716
43262
|
function getExerciseTranscriptText(result) {
|
|
42717
43263
|
const parts = [];
|
|
@@ -43456,7 +44002,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
43456
44002
|
return;
|
|
43457
44003
|
}
|
|
43458
44004
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
43459
|
-
|
|
44005
|
+
fs25.mkdirSync(fixtureDir, { recursive: true });
|
|
43460
44006
|
const name = slugifyFixtureName(String(body?.name || `${type}-${Date.now()}`));
|
|
43461
44007
|
const result = await runCliExerciseInternal(ctx, { ...request, type });
|
|
43462
44008
|
const fixture = {
|
|
@@ -43483,8 +44029,8 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
43483
44029
|
},
|
|
43484
44030
|
notes: typeof body?.notes === "string" ? body.notes : void 0
|
|
43485
44031
|
};
|
|
43486
|
-
const filePath =
|
|
43487
|
-
|
|
44032
|
+
const filePath = path37.join(fixtureDir, `${name}.json`);
|
|
44033
|
+
fs25.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
|
|
43488
44034
|
ctx.json(res, 200, {
|
|
43489
44035
|
saved: true,
|
|
43490
44036
|
name,
|
|
@@ -43502,14 +44048,14 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
43502
44048
|
async function handleCliFixtureList(ctx, type, _req, res) {
|
|
43503
44049
|
try {
|
|
43504
44050
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
43505
|
-
if (!
|
|
44051
|
+
if (!fs25.existsSync(fixtureDir)) {
|
|
43506
44052
|
ctx.json(res, 200, { fixtures: [], count: 0 });
|
|
43507
44053
|
return;
|
|
43508
44054
|
}
|
|
43509
|
-
const fixtures =
|
|
43510
|
-
const fullPath =
|
|
44055
|
+
const fixtures = fs25.readdirSync(fixtureDir).filter((file) => file.endsWith(".json")).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file) => {
|
|
44056
|
+
const fullPath = path37.join(fixtureDir, file);
|
|
43511
44057
|
try {
|
|
43512
|
-
const raw = JSON.parse(
|
|
44058
|
+
const raw = JSON.parse(fs25.readFileSync(fullPath, "utf-8"));
|
|
43513
44059
|
return {
|
|
43514
44060
|
name: raw.name || file.replace(/\.json$/i, ""),
|
|
43515
44061
|
path: fullPath,
|
|
@@ -43642,9 +44188,9 @@ async function handleCliRaw(ctx, req, res) {
|
|
|
43642
44188
|
}
|
|
43643
44189
|
|
|
43644
44190
|
// src/daemon/dev-auto-implement.ts
|
|
43645
|
-
import * as
|
|
43646
|
-
import * as
|
|
43647
|
-
import * as
|
|
44191
|
+
import * as fs26 from "fs";
|
|
44192
|
+
import * as path38 from "path";
|
|
44193
|
+
import * as os28 from "os";
|
|
43648
44194
|
function getAutoImplPid(ctx) {
|
|
43649
44195
|
const pid = ctx.autoImplProcess?.pid;
|
|
43650
44196
|
return typeof pid === "number" && pid > 0 ? pid : null;
|
|
@@ -43690,38 +44236,38 @@ function resolveAutoImplReference(ctx, category, requestedReference, targetType)
|
|
|
43690
44236
|
return fallback?.type || null;
|
|
43691
44237
|
}
|
|
43692
44238
|
function getLatestScriptVersionDir(scriptsDir) {
|
|
43693
|
-
if (!
|
|
43694
|
-
const versions =
|
|
44239
|
+
if (!fs26.existsSync(scriptsDir)) return null;
|
|
44240
|
+
const versions = fs26.readdirSync(scriptsDir).filter((d) => {
|
|
43695
44241
|
try {
|
|
43696
|
-
return
|
|
44242
|
+
return fs26.statSync(path38.join(scriptsDir, d)).isDirectory();
|
|
43697
44243
|
} catch {
|
|
43698
44244
|
return false;
|
|
43699
44245
|
}
|
|
43700
44246
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
43701
44247
|
if (versions.length === 0) return null;
|
|
43702
|
-
return
|
|
44248
|
+
return path38.join(scriptsDir, versions[0]);
|
|
43703
44249
|
}
|
|
43704
44250
|
function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
43705
|
-
const canonicalUserDir =
|
|
43706
|
-
const desiredDir = requestedDir ?
|
|
43707
|
-
const upstreamRoot =
|
|
43708
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
44251
|
+
const canonicalUserDir = path38.resolve(ctx.providerLoader.getUserProviderDir(category, type));
|
|
44252
|
+
const desiredDir = requestedDir ? path38.resolve(requestedDir) : canonicalUserDir;
|
|
44253
|
+
const upstreamRoot = path38.resolve(ctx.providerLoader.getUpstreamDir());
|
|
44254
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path38.sep}`)) {
|
|
43709
44255
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
43710
44256
|
}
|
|
43711
|
-
if (
|
|
44257
|
+
if (path38.basename(desiredDir) !== type) {
|
|
43712
44258
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
43713
44259
|
}
|
|
43714
44260
|
const sourceDir = ctx.findProviderDir(type);
|
|
43715
44261
|
if (!sourceDir) {
|
|
43716
44262
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
43717
44263
|
}
|
|
43718
|
-
if (!
|
|
43719
|
-
|
|
43720
|
-
|
|
44264
|
+
if (!fs26.existsSync(desiredDir)) {
|
|
44265
|
+
fs26.mkdirSync(path38.dirname(desiredDir), { recursive: true });
|
|
44266
|
+
fs26.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
43721
44267
|
ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
43722
44268
|
}
|
|
43723
|
-
const providerJson =
|
|
43724
|
-
if (!
|
|
44269
|
+
const providerJson = path38.join(desiredDir, "provider.json");
|
|
44270
|
+
if (!fs26.existsSync(providerJson)) {
|
|
43725
44271
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
43726
44272
|
}
|
|
43727
44273
|
return { dir: desiredDir };
|
|
@@ -43729,15 +44275,15 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
|
43729
44275
|
function loadAutoImplReferenceScripts(ctx, referenceType) {
|
|
43730
44276
|
if (!referenceType) return {};
|
|
43731
44277
|
const refDir = ctx.findProviderDir(referenceType);
|
|
43732
|
-
if (!refDir || !
|
|
44278
|
+
if (!refDir || !fs26.existsSync(refDir)) return {};
|
|
43733
44279
|
const referenceScripts = {};
|
|
43734
|
-
const scriptsDir =
|
|
44280
|
+
const scriptsDir = path38.join(refDir, "scripts");
|
|
43735
44281
|
const latestDir = getLatestScriptVersionDir(scriptsDir);
|
|
43736
44282
|
if (!latestDir) return referenceScripts;
|
|
43737
|
-
for (const file of
|
|
44283
|
+
for (const file of fs26.readdirSync(latestDir)) {
|
|
43738
44284
|
if (!file.endsWith(".js")) continue;
|
|
43739
44285
|
try {
|
|
43740
|
-
referenceScripts[file] =
|
|
44286
|
+
referenceScripts[file] = fs26.readFileSync(path38.join(latestDir, file), "utf-8");
|
|
43741
44287
|
} catch {
|
|
43742
44288
|
}
|
|
43743
44289
|
}
|
|
@@ -43845,16 +44391,16 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
43845
44391
|
});
|
|
43846
44392
|
const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
|
|
43847
44393
|
const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
|
|
43848
|
-
const tmpDir =
|
|
43849
|
-
if (!
|
|
43850
|
-
const promptFile =
|
|
43851
|
-
|
|
44394
|
+
const tmpDir = path38.join(os28.tmpdir(), "adhdev-autoimpl");
|
|
44395
|
+
if (!fs26.existsSync(tmpDir)) fs26.mkdirSync(tmpDir, { recursive: true });
|
|
44396
|
+
const promptFile = path38.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
|
|
44397
|
+
fs26.writeFileSync(promptFile, prompt, "utf-8");
|
|
43852
44398
|
ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
|
|
43853
44399
|
const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
|
|
43854
44400
|
const spawn4 = agentProvider?.spawn;
|
|
43855
44401
|
if (!spawn4?.command) {
|
|
43856
44402
|
try {
|
|
43857
|
-
|
|
44403
|
+
fs26.unlinkSync(promptFile);
|
|
43858
44404
|
} catch {
|
|
43859
44405
|
}
|
|
43860
44406
|
ctx.json(res, 400, { error: `Agent '${agent}' has no spawn config. Select a CLI provider with a spawn configuration.` });
|
|
@@ -43956,7 +44502,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
43956
44502
|
} catch {
|
|
43957
44503
|
}
|
|
43958
44504
|
try {
|
|
43959
|
-
|
|
44505
|
+
fs26.unlinkSync(promptFile);
|
|
43960
44506
|
} catch {
|
|
43961
44507
|
}
|
|
43962
44508
|
ctx.log(`Auto-implement (ACP) ${success ? "completed" : "failed"}: ${type} (exit: ${code})`);
|
|
@@ -44000,7 +44546,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
44000
44546
|
const interactiveFlags = ["--yolo", "--interactive", "-i"];
|
|
44001
44547
|
const baseArgs = [...spawn4.args || []].filter((a) => !interactiveFlags.includes(a));
|
|
44002
44548
|
let shellCmd;
|
|
44003
|
-
const isWin =
|
|
44549
|
+
const isWin = os28.platform() === "win32";
|
|
44004
44550
|
const escapeArg = (a) => isWin ? `"${a.replace(/"/g, '""')}"` : `'${a.replace(/'/g, "'\\''")}'`;
|
|
44005
44551
|
const promptMode = autoImpl?.promptMode ?? "stdin";
|
|
44006
44552
|
const extraArgs = autoImpl?.extraArgs ?? [];
|
|
@@ -44039,7 +44585,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
44039
44585
|
try {
|
|
44040
44586
|
const pty = __require("node-pty");
|
|
44041
44587
|
ctx.log(`Auto-implement spawn (PTY): ${shellCmd}`);
|
|
44042
|
-
const isWin2 =
|
|
44588
|
+
const isWin2 = os28.platform() === "win32";
|
|
44043
44589
|
child = pty.spawn(isWin2 ? "cmd.exe" : process.env.SHELL || "/bin/zsh", [isWin2 ? "/c" : "-c", shellCmd], {
|
|
44044
44590
|
name: "xterm-256color",
|
|
44045
44591
|
cols: 120,
|
|
@@ -44182,7 +44728,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
44182
44728
|
}
|
|
44183
44729
|
});
|
|
44184
44730
|
try {
|
|
44185
|
-
|
|
44731
|
+
fs26.unlinkSync(promptFile);
|
|
44186
44732
|
} catch {
|
|
44187
44733
|
}
|
|
44188
44734
|
ctx.log(`Auto-implement ${success ? "completed" : "failed"}: ${type} (exit: ${code})${verificationSummary ? ` verify=${verificationSummary.pass ? "pass" : "fail"}` : ""}`);
|
|
@@ -44279,7 +44825,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
44279
44825
|
setMode: "set_mode.js"
|
|
44280
44826
|
};
|
|
44281
44827
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
44282
|
-
const scriptsDir =
|
|
44828
|
+
const scriptsDir = path38.join(providerDir, "scripts");
|
|
44283
44829
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
44284
44830
|
if (latestScriptsDir) {
|
|
44285
44831
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -44287,10 +44833,10 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
44287
44833
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
44288
44834
|
lines.push("These are the ONLY files you are allowed to modify. Replace the TODO stubs with working implementations.");
|
|
44289
44835
|
lines.push("");
|
|
44290
|
-
for (const file of
|
|
44836
|
+
for (const file of fs26.readdirSync(latestScriptsDir)) {
|
|
44291
44837
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
44292
44838
|
try {
|
|
44293
|
-
const content =
|
|
44839
|
+
const content = fs26.readFileSync(path38.join(latestScriptsDir, file), "utf-8");
|
|
44294
44840
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
44295
44841
|
lines.push("```javascript");
|
|
44296
44842
|
lines.push(content);
|
|
@@ -44300,14 +44846,14 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
44300
44846
|
}
|
|
44301
44847
|
}
|
|
44302
44848
|
}
|
|
44303
|
-
const refFiles =
|
|
44849
|
+
const refFiles = fs26.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
44304
44850
|
if (refFiles.length > 0) {
|
|
44305
44851
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
44306
44852
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
44307
44853
|
lines.push("");
|
|
44308
44854
|
for (const file of refFiles) {
|
|
44309
44855
|
try {
|
|
44310
|
-
const content =
|
|
44856
|
+
const content = fs26.readFileSync(path38.join(latestScriptsDir, file), "utf-8");
|
|
44311
44857
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
44312
44858
|
lines.push("```javascript");
|
|
44313
44859
|
lines.push(content);
|
|
@@ -44348,11 +44894,11 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
44348
44894
|
lines.push("");
|
|
44349
44895
|
}
|
|
44350
44896
|
}
|
|
44351
|
-
const docsDir =
|
|
44897
|
+
const docsDir = path38.join(providerDir, "../../docs");
|
|
44352
44898
|
const loadGuide = (name) => {
|
|
44353
44899
|
try {
|
|
44354
|
-
const p =
|
|
44355
|
-
if (
|
|
44900
|
+
const p = path38.join(docsDir, name);
|
|
44901
|
+
if (fs26.existsSync(p)) return fs26.readFileSync(p, "utf-8");
|
|
44356
44902
|
} catch {
|
|
44357
44903
|
}
|
|
44358
44904
|
return null;
|
|
@@ -44588,7 +45134,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
44588
45134
|
parseApproval: "parse_approval.js"
|
|
44589
45135
|
};
|
|
44590
45136
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
44591
|
-
const scriptsDir =
|
|
45137
|
+
const scriptsDir = path38.join(providerDir, "scripts");
|
|
44592
45138
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
44593
45139
|
if (latestScriptsDir) {
|
|
44594
45140
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -44596,11 +45142,11 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
44596
45142
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
44597
45143
|
lines.push("These are the ONLY files you are allowed to modify. Replace TODO or heuristic-only logic with working PTY-aware implementations.");
|
|
44598
45144
|
lines.push("");
|
|
44599
|
-
for (const file of
|
|
45145
|
+
for (const file of fs26.readdirSync(latestScriptsDir)) {
|
|
44600
45146
|
if (!file.endsWith(".js")) continue;
|
|
44601
45147
|
if (!targetFileNames.has(file)) continue;
|
|
44602
45148
|
try {
|
|
44603
|
-
const content =
|
|
45149
|
+
const content = fs26.readFileSync(path38.join(latestScriptsDir, file), "utf-8");
|
|
44604
45150
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
44605
45151
|
lines.push("```javascript");
|
|
44606
45152
|
lines.push(content);
|
|
@@ -44609,14 +45155,14 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
44609
45155
|
} catch {
|
|
44610
45156
|
}
|
|
44611
45157
|
}
|
|
44612
|
-
const refFiles =
|
|
45158
|
+
const refFiles = fs26.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
44613
45159
|
if (refFiles.length > 0) {
|
|
44614
45160
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
44615
45161
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
44616
45162
|
lines.push("");
|
|
44617
45163
|
for (const file of refFiles) {
|
|
44618
45164
|
try {
|
|
44619
|
-
const content =
|
|
45165
|
+
const content = fs26.readFileSync(path38.join(latestScriptsDir, file), "utf-8");
|
|
44620
45166
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
44621
45167
|
lines.push("```javascript");
|
|
44622
45168
|
lines.push(content);
|
|
@@ -44649,11 +45195,11 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
44649
45195
|
lines.push("");
|
|
44650
45196
|
}
|
|
44651
45197
|
}
|
|
44652
|
-
const docsDir =
|
|
45198
|
+
const docsDir = path38.join(providerDir, "../../docs");
|
|
44653
45199
|
const loadGuide = (name) => {
|
|
44654
45200
|
try {
|
|
44655
|
-
const p =
|
|
44656
|
-
if (
|
|
45201
|
+
const p = path38.join(docsDir, name);
|
|
45202
|
+
if (fs26.existsSync(p)) return fs26.readFileSync(p, "utf-8");
|
|
44657
45203
|
} catch {
|
|
44658
45204
|
}
|
|
44659
45205
|
return null;
|
|
@@ -45099,8 +45645,8 @@ var DevServer = class _DevServer {
|
|
|
45099
45645
|
}
|
|
45100
45646
|
getEndpointList() {
|
|
45101
45647
|
return this.routes.map((r) => {
|
|
45102
|
-
const
|
|
45103
|
-
return `${r.method.padEnd(5)} ${
|
|
45648
|
+
const path40 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
|
|
45649
|
+
return `${r.method.padEnd(5)} ${path40}`;
|
|
45104
45650
|
});
|
|
45105
45651
|
}
|
|
45106
45652
|
async start(port = DEV_SERVER_PORT) {
|
|
@@ -45388,12 +45934,12 @@ var DevServer = class _DevServer {
|
|
|
45388
45934
|
// ─── DevConsole SPA ───
|
|
45389
45935
|
getConsoleDistDir() {
|
|
45390
45936
|
const candidates = [
|
|
45391
|
-
|
|
45392
|
-
|
|
45393
|
-
|
|
45937
|
+
path39.resolve(__dirname, "../../web-devconsole/dist"),
|
|
45938
|
+
path39.resolve(__dirname, "../../../web-devconsole/dist"),
|
|
45939
|
+
path39.join(process.cwd(), "packages/web-devconsole/dist")
|
|
45394
45940
|
];
|
|
45395
45941
|
for (const dir of candidates) {
|
|
45396
|
-
if (
|
|
45942
|
+
if (fs27.existsSync(path39.join(dir, "index.html"))) return dir;
|
|
45397
45943
|
}
|
|
45398
45944
|
return null;
|
|
45399
45945
|
}
|
|
@@ -45403,9 +45949,9 @@ var DevServer = class _DevServer {
|
|
|
45403
45949
|
this.json(res, 500, { error: "DevConsole not found. Run: npm run build -w packages/web-devconsole" });
|
|
45404
45950
|
return;
|
|
45405
45951
|
}
|
|
45406
|
-
const htmlPath =
|
|
45952
|
+
const htmlPath = path39.join(distDir, "index.html");
|
|
45407
45953
|
try {
|
|
45408
|
-
const html =
|
|
45954
|
+
const html = fs27.readFileSync(htmlPath, "utf-8");
|
|
45409
45955
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
45410
45956
|
res.end(html);
|
|
45411
45957
|
} catch (e) {
|
|
@@ -45428,15 +45974,15 @@ var DevServer = class _DevServer {
|
|
|
45428
45974
|
this.json(res, 404, { error: "Not found" });
|
|
45429
45975
|
return;
|
|
45430
45976
|
}
|
|
45431
|
-
const safePath =
|
|
45432
|
-
const filePath =
|
|
45977
|
+
const safePath = path39.normalize(pathname).replace(/^\.\.\//, "");
|
|
45978
|
+
const filePath = path39.join(distDir, safePath);
|
|
45433
45979
|
if (!filePath.startsWith(distDir)) {
|
|
45434
45980
|
this.json(res, 403, { error: "Forbidden" });
|
|
45435
45981
|
return;
|
|
45436
45982
|
}
|
|
45437
45983
|
try {
|
|
45438
|
-
const content =
|
|
45439
|
-
const ext =
|
|
45984
|
+
const content = fs27.readFileSync(filePath);
|
|
45985
|
+
const ext = path39.extname(filePath);
|
|
45440
45986
|
const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
|
|
45441
45987
|
res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
|
|
45442
45988
|
res.end(content);
|
|
@@ -45544,14 +46090,14 @@ var DevServer = class _DevServer {
|
|
|
45544
46090
|
const files = [];
|
|
45545
46091
|
const scan = (d, prefix) => {
|
|
45546
46092
|
try {
|
|
45547
|
-
for (const entry of
|
|
46093
|
+
for (const entry of fs27.readdirSync(d, { withFileTypes: true })) {
|
|
45548
46094
|
if (entry.name.startsWith(".") || entry.name.endsWith(".bak")) continue;
|
|
45549
46095
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
45550
46096
|
if (entry.isDirectory()) {
|
|
45551
46097
|
files.push({ path: rel, size: 0, type: "dir" });
|
|
45552
|
-
scan(
|
|
46098
|
+
scan(path39.join(d, entry.name), rel);
|
|
45553
46099
|
} else {
|
|
45554
|
-
const stat2 =
|
|
46100
|
+
const stat2 = fs27.statSync(path39.join(d, entry.name));
|
|
45555
46101
|
files.push({ path: rel, size: stat2.size, type: "file" });
|
|
45556
46102
|
}
|
|
45557
46103
|
}
|
|
@@ -45574,16 +46120,16 @@ var DevServer = class _DevServer {
|
|
|
45574
46120
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
45575
46121
|
return;
|
|
45576
46122
|
}
|
|
45577
|
-
const fullPath =
|
|
46123
|
+
const fullPath = path39.resolve(dir, path39.normalize(filePath));
|
|
45578
46124
|
if (!fullPath.startsWith(dir)) {
|
|
45579
46125
|
this.json(res, 403, { error: "Forbidden" });
|
|
45580
46126
|
return;
|
|
45581
46127
|
}
|
|
45582
|
-
if (!
|
|
46128
|
+
if (!fs27.existsSync(fullPath) || fs27.statSync(fullPath).isDirectory()) {
|
|
45583
46129
|
this.json(res, 404, { error: `File not found: ${filePath}` });
|
|
45584
46130
|
return;
|
|
45585
46131
|
}
|
|
45586
|
-
const content =
|
|
46132
|
+
const content = fs27.readFileSync(fullPath, "utf-8");
|
|
45587
46133
|
this.json(res, 200, { type, path: filePath, content, lines: content.split("\n").length });
|
|
45588
46134
|
}
|
|
45589
46135
|
/** POST /api/providers/:type/file — write a file { path, content } */
|
|
@@ -45599,15 +46145,15 @@ var DevServer = class _DevServer {
|
|
|
45599
46145
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
45600
46146
|
return;
|
|
45601
46147
|
}
|
|
45602
|
-
const fullPath =
|
|
46148
|
+
const fullPath = path39.resolve(dir, path39.normalize(filePath));
|
|
45603
46149
|
if (!fullPath.startsWith(dir)) {
|
|
45604
46150
|
this.json(res, 403, { error: "Forbidden" });
|
|
45605
46151
|
return;
|
|
45606
46152
|
}
|
|
45607
46153
|
try {
|
|
45608
|
-
if (
|
|
45609
|
-
|
|
45610
|
-
|
|
46154
|
+
if (fs27.existsSync(fullPath)) fs27.copyFileSync(fullPath, fullPath + ".bak");
|
|
46155
|
+
fs27.mkdirSync(path39.dirname(fullPath), { recursive: true });
|
|
46156
|
+
fs27.writeFileSync(fullPath, content, "utf-8");
|
|
45611
46157
|
this.log(`File saved: ${fullPath} (${content.length} chars)`);
|
|
45612
46158
|
this.providerLoader.reload();
|
|
45613
46159
|
this.json(res, 200, { saved: true, path: filePath, chars: content.length });
|
|
@@ -45623,9 +46169,9 @@ var DevServer = class _DevServer {
|
|
|
45623
46169
|
return;
|
|
45624
46170
|
}
|
|
45625
46171
|
for (const name of ["scripts.js", "provider.json"]) {
|
|
45626
|
-
const p =
|
|
45627
|
-
if (
|
|
45628
|
-
const source =
|
|
46172
|
+
const p = path39.join(dir, name);
|
|
46173
|
+
if (fs27.existsSync(p)) {
|
|
46174
|
+
const source = fs27.readFileSync(p, "utf-8");
|
|
45629
46175
|
this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
|
|
45630
46176
|
return;
|
|
45631
46177
|
}
|
|
@@ -45644,11 +46190,11 @@ var DevServer = class _DevServer {
|
|
|
45644
46190
|
this.json(res, 404, { error: `Provider not found: ${type}` });
|
|
45645
46191
|
return;
|
|
45646
46192
|
}
|
|
45647
|
-
const target =
|
|
45648
|
-
const targetPath =
|
|
46193
|
+
const target = fs27.existsSync(path39.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
|
|
46194
|
+
const targetPath = path39.join(dir, target);
|
|
45649
46195
|
try {
|
|
45650
|
-
if (
|
|
45651
|
-
|
|
46196
|
+
if (fs27.existsSync(targetPath)) fs27.copyFileSync(targetPath, targetPath + ".bak");
|
|
46197
|
+
fs27.writeFileSync(targetPath, source, "utf-8");
|
|
45652
46198
|
this.log(`Saved provider: ${targetPath} (${source.length} chars)`);
|
|
45653
46199
|
this.providerLoader.reload();
|
|
45654
46200
|
this.json(res, 200, { saved: true, path: targetPath, chars: source.length });
|
|
@@ -45792,21 +46338,21 @@ var DevServer = class _DevServer {
|
|
|
45792
46338
|
}
|
|
45793
46339
|
let targetDir;
|
|
45794
46340
|
targetDir = this.providerLoader.getUserProviderDir(category, type);
|
|
45795
|
-
const jsonPath =
|
|
45796
|
-
if (
|
|
46341
|
+
const jsonPath = path39.join(targetDir, "provider.json");
|
|
46342
|
+
if (fs27.existsSync(jsonPath)) {
|
|
45797
46343
|
this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
|
|
45798
46344
|
return;
|
|
45799
46345
|
}
|
|
45800
46346
|
try {
|
|
45801
46347
|
const result = generateFiles(type, name, category, { cdpPorts, cli, processName, installPath, binary, extensionId, version, osPaths, processNames });
|
|
45802
|
-
|
|
45803
|
-
|
|
46348
|
+
fs27.mkdirSync(targetDir, { recursive: true });
|
|
46349
|
+
fs27.writeFileSync(jsonPath, result["provider.json"], "utf-8");
|
|
45804
46350
|
const createdFiles = ["provider.json"];
|
|
45805
46351
|
if (result.files) {
|
|
45806
46352
|
for (const [relPath, content] of Object.entries(result.files)) {
|
|
45807
|
-
const fullPath =
|
|
45808
|
-
|
|
45809
|
-
|
|
46353
|
+
const fullPath = path39.join(targetDir, relPath);
|
|
46354
|
+
fs27.mkdirSync(path39.dirname(fullPath), { recursive: true });
|
|
46355
|
+
fs27.writeFileSync(fullPath, content, "utf-8");
|
|
45810
46356
|
createdFiles.push(relPath);
|
|
45811
46357
|
}
|
|
45812
46358
|
}
|
|
@@ -45855,38 +46401,38 @@ var DevServer = class _DevServer {
|
|
|
45855
46401
|
}
|
|
45856
46402
|
// ─── Phase 2: Auto-Implement Backend ───
|
|
45857
46403
|
getLatestScriptVersionDir(scriptsDir) {
|
|
45858
|
-
if (!
|
|
45859
|
-
const versions =
|
|
46404
|
+
if (!fs27.existsSync(scriptsDir)) return null;
|
|
46405
|
+
const versions = fs27.readdirSync(scriptsDir).filter((d) => {
|
|
45860
46406
|
try {
|
|
45861
|
-
return
|
|
46407
|
+
return fs27.statSync(path39.join(scriptsDir, d)).isDirectory();
|
|
45862
46408
|
} catch {
|
|
45863
46409
|
return false;
|
|
45864
46410
|
}
|
|
45865
46411
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
45866
46412
|
if (versions.length === 0) return null;
|
|
45867
|
-
return
|
|
46413
|
+
return path39.join(scriptsDir, versions[0]);
|
|
45868
46414
|
}
|
|
45869
46415
|
resolveAutoImplWritableProviderDir(category, type, requestedDir) {
|
|
45870
|
-
const canonicalUserDir =
|
|
45871
|
-
const desiredDir = requestedDir ?
|
|
45872
|
-
const upstreamRoot =
|
|
45873
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
46416
|
+
const canonicalUserDir = path39.resolve(this.providerLoader.getUserProviderDir(category, type));
|
|
46417
|
+
const desiredDir = requestedDir ? path39.resolve(requestedDir) : canonicalUserDir;
|
|
46418
|
+
const upstreamRoot = path39.resolve(this.providerLoader.getUpstreamDir());
|
|
46419
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path39.sep}`)) {
|
|
45874
46420
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
45875
46421
|
}
|
|
45876
|
-
if (
|
|
46422
|
+
if (path39.basename(desiredDir) !== type) {
|
|
45877
46423
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
45878
46424
|
}
|
|
45879
46425
|
const sourceDir = this.findProviderDir(type);
|
|
45880
46426
|
if (!sourceDir) {
|
|
45881
46427
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
45882
46428
|
}
|
|
45883
|
-
if (!
|
|
45884
|
-
|
|
45885
|
-
|
|
46429
|
+
if (!fs27.existsSync(desiredDir)) {
|
|
46430
|
+
fs27.mkdirSync(path39.dirname(desiredDir), { recursive: true });
|
|
46431
|
+
fs27.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
45886
46432
|
this.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
45887
46433
|
}
|
|
45888
|
-
const providerJson =
|
|
45889
|
-
if (!
|
|
46434
|
+
const providerJson = path39.join(desiredDir, "provider.json");
|
|
46435
|
+
if (!fs27.existsSync(providerJson)) {
|
|
45890
46436
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
45891
46437
|
}
|
|
45892
46438
|
return { dir: desiredDir };
|
|
@@ -45921,7 +46467,7 @@ var DevServer = class _DevServer {
|
|
|
45921
46467
|
setMode: "set_mode.js"
|
|
45922
46468
|
};
|
|
45923
46469
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
45924
|
-
const scriptsDir =
|
|
46470
|
+
const scriptsDir = path39.join(providerDir, "scripts");
|
|
45925
46471
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
45926
46472
|
if (latestScriptsDir) {
|
|
45927
46473
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -45929,10 +46475,10 @@ var DevServer = class _DevServer {
|
|
|
45929
46475
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
45930
46476
|
lines.push("These are the ONLY files you are allowed to modify. Replace the TODO stubs with working implementations.");
|
|
45931
46477
|
lines.push("");
|
|
45932
|
-
for (const file of
|
|
46478
|
+
for (const file of fs27.readdirSync(latestScriptsDir)) {
|
|
45933
46479
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
45934
46480
|
try {
|
|
45935
|
-
const content =
|
|
46481
|
+
const content = fs27.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
|
|
45936
46482
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
45937
46483
|
lines.push("```javascript");
|
|
45938
46484
|
lines.push(content);
|
|
@@ -45942,14 +46488,14 @@ var DevServer = class _DevServer {
|
|
|
45942
46488
|
}
|
|
45943
46489
|
}
|
|
45944
46490
|
}
|
|
45945
|
-
const refFiles =
|
|
46491
|
+
const refFiles = fs27.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
45946
46492
|
if (refFiles.length > 0) {
|
|
45947
46493
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
45948
46494
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
45949
46495
|
lines.push("");
|
|
45950
46496
|
for (const file of refFiles) {
|
|
45951
46497
|
try {
|
|
45952
|
-
const content =
|
|
46498
|
+
const content = fs27.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
|
|
45953
46499
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
45954
46500
|
lines.push("```javascript");
|
|
45955
46501
|
lines.push(content);
|
|
@@ -45990,11 +46536,11 @@ var DevServer = class _DevServer {
|
|
|
45990
46536
|
lines.push("");
|
|
45991
46537
|
}
|
|
45992
46538
|
}
|
|
45993
|
-
const docsDir =
|
|
46539
|
+
const docsDir = path39.join(providerDir, "../../docs");
|
|
45994
46540
|
const loadGuide = (name) => {
|
|
45995
46541
|
try {
|
|
45996
|
-
const p =
|
|
45997
|
-
if (
|
|
46542
|
+
const p = path39.join(docsDir, name);
|
|
46543
|
+
if (fs27.existsSync(p)) return fs27.readFileSync(p, "utf-8");
|
|
45998
46544
|
} catch {
|
|
45999
46545
|
}
|
|
46000
46546
|
return null;
|
|
@@ -46167,7 +46713,7 @@ var DevServer = class _DevServer {
|
|
|
46167
46713
|
parseApproval: "parse_approval.js"
|
|
46168
46714
|
};
|
|
46169
46715
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
46170
|
-
const scriptsDir =
|
|
46716
|
+
const scriptsDir = path39.join(providerDir, "scripts");
|
|
46171
46717
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
46172
46718
|
if (latestScriptsDir) {
|
|
46173
46719
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -46175,11 +46721,11 @@ var DevServer = class _DevServer {
|
|
|
46175
46721
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
46176
46722
|
lines.push("These are the ONLY files you are allowed to modify. Replace TODO or heuristic-only logic with working PTY-aware implementations.");
|
|
46177
46723
|
lines.push("");
|
|
46178
|
-
for (const file of
|
|
46724
|
+
for (const file of fs27.readdirSync(latestScriptsDir)) {
|
|
46179
46725
|
if (!file.endsWith(".js")) continue;
|
|
46180
46726
|
if (!targetFileNames.has(file)) continue;
|
|
46181
46727
|
try {
|
|
46182
|
-
const content =
|
|
46728
|
+
const content = fs27.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
|
|
46183
46729
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
46184
46730
|
lines.push("```javascript");
|
|
46185
46731
|
lines.push(content);
|
|
@@ -46188,14 +46734,14 @@ var DevServer = class _DevServer {
|
|
|
46188
46734
|
} catch {
|
|
46189
46735
|
}
|
|
46190
46736
|
}
|
|
46191
|
-
const refFiles =
|
|
46737
|
+
const refFiles = fs27.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
46192
46738
|
if (refFiles.length > 0) {
|
|
46193
46739
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
46194
46740
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
46195
46741
|
lines.push("");
|
|
46196
46742
|
for (const file of refFiles) {
|
|
46197
46743
|
try {
|
|
46198
|
-
const content =
|
|
46744
|
+
const content = fs27.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
|
|
46199
46745
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
46200
46746
|
lines.push("```javascript");
|
|
46201
46747
|
lines.push(content);
|
|
@@ -46228,11 +46774,11 @@ var DevServer = class _DevServer {
|
|
|
46228
46774
|
lines.push("");
|
|
46229
46775
|
}
|
|
46230
46776
|
}
|
|
46231
|
-
const docsDir =
|
|
46777
|
+
const docsDir = path39.join(providerDir, "../../docs");
|
|
46232
46778
|
const loadGuide = (name) => {
|
|
46233
46779
|
try {
|
|
46234
|
-
const p =
|
|
46235
|
-
if (
|
|
46780
|
+
const p = path39.join(docsDir, name);
|
|
46781
|
+
if (fs27.existsSync(p)) return fs27.readFileSync(p, "utf-8");
|
|
46236
46782
|
} catch {
|
|
46237
46783
|
}
|
|
46238
46784
|
return null;
|
|
@@ -47142,8 +47688,8 @@ async function installExtension(ide, extension) {
|
|
|
47142
47688
|
const res = await fetch(extension.vsixUrl);
|
|
47143
47689
|
if (res.ok) {
|
|
47144
47690
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
47145
|
-
const
|
|
47146
|
-
|
|
47691
|
+
const fs28 = await import("fs");
|
|
47692
|
+
fs28.writeFileSync(vsixPath, buffer);
|
|
47147
47693
|
return new Promise((resolve23) => {
|
|
47148
47694
|
const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
|
|
47149
47695
|
exec6(cmd, { timeout: 6e4 }, (error, _stdout, stderr) => {
|
|
@@ -47714,12 +48260,12 @@ init_parse_session();
|
|
|
47714
48260
|
|
|
47715
48261
|
// src/providers/sdk/v1/fixture-tooling/replay.ts
|
|
47716
48262
|
init_provider_cli_shared();
|
|
47717
|
-
import { readFileSync as
|
|
48263
|
+
import { readFileSync as readFileSync31 } from "fs";
|
|
47718
48264
|
import { dirname as dirname9, resolve as resolve21 } from "path";
|
|
47719
48265
|
|
|
47720
48266
|
// src/providers/sdk/v1/validators/taint.ts
|
|
47721
|
-
import { readFileSync as
|
|
47722
|
-
import { resolve as resolve22, dirname as dirname10, join as
|
|
48267
|
+
import { readFileSync as readFileSync32, existsSync as existsSync38 } from "fs";
|
|
48268
|
+
import { resolve as resolve22, dirname as dirname10, join as join43 } from "path";
|
|
47723
48269
|
|
|
47724
48270
|
// src/providers/sdk/v1/validators/index.ts
|
|
47725
48271
|
init_manifest();
|