adhdev 0.6.75 → 0.6.77
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/cli/index.js +147 -92
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +132 -77
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -560,6 +560,10 @@ var init_ide_detector = __esm({
|
|
|
560
560
|
});
|
|
561
561
|
|
|
562
562
|
// ../../oss/packages/daemon-core/src/detection/cli-detector.ts
|
|
563
|
+
function parseVersion(raw) {
|
|
564
|
+
const match = raw.match(/v?(\d+\.\d+(?:\.\d+)?(?:-[a-zA-Z0-9.]+)?)/);
|
|
565
|
+
return match ? match[1] : raw.split("\n")[0].slice(0, 100);
|
|
566
|
+
}
|
|
563
567
|
function execAsync(cmd, timeoutMs = 5e3) {
|
|
564
568
|
return new Promise((resolve10) => {
|
|
565
569
|
const child = (0, import_child_process2.exec)(cmd, { encoding: "utf-8", timeout: timeoutMs }, (err, stdout) => {
|
|
@@ -584,10 +588,18 @@ async function detectCLIs(providerLoader) {
|
|
|
584
588
|
const firstPath = pathResult.split("\n")[0];
|
|
585
589
|
let version2;
|
|
586
590
|
try {
|
|
587
|
-
const
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
+
const versionCommands = [
|
|
592
|
+
cli.versionCommand,
|
|
593
|
+
`${cli.command} --version 2>/dev/null`,
|
|
594
|
+
`${cli.command} -V 2>/dev/null`,
|
|
595
|
+
`${cli.command} -v 2>/dev/null`
|
|
596
|
+
].filter((v2) => !!v2);
|
|
597
|
+
for (const versionCommand of versionCommands) {
|
|
598
|
+
const versionResult = await execAsync(versionCommand, 3e3);
|
|
599
|
+
if (versionResult) {
|
|
600
|
+
version2 = parseVersion(versionResult);
|
|
601
|
+
break;
|
|
602
|
+
}
|
|
591
603
|
}
|
|
592
604
|
} catch {
|
|
593
605
|
}
|
|
@@ -3378,7 +3390,7 @@ function buildManagedClis(cliStates) {
|
|
|
3378
3390
|
cliType: s15.type,
|
|
3379
3391
|
cliName: s15.name,
|
|
3380
3392
|
status: s15.status,
|
|
3381
|
-
mode:
|
|
3393
|
+
mode: "terminal",
|
|
3382
3394
|
workspace: s15.workspace || "",
|
|
3383
3395
|
activeChat: s15.activeChat
|
|
3384
3396
|
}));
|
|
@@ -4972,8 +4984,13 @@ var init_handler = __esm({
|
|
|
4972
4984
|
getCliAdapter(type) {
|
|
4973
4985
|
const target = type || this._currentIdeType;
|
|
4974
4986
|
if (!target || !this._ctx.adapters) return null;
|
|
4987
|
+
let normalizedTarget = target;
|
|
4988
|
+
const colonIdx = normalizedTarget.lastIndexOf(":");
|
|
4989
|
+
if (colonIdx >= 0) normalizedTarget = normalizedTarget.substring(colonIdx + 1);
|
|
4990
|
+
const direct = this._ctx.adapters.get(normalizedTarget);
|
|
4991
|
+
if (direct) return direct;
|
|
4975
4992
|
for (const [key, adapter] of this._ctx.adapters.entries()) {
|
|
4976
|
-
if (adapter.cliType === target || key.startsWith(target)) {
|
|
4993
|
+
if (adapter.cliType === target || adapter.cliType === normalizedTarget || key === normalizedTarget || key.startsWith(target) || key.startsWith(normalizedTarget)) {
|
|
4977
4994
|
return adapter;
|
|
4978
4995
|
}
|
|
4979
4996
|
}
|
|
@@ -5482,10 +5499,10 @@ var init_readdirp = __esm({
|
|
|
5482
5499
|
}
|
|
5483
5500
|
async _formatEntry(dirent, path15) {
|
|
5484
5501
|
let entry;
|
|
5485
|
-
const
|
|
5502
|
+
const basename6 = this._isDirent ? dirent.name : dirent;
|
|
5486
5503
|
try {
|
|
5487
|
-
const fullPath = (0, import_node_path.resolve)((0, import_node_path.join)(path15,
|
|
5488
|
-
entry = { path: (0, import_node_path.relative)(this._root, fullPath), fullPath, basename:
|
|
5504
|
+
const fullPath = (0, import_node_path.resolve)((0, import_node_path.join)(path15, basename6));
|
|
5505
|
+
entry = { path: (0, import_node_path.relative)(this._root, fullPath), fullPath, basename: basename6 };
|
|
5489
5506
|
entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
|
|
5490
5507
|
} catch (err) {
|
|
5491
5508
|
this._onError(err);
|
|
@@ -6016,9 +6033,9 @@ var init_handler2 = __esm({
|
|
|
6016
6033
|
_watchWithNodeFs(path15, listener) {
|
|
6017
6034
|
const opts = this.fsw.options;
|
|
6018
6035
|
const directory = sp.dirname(path15);
|
|
6019
|
-
const
|
|
6036
|
+
const basename6 = sp.basename(path15);
|
|
6020
6037
|
const parent = this.fsw._getWatchedDir(directory);
|
|
6021
|
-
parent.add(
|
|
6038
|
+
parent.add(basename6);
|
|
6022
6039
|
const absolutePath = sp.resolve(path15);
|
|
6023
6040
|
const options = {
|
|
6024
6041
|
persistent: opts.persistent
|
|
@@ -6028,7 +6045,7 @@ var init_handler2 = __esm({
|
|
|
6028
6045
|
let closer;
|
|
6029
6046
|
if (opts.usePolling) {
|
|
6030
6047
|
const enableBin = opts.interval !== opts.binaryInterval;
|
|
6031
|
-
options.interval = enableBin && isBinaryPath(
|
|
6048
|
+
options.interval = enableBin && isBinaryPath(basename6) ? opts.binaryInterval : opts.interval;
|
|
6032
6049
|
closer = setFsWatchFileListener(path15, absolutePath, options, {
|
|
6033
6050
|
listener,
|
|
6034
6051
|
rawEmitter: this.fsw._emitRaw
|
|
@@ -6051,10 +6068,10 @@ var init_handler2 = __esm({
|
|
|
6051
6068
|
return;
|
|
6052
6069
|
}
|
|
6053
6070
|
const dirname9 = sp.dirname(file2);
|
|
6054
|
-
const
|
|
6071
|
+
const basename6 = sp.basename(file2);
|
|
6055
6072
|
const parent = this.fsw._getWatchedDir(dirname9);
|
|
6056
6073
|
let prevStats = stats;
|
|
6057
|
-
if (parent.has(
|
|
6074
|
+
if (parent.has(basename6))
|
|
6058
6075
|
return;
|
|
6059
6076
|
const listener = async (path15, newStats) => {
|
|
6060
6077
|
if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file2, 5))
|
|
@@ -6079,9 +6096,9 @@ var init_handler2 = __esm({
|
|
|
6079
6096
|
prevStats = newStats2;
|
|
6080
6097
|
}
|
|
6081
6098
|
} catch (error48) {
|
|
6082
|
-
this.fsw._remove(dirname9,
|
|
6099
|
+
this.fsw._remove(dirname9, basename6);
|
|
6083
6100
|
}
|
|
6084
|
-
} else if (parent.has(
|
|
6101
|
+
} else if (parent.has(basename6)) {
|
|
6085
6102
|
const at2 = newStats.atimeMs;
|
|
6086
6103
|
const mt2 = newStats.mtimeMs;
|
|
6087
6104
|
if (!at2 || at2 <= mt2 || mt2 !== prevStats.mtimeMs) {
|
|
@@ -7236,12 +7253,15 @@ var init_provider_loader = __esm({
|
|
|
7236
7253
|
const result = [];
|
|
7237
7254
|
for (const p of this.providers.values()) {
|
|
7238
7255
|
if ((p.category === "cli" || p.category === "acp") && p.spawn?.command) {
|
|
7256
|
+
const verCmdConfig = p.versionCommand;
|
|
7257
|
+
const versionCommand = typeof verCmdConfig === "object" && verCmdConfig !== null ? verCmdConfig[process.platform] : verCmdConfig;
|
|
7239
7258
|
result.push({
|
|
7240
7259
|
id: p.type,
|
|
7241
7260
|
displayName: p.displayName || p.name,
|
|
7242
7261
|
icon: p.icon || "\u{1F527}",
|
|
7243
7262
|
command: p.spawn.command,
|
|
7244
|
-
category: p.category
|
|
7263
|
+
category: p.category,
|
|
7264
|
+
...typeof versionCommand === "string" && versionCommand.trim() ? { versionCommand: versionCommand.trim() } : {}
|
|
7245
7265
|
});
|
|
7246
7266
|
}
|
|
7247
7267
|
}
|
|
@@ -18309,6 +18329,12 @@ __export(provider_cli_adapter_exports, {
|
|
|
18309
18329
|
function stripAnsi(str) {
|
|
18310
18330
|
return str.replace(/\x1B\[\d*[A-HJKSTfG]/g, " ").replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "").replace(/\x1B\][^\x07]*\x07/g, "").replace(/\x1B\][^\x1B]*\x1B\\/g, "").replace(/ +/g, " ");
|
|
18311
18331
|
}
|
|
18332
|
+
function stripTerminalNoise(str) {
|
|
18333
|
+
return String(str || "").replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F]/g, "").replace(/(^|[\s([])(?:\??\d{1,4}(?:;\d{1,4})*[A-Za-z])(?=$|[\s)\]])/g, "$1").replace(/(^|[\s([])(?:\[\??\d{1,4}(?:;\d{1,4})*[A-Za-z])(?=$|[\s)\]])/g, "$1").replace(/(^|[\s([])(?:\d{1,4};\?)(?=$|[\s)\]])/g, "$1").replace(/\r+/g, "\n").replace(/[ \t]+\n/g, "\n").replace(/\n{3,}/g, "\n\n").replace(/ {2,}/g, " ");
|
|
18334
|
+
}
|
|
18335
|
+
function sanitizeTerminalText(str) {
|
|
18336
|
+
return stripTerminalNoise(stripAnsi(str));
|
|
18337
|
+
}
|
|
18312
18338
|
function findBinary(name) {
|
|
18313
18339
|
const isWin = os12.platform() === "win32";
|
|
18314
18340
|
try {
|
|
@@ -18541,6 +18567,9 @@ var init_provider_cli_adapter = __esm({
|
|
|
18541
18567
|
// Approval state machine
|
|
18542
18568
|
approvalTransitionBuffer = "";
|
|
18543
18569
|
approvalExitTimeout = null;
|
|
18570
|
+
pendingScriptStatus = null;
|
|
18571
|
+
pendingScriptStatusSince = 0;
|
|
18572
|
+
pendingScriptStatusTimer = null;
|
|
18544
18573
|
// Output settle debounce — fires after PTY output goes quiet
|
|
18545
18574
|
settleTimer = null;
|
|
18546
18575
|
settledBuffer = "";
|
|
@@ -18606,6 +18635,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
18606
18635
|
sendDelayMs;
|
|
18607
18636
|
sendKey;
|
|
18608
18637
|
submitStrategy;
|
|
18638
|
+
static SCRIPT_STATUS_DEBOUNCE_MS = 1e3;
|
|
18609
18639
|
/** Inject CLI scripts after construction (e.g. when resolved by ProviderLoader) */
|
|
18610
18640
|
setCliScripts(scripts) {
|
|
18611
18641
|
this.cliScripts = scripts;
|
|
@@ -18732,7 +18762,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
18732
18762
|
handleOutput(rawData) {
|
|
18733
18763
|
this.terminalScreen.write(rawData);
|
|
18734
18764
|
this.terminalHistory = mergeTerminalHistory(this.terminalHistory, this.terminalScreen.getText());
|
|
18735
|
-
const cleanData =
|
|
18765
|
+
const cleanData = sanitizeTerminalText(rawData);
|
|
18736
18766
|
if (this.isWaitingForResponse && cleanData) {
|
|
18737
18767
|
this.responseBuffer = (this.responseBuffer + cleanData).slice(-8e3);
|
|
18738
18768
|
}
|
|
@@ -18829,24 +18859,39 @@ var init_provider_cli_adapter = __esm({
|
|
|
18829
18859
|
const scriptStatus = rawScriptStatus;
|
|
18830
18860
|
if (!scriptStatus) return;
|
|
18831
18861
|
const prevStatus = this.currentStatus;
|
|
18832
|
-
|
|
18833
|
-
|
|
18834
|
-
|
|
18835
|
-
|
|
18836
|
-
|
|
18837
|
-
|
|
18838
|
-
|
|
18839
|
-
|
|
18840
|
-
|
|
18841
|
-
|
|
18842
|
-
|
|
18843
|
-
|
|
18844
|
-
|
|
18845
|
-
|
|
18846
|
-
|
|
18847
|
-
|
|
18862
|
+
const clearPendingScriptStatus = () => {
|
|
18863
|
+
this.pendingScriptStatus = null;
|
|
18864
|
+
this.pendingScriptStatusSince = 0;
|
|
18865
|
+
if (this.pendingScriptStatusTimer) {
|
|
18866
|
+
clearTimeout(this.pendingScriptStatusTimer);
|
|
18867
|
+
this.pendingScriptStatusTimer = null;
|
|
18868
|
+
}
|
|
18869
|
+
};
|
|
18870
|
+
const armPendingScriptStatus = (delayMs) => {
|
|
18871
|
+
if (this.pendingScriptStatusTimer) clearTimeout(this.pendingScriptStatusTimer);
|
|
18872
|
+
this.pendingScriptStatusTimer = setTimeout(() => {
|
|
18873
|
+
this.pendingScriptStatusTimer = null;
|
|
18874
|
+
this.settledBuffer = this.recentOutputBuffer;
|
|
18875
|
+
this.evaluateSettled();
|
|
18876
|
+
}, delayMs);
|
|
18877
|
+
};
|
|
18878
|
+
const shouldDebouncePromotion = (status) => prevStatus === "idle" && !this.isWaitingForResponse && !this.currentTurnScope && (status === "generating" || status === "waiting_approval");
|
|
18879
|
+
if (shouldDebouncePromotion(scriptStatus)) {
|
|
18880
|
+
if (this.pendingScriptStatus !== scriptStatus) {
|
|
18881
|
+
this.pendingScriptStatus = scriptStatus;
|
|
18882
|
+
this.pendingScriptStatusSince = now;
|
|
18883
|
+
armPendingScriptStatus(_ProviderCliAdapter.SCRIPT_STATUS_DEBOUNCE_MS);
|
|
18884
|
+
return;
|
|
18885
|
+
}
|
|
18886
|
+
const elapsed = now - this.pendingScriptStatusSince;
|
|
18887
|
+
if (elapsed < _ProviderCliAdapter.SCRIPT_STATUS_DEBOUNCE_MS) {
|
|
18888
|
+
armPendingScriptStatus(_ProviderCliAdapter.SCRIPT_STATUS_DEBOUNCE_MS - elapsed);
|
|
18848
18889
|
return;
|
|
18849
18890
|
}
|
|
18891
|
+
} else {
|
|
18892
|
+
clearPendingScriptStatus();
|
|
18893
|
+
}
|
|
18894
|
+
if (scriptStatus === "waiting_approval") {
|
|
18850
18895
|
const inCooldown = this.lastApprovalResolvedAt && Date.now() - this.lastApprovalResolvedAt < this.timeouts.approvalCooldown;
|
|
18851
18896
|
if (!inCooldown) {
|
|
18852
18897
|
this.isWaitingForResponse = true;
|
|
@@ -18859,6 +18904,12 @@ var init_provider_cli_adapter = __esm({
|
|
|
18859
18904
|
}
|
|
18860
18905
|
}
|
|
18861
18906
|
if (scriptStatus === "generating") {
|
|
18907
|
+
const screenText = this.terminalScreen.getText() || this.accumulatedBuffer;
|
|
18908
|
+
const noActiveTurn = !this.currentTurnScope;
|
|
18909
|
+
const looksIdleChrome = /(^|\n)\s*[❯›>]\s*(?:\n|$)/m.test(screenText) || /accept edits on/i.test(screenText) && (/Update available!/i.test(screenText) || /\/effort/i.test(screenText) || /^.*➜\s+\S+/m.test(screenText));
|
|
18910
|
+
if (prevStatus === "idle" && !this.isWaitingForResponse && noActiveTurn && !modal && looksIdleChrome) {
|
|
18911
|
+
return;
|
|
18912
|
+
}
|
|
18862
18913
|
if (prevStatus === "waiting_approval") {
|
|
18863
18914
|
if (this.approvalExitTimeout) {
|
|
18864
18915
|
clearTimeout(this.approvalExitTimeout);
|
|
@@ -19316,7 +19367,7 @@ ${data.message || ""}`.trim();
|
|
|
19316
19367
|
committedMessages: this.committedMessages.slice(-20),
|
|
19317
19368
|
structuredMessages: this.structuredMessages.slice(-20),
|
|
19318
19369
|
messageCount: this.committedMessages.length,
|
|
19319
|
-
screenText: this.terminalScreen.getText().slice(-4e3),
|
|
19370
|
+
screenText: sanitizeTerminalText(this.terminalScreen.getText()).slice(-4e3),
|
|
19320
19371
|
terminalHistory: this.terminalHistory.slice(-8e3),
|
|
19321
19372
|
currentTurnScope: this.currentTurnScope,
|
|
19322
19373
|
startupBuffer: this.startupBuffer.slice(-4e3),
|
|
@@ -19325,6 +19376,7 @@ ${data.message || ""}`.trim();
|
|
|
19325
19376
|
accumulatedBufferLength: this.accumulatedBuffer.length,
|
|
19326
19377
|
accumulatedRawBufferLength: this.accumulatedRawBuffer.length,
|
|
19327
19378
|
rawBufferPreview: this.accumulatedRawBuffer.slice(-1e3),
|
|
19379
|
+
sanitizedRawPreview: sanitizeTerminalText(this.accumulatedRawBuffer).slice(-1e3),
|
|
19328
19380
|
responseBuffer: this.responseBuffer.slice(-1e3),
|
|
19329
19381
|
isWaitingForResponse: this.isWaitingForResponse,
|
|
19330
19382
|
activeModal: this.activeModal,
|
|
@@ -19408,19 +19460,6 @@ var init_cli_provider_instance = __esm({
|
|
|
19408
19460
|
getState() {
|
|
19409
19461
|
const adapterStatus = this.adapter.getStatus();
|
|
19410
19462
|
const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
|
|
19411
|
-
const recentMessages = adapterStatus.messages.slice(-50).map((m) => {
|
|
19412
|
-
const content = typeof m.content === "string" && m.content.length > 8e3 ? m.content.slice(0, 8e3) + "\n... (truncated)" : m.content;
|
|
19413
|
-
return { ...m, content };
|
|
19414
|
-
});
|
|
19415
|
-
if (recentMessages.length > 0) {
|
|
19416
|
-
const dirName2 = this.workingDir.split("/").filter(Boolean).pop() || "session";
|
|
19417
|
-
this.historyWriter.appendNewMessages(
|
|
19418
|
-
this.type,
|
|
19419
|
-
recentMessages,
|
|
19420
|
-
`${this.provider.name} \xB7 ${dirName2}`,
|
|
19421
|
-
this.instanceId
|
|
19422
|
-
);
|
|
19423
|
-
}
|
|
19424
19463
|
if (adapterStatus.terminalHistory?.trim()) {
|
|
19425
19464
|
this.historyWriter.appendTerminalHistory(
|
|
19426
19465
|
this.type,
|
|
@@ -19434,12 +19473,12 @@ var init_cli_provider_instance = __esm({
|
|
|
19434
19473
|
name: this.provider.name,
|
|
19435
19474
|
category: "cli",
|
|
19436
19475
|
status: adapterStatus.status,
|
|
19437
|
-
mode:
|
|
19476
|
+
mode: "terminal",
|
|
19438
19477
|
activeChat: {
|
|
19439
19478
|
id: `${this.type}_${this.workingDir}`,
|
|
19440
19479
|
title: `${this.provider.name} \xB7 ${dirName}`,
|
|
19441
19480
|
status: adapterStatus.status,
|
|
19442
|
-
messages:
|
|
19481
|
+
messages: [],
|
|
19443
19482
|
activeModal: adapterStatus.activeModal,
|
|
19444
19483
|
terminalHistory: adapterStatus.terminalHistory,
|
|
19445
19484
|
inputContent: ""
|
|
@@ -19453,11 +19492,15 @@ var init_cli_provider_instance = __esm({
|
|
|
19453
19492
|
}
|
|
19454
19493
|
onEvent(event, data) {
|
|
19455
19494
|
if (event === "send_message" && data?.text) {
|
|
19456
|
-
this.adapter.sendMessage(data.text)
|
|
19495
|
+
void this.adapter.sendMessage(data.text).catch((e) => {
|
|
19496
|
+
LOG.warn("CLI", `[${this.type}] send_message failed: ${e?.message || e}`);
|
|
19497
|
+
});
|
|
19457
19498
|
} else if (event === "server_connected" && data?.serverConn) {
|
|
19458
19499
|
this.adapter.setServerConn(data.serverConn);
|
|
19459
19500
|
} else if (event === "resolve_action" && data) {
|
|
19460
|
-
this.adapter.resolveAction(data)
|
|
19501
|
+
void this.adapter.resolveAction(data).catch((e) => {
|
|
19502
|
+
LOG.warn("CLI", `[${this.type}] resolve_action failed: ${e?.message || e}`);
|
|
19503
|
+
});
|
|
19461
19504
|
}
|
|
19462
19505
|
}
|
|
19463
19506
|
dispose() {
|
|
@@ -37899,18 +37942,18 @@ function findBinary2(name) {
|
|
|
37899
37942
|
const result = runCommand(cmd, 5e3);
|
|
37900
37943
|
return result ? result.split("\n")[0] : null;
|
|
37901
37944
|
}
|
|
37902
|
-
function
|
|
37945
|
+
function parseVersion2(raw) {
|
|
37903
37946
|
const match = raw.match(/v?(\d+\.\d+(?:\.\d+)?(?:-[a-zA-Z0-9.]+)?)/);
|
|
37904
37947
|
return match ? match[1] : raw.split("\n")[0].substring(0, 100);
|
|
37905
37948
|
}
|
|
37906
37949
|
function getVersion(binary, versionCommand) {
|
|
37907
37950
|
if (versionCommand) {
|
|
37908
37951
|
const raw = runCommand(versionCommand);
|
|
37909
|
-
return raw ?
|
|
37952
|
+
return raw ? parseVersion2(raw) : null;
|
|
37910
37953
|
}
|
|
37911
37954
|
for (const flag of ["--version", "-V", "-v"]) {
|
|
37912
37955
|
const raw = runCommand(`"${binary}" ${flag}`);
|
|
37913
|
-
if (raw && raw.length < 500) return
|
|
37956
|
+
if (raw && raw.length < 500) return parseVersion2(raw);
|
|
37914
37957
|
}
|
|
37915
37958
|
return null;
|
|
37916
37959
|
}
|
|
@@ -40244,16 +40287,16 @@ var init_dev_server = __esm({
|
|
|
40244
40287
|
resolveAutoImplWritableProviderDir(category, type, requestedDir) {
|
|
40245
40288
|
const canonicalUserDir = path12.resolve(this.providerLoader.getUserProviderDir(category, type));
|
|
40246
40289
|
const desiredDir = requestedDir ? path12.resolve(requestedDir) : canonicalUserDir;
|
|
40247
|
-
|
|
40248
|
-
|
|
40290
|
+
const upstreamRoot = path12.resolve(this.providerLoader.getUpstreamDir());
|
|
40291
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path12.sep}`)) {
|
|
40292
|
+
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
40249
40293
|
}
|
|
40250
|
-
|
|
40251
|
-
|
|
40252
|
-
return null;
|
|
40294
|
+
if (path12.basename(desiredDir) !== type) {
|
|
40295
|
+
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
40253
40296
|
}
|
|
40254
40297
|
const sourceDir = this.findProviderDir(type);
|
|
40255
40298
|
if (!sourceDir) {
|
|
40256
|
-
return null;
|
|
40299
|
+
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
40257
40300
|
}
|
|
40258
40301
|
if (!fs10.existsSync(desiredDir)) {
|
|
40259
40302
|
fs10.mkdirSync(path12.dirname(desiredDir), { recursive: true });
|
|
@@ -40262,7 +40305,7 @@ var init_dev_server = __esm({
|
|
|
40262
40305
|
}
|
|
40263
40306
|
const providerJson = path12.join(desiredDir, "provider.json");
|
|
40264
40307
|
if (!fs10.existsSync(providerJson)) {
|
|
40265
|
-
return null;
|
|
40308
|
+
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
40266
40309
|
}
|
|
40267
40310
|
try {
|
|
40268
40311
|
const providerData = JSON.parse(fs10.readFileSync(providerJson, "utf-8"));
|
|
@@ -40270,10 +40313,13 @@ var init_dev_server = __esm({
|
|
|
40270
40313
|
providerData.disableUpstream = true;
|
|
40271
40314
|
fs10.writeFileSync(providerJson, JSON.stringify(providerData, null, 2));
|
|
40272
40315
|
}
|
|
40273
|
-
} catch {
|
|
40274
|
-
return
|
|
40316
|
+
} catch (error48) {
|
|
40317
|
+
return {
|
|
40318
|
+
dir: null,
|
|
40319
|
+
reason: `Failed to update provider.json in writable provider directory: ${error48.message}`
|
|
40320
|
+
};
|
|
40275
40321
|
}
|
|
40276
|
-
return desiredDir;
|
|
40322
|
+
return { dir: desiredDir };
|
|
40277
40323
|
}
|
|
40278
40324
|
loadAutoImplReferenceScripts(referenceType) {
|
|
40279
40325
|
if (!referenceType) return {};
|
|
@@ -40308,13 +40354,14 @@ var init_dev_server = __esm({
|
|
|
40308
40354
|
this.json(res, 404, { error: `Provider not found: ${type}` });
|
|
40309
40355
|
return;
|
|
40310
40356
|
}
|
|
40311
|
-
const
|
|
40312
|
-
if (!
|
|
40357
|
+
const writableProvider = this.resolveAutoImplWritableProviderDir(provider.category, type, requestedProviderDir);
|
|
40358
|
+
if (!writableProvider.dir) {
|
|
40313
40359
|
this.json(res, 409, {
|
|
40314
|
-
error: `Auto-implement only writes to the canonical user provider directory for '${type}'.`
|
|
40360
|
+
error: writableProvider.reason || `Auto-implement only writes to the canonical user provider directory for '${type}'.`
|
|
40315
40361
|
});
|
|
40316
40362
|
return;
|
|
40317
40363
|
}
|
|
40364
|
+
const providerDir = writableProvider.dir;
|
|
40318
40365
|
try {
|
|
40319
40366
|
const resolvedReference = this.resolveAutoImplReference(provider.category, reference, type);
|
|
40320
40367
|
this.sendAutoImplSSE({
|
|
@@ -40815,14 +40862,16 @@ var init_dev_server = __esm({
|
|
|
40815
40862
|
lines.push("| Status | When to use | How to detect |");
|
|
40816
40863
|
lines.push("|---|---|---|");
|
|
40817
40864
|
lines.push("| `idle` | AI is NOT generating, no approval needed | Default state. No stop button, no spinners, no approval pills/buttons |");
|
|
40818
|
-
lines.push(
|
|
40865
|
+
lines.push('| `generating` | AI is actively streaming/thinking | ANY of: (1) Submit button icon SVG changes (e.g. arrow\u2192stop square, fill="none"\u2192fill="currentColor"), (2) Stop/Cancel button visible, (3) CSS animation, (4) Structural markers (aria-labels that only appear during generation) |');
|
|
40819
40866
|
lines.push("| `waiting_approval` | AI stopped and needs user action | Actionable buttons like Run/Skip/Accept/Reject are visible AND clickable |");
|
|
40820
40867
|
lines.push("");
|
|
40821
40868
|
lines.push("### \u26A0\uFE0F Status Detection Gotchas (MUST READ!)");
|
|
40822
|
-
lines.push(
|
|
40823
|
-
lines.push('2. **
|
|
40824
|
-
lines.push("3. **
|
|
40825
|
-
lines.push(
|
|
40869
|
+
lines.push(`1. **DO NOT rely on button text/labels in the user's language.** OS locale may be Korean, Japanese, etc. Button text like "Cancel" or "Stop" will be localized. Instead, detect STRUCTURAL indicators: SVG icon changes, CSS classes, aria-labels from the extension's own React/Radix UI (which stay in English regardless of OS locale).`);
|
|
40870
|
+
lines.push('2. **Use sendMessage to CREATE a generating state, then CAPTURE the DOM.** Send a LONG prompt (e.g. "Write an extremely detailed 5000-word essay...") so the AI takes 10+ seconds. Then periodically capture the DOM during generation to find which elements appear/change. Compare idle vs generating DOM snapshots to find reliable structural markers.');
|
|
40871
|
+
lines.push("3. **Look for SVG icon changes in the submit button.** Many IDEs change the submit button icon from an arrow (send) to a square (stop) during generation. Check the SVG `fill` attribute or path data.");
|
|
40872
|
+
lines.push('4. **FALSE POSITIVES from old messages**: Chat history may contain text like "Command Awaiting Approval" from PAST turns. ONLY match small leaf elements (under 80 chars) or use explicit button/pill selectors.');
|
|
40873
|
+
lines.push("5. **Awaiting Approval pill without actions**: Some IDEs show a floating pill/banner that is just a scroll-to indicator. If NO actionable buttons exist, the status should be `idle`, NOT `waiting_approval`.");
|
|
40874
|
+
lines.push("6. **activeModal must include actions**: When `status` is `waiting_approval`, the `activeModal` object MUST include a non-empty `actions` array.");
|
|
40826
40875
|
lines.push("");
|
|
40827
40876
|
lines.push("## Action");
|
|
40828
40877
|
lines.push("1. Edit the script files to implement working code");
|
|
@@ -40880,10 +40929,10 @@ var init_dev_server = __esm({
|
|
|
40880
40929
|
lines.push(`echo "$RESULT" | python3 -c "import sys,json; d=json.load(sys.stdin); r=d.get('result',d); r=json.loads(r) if isinstance(r,str) else r; assert r.get('status')=='idle', f'Expected idle, got {r.get(chr(34)+chr(115)+chr(116)+chr(97)+chr(116)+chr(117)+chr(115)+chr(34))}'; print('Step 1 PASS: status=idle')"`);
|
|
40881
40930
|
lines.push("```");
|
|
40882
40931
|
lines.push("");
|
|
40883
|
-
lines.push("### Step 2: Send a message that triggers generation");
|
|
40932
|
+
lines.push("### Step 2: Send a LONG message that triggers extended generation (10+ seconds)");
|
|
40884
40933
|
lines.push("```bash");
|
|
40885
|
-
lines.push(`curl -sS -X POST http://127.0.0.1:${DEV_SERVER_PORT}/api/scripts/run -H "Content-Type: application/json" -d '{"script": "sendMessage", "type": "${type}", "ideType": "${type}", "args": {"message": "
|
|
40886
|
-
lines.push("sleep
|
|
40934
|
+
lines.push(`curl -sS -X POST http://127.0.0.1:${DEV_SERVER_PORT}/api/scripts/run -H "Content-Type: application/json" -d '{"script": "sendMessage", "type": "${type}", "ideType": "${type}", "args": {"message": "Write an extremely detailed 5000-word essay about the history of artificial intelligence from Alan Turing to 2025. Be very thorough and verbose."}}'`);
|
|
40935
|
+
lines.push("sleep 3");
|
|
40887
40936
|
lines.push("```");
|
|
40888
40937
|
lines.push("");
|
|
40889
40938
|
lines.push("### Step 3: Check generating OR completed");
|
|
@@ -41007,6 +41056,9 @@ var init_dev_server = __esm({
|
|
|
41007
41056
|
lines.push("8. Keep exports compatible with the existing `scripts.js` router (`module.exports = function ...`).");
|
|
41008
41057
|
lines.push("9. Do not rewrite unrelated provider config. Only touch the scripts needed for this task unless a tiny supporting change is required.");
|
|
41009
41058
|
lines.push("10. When the verification API returns `instanceId`, keep using that exact instance for follow-up `send`, `resolve`, `raw`, and `stop` calls. Do not assume type-only routing is safe if multiple sessions exist.");
|
|
41059
|
+
lines.push("11. Do NOT repeatedly dump the same target files. Read the target scripts once, reproduce the bug, then move directly to patching.");
|
|
41060
|
+
lines.push("12. If the user instructions include concrete screen text, raw PTY snippets, or a specific repro, treat that as the primary acceptance criteria.");
|
|
41061
|
+
lines.push("13. After the first successful live repro, stop broad diagnosis. Edit the scripts, reload, and verify. Do not burn tokens on repeated re-inspection without code changes.");
|
|
41010
41062
|
lines.push("");
|
|
41011
41063
|
lines.push("## Task");
|
|
41012
41064
|
lines.push(`Edit files in \`${providerDir}\` to implement: **${functions.join(", ")}**`);
|
|
@@ -41048,6 +41100,9 @@ var init_dev_server = __esm({
|
|
|
41048
41100
|
lines.push("");
|
|
41049
41101
|
lines.push("Use `resolve` when the parsed modal buttons are correct. Use `raw` when the CLI expects a literal keystroke like `1`, `y`, or Enter. Repeat until idle.");
|
|
41050
41102
|
lines.push("");
|
|
41103
|
+
lines.push("### Patch Discipline");
|
|
41104
|
+
lines.push("Once the repro is confirmed, immediately edit the target files. Avoid loops where you keep re-reading long files or re-running the same debug commands without changing code.");
|
|
41105
|
+
lines.push("");
|
|
41051
41106
|
lines.push("### 5. Verify the side effects outside the CLI");
|
|
41052
41107
|
lines.push("```bash");
|
|
41053
41108
|
lines.push("test -f tmp/adhdev_provider_fix_test.py");
|
|
@@ -43209,7 +43264,7 @@ var init_adhdev_daemon = __esm({
|
|
|
43209
43264
|
fs12 = __toESM(require("fs"));
|
|
43210
43265
|
path14 = __toESM(require("path"));
|
|
43211
43266
|
import_chalk2 = __toESM(require("chalk"));
|
|
43212
|
-
pkgVersion = "0.6.
|
|
43267
|
+
pkgVersion = "0.6.77";
|
|
43213
43268
|
if (pkgVersion === "unknown") {
|
|
43214
43269
|
try {
|
|
43215
43270
|
const possiblePaths = [
|
|
@@ -44698,13 +44753,21 @@ function hideCommand2(command) {
|
|
|
44698
44753
|
command.hideHelp?.();
|
|
44699
44754
|
return command;
|
|
44700
44755
|
}
|
|
44756
|
+
async function createConfiguredProviderLoader() {
|
|
44757
|
+
const { ProviderLoader: ProviderLoader2, loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
44758
|
+
const config2 = loadConfig2();
|
|
44759
|
+
const loader = new ProviderLoader2({
|
|
44760
|
+
userDir: config2.providerDir,
|
|
44761
|
+
disableUpstream: config2.disableUpstream
|
|
44762
|
+
});
|
|
44763
|
+
loader.loadAll();
|
|
44764
|
+
return loader;
|
|
44765
|
+
}
|
|
44701
44766
|
function registerProviderCommands(program2) {
|
|
44702
44767
|
const provider = hideCommand2(program2.command("provider").description("\u{1F50C} Provider management \u2014 list, test, reload providers"));
|
|
44703
44768
|
provider.command("list").description("List all loaded providers").option("-j, --json", "Output raw JSON").action(async (options) => {
|
|
44704
44769
|
try {
|
|
44705
|
-
const
|
|
44706
|
-
const loader = new ProviderLoader2();
|
|
44707
|
-
loader.loadAll();
|
|
44770
|
+
const loader = await createConfiguredProviderLoader();
|
|
44708
44771
|
const providers = loader.getAll();
|
|
44709
44772
|
if (options.json) {
|
|
44710
44773
|
console.log(JSON.stringify(providers.map((p) => ({
|
|
@@ -44918,8 +44981,7 @@ function registerProviderCommands(program2) {
|
|
|
44918
44981
|
}).catch(async () => {
|
|
44919
44982
|
const pathMod = await import("path");
|
|
44920
44983
|
const fsMod = await import("fs");
|
|
44921
|
-
const
|
|
44922
|
-
const loader = new ProviderLoader2();
|
|
44984
|
+
const loader = await createConfiguredProviderLoader();
|
|
44923
44985
|
let targetDir = location === "builtin" ? loader.getUpstreamProviderDir(category, type) : loader.getUserProviderDir(category, type);
|
|
44924
44986
|
if (fsMod.existsSync(targetDir)) return { error: `Provider already exists at ${targetDir}` };
|
|
44925
44987
|
const isExt = category === "extension";
|
|
@@ -44972,9 +45034,7 @@ function registerProviderCommands(program2) {
|
|
|
44972
45034
|
try {
|
|
44973
45035
|
const http3 = await import("http");
|
|
44974
45036
|
const inquirer2 = (await import("inquirer")).default;
|
|
44975
|
-
const
|
|
44976
|
-
const loader = new ProviderLoader2();
|
|
44977
|
-
loader.loadAll();
|
|
45037
|
+
const loader = await createConfiguredProviderLoader();
|
|
44978
45038
|
const allProviders = loader.getAll();
|
|
44979
45039
|
const fsMod = await import("fs");
|
|
44980
45040
|
const isUserProvider = (p) => {
|
|
@@ -45143,10 +45203,7 @@ function registerProviderCommands(program2) {
|
|
|
45143
45203
|
throw new Error(`Unexpected response: ${JSON.stringify(startResult)}`);
|
|
45144
45204
|
}
|
|
45145
45205
|
const pathMod = await import("path");
|
|
45146
|
-
const
|
|
45147
|
-
const loader2 = new ProviderLoader3();
|
|
45148
|
-
loader2.loadAll();
|
|
45149
|
-
const providerMeta = loader2.getMeta(type);
|
|
45206
|
+
const providerMeta = loader.getMeta(type);
|
|
45150
45207
|
if (!providerMeta) throw new Error(`Unknown provider: ${type}`);
|
|
45151
45208
|
const fsMock = await import("fs");
|
|
45152
45209
|
const logFile2 = pathMod.join(targetDir, `auto-impl.log`);
|
|
@@ -45327,9 +45384,7 @@ function registerProviderCommands(program2) {
|
|
|
45327
45384
|
}).catch(async () => {
|
|
45328
45385
|
const pathMod = await import("path");
|
|
45329
45386
|
const fsMod = await import("fs");
|
|
45330
|
-
const
|
|
45331
|
-
const loader = new ProviderLoader2();
|
|
45332
|
-
loader.loadAll();
|
|
45387
|
+
const loader = await createConfiguredProviderLoader();
|
|
45333
45388
|
const providerMeta = loader.getMeta(type);
|
|
45334
45389
|
if (!providerMeta) {
|
|
45335
45390
|
return { error: `Provider '${type}' not found` };
|