@adhdev/daemon-core 0.8.52 → 0.8.54
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/cli-manager.d.ts +8 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +896 -299
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +887 -300
- package/dist/index.mjs.map +1 -1
- package/dist/providers/acp-provider-instance.d.ts +2 -1
- package/dist/providers/cli-provider-instance.d.ts +3 -1
- package/dist/providers/cli-script-results.d.ts +8 -0
- package/dist/providers/contracts.d.ts +58 -9
- package/dist/providers/control-effects.d.ts +4 -1
- package/dist/providers/io-contracts.d.ts +91 -0
- package/dist/providers/provider-schema.d.ts +5 -0
- package/dist/session-host/runtime-surface.d.ts +16 -0
- package/dist/session-host/startup-restore-policy.d.ts +1 -0
- package/dist/shared-types.d.ts +6 -0
- package/dist/types.d.ts +3 -3
- package/node_modules/@adhdev/session-host-core/dist/index.d.mts +16 -1
- package/node_modules/@adhdev/session-host-core/dist/index.d.ts +16 -1
- package/node_modules/@adhdev/session-host-core/dist/index.js +59 -0
- package/node_modules/@adhdev/session-host-core/dist/index.js.map +1 -1
- package/node_modules/@adhdev/session-host-core/dist/index.mjs +54 -0
- package/node_modules/@adhdev/session-host-core/dist/index.mjs.map +1 -1
- package/node_modules/@adhdev/session-host-core/package.json +1 -1
- package/package.json +1 -1
- package/src/commands/cdp-commands.ts +27 -0
- package/src/commands/chat-commands.ts +7 -2
- package/src/commands/cli-manager.ts +9 -5
- package/src/commands/handler.ts +1 -9
- package/src/commands/stream-commands.ts +26 -36
- package/src/daemon/dev-server.ts +4 -18
- package/src/index.d.ts +3 -0
- package/src/index.ts +12 -1
- package/src/providers/acp-provider-instance.ts +156 -14
- package/src/providers/cli-provider-instance.ts +54 -5
- package/src/providers/cli-script-results.ts +39 -0
- package/src/providers/contracts.ts +72 -19
- package/src/providers/control-effects.ts +86 -1
- package/src/providers/io-contracts.ts +340 -0
- package/src/providers/provider-loader.ts +18 -13
- package/src/providers/provider-schema.ts +154 -0
- package/src/session-host/runtime-surface.ts +80 -0
- package/src/session-host/startup-restore-policy.d.ts +1 -0
- package/src/session-host/startup-restore-policy.js +7 -0
- package/src/session-host/startup-restore-policy.ts +7 -0
- package/src/shared-types.ts +6 -0
- package/src/status/builders.ts +5 -81
- package/src/types.ts +3 -3
package/dist/index.mjs
CHANGED
|
@@ -5085,6 +5085,61 @@ function normalizeProviderEffects(data) {
|
|
|
5085
5085
|
}
|
|
5086
5086
|
return effects;
|
|
5087
5087
|
}
|
|
5088
|
+
function normalizeControlListResult(data) {
|
|
5089
|
+
if (data && typeof data === "object" && Array.isArray(data.options)) {
|
|
5090
|
+
return {
|
|
5091
|
+
options: normalizeControlOptions(data.options),
|
|
5092
|
+
...isScalarControlValue(data.currentValue) ? { currentValue: data.currentValue } : {},
|
|
5093
|
+
...typeof data.error === "string" ? { error: data.error } : {}
|
|
5094
|
+
};
|
|
5095
|
+
}
|
|
5096
|
+
const rawOptions = Array.isArray(data?.models) ? data.models : Array.isArray(data?.modes) ? data.modes : Array.isArray(data?.options) ? data.options : [];
|
|
5097
|
+
const options = normalizeControlOptions(rawOptions);
|
|
5098
|
+
return {
|
|
5099
|
+
options,
|
|
5100
|
+
...isScalarControlValue(data?.current) ? { currentValue: data.current } : {},
|
|
5101
|
+
...isScalarControlValue(data?.currentValue) ? { currentValue: data.currentValue } : {},
|
|
5102
|
+
...typeof data?.error === "string" ? { error: data.error } : {}
|
|
5103
|
+
};
|
|
5104
|
+
}
|
|
5105
|
+
function normalizeControlSetResult(data) {
|
|
5106
|
+
const currentValue = isScalarControlValue(data?.currentValue) ? data.currentValue : isScalarControlValue(data?.value) ? data.value : void 0;
|
|
5107
|
+
return {
|
|
5108
|
+
ok: data?.ok === true || data?.success === true,
|
|
5109
|
+
...currentValue !== void 0 ? { currentValue } : {},
|
|
5110
|
+
...Array.isArray(data?.effects) ? { effects: normalizeProviderEffects(data) } : {},
|
|
5111
|
+
...typeof data?.error === "string" ? { error: data.error } : {}
|
|
5112
|
+
};
|
|
5113
|
+
}
|
|
5114
|
+
function normalizeControlInvokeResult(data) {
|
|
5115
|
+
const currentValue = isScalarControlValue(data?.currentValue) ? data.currentValue : isScalarControlValue(data?.value) ? data.value : void 0;
|
|
5116
|
+
return {
|
|
5117
|
+
ok: data?.ok === true || data?.success === true,
|
|
5118
|
+
...currentValue !== void 0 ? { currentValue } : {},
|
|
5119
|
+
...Array.isArray(data?.effects) ? { effects: normalizeProviderEffects(data) } : {},
|
|
5120
|
+
...typeof data?.error === "string" ? { error: data.error } : {}
|
|
5121
|
+
};
|
|
5122
|
+
}
|
|
5123
|
+
function normalizeControlOptions(options) {
|
|
5124
|
+
return options.map((option) => normalizeControlOption(option)).filter((option) => !!option);
|
|
5125
|
+
}
|
|
5126
|
+
function normalizeControlOption(option) {
|
|
5127
|
+
if (typeof option === "string") {
|
|
5128
|
+
return { value: option, label: option };
|
|
5129
|
+
}
|
|
5130
|
+
if (!option || typeof option !== "object") return null;
|
|
5131
|
+
const record = option;
|
|
5132
|
+
const value = typeof record.value === "string" ? record.value : typeof record.id === "string" ? record.id : null;
|
|
5133
|
+
if (!value) return null;
|
|
5134
|
+
const label = typeof record.label === "string" ? record.label : typeof record.name === "string" ? record.name : value;
|
|
5135
|
+
const normalized = { value, label };
|
|
5136
|
+
if (typeof record.description === "string") normalized.description = record.description;
|
|
5137
|
+
if (typeof record.group === "string") normalized.group = record.group;
|
|
5138
|
+
return normalized;
|
|
5139
|
+
}
|
|
5140
|
+
function isScalarControlValue(value) {
|
|
5141
|
+
return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
5142
|
+
}
|
|
5088
5143
|
function normalizeControlValue(value) {
|
|
5089
5144
|
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
5090
5145
|
return value;
|
|
@@ -7076,50 +7131,6 @@ function isCdpConnected(cdpManagers, key) {
|
|
|
7076
7131
|
}
|
|
7077
7132
|
return false;
|
|
7078
7133
|
}
|
|
7079
|
-
function buildFallbackControls(providerControls, serverModel, serverMode, acpConfigOptions, acpModes) {
|
|
7080
|
-
if (providerControls && providerControls.length > 0) return providerControls;
|
|
7081
|
-
const controls = [];
|
|
7082
|
-
const isAcp = !!(acpConfigOptions || acpModes);
|
|
7083
|
-
const modelFromAcp = acpConfigOptions?.find((c) => c.category === "model");
|
|
7084
|
-
if (!isAcp || modelFromAcp) {
|
|
7085
|
-
controls.push({
|
|
7086
|
-
id: "model",
|
|
7087
|
-
type: "select",
|
|
7088
|
-
label: "Model",
|
|
7089
|
-
icon: "\u{1F916}",
|
|
7090
|
-
placement: "bar",
|
|
7091
|
-
dynamic: !modelFromAcp,
|
|
7092
|
-
listScript: "listModels",
|
|
7093
|
-
setScript: "setModel",
|
|
7094
|
-
readFrom: "model",
|
|
7095
|
-
...modelFromAcp && {
|
|
7096
|
-
options: modelFromAcp.options.map((o) => ({ value: o.value, label: o.name || o.value }))
|
|
7097
|
-
}
|
|
7098
|
-
});
|
|
7099
|
-
}
|
|
7100
|
-
const modeFromAcp = acpModes && acpModes.length > 0;
|
|
7101
|
-
const thoughtFromAcp = !modeFromAcp && acpConfigOptions?.find((c) => c.category !== "model");
|
|
7102
|
-
if (!isAcp || modeFromAcp || thoughtFromAcp) {
|
|
7103
|
-
controls.push({
|
|
7104
|
-
id: "mode",
|
|
7105
|
-
type: thoughtFromAcp ? "cycle" : "select",
|
|
7106
|
-
label: thoughtFromAcp ? "Thinking" : "Mode",
|
|
7107
|
-
icon: thoughtFromAcp ? "\u{1F9E0}" : "\u26A1",
|
|
7108
|
-
placement: "bar",
|
|
7109
|
-
dynamic: !modeFromAcp && !thoughtFromAcp,
|
|
7110
|
-
listScript: "listModes",
|
|
7111
|
-
setScript: thoughtFromAcp ? "setThinkingLevel" : "setMode",
|
|
7112
|
-
readFrom: "mode",
|
|
7113
|
-
...modeFromAcp && {
|
|
7114
|
-
options: acpModes.map((m) => ({ value: m.id, label: m.name || m.id }))
|
|
7115
|
-
},
|
|
7116
|
-
...thoughtFromAcp && {
|
|
7117
|
-
options: thoughtFromAcp.options.map((o) => ({ value: o.value, label: o.name || o.value }))
|
|
7118
|
-
}
|
|
7119
|
-
});
|
|
7120
|
-
}
|
|
7121
|
-
return controls;
|
|
7122
|
-
}
|
|
7123
7134
|
var IDE_SESSION_CAPABILITIES = [
|
|
7124
7135
|
"read_chat",
|
|
7125
7136
|
"send_message",
|
|
@@ -7188,11 +7199,7 @@ function buildIdeWorkspaceSession(state, cdpManagers, options) {
|
|
|
7188
7199
|
currentAutoApprove: state.currentAutoApprove,
|
|
7189
7200
|
...includeSessionControls && {
|
|
7190
7201
|
controlValues: state.controlValues,
|
|
7191
|
-
providerControls:
|
|
7192
|
-
state.providerControls,
|
|
7193
|
-
state.currentModel,
|
|
7194
|
-
state.currentPlan
|
|
7195
|
-
)
|
|
7202
|
+
providerControls: state.providerControls
|
|
7196
7203
|
},
|
|
7197
7204
|
errorMessage: state.errorMessage,
|
|
7198
7205
|
errorReason: state.errorReason,
|
|
@@ -7222,11 +7229,7 @@ function buildExtensionAgentSession(parent, ext, options) {
|
|
|
7222
7229
|
currentPlan: ext.currentPlan,
|
|
7223
7230
|
...includeSessionControls && {
|
|
7224
7231
|
controlValues: ext.controlValues,
|
|
7225
|
-
providerControls:
|
|
7226
|
-
ext.providerControls,
|
|
7227
|
-
ext.currentModel,
|
|
7228
|
-
ext.currentPlan
|
|
7229
|
-
)
|
|
7232
|
+
providerControls: ext.providerControls
|
|
7230
7233
|
},
|
|
7231
7234
|
errorMessage: ext.errorMessage,
|
|
7232
7235
|
errorReason: ext.errorReason,
|
|
@@ -7267,9 +7270,7 @@ function buildCliSession(state, options) {
|
|
|
7267
7270
|
},
|
|
7268
7271
|
...includeSessionControls && {
|
|
7269
7272
|
controlValues: state.controlValues,
|
|
7270
|
-
providerControls:
|
|
7271
|
-
state.providerControls
|
|
7272
|
-
)
|
|
7273
|
+
providerControls: state.providerControls
|
|
7273
7274
|
},
|
|
7274
7275
|
errorMessage: state.errorMessage,
|
|
7275
7276
|
errorReason: state.errorReason,
|
|
@@ -7301,13 +7302,7 @@ function buildAcpSession(state, options) {
|
|
|
7301
7302
|
acpConfigOptions: state.acpConfigOptions,
|
|
7302
7303
|
acpModes: state.acpModes,
|
|
7303
7304
|
controlValues: state.controlValues,
|
|
7304
|
-
providerControls:
|
|
7305
|
-
state.providerControls,
|
|
7306
|
-
state.currentModel,
|
|
7307
|
-
state.currentPlan,
|
|
7308
|
-
state.acpConfigOptions,
|
|
7309
|
-
state.acpModes
|
|
7310
|
-
)
|
|
7305
|
+
providerControls: state.providerControls
|
|
7311
7306
|
},
|
|
7312
7307
|
errorMessage: state.errorMessage,
|
|
7313
7308
|
errorReason: state.errorReason,
|
|
@@ -7390,10 +7385,217 @@ function reconcileIdeRuntimeSessions(instanceManager, sessionRegistry) {
|
|
|
7390
7385
|
// src/commands/handler.ts
|
|
7391
7386
|
init_logger();
|
|
7392
7387
|
|
|
7388
|
+
// src/providers/io-contracts.ts
|
|
7389
|
+
function normalizeInputEnvelope(input) {
|
|
7390
|
+
const normalized = normalizeInputEnvelopePayload(input);
|
|
7391
|
+
const textFallback = normalized.textFallback ?? flattenInputParts(normalized.parts);
|
|
7392
|
+
return {
|
|
7393
|
+
parts: normalized.parts,
|
|
7394
|
+
textFallback,
|
|
7395
|
+
...normalized.metadata ? { metadata: normalized.metadata } : {}
|
|
7396
|
+
};
|
|
7397
|
+
}
|
|
7398
|
+
function normalizeMessageParts(content) {
|
|
7399
|
+
if (typeof content === "string") return [{ type: "text", text: content }];
|
|
7400
|
+
if (!Array.isArray(content)) {
|
|
7401
|
+
if (content && typeof content === "object" && typeof content.text === "string") {
|
|
7402
|
+
return [{ type: "text", text: String(content.text) }];
|
|
7403
|
+
}
|
|
7404
|
+
return [];
|
|
7405
|
+
}
|
|
7406
|
+
const parts = [];
|
|
7407
|
+
for (const raw of content) {
|
|
7408
|
+
if (typeof raw === "string") {
|
|
7409
|
+
parts.push({ type: "text", text: raw });
|
|
7410
|
+
continue;
|
|
7411
|
+
}
|
|
7412
|
+
if (!raw || typeof raw !== "object") continue;
|
|
7413
|
+
const part = normalizeMessagePartObject(raw);
|
|
7414
|
+
if (part) parts.push(part);
|
|
7415
|
+
}
|
|
7416
|
+
return parts;
|
|
7417
|
+
}
|
|
7418
|
+
function flattenMessageParts(parts) {
|
|
7419
|
+
return parts.map((part) => {
|
|
7420
|
+
if (part.type === "text") return part.text;
|
|
7421
|
+
if (part.type === "resource") return part.resource.text || "";
|
|
7422
|
+
return "";
|
|
7423
|
+
}).filter((value) => value.length > 0).join("\n");
|
|
7424
|
+
}
|
|
7425
|
+
function normalizeInputEnvelopePayload(input) {
|
|
7426
|
+
if (typeof input === "string") {
|
|
7427
|
+
return { parts: [{ type: "text", text: input }], textFallback: input };
|
|
7428
|
+
}
|
|
7429
|
+
if (!input || typeof input !== "object") {
|
|
7430
|
+
return { parts: [], textFallback: "" };
|
|
7431
|
+
}
|
|
7432
|
+
const record = input;
|
|
7433
|
+
const nestedInput = record.input;
|
|
7434
|
+
if (nestedInput && typeof nestedInput === "object") {
|
|
7435
|
+
const nested = nestedInput;
|
|
7436
|
+
return {
|
|
7437
|
+
parts: normalizeInputParts(nested.parts ?? nested.prompt),
|
|
7438
|
+
textFallback: typeof nested.textFallback === "string" ? nested.textFallback : void 0,
|
|
7439
|
+
metadata: normalizeInputMetadata(nested.metadata)
|
|
7440
|
+
};
|
|
7441
|
+
}
|
|
7442
|
+
const directText = typeof record.text === "string" ? record.text : typeof record.message === "string" ? record.message : void 0;
|
|
7443
|
+
if (directText !== void 0) {
|
|
7444
|
+
return { parts: [{ type: "text", text: directText }], textFallback: directText };
|
|
7445
|
+
}
|
|
7446
|
+
const directParts = normalizeInputParts(record.parts ?? record.prompt);
|
|
7447
|
+
return {
|
|
7448
|
+
parts: directParts,
|
|
7449
|
+
textFallback: typeof record.textFallback === "string" ? record.textFallback : void 0,
|
|
7450
|
+
metadata: normalizeInputMetadata(record.metadata)
|
|
7451
|
+
};
|
|
7452
|
+
}
|
|
7453
|
+
function normalizeInputMetadata(value) {
|
|
7454
|
+
if (!value || typeof value !== "object") return void 0;
|
|
7455
|
+
const record = value;
|
|
7456
|
+
const metadata = {};
|
|
7457
|
+
if (record.source === "dashboard" || record.source === "shortcut_api" || record.source === "provider_script" || record.source === "session_replay") {
|
|
7458
|
+
metadata.source = record.source;
|
|
7459
|
+
}
|
|
7460
|
+
if (typeof record.clientTimestamp === "number" && Number.isFinite(record.clientTimestamp)) {
|
|
7461
|
+
metadata.clientTimestamp = record.clientTimestamp;
|
|
7462
|
+
}
|
|
7463
|
+
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
7464
|
+
}
|
|
7465
|
+
function normalizeInputParts(value) {
|
|
7466
|
+
if (!Array.isArray(value)) return [];
|
|
7467
|
+
const parts = [];
|
|
7468
|
+
for (const raw of value) {
|
|
7469
|
+
if (typeof raw === "string") {
|
|
7470
|
+
parts.push({ type: "text", text: raw });
|
|
7471
|
+
continue;
|
|
7472
|
+
}
|
|
7473
|
+
if (!raw || typeof raw !== "object") continue;
|
|
7474
|
+
const part = normalizeInputPartObject(raw);
|
|
7475
|
+
if (part) parts.push(part);
|
|
7476
|
+
}
|
|
7477
|
+
return parts;
|
|
7478
|
+
}
|
|
7479
|
+
function normalizeInputPartObject(raw) {
|
|
7480
|
+
const type = raw.type;
|
|
7481
|
+
if (type === "text" && typeof raw.text === "string") {
|
|
7482
|
+
return { type, text: raw.text };
|
|
7483
|
+
}
|
|
7484
|
+
if (type === "image" && typeof raw.mimeType === "string") {
|
|
7485
|
+
return {
|
|
7486
|
+
type,
|
|
7487
|
+
mimeType: raw.mimeType,
|
|
7488
|
+
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
7489
|
+
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
7490
|
+
...typeof raw.alt === "string" ? { alt: raw.alt } : {}
|
|
7491
|
+
};
|
|
7492
|
+
}
|
|
7493
|
+
if (type === "audio" && typeof raw.mimeType === "string") {
|
|
7494
|
+
return {
|
|
7495
|
+
type,
|
|
7496
|
+
mimeType: raw.mimeType,
|
|
7497
|
+
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
7498
|
+
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
7499
|
+
...typeof raw.transcript === "string" ? { transcript: raw.transcript } : {}
|
|
7500
|
+
};
|
|
7501
|
+
}
|
|
7502
|
+
if (type === "video" && typeof raw.mimeType === "string") {
|
|
7503
|
+
return {
|
|
7504
|
+
type,
|
|
7505
|
+
mimeType: raw.mimeType,
|
|
7506
|
+
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
7507
|
+
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
7508
|
+
...typeof raw.posterUri === "string" ? { posterUri: raw.posterUri } : {}
|
|
7509
|
+
};
|
|
7510
|
+
}
|
|
7511
|
+
if (type === "resource" && typeof raw.uri === "string") {
|
|
7512
|
+
return {
|
|
7513
|
+
type,
|
|
7514
|
+
uri: raw.uri,
|
|
7515
|
+
...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
|
|
7516
|
+
...typeof raw.name === "string" ? { name: raw.name } : {},
|
|
7517
|
+
...typeof raw.text === "string" ? { text: raw.text } : {},
|
|
7518
|
+
...typeof raw.data === "string" ? { data: raw.data } : {}
|
|
7519
|
+
};
|
|
7520
|
+
}
|
|
7521
|
+
if (type === "resource_link" && typeof raw.uri === "string") {
|
|
7522
|
+
return {
|
|
7523
|
+
type: "resource",
|
|
7524
|
+
uri: raw.uri,
|
|
7525
|
+
...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
|
|
7526
|
+
...typeof raw.name === "string" ? { name: raw.name } : {}
|
|
7527
|
+
};
|
|
7528
|
+
}
|
|
7529
|
+
return null;
|
|
7530
|
+
}
|
|
7531
|
+
function normalizeMessagePartObject(raw) {
|
|
7532
|
+
const type = raw.type;
|
|
7533
|
+
if (type === "text" && typeof raw.text === "string") {
|
|
7534
|
+
return { type, text: raw.text };
|
|
7535
|
+
}
|
|
7536
|
+
if (type === "image" && typeof raw.mimeType === "string") {
|
|
7537
|
+
return {
|
|
7538
|
+
type,
|
|
7539
|
+
mimeType: raw.mimeType,
|
|
7540
|
+
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
7541
|
+
...typeof raw.data === "string" ? { data: raw.data } : {}
|
|
7542
|
+
};
|
|
7543
|
+
}
|
|
7544
|
+
if (type === "audio" && typeof raw.mimeType === "string") {
|
|
7545
|
+
return {
|
|
7546
|
+
type,
|
|
7547
|
+
mimeType: raw.mimeType,
|
|
7548
|
+
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
7549
|
+
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
7550
|
+
...typeof raw.transcript === "string" ? { transcript: raw.transcript } : {}
|
|
7551
|
+
};
|
|
7552
|
+
}
|
|
7553
|
+
if (type === "video" && typeof raw.mimeType === "string") {
|
|
7554
|
+
return {
|
|
7555
|
+
type,
|
|
7556
|
+
mimeType: raw.mimeType,
|
|
7557
|
+
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
7558
|
+
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
7559
|
+
...typeof raw.posterUri === "string" ? { posterUri: raw.posterUri } : {}
|
|
7560
|
+
};
|
|
7561
|
+
}
|
|
7562
|
+
if (type === "resource_link" && typeof raw.uri === "string" && typeof raw.name === "string") {
|
|
7563
|
+
return {
|
|
7564
|
+
type,
|
|
7565
|
+
uri: raw.uri,
|
|
7566
|
+
name: raw.name,
|
|
7567
|
+
...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
|
|
7568
|
+
...typeof raw.size === "number" ? { size: raw.size } : {}
|
|
7569
|
+
};
|
|
7570
|
+
}
|
|
7571
|
+
if (type === "resource" && raw.resource && typeof raw.resource === "object") {
|
|
7572
|
+
const resource = raw.resource;
|
|
7573
|
+
if (typeof resource.uri !== "string") return null;
|
|
7574
|
+
return {
|
|
7575
|
+
type,
|
|
7576
|
+
resource: {
|
|
7577
|
+
uri: resource.uri,
|
|
7578
|
+
...typeof resource.mimeType === "string" || resource.mimeType === null ? { mimeType: resource.mimeType } : {},
|
|
7579
|
+
...typeof resource.text === "string" ? { text: resource.text } : {},
|
|
7580
|
+
...typeof resource.blob === "string" ? { blob: resource.blob } : {}
|
|
7581
|
+
}
|
|
7582
|
+
};
|
|
7583
|
+
}
|
|
7584
|
+
return null;
|
|
7585
|
+
}
|
|
7586
|
+
function flattenInputParts(parts) {
|
|
7587
|
+
return parts.map((part) => {
|
|
7588
|
+
if (part.type === "text") return part.text;
|
|
7589
|
+
if (part.type === "audio") return part.transcript || "";
|
|
7590
|
+
if (part.type === "resource") return part.text || "";
|
|
7591
|
+
return "";
|
|
7592
|
+
}).filter((value) => value.length > 0).join("\n");
|
|
7593
|
+
}
|
|
7594
|
+
|
|
7393
7595
|
// src/providers/contracts.ts
|
|
7394
7596
|
function flattenContent(content) {
|
|
7395
7597
|
if (typeof content === "string") return content;
|
|
7396
|
-
return
|
|
7598
|
+
return flattenMessageParts(normalizeMessageParts(content));
|
|
7397
7599
|
}
|
|
7398
7600
|
|
|
7399
7601
|
// src/commands/chat-commands.ts
|
|
@@ -7582,6 +7784,9 @@ function buildRecentSendKey(h, args, provider, text) {
|
|
|
7582
7784
|
const target = args?.targetSessionId || args?.agentType || h.currentSession?.providerType || h.currentProviderType || h.currentManagerKey || "unknown";
|
|
7583
7785
|
return `${transport}:${target}:${text.trim()}`;
|
|
7584
7786
|
}
|
|
7787
|
+
function getSendChatInputEnvelope(args) {
|
|
7788
|
+
return normalizeInputEnvelope(args?.input ? { input: args.input } : args);
|
|
7789
|
+
}
|
|
7585
7790
|
function getHistorySessionId(h, args) {
|
|
7586
7791
|
const explicit = typeof args?.historySessionId === "string" ? args.historySessionId.trim() : "";
|
|
7587
7792
|
if (explicit) return explicit;
|
|
@@ -7986,7 +8191,8 @@ async function handleReadChat(h, args) {
|
|
|
7986
8191
|
return buildReadChatCommandResult({ messages: [], status: "idle" }, args);
|
|
7987
8192
|
}
|
|
7988
8193
|
async function handleSendChat(h, args) {
|
|
7989
|
-
const
|
|
8194
|
+
const input = getSendChatInputEnvelope(args);
|
|
8195
|
+
const text = input.textFallback;
|
|
7990
8196
|
if (!text) return { success: false, error: "text required" };
|
|
7991
8197
|
const _log = (msg) => LOG.debug("Command", `[send_chat] ${msg}`);
|
|
7992
8198
|
const provider = h.getProvider(args?.agentType);
|
|
@@ -8926,6 +9132,21 @@ function listDirectoryEntriesSafe(dirPath) {
|
|
|
8926
9132
|
}
|
|
8927
9133
|
return files;
|
|
8928
9134
|
}
|
|
9135
|
+
function listWindowsDriveEntries(excludePath) {
|
|
9136
|
+
const excluded = typeof excludePath === "string" ? excludePath.toLowerCase() : "";
|
|
9137
|
+
const drives = [];
|
|
9138
|
+
for (let code = 65; code <= 90; code += 1) {
|
|
9139
|
+
const letter = String.fromCharCode(code);
|
|
9140
|
+
const root = `${letter}:\\`;
|
|
9141
|
+
try {
|
|
9142
|
+
if (!fs4.existsSync(root)) continue;
|
|
9143
|
+
if (excluded && root.toLowerCase() === excluded) continue;
|
|
9144
|
+
drives.push({ name: `${letter}:`, type: "directory", path: root });
|
|
9145
|
+
} catch {
|
|
9146
|
+
}
|
|
9147
|
+
}
|
|
9148
|
+
return drives;
|
|
9149
|
+
}
|
|
8929
9150
|
async function handleFileRead(h, args) {
|
|
8930
9151
|
try {
|
|
8931
9152
|
const filePath = resolveSafePath(args?.path);
|
|
@@ -8958,12 +9179,51 @@ async function handleFileListBrowse(h, args) {
|
|
|
8958
9179
|
try {
|
|
8959
9180
|
const dirPath = resolveSafePath(args?.path || ".");
|
|
8960
9181
|
const files = listDirectoryEntriesSafe(dirPath).filter((entry) => entry.type === "directory").sort((a, b) => a.name.localeCompare(b.name));
|
|
9182
|
+
if (process.platform === "win32" && /^[A-Za-z]:\\?$/.test(dirPath)) {
|
|
9183
|
+
const driveEntries = listWindowsDriveEntries(dirPath);
|
|
9184
|
+
return {
|
|
9185
|
+
success: true,
|
|
9186
|
+
files: [...driveEntries, ...files],
|
|
9187
|
+
path: dirPath
|
|
9188
|
+
};
|
|
9189
|
+
}
|
|
8961
9190
|
return { success: true, files, path: dirPath };
|
|
8962
9191
|
} catch (e) {
|
|
8963
9192
|
return { success: false, error: e.message };
|
|
8964
9193
|
}
|
|
8965
9194
|
}
|
|
8966
9195
|
|
|
9196
|
+
// src/providers/cli-script-results.ts
|
|
9197
|
+
function parseCliScriptResult(result) {
|
|
9198
|
+
if (typeof result === "string") {
|
|
9199
|
+
try {
|
|
9200
|
+
const parsed = JSON.parse(result);
|
|
9201
|
+
if (parsed && typeof parsed === "object" && parsed.success === false) {
|
|
9202
|
+
return { success: false, payload: parsed };
|
|
9203
|
+
}
|
|
9204
|
+
return { success: true, payload: parsed };
|
|
9205
|
+
} catch {
|
|
9206
|
+
return { success: true, payload: { result } };
|
|
9207
|
+
}
|
|
9208
|
+
}
|
|
9209
|
+
if (result && typeof result === "object" && "success" in result && result.success === false) {
|
|
9210
|
+
return { success: false, payload: result };
|
|
9211
|
+
}
|
|
9212
|
+
return { success: true, payload: result };
|
|
9213
|
+
}
|
|
9214
|
+
function getCliScriptCommand(payload) {
|
|
9215
|
+
if (!payload || typeof payload !== "object") return null;
|
|
9216
|
+
if (typeof payload.sendMessage === "string" && payload.sendMessage.trim()) {
|
|
9217
|
+
return { type: "send_message", text: payload.sendMessage.trim() };
|
|
9218
|
+
}
|
|
9219
|
+
const command = payload.command;
|
|
9220
|
+
if (!command || typeof command !== "object") return null;
|
|
9221
|
+
if (command.type !== "send_message" && command.type !== "pty_write") return null;
|
|
9222
|
+
const text = typeof command.text === "string" ? command.text.trim() : typeof command.message === "string" ? command.message.trim() : "";
|
|
9223
|
+
if (!text) return null;
|
|
9224
|
+
return { type: command.type, text };
|
|
9225
|
+
}
|
|
9226
|
+
|
|
8967
9227
|
// src/commands/stream-commands.ts
|
|
8968
9228
|
init_logger();
|
|
8969
9229
|
function getCliPresentationMode(h, targetSessionId) {
|
|
@@ -9054,34 +9314,19 @@ function normalizeProviderScriptArgs(args) {
|
|
|
9054
9314
|
}
|
|
9055
9315
|
return normalizedArgs;
|
|
9056
9316
|
}
|
|
9057
|
-
function
|
|
9058
|
-
if (typeof
|
|
9059
|
-
|
|
9060
|
-
|
|
9061
|
-
if (parsed && typeof parsed === "object" && parsed.success === false) {
|
|
9062
|
-
return { success: false, payload: parsed };
|
|
9063
|
-
}
|
|
9064
|
-
return { success: true, payload: parsed };
|
|
9065
|
-
} catch {
|
|
9066
|
-
return { success: true, payload: { result } };
|
|
9067
|
-
}
|
|
9317
|
+
function buildControlScriptResult(scriptName, payload) {
|
|
9318
|
+
if (!payload || typeof payload !== "object") return {};
|
|
9319
|
+
if (Array.isArray(payload.options) || Array.isArray(payload.models) || Array.isArray(payload.modes)) {
|
|
9320
|
+
return { controlResult: normalizeControlListResult(payload) };
|
|
9068
9321
|
}
|
|
9069
|
-
|
|
9070
|
-
|
|
9322
|
+
const looksLikeValueMutation = /^set|^change/i.test(scriptName) || payload.currentValue !== void 0 || payload.value !== void 0;
|
|
9323
|
+
if (looksLikeValueMutation) {
|
|
9324
|
+
return { controlResult: normalizeControlSetResult(payload) };
|
|
9071
9325
|
}
|
|
9072
|
-
|
|
9073
|
-
}
|
|
9074
|
-
function getCliScriptCommand(payload) {
|
|
9075
|
-
if (!payload || typeof payload !== "object") return null;
|
|
9076
|
-
if (typeof payload.sendMessage === "string" && payload.sendMessage.trim()) {
|
|
9077
|
-
return { type: "send_message", text: payload.sendMessage.trim() };
|
|
9326
|
+
if (payload.ok !== void 0 || payload.success !== void 0 || Array.isArray(payload.effects)) {
|
|
9327
|
+
return { controlResult: normalizeControlInvokeResult(payload) };
|
|
9078
9328
|
}
|
|
9079
|
-
|
|
9080
|
-
if (!command || typeof command !== "object") return null;
|
|
9081
|
-
if (command.type !== "send_message" && command.type !== "pty_write") return null;
|
|
9082
|
-
const text = typeof command.text === "string" ? command.text.trim() : typeof command.message === "string" ? command.message.trim() : "";
|
|
9083
|
-
if (!text) return null;
|
|
9084
|
-
return { type: command.type, text };
|
|
9329
|
+
return {};
|
|
9085
9330
|
}
|
|
9086
9331
|
function applyProviderPatch(h, args, payload) {
|
|
9087
9332
|
if (!payload || typeof payload !== "object") return;
|
|
@@ -9115,7 +9360,7 @@ async function executeProviderScript(h, args, scriptName) {
|
|
|
9115
9360
|
}
|
|
9116
9361
|
try {
|
|
9117
9362
|
const raw = await adapter.invokeScript(actualScriptName, normalizedArgs);
|
|
9118
|
-
const parsed =
|
|
9363
|
+
const parsed = parseCliScriptResult(raw);
|
|
9119
9364
|
if (!parsed.success) {
|
|
9120
9365
|
return { success: false, ...parsed.payload || {} };
|
|
9121
9366
|
}
|
|
@@ -9126,7 +9371,11 @@ async function executeProviderScript(h, args, scriptName) {
|
|
|
9126
9371
|
adapter.writeRaw(cliCommand.text + "\r");
|
|
9127
9372
|
}
|
|
9128
9373
|
applyProviderPatch(h, args, parsed.payload);
|
|
9129
|
-
return {
|
|
9374
|
+
return {
|
|
9375
|
+
success: true,
|
|
9376
|
+
...parsed.payload && typeof parsed.payload === "object" ? parsed.payload : { result: parsed.payload },
|
|
9377
|
+
...buildControlScriptResult(scriptName, parsed.payload)
|
|
9378
|
+
};
|
|
9130
9379
|
} catch (e) {
|
|
9131
9380
|
return { success: false, error: `Script execution failed: ${e.message}` };
|
|
9132
9381
|
}
|
|
@@ -9189,7 +9438,7 @@ async function executeProviderScript(h, args, scriptName) {
|
|
|
9189
9438
|
if (parsed && typeof parsed === "object" && parsed.success === false) {
|
|
9190
9439
|
return { success: false, ...parsed };
|
|
9191
9440
|
}
|
|
9192
|
-
return { success: true, ...parsed };
|
|
9441
|
+
return { success: true, ...parsed, ...buildControlScriptResult(scriptName, parsed) };
|
|
9193
9442
|
} catch {
|
|
9194
9443
|
return { success: true, result };
|
|
9195
9444
|
}
|
|
@@ -9200,9 +9449,6 @@ async function executeProviderScript(h, args, scriptName) {
|
|
|
9200
9449
|
return { success: false, error: `Script execution failed: ${e.message}` };
|
|
9201
9450
|
}
|
|
9202
9451
|
}
|
|
9203
|
-
async function handleExtensionScript(h, args, scriptName) {
|
|
9204
|
-
return executeProviderScript(h, args, scriptName);
|
|
9205
|
-
}
|
|
9206
9452
|
async function handleProviderScript(h, args) {
|
|
9207
9453
|
const scriptName = typeof args?.scriptName === "string" ? args.scriptName.trim() : "";
|
|
9208
9454
|
if (!scriptName) return { success: false, error: "scriptName is required" };
|
|
@@ -9645,11 +9891,7 @@ var DaemonCommandHandler = class {
|
|
|
9645
9891
|
"focus_session",
|
|
9646
9892
|
"pty_input",
|
|
9647
9893
|
"pty_resize",
|
|
9648
|
-
"invoke_provider_script"
|
|
9649
|
-
"list_extension_models",
|
|
9650
|
-
"set_extension_model",
|
|
9651
|
-
"list_extension_modes",
|
|
9652
|
-
"set_extension_mode"
|
|
9894
|
+
"invoke_provider_script"
|
|
9653
9895
|
]);
|
|
9654
9896
|
if (this._currentRoute.sessionLookupFailed && sessionScopedCommands.has(cmd)) {
|
|
9655
9897
|
const result2 = {
|
|
@@ -9761,17 +10003,9 @@ var DaemonCommandHandler = class {
|
|
|
9761
10003
|
return handleGetIdeExtensions(this, args);
|
|
9762
10004
|
case "set_ide_extension":
|
|
9763
10005
|
return handleSetIdeExtension(this, args);
|
|
9764
|
-
// ───
|
|
10006
|
+
// ─── Provider control execution (stream-commands.ts) ──────────
|
|
9765
10007
|
case "invoke_provider_script":
|
|
9766
10008
|
return handleProviderScript(this, args);
|
|
9767
|
-
case "list_extension_models":
|
|
9768
|
-
return handleExtensionScript(this, args, "listModels");
|
|
9769
|
-
case "set_extension_model":
|
|
9770
|
-
return handleExtensionScript(this, args, "setModel");
|
|
9771
|
-
case "list_extension_modes":
|
|
9772
|
-
return handleExtensionScript(this, args, "listModes");
|
|
9773
|
-
case "set_extension_mode":
|
|
9774
|
-
return handleExtensionScript(this, args, "setMode");
|
|
9775
10009
|
// ─── Provider Auto-Fix / Clone (DevServer proxy) ──────────
|
|
9776
10010
|
case "provider_auto_fix":
|
|
9777
10011
|
return this.proxyDevServerPost(args, "auto-implement");
|
|
@@ -9889,18 +10123,18 @@ var DaemonCommandHandler = class {
|
|
|
9889
10123
|
// src/commands/cli-manager.ts
|
|
9890
10124
|
init_provider_cli_adapter();
|
|
9891
10125
|
import * as os12 from "os";
|
|
9892
|
-
import * as
|
|
10126
|
+
import * as path13 from "path";
|
|
9893
10127
|
import * as crypto4 from "crypto";
|
|
9894
10128
|
import chalk from "chalk";
|
|
9895
10129
|
init_config();
|
|
9896
10130
|
|
|
9897
10131
|
// src/providers/cli-provider-instance.ts
|
|
9898
|
-
init_provider_cli_adapter();
|
|
9899
10132
|
import * as os11 from "os";
|
|
9900
10133
|
import * as path11 from "path";
|
|
9901
10134
|
import * as crypto3 from "crypto";
|
|
9902
10135
|
import * as fs5 from "fs";
|
|
9903
10136
|
import { createRequire } from "module";
|
|
10137
|
+
init_provider_cli_adapter();
|
|
9904
10138
|
init_logger();
|
|
9905
10139
|
var CachedDatabaseSync = null;
|
|
9906
10140
|
function getDatabaseSync() {
|
|
@@ -9913,6 +10147,23 @@ function getDatabaseSync() {
|
|
|
9913
10147
|
}
|
|
9914
10148
|
return CachedDatabaseSync;
|
|
9915
10149
|
}
|
|
10150
|
+
function getForcedNewSessionScriptName(provider, launchMode) {
|
|
10151
|
+
if (!provider || launchMode !== "new") return null;
|
|
10152
|
+
const resume = provider.resume;
|
|
10153
|
+
if (!resume?.supported) return null;
|
|
10154
|
+
if (Array.isArray(resume.newSessionArgs) && resume.newSessionArgs.length > 0) return null;
|
|
10155
|
+
const controls = Array.isArray(provider.controls) ? provider.controls : [];
|
|
10156
|
+
for (const control of controls) {
|
|
10157
|
+
if (control?.type !== "action") continue;
|
|
10158
|
+
const invokeScript = typeof control?.invokeScript === "string" ? control.invokeScript.trim() : "";
|
|
10159
|
+
if (!invokeScript) continue;
|
|
10160
|
+
const controlId = typeof control?.id === "string" ? control.id.trim() : "";
|
|
10161
|
+
if (controlId === "new_session" || /^new.?session$/i.test(invokeScript)) {
|
|
10162
|
+
return invokeScript;
|
|
10163
|
+
}
|
|
10164
|
+
}
|
|
10165
|
+
return null;
|
|
10166
|
+
}
|
|
9916
10167
|
var CliProviderInstance = class {
|
|
9917
10168
|
constructor(provider, workingDir, cliArgs = [], instanceId, transportFactory, options) {
|
|
9918
10169
|
this.provider = provider;
|
|
@@ -9971,6 +10222,7 @@ var CliProviderInstance = class {
|
|
|
9971
10222
|
this.detectStatusTransition();
|
|
9972
10223
|
});
|
|
9973
10224
|
await this.adapter.spawn();
|
|
10225
|
+
await this.enforceFreshSessionLaunchIfNeeded();
|
|
9974
10226
|
this.maybeAppendRuntimeRecoveryMessage(this.adapter.getRuntimeMetadata());
|
|
9975
10227
|
if (this.providerSessionId) {
|
|
9976
10228
|
this.historyWriter.compactHistorySession(this.type, this.providerSessionId);
|
|
@@ -10162,10 +10414,13 @@ var CliProviderInstance = class {
|
|
|
10162
10414
|
});
|
|
10163
10415
|
}
|
|
10164
10416
|
onEvent(event, data) {
|
|
10165
|
-
if (event === "send_message"
|
|
10166
|
-
|
|
10167
|
-
|
|
10168
|
-
|
|
10417
|
+
if (event === "send_message") {
|
|
10418
|
+
const input = normalizeInputEnvelope(data);
|
|
10419
|
+
if (input.textFallback) {
|
|
10420
|
+
void this.adapter.sendMessage(input.textFallback).catch((e) => {
|
|
10421
|
+
LOG.warn("CLI", `[${this.type}] send_message failed: ${e?.message || e}`);
|
|
10422
|
+
});
|
|
10423
|
+
}
|
|
10169
10424
|
} else if (event === "server_connected" && data?.serverConn) {
|
|
10170
10425
|
this.adapter.setServerConn(data.serverConn);
|
|
10171
10426
|
} else if (event === "resolve_action" && data) {
|
|
@@ -10183,6 +10438,23 @@ var CliProviderInstance = class {
|
|
|
10183
10438
|
}
|
|
10184
10439
|
completedDebounceTimer = null;
|
|
10185
10440
|
completedDebouncePending = null;
|
|
10441
|
+
async enforceFreshSessionLaunchIfNeeded() {
|
|
10442
|
+
const scriptName = getForcedNewSessionScriptName(this.provider, this.launchMode);
|
|
10443
|
+
if (!scriptName) return;
|
|
10444
|
+
LOG.info("CLI", `[${this.type}] forcing fresh session launch via script: ${scriptName}`);
|
|
10445
|
+
const raw = await this.adapter.invokeScript(scriptName, {});
|
|
10446
|
+
const parsed = parseCliScriptResult(raw);
|
|
10447
|
+
if (!parsed.success) {
|
|
10448
|
+
throw new Error(parsed.payload?.error || `Failed to invoke fresh-session script '${scriptName}'`);
|
|
10449
|
+
}
|
|
10450
|
+
const cliCommand = getCliScriptCommand(parsed.payload);
|
|
10451
|
+
if (cliCommand?.type === "send_message" && cliCommand.text) {
|
|
10452
|
+
await this.adapter.sendMessage(cliCommand.text);
|
|
10453
|
+
} else if (cliCommand?.type === "pty_write" && cliCommand.text) {
|
|
10454
|
+
this.adapter.writeRaw(cliCommand.text + "\r");
|
|
10455
|
+
}
|
|
10456
|
+
this.applyProviderResponse(parsed.payload, { phase: "immediate" });
|
|
10457
|
+
}
|
|
10186
10458
|
detectStatusTransition() {
|
|
10187
10459
|
const now = Date.now();
|
|
10188
10460
|
const adapterStatus = this.adapter.getStatus();
|
|
@@ -10566,6 +10838,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
10566
10838
|
};
|
|
10567
10839
|
|
|
10568
10840
|
// src/providers/acp-provider-instance.ts
|
|
10841
|
+
import * as path12 from "path";
|
|
10569
10842
|
import { Readable, Writable } from "stream";
|
|
10570
10843
|
import { spawn } from "child_process";
|
|
10571
10844
|
import {
|
|
@@ -10575,6 +10848,101 @@ import {
|
|
|
10575
10848
|
PROTOCOL_VERSION
|
|
10576
10849
|
} from "@agentclientprotocol/sdk";
|
|
10577
10850
|
init_logger();
|
|
10851
|
+
function getPromptCapabilityFlags(agentCapabilities) {
|
|
10852
|
+
const prompt = agentCapabilities?.promptCapabilities || {};
|
|
10853
|
+
return {
|
|
10854
|
+
image: prompt.image === true,
|
|
10855
|
+
audio: prompt.audio === true,
|
|
10856
|
+
embeddedContext: prompt.embeddedContext === true
|
|
10857
|
+
};
|
|
10858
|
+
}
|
|
10859
|
+
function getResourceNameFromUri(uri, fallback) {
|
|
10860
|
+
try {
|
|
10861
|
+
if (uri.startsWith("file://")) {
|
|
10862
|
+
return path12.basename(new URL(uri).pathname) || fallback;
|
|
10863
|
+
}
|
|
10864
|
+
return path12.basename(uri) || fallback;
|
|
10865
|
+
} catch {
|
|
10866
|
+
return fallback;
|
|
10867
|
+
}
|
|
10868
|
+
}
|
|
10869
|
+
function inputPartToResourceLink(part, fallbackName) {
|
|
10870
|
+
if (!part.uri) return null;
|
|
10871
|
+
return {
|
|
10872
|
+
type: "resource_link",
|
|
10873
|
+
uri: part.uri,
|
|
10874
|
+
name: getResourceNameFromUri(part.uri, fallbackName),
|
|
10875
|
+
...part.mimeType ? { mimeType: part.mimeType } : {}
|
|
10876
|
+
};
|
|
10877
|
+
}
|
|
10878
|
+
function appendPromptText(promptParts, text) {
|
|
10879
|
+
const normalized = typeof text === "string" ? text.trim() : "";
|
|
10880
|
+
if (!normalized) return;
|
|
10881
|
+
const last = promptParts[promptParts.length - 1];
|
|
10882
|
+
if (last?.type === "text" && last.text === normalized) return;
|
|
10883
|
+
promptParts.push({ type: "text", text: normalized });
|
|
10884
|
+
}
|
|
10885
|
+
function buildAcpPromptParts(input, agentCapabilities) {
|
|
10886
|
+
const caps = getPromptCapabilityFlags(agentCapabilities);
|
|
10887
|
+
const promptParts = [];
|
|
10888
|
+
for (const part of input.parts) {
|
|
10889
|
+
if (part.type === "text") {
|
|
10890
|
+
promptParts.push({ type: "text", text: part.text });
|
|
10891
|
+
continue;
|
|
10892
|
+
}
|
|
10893
|
+
if (part.type === "image") {
|
|
10894
|
+
if (caps.image && part.data) {
|
|
10895
|
+
promptParts.push({
|
|
10896
|
+
type: "image",
|
|
10897
|
+
data: part.data,
|
|
10898
|
+
mimeType: part.mimeType,
|
|
10899
|
+
...part.uri ? { uri: part.uri } : {}
|
|
10900
|
+
});
|
|
10901
|
+
continue;
|
|
10902
|
+
}
|
|
10903
|
+
const fallback = inputPartToResourceLink(part, "image");
|
|
10904
|
+
if (fallback) promptParts.push(fallback);
|
|
10905
|
+
appendPromptText(promptParts, part.alt || (!part.uri ? `Attached image (${part.mimeType})` : void 0));
|
|
10906
|
+
continue;
|
|
10907
|
+
}
|
|
10908
|
+
if (part.type === "audio") {
|
|
10909
|
+
if (caps.audio && part.data) {
|
|
10910
|
+
promptParts.push({
|
|
10911
|
+
type: "audio",
|
|
10912
|
+
data: part.data,
|
|
10913
|
+
mimeType: part.mimeType
|
|
10914
|
+
});
|
|
10915
|
+
continue;
|
|
10916
|
+
}
|
|
10917
|
+
const fallback = inputPartToResourceLink(part, "audio");
|
|
10918
|
+
if (fallback) promptParts.push(fallback);
|
|
10919
|
+
appendPromptText(promptParts, part.transcript || (!part.uri ? `Attached audio (${part.mimeType})` : void 0));
|
|
10920
|
+
continue;
|
|
10921
|
+
}
|
|
10922
|
+
if (part.type === "resource") {
|
|
10923
|
+
if (caps.embeddedContext && (part.text || part.data)) {
|
|
10924
|
+
promptParts.push({
|
|
10925
|
+
type: "resource",
|
|
10926
|
+
resource: part.text ? { uri: part.uri, text: part.text, mimeType: part.mimeType ?? null } : { uri: part.uri, blob: part.data || "", mimeType: part.mimeType ?? null }
|
|
10927
|
+
});
|
|
10928
|
+
continue;
|
|
10929
|
+
}
|
|
10930
|
+
const fallback = inputPartToResourceLink(part, part.name || "resource");
|
|
10931
|
+
if (fallback) promptParts.push(fallback);
|
|
10932
|
+
appendPromptText(promptParts, part.text || (!part.uri && part.name ? part.name : void 0));
|
|
10933
|
+
continue;
|
|
10934
|
+
}
|
|
10935
|
+
if (part.type === "video") {
|
|
10936
|
+
const fallback = inputPartToResourceLink(part, "video");
|
|
10937
|
+
if (fallback) promptParts.push(fallback);
|
|
10938
|
+
appendPromptText(promptParts, !part.uri ? `Attached video (${part.mimeType})` : void 0);
|
|
10939
|
+
}
|
|
10940
|
+
}
|
|
10941
|
+
if (!promptParts.some((part) => part.type === "text") && input.textFallback) {
|
|
10942
|
+
promptParts.unshift({ type: "text", text: input.textFallback });
|
|
10943
|
+
}
|
|
10944
|
+
return promptParts;
|
|
10945
|
+
}
|
|
10578
10946
|
var AcpProviderInstance = class {
|
|
10579
10947
|
constructor(provider, workingDir, cliArgs = []) {
|
|
10580
10948
|
this.cliArgs = cliArgs;
|
|
@@ -10703,8 +11071,10 @@ var AcpProviderInstance = class {
|
|
|
10703
11071
|
};
|
|
10704
11072
|
}
|
|
10705
11073
|
onEvent(event, data) {
|
|
10706
|
-
if (event === "send_message"
|
|
10707
|
-
|
|
11074
|
+
if (event === "send_message") {
|
|
11075
|
+
const input = normalizeInputEnvelope(data);
|
|
11076
|
+
const promptParts = buildAcpPromptParts(input, this.agentCapabilities);
|
|
11077
|
+
this.sendPrompt(input.textFallback, promptParts.length > 0 ? promptParts : void 0).catch(
|
|
10708
11078
|
(e) => this.log.warn(`[${this.type}] sendPrompt error: ${e?.message}`)
|
|
10709
11079
|
);
|
|
10710
11080
|
} else if (event === "resolve_action") {
|
|
@@ -11129,18 +11499,34 @@ var AcpProviderInstance = class {
|
|
|
11129
11499
|
this.log.warn(`[${this.type}] Cannot send prompt: no active connection/session`);
|
|
11130
11500
|
return;
|
|
11131
11501
|
}
|
|
11132
|
-
|
|
11133
|
-
|
|
11134
|
-
|
|
11135
|
-
|
|
11136
|
-
|
|
11137
|
-
|
|
11138
|
-
|
|
11139
|
-
|
|
11140
|
-
|
|
11141
|
-
|
|
11142
|
-
|
|
11143
|
-
|
|
11502
|
+
const promptParts = contentBlocks && contentBlocks.length > 0 ? contentBlocks.map((b) => {
|
|
11503
|
+
if (b.type === "text") return { type: "text", text: b.text };
|
|
11504
|
+
if (b.type === "image") {
|
|
11505
|
+
return {
|
|
11506
|
+
type: "image",
|
|
11507
|
+
data: b.data,
|
|
11508
|
+
mimeType: b.mimeType,
|
|
11509
|
+
...b.uri ? { uri: b.uri } : {}
|
|
11510
|
+
};
|
|
11511
|
+
}
|
|
11512
|
+
if (b.type === "audio") {
|
|
11513
|
+
return {
|
|
11514
|
+
type: "audio",
|
|
11515
|
+
data: b.data,
|
|
11516
|
+
mimeType: b.mimeType
|
|
11517
|
+
};
|
|
11518
|
+
}
|
|
11519
|
+
if (b.type === "resource_link") {
|
|
11520
|
+
return {
|
|
11521
|
+
type: "resource_link",
|
|
11522
|
+
uri: b.uri,
|
|
11523
|
+
name: b.name,
|
|
11524
|
+
...b.mimeType ? { mimeType: b.mimeType } : {}
|
|
11525
|
+
};
|
|
11526
|
+
}
|
|
11527
|
+
if (b.type === "resource") return { type: "resource", resource: b.resource };
|
|
11528
|
+
return { type: "text", text: flattenContent([b]) };
|
|
11529
|
+
}) : [{ type: "text", text }];
|
|
11144
11530
|
this.messages.push({
|
|
11145
11531
|
role: "user",
|
|
11146
11532
|
content: contentBlocks && contentBlocks.length > 0 ? contentBlocks : text,
|
|
@@ -11204,6 +11590,13 @@ var AcpProviderInstance = class {
|
|
|
11204
11590
|
this.partialBlocks.push({
|
|
11205
11591
|
type: "image",
|
|
11206
11592
|
data: content.data,
|
|
11593
|
+
mimeType: content.mimeType,
|
|
11594
|
+
...content.uri ? { uri: content.uri } : {}
|
|
11595
|
+
});
|
|
11596
|
+
} else if (content.type === "audio") {
|
|
11597
|
+
this.partialBlocks.push({
|
|
11598
|
+
type: "audio",
|
|
11599
|
+
data: content.data,
|
|
11207
11600
|
mimeType: content.mimeType
|
|
11208
11601
|
});
|
|
11209
11602
|
} else if (content.type === "resource_link") {
|
|
@@ -11595,7 +11988,7 @@ function resolveCliSessionBinding(provider, normalizedType, cliArgs, requestedRe
|
|
|
11595
11988
|
};
|
|
11596
11989
|
}
|
|
11597
11990
|
if (!supportsExplicitSessionStart(resume)) {
|
|
11598
|
-
return { cliArgs: baseArgs, launchMode: "
|
|
11991
|
+
return { cliArgs: baseArgs, launchMode: "new" };
|
|
11599
11992
|
}
|
|
11600
11993
|
const providerSessionId = crypto4.randomUUID();
|
|
11601
11994
|
const newSessionArgs = expandResumeArgs(resume.newSessionArgs, providerSessionId);
|
|
@@ -11743,7 +12136,7 @@ var DaemonCliManager = class {
|
|
|
11743
12136
|
async startSession(cliType, workingDir, cliArgs, initialModel, options) {
|
|
11744
12137
|
const trimmed = (workingDir || "").trim();
|
|
11745
12138
|
if (!trimmed) throw new Error("working directory required");
|
|
11746
|
-
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os12.homedir()) :
|
|
12139
|
+
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os12.homedir()) : path13.resolve(trimmed);
|
|
11747
12140
|
const normalizedType = this.providerLoader.resolveAlias(cliType);
|
|
11748
12141
|
const provider = this.providerLoader.getByAlias(cliType);
|
|
11749
12142
|
const key = crypto4.randomUUID();
|
|
@@ -11791,7 +12184,8 @@ ${installInfo}`
|
|
|
11791
12184
|
instanceManager2.removeInstance(key);
|
|
11792
12185
|
},
|
|
11793
12186
|
sendMessage: async (text) => {
|
|
11794
|
-
|
|
12187
|
+
const input = normalizeInputEnvelope(text);
|
|
12188
|
+
acpInstance.onEvent("send_message", { input });
|
|
11795
12189
|
},
|
|
11796
12190
|
getStatus: () => {
|
|
11797
12191
|
const state = acpInstance.getState();
|
|
@@ -12200,7 +12594,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
12200
12594
|
if (!found) throw new Error(`CLI agent not running: ${agentType}`);
|
|
12201
12595
|
const { adapter, key } = found;
|
|
12202
12596
|
if (action === "send_chat") {
|
|
12203
|
-
const
|
|
12597
|
+
const input = normalizeInputEnvelope(args?.input ? { input: args.input } : args);
|
|
12598
|
+
const message = input.textFallback;
|
|
12204
12599
|
if (!message) throw new Error("message required for send_chat");
|
|
12205
12600
|
await adapter.sendMessage(message);
|
|
12206
12601
|
return { success: true, status: "generating" };
|
|
@@ -12222,14 +12617,144 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
12222
12617
|
import { execSync as execSync4, spawn as spawn2 } from "child_process";
|
|
12223
12618
|
import * as net from "net";
|
|
12224
12619
|
import * as os14 from "os";
|
|
12225
|
-
import * as
|
|
12620
|
+
import * as path15 from "path";
|
|
12226
12621
|
|
|
12227
12622
|
// src/providers/provider-loader.ts
|
|
12228
12623
|
import * as fs6 from "fs";
|
|
12229
|
-
import * as
|
|
12624
|
+
import * as path14 from "path";
|
|
12230
12625
|
import * as os13 from "os";
|
|
12231
12626
|
import * as chokidar from "chokidar";
|
|
12232
12627
|
init_logger();
|
|
12628
|
+
|
|
12629
|
+
// src/providers/provider-schema.ts
|
|
12630
|
+
var KNOWN_PROVIDER_FIELDS = /* @__PURE__ */ new Set([
|
|
12631
|
+
"type",
|
|
12632
|
+
"name",
|
|
12633
|
+
"category",
|
|
12634
|
+
"aliases",
|
|
12635
|
+
"cdpPorts",
|
|
12636
|
+
"targetFilter",
|
|
12637
|
+
"cli",
|
|
12638
|
+
"icon",
|
|
12639
|
+
"displayName",
|
|
12640
|
+
"install",
|
|
12641
|
+
"versionCommand",
|
|
12642
|
+
"testedVersions",
|
|
12643
|
+
"processNames",
|
|
12644
|
+
"launch",
|
|
12645
|
+
"paths",
|
|
12646
|
+
"extensionId",
|
|
12647
|
+
"extensionIdPattern",
|
|
12648
|
+
"extensionIdPattern_flags",
|
|
12649
|
+
"compatibility",
|
|
12650
|
+
"defaultScriptDir",
|
|
12651
|
+
"binary",
|
|
12652
|
+
"spawn",
|
|
12653
|
+
"approvalKeys",
|
|
12654
|
+
"patterns",
|
|
12655
|
+
"cleanOutput",
|
|
12656
|
+
"resume",
|
|
12657
|
+
"sessionProbe",
|
|
12658
|
+
"approvalPositiveHints",
|
|
12659
|
+
"scripts",
|
|
12660
|
+
"vscodeCommands",
|
|
12661
|
+
"inputMethod",
|
|
12662
|
+
"inputSelector",
|
|
12663
|
+
"webviewMatchText",
|
|
12664
|
+
"os",
|
|
12665
|
+
"versions",
|
|
12666
|
+
"overrides",
|
|
12667
|
+
"settings",
|
|
12668
|
+
"controls",
|
|
12669
|
+
"staticConfigOptions",
|
|
12670
|
+
"spawnArgBuilder",
|
|
12671
|
+
"auth",
|
|
12672
|
+
"contractVersion",
|
|
12673
|
+
"capabilities",
|
|
12674
|
+
"providerVersion",
|
|
12675
|
+
"status",
|
|
12676
|
+
"details",
|
|
12677
|
+
"sendDelayMs",
|
|
12678
|
+
"sendKey",
|
|
12679
|
+
"submitStrategy",
|
|
12680
|
+
"disableUpstream"
|
|
12681
|
+
]);
|
|
12682
|
+
var VALUE_CONTROL_TYPES = /* @__PURE__ */ new Set(["select", "toggle", "cycle", "slider"]);
|
|
12683
|
+
function validateProviderDefinition(raw) {
|
|
12684
|
+
const errors = [];
|
|
12685
|
+
const warnings = [];
|
|
12686
|
+
if (!raw || typeof raw !== "object") {
|
|
12687
|
+
return { errors: ["Provider definition must be an object"], warnings };
|
|
12688
|
+
}
|
|
12689
|
+
const provider = raw;
|
|
12690
|
+
if (!provider.type) errors.push("Missing required field: type");
|
|
12691
|
+
if (!provider.name) errors.push("Missing required field: name");
|
|
12692
|
+
if (!provider.category) {
|
|
12693
|
+
errors.push("Missing required field: category");
|
|
12694
|
+
} else if (!["ide", "extension", "cli", "acp"].includes(String(provider.category))) {
|
|
12695
|
+
errors.push(`Invalid category: ${String(provider.category)}`);
|
|
12696
|
+
}
|
|
12697
|
+
for (const key of Object.keys(provider)) {
|
|
12698
|
+
if (!KNOWN_PROVIDER_FIELDS.has(key)) {
|
|
12699
|
+
warnings.push(`Unknown provider field: ${key}`);
|
|
12700
|
+
}
|
|
12701
|
+
}
|
|
12702
|
+
const category = provider.category;
|
|
12703
|
+
if (category === "cli" || category === "acp") {
|
|
12704
|
+
const spawn4 = provider.spawn;
|
|
12705
|
+
const command = spawn4 && typeof spawn4 === "object" ? spawn4.command : void 0;
|
|
12706
|
+
if (!spawn4 || typeof spawn4 !== "object") {
|
|
12707
|
+
errors.push(`${String(category).toUpperCase()}/CLI providers must have spawn config`);
|
|
12708
|
+
} else if (typeof command !== "string" || !command.trim()) {
|
|
12709
|
+
errors.push("spawn.command is required");
|
|
12710
|
+
}
|
|
12711
|
+
}
|
|
12712
|
+
if ((category === "ide" || category === "extension") && provider.cdpPorts !== void 0) {
|
|
12713
|
+
if (!Array.isArray(provider.cdpPorts) || provider.cdpPorts.length === 0) {
|
|
12714
|
+
warnings.push("IDE/Extension providers should have cdpPorts");
|
|
12715
|
+
}
|
|
12716
|
+
}
|
|
12717
|
+
if (category === "extension" && !provider.extensionId) {
|
|
12718
|
+
warnings.push("Extension providers should have extensionId");
|
|
12719
|
+
}
|
|
12720
|
+
for (const control of Array.isArray(provider.controls) ? provider.controls : []) {
|
|
12721
|
+
validateControl(control, errors);
|
|
12722
|
+
}
|
|
12723
|
+
return { errors, warnings };
|
|
12724
|
+
}
|
|
12725
|
+
function validateControl(control, errors) {
|
|
12726
|
+
if (!control || typeof control !== "object") {
|
|
12727
|
+
errors.push("controls: each control must be an object");
|
|
12728
|
+
return;
|
|
12729
|
+
}
|
|
12730
|
+
const id = typeof control.id === "string" && control.id.trim() ? control.id.trim() : "unknown";
|
|
12731
|
+
const prefix = `controls.${id}`;
|
|
12732
|
+
if (!control.id || !String(control.id).trim()) errors.push(`${prefix}: id is required`);
|
|
12733
|
+
if (!control.type) errors.push(`${prefix}: type is required`);
|
|
12734
|
+
if (!control.label || !String(control.label).trim()) errors.push(`${prefix}: label is required`);
|
|
12735
|
+
if (!control.placement) errors.push(`${prefix}: placement is required`);
|
|
12736
|
+
if (control.dynamic && !control.listScript) {
|
|
12737
|
+
errors.push(`${prefix}: dynamic controls require listScript`);
|
|
12738
|
+
}
|
|
12739
|
+
if (VALUE_CONTROL_TYPES.has(control.type) && !control.setScript) {
|
|
12740
|
+
errors.push(`${prefix}: ${control.type} controls require setScript`);
|
|
12741
|
+
}
|
|
12742
|
+
if (control.type === "action" && !control.invokeScript) {
|
|
12743
|
+
errors.push(`${prefix}: action controls require invokeScript`);
|
|
12744
|
+
}
|
|
12745
|
+
if (control.type === "slider") {
|
|
12746
|
+
if (typeof control.min !== "number" || typeof control.max !== "number") {
|
|
12747
|
+
errors.push(`${prefix}: slider controls require numeric min and max`);
|
|
12748
|
+
} else if (control.min > control.max) {
|
|
12749
|
+
errors.push(`${prefix}: slider min cannot exceed max`);
|
|
12750
|
+
}
|
|
12751
|
+
}
|
|
12752
|
+
if (control.readFrom !== void 0 && (typeof control.readFrom !== "string" || !control.readFrom.trim())) {
|
|
12753
|
+
errors.push(`${prefix}: readFrom must be a non-empty string when provided`);
|
|
12754
|
+
}
|
|
12755
|
+
}
|
|
12756
|
+
|
|
12757
|
+
// src/providers/provider-loader.ts
|
|
12233
12758
|
var ProviderLoader = class _ProviderLoader {
|
|
12234
12759
|
providers = /* @__PURE__ */ new Map();
|
|
12235
12760
|
providerAvailability = /* @__PURE__ */ new Map();
|
|
@@ -12248,12 +12773,12 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12248
12773
|
static META_FILE = ".meta.json";
|
|
12249
12774
|
constructor(options) {
|
|
12250
12775
|
this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
|
|
12251
|
-
const defaultProvidersDir =
|
|
12776
|
+
const defaultProvidersDir = path14.join(os13.homedir(), ".adhdev", "providers");
|
|
12252
12777
|
if (options?.userDir) {
|
|
12253
12778
|
this.userDir = options.userDir;
|
|
12254
12779
|
this.log(`Config 'providerDir' applied: ${this.userDir}`);
|
|
12255
12780
|
} else {
|
|
12256
|
-
const localRepoPath =
|
|
12781
|
+
const localRepoPath = path14.resolve(__dirname, "../../../../../adhdev-providers");
|
|
12257
12782
|
if (fs6.existsSync(localRepoPath)) {
|
|
12258
12783
|
this.userDir = localRepoPath;
|
|
12259
12784
|
this.log(`Auto-detected local public repository: ${this.userDir} (Dev workspace speedup)`);
|
|
@@ -12262,7 +12787,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12262
12787
|
this.log(`Using default user providers directory: ${this.userDir}`);
|
|
12263
12788
|
}
|
|
12264
12789
|
}
|
|
12265
|
-
this.upstreamDir =
|
|
12790
|
+
this.upstreamDir = path14.join(defaultProvidersDir, ".upstream");
|
|
12266
12791
|
this.disableUpstream = options?.disableUpstream ?? false;
|
|
12267
12792
|
}
|
|
12268
12793
|
log(msg) {
|
|
@@ -12292,7 +12817,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12292
12817
|
* Canonical provider directory shape for a given root.
|
|
12293
12818
|
*/
|
|
12294
12819
|
getProviderDir(root, category, type) {
|
|
12295
|
-
return
|
|
12820
|
+
return path14.join(root, category, type);
|
|
12296
12821
|
}
|
|
12297
12822
|
/**
|
|
12298
12823
|
* Canonical user override directory for a provider.
|
|
@@ -12319,7 +12844,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12319
12844
|
resolveProviderFile(type, ...segments) {
|
|
12320
12845
|
const dir = this.findProviderDirInternal(type);
|
|
12321
12846
|
if (!dir) return null;
|
|
12322
|
-
return
|
|
12847
|
+
return path14.join(dir, ...segments);
|
|
12323
12848
|
}
|
|
12324
12849
|
/**
|
|
12325
12850
|
* Load all providers (3-tier priority)
|
|
@@ -12358,7 +12883,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12358
12883
|
if (!fs6.existsSync(this.upstreamDir)) return false;
|
|
12359
12884
|
try {
|
|
12360
12885
|
return fs6.readdirSync(this.upstreamDir).some(
|
|
12361
|
-
(d) => fs6.statSync(
|
|
12886
|
+
(d) => fs6.statSync(path14.join(this.upstreamDir, d)).isDirectory()
|
|
12362
12887
|
);
|
|
12363
12888
|
} catch {
|
|
12364
12889
|
return false;
|
|
@@ -12673,8 +13198,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12673
13198
|
resolved._resolvedScriptDir = entry.scriptDir;
|
|
12674
13199
|
resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
|
|
12675
13200
|
if (providerDir) {
|
|
12676
|
-
const fullDir =
|
|
12677
|
-
resolved._resolvedScriptsPath = fs6.existsSync(
|
|
13201
|
+
const fullDir = path14.join(providerDir, entry.scriptDir);
|
|
13202
|
+
resolved._resolvedScriptsPath = fs6.existsSync(path14.join(fullDir, "scripts.js")) ? path14.join(fullDir, "scripts.js") : fullDir;
|
|
12678
13203
|
}
|
|
12679
13204
|
matched = true;
|
|
12680
13205
|
}
|
|
@@ -12689,8 +13214,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12689
13214
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
12690
13215
|
resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
|
|
12691
13216
|
if (providerDir) {
|
|
12692
|
-
const fullDir =
|
|
12693
|
-
resolved._resolvedScriptsPath = fs6.existsSync(
|
|
13217
|
+
const fullDir = path14.join(providerDir, base.defaultScriptDir);
|
|
13218
|
+
resolved._resolvedScriptsPath = fs6.existsSync(path14.join(fullDir, "scripts.js")) ? path14.join(fullDir, "scripts.js") : fullDir;
|
|
12694
13219
|
}
|
|
12695
13220
|
}
|
|
12696
13221
|
resolved._versionWarning = `Version ${currentVersion} not in compatibility matrix. Using default scripts.`;
|
|
@@ -12707,8 +13232,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12707
13232
|
resolved._resolvedScriptDir = dirOverride;
|
|
12708
13233
|
resolved._resolvedScriptsSource = `versions:${range}`;
|
|
12709
13234
|
if (providerDir) {
|
|
12710
|
-
const fullDir =
|
|
12711
|
-
resolved._resolvedScriptsPath = fs6.existsSync(
|
|
13235
|
+
const fullDir = path14.join(providerDir, dirOverride);
|
|
13236
|
+
resolved._resolvedScriptsPath = fs6.existsSync(path14.join(fullDir, "scripts.js")) ? path14.join(fullDir, "scripts.js") : fullDir;
|
|
12712
13237
|
}
|
|
12713
13238
|
}
|
|
12714
13239
|
} else if (override.scripts) {
|
|
@@ -12724,8 +13249,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12724
13249
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
12725
13250
|
resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
|
|
12726
13251
|
if (providerDir) {
|
|
12727
|
-
const fullDir =
|
|
12728
|
-
resolved._resolvedScriptsPath = fs6.existsSync(
|
|
13252
|
+
const fullDir = path14.join(providerDir, base.defaultScriptDir);
|
|
13253
|
+
resolved._resolvedScriptsPath = fs6.existsSync(path14.join(fullDir, "scripts.js")) ? path14.join(fullDir, "scripts.js") : fullDir;
|
|
12729
13254
|
}
|
|
12730
13255
|
}
|
|
12731
13256
|
}
|
|
@@ -12750,14 +13275,14 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12750
13275
|
this.log(` [loadScriptsFromDir] ${type}: providerDir not found`);
|
|
12751
13276
|
return null;
|
|
12752
13277
|
}
|
|
12753
|
-
const dir =
|
|
13278
|
+
const dir = path14.join(providerDir, scriptDir);
|
|
12754
13279
|
if (!fs6.existsSync(dir)) {
|
|
12755
13280
|
this.log(` [loadScriptsFromDir] ${type}: dir not found: ${dir}`);
|
|
12756
13281
|
return null;
|
|
12757
13282
|
}
|
|
12758
13283
|
const cached = this.scriptsCache.get(dir);
|
|
12759
13284
|
if (cached) return cached;
|
|
12760
|
-
const scriptsJs =
|
|
13285
|
+
const scriptsJs = path14.join(dir, "scripts.js");
|
|
12761
13286
|
if (fs6.existsSync(scriptsJs)) {
|
|
12762
13287
|
try {
|
|
12763
13288
|
delete __require.cache[__require.resolve(scriptsJs)];
|
|
@@ -12799,7 +13324,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12799
13324
|
return;
|
|
12800
13325
|
}
|
|
12801
13326
|
if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
|
|
12802
|
-
this.log(`File changed: ${
|
|
13327
|
+
this.log(`File changed: ${path14.basename(filePath)}, reloading...`);
|
|
12803
13328
|
this.reload();
|
|
12804
13329
|
}
|
|
12805
13330
|
};
|
|
@@ -12854,7 +13379,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12854
13379
|
}
|
|
12855
13380
|
const https = __require("https");
|
|
12856
13381
|
const { execSync: execSync7 } = __require("child_process");
|
|
12857
|
-
const metaPath =
|
|
13382
|
+
const metaPath = path14.join(this.upstreamDir, _ProviderLoader.META_FILE);
|
|
12858
13383
|
let prevEtag = "";
|
|
12859
13384
|
let prevTimestamp = 0;
|
|
12860
13385
|
try {
|
|
@@ -12914,17 +13439,17 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12914
13439
|
return { updated: false };
|
|
12915
13440
|
}
|
|
12916
13441
|
this.log("Downloading latest providers from GitHub...");
|
|
12917
|
-
const tmpTar =
|
|
12918
|
-
const tmpExtract =
|
|
13442
|
+
const tmpTar = path14.join(os13.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
|
|
13443
|
+
const tmpExtract = path14.join(os13.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
|
|
12919
13444
|
await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
|
|
12920
13445
|
fs6.mkdirSync(tmpExtract, { recursive: true });
|
|
12921
13446
|
execSync7(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
|
|
12922
13447
|
const extracted = fs6.readdirSync(tmpExtract);
|
|
12923
13448
|
const rootDir = extracted.find(
|
|
12924
|
-
(d) => fs6.statSync(
|
|
13449
|
+
(d) => fs6.statSync(path14.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
|
|
12925
13450
|
);
|
|
12926
13451
|
if (!rootDir) throw new Error("Unexpected tarball structure");
|
|
12927
|
-
const sourceDir =
|
|
13452
|
+
const sourceDir = path14.join(tmpExtract, rootDir);
|
|
12928
13453
|
const backupDir = this.upstreamDir + ".bak";
|
|
12929
13454
|
if (fs6.existsSync(this.upstreamDir)) {
|
|
12930
13455
|
if (fs6.existsSync(backupDir)) fs6.rmSync(backupDir, { recursive: true, force: true });
|
|
@@ -12999,8 +13524,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12999
13524
|
copyDirRecursive(src, dest) {
|
|
13000
13525
|
fs6.mkdirSync(dest, { recursive: true });
|
|
13001
13526
|
for (const entry of fs6.readdirSync(src, { withFileTypes: true })) {
|
|
13002
|
-
const srcPath =
|
|
13003
|
-
const destPath =
|
|
13527
|
+
const srcPath = path14.join(src, entry.name);
|
|
13528
|
+
const destPath = path14.join(dest, entry.name);
|
|
13004
13529
|
if (entry.isDirectory()) {
|
|
13005
13530
|
this.copyDirRecursive(srcPath, destPath);
|
|
13006
13531
|
} else {
|
|
@@ -13011,7 +13536,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
13011
13536
|
/** .meta.json save */
|
|
13012
13537
|
writeMeta(metaPath, etag, timestamp) {
|
|
13013
13538
|
try {
|
|
13014
|
-
fs6.mkdirSync(
|
|
13539
|
+
fs6.mkdirSync(path14.dirname(metaPath), { recursive: true });
|
|
13015
13540
|
fs6.writeFileSync(metaPath, JSON.stringify({
|
|
13016
13541
|
etag,
|
|
13017
13542
|
timestamp,
|
|
@@ -13028,7 +13553,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
13028
13553
|
const scan = (d) => {
|
|
13029
13554
|
try {
|
|
13030
13555
|
for (const entry of fs6.readdirSync(d, { withFileTypes: true })) {
|
|
13031
|
-
if (entry.isDirectory()) scan(
|
|
13556
|
+
if (entry.isDirectory()) scan(path14.join(d, entry.name));
|
|
13032
13557
|
else if (entry.name === "provider.json") count++;
|
|
13033
13558
|
}
|
|
13034
13559
|
} catch {
|
|
@@ -13213,17 +13738,17 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
13213
13738
|
for (const root of searchRoots) {
|
|
13214
13739
|
if (!fs6.existsSync(root)) continue;
|
|
13215
13740
|
const candidate = this.getProviderDir(root, cat, type);
|
|
13216
|
-
if (fs6.existsSync(
|
|
13217
|
-
const catDir =
|
|
13741
|
+
if (fs6.existsSync(path14.join(candidate, "provider.json"))) return candidate;
|
|
13742
|
+
const catDir = path14.join(root, cat);
|
|
13218
13743
|
if (fs6.existsSync(catDir)) {
|
|
13219
13744
|
try {
|
|
13220
13745
|
for (const entry of fs6.readdirSync(catDir, { withFileTypes: true })) {
|
|
13221
13746
|
if (!entry.isDirectory()) continue;
|
|
13222
|
-
const jsonPath =
|
|
13747
|
+
const jsonPath = path14.join(catDir, entry.name, "provider.json");
|
|
13223
13748
|
if (fs6.existsSync(jsonPath)) {
|
|
13224
13749
|
try {
|
|
13225
13750
|
const data = JSON.parse(fs6.readFileSync(jsonPath, "utf-8"));
|
|
13226
|
-
if (data.type === type) return
|
|
13751
|
+
if (data.type === type) return path14.join(catDir, entry.name);
|
|
13227
13752
|
} catch {
|
|
13228
13753
|
}
|
|
13229
13754
|
}
|
|
@@ -13240,7 +13765,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
13240
13765
|
* (template substitution is NOT applied here — scripts.js handles that)
|
|
13241
13766
|
*/
|
|
13242
13767
|
buildScriptWrappersFromDir(dir) {
|
|
13243
|
-
const scriptsJs =
|
|
13768
|
+
const scriptsJs = path14.join(dir, "scripts.js");
|
|
13244
13769
|
if (fs6.existsSync(scriptsJs)) {
|
|
13245
13770
|
try {
|
|
13246
13771
|
delete __require.cache[__require.resolve(scriptsJs)];
|
|
@@ -13254,7 +13779,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
13254
13779
|
for (const file of fs6.readdirSync(dir)) {
|
|
13255
13780
|
if (!file.endsWith(".js")) continue;
|
|
13256
13781
|
const scriptName = toCamel(file.replace(".js", ""));
|
|
13257
|
-
const filePath =
|
|
13782
|
+
const filePath = path14.join(dir, file);
|
|
13258
13783
|
result[scriptName] = (...args) => {
|
|
13259
13784
|
try {
|
|
13260
13785
|
let content = fs6.readFileSync(filePath, "utf-8");
|
|
@@ -13314,24 +13839,28 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
13314
13839
|
}
|
|
13315
13840
|
const hasJson = entries.some((e) => e.name === "provider.json");
|
|
13316
13841
|
if (hasJson) {
|
|
13317
|
-
const jsonPath =
|
|
13842
|
+
const jsonPath = path14.join(d, "provider.json");
|
|
13318
13843
|
try {
|
|
13319
13844
|
const raw = fs6.readFileSync(jsonPath, "utf-8");
|
|
13320
13845
|
const mod = JSON.parse(raw);
|
|
13321
|
-
if (
|
|
13322
|
-
|
|
13846
|
+
if (typeof mod.extensionIdPattern === "string") {
|
|
13847
|
+
const flags = mod.extensionIdPattern_flags || "";
|
|
13848
|
+
mod.extensionIdPattern = new RegExp(mod.extensionIdPattern, flags);
|
|
13849
|
+
}
|
|
13850
|
+
const { extensionIdPattern_flags, extensionIdPattern, ...providerFields } = mod;
|
|
13851
|
+
const normalizedProvider = {
|
|
13852
|
+
...providerFields,
|
|
13853
|
+
...extensionIdPattern instanceof RegExp ? { extensionIdPattern } : {}
|
|
13854
|
+
};
|
|
13855
|
+
const validation = validateProviderDefinition(normalizedProvider);
|
|
13856
|
+
for (const warning of validation.warnings) {
|
|
13857
|
+
this.log(`\u26A0 ${jsonPath}: ${warning}`);
|
|
13858
|
+
}
|
|
13859
|
+
if (validation.errors.length > 0) {
|
|
13860
|
+
this.log(`\u26A0 Invalid provider at ${jsonPath}: ${validation.errors.join("; ")}`);
|
|
13323
13861
|
} else {
|
|
13324
|
-
if (typeof mod.extensionIdPattern === "string") {
|
|
13325
|
-
const flags = mod.extensionIdPattern_flags || "";
|
|
13326
|
-
mod.extensionIdPattern = new RegExp(mod.extensionIdPattern, flags);
|
|
13327
|
-
}
|
|
13328
|
-
const { extensionIdPattern_flags, extensionIdPattern, ...providerFields } = mod;
|
|
13329
|
-
const normalizedProvider = {
|
|
13330
|
-
...providerFields,
|
|
13331
|
-
...extensionIdPattern instanceof RegExp ? { extensionIdPattern } : {}
|
|
13332
|
-
};
|
|
13333
13862
|
const hasCompatibility = Array.isArray(normalizedProvider.compatibility);
|
|
13334
|
-
const scriptsPath =
|
|
13863
|
+
const scriptsPath = path14.join(d, "scripts.js");
|
|
13335
13864
|
if (!hasCompatibility && fs6.existsSync(scriptsPath)) {
|
|
13336
13865
|
try {
|
|
13337
13866
|
delete __require.cache[__require.resolve(scriptsPath)];
|
|
@@ -13357,7 +13886,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
13357
13886
|
if (!entry.isDirectory()) continue;
|
|
13358
13887
|
if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
|
|
13359
13888
|
if (excludeDirs && d === dir && excludeDirs.includes(entry.name)) continue;
|
|
13360
|
-
scan(
|
|
13889
|
+
scan(path14.join(d, entry.name));
|
|
13361
13890
|
}
|
|
13362
13891
|
}
|
|
13363
13892
|
};
|
|
@@ -13615,8 +14144,8 @@ function detectCurrentWorkspace(ideId) {
|
|
|
13615
14144
|
const appNameMap = getMacAppIdentifiers();
|
|
13616
14145
|
const appName = appNameMap[ideId];
|
|
13617
14146
|
if (appName) {
|
|
13618
|
-
const storagePath =
|
|
13619
|
-
process.env.APPDATA ||
|
|
14147
|
+
const storagePath = path15.join(
|
|
14148
|
+
process.env.APPDATA || path15.join(os14.homedir(), "AppData", "Roaming"),
|
|
13620
14149
|
appName,
|
|
13621
14150
|
"storage.json"
|
|
13622
14151
|
);
|
|
@@ -13794,9 +14323,9 @@ init_logger();
|
|
|
13794
14323
|
|
|
13795
14324
|
// src/logging/command-log.ts
|
|
13796
14325
|
import * as fs7 from "fs";
|
|
13797
|
-
import * as
|
|
14326
|
+
import * as path16 from "path";
|
|
13798
14327
|
import * as os15 from "os";
|
|
13799
|
-
var LOG_DIR2 = process.platform === "win32" ?
|
|
14328
|
+
var LOG_DIR2 = process.platform === "win32" ? path16.join(process.env.LOCALAPPDATA || process.env.APPDATA || path16.join(os15.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path16.join(os15.homedir(), "Library", "Logs", "adhdev") : path16.join(os15.homedir(), ".local", "share", "adhdev", "logs");
|
|
13800
14329
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
13801
14330
|
var MAX_DAYS = 7;
|
|
13802
14331
|
try {
|
|
@@ -13834,13 +14363,13 @@ function getDateStr2() {
|
|
|
13834
14363
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
13835
14364
|
}
|
|
13836
14365
|
var currentDate2 = getDateStr2();
|
|
13837
|
-
var currentFile =
|
|
14366
|
+
var currentFile = path16.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
13838
14367
|
var writeCount2 = 0;
|
|
13839
14368
|
function checkRotation() {
|
|
13840
14369
|
const today = getDateStr2();
|
|
13841
14370
|
if (today !== currentDate2) {
|
|
13842
14371
|
currentDate2 = today;
|
|
13843
|
-
currentFile =
|
|
14372
|
+
currentFile = path16.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
13844
14373
|
cleanOldFiles();
|
|
13845
14374
|
}
|
|
13846
14375
|
}
|
|
@@ -13854,7 +14383,7 @@ function cleanOldFiles() {
|
|
|
13854
14383
|
const dateMatch = file.match(/commands-(\d{4}-\d{2}-\d{2})/);
|
|
13855
14384
|
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
13856
14385
|
try {
|
|
13857
|
-
fs7.unlinkSync(
|
|
14386
|
+
fs7.unlinkSync(path16.join(LOG_DIR2, file));
|
|
13858
14387
|
} catch {
|
|
13859
14388
|
}
|
|
13860
14389
|
}
|
|
@@ -14171,13 +14700,13 @@ import { execFileSync } from "child_process";
|
|
|
14171
14700
|
import { spawn as spawn3 } from "child_process";
|
|
14172
14701
|
import * as fs8 from "fs";
|
|
14173
14702
|
import * as os17 from "os";
|
|
14174
|
-
import * as
|
|
14703
|
+
import * as path17 from "path";
|
|
14175
14704
|
var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
|
|
14176
14705
|
function getUpgradeLogPath() {
|
|
14177
14706
|
const home = os17.homedir();
|
|
14178
|
-
const dir =
|
|
14707
|
+
const dir = path17.join(home, ".adhdev");
|
|
14179
14708
|
fs8.mkdirSync(dir, { recursive: true });
|
|
14180
|
-
return
|
|
14709
|
+
return path17.join(dir, "daemon-upgrade.log");
|
|
14181
14710
|
}
|
|
14182
14711
|
function appendUpgradeLog(message) {
|
|
14183
14712
|
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
|
|
@@ -14217,7 +14746,7 @@ async function waitForPidExit(pid, timeoutMs) {
|
|
|
14217
14746
|
}
|
|
14218
14747
|
}
|
|
14219
14748
|
function stopSessionHostProcesses(appName) {
|
|
14220
|
-
const pidFile =
|
|
14749
|
+
const pidFile = path17.join(os17.homedir(), ".adhdev", `${appName}-session-host.pid`);
|
|
14221
14750
|
try {
|
|
14222
14751
|
if (fs8.existsSync(pidFile)) {
|
|
14223
14752
|
const pid = Number.parseInt(fs8.readFileSync(pidFile, "utf8").trim(), 10);
|
|
@@ -14246,7 +14775,7 @@ function stopSessionHostProcesses(appName) {
|
|
|
14246
14775
|
}
|
|
14247
14776
|
}
|
|
14248
14777
|
function removeDaemonPidFile() {
|
|
14249
|
-
const pidFile =
|
|
14778
|
+
const pidFile = path17.join(os17.homedir(), ".adhdev", "daemon.pid");
|
|
14250
14779
|
try {
|
|
14251
14780
|
fs8.unlinkSync(pidFile);
|
|
14252
14781
|
} catch {
|
|
@@ -14257,7 +14786,7 @@ function cleanupStaleGlobalInstallDirs(pkgName) {
|
|
|
14257
14786
|
const npmRoot = execFileSync(getNpmExecutable(), ["root", "-g"], { encoding: "utf8", ...npmExecOpts }).trim();
|
|
14258
14787
|
if (!npmRoot) return;
|
|
14259
14788
|
const npmPrefix = execFileSync(getNpmExecutable(), ["prefix", "-g"], { encoding: "utf8", ...npmExecOpts }).trim();
|
|
14260
|
-
const binDir = process.platform === "win32" ? npmPrefix :
|
|
14789
|
+
const binDir = process.platform === "win32" ? npmPrefix : path17.join(npmPrefix, "bin");
|
|
14261
14790
|
const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
|
|
14262
14791
|
const binNames = /* @__PURE__ */ new Set([packageBaseName]);
|
|
14263
14792
|
if (pkgName === "@adhdev/daemon-standalone") {
|
|
@@ -14265,25 +14794,25 @@ function cleanupStaleGlobalInstallDirs(pkgName) {
|
|
|
14265
14794
|
}
|
|
14266
14795
|
if (pkgName.startsWith("@")) {
|
|
14267
14796
|
const [scope, name] = pkgName.split("/");
|
|
14268
|
-
const scopeDir =
|
|
14797
|
+
const scopeDir = path17.join(npmRoot, scope);
|
|
14269
14798
|
if (!fs8.existsSync(scopeDir)) return;
|
|
14270
14799
|
for (const entry of fs8.readdirSync(scopeDir)) {
|
|
14271
14800
|
if (!entry.startsWith(`.${name}-`)) continue;
|
|
14272
|
-
fs8.rmSync(
|
|
14273
|
-
appendUpgradeLog(`Removed stale scoped staging dir: ${
|
|
14801
|
+
fs8.rmSync(path17.join(scopeDir, entry), { recursive: true, force: true });
|
|
14802
|
+
appendUpgradeLog(`Removed stale scoped staging dir: ${path17.join(scopeDir, entry)}`);
|
|
14274
14803
|
}
|
|
14275
14804
|
} else {
|
|
14276
14805
|
for (const entry of fs8.readdirSync(npmRoot)) {
|
|
14277
14806
|
if (!entry.startsWith(`.${pkgName}-`)) continue;
|
|
14278
|
-
fs8.rmSync(
|
|
14279
|
-
appendUpgradeLog(`Removed stale staging dir: ${
|
|
14807
|
+
fs8.rmSync(path17.join(npmRoot, entry), { recursive: true, force: true });
|
|
14808
|
+
appendUpgradeLog(`Removed stale staging dir: ${path17.join(npmRoot, entry)}`);
|
|
14280
14809
|
}
|
|
14281
14810
|
}
|
|
14282
14811
|
if (fs8.existsSync(binDir)) {
|
|
14283
14812
|
for (const entry of fs8.readdirSync(binDir)) {
|
|
14284
14813
|
if (![...binNames].some((name) => entry.startsWith(`.${name}-`))) continue;
|
|
14285
|
-
fs8.rmSync(
|
|
14286
|
-
appendUpgradeLog(`Removed stale bin staging entry: ${
|
|
14814
|
+
fs8.rmSync(path17.join(binDir, entry), { recursive: true, force: true });
|
|
14815
|
+
appendUpgradeLog(`Removed stale bin staging entry: ${path17.join(binDir, entry)}`);
|
|
14287
14816
|
}
|
|
14288
14817
|
}
|
|
14289
14818
|
}
|
|
@@ -16161,11 +16690,11 @@ var ProviderInstanceManager = class {
|
|
|
16161
16690
|
|
|
16162
16691
|
// src/providers/version-archive.ts
|
|
16163
16692
|
import * as fs10 from "fs";
|
|
16164
|
-
import * as
|
|
16693
|
+
import * as path18 from "path";
|
|
16165
16694
|
import * as os18 from "os";
|
|
16166
16695
|
import { execSync as execSync5 } from "child_process";
|
|
16167
16696
|
import { platform as platform8 } from "os";
|
|
16168
|
-
var ARCHIVE_PATH =
|
|
16697
|
+
var ARCHIVE_PATH = path18.join(os18.homedir(), ".adhdev", "version-history.json");
|
|
16169
16698
|
var MAX_ENTRIES_PER_PROVIDER = 20;
|
|
16170
16699
|
var VersionArchive = class {
|
|
16171
16700
|
history = {};
|
|
@@ -16212,7 +16741,7 @@ var VersionArchive = class {
|
|
|
16212
16741
|
}
|
|
16213
16742
|
save() {
|
|
16214
16743
|
try {
|
|
16215
|
-
fs10.mkdirSync(
|
|
16744
|
+
fs10.mkdirSync(path18.dirname(ARCHIVE_PATH), { recursive: true });
|
|
16216
16745
|
fs10.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
|
|
16217
16746
|
} catch {
|
|
16218
16747
|
}
|
|
@@ -16269,7 +16798,7 @@ function checkPathExists2(paths) {
|
|
|
16269
16798
|
for (const p of paths) {
|
|
16270
16799
|
if (p.includes("*")) {
|
|
16271
16800
|
const home = os18.homedir();
|
|
16272
|
-
const resolved = p.replace(/\*/g, home.split(
|
|
16801
|
+
const resolved = p.replace(/\*/g, home.split(path18.sep).pop() || "");
|
|
16273
16802
|
if (fs10.existsSync(resolved)) return resolved;
|
|
16274
16803
|
} else {
|
|
16275
16804
|
if (fs10.existsSync(p)) return p;
|
|
@@ -16279,7 +16808,7 @@ function checkPathExists2(paths) {
|
|
|
16279
16808
|
}
|
|
16280
16809
|
function getMacAppVersion(appPath) {
|
|
16281
16810
|
if (platform8() !== "darwin" || !appPath.endsWith(".app")) return null;
|
|
16282
|
-
const plistPath =
|
|
16811
|
+
const plistPath = path18.join(appPath, "Contents", "Info.plist");
|
|
16283
16812
|
if (!fs10.existsSync(plistPath)) return null;
|
|
16284
16813
|
const raw = runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
|
|
16285
16814
|
return raw || null;
|
|
@@ -16305,7 +16834,7 @@ async function detectAllVersions(loader, archive) {
|
|
|
16305
16834
|
const cliBin = provider.cli ? findBinary2(provider.cli) : null;
|
|
16306
16835
|
let resolvedBin = cliBin;
|
|
16307
16836
|
if (!resolvedBin && appPath && currentOs === "darwin") {
|
|
16308
|
-
const bundled =
|
|
16837
|
+
const bundled = path18.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
|
|
16309
16838
|
if (provider.cli && fs10.existsSync(bundled)) resolvedBin = bundled;
|
|
16310
16839
|
}
|
|
16311
16840
|
info.installed = !!(appPath || resolvedBin);
|
|
@@ -16346,7 +16875,7 @@ async function detectAllVersions(loader, archive) {
|
|
|
16346
16875
|
// src/daemon/dev-server.ts
|
|
16347
16876
|
import * as http2 from "http";
|
|
16348
16877
|
import * as fs14 from "fs";
|
|
16349
|
-
import * as
|
|
16878
|
+
import * as path22 from "path";
|
|
16350
16879
|
|
|
16351
16880
|
// src/daemon/scaffold-template.ts
|
|
16352
16881
|
function generateFiles(type, name, category, opts = {}) {
|
|
@@ -16683,7 +17212,7 @@ init_logger();
|
|
|
16683
17212
|
// src/daemon/dev-cdp-handlers.ts
|
|
16684
17213
|
init_logger();
|
|
16685
17214
|
import * as fs11 from "fs";
|
|
16686
|
-
import * as
|
|
17215
|
+
import * as path19 from "path";
|
|
16687
17216
|
async function handleCdpEvaluate(ctx, req, res) {
|
|
16688
17217
|
const body = await ctx.readBody(req);
|
|
16689
17218
|
const { expression, timeout, ideType } = body;
|
|
@@ -16861,17 +17390,17 @@ async function handleScriptHints(ctx, type, _req, res) {
|
|
|
16861
17390
|
return;
|
|
16862
17391
|
}
|
|
16863
17392
|
let scriptsPath = "";
|
|
16864
|
-
const directScripts =
|
|
17393
|
+
const directScripts = path19.join(dir, "scripts.js");
|
|
16865
17394
|
if (fs11.existsSync(directScripts)) {
|
|
16866
17395
|
scriptsPath = directScripts;
|
|
16867
17396
|
} else {
|
|
16868
|
-
const scriptsDir =
|
|
17397
|
+
const scriptsDir = path19.join(dir, "scripts");
|
|
16869
17398
|
if (fs11.existsSync(scriptsDir)) {
|
|
16870
17399
|
const versions = fs11.readdirSync(scriptsDir).filter((d) => {
|
|
16871
|
-
return fs11.statSync(
|
|
17400
|
+
return fs11.statSync(path19.join(scriptsDir, d)).isDirectory();
|
|
16872
17401
|
}).sort().reverse();
|
|
16873
17402
|
for (const ver of versions) {
|
|
16874
|
-
const p =
|
|
17403
|
+
const p = path19.join(scriptsDir, ver, "scripts.js");
|
|
16875
17404
|
if (fs11.existsSync(p)) {
|
|
16876
17405
|
scriptsPath = p;
|
|
16877
17406
|
break;
|
|
@@ -17700,7 +18229,7 @@ async function handleDomContext(ctx, type, req, res) {
|
|
|
17700
18229
|
|
|
17701
18230
|
// src/daemon/dev-cli-debug.ts
|
|
17702
18231
|
import * as fs12 from "fs";
|
|
17703
|
-
import * as
|
|
18232
|
+
import * as path20 from "path";
|
|
17704
18233
|
function slugifyFixtureName(value) {
|
|
17705
18234
|
const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
17706
18235
|
return normalized || `fixture-${Date.now()}`;
|
|
@@ -17710,11 +18239,11 @@ function getCliFixtureDir(ctx, type) {
|
|
|
17710
18239
|
if (!providerDir) {
|
|
17711
18240
|
throw new Error(`Provider directory not found for '${type}'`);
|
|
17712
18241
|
}
|
|
17713
|
-
return
|
|
18242
|
+
return path20.join(providerDir, "fixtures");
|
|
17714
18243
|
}
|
|
17715
18244
|
function readCliFixture(ctx, type, name) {
|
|
17716
18245
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
17717
|
-
const filePath =
|
|
18246
|
+
const filePath = path20.join(fixtureDir, `${name}.json`);
|
|
17718
18247
|
if (!fs12.existsSync(filePath)) {
|
|
17719
18248
|
throw new Error(`Fixture not found: ${filePath}`);
|
|
17720
18249
|
}
|
|
@@ -18482,7 +19011,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
18482
19011
|
},
|
|
18483
19012
|
notes: typeof body?.notes === "string" ? body.notes : void 0
|
|
18484
19013
|
};
|
|
18485
|
-
const filePath =
|
|
19014
|
+
const filePath = path20.join(fixtureDir, `${name}.json`);
|
|
18486
19015
|
fs12.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
|
|
18487
19016
|
ctx.json(res, 200, {
|
|
18488
19017
|
saved: true,
|
|
@@ -18506,7 +19035,7 @@ async function handleCliFixtureList(ctx, type, _req, res) {
|
|
|
18506
19035
|
return;
|
|
18507
19036
|
}
|
|
18508
19037
|
const fixtures = fs12.readdirSync(fixtureDir).filter((file) => file.endsWith(".json")).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file) => {
|
|
18509
|
-
const fullPath =
|
|
19038
|
+
const fullPath = path20.join(fixtureDir, file);
|
|
18510
19039
|
try {
|
|
18511
19040
|
const raw = JSON.parse(fs12.readFileSync(fullPath, "utf-8"));
|
|
18512
19041
|
return {
|
|
@@ -18642,7 +19171,7 @@ async function handleCliRaw(ctx, req, res) {
|
|
|
18642
19171
|
|
|
18643
19172
|
// src/daemon/dev-auto-implement.ts
|
|
18644
19173
|
import * as fs13 from "fs";
|
|
18645
|
-
import * as
|
|
19174
|
+
import * as path21 from "path";
|
|
18646
19175
|
import * as os19 from "os";
|
|
18647
19176
|
function getAutoImplPid(ctx) {
|
|
18648
19177
|
const pid = ctx.autoImplProcess?.pid;
|
|
@@ -18699,22 +19228,22 @@ function getLatestScriptVersionDir(scriptsDir) {
|
|
|
18699
19228
|
if (!fs13.existsSync(scriptsDir)) return null;
|
|
18700
19229
|
const versions = fs13.readdirSync(scriptsDir).filter((d) => {
|
|
18701
19230
|
try {
|
|
18702
|
-
return fs13.statSync(
|
|
19231
|
+
return fs13.statSync(path21.join(scriptsDir, d)).isDirectory();
|
|
18703
19232
|
} catch {
|
|
18704
19233
|
return false;
|
|
18705
19234
|
}
|
|
18706
19235
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
18707
19236
|
if (versions.length === 0) return null;
|
|
18708
|
-
return
|
|
19237
|
+
return path21.join(scriptsDir, versions[0]);
|
|
18709
19238
|
}
|
|
18710
19239
|
function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
18711
|
-
const canonicalUserDir =
|
|
18712
|
-
const desiredDir = requestedDir ?
|
|
18713
|
-
const upstreamRoot =
|
|
18714
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
19240
|
+
const canonicalUserDir = path21.resolve(ctx.providerLoader.getUserProviderDir(category, type));
|
|
19241
|
+
const desiredDir = requestedDir ? path21.resolve(requestedDir) : canonicalUserDir;
|
|
19242
|
+
const upstreamRoot = path21.resolve(ctx.providerLoader.getUpstreamDir());
|
|
19243
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path21.sep}`)) {
|
|
18715
19244
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
18716
19245
|
}
|
|
18717
|
-
if (
|
|
19246
|
+
if (path21.basename(desiredDir) !== type) {
|
|
18718
19247
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
18719
19248
|
}
|
|
18720
19249
|
const sourceDir = ctx.findProviderDir(type);
|
|
@@ -18722,11 +19251,11 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
|
18722
19251
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
18723
19252
|
}
|
|
18724
19253
|
if (!fs13.existsSync(desiredDir)) {
|
|
18725
|
-
fs13.mkdirSync(
|
|
19254
|
+
fs13.mkdirSync(path21.dirname(desiredDir), { recursive: true });
|
|
18726
19255
|
fs13.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
18727
19256
|
ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
18728
19257
|
}
|
|
18729
|
-
const providerJson =
|
|
19258
|
+
const providerJson = path21.join(desiredDir, "provider.json");
|
|
18730
19259
|
if (!fs13.existsSync(providerJson)) {
|
|
18731
19260
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
18732
19261
|
}
|
|
@@ -18749,13 +19278,13 @@ function loadAutoImplReferenceScripts(ctx, referenceType) {
|
|
|
18749
19278
|
const refDir = ctx.findProviderDir(referenceType);
|
|
18750
19279
|
if (!refDir || !fs13.existsSync(refDir)) return {};
|
|
18751
19280
|
const referenceScripts = {};
|
|
18752
|
-
const scriptsDir =
|
|
19281
|
+
const scriptsDir = path21.join(refDir, "scripts");
|
|
18753
19282
|
const latestDir = getLatestScriptVersionDir(scriptsDir);
|
|
18754
19283
|
if (!latestDir) return referenceScripts;
|
|
18755
19284
|
for (const file of fs13.readdirSync(latestDir)) {
|
|
18756
19285
|
if (!file.endsWith(".js")) continue;
|
|
18757
19286
|
try {
|
|
18758
|
-
referenceScripts[file] = fs13.readFileSync(
|
|
19287
|
+
referenceScripts[file] = fs13.readFileSync(path21.join(latestDir, file), "utf-8");
|
|
18759
19288
|
} catch {
|
|
18760
19289
|
}
|
|
18761
19290
|
}
|
|
@@ -18863,9 +19392,9 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
18863
19392
|
});
|
|
18864
19393
|
const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
|
|
18865
19394
|
const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
|
|
18866
|
-
const tmpDir =
|
|
19395
|
+
const tmpDir = path21.join(os19.tmpdir(), "adhdev-autoimpl");
|
|
18867
19396
|
if (!fs13.existsSync(tmpDir)) fs13.mkdirSync(tmpDir, { recursive: true });
|
|
18868
|
-
const promptFile =
|
|
19397
|
+
const promptFile = path21.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
|
|
18869
19398
|
fs13.writeFileSync(promptFile, prompt, "utf-8");
|
|
18870
19399
|
ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
|
|
18871
19400
|
const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
|
|
@@ -19302,7 +19831,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
19302
19831
|
setMode: "set_mode.js"
|
|
19303
19832
|
};
|
|
19304
19833
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
19305
|
-
const scriptsDir =
|
|
19834
|
+
const scriptsDir = path21.join(providerDir, "scripts");
|
|
19306
19835
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
19307
19836
|
if (latestScriptsDir) {
|
|
19308
19837
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -19313,7 +19842,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
19313
19842
|
for (const file of fs13.readdirSync(latestScriptsDir)) {
|
|
19314
19843
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
19315
19844
|
try {
|
|
19316
|
-
const content = fs13.readFileSync(
|
|
19845
|
+
const content = fs13.readFileSync(path21.join(latestScriptsDir, file), "utf-8");
|
|
19317
19846
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
19318
19847
|
lines.push("```javascript");
|
|
19319
19848
|
lines.push(content);
|
|
@@ -19330,7 +19859,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
19330
19859
|
lines.push("");
|
|
19331
19860
|
for (const file of refFiles) {
|
|
19332
19861
|
try {
|
|
19333
|
-
const content = fs13.readFileSync(
|
|
19862
|
+
const content = fs13.readFileSync(path21.join(latestScriptsDir, file), "utf-8");
|
|
19334
19863
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
19335
19864
|
lines.push("```javascript");
|
|
19336
19865
|
lines.push(content);
|
|
@@ -19371,10 +19900,10 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
19371
19900
|
lines.push("");
|
|
19372
19901
|
}
|
|
19373
19902
|
}
|
|
19374
|
-
const docsDir =
|
|
19903
|
+
const docsDir = path21.join(providerDir, "../../docs");
|
|
19375
19904
|
const loadGuide = (name) => {
|
|
19376
19905
|
try {
|
|
19377
|
-
const p =
|
|
19906
|
+
const p = path21.join(docsDir, name);
|
|
19378
19907
|
if (fs13.existsSync(p)) return fs13.readFileSync(p, "utf-8");
|
|
19379
19908
|
} catch {
|
|
19380
19909
|
}
|
|
@@ -19611,7 +20140,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
19611
20140
|
parseApproval: "parse_approval.js"
|
|
19612
20141
|
};
|
|
19613
20142
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
19614
|
-
const scriptsDir =
|
|
20143
|
+
const scriptsDir = path21.join(providerDir, "scripts");
|
|
19615
20144
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
19616
20145
|
if (latestScriptsDir) {
|
|
19617
20146
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -19623,7 +20152,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
19623
20152
|
if (!file.endsWith(".js")) continue;
|
|
19624
20153
|
if (!targetFileNames.has(file)) continue;
|
|
19625
20154
|
try {
|
|
19626
|
-
const content = fs13.readFileSync(
|
|
20155
|
+
const content = fs13.readFileSync(path21.join(latestScriptsDir, file), "utf-8");
|
|
19627
20156
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
19628
20157
|
lines.push("```javascript");
|
|
19629
20158
|
lines.push(content);
|
|
@@ -19639,7 +20168,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
19639
20168
|
lines.push("");
|
|
19640
20169
|
for (const file of refFiles) {
|
|
19641
20170
|
try {
|
|
19642
|
-
const content = fs13.readFileSync(
|
|
20171
|
+
const content = fs13.readFileSync(path21.join(latestScriptsDir, file), "utf-8");
|
|
19643
20172
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
19644
20173
|
lines.push("```javascript");
|
|
19645
20174
|
lines.push(content);
|
|
@@ -19672,10 +20201,10 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
19672
20201
|
lines.push("");
|
|
19673
20202
|
}
|
|
19674
20203
|
}
|
|
19675
|
-
const docsDir =
|
|
20204
|
+
const docsDir = path21.join(providerDir, "../../docs");
|
|
19676
20205
|
const loadGuide = (name) => {
|
|
19677
20206
|
try {
|
|
19678
|
-
const p =
|
|
20207
|
+
const p = path21.join(docsDir, name);
|
|
19679
20208
|
if (fs13.existsSync(p)) return fs13.readFileSync(p, "utf-8");
|
|
19680
20209
|
} catch {
|
|
19681
20210
|
}
|
|
@@ -20118,8 +20647,8 @@ var DevServer = class _DevServer {
|
|
|
20118
20647
|
}
|
|
20119
20648
|
getEndpointList() {
|
|
20120
20649
|
return this.routes.map((r) => {
|
|
20121
|
-
const
|
|
20122
|
-
return `${r.method.padEnd(5)} ${
|
|
20650
|
+
const path23 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
|
|
20651
|
+
return `${r.method.padEnd(5)} ${path23}`;
|
|
20123
20652
|
});
|
|
20124
20653
|
}
|
|
20125
20654
|
async start(port = DEV_SERVER_PORT) {
|
|
@@ -20374,12 +20903,12 @@ var DevServer = class _DevServer {
|
|
|
20374
20903
|
// ─── DevConsole SPA ───
|
|
20375
20904
|
getConsoleDistDir() {
|
|
20376
20905
|
const candidates = [
|
|
20377
|
-
|
|
20378
|
-
|
|
20379
|
-
|
|
20906
|
+
path22.resolve(__dirname, "../../web-devconsole/dist"),
|
|
20907
|
+
path22.resolve(__dirname, "../../../web-devconsole/dist"),
|
|
20908
|
+
path22.join(process.cwd(), "packages/web-devconsole/dist")
|
|
20380
20909
|
];
|
|
20381
20910
|
for (const dir of candidates) {
|
|
20382
|
-
if (fs14.existsSync(
|
|
20911
|
+
if (fs14.existsSync(path22.join(dir, "index.html"))) return dir;
|
|
20383
20912
|
}
|
|
20384
20913
|
return null;
|
|
20385
20914
|
}
|
|
@@ -20389,7 +20918,7 @@ var DevServer = class _DevServer {
|
|
|
20389
20918
|
this.json(res, 500, { error: "DevConsole not found. Run: npm run build -w packages/web-devconsole" });
|
|
20390
20919
|
return;
|
|
20391
20920
|
}
|
|
20392
|
-
const htmlPath =
|
|
20921
|
+
const htmlPath = path22.join(distDir, "index.html");
|
|
20393
20922
|
try {
|
|
20394
20923
|
const html = fs14.readFileSync(htmlPath, "utf-8");
|
|
20395
20924
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
@@ -20414,15 +20943,15 @@ var DevServer = class _DevServer {
|
|
|
20414
20943
|
this.json(res, 404, { error: "Not found" });
|
|
20415
20944
|
return;
|
|
20416
20945
|
}
|
|
20417
|
-
const safePath =
|
|
20418
|
-
const filePath =
|
|
20946
|
+
const safePath = path22.normalize(pathname).replace(/^\.\.\//, "");
|
|
20947
|
+
const filePath = path22.join(distDir, safePath);
|
|
20419
20948
|
if (!filePath.startsWith(distDir)) {
|
|
20420
20949
|
this.json(res, 403, { error: "Forbidden" });
|
|
20421
20950
|
return;
|
|
20422
20951
|
}
|
|
20423
20952
|
try {
|
|
20424
20953
|
const content = fs14.readFileSync(filePath);
|
|
20425
|
-
const ext =
|
|
20954
|
+
const ext = path22.extname(filePath);
|
|
20426
20955
|
const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
|
|
20427
20956
|
res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
|
|
20428
20957
|
res.end(content);
|
|
@@ -20535,9 +21064,9 @@ var DevServer = class _DevServer {
|
|
|
20535
21064
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
20536
21065
|
if (entry.isDirectory()) {
|
|
20537
21066
|
files.push({ path: rel, size: 0, type: "dir" });
|
|
20538
|
-
scan(
|
|
21067
|
+
scan(path22.join(d, entry.name), rel);
|
|
20539
21068
|
} else {
|
|
20540
|
-
const stat = fs14.statSync(
|
|
21069
|
+
const stat = fs14.statSync(path22.join(d, entry.name));
|
|
20541
21070
|
files.push({ path: rel, size: stat.size, type: "file" });
|
|
20542
21071
|
}
|
|
20543
21072
|
}
|
|
@@ -20560,7 +21089,7 @@ var DevServer = class _DevServer {
|
|
|
20560
21089
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
20561
21090
|
return;
|
|
20562
21091
|
}
|
|
20563
|
-
const fullPath =
|
|
21092
|
+
const fullPath = path22.resolve(dir, path22.normalize(filePath));
|
|
20564
21093
|
if (!fullPath.startsWith(dir)) {
|
|
20565
21094
|
this.json(res, 403, { error: "Forbidden" });
|
|
20566
21095
|
return;
|
|
@@ -20585,14 +21114,14 @@ var DevServer = class _DevServer {
|
|
|
20585
21114
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
20586
21115
|
return;
|
|
20587
21116
|
}
|
|
20588
|
-
const fullPath =
|
|
21117
|
+
const fullPath = path22.resolve(dir, path22.normalize(filePath));
|
|
20589
21118
|
if (!fullPath.startsWith(dir)) {
|
|
20590
21119
|
this.json(res, 403, { error: "Forbidden" });
|
|
20591
21120
|
return;
|
|
20592
21121
|
}
|
|
20593
21122
|
try {
|
|
20594
21123
|
if (fs14.existsSync(fullPath)) fs14.copyFileSync(fullPath, fullPath + ".bak");
|
|
20595
|
-
fs14.mkdirSync(
|
|
21124
|
+
fs14.mkdirSync(path22.dirname(fullPath), { recursive: true });
|
|
20596
21125
|
fs14.writeFileSync(fullPath, content, "utf-8");
|
|
20597
21126
|
this.log(`File saved: ${fullPath} (${content.length} chars)`);
|
|
20598
21127
|
this.providerLoader.reload();
|
|
@@ -20609,7 +21138,7 @@ var DevServer = class _DevServer {
|
|
|
20609
21138
|
return;
|
|
20610
21139
|
}
|
|
20611
21140
|
for (const name of ["scripts.js", "provider.json"]) {
|
|
20612
|
-
const p =
|
|
21141
|
+
const p = path22.join(dir, name);
|
|
20613
21142
|
if (fs14.existsSync(p)) {
|
|
20614
21143
|
const source = fs14.readFileSync(p, "utf-8");
|
|
20615
21144
|
this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
|
|
@@ -20630,8 +21159,8 @@ var DevServer = class _DevServer {
|
|
|
20630
21159
|
this.json(res, 404, { error: `Provider not found: ${type}` });
|
|
20631
21160
|
return;
|
|
20632
21161
|
}
|
|
20633
|
-
const target = fs14.existsSync(
|
|
20634
|
-
const targetPath =
|
|
21162
|
+
const target = fs14.existsSync(path22.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
|
|
21163
|
+
const targetPath = path22.join(dir, target);
|
|
20635
21164
|
try {
|
|
20636
21165
|
if (fs14.existsSync(targetPath)) fs14.copyFileSync(targetPath, targetPath + ".bak");
|
|
20637
21166
|
fs14.writeFileSync(targetPath, source, "utf-8");
|
|
@@ -20659,22 +21188,9 @@ var DevServer = class _DevServer {
|
|
|
20659
21188
|
const warnings = [];
|
|
20660
21189
|
try {
|
|
20661
21190
|
const config = typeof content === "string" ? JSON.parse(content) : content;
|
|
20662
|
-
|
|
20663
|
-
|
|
20664
|
-
|
|
20665
|
-
else if (!["ide", "extension", "cli", "acp"].includes(config.category)) errors.push(`Invalid category: ${config.category}`);
|
|
20666
|
-
if (config.category === "ide" || config.category === "extension") {
|
|
20667
|
-
if (!config.cdpPorts || !Array.isArray(config.cdpPorts) || config.cdpPorts.length === 0)
|
|
20668
|
-
warnings.push("IDE/Extension providers should have cdpPorts");
|
|
20669
|
-
if (config.category === "extension" && !config.extensionId)
|
|
20670
|
-
warnings.push("Extension providers should have extensionId");
|
|
20671
|
-
}
|
|
20672
|
-
if (config.category === "acp" || config.category === "cli") {
|
|
20673
|
-
if (!config.spawn) errors.push("ACP/CLI providers must have spawn config");
|
|
20674
|
-
else {
|
|
20675
|
-
if (!config.spawn.command) errors.push("spawn.command is required");
|
|
20676
|
-
}
|
|
20677
|
-
}
|
|
21191
|
+
const validation = validateProviderDefinition(config);
|
|
21192
|
+
errors.push(...validation.errors);
|
|
21193
|
+
warnings.push(...validation.warnings);
|
|
20678
21194
|
if (config.settings) {
|
|
20679
21195
|
for (const [key, val] of Object.entries(config.settings)) {
|
|
20680
21196
|
const s = val;
|
|
@@ -20791,7 +21307,7 @@ var DevServer = class _DevServer {
|
|
|
20791
21307
|
}
|
|
20792
21308
|
let targetDir;
|
|
20793
21309
|
targetDir = this.providerLoader.getUserProviderDir(category, type);
|
|
20794
|
-
const jsonPath =
|
|
21310
|
+
const jsonPath = path22.join(targetDir, "provider.json");
|
|
20795
21311
|
if (fs14.existsSync(jsonPath)) {
|
|
20796
21312
|
this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
|
|
20797
21313
|
return;
|
|
@@ -20803,8 +21319,8 @@ var DevServer = class _DevServer {
|
|
|
20803
21319
|
const createdFiles = ["provider.json"];
|
|
20804
21320
|
if (result.files) {
|
|
20805
21321
|
for (const [relPath, content] of Object.entries(result.files)) {
|
|
20806
|
-
const fullPath =
|
|
20807
|
-
fs14.mkdirSync(
|
|
21322
|
+
const fullPath = path22.join(targetDir, relPath);
|
|
21323
|
+
fs14.mkdirSync(path22.dirname(fullPath), { recursive: true });
|
|
20808
21324
|
fs14.writeFileSync(fullPath, content, "utf-8");
|
|
20809
21325
|
createdFiles.push(relPath);
|
|
20810
21326
|
}
|
|
@@ -20857,22 +21373,22 @@ var DevServer = class _DevServer {
|
|
|
20857
21373
|
if (!fs14.existsSync(scriptsDir)) return null;
|
|
20858
21374
|
const versions = fs14.readdirSync(scriptsDir).filter((d) => {
|
|
20859
21375
|
try {
|
|
20860
|
-
return fs14.statSync(
|
|
21376
|
+
return fs14.statSync(path22.join(scriptsDir, d)).isDirectory();
|
|
20861
21377
|
} catch {
|
|
20862
21378
|
return false;
|
|
20863
21379
|
}
|
|
20864
21380
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
20865
21381
|
if (versions.length === 0) return null;
|
|
20866
|
-
return
|
|
21382
|
+
return path22.join(scriptsDir, versions[0]);
|
|
20867
21383
|
}
|
|
20868
21384
|
resolveAutoImplWritableProviderDir(category, type, requestedDir) {
|
|
20869
|
-
const canonicalUserDir =
|
|
20870
|
-
const desiredDir = requestedDir ?
|
|
20871
|
-
const upstreamRoot =
|
|
20872
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
21385
|
+
const canonicalUserDir = path22.resolve(this.providerLoader.getUserProviderDir(category, type));
|
|
21386
|
+
const desiredDir = requestedDir ? path22.resolve(requestedDir) : canonicalUserDir;
|
|
21387
|
+
const upstreamRoot = path22.resolve(this.providerLoader.getUpstreamDir());
|
|
21388
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path22.sep}`)) {
|
|
20873
21389
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
20874
21390
|
}
|
|
20875
|
-
if (
|
|
21391
|
+
if (path22.basename(desiredDir) !== type) {
|
|
20876
21392
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
20877
21393
|
}
|
|
20878
21394
|
const sourceDir = this.findProviderDir(type);
|
|
@@ -20880,11 +21396,11 @@ var DevServer = class _DevServer {
|
|
|
20880
21396
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
20881
21397
|
}
|
|
20882
21398
|
if (!fs14.existsSync(desiredDir)) {
|
|
20883
|
-
fs14.mkdirSync(
|
|
21399
|
+
fs14.mkdirSync(path22.dirname(desiredDir), { recursive: true });
|
|
20884
21400
|
fs14.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
20885
21401
|
this.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
20886
21402
|
}
|
|
20887
|
-
const providerJson =
|
|
21403
|
+
const providerJson = path22.join(desiredDir, "provider.json");
|
|
20888
21404
|
if (!fs14.existsSync(providerJson)) {
|
|
20889
21405
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
20890
21406
|
}
|
|
@@ -20932,7 +21448,7 @@ var DevServer = class _DevServer {
|
|
|
20932
21448
|
setMode: "set_mode.js"
|
|
20933
21449
|
};
|
|
20934
21450
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
20935
|
-
const scriptsDir =
|
|
21451
|
+
const scriptsDir = path22.join(providerDir, "scripts");
|
|
20936
21452
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
20937
21453
|
if (latestScriptsDir) {
|
|
20938
21454
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -20943,7 +21459,7 @@ var DevServer = class _DevServer {
|
|
|
20943
21459
|
for (const file of fs14.readdirSync(latestScriptsDir)) {
|
|
20944
21460
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
20945
21461
|
try {
|
|
20946
|
-
const content = fs14.readFileSync(
|
|
21462
|
+
const content = fs14.readFileSync(path22.join(latestScriptsDir, file), "utf-8");
|
|
20947
21463
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
20948
21464
|
lines.push("```javascript");
|
|
20949
21465
|
lines.push(content);
|
|
@@ -20960,7 +21476,7 @@ var DevServer = class _DevServer {
|
|
|
20960
21476
|
lines.push("");
|
|
20961
21477
|
for (const file of refFiles) {
|
|
20962
21478
|
try {
|
|
20963
|
-
const content = fs14.readFileSync(
|
|
21479
|
+
const content = fs14.readFileSync(path22.join(latestScriptsDir, file), "utf-8");
|
|
20964
21480
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
20965
21481
|
lines.push("```javascript");
|
|
20966
21482
|
lines.push(content);
|
|
@@ -21001,10 +21517,10 @@ var DevServer = class _DevServer {
|
|
|
21001
21517
|
lines.push("");
|
|
21002
21518
|
}
|
|
21003
21519
|
}
|
|
21004
|
-
const docsDir =
|
|
21520
|
+
const docsDir = path22.join(providerDir, "../../docs");
|
|
21005
21521
|
const loadGuide = (name) => {
|
|
21006
21522
|
try {
|
|
21007
|
-
const p =
|
|
21523
|
+
const p = path22.join(docsDir, name);
|
|
21008
21524
|
if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
|
|
21009
21525
|
} catch {
|
|
21010
21526
|
}
|
|
@@ -21178,7 +21694,7 @@ var DevServer = class _DevServer {
|
|
|
21178
21694
|
parseApproval: "parse_approval.js"
|
|
21179
21695
|
};
|
|
21180
21696
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
21181
|
-
const scriptsDir =
|
|
21697
|
+
const scriptsDir = path22.join(providerDir, "scripts");
|
|
21182
21698
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
21183
21699
|
if (latestScriptsDir) {
|
|
21184
21700
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -21190,7 +21706,7 @@ var DevServer = class _DevServer {
|
|
|
21190
21706
|
if (!file.endsWith(".js")) continue;
|
|
21191
21707
|
if (!targetFileNames.has(file)) continue;
|
|
21192
21708
|
try {
|
|
21193
|
-
const content = fs14.readFileSync(
|
|
21709
|
+
const content = fs14.readFileSync(path22.join(latestScriptsDir, file), "utf-8");
|
|
21194
21710
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
21195
21711
|
lines.push("```javascript");
|
|
21196
21712
|
lines.push(content);
|
|
@@ -21206,7 +21722,7 @@ var DevServer = class _DevServer {
|
|
|
21206
21722
|
lines.push("");
|
|
21207
21723
|
for (const file of refFiles) {
|
|
21208
21724
|
try {
|
|
21209
|
-
const content = fs14.readFileSync(
|
|
21725
|
+
const content = fs14.readFileSync(path22.join(latestScriptsDir, file), "utf-8");
|
|
21210
21726
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
21211
21727
|
lines.push("```javascript");
|
|
21212
21728
|
lines.push(content);
|
|
@@ -21239,10 +21755,10 @@ var DevServer = class _DevServer {
|
|
|
21239
21755
|
lines.push("");
|
|
21240
21756
|
}
|
|
21241
21757
|
}
|
|
21242
|
-
const docsDir =
|
|
21758
|
+
const docsDir = path22.join(providerDir, "../../docs");
|
|
21243
21759
|
const loadGuide = (name) => {
|
|
21244
21760
|
try {
|
|
21245
|
-
const p =
|
|
21761
|
+
const p = path22.join(docsDir, name);
|
|
21246
21762
|
if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
|
|
21247
21763
|
} catch {
|
|
21248
21764
|
}
|
|
@@ -21955,6 +22471,67 @@ async function listHostedCliRuntimes(endpoint) {
|
|
|
21955
22471
|
}
|
|
21956
22472
|
}
|
|
21957
22473
|
|
|
22474
|
+
// src/session-host/runtime-surface.ts
|
|
22475
|
+
var LIVE_LIFECYCLES = /* @__PURE__ */ new Set(["starting", "running", "stopping", "interrupted"]);
|
|
22476
|
+
function isSessionHostLiveRuntime(record) {
|
|
22477
|
+
const lifecycle = String(record?.lifecycle || "").trim();
|
|
22478
|
+
return LIVE_LIFECYCLES.has(lifecycle);
|
|
22479
|
+
}
|
|
22480
|
+
function getSessionHostRecoveryLabel(meta) {
|
|
22481
|
+
const recoveryState = typeof meta?.runtimeRecoveryState === "string" ? String(meta.runtimeRecoveryState).trim() : "";
|
|
22482
|
+
if (!recoveryState) return null;
|
|
22483
|
+
if (recoveryState === "auto_resumed") return "restored after restart";
|
|
22484
|
+
if (recoveryState === "resume_failed") return "restore failed";
|
|
22485
|
+
if (recoveryState === "host_restart_interrupted") return "host restart interrupted";
|
|
22486
|
+
if (recoveryState === "orphan_snapshot") return "snapshot recovered";
|
|
22487
|
+
return recoveryState.replace(/_/g, " ");
|
|
22488
|
+
}
|
|
22489
|
+
function isSessionHostRecoverySnapshot(record) {
|
|
22490
|
+
if (!record) return false;
|
|
22491
|
+
if (isSessionHostLiveRuntime(record)) return false;
|
|
22492
|
+
const lifecycle = String(record.lifecycle || "").trim();
|
|
22493
|
+
if (lifecycle && lifecycle !== "stopped" && lifecycle !== "failed") {
|
|
22494
|
+
return false;
|
|
22495
|
+
}
|
|
22496
|
+
const meta = record.meta || void 0;
|
|
22497
|
+
if (meta?.restoredFromStorage === true) return true;
|
|
22498
|
+
return getSessionHostRecoveryLabel(meta) !== null;
|
|
22499
|
+
}
|
|
22500
|
+
function getSessionHostSurfaceKind(record) {
|
|
22501
|
+
if (isSessionHostLiveRuntime(record)) return "live_runtime";
|
|
22502
|
+
if (isSessionHostRecoverySnapshot(record)) return "recovery_snapshot";
|
|
22503
|
+
return "inactive_record";
|
|
22504
|
+
}
|
|
22505
|
+
function partitionSessionHostRecords(records) {
|
|
22506
|
+
const liveRuntimes = [];
|
|
22507
|
+
const recoverySnapshots = [];
|
|
22508
|
+
const inactiveRecords = [];
|
|
22509
|
+
for (const record of records) {
|
|
22510
|
+
const kind = getSessionHostSurfaceKind(record);
|
|
22511
|
+
if (kind === "live_runtime") {
|
|
22512
|
+
liveRuntimes.push(record);
|
|
22513
|
+
} else if (kind === "recovery_snapshot") {
|
|
22514
|
+
recoverySnapshots.push(record);
|
|
22515
|
+
} else {
|
|
22516
|
+
inactiveRecords.push(record);
|
|
22517
|
+
}
|
|
22518
|
+
}
|
|
22519
|
+
return {
|
|
22520
|
+
liveRuntimes,
|
|
22521
|
+
recoverySnapshots,
|
|
22522
|
+
inactiveRecords
|
|
22523
|
+
};
|
|
22524
|
+
}
|
|
22525
|
+
function partitionSessionHostDiagnosticsSessions(records) {
|
|
22526
|
+
return partitionSessionHostRecords(records || []);
|
|
22527
|
+
}
|
|
22528
|
+
|
|
22529
|
+
// src/session-host/startup-restore-policy.js
|
|
22530
|
+
function shouldAutoRestoreHostedSessionsOnStartup(env = process.env) {
|
|
22531
|
+
const raw = typeof env.ADHDEV_RESTORE_HOSTED_SESSIONS_ON_STARTUP === "string" ? env.ADHDEV_RESTORE_HOSTED_SESSIONS_ON_STARTUP.trim().toLowerCase() : "";
|
|
22532
|
+
return raw === "1" || raw === "true" || raw === "yes";
|
|
22533
|
+
}
|
|
22534
|
+
|
|
21958
22535
|
// src/installer.ts
|
|
21959
22536
|
import { execSync as execSync6, exec as exec2 } from "child_process";
|
|
21960
22537
|
var EXTENSION_CATALOG = [
|
|
@@ -22460,6 +23037,7 @@ export {
|
|
|
22460
23037
|
detectIDEs,
|
|
22461
23038
|
ensureSessionHostReady,
|
|
22462
23039
|
findCdpManager,
|
|
23040
|
+
flattenMessageParts,
|
|
22463
23041
|
forwardAgentStreamsToIdeInstance,
|
|
22464
23042
|
getAIExtensions,
|
|
22465
23043
|
getAvailableIdeIds,
|
|
@@ -22473,6 +23051,8 @@ export {
|
|
|
22473
23051
|
getRecentDebugTrace,
|
|
22474
23052
|
getRecentLogs,
|
|
22475
23053
|
getSavedProviderSessions,
|
|
23054
|
+
getSessionHostRecoveryLabel,
|
|
23055
|
+
getSessionHostSurfaceKind,
|
|
22476
23056
|
getWorkspaceState,
|
|
22477
23057
|
hasCdpManager,
|
|
22478
23058
|
initDaemonComponents,
|
|
@@ -22483,6 +23063,8 @@ export {
|
|
|
22483
23063
|
isIdeRunning,
|
|
22484
23064
|
isManagedStatusWaiting,
|
|
22485
23065
|
isManagedStatusWorking,
|
|
23066
|
+
isSessionHostLiveRuntime,
|
|
23067
|
+
isSessionHostRecoverySnapshot,
|
|
22486
23068
|
isSetupComplete,
|
|
22487
23069
|
killIdeProcess,
|
|
22488
23070
|
launchIDE,
|
|
@@ -22494,7 +23076,11 @@ export {
|
|
|
22494
23076
|
markSetupComplete,
|
|
22495
23077
|
maybeRunDaemonUpgradeHelperFromEnv,
|
|
22496
23078
|
normalizeActiveChatData,
|
|
23079
|
+
normalizeInputEnvelope,
|
|
22497
23080
|
normalizeManagedStatus,
|
|
23081
|
+
normalizeMessageParts,
|
|
23082
|
+
partitionSessionHostDiagnosticsSessions,
|
|
23083
|
+
partitionSessionHostRecords,
|
|
22498
23084
|
probeCdpPort,
|
|
22499
23085
|
readChatHistory,
|
|
22500
23086
|
recordDebugTrace,
|
|
@@ -22509,6 +23095,7 @@ export {
|
|
|
22509
23095
|
setDebugRuntimeConfig,
|
|
22510
23096
|
setLogLevel,
|
|
22511
23097
|
setupIdeInstance,
|
|
23098
|
+
shouldAutoRestoreHostedSessionsOnStartup,
|
|
22512
23099
|
shouldCollectTraceCategory,
|
|
22513
23100
|
shutdownDaemonComponents,
|
|
22514
23101
|
spawnDetachedDaemonUpgradeHelper,
|