@adhdev/daemon-core 0.8.52 → 0.8.53
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.js
CHANGED
|
@@ -3042,6 +3042,7 @@ __export(index_exports, {
|
|
|
3042
3042
|
detectIDEs: () => detectIDEs,
|
|
3043
3043
|
ensureSessionHostReady: () => ensureSessionHostReady,
|
|
3044
3044
|
findCdpManager: () => findCdpManager,
|
|
3045
|
+
flattenMessageParts: () => flattenMessageParts,
|
|
3045
3046
|
forwardAgentStreamsToIdeInstance: () => forwardAgentStreamsToIdeInstance,
|
|
3046
3047
|
getAIExtensions: () => getAIExtensions,
|
|
3047
3048
|
getAvailableIdeIds: () => getAvailableIdeIds,
|
|
@@ -3055,6 +3056,8 @@ __export(index_exports, {
|
|
|
3055
3056
|
getRecentDebugTrace: () => getRecentDebugTrace,
|
|
3056
3057
|
getRecentLogs: () => getRecentLogs,
|
|
3057
3058
|
getSavedProviderSessions: () => getSavedProviderSessions,
|
|
3059
|
+
getSessionHostRecoveryLabel: () => getSessionHostRecoveryLabel,
|
|
3060
|
+
getSessionHostSurfaceKind: () => getSessionHostSurfaceKind,
|
|
3058
3061
|
getWorkspaceState: () => getWorkspaceState,
|
|
3059
3062
|
hasCdpManager: () => hasCdpManager,
|
|
3060
3063
|
initDaemonComponents: () => initDaemonComponents,
|
|
@@ -3065,6 +3068,8 @@ __export(index_exports, {
|
|
|
3065
3068
|
isIdeRunning: () => isIdeRunning,
|
|
3066
3069
|
isManagedStatusWaiting: () => isManagedStatusWaiting,
|
|
3067
3070
|
isManagedStatusWorking: () => isManagedStatusWorking,
|
|
3071
|
+
isSessionHostLiveRuntime: () => isSessionHostLiveRuntime,
|
|
3072
|
+
isSessionHostRecoverySnapshot: () => isSessionHostRecoverySnapshot,
|
|
3068
3073
|
isSetupComplete: () => isSetupComplete,
|
|
3069
3074
|
killIdeProcess: () => killIdeProcess,
|
|
3070
3075
|
launchIDE: () => launchIDE,
|
|
@@ -3076,7 +3081,11 @@ __export(index_exports, {
|
|
|
3076
3081
|
markSetupComplete: () => markSetupComplete,
|
|
3077
3082
|
maybeRunDaemonUpgradeHelperFromEnv: () => maybeRunDaemonUpgradeHelperFromEnv,
|
|
3078
3083
|
normalizeActiveChatData: () => normalizeActiveChatData,
|
|
3084
|
+
normalizeInputEnvelope: () => normalizeInputEnvelope,
|
|
3079
3085
|
normalizeManagedStatus: () => normalizeManagedStatus,
|
|
3086
|
+
normalizeMessageParts: () => normalizeMessageParts,
|
|
3087
|
+
partitionSessionHostDiagnosticsSessions: () => partitionSessionHostDiagnosticsSessions,
|
|
3088
|
+
partitionSessionHostRecords: () => partitionSessionHostRecords,
|
|
3080
3089
|
probeCdpPort: () => probeCdpPort,
|
|
3081
3090
|
readChatHistory: () => readChatHistory,
|
|
3082
3091
|
recordDebugTrace: () => recordDebugTrace,
|
|
@@ -3091,6 +3100,7 @@ __export(index_exports, {
|
|
|
3091
3100
|
setDebugRuntimeConfig: () => setDebugRuntimeConfig,
|
|
3092
3101
|
setLogLevel: () => setLogLevel,
|
|
3093
3102
|
setupIdeInstance: () => setupIdeInstance,
|
|
3103
|
+
shouldAutoRestoreHostedSessionsOnStartup: () => shouldAutoRestoreHostedSessionsOnStartup,
|
|
3094
3104
|
shouldCollectTraceCategory: () => shouldCollectTraceCategory,
|
|
3095
3105
|
shutdownDaemonComponents: () => shutdownDaemonComponents,
|
|
3096
3106
|
spawnDetachedDaemonUpgradeHelper: () => spawnDetachedDaemonUpgradeHelper,
|
|
@@ -5186,6 +5196,61 @@ function normalizeProviderEffects(data) {
|
|
|
5186
5196
|
}
|
|
5187
5197
|
return effects;
|
|
5188
5198
|
}
|
|
5199
|
+
function normalizeControlListResult(data) {
|
|
5200
|
+
if (data && typeof data === "object" && Array.isArray(data.options)) {
|
|
5201
|
+
return {
|
|
5202
|
+
options: normalizeControlOptions(data.options),
|
|
5203
|
+
...isScalarControlValue(data.currentValue) ? { currentValue: data.currentValue } : {},
|
|
5204
|
+
...typeof data.error === "string" ? { error: data.error } : {}
|
|
5205
|
+
};
|
|
5206
|
+
}
|
|
5207
|
+
const rawOptions = Array.isArray(data?.models) ? data.models : Array.isArray(data?.modes) ? data.modes : Array.isArray(data?.options) ? data.options : [];
|
|
5208
|
+
const options = normalizeControlOptions(rawOptions);
|
|
5209
|
+
return {
|
|
5210
|
+
options,
|
|
5211
|
+
...isScalarControlValue(data?.current) ? { currentValue: data.current } : {},
|
|
5212
|
+
...isScalarControlValue(data?.currentValue) ? { currentValue: data.currentValue } : {},
|
|
5213
|
+
...typeof data?.error === "string" ? { error: data.error } : {}
|
|
5214
|
+
};
|
|
5215
|
+
}
|
|
5216
|
+
function normalizeControlSetResult(data) {
|
|
5217
|
+
const currentValue = isScalarControlValue(data?.currentValue) ? data.currentValue : isScalarControlValue(data?.value) ? data.value : void 0;
|
|
5218
|
+
return {
|
|
5219
|
+
ok: data?.ok === true || data?.success === true,
|
|
5220
|
+
...currentValue !== void 0 ? { currentValue } : {},
|
|
5221
|
+
...Array.isArray(data?.effects) ? { effects: normalizeProviderEffects(data) } : {},
|
|
5222
|
+
...typeof data?.error === "string" ? { error: data.error } : {}
|
|
5223
|
+
};
|
|
5224
|
+
}
|
|
5225
|
+
function normalizeControlInvokeResult(data) {
|
|
5226
|
+
const currentValue = isScalarControlValue(data?.currentValue) ? data.currentValue : isScalarControlValue(data?.value) ? data.value : void 0;
|
|
5227
|
+
return {
|
|
5228
|
+
ok: data?.ok === true || data?.success === true,
|
|
5229
|
+
...currentValue !== void 0 ? { currentValue } : {},
|
|
5230
|
+
...Array.isArray(data?.effects) ? { effects: normalizeProviderEffects(data) } : {},
|
|
5231
|
+
...typeof data?.error === "string" ? { error: data.error } : {}
|
|
5232
|
+
};
|
|
5233
|
+
}
|
|
5234
|
+
function normalizeControlOptions(options) {
|
|
5235
|
+
return options.map((option) => normalizeControlOption(option)).filter((option) => !!option);
|
|
5236
|
+
}
|
|
5237
|
+
function normalizeControlOption(option) {
|
|
5238
|
+
if (typeof option === "string") {
|
|
5239
|
+
return { value: option, label: option };
|
|
5240
|
+
}
|
|
5241
|
+
if (!option || typeof option !== "object") return null;
|
|
5242
|
+
const record = option;
|
|
5243
|
+
const value = typeof record.value === "string" ? record.value : typeof record.id === "string" ? record.id : null;
|
|
5244
|
+
if (!value) return null;
|
|
5245
|
+
const label = typeof record.label === "string" ? record.label : typeof record.name === "string" ? record.name : value;
|
|
5246
|
+
const normalized = { value, label };
|
|
5247
|
+
if (typeof record.description === "string") normalized.description = record.description;
|
|
5248
|
+
if (typeof record.group === "string") normalized.group = record.group;
|
|
5249
|
+
return normalized;
|
|
5250
|
+
}
|
|
5251
|
+
function isScalarControlValue(value) {
|
|
5252
|
+
return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
5253
|
+
}
|
|
5189
5254
|
function normalizeControlValue(value) {
|
|
5190
5255
|
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
5191
5256
|
return value;
|
|
@@ -7177,50 +7242,6 @@ function isCdpConnected(cdpManagers, key) {
|
|
|
7177
7242
|
}
|
|
7178
7243
|
return false;
|
|
7179
7244
|
}
|
|
7180
|
-
function buildFallbackControls(providerControls, serverModel, serverMode, acpConfigOptions, acpModes) {
|
|
7181
|
-
if (providerControls && providerControls.length > 0) return providerControls;
|
|
7182
|
-
const controls = [];
|
|
7183
|
-
const isAcp = !!(acpConfigOptions || acpModes);
|
|
7184
|
-
const modelFromAcp = acpConfigOptions?.find((c) => c.category === "model");
|
|
7185
|
-
if (!isAcp || modelFromAcp) {
|
|
7186
|
-
controls.push({
|
|
7187
|
-
id: "model",
|
|
7188
|
-
type: "select",
|
|
7189
|
-
label: "Model",
|
|
7190
|
-
icon: "\u{1F916}",
|
|
7191
|
-
placement: "bar",
|
|
7192
|
-
dynamic: !modelFromAcp,
|
|
7193
|
-
listScript: "listModels",
|
|
7194
|
-
setScript: "setModel",
|
|
7195
|
-
readFrom: "model",
|
|
7196
|
-
...modelFromAcp && {
|
|
7197
|
-
options: modelFromAcp.options.map((o) => ({ value: o.value, label: o.name || o.value }))
|
|
7198
|
-
}
|
|
7199
|
-
});
|
|
7200
|
-
}
|
|
7201
|
-
const modeFromAcp = acpModes && acpModes.length > 0;
|
|
7202
|
-
const thoughtFromAcp = !modeFromAcp && acpConfigOptions?.find((c) => c.category !== "model");
|
|
7203
|
-
if (!isAcp || modeFromAcp || thoughtFromAcp) {
|
|
7204
|
-
controls.push({
|
|
7205
|
-
id: "mode",
|
|
7206
|
-
type: thoughtFromAcp ? "cycle" : "select",
|
|
7207
|
-
label: thoughtFromAcp ? "Thinking" : "Mode",
|
|
7208
|
-
icon: thoughtFromAcp ? "\u{1F9E0}" : "\u26A1",
|
|
7209
|
-
placement: "bar",
|
|
7210
|
-
dynamic: !modeFromAcp && !thoughtFromAcp,
|
|
7211
|
-
listScript: "listModes",
|
|
7212
|
-
setScript: thoughtFromAcp ? "setThinkingLevel" : "setMode",
|
|
7213
|
-
readFrom: "mode",
|
|
7214
|
-
...modeFromAcp && {
|
|
7215
|
-
options: acpModes.map((m) => ({ value: m.id, label: m.name || m.id }))
|
|
7216
|
-
},
|
|
7217
|
-
...thoughtFromAcp && {
|
|
7218
|
-
options: thoughtFromAcp.options.map((o) => ({ value: o.value, label: o.name || o.value }))
|
|
7219
|
-
}
|
|
7220
|
-
});
|
|
7221
|
-
}
|
|
7222
|
-
return controls;
|
|
7223
|
-
}
|
|
7224
7245
|
var IDE_SESSION_CAPABILITIES = [
|
|
7225
7246
|
"read_chat",
|
|
7226
7247
|
"send_message",
|
|
@@ -7289,11 +7310,7 @@ function buildIdeWorkspaceSession(state, cdpManagers, options) {
|
|
|
7289
7310
|
currentAutoApprove: state.currentAutoApprove,
|
|
7290
7311
|
...includeSessionControls && {
|
|
7291
7312
|
controlValues: state.controlValues,
|
|
7292
|
-
providerControls:
|
|
7293
|
-
state.providerControls,
|
|
7294
|
-
state.currentModel,
|
|
7295
|
-
state.currentPlan
|
|
7296
|
-
)
|
|
7313
|
+
providerControls: state.providerControls
|
|
7297
7314
|
},
|
|
7298
7315
|
errorMessage: state.errorMessage,
|
|
7299
7316
|
errorReason: state.errorReason,
|
|
@@ -7323,11 +7340,7 @@ function buildExtensionAgentSession(parent, ext, options) {
|
|
|
7323
7340
|
currentPlan: ext.currentPlan,
|
|
7324
7341
|
...includeSessionControls && {
|
|
7325
7342
|
controlValues: ext.controlValues,
|
|
7326
|
-
providerControls:
|
|
7327
|
-
ext.providerControls,
|
|
7328
|
-
ext.currentModel,
|
|
7329
|
-
ext.currentPlan
|
|
7330
|
-
)
|
|
7343
|
+
providerControls: ext.providerControls
|
|
7331
7344
|
},
|
|
7332
7345
|
errorMessage: ext.errorMessage,
|
|
7333
7346
|
errorReason: ext.errorReason,
|
|
@@ -7368,9 +7381,7 @@ function buildCliSession(state, options) {
|
|
|
7368
7381
|
},
|
|
7369
7382
|
...includeSessionControls && {
|
|
7370
7383
|
controlValues: state.controlValues,
|
|
7371
|
-
providerControls:
|
|
7372
|
-
state.providerControls
|
|
7373
|
-
)
|
|
7384
|
+
providerControls: state.providerControls
|
|
7374
7385
|
},
|
|
7375
7386
|
errorMessage: state.errorMessage,
|
|
7376
7387
|
errorReason: state.errorReason,
|
|
@@ -7402,13 +7413,7 @@ function buildAcpSession(state, options) {
|
|
|
7402
7413
|
acpConfigOptions: state.acpConfigOptions,
|
|
7403
7414
|
acpModes: state.acpModes,
|
|
7404
7415
|
controlValues: state.controlValues,
|
|
7405
|
-
providerControls:
|
|
7406
|
-
state.providerControls,
|
|
7407
|
-
state.currentModel,
|
|
7408
|
-
state.currentPlan,
|
|
7409
|
-
state.acpConfigOptions,
|
|
7410
|
-
state.acpModes
|
|
7411
|
-
)
|
|
7416
|
+
providerControls: state.providerControls
|
|
7412
7417
|
},
|
|
7413
7418
|
errorMessage: state.errorMessage,
|
|
7414
7419
|
errorReason: state.errorReason,
|
|
@@ -7491,10 +7496,217 @@ function reconcileIdeRuntimeSessions(instanceManager, sessionRegistry) {
|
|
|
7491
7496
|
// src/commands/handler.ts
|
|
7492
7497
|
init_logger();
|
|
7493
7498
|
|
|
7499
|
+
// src/providers/io-contracts.ts
|
|
7500
|
+
function normalizeInputEnvelope(input) {
|
|
7501
|
+
const normalized = normalizeInputEnvelopePayload(input);
|
|
7502
|
+
const textFallback = normalized.textFallback ?? flattenInputParts(normalized.parts);
|
|
7503
|
+
return {
|
|
7504
|
+
parts: normalized.parts,
|
|
7505
|
+
textFallback,
|
|
7506
|
+
...normalized.metadata ? { metadata: normalized.metadata } : {}
|
|
7507
|
+
};
|
|
7508
|
+
}
|
|
7509
|
+
function normalizeMessageParts(content) {
|
|
7510
|
+
if (typeof content === "string") return [{ type: "text", text: content }];
|
|
7511
|
+
if (!Array.isArray(content)) {
|
|
7512
|
+
if (content && typeof content === "object" && typeof content.text === "string") {
|
|
7513
|
+
return [{ type: "text", text: String(content.text) }];
|
|
7514
|
+
}
|
|
7515
|
+
return [];
|
|
7516
|
+
}
|
|
7517
|
+
const parts = [];
|
|
7518
|
+
for (const raw of content) {
|
|
7519
|
+
if (typeof raw === "string") {
|
|
7520
|
+
parts.push({ type: "text", text: raw });
|
|
7521
|
+
continue;
|
|
7522
|
+
}
|
|
7523
|
+
if (!raw || typeof raw !== "object") continue;
|
|
7524
|
+
const part = normalizeMessagePartObject(raw);
|
|
7525
|
+
if (part) parts.push(part);
|
|
7526
|
+
}
|
|
7527
|
+
return parts;
|
|
7528
|
+
}
|
|
7529
|
+
function flattenMessageParts(parts) {
|
|
7530
|
+
return parts.map((part) => {
|
|
7531
|
+
if (part.type === "text") return part.text;
|
|
7532
|
+
if (part.type === "resource") return part.resource.text || "";
|
|
7533
|
+
return "";
|
|
7534
|
+
}).filter((value) => value.length > 0).join("\n");
|
|
7535
|
+
}
|
|
7536
|
+
function normalizeInputEnvelopePayload(input) {
|
|
7537
|
+
if (typeof input === "string") {
|
|
7538
|
+
return { parts: [{ type: "text", text: input }], textFallback: input };
|
|
7539
|
+
}
|
|
7540
|
+
if (!input || typeof input !== "object") {
|
|
7541
|
+
return { parts: [], textFallback: "" };
|
|
7542
|
+
}
|
|
7543
|
+
const record = input;
|
|
7544
|
+
const nestedInput = record.input;
|
|
7545
|
+
if (nestedInput && typeof nestedInput === "object") {
|
|
7546
|
+
const nested = nestedInput;
|
|
7547
|
+
return {
|
|
7548
|
+
parts: normalizeInputParts(nested.parts ?? nested.prompt),
|
|
7549
|
+
textFallback: typeof nested.textFallback === "string" ? nested.textFallback : void 0,
|
|
7550
|
+
metadata: normalizeInputMetadata(nested.metadata)
|
|
7551
|
+
};
|
|
7552
|
+
}
|
|
7553
|
+
const directText = typeof record.text === "string" ? record.text : typeof record.message === "string" ? record.message : void 0;
|
|
7554
|
+
if (directText !== void 0) {
|
|
7555
|
+
return { parts: [{ type: "text", text: directText }], textFallback: directText };
|
|
7556
|
+
}
|
|
7557
|
+
const directParts = normalizeInputParts(record.parts ?? record.prompt);
|
|
7558
|
+
return {
|
|
7559
|
+
parts: directParts,
|
|
7560
|
+
textFallback: typeof record.textFallback === "string" ? record.textFallback : void 0,
|
|
7561
|
+
metadata: normalizeInputMetadata(record.metadata)
|
|
7562
|
+
};
|
|
7563
|
+
}
|
|
7564
|
+
function normalizeInputMetadata(value) {
|
|
7565
|
+
if (!value || typeof value !== "object") return void 0;
|
|
7566
|
+
const record = value;
|
|
7567
|
+
const metadata = {};
|
|
7568
|
+
if (record.source === "dashboard" || record.source === "shortcut_api" || record.source === "provider_script" || record.source === "session_replay") {
|
|
7569
|
+
metadata.source = record.source;
|
|
7570
|
+
}
|
|
7571
|
+
if (typeof record.clientTimestamp === "number" && Number.isFinite(record.clientTimestamp)) {
|
|
7572
|
+
metadata.clientTimestamp = record.clientTimestamp;
|
|
7573
|
+
}
|
|
7574
|
+
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
7575
|
+
}
|
|
7576
|
+
function normalizeInputParts(value) {
|
|
7577
|
+
if (!Array.isArray(value)) return [];
|
|
7578
|
+
const parts = [];
|
|
7579
|
+
for (const raw of value) {
|
|
7580
|
+
if (typeof raw === "string") {
|
|
7581
|
+
parts.push({ type: "text", text: raw });
|
|
7582
|
+
continue;
|
|
7583
|
+
}
|
|
7584
|
+
if (!raw || typeof raw !== "object") continue;
|
|
7585
|
+
const part = normalizeInputPartObject(raw);
|
|
7586
|
+
if (part) parts.push(part);
|
|
7587
|
+
}
|
|
7588
|
+
return parts;
|
|
7589
|
+
}
|
|
7590
|
+
function normalizeInputPartObject(raw) {
|
|
7591
|
+
const type = raw.type;
|
|
7592
|
+
if (type === "text" && typeof raw.text === "string") {
|
|
7593
|
+
return { type, text: raw.text };
|
|
7594
|
+
}
|
|
7595
|
+
if (type === "image" && typeof raw.mimeType === "string") {
|
|
7596
|
+
return {
|
|
7597
|
+
type,
|
|
7598
|
+
mimeType: raw.mimeType,
|
|
7599
|
+
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
7600
|
+
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
7601
|
+
...typeof raw.alt === "string" ? { alt: raw.alt } : {}
|
|
7602
|
+
};
|
|
7603
|
+
}
|
|
7604
|
+
if (type === "audio" && typeof raw.mimeType === "string") {
|
|
7605
|
+
return {
|
|
7606
|
+
type,
|
|
7607
|
+
mimeType: raw.mimeType,
|
|
7608
|
+
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
7609
|
+
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
7610
|
+
...typeof raw.transcript === "string" ? { transcript: raw.transcript } : {}
|
|
7611
|
+
};
|
|
7612
|
+
}
|
|
7613
|
+
if (type === "video" && typeof raw.mimeType === "string") {
|
|
7614
|
+
return {
|
|
7615
|
+
type,
|
|
7616
|
+
mimeType: raw.mimeType,
|
|
7617
|
+
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
7618
|
+
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
7619
|
+
...typeof raw.posterUri === "string" ? { posterUri: raw.posterUri } : {}
|
|
7620
|
+
};
|
|
7621
|
+
}
|
|
7622
|
+
if (type === "resource" && typeof raw.uri === "string") {
|
|
7623
|
+
return {
|
|
7624
|
+
type,
|
|
7625
|
+
uri: raw.uri,
|
|
7626
|
+
...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
|
|
7627
|
+
...typeof raw.name === "string" ? { name: raw.name } : {},
|
|
7628
|
+
...typeof raw.text === "string" ? { text: raw.text } : {},
|
|
7629
|
+
...typeof raw.data === "string" ? { data: raw.data } : {}
|
|
7630
|
+
};
|
|
7631
|
+
}
|
|
7632
|
+
if (type === "resource_link" && typeof raw.uri === "string") {
|
|
7633
|
+
return {
|
|
7634
|
+
type: "resource",
|
|
7635
|
+
uri: raw.uri,
|
|
7636
|
+
...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
|
|
7637
|
+
...typeof raw.name === "string" ? { name: raw.name } : {}
|
|
7638
|
+
};
|
|
7639
|
+
}
|
|
7640
|
+
return null;
|
|
7641
|
+
}
|
|
7642
|
+
function normalizeMessagePartObject(raw) {
|
|
7643
|
+
const type = raw.type;
|
|
7644
|
+
if (type === "text" && typeof raw.text === "string") {
|
|
7645
|
+
return { type, text: raw.text };
|
|
7646
|
+
}
|
|
7647
|
+
if (type === "image" && typeof raw.mimeType === "string") {
|
|
7648
|
+
return {
|
|
7649
|
+
type,
|
|
7650
|
+
mimeType: raw.mimeType,
|
|
7651
|
+
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
7652
|
+
...typeof raw.data === "string" ? { data: raw.data } : {}
|
|
7653
|
+
};
|
|
7654
|
+
}
|
|
7655
|
+
if (type === "audio" && typeof raw.mimeType === "string") {
|
|
7656
|
+
return {
|
|
7657
|
+
type,
|
|
7658
|
+
mimeType: raw.mimeType,
|
|
7659
|
+
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
7660
|
+
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
7661
|
+
...typeof raw.transcript === "string" ? { transcript: raw.transcript } : {}
|
|
7662
|
+
};
|
|
7663
|
+
}
|
|
7664
|
+
if (type === "video" && typeof raw.mimeType === "string") {
|
|
7665
|
+
return {
|
|
7666
|
+
type,
|
|
7667
|
+
mimeType: raw.mimeType,
|
|
7668
|
+
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
7669
|
+
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
7670
|
+
...typeof raw.posterUri === "string" ? { posterUri: raw.posterUri } : {}
|
|
7671
|
+
};
|
|
7672
|
+
}
|
|
7673
|
+
if (type === "resource_link" && typeof raw.uri === "string" && typeof raw.name === "string") {
|
|
7674
|
+
return {
|
|
7675
|
+
type,
|
|
7676
|
+
uri: raw.uri,
|
|
7677
|
+
name: raw.name,
|
|
7678
|
+
...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
|
|
7679
|
+
...typeof raw.size === "number" ? { size: raw.size } : {}
|
|
7680
|
+
};
|
|
7681
|
+
}
|
|
7682
|
+
if (type === "resource" && raw.resource && typeof raw.resource === "object") {
|
|
7683
|
+
const resource = raw.resource;
|
|
7684
|
+
if (typeof resource.uri !== "string") return null;
|
|
7685
|
+
return {
|
|
7686
|
+
type,
|
|
7687
|
+
resource: {
|
|
7688
|
+
uri: resource.uri,
|
|
7689
|
+
...typeof resource.mimeType === "string" || resource.mimeType === null ? { mimeType: resource.mimeType } : {},
|
|
7690
|
+
...typeof resource.text === "string" ? { text: resource.text } : {},
|
|
7691
|
+
...typeof resource.blob === "string" ? { blob: resource.blob } : {}
|
|
7692
|
+
}
|
|
7693
|
+
};
|
|
7694
|
+
}
|
|
7695
|
+
return null;
|
|
7696
|
+
}
|
|
7697
|
+
function flattenInputParts(parts) {
|
|
7698
|
+
return parts.map((part) => {
|
|
7699
|
+
if (part.type === "text") return part.text;
|
|
7700
|
+
if (part.type === "audio") return part.transcript || "";
|
|
7701
|
+
if (part.type === "resource") return part.text || "";
|
|
7702
|
+
return "";
|
|
7703
|
+
}).filter((value) => value.length > 0).join("\n");
|
|
7704
|
+
}
|
|
7705
|
+
|
|
7494
7706
|
// src/providers/contracts.ts
|
|
7495
7707
|
function flattenContent(content) {
|
|
7496
7708
|
if (typeof content === "string") return content;
|
|
7497
|
-
return
|
|
7709
|
+
return flattenMessageParts(normalizeMessageParts(content));
|
|
7498
7710
|
}
|
|
7499
7711
|
|
|
7500
7712
|
// src/commands/chat-commands.ts
|
|
@@ -7683,6 +7895,9 @@ function buildRecentSendKey(h, args, provider, text) {
|
|
|
7683
7895
|
const target = args?.targetSessionId || args?.agentType || h.currentSession?.providerType || h.currentProviderType || h.currentManagerKey || "unknown";
|
|
7684
7896
|
return `${transport}:${target}:${text.trim()}`;
|
|
7685
7897
|
}
|
|
7898
|
+
function getSendChatInputEnvelope(args) {
|
|
7899
|
+
return normalizeInputEnvelope(args?.input ? { input: args.input } : args);
|
|
7900
|
+
}
|
|
7686
7901
|
function getHistorySessionId(h, args) {
|
|
7687
7902
|
const explicit = typeof args?.historySessionId === "string" ? args.historySessionId.trim() : "";
|
|
7688
7903
|
if (explicit) return explicit;
|
|
@@ -8087,7 +8302,8 @@ async function handleReadChat(h, args) {
|
|
|
8087
8302
|
return buildReadChatCommandResult({ messages: [], status: "idle" }, args);
|
|
8088
8303
|
}
|
|
8089
8304
|
async function handleSendChat(h, args) {
|
|
8090
|
-
const
|
|
8305
|
+
const input = getSendChatInputEnvelope(args);
|
|
8306
|
+
const text = input.textFallback;
|
|
8091
8307
|
if (!text) return { success: false, error: "text required" };
|
|
8092
8308
|
const _log = (msg) => LOG.debug("Command", `[send_chat] ${msg}`);
|
|
8093
8309
|
const provider = h.getProvider(args?.agentType);
|
|
@@ -9027,6 +9243,21 @@ function listDirectoryEntriesSafe(dirPath) {
|
|
|
9027
9243
|
}
|
|
9028
9244
|
return files;
|
|
9029
9245
|
}
|
|
9246
|
+
function listWindowsDriveEntries(excludePath) {
|
|
9247
|
+
const excluded = typeof excludePath === "string" ? excludePath.toLowerCase() : "";
|
|
9248
|
+
const drives = [];
|
|
9249
|
+
for (let code = 65; code <= 90; code += 1) {
|
|
9250
|
+
const letter = String.fromCharCode(code);
|
|
9251
|
+
const root = `${letter}:\\`;
|
|
9252
|
+
try {
|
|
9253
|
+
if (!fs4.existsSync(root)) continue;
|
|
9254
|
+
if (excluded && root.toLowerCase() === excluded) continue;
|
|
9255
|
+
drives.push({ name: `${letter}:`, type: "directory", path: root });
|
|
9256
|
+
} catch {
|
|
9257
|
+
}
|
|
9258
|
+
}
|
|
9259
|
+
return drives;
|
|
9260
|
+
}
|
|
9030
9261
|
async function handleFileRead(h, args) {
|
|
9031
9262
|
try {
|
|
9032
9263
|
const filePath = resolveSafePath(args?.path);
|
|
@@ -9059,12 +9290,51 @@ async function handleFileListBrowse(h, args) {
|
|
|
9059
9290
|
try {
|
|
9060
9291
|
const dirPath = resolveSafePath(args?.path || ".");
|
|
9061
9292
|
const files = listDirectoryEntriesSafe(dirPath).filter((entry) => entry.type === "directory").sort((a, b) => a.name.localeCompare(b.name));
|
|
9293
|
+
if (process.platform === "win32" && /^[A-Za-z]:\\?$/.test(dirPath)) {
|
|
9294
|
+
const driveEntries = listWindowsDriveEntries(dirPath);
|
|
9295
|
+
return {
|
|
9296
|
+
success: true,
|
|
9297
|
+
files: [...driveEntries, ...files],
|
|
9298
|
+
path: dirPath
|
|
9299
|
+
};
|
|
9300
|
+
}
|
|
9062
9301
|
return { success: true, files, path: dirPath };
|
|
9063
9302
|
} catch (e) {
|
|
9064
9303
|
return { success: false, error: e.message };
|
|
9065
9304
|
}
|
|
9066
9305
|
}
|
|
9067
9306
|
|
|
9307
|
+
// src/providers/cli-script-results.ts
|
|
9308
|
+
function parseCliScriptResult(result) {
|
|
9309
|
+
if (typeof result === "string") {
|
|
9310
|
+
try {
|
|
9311
|
+
const parsed = JSON.parse(result);
|
|
9312
|
+
if (parsed && typeof parsed === "object" && parsed.success === false) {
|
|
9313
|
+
return { success: false, payload: parsed };
|
|
9314
|
+
}
|
|
9315
|
+
return { success: true, payload: parsed };
|
|
9316
|
+
} catch {
|
|
9317
|
+
return { success: true, payload: { result } };
|
|
9318
|
+
}
|
|
9319
|
+
}
|
|
9320
|
+
if (result && typeof result === "object" && "success" in result && result.success === false) {
|
|
9321
|
+
return { success: false, payload: result };
|
|
9322
|
+
}
|
|
9323
|
+
return { success: true, payload: result };
|
|
9324
|
+
}
|
|
9325
|
+
function getCliScriptCommand(payload) {
|
|
9326
|
+
if (!payload || typeof payload !== "object") return null;
|
|
9327
|
+
if (typeof payload.sendMessage === "string" && payload.sendMessage.trim()) {
|
|
9328
|
+
return { type: "send_message", text: payload.sendMessage.trim() };
|
|
9329
|
+
}
|
|
9330
|
+
const command = payload.command;
|
|
9331
|
+
if (!command || typeof command !== "object") return null;
|
|
9332
|
+
if (command.type !== "send_message" && command.type !== "pty_write") return null;
|
|
9333
|
+
const text = typeof command.text === "string" ? command.text.trim() : typeof command.message === "string" ? command.message.trim() : "";
|
|
9334
|
+
if (!text) return null;
|
|
9335
|
+
return { type: command.type, text };
|
|
9336
|
+
}
|
|
9337
|
+
|
|
9068
9338
|
// src/commands/stream-commands.ts
|
|
9069
9339
|
init_logger();
|
|
9070
9340
|
function getCliPresentationMode(h, targetSessionId) {
|
|
@@ -9155,34 +9425,19 @@ function normalizeProviderScriptArgs(args) {
|
|
|
9155
9425
|
}
|
|
9156
9426
|
return normalizedArgs;
|
|
9157
9427
|
}
|
|
9158
|
-
function
|
|
9159
|
-
if (typeof
|
|
9160
|
-
|
|
9161
|
-
|
|
9162
|
-
if (parsed && typeof parsed === "object" && parsed.success === false) {
|
|
9163
|
-
return { success: false, payload: parsed };
|
|
9164
|
-
}
|
|
9165
|
-
return { success: true, payload: parsed };
|
|
9166
|
-
} catch {
|
|
9167
|
-
return { success: true, payload: { result } };
|
|
9168
|
-
}
|
|
9428
|
+
function buildControlScriptResult(scriptName, payload) {
|
|
9429
|
+
if (!payload || typeof payload !== "object") return {};
|
|
9430
|
+
if (Array.isArray(payload.options) || Array.isArray(payload.models) || Array.isArray(payload.modes)) {
|
|
9431
|
+
return { controlResult: normalizeControlListResult(payload) };
|
|
9169
9432
|
}
|
|
9170
|
-
|
|
9171
|
-
|
|
9433
|
+
const looksLikeValueMutation = /^set|^change/i.test(scriptName) || payload.currentValue !== void 0 || payload.value !== void 0;
|
|
9434
|
+
if (looksLikeValueMutation) {
|
|
9435
|
+
return { controlResult: normalizeControlSetResult(payload) };
|
|
9172
9436
|
}
|
|
9173
|
-
|
|
9174
|
-
}
|
|
9175
|
-
function getCliScriptCommand(payload) {
|
|
9176
|
-
if (!payload || typeof payload !== "object") return null;
|
|
9177
|
-
if (typeof payload.sendMessage === "string" && payload.sendMessage.trim()) {
|
|
9178
|
-
return { type: "send_message", text: payload.sendMessage.trim() };
|
|
9437
|
+
if (payload.ok !== void 0 || payload.success !== void 0 || Array.isArray(payload.effects)) {
|
|
9438
|
+
return { controlResult: normalizeControlInvokeResult(payload) };
|
|
9179
9439
|
}
|
|
9180
|
-
|
|
9181
|
-
if (!command || typeof command !== "object") return null;
|
|
9182
|
-
if (command.type !== "send_message" && command.type !== "pty_write") return null;
|
|
9183
|
-
const text = typeof command.text === "string" ? command.text.trim() : typeof command.message === "string" ? command.message.trim() : "";
|
|
9184
|
-
if (!text) return null;
|
|
9185
|
-
return { type: command.type, text };
|
|
9440
|
+
return {};
|
|
9186
9441
|
}
|
|
9187
9442
|
function applyProviderPatch(h, args, payload) {
|
|
9188
9443
|
if (!payload || typeof payload !== "object") return;
|
|
@@ -9216,7 +9471,7 @@ async function executeProviderScript(h, args, scriptName) {
|
|
|
9216
9471
|
}
|
|
9217
9472
|
try {
|
|
9218
9473
|
const raw = await adapter.invokeScript(actualScriptName, normalizedArgs);
|
|
9219
|
-
const parsed =
|
|
9474
|
+
const parsed = parseCliScriptResult(raw);
|
|
9220
9475
|
if (!parsed.success) {
|
|
9221
9476
|
return { success: false, ...parsed.payload || {} };
|
|
9222
9477
|
}
|
|
@@ -9227,7 +9482,11 @@ async function executeProviderScript(h, args, scriptName) {
|
|
|
9227
9482
|
adapter.writeRaw(cliCommand.text + "\r");
|
|
9228
9483
|
}
|
|
9229
9484
|
applyProviderPatch(h, args, parsed.payload);
|
|
9230
|
-
return {
|
|
9485
|
+
return {
|
|
9486
|
+
success: true,
|
|
9487
|
+
...parsed.payload && typeof parsed.payload === "object" ? parsed.payload : { result: parsed.payload },
|
|
9488
|
+
...buildControlScriptResult(scriptName, parsed.payload)
|
|
9489
|
+
};
|
|
9231
9490
|
} catch (e) {
|
|
9232
9491
|
return { success: false, error: `Script execution failed: ${e.message}` };
|
|
9233
9492
|
}
|
|
@@ -9290,7 +9549,7 @@ async function executeProviderScript(h, args, scriptName) {
|
|
|
9290
9549
|
if (parsed && typeof parsed === "object" && parsed.success === false) {
|
|
9291
9550
|
return { success: false, ...parsed };
|
|
9292
9551
|
}
|
|
9293
|
-
return { success: true, ...parsed };
|
|
9552
|
+
return { success: true, ...parsed, ...buildControlScriptResult(scriptName, parsed) };
|
|
9294
9553
|
} catch {
|
|
9295
9554
|
return { success: true, result };
|
|
9296
9555
|
}
|
|
@@ -9301,9 +9560,6 @@ async function executeProviderScript(h, args, scriptName) {
|
|
|
9301
9560
|
return { success: false, error: `Script execution failed: ${e.message}` };
|
|
9302
9561
|
}
|
|
9303
9562
|
}
|
|
9304
|
-
async function handleExtensionScript(h, args, scriptName) {
|
|
9305
|
-
return executeProviderScript(h, args, scriptName);
|
|
9306
|
-
}
|
|
9307
9563
|
async function handleProviderScript(h, args) {
|
|
9308
9564
|
const scriptName = typeof args?.scriptName === "string" ? args.scriptName.trim() : "";
|
|
9309
9565
|
if (!scriptName) return { success: false, error: "scriptName is required" };
|
|
@@ -9746,11 +10002,7 @@ var DaemonCommandHandler = class {
|
|
|
9746
10002
|
"focus_session",
|
|
9747
10003
|
"pty_input",
|
|
9748
10004
|
"pty_resize",
|
|
9749
|
-
"invoke_provider_script"
|
|
9750
|
-
"list_extension_models",
|
|
9751
|
-
"set_extension_model",
|
|
9752
|
-
"list_extension_modes",
|
|
9753
|
-
"set_extension_mode"
|
|
10005
|
+
"invoke_provider_script"
|
|
9754
10006
|
]);
|
|
9755
10007
|
if (this._currentRoute.sessionLookupFailed && sessionScopedCommands.has(cmd)) {
|
|
9756
10008
|
const result2 = {
|
|
@@ -9862,17 +10114,9 @@ var DaemonCommandHandler = class {
|
|
|
9862
10114
|
return handleGetIdeExtensions(this, args);
|
|
9863
10115
|
case "set_ide_extension":
|
|
9864
10116
|
return handleSetIdeExtension(this, args);
|
|
9865
|
-
// ───
|
|
10117
|
+
// ─── Provider control execution (stream-commands.ts) ──────────
|
|
9866
10118
|
case "invoke_provider_script":
|
|
9867
10119
|
return handleProviderScript(this, args);
|
|
9868
|
-
case "list_extension_models":
|
|
9869
|
-
return handleExtensionScript(this, args, "listModels");
|
|
9870
|
-
case "set_extension_model":
|
|
9871
|
-
return handleExtensionScript(this, args, "setModel");
|
|
9872
|
-
case "list_extension_modes":
|
|
9873
|
-
return handleExtensionScript(this, args, "listModes");
|
|
9874
|
-
case "set_extension_mode":
|
|
9875
|
-
return handleExtensionScript(this, args, "setMode");
|
|
9876
10120
|
// ─── Provider Auto-Fix / Clone (DevServer proxy) ──────────
|
|
9877
10121
|
case "provider_auto_fix":
|
|
9878
10122
|
return this.proxyDevServerPost(args, "auto-implement");
|
|
@@ -9989,7 +10233,7 @@ var DaemonCommandHandler = class {
|
|
|
9989
10233
|
|
|
9990
10234
|
// src/commands/cli-manager.ts
|
|
9991
10235
|
var os12 = __toESM(require("os"));
|
|
9992
|
-
var
|
|
10236
|
+
var path13 = __toESM(require("path"));
|
|
9993
10237
|
var crypto4 = __toESM(require("crypto"));
|
|
9994
10238
|
var import_chalk = __toESM(require("chalk"));
|
|
9995
10239
|
init_provider_cli_adapter();
|
|
@@ -10014,6 +10258,23 @@ function getDatabaseSync() {
|
|
|
10014
10258
|
}
|
|
10015
10259
|
return CachedDatabaseSync;
|
|
10016
10260
|
}
|
|
10261
|
+
function getForcedNewSessionScriptName(provider, launchMode) {
|
|
10262
|
+
if (!provider || launchMode !== "new") return null;
|
|
10263
|
+
const resume = provider.resume;
|
|
10264
|
+
if (!resume?.supported) return null;
|
|
10265
|
+
if (Array.isArray(resume.newSessionArgs) && resume.newSessionArgs.length > 0) return null;
|
|
10266
|
+
const controls = Array.isArray(provider.controls) ? provider.controls : [];
|
|
10267
|
+
for (const control of controls) {
|
|
10268
|
+
if (control?.type !== "action") continue;
|
|
10269
|
+
const invokeScript = typeof control?.invokeScript === "string" ? control.invokeScript.trim() : "";
|
|
10270
|
+
if (!invokeScript) continue;
|
|
10271
|
+
const controlId = typeof control?.id === "string" ? control.id.trim() : "";
|
|
10272
|
+
if (controlId === "new_session" || /^new.?session$/i.test(invokeScript)) {
|
|
10273
|
+
return invokeScript;
|
|
10274
|
+
}
|
|
10275
|
+
}
|
|
10276
|
+
return null;
|
|
10277
|
+
}
|
|
10017
10278
|
var CliProviderInstance = class {
|
|
10018
10279
|
constructor(provider, workingDir, cliArgs = [], instanceId, transportFactory, options) {
|
|
10019
10280
|
this.provider = provider;
|
|
@@ -10072,6 +10333,7 @@ var CliProviderInstance = class {
|
|
|
10072
10333
|
this.detectStatusTransition();
|
|
10073
10334
|
});
|
|
10074
10335
|
await this.adapter.spawn();
|
|
10336
|
+
await this.enforceFreshSessionLaunchIfNeeded();
|
|
10075
10337
|
this.maybeAppendRuntimeRecoveryMessage(this.adapter.getRuntimeMetadata());
|
|
10076
10338
|
if (this.providerSessionId) {
|
|
10077
10339
|
this.historyWriter.compactHistorySession(this.type, this.providerSessionId);
|
|
@@ -10263,10 +10525,13 @@ var CliProviderInstance = class {
|
|
|
10263
10525
|
});
|
|
10264
10526
|
}
|
|
10265
10527
|
onEvent(event, data) {
|
|
10266
|
-
if (event === "send_message"
|
|
10267
|
-
|
|
10268
|
-
|
|
10269
|
-
|
|
10528
|
+
if (event === "send_message") {
|
|
10529
|
+
const input = normalizeInputEnvelope(data);
|
|
10530
|
+
if (input.textFallback) {
|
|
10531
|
+
void this.adapter.sendMessage(input.textFallback).catch((e) => {
|
|
10532
|
+
LOG.warn("CLI", `[${this.type}] send_message failed: ${e?.message || e}`);
|
|
10533
|
+
});
|
|
10534
|
+
}
|
|
10270
10535
|
} else if (event === "server_connected" && data?.serverConn) {
|
|
10271
10536
|
this.adapter.setServerConn(data.serverConn);
|
|
10272
10537
|
} else if (event === "resolve_action" && data) {
|
|
@@ -10284,6 +10549,23 @@ var CliProviderInstance = class {
|
|
|
10284
10549
|
}
|
|
10285
10550
|
completedDebounceTimer = null;
|
|
10286
10551
|
completedDebouncePending = null;
|
|
10552
|
+
async enforceFreshSessionLaunchIfNeeded() {
|
|
10553
|
+
const scriptName = getForcedNewSessionScriptName(this.provider, this.launchMode);
|
|
10554
|
+
if (!scriptName) return;
|
|
10555
|
+
LOG.info("CLI", `[${this.type}] forcing fresh session launch via script: ${scriptName}`);
|
|
10556
|
+
const raw = await this.adapter.invokeScript(scriptName, {});
|
|
10557
|
+
const parsed = parseCliScriptResult(raw);
|
|
10558
|
+
if (!parsed.success) {
|
|
10559
|
+
throw new Error(parsed.payload?.error || `Failed to invoke fresh-session script '${scriptName}'`);
|
|
10560
|
+
}
|
|
10561
|
+
const cliCommand = getCliScriptCommand(parsed.payload);
|
|
10562
|
+
if (cliCommand?.type === "send_message" && cliCommand.text) {
|
|
10563
|
+
await this.adapter.sendMessage(cliCommand.text);
|
|
10564
|
+
} else if (cliCommand?.type === "pty_write" && cliCommand.text) {
|
|
10565
|
+
this.adapter.writeRaw(cliCommand.text + "\r");
|
|
10566
|
+
}
|
|
10567
|
+
this.applyProviderResponse(parsed.payload, { phase: "immediate" });
|
|
10568
|
+
}
|
|
10287
10569
|
detectStatusTransition() {
|
|
10288
10570
|
const now = Date.now();
|
|
10289
10571
|
const adapterStatus = this.adapter.getStatus();
|
|
@@ -10667,10 +10949,106 @@ ${effect.notification.body || ""}`.trim();
|
|
|
10667
10949
|
};
|
|
10668
10950
|
|
|
10669
10951
|
// src/providers/acp-provider-instance.ts
|
|
10952
|
+
var path12 = __toESM(require("path"));
|
|
10670
10953
|
var import_stream = require("stream");
|
|
10671
10954
|
var import_child_process5 = require("child_process");
|
|
10672
10955
|
var import_sdk = require("@agentclientprotocol/sdk");
|
|
10673
10956
|
init_logger();
|
|
10957
|
+
function getPromptCapabilityFlags(agentCapabilities) {
|
|
10958
|
+
const prompt = agentCapabilities?.promptCapabilities || {};
|
|
10959
|
+
return {
|
|
10960
|
+
image: prompt.image === true,
|
|
10961
|
+
audio: prompt.audio === true,
|
|
10962
|
+
embeddedContext: prompt.embeddedContext === true
|
|
10963
|
+
};
|
|
10964
|
+
}
|
|
10965
|
+
function getResourceNameFromUri(uri, fallback) {
|
|
10966
|
+
try {
|
|
10967
|
+
if (uri.startsWith("file://")) {
|
|
10968
|
+
return path12.basename(new URL(uri).pathname) || fallback;
|
|
10969
|
+
}
|
|
10970
|
+
return path12.basename(uri) || fallback;
|
|
10971
|
+
} catch {
|
|
10972
|
+
return fallback;
|
|
10973
|
+
}
|
|
10974
|
+
}
|
|
10975
|
+
function inputPartToResourceLink(part, fallbackName) {
|
|
10976
|
+
if (!part.uri) return null;
|
|
10977
|
+
return {
|
|
10978
|
+
type: "resource_link",
|
|
10979
|
+
uri: part.uri,
|
|
10980
|
+
name: getResourceNameFromUri(part.uri, fallbackName),
|
|
10981
|
+
...part.mimeType ? { mimeType: part.mimeType } : {}
|
|
10982
|
+
};
|
|
10983
|
+
}
|
|
10984
|
+
function appendPromptText(promptParts, text) {
|
|
10985
|
+
const normalized = typeof text === "string" ? text.trim() : "";
|
|
10986
|
+
if (!normalized) return;
|
|
10987
|
+
const last = promptParts[promptParts.length - 1];
|
|
10988
|
+
if (last?.type === "text" && last.text === normalized) return;
|
|
10989
|
+
promptParts.push({ type: "text", text: normalized });
|
|
10990
|
+
}
|
|
10991
|
+
function buildAcpPromptParts(input, agentCapabilities) {
|
|
10992
|
+
const caps = getPromptCapabilityFlags(agentCapabilities);
|
|
10993
|
+
const promptParts = [];
|
|
10994
|
+
for (const part of input.parts) {
|
|
10995
|
+
if (part.type === "text") {
|
|
10996
|
+
promptParts.push({ type: "text", text: part.text });
|
|
10997
|
+
continue;
|
|
10998
|
+
}
|
|
10999
|
+
if (part.type === "image") {
|
|
11000
|
+
if (caps.image && part.data) {
|
|
11001
|
+
promptParts.push({
|
|
11002
|
+
type: "image",
|
|
11003
|
+
data: part.data,
|
|
11004
|
+
mimeType: part.mimeType,
|
|
11005
|
+
...part.uri ? { uri: part.uri } : {}
|
|
11006
|
+
});
|
|
11007
|
+
continue;
|
|
11008
|
+
}
|
|
11009
|
+
const fallback = inputPartToResourceLink(part, "image");
|
|
11010
|
+
if (fallback) promptParts.push(fallback);
|
|
11011
|
+
appendPromptText(promptParts, part.alt || (!part.uri ? `Attached image (${part.mimeType})` : void 0));
|
|
11012
|
+
continue;
|
|
11013
|
+
}
|
|
11014
|
+
if (part.type === "audio") {
|
|
11015
|
+
if (caps.audio && part.data) {
|
|
11016
|
+
promptParts.push({
|
|
11017
|
+
type: "audio",
|
|
11018
|
+
data: part.data,
|
|
11019
|
+
mimeType: part.mimeType
|
|
11020
|
+
});
|
|
11021
|
+
continue;
|
|
11022
|
+
}
|
|
11023
|
+
const fallback = inputPartToResourceLink(part, "audio");
|
|
11024
|
+
if (fallback) promptParts.push(fallback);
|
|
11025
|
+
appendPromptText(promptParts, part.transcript || (!part.uri ? `Attached audio (${part.mimeType})` : void 0));
|
|
11026
|
+
continue;
|
|
11027
|
+
}
|
|
11028
|
+
if (part.type === "resource") {
|
|
11029
|
+
if (caps.embeddedContext && (part.text || part.data)) {
|
|
11030
|
+
promptParts.push({
|
|
11031
|
+
type: "resource",
|
|
11032
|
+
resource: part.text ? { uri: part.uri, text: part.text, mimeType: part.mimeType ?? null } : { uri: part.uri, blob: part.data || "", mimeType: part.mimeType ?? null }
|
|
11033
|
+
});
|
|
11034
|
+
continue;
|
|
11035
|
+
}
|
|
11036
|
+
const fallback = inputPartToResourceLink(part, part.name || "resource");
|
|
11037
|
+
if (fallback) promptParts.push(fallback);
|
|
11038
|
+
appendPromptText(promptParts, part.text || (!part.uri && part.name ? part.name : void 0));
|
|
11039
|
+
continue;
|
|
11040
|
+
}
|
|
11041
|
+
if (part.type === "video") {
|
|
11042
|
+
const fallback = inputPartToResourceLink(part, "video");
|
|
11043
|
+
if (fallback) promptParts.push(fallback);
|
|
11044
|
+
appendPromptText(promptParts, !part.uri ? `Attached video (${part.mimeType})` : void 0);
|
|
11045
|
+
}
|
|
11046
|
+
}
|
|
11047
|
+
if (!promptParts.some((part) => part.type === "text") && input.textFallback) {
|
|
11048
|
+
promptParts.unshift({ type: "text", text: input.textFallback });
|
|
11049
|
+
}
|
|
11050
|
+
return promptParts;
|
|
11051
|
+
}
|
|
10674
11052
|
var AcpProviderInstance = class {
|
|
10675
11053
|
constructor(provider, workingDir, cliArgs = []) {
|
|
10676
11054
|
this.cliArgs = cliArgs;
|
|
@@ -10799,8 +11177,10 @@ var AcpProviderInstance = class {
|
|
|
10799
11177
|
};
|
|
10800
11178
|
}
|
|
10801
11179
|
onEvent(event, data) {
|
|
10802
|
-
if (event === "send_message"
|
|
10803
|
-
|
|
11180
|
+
if (event === "send_message") {
|
|
11181
|
+
const input = normalizeInputEnvelope(data);
|
|
11182
|
+
const promptParts = buildAcpPromptParts(input, this.agentCapabilities);
|
|
11183
|
+
this.sendPrompt(input.textFallback, promptParts.length > 0 ? promptParts : void 0).catch(
|
|
10804
11184
|
(e) => this.log.warn(`[${this.type}] sendPrompt error: ${e?.message}`)
|
|
10805
11185
|
);
|
|
10806
11186
|
} else if (event === "resolve_action") {
|
|
@@ -11225,18 +11605,34 @@ var AcpProviderInstance = class {
|
|
|
11225
11605
|
this.log.warn(`[${this.type}] Cannot send prompt: no active connection/session`);
|
|
11226
11606
|
return;
|
|
11227
11607
|
}
|
|
11228
|
-
|
|
11229
|
-
|
|
11230
|
-
|
|
11231
|
-
|
|
11232
|
-
|
|
11233
|
-
|
|
11234
|
-
|
|
11235
|
-
|
|
11236
|
-
|
|
11237
|
-
|
|
11238
|
-
|
|
11239
|
-
|
|
11608
|
+
const promptParts = contentBlocks && contentBlocks.length > 0 ? contentBlocks.map((b) => {
|
|
11609
|
+
if (b.type === "text") return { type: "text", text: b.text };
|
|
11610
|
+
if (b.type === "image") {
|
|
11611
|
+
return {
|
|
11612
|
+
type: "image",
|
|
11613
|
+
data: b.data,
|
|
11614
|
+
mimeType: b.mimeType,
|
|
11615
|
+
...b.uri ? { uri: b.uri } : {}
|
|
11616
|
+
};
|
|
11617
|
+
}
|
|
11618
|
+
if (b.type === "audio") {
|
|
11619
|
+
return {
|
|
11620
|
+
type: "audio",
|
|
11621
|
+
data: b.data,
|
|
11622
|
+
mimeType: b.mimeType
|
|
11623
|
+
};
|
|
11624
|
+
}
|
|
11625
|
+
if (b.type === "resource_link") {
|
|
11626
|
+
return {
|
|
11627
|
+
type: "resource_link",
|
|
11628
|
+
uri: b.uri,
|
|
11629
|
+
name: b.name,
|
|
11630
|
+
...b.mimeType ? { mimeType: b.mimeType } : {}
|
|
11631
|
+
};
|
|
11632
|
+
}
|
|
11633
|
+
if (b.type === "resource") return { type: "resource", resource: b.resource };
|
|
11634
|
+
return { type: "text", text: flattenContent([b]) };
|
|
11635
|
+
}) : [{ type: "text", text }];
|
|
11240
11636
|
this.messages.push({
|
|
11241
11637
|
role: "user",
|
|
11242
11638
|
content: contentBlocks && contentBlocks.length > 0 ? contentBlocks : text,
|
|
@@ -11300,6 +11696,13 @@ var AcpProviderInstance = class {
|
|
|
11300
11696
|
this.partialBlocks.push({
|
|
11301
11697
|
type: "image",
|
|
11302
11698
|
data: content.data,
|
|
11699
|
+
mimeType: content.mimeType,
|
|
11700
|
+
...content.uri ? { uri: content.uri } : {}
|
|
11701
|
+
});
|
|
11702
|
+
} else if (content.type === "audio") {
|
|
11703
|
+
this.partialBlocks.push({
|
|
11704
|
+
type: "audio",
|
|
11705
|
+
data: content.data,
|
|
11303
11706
|
mimeType: content.mimeType
|
|
11304
11707
|
});
|
|
11305
11708
|
} else if (content.type === "resource_link") {
|
|
@@ -11691,7 +12094,7 @@ function resolveCliSessionBinding(provider, normalizedType, cliArgs, requestedRe
|
|
|
11691
12094
|
};
|
|
11692
12095
|
}
|
|
11693
12096
|
if (!supportsExplicitSessionStart(resume)) {
|
|
11694
|
-
return { cliArgs: baseArgs, launchMode: "
|
|
12097
|
+
return { cliArgs: baseArgs, launchMode: "new" };
|
|
11695
12098
|
}
|
|
11696
12099
|
const providerSessionId = crypto4.randomUUID();
|
|
11697
12100
|
const newSessionArgs = expandResumeArgs(resume.newSessionArgs, providerSessionId);
|
|
@@ -11839,7 +12242,7 @@ var DaemonCliManager = class {
|
|
|
11839
12242
|
async startSession(cliType, workingDir, cliArgs, initialModel, options) {
|
|
11840
12243
|
const trimmed = (workingDir || "").trim();
|
|
11841
12244
|
if (!trimmed) throw new Error("working directory required");
|
|
11842
|
-
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os12.homedir()) :
|
|
12245
|
+
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os12.homedir()) : path13.resolve(trimmed);
|
|
11843
12246
|
const normalizedType = this.providerLoader.resolveAlias(cliType);
|
|
11844
12247
|
const provider = this.providerLoader.getByAlias(cliType);
|
|
11845
12248
|
const key = crypto4.randomUUID();
|
|
@@ -11887,7 +12290,8 @@ ${installInfo}`
|
|
|
11887
12290
|
instanceManager2.removeInstance(key);
|
|
11888
12291
|
},
|
|
11889
12292
|
sendMessage: async (text) => {
|
|
11890
|
-
|
|
12293
|
+
const input = normalizeInputEnvelope(text);
|
|
12294
|
+
acpInstance.onEvent("send_message", { input });
|
|
11891
12295
|
},
|
|
11892
12296
|
getStatus: () => {
|
|
11893
12297
|
const state = acpInstance.getState();
|
|
@@ -12296,7 +12700,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
12296
12700
|
if (!found) throw new Error(`CLI agent not running: ${agentType}`);
|
|
12297
12701
|
const { adapter, key } = found;
|
|
12298
12702
|
if (action === "send_chat") {
|
|
12299
|
-
const
|
|
12703
|
+
const input = normalizeInputEnvelope(args?.input ? { input: args.input } : args);
|
|
12704
|
+
const message = input.textFallback;
|
|
12300
12705
|
if (!message) throw new Error("message required for send_chat");
|
|
12301
12706
|
await adapter.sendMessage(message);
|
|
12302
12707
|
return { success: true, status: "generating" };
|
|
@@ -12318,14 +12723,144 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
12318
12723
|
var import_child_process6 = require("child_process");
|
|
12319
12724
|
var net = __toESM(require("net"));
|
|
12320
12725
|
var os14 = __toESM(require("os"));
|
|
12321
|
-
var
|
|
12726
|
+
var path15 = __toESM(require("path"));
|
|
12322
12727
|
|
|
12323
12728
|
// src/providers/provider-loader.ts
|
|
12324
12729
|
var fs6 = __toESM(require("fs"));
|
|
12325
|
-
var
|
|
12730
|
+
var path14 = __toESM(require("path"));
|
|
12326
12731
|
var os13 = __toESM(require("os"));
|
|
12327
12732
|
var chokidar = __toESM(require("chokidar"));
|
|
12328
12733
|
init_logger();
|
|
12734
|
+
|
|
12735
|
+
// src/providers/provider-schema.ts
|
|
12736
|
+
var KNOWN_PROVIDER_FIELDS = /* @__PURE__ */ new Set([
|
|
12737
|
+
"type",
|
|
12738
|
+
"name",
|
|
12739
|
+
"category",
|
|
12740
|
+
"aliases",
|
|
12741
|
+
"cdpPorts",
|
|
12742
|
+
"targetFilter",
|
|
12743
|
+
"cli",
|
|
12744
|
+
"icon",
|
|
12745
|
+
"displayName",
|
|
12746
|
+
"install",
|
|
12747
|
+
"versionCommand",
|
|
12748
|
+
"testedVersions",
|
|
12749
|
+
"processNames",
|
|
12750
|
+
"launch",
|
|
12751
|
+
"paths",
|
|
12752
|
+
"extensionId",
|
|
12753
|
+
"extensionIdPattern",
|
|
12754
|
+
"extensionIdPattern_flags",
|
|
12755
|
+
"compatibility",
|
|
12756
|
+
"defaultScriptDir",
|
|
12757
|
+
"binary",
|
|
12758
|
+
"spawn",
|
|
12759
|
+
"approvalKeys",
|
|
12760
|
+
"patterns",
|
|
12761
|
+
"cleanOutput",
|
|
12762
|
+
"resume",
|
|
12763
|
+
"sessionProbe",
|
|
12764
|
+
"approvalPositiveHints",
|
|
12765
|
+
"scripts",
|
|
12766
|
+
"vscodeCommands",
|
|
12767
|
+
"inputMethod",
|
|
12768
|
+
"inputSelector",
|
|
12769
|
+
"webviewMatchText",
|
|
12770
|
+
"os",
|
|
12771
|
+
"versions",
|
|
12772
|
+
"overrides",
|
|
12773
|
+
"settings",
|
|
12774
|
+
"controls",
|
|
12775
|
+
"staticConfigOptions",
|
|
12776
|
+
"spawnArgBuilder",
|
|
12777
|
+
"auth",
|
|
12778
|
+
"contractVersion",
|
|
12779
|
+
"capabilities",
|
|
12780
|
+
"providerVersion",
|
|
12781
|
+
"status",
|
|
12782
|
+
"details",
|
|
12783
|
+
"sendDelayMs",
|
|
12784
|
+
"sendKey",
|
|
12785
|
+
"submitStrategy",
|
|
12786
|
+
"disableUpstream"
|
|
12787
|
+
]);
|
|
12788
|
+
var VALUE_CONTROL_TYPES = /* @__PURE__ */ new Set(["select", "toggle", "cycle", "slider"]);
|
|
12789
|
+
function validateProviderDefinition(raw) {
|
|
12790
|
+
const errors = [];
|
|
12791
|
+
const warnings = [];
|
|
12792
|
+
if (!raw || typeof raw !== "object") {
|
|
12793
|
+
return { errors: ["Provider definition must be an object"], warnings };
|
|
12794
|
+
}
|
|
12795
|
+
const provider = raw;
|
|
12796
|
+
if (!provider.type) errors.push("Missing required field: type");
|
|
12797
|
+
if (!provider.name) errors.push("Missing required field: name");
|
|
12798
|
+
if (!provider.category) {
|
|
12799
|
+
errors.push("Missing required field: category");
|
|
12800
|
+
} else if (!["ide", "extension", "cli", "acp"].includes(String(provider.category))) {
|
|
12801
|
+
errors.push(`Invalid category: ${String(provider.category)}`);
|
|
12802
|
+
}
|
|
12803
|
+
for (const key of Object.keys(provider)) {
|
|
12804
|
+
if (!KNOWN_PROVIDER_FIELDS.has(key)) {
|
|
12805
|
+
warnings.push(`Unknown provider field: ${key}`);
|
|
12806
|
+
}
|
|
12807
|
+
}
|
|
12808
|
+
const category = provider.category;
|
|
12809
|
+
if (category === "cli" || category === "acp") {
|
|
12810
|
+
const spawn4 = provider.spawn;
|
|
12811
|
+
const command = spawn4 && typeof spawn4 === "object" ? spawn4.command : void 0;
|
|
12812
|
+
if (!spawn4 || typeof spawn4 !== "object") {
|
|
12813
|
+
errors.push(`${String(category).toUpperCase()}/CLI providers must have spawn config`);
|
|
12814
|
+
} else if (typeof command !== "string" || !command.trim()) {
|
|
12815
|
+
errors.push("spawn.command is required");
|
|
12816
|
+
}
|
|
12817
|
+
}
|
|
12818
|
+
if ((category === "ide" || category === "extension") && provider.cdpPorts !== void 0) {
|
|
12819
|
+
if (!Array.isArray(provider.cdpPorts) || provider.cdpPorts.length === 0) {
|
|
12820
|
+
warnings.push("IDE/Extension providers should have cdpPorts");
|
|
12821
|
+
}
|
|
12822
|
+
}
|
|
12823
|
+
if (category === "extension" && !provider.extensionId) {
|
|
12824
|
+
warnings.push("Extension providers should have extensionId");
|
|
12825
|
+
}
|
|
12826
|
+
for (const control of Array.isArray(provider.controls) ? provider.controls : []) {
|
|
12827
|
+
validateControl(control, errors);
|
|
12828
|
+
}
|
|
12829
|
+
return { errors, warnings };
|
|
12830
|
+
}
|
|
12831
|
+
function validateControl(control, errors) {
|
|
12832
|
+
if (!control || typeof control !== "object") {
|
|
12833
|
+
errors.push("controls: each control must be an object");
|
|
12834
|
+
return;
|
|
12835
|
+
}
|
|
12836
|
+
const id = typeof control.id === "string" && control.id.trim() ? control.id.trim() : "unknown";
|
|
12837
|
+
const prefix = `controls.${id}`;
|
|
12838
|
+
if (!control.id || !String(control.id).trim()) errors.push(`${prefix}: id is required`);
|
|
12839
|
+
if (!control.type) errors.push(`${prefix}: type is required`);
|
|
12840
|
+
if (!control.label || !String(control.label).trim()) errors.push(`${prefix}: label is required`);
|
|
12841
|
+
if (!control.placement) errors.push(`${prefix}: placement is required`);
|
|
12842
|
+
if (control.dynamic && !control.listScript) {
|
|
12843
|
+
errors.push(`${prefix}: dynamic controls require listScript`);
|
|
12844
|
+
}
|
|
12845
|
+
if (VALUE_CONTROL_TYPES.has(control.type) && !control.setScript) {
|
|
12846
|
+
errors.push(`${prefix}: ${control.type} controls require setScript`);
|
|
12847
|
+
}
|
|
12848
|
+
if (control.type === "action" && !control.invokeScript) {
|
|
12849
|
+
errors.push(`${prefix}: action controls require invokeScript`);
|
|
12850
|
+
}
|
|
12851
|
+
if (control.type === "slider") {
|
|
12852
|
+
if (typeof control.min !== "number" || typeof control.max !== "number") {
|
|
12853
|
+
errors.push(`${prefix}: slider controls require numeric min and max`);
|
|
12854
|
+
} else if (control.min > control.max) {
|
|
12855
|
+
errors.push(`${prefix}: slider min cannot exceed max`);
|
|
12856
|
+
}
|
|
12857
|
+
}
|
|
12858
|
+
if (control.readFrom !== void 0 && (typeof control.readFrom !== "string" || !control.readFrom.trim())) {
|
|
12859
|
+
errors.push(`${prefix}: readFrom must be a non-empty string when provided`);
|
|
12860
|
+
}
|
|
12861
|
+
}
|
|
12862
|
+
|
|
12863
|
+
// src/providers/provider-loader.ts
|
|
12329
12864
|
var ProviderLoader = class _ProviderLoader {
|
|
12330
12865
|
providers = /* @__PURE__ */ new Map();
|
|
12331
12866
|
providerAvailability = /* @__PURE__ */ new Map();
|
|
@@ -12344,12 +12879,12 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12344
12879
|
static META_FILE = ".meta.json";
|
|
12345
12880
|
constructor(options) {
|
|
12346
12881
|
this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
|
|
12347
|
-
const defaultProvidersDir =
|
|
12882
|
+
const defaultProvidersDir = path14.join(os13.homedir(), ".adhdev", "providers");
|
|
12348
12883
|
if (options?.userDir) {
|
|
12349
12884
|
this.userDir = options.userDir;
|
|
12350
12885
|
this.log(`Config 'providerDir' applied: ${this.userDir}`);
|
|
12351
12886
|
} else {
|
|
12352
|
-
const localRepoPath =
|
|
12887
|
+
const localRepoPath = path14.resolve(__dirname, "../../../../../adhdev-providers");
|
|
12353
12888
|
if (fs6.existsSync(localRepoPath)) {
|
|
12354
12889
|
this.userDir = localRepoPath;
|
|
12355
12890
|
this.log(`Auto-detected local public repository: ${this.userDir} (Dev workspace speedup)`);
|
|
@@ -12358,7 +12893,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12358
12893
|
this.log(`Using default user providers directory: ${this.userDir}`);
|
|
12359
12894
|
}
|
|
12360
12895
|
}
|
|
12361
|
-
this.upstreamDir =
|
|
12896
|
+
this.upstreamDir = path14.join(defaultProvidersDir, ".upstream");
|
|
12362
12897
|
this.disableUpstream = options?.disableUpstream ?? false;
|
|
12363
12898
|
}
|
|
12364
12899
|
log(msg) {
|
|
@@ -12388,7 +12923,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12388
12923
|
* Canonical provider directory shape for a given root.
|
|
12389
12924
|
*/
|
|
12390
12925
|
getProviderDir(root, category, type) {
|
|
12391
|
-
return
|
|
12926
|
+
return path14.join(root, category, type);
|
|
12392
12927
|
}
|
|
12393
12928
|
/**
|
|
12394
12929
|
* Canonical user override directory for a provider.
|
|
@@ -12415,7 +12950,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12415
12950
|
resolveProviderFile(type, ...segments) {
|
|
12416
12951
|
const dir = this.findProviderDirInternal(type);
|
|
12417
12952
|
if (!dir) return null;
|
|
12418
|
-
return
|
|
12953
|
+
return path14.join(dir, ...segments);
|
|
12419
12954
|
}
|
|
12420
12955
|
/**
|
|
12421
12956
|
* Load all providers (3-tier priority)
|
|
@@ -12454,7 +12989,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12454
12989
|
if (!fs6.existsSync(this.upstreamDir)) return false;
|
|
12455
12990
|
try {
|
|
12456
12991
|
return fs6.readdirSync(this.upstreamDir).some(
|
|
12457
|
-
(d) => fs6.statSync(
|
|
12992
|
+
(d) => fs6.statSync(path14.join(this.upstreamDir, d)).isDirectory()
|
|
12458
12993
|
);
|
|
12459
12994
|
} catch {
|
|
12460
12995
|
return false;
|
|
@@ -12769,8 +13304,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12769
13304
|
resolved._resolvedScriptDir = entry.scriptDir;
|
|
12770
13305
|
resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
|
|
12771
13306
|
if (providerDir) {
|
|
12772
|
-
const fullDir =
|
|
12773
|
-
resolved._resolvedScriptsPath = fs6.existsSync(
|
|
13307
|
+
const fullDir = path14.join(providerDir, entry.scriptDir);
|
|
13308
|
+
resolved._resolvedScriptsPath = fs6.existsSync(path14.join(fullDir, "scripts.js")) ? path14.join(fullDir, "scripts.js") : fullDir;
|
|
12774
13309
|
}
|
|
12775
13310
|
matched = true;
|
|
12776
13311
|
}
|
|
@@ -12785,8 +13320,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12785
13320
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
12786
13321
|
resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
|
|
12787
13322
|
if (providerDir) {
|
|
12788
|
-
const fullDir =
|
|
12789
|
-
resolved._resolvedScriptsPath = fs6.existsSync(
|
|
13323
|
+
const fullDir = path14.join(providerDir, base.defaultScriptDir);
|
|
13324
|
+
resolved._resolvedScriptsPath = fs6.existsSync(path14.join(fullDir, "scripts.js")) ? path14.join(fullDir, "scripts.js") : fullDir;
|
|
12790
13325
|
}
|
|
12791
13326
|
}
|
|
12792
13327
|
resolved._versionWarning = `Version ${currentVersion} not in compatibility matrix. Using default scripts.`;
|
|
@@ -12803,8 +13338,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12803
13338
|
resolved._resolvedScriptDir = dirOverride;
|
|
12804
13339
|
resolved._resolvedScriptsSource = `versions:${range}`;
|
|
12805
13340
|
if (providerDir) {
|
|
12806
|
-
const fullDir =
|
|
12807
|
-
resolved._resolvedScriptsPath = fs6.existsSync(
|
|
13341
|
+
const fullDir = path14.join(providerDir, dirOverride);
|
|
13342
|
+
resolved._resolvedScriptsPath = fs6.existsSync(path14.join(fullDir, "scripts.js")) ? path14.join(fullDir, "scripts.js") : fullDir;
|
|
12808
13343
|
}
|
|
12809
13344
|
}
|
|
12810
13345
|
} else if (override.scripts) {
|
|
@@ -12820,8 +13355,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12820
13355
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
12821
13356
|
resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
|
|
12822
13357
|
if (providerDir) {
|
|
12823
|
-
const fullDir =
|
|
12824
|
-
resolved._resolvedScriptsPath = fs6.existsSync(
|
|
13358
|
+
const fullDir = path14.join(providerDir, base.defaultScriptDir);
|
|
13359
|
+
resolved._resolvedScriptsPath = fs6.existsSync(path14.join(fullDir, "scripts.js")) ? path14.join(fullDir, "scripts.js") : fullDir;
|
|
12825
13360
|
}
|
|
12826
13361
|
}
|
|
12827
13362
|
}
|
|
@@ -12846,14 +13381,14 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12846
13381
|
this.log(` [loadScriptsFromDir] ${type}: providerDir not found`);
|
|
12847
13382
|
return null;
|
|
12848
13383
|
}
|
|
12849
|
-
const dir =
|
|
13384
|
+
const dir = path14.join(providerDir, scriptDir);
|
|
12850
13385
|
if (!fs6.existsSync(dir)) {
|
|
12851
13386
|
this.log(` [loadScriptsFromDir] ${type}: dir not found: ${dir}`);
|
|
12852
13387
|
return null;
|
|
12853
13388
|
}
|
|
12854
13389
|
const cached = this.scriptsCache.get(dir);
|
|
12855
13390
|
if (cached) return cached;
|
|
12856
|
-
const scriptsJs =
|
|
13391
|
+
const scriptsJs = path14.join(dir, "scripts.js");
|
|
12857
13392
|
if (fs6.existsSync(scriptsJs)) {
|
|
12858
13393
|
try {
|
|
12859
13394
|
delete require.cache[require.resolve(scriptsJs)];
|
|
@@ -12895,7 +13430,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12895
13430
|
return;
|
|
12896
13431
|
}
|
|
12897
13432
|
if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
|
|
12898
|
-
this.log(`File changed: ${
|
|
13433
|
+
this.log(`File changed: ${path14.basename(filePath)}, reloading...`);
|
|
12899
13434
|
this.reload();
|
|
12900
13435
|
}
|
|
12901
13436
|
};
|
|
@@ -12950,7 +13485,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12950
13485
|
}
|
|
12951
13486
|
const https = require("https");
|
|
12952
13487
|
const { execSync: execSync7 } = require("child_process");
|
|
12953
|
-
const metaPath =
|
|
13488
|
+
const metaPath = path14.join(this.upstreamDir, _ProviderLoader.META_FILE);
|
|
12954
13489
|
let prevEtag = "";
|
|
12955
13490
|
let prevTimestamp = 0;
|
|
12956
13491
|
try {
|
|
@@ -13010,17 +13545,17 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
13010
13545
|
return { updated: false };
|
|
13011
13546
|
}
|
|
13012
13547
|
this.log("Downloading latest providers from GitHub...");
|
|
13013
|
-
const tmpTar =
|
|
13014
|
-
const tmpExtract =
|
|
13548
|
+
const tmpTar = path14.join(os13.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
|
|
13549
|
+
const tmpExtract = path14.join(os13.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
|
|
13015
13550
|
await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
|
|
13016
13551
|
fs6.mkdirSync(tmpExtract, { recursive: true });
|
|
13017
13552
|
execSync7(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
|
|
13018
13553
|
const extracted = fs6.readdirSync(tmpExtract);
|
|
13019
13554
|
const rootDir = extracted.find(
|
|
13020
|
-
(d) => fs6.statSync(
|
|
13555
|
+
(d) => fs6.statSync(path14.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
|
|
13021
13556
|
);
|
|
13022
13557
|
if (!rootDir) throw new Error("Unexpected tarball structure");
|
|
13023
|
-
const sourceDir =
|
|
13558
|
+
const sourceDir = path14.join(tmpExtract, rootDir);
|
|
13024
13559
|
const backupDir = this.upstreamDir + ".bak";
|
|
13025
13560
|
if (fs6.existsSync(this.upstreamDir)) {
|
|
13026
13561
|
if (fs6.existsSync(backupDir)) fs6.rmSync(backupDir, { recursive: true, force: true });
|
|
@@ -13095,8 +13630,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
13095
13630
|
copyDirRecursive(src, dest) {
|
|
13096
13631
|
fs6.mkdirSync(dest, { recursive: true });
|
|
13097
13632
|
for (const entry of fs6.readdirSync(src, { withFileTypes: true })) {
|
|
13098
|
-
const srcPath =
|
|
13099
|
-
const destPath =
|
|
13633
|
+
const srcPath = path14.join(src, entry.name);
|
|
13634
|
+
const destPath = path14.join(dest, entry.name);
|
|
13100
13635
|
if (entry.isDirectory()) {
|
|
13101
13636
|
this.copyDirRecursive(srcPath, destPath);
|
|
13102
13637
|
} else {
|
|
@@ -13107,7 +13642,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
13107
13642
|
/** .meta.json save */
|
|
13108
13643
|
writeMeta(metaPath, etag, timestamp) {
|
|
13109
13644
|
try {
|
|
13110
|
-
fs6.mkdirSync(
|
|
13645
|
+
fs6.mkdirSync(path14.dirname(metaPath), { recursive: true });
|
|
13111
13646
|
fs6.writeFileSync(metaPath, JSON.stringify({
|
|
13112
13647
|
etag,
|
|
13113
13648
|
timestamp,
|
|
@@ -13124,7 +13659,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
13124
13659
|
const scan = (d) => {
|
|
13125
13660
|
try {
|
|
13126
13661
|
for (const entry of fs6.readdirSync(d, { withFileTypes: true })) {
|
|
13127
|
-
if (entry.isDirectory()) scan(
|
|
13662
|
+
if (entry.isDirectory()) scan(path14.join(d, entry.name));
|
|
13128
13663
|
else if (entry.name === "provider.json") count++;
|
|
13129
13664
|
}
|
|
13130
13665
|
} catch {
|
|
@@ -13309,17 +13844,17 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
13309
13844
|
for (const root of searchRoots) {
|
|
13310
13845
|
if (!fs6.existsSync(root)) continue;
|
|
13311
13846
|
const candidate = this.getProviderDir(root, cat, type);
|
|
13312
|
-
if (fs6.existsSync(
|
|
13313
|
-
const catDir =
|
|
13847
|
+
if (fs6.existsSync(path14.join(candidate, "provider.json"))) return candidate;
|
|
13848
|
+
const catDir = path14.join(root, cat);
|
|
13314
13849
|
if (fs6.existsSync(catDir)) {
|
|
13315
13850
|
try {
|
|
13316
13851
|
for (const entry of fs6.readdirSync(catDir, { withFileTypes: true })) {
|
|
13317
13852
|
if (!entry.isDirectory()) continue;
|
|
13318
|
-
const jsonPath =
|
|
13853
|
+
const jsonPath = path14.join(catDir, entry.name, "provider.json");
|
|
13319
13854
|
if (fs6.existsSync(jsonPath)) {
|
|
13320
13855
|
try {
|
|
13321
13856
|
const data = JSON.parse(fs6.readFileSync(jsonPath, "utf-8"));
|
|
13322
|
-
if (data.type === type) return
|
|
13857
|
+
if (data.type === type) return path14.join(catDir, entry.name);
|
|
13323
13858
|
} catch {
|
|
13324
13859
|
}
|
|
13325
13860
|
}
|
|
@@ -13336,7 +13871,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
13336
13871
|
* (template substitution is NOT applied here — scripts.js handles that)
|
|
13337
13872
|
*/
|
|
13338
13873
|
buildScriptWrappersFromDir(dir) {
|
|
13339
|
-
const scriptsJs =
|
|
13874
|
+
const scriptsJs = path14.join(dir, "scripts.js");
|
|
13340
13875
|
if (fs6.existsSync(scriptsJs)) {
|
|
13341
13876
|
try {
|
|
13342
13877
|
delete require.cache[require.resolve(scriptsJs)];
|
|
@@ -13350,7 +13885,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
13350
13885
|
for (const file of fs6.readdirSync(dir)) {
|
|
13351
13886
|
if (!file.endsWith(".js")) continue;
|
|
13352
13887
|
const scriptName = toCamel(file.replace(".js", ""));
|
|
13353
|
-
const filePath =
|
|
13888
|
+
const filePath = path14.join(dir, file);
|
|
13354
13889
|
result[scriptName] = (...args) => {
|
|
13355
13890
|
try {
|
|
13356
13891
|
let content = fs6.readFileSync(filePath, "utf-8");
|
|
@@ -13410,24 +13945,28 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
13410
13945
|
}
|
|
13411
13946
|
const hasJson = entries.some((e) => e.name === "provider.json");
|
|
13412
13947
|
if (hasJson) {
|
|
13413
|
-
const jsonPath =
|
|
13948
|
+
const jsonPath = path14.join(d, "provider.json");
|
|
13414
13949
|
try {
|
|
13415
13950
|
const raw = fs6.readFileSync(jsonPath, "utf-8");
|
|
13416
13951
|
const mod = JSON.parse(raw);
|
|
13417
|
-
if (
|
|
13418
|
-
|
|
13952
|
+
if (typeof mod.extensionIdPattern === "string") {
|
|
13953
|
+
const flags = mod.extensionIdPattern_flags || "";
|
|
13954
|
+
mod.extensionIdPattern = new RegExp(mod.extensionIdPattern, flags);
|
|
13955
|
+
}
|
|
13956
|
+
const { extensionIdPattern_flags, extensionIdPattern, ...providerFields } = mod;
|
|
13957
|
+
const normalizedProvider = {
|
|
13958
|
+
...providerFields,
|
|
13959
|
+
...extensionIdPattern instanceof RegExp ? { extensionIdPattern } : {}
|
|
13960
|
+
};
|
|
13961
|
+
const validation = validateProviderDefinition(normalizedProvider);
|
|
13962
|
+
for (const warning of validation.warnings) {
|
|
13963
|
+
this.log(`\u26A0 ${jsonPath}: ${warning}`);
|
|
13964
|
+
}
|
|
13965
|
+
if (validation.errors.length > 0) {
|
|
13966
|
+
this.log(`\u26A0 Invalid provider at ${jsonPath}: ${validation.errors.join("; ")}`);
|
|
13419
13967
|
} else {
|
|
13420
|
-
if (typeof mod.extensionIdPattern === "string") {
|
|
13421
|
-
const flags = mod.extensionIdPattern_flags || "";
|
|
13422
|
-
mod.extensionIdPattern = new RegExp(mod.extensionIdPattern, flags);
|
|
13423
|
-
}
|
|
13424
|
-
const { extensionIdPattern_flags, extensionIdPattern, ...providerFields } = mod;
|
|
13425
|
-
const normalizedProvider = {
|
|
13426
|
-
...providerFields,
|
|
13427
|
-
...extensionIdPattern instanceof RegExp ? { extensionIdPattern } : {}
|
|
13428
|
-
};
|
|
13429
13968
|
const hasCompatibility = Array.isArray(normalizedProvider.compatibility);
|
|
13430
|
-
const scriptsPath =
|
|
13969
|
+
const scriptsPath = path14.join(d, "scripts.js");
|
|
13431
13970
|
if (!hasCompatibility && fs6.existsSync(scriptsPath)) {
|
|
13432
13971
|
try {
|
|
13433
13972
|
delete require.cache[require.resolve(scriptsPath)];
|
|
@@ -13453,7 +13992,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
13453
13992
|
if (!entry.isDirectory()) continue;
|
|
13454
13993
|
if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
|
|
13455
13994
|
if (excludeDirs && d === dir && excludeDirs.includes(entry.name)) continue;
|
|
13456
|
-
scan(
|
|
13995
|
+
scan(path14.join(d, entry.name));
|
|
13457
13996
|
}
|
|
13458
13997
|
}
|
|
13459
13998
|
};
|
|
@@ -13711,8 +14250,8 @@ function detectCurrentWorkspace(ideId) {
|
|
|
13711
14250
|
const appNameMap = getMacAppIdentifiers();
|
|
13712
14251
|
const appName = appNameMap[ideId];
|
|
13713
14252
|
if (appName) {
|
|
13714
|
-
const storagePath =
|
|
13715
|
-
process.env.APPDATA ||
|
|
14253
|
+
const storagePath = path15.join(
|
|
14254
|
+
process.env.APPDATA || path15.join(os14.homedir(), "AppData", "Roaming"),
|
|
13716
14255
|
appName,
|
|
13717
14256
|
"storage.json"
|
|
13718
14257
|
);
|
|
@@ -13890,9 +14429,9 @@ init_logger();
|
|
|
13890
14429
|
|
|
13891
14430
|
// src/logging/command-log.ts
|
|
13892
14431
|
var fs7 = __toESM(require("fs"));
|
|
13893
|
-
var
|
|
14432
|
+
var path16 = __toESM(require("path"));
|
|
13894
14433
|
var os15 = __toESM(require("os"));
|
|
13895
|
-
var LOG_DIR2 = process.platform === "win32" ?
|
|
14434
|
+
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");
|
|
13896
14435
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
13897
14436
|
var MAX_DAYS = 7;
|
|
13898
14437
|
try {
|
|
@@ -13930,13 +14469,13 @@ function getDateStr2() {
|
|
|
13930
14469
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
13931
14470
|
}
|
|
13932
14471
|
var currentDate2 = getDateStr2();
|
|
13933
|
-
var currentFile =
|
|
14472
|
+
var currentFile = path16.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
13934
14473
|
var writeCount2 = 0;
|
|
13935
14474
|
function checkRotation() {
|
|
13936
14475
|
const today = getDateStr2();
|
|
13937
14476
|
if (today !== currentDate2) {
|
|
13938
14477
|
currentDate2 = today;
|
|
13939
|
-
currentFile =
|
|
14478
|
+
currentFile = path16.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
13940
14479
|
cleanOldFiles();
|
|
13941
14480
|
}
|
|
13942
14481
|
}
|
|
@@ -13950,7 +14489,7 @@ function cleanOldFiles() {
|
|
|
13950
14489
|
const dateMatch = file.match(/commands-(\d{4}-\d{2}-\d{2})/);
|
|
13951
14490
|
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
13952
14491
|
try {
|
|
13953
|
-
fs7.unlinkSync(
|
|
14492
|
+
fs7.unlinkSync(path16.join(LOG_DIR2, file));
|
|
13954
14493
|
} catch {
|
|
13955
14494
|
}
|
|
13956
14495
|
}
|
|
@@ -14267,13 +14806,13 @@ var import_child_process7 = require("child_process");
|
|
|
14267
14806
|
var import_child_process8 = require("child_process");
|
|
14268
14807
|
var fs8 = __toESM(require("fs"));
|
|
14269
14808
|
var os17 = __toESM(require("os"));
|
|
14270
|
-
var
|
|
14809
|
+
var path17 = __toESM(require("path"));
|
|
14271
14810
|
var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
|
|
14272
14811
|
function getUpgradeLogPath() {
|
|
14273
14812
|
const home = os17.homedir();
|
|
14274
|
-
const dir =
|
|
14813
|
+
const dir = path17.join(home, ".adhdev");
|
|
14275
14814
|
fs8.mkdirSync(dir, { recursive: true });
|
|
14276
|
-
return
|
|
14815
|
+
return path17.join(dir, "daemon-upgrade.log");
|
|
14277
14816
|
}
|
|
14278
14817
|
function appendUpgradeLog(message) {
|
|
14279
14818
|
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
|
|
@@ -14313,7 +14852,7 @@ async function waitForPidExit(pid, timeoutMs) {
|
|
|
14313
14852
|
}
|
|
14314
14853
|
}
|
|
14315
14854
|
function stopSessionHostProcesses(appName) {
|
|
14316
|
-
const pidFile =
|
|
14855
|
+
const pidFile = path17.join(os17.homedir(), ".adhdev", `${appName}-session-host.pid`);
|
|
14317
14856
|
try {
|
|
14318
14857
|
if (fs8.existsSync(pidFile)) {
|
|
14319
14858
|
const pid = Number.parseInt(fs8.readFileSync(pidFile, "utf8").trim(), 10);
|
|
@@ -14342,7 +14881,7 @@ function stopSessionHostProcesses(appName) {
|
|
|
14342
14881
|
}
|
|
14343
14882
|
}
|
|
14344
14883
|
function removeDaemonPidFile() {
|
|
14345
|
-
const pidFile =
|
|
14884
|
+
const pidFile = path17.join(os17.homedir(), ".adhdev", "daemon.pid");
|
|
14346
14885
|
try {
|
|
14347
14886
|
fs8.unlinkSync(pidFile);
|
|
14348
14887
|
} catch {
|
|
@@ -14353,7 +14892,7 @@ function cleanupStaleGlobalInstallDirs(pkgName) {
|
|
|
14353
14892
|
const npmRoot = (0, import_child_process7.execFileSync)(getNpmExecutable(), ["root", "-g"], { encoding: "utf8", ...npmExecOpts }).trim();
|
|
14354
14893
|
if (!npmRoot) return;
|
|
14355
14894
|
const npmPrefix = (0, import_child_process7.execFileSync)(getNpmExecutable(), ["prefix", "-g"], { encoding: "utf8", ...npmExecOpts }).trim();
|
|
14356
|
-
const binDir = process.platform === "win32" ? npmPrefix :
|
|
14895
|
+
const binDir = process.platform === "win32" ? npmPrefix : path17.join(npmPrefix, "bin");
|
|
14357
14896
|
const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
|
|
14358
14897
|
const binNames = /* @__PURE__ */ new Set([packageBaseName]);
|
|
14359
14898
|
if (pkgName === "@adhdev/daemon-standalone") {
|
|
@@ -14361,25 +14900,25 @@ function cleanupStaleGlobalInstallDirs(pkgName) {
|
|
|
14361
14900
|
}
|
|
14362
14901
|
if (pkgName.startsWith("@")) {
|
|
14363
14902
|
const [scope, name] = pkgName.split("/");
|
|
14364
|
-
const scopeDir =
|
|
14903
|
+
const scopeDir = path17.join(npmRoot, scope);
|
|
14365
14904
|
if (!fs8.existsSync(scopeDir)) return;
|
|
14366
14905
|
for (const entry of fs8.readdirSync(scopeDir)) {
|
|
14367
14906
|
if (!entry.startsWith(`.${name}-`)) continue;
|
|
14368
|
-
fs8.rmSync(
|
|
14369
|
-
appendUpgradeLog(`Removed stale scoped staging dir: ${
|
|
14907
|
+
fs8.rmSync(path17.join(scopeDir, entry), { recursive: true, force: true });
|
|
14908
|
+
appendUpgradeLog(`Removed stale scoped staging dir: ${path17.join(scopeDir, entry)}`);
|
|
14370
14909
|
}
|
|
14371
14910
|
} else {
|
|
14372
14911
|
for (const entry of fs8.readdirSync(npmRoot)) {
|
|
14373
14912
|
if (!entry.startsWith(`.${pkgName}-`)) continue;
|
|
14374
|
-
fs8.rmSync(
|
|
14375
|
-
appendUpgradeLog(`Removed stale staging dir: ${
|
|
14913
|
+
fs8.rmSync(path17.join(npmRoot, entry), { recursive: true, force: true });
|
|
14914
|
+
appendUpgradeLog(`Removed stale staging dir: ${path17.join(npmRoot, entry)}`);
|
|
14376
14915
|
}
|
|
14377
14916
|
}
|
|
14378
14917
|
if (fs8.existsSync(binDir)) {
|
|
14379
14918
|
for (const entry of fs8.readdirSync(binDir)) {
|
|
14380
14919
|
if (![...binNames].some((name) => entry.startsWith(`.${name}-`))) continue;
|
|
14381
|
-
fs8.rmSync(
|
|
14382
|
-
appendUpgradeLog(`Removed stale bin staging entry: ${
|
|
14920
|
+
fs8.rmSync(path17.join(binDir, entry), { recursive: true, force: true });
|
|
14921
|
+
appendUpgradeLog(`Removed stale bin staging entry: ${path17.join(binDir, entry)}`);
|
|
14383
14922
|
}
|
|
14384
14923
|
}
|
|
14385
14924
|
}
|
|
@@ -16257,11 +16796,11 @@ var ProviderInstanceManager = class {
|
|
|
16257
16796
|
|
|
16258
16797
|
// src/providers/version-archive.ts
|
|
16259
16798
|
var fs10 = __toESM(require("fs"));
|
|
16260
|
-
var
|
|
16799
|
+
var path18 = __toESM(require("path"));
|
|
16261
16800
|
var os18 = __toESM(require("os"));
|
|
16262
16801
|
var import_child_process9 = require("child_process");
|
|
16263
16802
|
var import_os3 = require("os");
|
|
16264
|
-
var ARCHIVE_PATH =
|
|
16803
|
+
var ARCHIVE_PATH = path18.join(os18.homedir(), ".adhdev", "version-history.json");
|
|
16265
16804
|
var MAX_ENTRIES_PER_PROVIDER = 20;
|
|
16266
16805
|
var VersionArchive = class {
|
|
16267
16806
|
history = {};
|
|
@@ -16308,7 +16847,7 @@ var VersionArchive = class {
|
|
|
16308
16847
|
}
|
|
16309
16848
|
save() {
|
|
16310
16849
|
try {
|
|
16311
|
-
fs10.mkdirSync(
|
|
16850
|
+
fs10.mkdirSync(path18.dirname(ARCHIVE_PATH), { recursive: true });
|
|
16312
16851
|
fs10.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
|
|
16313
16852
|
} catch {
|
|
16314
16853
|
}
|
|
@@ -16365,7 +16904,7 @@ function checkPathExists2(paths) {
|
|
|
16365
16904
|
for (const p of paths) {
|
|
16366
16905
|
if (p.includes("*")) {
|
|
16367
16906
|
const home = os18.homedir();
|
|
16368
|
-
const resolved = p.replace(/\*/g, home.split(
|
|
16907
|
+
const resolved = p.replace(/\*/g, home.split(path18.sep).pop() || "");
|
|
16369
16908
|
if (fs10.existsSync(resolved)) return resolved;
|
|
16370
16909
|
} else {
|
|
16371
16910
|
if (fs10.existsSync(p)) return p;
|
|
@@ -16375,7 +16914,7 @@ function checkPathExists2(paths) {
|
|
|
16375
16914
|
}
|
|
16376
16915
|
function getMacAppVersion(appPath) {
|
|
16377
16916
|
if ((0, import_os3.platform)() !== "darwin" || !appPath.endsWith(".app")) return null;
|
|
16378
|
-
const plistPath =
|
|
16917
|
+
const plistPath = path18.join(appPath, "Contents", "Info.plist");
|
|
16379
16918
|
if (!fs10.existsSync(plistPath)) return null;
|
|
16380
16919
|
const raw = runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
|
|
16381
16920
|
return raw || null;
|
|
@@ -16401,7 +16940,7 @@ async function detectAllVersions(loader, archive) {
|
|
|
16401
16940
|
const cliBin = provider.cli ? findBinary2(provider.cli) : null;
|
|
16402
16941
|
let resolvedBin = cliBin;
|
|
16403
16942
|
if (!resolvedBin && appPath && currentOs === "darwin") {
|
|
16404
|
-
const bundled =
|
|
16943
|
+
const bundled = path18.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
|
|
16405
16944
|
if (provider.cli && fs10.existsSync(bundled)) resolvedBin = bundled;
|
|
16406
16945
|
}
|
|
16407
16946
|
info.installed = !!(appPath || resolvedBin);
|
|
@@ -16442,7 +16981,7 @@ async function detectAllVersions(loader, archive) {
|
|
|
16442
16981
|
// src/daemon/dev-server.ts
|
|
16443
16982
|
var http2 = __toESM(require("http"));
|
|
16444
16983
|
var fs14 = __toESM(require("fs"));
|
|
16445
|
-
var
|
|
16984
|
+
var path22 = __toESM(require("path"));
|
|
16446
16985
|
|
|
16447
16986
|
// src/daemon/scaffold-template.ts
|
|
16448
16987
|
function generateFiles(type, name, category, opts = {}) {
|
|
@@ -16778,7 +17317,7 @@ init_logger();
|
|
|
16778
17317
|
|
|
16779
17318
|
// src/daemon/dev-cdp-handlers.ts
|
|
16780
17319
|
var fs11 = __toESM(require("fs"));
|
|
16781
|
-
var
|
|
17320
|
+
var path19 = __toESM(require("path"));
|
|
16782
17321
|
init_logger();
|
|
16783
17322
|
async function handleCdpEvaluate(ctx, req, res) {
|
|
16784
17323
|
const body = await ctx.readBody(req);
|
|
@@ -16957,17 +17496,17 @@ async function handleScriptHints(ctx, type, _req, res) {
|
|
|
16957
17496
|
return;
|
|
16958
17497
|
}
|
|
16959
17498
|
let scriptsPath = "";
|
|
16960
|
-
const directScripts =
|
|
17499
|
+
const directScripts = path19.join(dir, "scripts.js");
|
|
16961
17500
|
if (fs11.existsSync(directScripts)) {
|
|
16962
17501
|
scriptsPath = directScripts;
|
|
16963
17502
|
} else {
|
|
16964
|
-
const scriptsDir =
|
|
17503
|
+
const scriptsDir = path19.join(dir, "scripts");
|
|
16965
17504
|
if (fs11.existsSync(scriptsDir)) {
|
|
16966
17505
|
const versions = fs11.readdirSync(scriptsDir).filter((d) => {
|
|
16967
|
-
return fs11.statSync(
|
|
17506
|
+
return fs11.statSync(path19.join(scriptsDir, d)).isDirectory();
|
|
16968
17507
|
}).sort().reverse();
|
|
16969
17508
|
for (const ver of versions) {
|
|
16970
|
-
const p =
|
|
17509
|
+
const p = path19.join(scriptsDir, ver, "scripts.js");
|
|
16971
17510
|
if (fs11.existsSync(p)) {
|
|
16972
17511
|
scriptsPath = p;
|
|
16973
17512
|
break;
|
|
@@ -17796,7 +18335,7 @@ async function handleDomContext(ctx, type, req, res) {
|
|
|
17796
18335
|
|
|
17797
18336
|
// src/daemon/dev-cli-debug.ts
|
|
17798
18337
|
var fs12 = __toESM(require("fs"));
|
|
17799
|
-
var
|
|
18338
|
+
var path20 = __toESM(require("path"));
|
|
17800
18339
|
function slugifyFixtureName(value) {
|
|
17801
18340
|
const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
17802
18341
|
return normalized || `fixture-${Date.now()}`;
|
|
@@ -17806,11 +18345,11 @@ function getCliFixtureDir(ctx, type) {
|
|
|
17806
18345
|
if (!providerDir) {
|
|
17807
18346
|
throw new Error(`Provider directory not found for '${type}'`);
|
|
17808
18347
|
}
|
|
17809
|
-
return
|
|
18348
|
+
return path20.join(providerDir, "fixtures");
|
|
17810
18349
|
}
|
|
17811
18350
|
function readCliFixture(ctx, type, name) {
|
|
17812
18351
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
17813
|
-
const filePath =
|
|
18352
|
+
const filePath = path20.join(fixtureDir, `${name}.json`);
|
|
17814
18353
|
if (!fs12.existsSync(filePath)) {
|
|
17815
18354
|
throw new Error(`Fixture not found: ${filePath}`);
|
|
17816
18355
|
}
|
|
@@ -18578,7 +19117,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
18578
19117
|
},
|
|
18579
19118
|
notes: typeof body?.notes === "string" ? body.notes : void 0
|
|
18580
19119
|
};
|
|
18581
|
-
const filePath =
|
|
19120
|
+
const filePath = path20.join(fixtureDir, `${name}.json`);
|
|
18582
19121
|
fs12.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
|
|
18583
19122
|
ctx.json(res, 200, {
|
|
18584
19123
|
saved: true,
|
|
@@ -18602,7 +19141,7 @@ async function handleCliFixtureList(ctx, type, _req, res) {
|
|
|
18602
19141
|
return;
|
|
18603
19142
|
}
|
|
18604
19143
|
const fixtures = fs12.readdirSync(fixtureDir).filter((file) => file.endsWith(".json")).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file) => {
|
|
18605
|
-
const fullPath =
|
|
19144
|
+
const fullPath = path20.join(fixtureDir, file);
|
|
18606
19145
|
try {
|
|
18607
19146
|
const raw = JSON.parse(fs12.readFileSync(fullPath, "utf-8"));
|
|
18608
19147
|
return {
|
|
@@ -18738,7 +19277,7 @@ async function handleCliRaw(ctx, req, res) {
|
|
|
18738
19277
|
|
|
18739
19278
|
// src/daemon/dev-auto-implement.ts
|
|
18740
19279
|
var fs13 = __toESM(require("fs"));
|
|
18741
|
-
var
|
|
19280
|
+
var path21 = __toESM(require("path"));
|
|
18742
19281
|
var os19 = __toESM(require("os"));
|
|
18743
19282
|
function getAutoImplPid(ctx) {
|
|
18744
19283
|
const pid = ctx.autoImplProcess?.pid;
|
|
@@ -18795,22 +19334,22 @@ function getLatestScriptVersionDir(scriptsDir) {
|
|
|
18795
19334
|
if (!fs13.existsSync(scriptsDir)) return null;
|
|
18796
19335
|
const versions = fs13.readdirSync(scriptsDir).filter((d) => {
|
|
18797
19336
|
try {
|
|
18798
|
-
return fs13.statSync(
|
|
19337
|
+
return fs13.statSync(path21.join(scriptsDir, d)).isDirectory();
|
|
18799
19338
|
} catch {
|
|
18800
19339
|
return false;
|
|
18801
19340
|
}
|
|
18802
19341
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
18803
19342
|
if (versions.length === 0) return null;
|
|
18804
|
-
return
|
|
19343
|
+
return path21.join(scriptsDir, versions[0]);
|
|
18805
19344
|
}
|
|
18806
19345
|
function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
18807
|
-
const canonicalUserDir =
|
|
18808
|
-
const desiredDir = requestedDir ?
|
|
18809
|
-
const upstreamRoot =
|
|
18810
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
19346
|
+
const canonicalUserDir = path21.resolve(ctx.providerLoader.getUserProviderDir(category, type));
|
|
19347
|
+
const desiredDir = requestedDir ? path21.resolve(requestedDir) : canonicalUserDir;
|
|
19348
|
+
const upstreamRoot = path21.resolve(ctx.providerLoader.getUpstreamDir());
|
|
19349
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path21.sep}`)) {
|
|
18811
19350
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
18812
19351
|
}
|
|
18813
|
-
if (
|
|
19352
|
+
if (path21.basename(desiredDir) !== type) {
|
|
18814
19353
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
18815
19354
|
}
|
|
18816
19355
|
const sourceDir = ctx.findProviderDir(type);
|
|
@@ -18818,11 +19357,11 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
|
18818
19357
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
18819
19358
|
}
|
|
18820
19359
|
if (!fs13.existsSync(desiredDir)) {
|
|
18821
|
-
fs13.mkdirSync(
|
|
19360
|
+
fs13.mkdirSync(path21.dirname(desiredDir), { recursive: true });
|
|
18822
19361
|
fs13.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
18823
19362
|
ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
18824
19363
|
}
|
|
18825
|
-
const providerJson =
|
|
19364
|
+
const providerJson = path21.join(desiredDir, "provider.json");
|
|
18826
19365
|
if (!fs13.existsSync(providerJson)) {
|
|
18827
19366
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
18828
19367
|
}
|
|
@@ -18845,13 +19384,13 @@ function loadAutoImplReferenceScripts(ctx, referenceType) {
|
|
|
18845
19384
|
const refDir = ctx.findProviderDir(referenceType);
|
|
18846
19385
|
if (!refDir || !fs13.existsSync(refDir)) return {};
|
|
18847
19386
|
const referenceScripts = {};
|
|
18848
|
-
const scriptsDir =
|
|
19387
|
+
const scriptsDir = path21.join(refDir, "scripts");
|
|
18849
19388
|
const latestDir = getLatestScriptVersionDir(scriptsDir);
|
|
18850
19389
|
if (!latestDir) return referenceScripts;
|
|
18851
19390
|
for (const file of fs13.readdirSync(latestDir)) {
|
|
18852
19391
|
if (!file.endsWith(".js")) continue;
|
|
18853
19392
|
try {
|
|
18854
|
-
referenceScripts[file] = fs13.readFileSync(
|
|
19393
|
+
referenceScripts[file] = fs13.readFileSync(path21.join(latestDir, file), "utf-8");
|
|
18855
19394
|
} catch {
|
|
18856
19395
|
}
|
|
18857
19396
|
}
|
|
@@ -18959,9 +19498,9 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
18959
19498
|
});
|
|
18960
19499
|
const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
|
|
18961
19500
|
const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
|
|
18962
|
-
const tmpDir =
|
|
19501
|
+
const tmpDir = path21.join(os19.tmpdir(), "adhdev-autoimpl");
|
|
18963
19502
|
if (!fs13.existsSync(tmpDir)) fs13.mkdirSync(tmpDir, { recursive: true });
|
|
18964
|
-
const promptFile =
|
|
19503
|
+
const promptFile = path21.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
|
|
18965
19504
|
fs13.writeFileSync(promptFile, prompt, "utf-8");
|
|
18966
19505
|
ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
|
|
18967
19506
|
const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
|
|
@@ -19398,7 +19937,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
19398
19937
|
setMode: "set_mode.js"
|
|
19399
19938
|
};
|
|
19400
19939
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
19401
|
-
const scriptsDir =
|
|
19940
|
+
const scriptsDir = path21.join(providerDir, "scripts");
|
|
19402
19941
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
19403
19942
|
if (latestScriptsDir) {
|
|
19404
19943
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -19409,7 +19948,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
19409
19948
|
for (const file of fs13.readdirSync(latestScriptsDir)) {
|
|
19410
19949
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
19411
19950
|
try {
|
|
19412
|
-
const content = fs13.readFileSync(
|
|
19951
|
+
const content = fs13.readFileSync(path21.join(latestScriptsDir, file), "utf-8");
|
|
19413
19952
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
19414
19953
|
lines.push("```javascript");
|
|
19415
19954
|
lines.push(content);
|
|
@@ -19426,7 +19965,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
19426
19965
|
lines.push("");
|
|
19427
19966
|
for (const file of refFiles) {
|
|
19428
19967
|
try {
|
|
19429
|
-
const content = fs13.readFileSync(
|
|
19968
|
+
const content = fs13.readFileSync(path21.join(latestScriptsDir, file), "utf-8");
|
|
19430
19969
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
19431
19970
|
lines.push("```javascript");
|
|
19432
19971
|
lines.push(content);
|
|
@@ -19467,10 +20006,10 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
19467
20006
|
lines.push("");
|
|
19468
20007
|
}
|
|
19469
20008
|
}
|
|
19470
|
-
const docsDir =
|
|
20009
|
+
const docsDir = path21.join(providerDir, "../../docs");
|
|
19471
20010
|
const loadGuide = (name) => {
|
|
19472
20011
|
try {
|
|
19473
|
-
const p =
|
|
20012
|
+
const p = path21.join(docsDir, name);
|
|
19474
20013
|
if (fs13.existsSync(p)) return fs13.readFileSync(p, "utf-8");
|
|
19475
20014
|
} catch {
|
|
19476
20015
|
}
|
|
@@ -19707,7 +20246,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
19707
20246
|
parseApproval: "parse_approval.js"
|
|
19708
20247
|
};
|
|
19709
20248
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
19710
|
-
const scriptsDir =
|
|
20249
|
+
const scriptsDir = path21.join(providerDir, "scripts");
|
|
19711
20250
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
19712
20251
|
if (latestScriptsDir) {
|
|
19713
20252
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -19719,7 +20258,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
19719
20258
|
if (!file.endsWith(".js")) continue;
|
|
19720
20259
|
if (!targetFileNames.has(file)) continue;
|
|
19721
20260
|
try {
|
|
19722
|
-
const content = fs13.readFileSync(
|
|
20261
|
+
const content = fs13.readFileSync(path21.join(latestScriptsDir, file), "utf-8");
|
|
19723
20262
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
19724
20263
|
lines.push("```javascript");
|
|
19725
20264
|
lines.push(content);
|
|
@@ -19735,7 +20274,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
19735
20274
|
lines.push("");
|
|
19736
20275
|
for (const file of refFiles) {
|
|
19737
20276
|
try {
|
|
19738
|
-
const content = fs13.readFileSync(
|
|
20277
|
+
const content = fs13.readFileSync(path21.join(latestScriptsDir, file), "utf-8");
|
|
19739
20278
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
19740
20279
|
lines.push("```javascript");
|
|
19741
20280
|
lines.push(content);
|
|
@@ -19768,10 +20307,10 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
19768
20307
|
lines.push("");
|
|
19769
20308
|
}
|
|
19770
20309
|
}
|
|
19771
|
-
const docsDir =
|
|
20310
|
+
const docsDir = path21.join(providerDir, "../../docs");
|
|
19772
20311
|
const loadGuide = (name) => {
|
|
19773
20312
|
try {
|
|
19774
|
-
const p =
|
|
20313
|
+
const p = path21.join(docsDir, name);
|
|
19775
20314
|
if (fs13.existsSync(p)) return fs13.readFileSync(p, "utf-8");
|
|
19776
20315
|
} catch {
|
|
19777
20316
|
}
|
|
@@ -20214,8 +20753,8 @@ var DevServer = class _DevServer {
|
|
|
20214
20753
|
}
|
|
20215
20754
|
getEndpointList() {
|
|
20216
20755
|
return this.routes.map((r) => {
|
|
20217
|
-
const
|
|
20218
|
-
return `${r.method.padEnd(5)} ${
|
|
20756
|
+
const path23 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
|
|
20757
|
+
return `${r.method.padEnd(5)} ${path23}`;
|
|
20219
20758
|
});
|
|
20220
20759
|
}
|
|
20221
20760
|
async start(port = DEV_SERVER_PORT) {
|
|
@@ -20470,12 +21009,12 @@ var DevServer = class _DevServer {
|
|
|
20470
21009
|
// ─── DevConsole SPA ───
|
|
20471
21010
|
getConsoleDistDir() {
|
|
20472
21011
|
const candidates = [
|
|
20473
|
-
|
|
20474
|
-
|
|
20475
|
-
|
|
21012
|
+
path22.resolve(__dirname, "../../web-devconsole/dist"),
|
|
21013
|
+
path22.resolve(__dirname, "../../../web-devconsole/dist"),
|
|
21014
|
+
path22.join(process.cwd(), "packages/web-devconsole/dist")
|
|
20476
21015
|
];
|
|
20477
21016
|
for (const dir of candidates) {
|
|
20478
|
-
if (fs14.existsSync(
|
|
21017
|
+
if (fs14.existsSync(path22.join(dir, "index.html"))) return dir;
|
|
20479
21018
|
}
|
|
20480
21019
|
return null;
|
|
20481
21020
|
}
|
|
@@ -20485,7 +21024,7 @@ var DevServer = class _DevServer {
|
|
|
20485
21024
|
this.json(res, 500, { error: "DevConsole not found. Run: npm run build -w packages/web-devconsole" });
|
|
20486
21025
|
return;
|
|
20487
21026
|
}
|
|
20488
|
-
const htmlPath =
|
|
21027
|
+
const htmlPath = path22.join(distDir, "index.html");
|
|
20489
21028
|
try {
|
|
20490
21029
|
const html = fs14.readFileSync(htmlPath, "utf-8");
|
|
20491
21030
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
@@ -20510,15 +21049,15 @@ var DevServer = class _DevServer {
|
|
|
20510
21049
|
this.json(res, 404, { error: "Not found" });
|
|
20511
21050
|
return;
|
|
20512
21051
|
}
|
|
20513
|
-
const safePath =
|
|
20514
|
-
const filePath =
|
|
21052
|
+
const safePath = path22.normalize(pathname).replace(/^\.\.\//, "");
|
|
21053
|
+
const filePath = path22.join(distDir, safePath);
|
|
20515
21054
|
if (!filePath.startsWith(distDir)) {
|
|
20516
21055
|
this.json(res, 403, { error: "Forbidden" });
|
|
20517
21056
|
return;
|
|
20518
21057
|
}
|
|
20519
21058
|
try {
|
|
20520
21059
|
const content = fs14.readFileSync(filePath);
|
|
20521
|
-
const ext =
|
|
21060
|
+
const ext = path22.extname(filePath);
|
|
20522
21061
|
const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
|
|
20523
21062
|
res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
|
|
20524
21063
|
res.end(content);
|
|
@@ -20631,9 +21170,9 @@ var DevServer = class _DevServer {
|
|
|
20631
21170
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
20632
21171
|
if (entry.isDirectory()) {
|
|
20633
21172
|
files.push({ path: rel, size: 0, type: "dir" });
|
|
20634
|
-
scan(
|
|
21173
|
+
scan(path22.join(d, entry.name), rel);
|
|
20635
21174
|
} else {
|
|
20636
|
-
const stat = fs14.statSync(
|
|
21175
|
+
const stat = fs14.statSync(path22.join(d, entry.name));
|
|
20637
21176
|
files.push({ path: rel, size: stat.size, type: "file" });
|
|
20638
21177
|
}
|
|
20639
21178
|
}
|
|
@@ -20656,7 +21195,7 @@ var DevServer = class _DevServer {
|
|
|
20656
21195
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
20657
21196
|
return;
|
|
20658
21197
|
}
|
|
20659
|
-
const fullPath =
|
|
21198
|
+
const fullPath = path22.resolve(dir, path22.normalize(filePath));
|
|
20660
21199
|
if (!fullPath.startsWith(dir)) {
|
|
20661
21200
|
this.json(res, 403, { error: "Forbidden" });
|
|
20662
21201
|
return;
|
|
@@ -20681,14 +21220,14 @@ var DevServer = class _DevServer {
|
|
|
20681
21220
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
20682
21221
|
return;
|
|
20683
21222
|
}
|
|
20684
|
-
const fullPath =
|
|
21223
|
+
const fullPath = path22.resolve(dir, path22.normalize(filePath));
|
|
20685
21224
|
if (!fullPath.startsWith(dir)) {
|
|
20686
21225
|
this.json(res, 403, { error: "Forbidden" });
|
|
20687
21226
|
return;
|
|
20688
21227
|
}
|
|
20689
21228
|
try {
|
|
20690
21229
|
if (fs14.existsSync(fullPath)) fs14.copyFileSync(fullPath, fullPath + ".bak");
|
|
20691
|
-
fs14.mkdirSync(
|
|
21230
|
+
fs14.mkdirSync(path22.dirname(fullPath), { recursive: true });
|
|
20692
21231
|
fs14.writeFileSync(fullPath, content, "utf-8");
|
|
20693
21232
|
this.log(`File saved: ${fullPath} (${content.length} chars)`);
|
|
20694
21233
|
this.providerLoader.reload();
|
|
@@ -20705,7 +21244,7 @@ var DevServer = class _DevServer {
|
|
|
20705
21244
|
return;
|
|
20706
21245
|
}
|
|
20707
21246
|
for (const name of ["scripts.js", "provider.json"]) {
|
|
20708
|
-
const p =
|
|
21247
|
+
const p = path22.join(dir, name);
|
|
20709
21248
|
if (fs14.existsSync(p)) {
|
|
20710
21249
|
const source = fs14.readFileSync(p, "utf-8");
|
|
20711
21250
|
this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
|
|
@@ -20726,8 +21265,8 @@ var DevServer = class _DevServer {
|
|
|
20726
21265
|
this.json(res, 404, { error: `Provider not found: ${type}` });
|
|
20727
21266
|
return;
|
|
20728
21267
|
}
|
|
20729
|
-
const target = fs14.existsSync(
|
|
20730
|
-
const targetPath =
|
|
21268
|
+
const target = fs14.existsSync(path22.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
|
|
21269
|
+
const targetPath = path22.join(dir, target);
|
|
20731
21270
|
try {
|
|
20732
21271
|
if (fs14.existsSync(targetPath)) fs14.copyFileSync(targetPath, targetPath + ".bak");
|
|
20733
21272
|
fs14.writeFileSync(targetPath, source, "utf-8");
|
|
@@ -20755,22 +21294,9 @@ var DevServer = class _DevServer {
|
|
|
20755
21294
|
const warnings = [];
|
|
20756
21295
|
try {
|
|
20757
21296
|
const config = typeof content === "string" ? JSON.parse(content) : content;
|
|
20758
|
-
|
|
20759
|
-
|
|
20760
|
-
|
|
20761
|
-
else if (!["ide", "extension", "cli", "acp"].includes(config.category)) errors.push(`Invalid category: ${config.category}`);
|
|
20762
|
-
if (config.category === "ide" || config.category === "extension") {
|
|
20763
|
-
if (!config.cdpPorts || !Array.isArray(config.cdpPorts) || config.cdpPorts.length === 0)
|
|
20764
|
-
warnings.push("IDE/Extension providers should have cdpPorts");
|
|
20765
|
-
if (config.category === "extension" && !config.extensionId)
|
|
20766
|
-
warnings.push("Extension providers should have extensionId");
|
|
20767
|
-
}
|
|
20768
|
-
if (config.category === "acp" || config.category === "cli") {
|
|
20769
|
-
if (!config.spawn) errors.push("ACP/CLI providers must have spawn config");
|
|
20770
|
-
else {
|
|
20771
|
-
if (!config.spawn.command) errors.push("spawn.command is required");
|
|
20772
|
-
}
|
|
20773
|
-
}
|
|
21297
|
+
const validation = validateProviderDefinition(config);
|
|
21298
|
+
errors.push(...validation.errors);
|
|
21299
|
+
warnings.push(...validation.warnings);
|
|
20774
21300
|
if (config.settings) {
|
|
20775
21301
|
for (const [key, val] of Object.entries(config.settings)) {
|
|
20776
21302
|
const s = val;
|
|
@@ -20887,7 +21413,7 @@ var DevServer = class _DevServer {
|
|
|
20887
21413
|
}
|
|
20888
21414
|
let targetDir;
|
|
20889
21415
|
targetDir = this.providerLoader.getUserProviderDir(category, type);
|
|
20890
|
-
const jsonPath =
|
|
21416
|
+
const jsonPath = path22.join(targetDir, "provider.json");
|
|
20891
21417
|
if (fs14.existsSync(jsonPath)) {
|
|
20892
21418
|
this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
|
|
20893
21419
|
return;
|
|
@@ -20899,8 +21425,8 @@ var DevServer = class _DevServer {
|
|
|
20899
21425
|
const createdFiles = ["provider.json"];
|
|
20900
21426
|
if (result.files) {
|
|
20901
21427
|
for (const [relPath, content] of Object.entries(result.files)) {
|
|
20902
|
-
const fullPath =
|
|
20903
|
-
fs14.mkdirSync(
|
|
21428
|
+
const fullPath = path22.join(targetDir, relPath);
|
|
21429
|
+
fs14.mkdirSync(path22.dirname(fullPath), { recursive: true });
|
|
20904
21430
|
fs14.writeFileSync(fullPath, content, "utf-8");
|
|
20905
21431
|
createdFiles.push(relPath);
|
|
20906
21432
|
}
|
|
@@ -20953,22 +21479,22 @@ var DevServer = class _DevServer {
|
|
|
20953
21479
|
if (!fs14.existsSync(scriptsDir)) return null;
|
|
20954
21480
|
const versions = fs14.readdirSync(scriptsDir).filter((d) => {
|
|
20955
21481
|
try {
|
|
20956
|
-
return fs14.statSync(
|
|
21482
|
+
return fs14.statSync(path22.join(scriptsDir, d)).isDirectory();
|
|
20957
21483
|
} catch {
|
|
20958
21484
|
return false;
|
|
20959
21485
|
}
|
|
20960
21486
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
20961
21487
|
if (versions.length === 0) return null;
|
|
20962
|
-
return
|
|
21488
|
+
return path22.join(scriptsDir, versions[0]);
|
|
20963
21489
|
}
|
|
20964
21490
|
resolveAutoImplWritableProviderDir(category, type, requestedDir) {
|
|
20965
|
-
const canonicalUserDir =
|
|
20966
|
-
const desiredDir = requestedDir ?
|
|
20967
|
-
const upstreamRoot =
|
|
20968
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
21491
|
+
const canonicalUserDir = path22.resolve(this.providerLoader.getUserProviderDir(category, type));
|
|
21492
|
+
const desiredDir = requestedDir ? path22.resolve(requestedDir) : canonicalUserDir;
|
|
21493
|
+
const upstreamRoot = path22.resolve(this.providerLoader.getUpstreamDir());
|
|
21494
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path22.sep}`)) {
|
|
20969
21495
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
20970
21496
|
}
|
|
20971
|
-
if (
|
|
21497
|
+
if (path22.basename(desiredDir) !== type) {
|
|
20972
21498
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
20973
21499
|
}
|
|
20974
21500
|
const sourceDir = this.findProviderDir(type);
|
|
@@ -20976,11 +21502,11 @@ var DevServer = class _DevServer {
|
|
|
20976
21502
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
20977
21503
|
}
|
|
20978
21504
|
if (!fs14.existsSync(desiredDir)) {
|
|
20979
|
-
fs14.mkdirSync(
|
|
21505
|
+
fs14.mkdirSync(path22.dirname(desiredDir), { recursive: true });
|
|
20980
21506
|
fs14.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
20981
21507
|
this.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
20982
21508
|
}
|
|
20983
|
-
const providerJson =
|
|
21509
|
+
const providerJson = path22.join(desiredDir, "provider.json");
|
|
20984
21510
|
if (!fs14.existsSync(providerJson)) {
|
|
20985
21511
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
20986
21512
|
}
|
|
@@ -21028,7 +21554,7 @@ var DevServer = class _DevServer {
|
|
|
21028
21554
|
setMode: "set_mode.js"
|
|
21029
21555
|
};
|
|
21030
21556
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
21031
|
-
const scriptsDir =
|
|
21557
|
+
const scriptsDir = path22.join(providerDir, "scripts");
|
|
21032
21558
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
21033
21559
|
if (latestScriptsDir) {
|
|
21034
21560
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -21039,7 +21565,7 @@ var DevServer = class _DevServer {
|
|
|
21039
21565
|
for (const file of fs14.readdirSync(latestScriptsDir)) {
|
|
21040
21566
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
21041
21567
|
try {
|
|
21042
|
-
const content = fs14.readFileSync(
|
|
21568
|
+
const content = fs14.readFileSync(path22.join(latestScriptsDir, file), "utf-8");
|
|
21043
21569
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
21044
21570
|
lines.push("```javascript");
|
|
21045
21571
|
lines.push(content);
|
|
@@ -21056,7 +21582,7 @@ var DevServer = class _DevServer {
|
|
|
21056
21582
|
lines.push("");
|
|
21057
21583
|
for (const file of refFiles) {
|
|
21058
21584
|
try {
|
|
21059
|
-
const content = fs14.readFileSync(
|
|
21585
|
+
const content = fs14.readFileSync(path22.join(latestScriptsDir, file), "utf-8");
|
|
21060
21586
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
21061
21587
|
lines.push("```javascript");
|
|
21062
21588
|
lines.push(content);
|
|
@@ -21097,10 +21623,10 @@ var DevServer = class _DevServer {
|
|
|
21097
21623
|
lines.push("");
|
|
21098
21624
|
}
|
|
21099
21625
|
}
|
|
21100
|
-
const docsDir =
|
|
21626
|
+
const docsDir = path22.join(providerDir, "../../docs");
|
|
21101
21627
|
const loadGuide = (name) => {
|
|
21102
21628
|
try {
|
|
21103
|
-
const p =
|
|
21629
|
+
const p = path22.join(docsDir, name);
|
|
21104
21630
|
if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
|
|
21105
21631
|
} catch {
|
|
21106
21632
|
}
|
|
@@ -21274,7 +21800,7 @@ var DevServer = class _DevServer {
|
|
|
21274
21800
|
parseApproval: "parse_approval.js"
|
|
21275
21801
|
};
|
|
21276
21802
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
21277
|
-
const scriptsDir =
|
|
21803
|
+
const scriptsDir = path22.join(providerDir, "scripts");
|
|
21278
21804
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
21279
21805
|
if (latestScriptsDir) {
|
|
21280
21806
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -21286,7 +21812,7 @@ var DevServer = class _DevServer {
|
|
|
21286
21812
|
if (!file.endsWith(".js")) continue;
|
|
21287
21813
|
if (!targetFileNames.has(file)) continue;
|
|
21288
21814
|
try {
|
|
21289
|
-
const content = fs14.readFileSync(
|
|
21815
|
+
const content = fs14.readFileSync(path22.join(latestScriptsDir, file), "utf-8");
|
|
21290
21816
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
21291
21817
|
lines.push("```javascript");
|
|
21292
21818
|
lines.push(content);
|
|
@@ -21302,7 +21828,7 @@ var DevServer = class _DevServer {
|
|
|
21302
21828
|
lines.push("");
|
|
21303
21829
|
for (const file of refFiles) {
|
|
21304
21830
|
try {
|
|
21305
|
-
const content = fs14.readFileSync(
|
|
21831
|
+
const content = fs14.readFileSync(path22.join(latestScriptsDir, file), "utf-8");
|
|
21306
21832
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
21307
21833
|
lines.push("```javascript");
|
|
21308
21834
|
lines.push(content);
|
|
@@ -21335,10 +21861,10 @@ var DevServer = class _DevServer {
|
|
|
21335
21861
|
lines.push("");
|
|
21336
21862
|
}
|
|
21337
21863
|
}
|
|
21338
|
-
const docsDir =
|
|
21864
|
+
const docsDir = path22.join(providerDir, "../../docs");
|
|
21339
21865
|
const loadGuide = (name) => {
|
|
21340
21866
|
try {
|
|
21341
|
-
const p =
|
|
21867
|
+
const p = path22.join(docsDir, name);
|
|
21342
21868
|
if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
|
|
21343
21869
|
} catch {
|
|
21344
21870
|
}
|
|
@@ -22046,6 +22572,67 @@ async function listHostedCliRuntimes(endpoint) {
|
|
|
22046
22572
|
}
|
|
22047
22573
|
}
|
|
22048
22574
|
|
|
22575
|
+
// src/session-host/runtime-surface.ts
|
|
22576
|
+
var LIVE_LIFECYCLES = /* @__PURE__ */ new Set(["starting", "running", "stopping", "interrupted"]);
|
|
22577
|
+
function isSessionHostLiveRuntime(record) {
|
|
22578
|
+
const lifecycle = String(record?.lifecycle || "").trim();
|
|
22579
|
+
return LIVE_LIFECYCLES.has(lifecycle);
|
|
22580
|
+
}
|
|
22581
|
+
function getSessionHostRecoveryLabel(meta) {
|
|
22582
|
+
const recoveryState = typeof meta?.runtimeRecoveryState === "string" ? String(meta.runtimeRecoveryState).trim() : "";
|
|
22583
|
+
if (!recoveryState) return null;
|
|
22584
|
+
if (recoveryState === "auto_resumed") return "restored after restart";
|
|
22585
|
+
if (recoveryState === "resume_failed") return "restore failed";
|
|
22586
|
+
if (recoveryState === "host_restart_interrupted") return "host restart interrupted";
|
|
22587
|
+
if (recoveryState === "orphan_snapshot") return "snapshot recovered";
|
|
22588
|
+
return recoveryState.replace(/_/g, " ");
|
|
22589
|
+
}
|
|
22590
|
+
function isSessionHostRecoverySnapshot(record) {
|
|
22591
|
+
if (!record) return false;
|
|
22592
|
+
if (isSessionHostLiveRuntime(record)) return false;
|
|
22593
|
+
const lifecycle = String(record.lifecycle || "").trim();
|
|
22594
|
+
if (lifecycle && lifecycle !== "stopped" && lifecycle !== "failed") {
|
|
22595
|
+
return false;
|
|
22596
|
+
}
|
|
22597
|
+
const meta = record.meta || void 0;
|
|
22598
|
+
if (meta?.restoredFromStorage === true) return true;
|
|
22599
|
+
return getSessionHostRecoveryLabel(meta) !== null;
|
|
22600
|
+
}
|
|
22601
|
+
function getSessionHostSurfaceKind(record) {
|
|
22602
|
+
if (isSessionHostLiveRuntime(record)) return "live_runtime";
|
|
22603
|
+
if (isSessionHostRecoverySnapshot(record)) return "recovery_snapshot";
|
|
22604
|
+
return "inactive_record";
|
|
22605
|
+
}
|
|
22606
|
+
function partitionSessionHostRecords(records) {
|
|
22607
|
+
const liveRuntimes = [];
|
|
22608
|
+
const recoverySnapshots = [];
|
|
22609
|
+
const inactiveRecords = [];
|
|
22610
|
+
for (const record of records) {
|
|
22611
|
+
const kind = getSessionHostSurfaceKind(record);
|
|
22612
|
+
if (kind === "live_runtime") {
|
|
22613
|
+
liveRuntimes.push(record);
|
|
22614
|
+
} else if (kind === "recovery_snapshot") {
|
|
22615
|
+
recoverySnapshots.push(record);
|
|
22616
|
+
} else {
|
|
22617
|
+
inactiveRecords.push(record);
|
|
22618
|
+
}
|
|
22619
|
+
}
|
|
22620
|
+
return {
|
|
22621
|
+
liveRuntimes,
|
|
22622
|
+
recoverySnapshots,
|
|
22623
|
+
inactiveRecords
|
|
22624
|
+
};
|
|
22625
|
+
}
|
|
22626
|
+
function partitionSessionHostDiagnosticsSessions(records) {
|
|
22627
|
+
return partitionSessionHostRecords(records || []);
|
|
22628
|
+
}
|
|
22629
|
+
|
|
22630
|
+
// src/session-host/startup-restore-policy.js
|
|
22631
|
+
function shouldAutoRestoreHostedSessionsOnStartup(env = process.env) {
|
|
22632
|
+
const raw = typeof env.ADHDEV_RESTORE_HOSTED_SESSIONS_ON_STARTUP === "string" ? env.ADHDEV_RESTORE_HOSTED_SESSIONS_ON_STARTUP.trim().toLowerCase() : "";
|
|
22633
|
+
return raw === "1" || raw === "true" || raw === "yes";
|
|
22634
|
+
}
|
|
22635
|
+
|
|
22049
22636
|
// src/installer.ts
|
|
22050
22637
|
var import_child_process10 = require("child_process");
|
|
22051
22638
|
var EXTENSION_CATALOG = [
|
|
@@ -22552,6 +23139,7 @@ async function shutdownDaemonComponents(components) {
|
|
|
22552
23139
|
detectIDEs,
|
|
22553
23140
|
ensureSessionHostReady,
|
|
22554
23141
|
findCdpManager,
|
|
23142
|
+
flattenMessageParts,
|
|
22555
23143
|
forwardAgentStreamsToIdeInstance,
|
|
22556
23144
|
getAIExtensions,
|
|
22557
23145
|
getAvailableIdeIds,
|
|
@@ -22565,6 +23153,8 @@ async function shutdownDaemonComponents(components) {
|
|
|
22565
23153
|
getRecentDebugTrace,
|
|
22566
23154
|
getRecentLogs,
|
|
22567
23155
|
getSavedProviderSessions,
|
|
23156
|
+
getSessionHostRecoveryLabel,
|
|
23157
|
+
getSessionHostSurfaceKind,
|
|
22568
23158
|
getWorkspaceState,
|
|
22569
23159
|
hasCdpManager,
|
|
22570
23160
|
initDaemonComponents,
|
|
@@ -22575,6 +23165,8 @@ async function shutdownDaemonComponents(components) {
|
|
|
22575
23165
|
isIdeRunning,
|
|
22576
23166
|
isManagedStatusWaiting,
|
|
22577
23167
|
isManagedStatusWorking,
|
|
23168
|
+
isSessionHostLiveRuntime,
|
|
23169
|
+
isSessionHostRecoverySnapshot,
|
|
22578
23170
|
isSetupComplete,
|
|
22579
23171
|
killIdeProcess,
|
|
22580
23172
|
launchIDE,
|
|
@@ -22586,7 +23178,11 @@ async function shutdownDaemonComponents(components) {
|
|
|
22586
23178
|
markSetupComplete,
|
|
22587
23179
|
maybeRunDaemonUpgradeHelperFromEnv,
|
|
22588
23180
|
normalizeActiveChatData,
|
|
23181
|
+
normalizeInputEnvelope,
|
|
22589
23182
|
normalizeManagedStatus,
|
|
23183
|
+
normalizeMessageParts,
|
|
23184
|
+
partitionSessionHostDiagnosticsSessions,
|
|
23185
|
+
partitionSessionHostRecords,
|
|
22590
23186
|
probeCdpPort,
|
|
22591
23187
|
readChatHistory,
|
|
22592
23188
|
recordDebugTrace,
|
|
@@ -22601,6 +23197,7 @@ async function shutdownDaemonComponents(components) {
|
|
|
22601
23197
|
setDebugRuntimeConfig,
|
|
22602
23198
|
setLogLevel,
|
|
22603
23199
|
setupIdeInstance,
|
|
23200
|
+
shouldAutoRestoreHostedSessionsOnStartup,
|
|
22604
23201
|
shouldCollectTraceCategory,
|
|
22605
23202
|
shutdownDaemonComponents,
|
|
22606
23203
|
spawnDetachedDaemonUpgradeHelper,
|