adhdev 0.6.53 → 0.6.55
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 +817 -300
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +749 -277
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/cli/index.js
CHANGED
|
@@ -3341,6 +3341,9 @@ var init_builders = __esm({
|
|
|
3341
3341
|
});
|
|
3342
3342
|
|
|
3343
3343
|
// ../daemon-core/src/commands/chat-commands.ts
|
|
3344
|
+
function getTargetedCliAdapter(h, args, providerType) {
|
|
3345
|
+
return h.getCliAdapter(args?._targetInstance || h.currentIdeType || providerType);
|
|
3346
|
+
}
|
|
3344
3347
|
async function handleChatHistory(h, args) {
|
|
3345
3348
|
const { agentType, offset, limit, instanceId } = args;
|
|
3346
3349
|
try {
|
|
@@ -3353,10 +3356,10 @@ async function handleChatHistory(h, args) {
|
|
|
3353
3356
|
}
|
|
3354
3357
|
}
|
|
3355
3358
|
async function handleReadChat(h, args) {
|
|
3356
|
-
const provider = h.getProvider();
|
|
3359
|
+
const provider = h.getProvider(args?.agentType);
|
|
3357
3360
|
const _log = (msg) => LOG.debug("Command", `[read_chat] ${msg}`);
|
|
3358
3361
|
if (provider?.category === "cli" || provider?.category === "acp") {
|
|
3359
|
-
const adapter = h
|
|
3362
|
+
const adapter = getTargetedCliAdapter(h, args, provider.type);
|
|
3360
3363
|
if (adapter) {
|
|
3361
3364
|
_log(`${provider.category} adapter: ${adapter.cliType}`);
|
|
3362
3365
|
const status = adapter.getStatus?.();
|
|
@@ -3472,7 +3475,7 @@ async function handleSendChat(h, args) {
|
|
|
3472
3475
|
const text = args?.text || args?.message;
|
|
3473
3476
|
if (!text) return { success: false, error: "text required" };
|
|
3474
3477
|
const _log = (msg) => LOG.debug("Command", `[send_chat] ${msg}`);
|
|
3475
|
-
const provider = h.getProvider();
|
|
3478
|
+
const provider = h.getProvider(args?.agentType);
|
|
3476
3479
|
const _logSendSuccess = (method, targetAgent) => {
|
|
3477
3480
|
h.historyWriter.appendNewMessages(
|
|
3478
3481
|
targetAgent || provider?.type || h.currentIdeType || "unknown_agent",
|
|
@@ -3484,7 +3487,7 @@ async function handleSendChat(h, args) {
|
|
|
3484
3487
|
return { success: true, sent: true, method, targetAgent };
|
|
3485
3488
|
};
|
|
3486
3489
|
if (provider?.category === "cli" || provider?.category === "acp") {
|
|
3487
|
-
const adapter = h
|
|
3490
|
+
const adapter = getTargetedCliAdapter(h, args, provider.type);
|
|
3488
3491
|
if (adapter) {
|
|
3489
3492
|
_log(`${provider.category} adapter: ${adapter.cliType}`);
|
|
3490
3493
|
try {
|
|
@@ -3637,7 +3640,7 @@ async function handleSendChat(h, args) {
|
|
|
3637
3640
|
return { success: false, error: "No provider method could send the message" };
|
|
3638
3641
|
}
|
|
3639
3642
|
async function handleListChats(h, args) {
|
|
3640
|
-
const provider = h.getProvider();
|
|
3643
|
+
const provider = h.getProvider(args?.agentType);
|
|
3641
3644
|
if (provider?.category === "extension" && h.agentStream && h.getCdp()) {
|
|
3642
3645
|
try {
|
|
3643
3646
|
const chats = await h.agentStream.listAgentChats(h.getCdp(), provider.type);
|
|
@@ -3689,7 +3692,16 @@ async function handleListChats(h, args) {
|
|
|
3689
3692
|
return { success: false, error: "listSessions script not available for this provider" };
|
|
3690
3693
|
}
|
|
3691
3694
|
async function handleNewChat(h, args) {
|
|
3692
|
-
const provider = h.getProvider();
|
|
3695
|
+
const provider = h.getProvider(args?.agentType);
|
|
3696
|
+
if (provider?.category === "cli") {
|
|
3697
|
+
const adapter = getTargetedCliAdapter(h, args, provider.type);
|
|
3698
|
+
if (!adapter) return { success: false, error: "CLI adapter not running" };
|
|
3699
|
+
if (typeof adapter.clearHistory === "function") {
|
|
3700
|
+
adapter.clearHistory();
|
|
3701
|
+
return { success: true, cleared: true };
|
|
3702
|
+
}
|
|
3703
|
+
return { success: false, error: "new_chat not supported by this CLI provider" };
|
|
3704
|
+
}
|
|
3693
3705
|
if (provider?.category === "extension" && h.agentStream && h.getCdp()) {
|
|
3694
3706
|
const ok = await h.agentStream.newAgentSession(h.getCdp(), provider.type, h.currentIdeType);
|
|
3695
3707
|
return { success: ok };
|
|
@@ -3714,7 +3726,7 @@ async function handleNewChat(h, args) {
|
|
|
3714
3726
|
return { success: false, error: "newSession script not available for this provider" };
|
|
3715
3727
|
}
|
|
3716
3728
|
async function handleSwitchChat(h, args) {
|
|
3717
|
-
const provider = h.getProvider();
|
|
3729
|
+
const provider = h.getProvider(args?.agentType);
|
|
3718
3730
|
const ideType = h.currentIdeType;
|
|
3719
3731
|
const sessionId = args?.sessionId || args?.id || args?.chatId;
|
|
3720
3732
|
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
@@ -3808,10 +3820,10 @@ async function handleSwitchChat(h, args) {
|
|
|
3808
3820
|
}
|
|
3809
3821
|
}
|
|
3810
3822
|
async function handleSetMode(h, args) {
|
|
3811
|
-
const provider = h.getProvider();
|
|
3823
|
+
const provider = h.getProvider(args?.agentType);
|
|
3812
3824
|
const mode = args?.mode || "agent";
|
|
3813
3825
|
if (provider?.category === "acp") {
|
|
3814
|
-
const adapter = h
|
|
3826
|
+
const adapter = getTargetedCliAdapter(h, args, provider.type);
|
|
3815
3827
|
if (adapter) {
|
|
3816
3828
|
const acpInstance = adapter._acpInstance;
|
|
3817
3829
|
if (acpInstance && typeof acpInstance.onEvent === "function") {
|
|
@@ -3863,11 +3875,11 @@ async function handleSetMode(h, args) {
|
|
|
3863
3875
|
return { success: false, error: `setMode '${mode}' not supported by this provider` };
|
|
3864
3876
|
}
|
|
3865
3877
|
async function handleChangeModel(h, args) {
|
|
3866
|
-
const provider = h.getProvider();
|
|
3878
|
+
const provider = h.getProvider(args?.agentType);
|
|
3867
3879
|
const model = args?.model;
|
|
3868
3880
|
LOG.info("Command", `[change_model] model=${model} provider=${provider?.type} category=${provider?.category} ideType=${h.currentIdeType} providerType=${h.currentProviderType}`);
|
|
3869
3881
|
if (provider?.category === "acp") {
|
|
3870
|
-
const adapter = h
|
|
3882
|
+
const adapter = getTargetedCliAdapter(h, args, provider.type);
|
|
3871
3883
|
LOG.info("Command", `[change_model] ACP adapter found: ${!!adapter}, type=${adapter?.cliType}, hasAcpInstance=${!!adapter?._acpInstance}`);
|
|
3872
3884
|
if (adapter) {
|
|
3873
3885
|
const acpInstance = adapter._acpInstance;
|
|
@@ -3924,11 +3936,11 @@ async function handleSetThoughtLevel(h, args) {
|
|
|
3924
3936
|
const configId = args?.configId;
|
|
3925
3937
|
const value = args?.value;
|
|
3926
3938
|
if (!configId || !value) return { success: false, error: "configId and value required" };
|
|
3927
|
-
const provider = h.getProvider();
|
|
3939
|
+
const provider = h.getProvider(args?.agentType);
|
|
3928
3940
|
if (!provider || provider.category !== "acp") {
|
|
3929
3941
|
return { success: false, error: "set_thought_level only for ACP providers" };
|
|
3930
3942
|
}
|
|
3931
|
-
const adapter = h
|
|
3943
|
+
const adapter = getTargetedCliAdapter(h, args, provider.type);
|
|
3932
3944
|
const acpInstance = adapter?._acpInstance;
|
|
3933
3945
|
if (!acpInstance) return { success: false, error: "ACP instance not found" };
|
|
3934
3946
|
try {
|
|
@@ -3940,13 +3952,22 @@ async function handleSetThoughtLevel(h, args) {
|
|
|
3940
3952
|
}
|
|
3941
3953
|
}
|
|
3942
3954
|
async function handleResolveAction(h, args) {
|
|
3943
|
-
const provider = h.getProvider();
|
|
3955
|
+
const provider = h.getProvider(args?.agentType);
|
|
3944
3956
|
const action = args?.action || "approve";
|
|
3945
3957
|
const button = args?.button || args?.buttonText || (action === "approve" ? "Accept" : action === "reject" ? "Reject" : "Accept");
|
|
3946
3958
|
LOG.info("Command", `[resolveAction] action=${action} button="${button}" provider=${provider?.type}`);
|
|
3947
3959
|
if (provider?.category === "cli") {
|
|
3948
|
-
const adapter = h
|
|
3960
|
+
const adapter = getTargetedCliAdapter(h, args, provider.type);
|
|
3949
3961
|
if (!adapter) return { success: false, error: "CLI adapter not running" };
|
|
3962
|
+
if (args?.data && typeof adapter.resolveAction === "function") {
|
|
3963
|
+
try {
|
|
3964
|
+
await adapter.resolveAction(args.data);
|
|
3965
|
+
LOG.info("Command", `[resolveAction] CLI PTY \u2192 resolveAction triggered with data payload`);
|
|
3966
|
+
return { success: true, method: "cli-resolve-action" };
|
|
3967
|
+
} catch (e) {
|
|
3968
|
+
return { success: false, error: `CLI resolveAction failed: ${e.message}` };
|
|
3969
|
+
}
|
|
3970
|
+
}
|
|
3950
3971
|
const status = adapter.getStatus?.();
|
|
3951
3972
|
if (status?.status !== "waiting_approval") {
|
|
3952
3973
|
return { success: false, error: "Not in approval state" };
|
|
@@ -6183,8 +6204,9 @@ var init_provider_loader = __esm({
|
|
|
6183
6204
|
}
|
|
6184
6205
|
}
|
|
6185
6206
|
compareVersions(a, b) {
|
|
6186
|
-
const
|
|
6187
|
-
const
|
|
6207
|
+
const normalize2 = (v) => v.split(/[-_+]/)[0].split(".").map((x) => parseInt(x, 10) || 0);
|
|
6208
|
+
const pa = normalize2(a);
|
|
6209
|
+
const pb = normalize2(b);
|
|
6188
6210
|
for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
|
|
6189
6211
|
const va = pa[i] || 0;
|
|
6190
6212
|
const vb = pb[i] || 0;
|
|
@@ -7236,6 +7258,246 @@ var init_reporter = __esm({
|
|
|
7236
7258
|
}
|
|
7237
7259
|
});
|
|
7238
7260
|
|
|
7261
|
+
// ../daemon-core/src/cli-adapters/terminal-screen.ts
|
|
7262
|
+
function clamp(value, min, max) {
|
|
7263
|
+
return Math.max(min, Math.min(max, value));
|
|
7264
|
+
}
|
|
7265
|
+
var TerminalScreen;
|
|
7266
|
+
var init_terminal_screen = __esm({
|
|
7267
|
+
"../daemon-core/src/cli-adapters/terminal-screen.ts"() {
|
|
7268
|
+
"use strict";
|
|
7269
|
+
TerminalScreen = class {
|
|
7270
|
+
rows;
|
|
7271
|
+
cols;
|
|
7272
|
+
cursorRow = 0;
|
|
7273
|
+
cursorCol = 0;
|
|
7274
|
+
savedRow = 0;
|
|
7275
|
+
savedCol = 0;
|
|
7276
|
+
lines;
|
|
7277
|
+
constructor(rows = 40, cols = 120) {
|
|
7278
|
+
this.rows = rows;
|
|
7279
|
+
this.cols = cols;
|
|
7280
|
+
this.lines = this.makeLines(rows, cols);
|
|
7281
|
+
}
|
|
7282
|
+
reset(rows = this.rows, cols = this.cols) {
|
|
7283
|
+
this.rows = rows;
|
|
7284
|
+
this.cols = cols;
|
|
7285
|
+
this.cursorRow = 0;
|
|
7286
|
+
this.cursorCol = 0;
|
|
7287
|
+
this.savedRow = 0;
|
|
7288
|
+
this.savedCol = 0;
|
|
7289
|
+
this.lines = this.makeLines(rows, cols);
|
|
7290
|
+
}
|
|
7291
|
+
resize(rows, cols) {
|
|
7292
|
+
const nextRows = Math.max(1, rows | 0);
|
|
7293
|
+
const nextCols = Math.max(1, cols | 0);
|
|
7294
|
+
const next = this.makeLines(nextRows, nextCols);
|
|
7295
|
+
const copyRows = Math.min(this.rows, nextRows);
|
|
7296
|
+
const copyCols = Math.min(this.cols, nextCols);
|
|
7297
|
+
for (let r = 0; r < copyRows; r++) {
|
|
7298
|
+
for (let c = 0; c < copyCols; c++) {
|
|
7299
|
+
next[r][c] = this.lines[r][c];
|
|
7300
|
+
}
|
|
7301
|
+
}
|
|
7302
|
+
this.rows = nextRows;
|
|
7303
|
+
this.cols = nextCols;
|
|
7304
|
+
this.lines = next;
|
|
7305
|
+
this.cursorRow = clamp(this.cursorRow, 0, this.rows - 1);
|
|
7306
|
+
this.cursorCol = clamp(this.cursorCol, 0, this.cols - 1);
|
|
7307
|
+
this.savedRow = clamp(this.savedRow, 0, this.rows - 1);
|
|
7308
|
+
this.savedCol = clamp(this.savedCol, 0, this.cols - 1);
|
|
7309
|
+
}
|
|
7310
|
+
write(data) {
|
|
7311
|
+
let i = 0;
|
|
7312
|
+
while (i < data.length) {
|
|
7313
|
+
const ch = data[i];
|
|
7314
|
+
if (ch === "\x1B") {
|
|
7315
|
+
const consumed = this.consumeEscape(data, i);
|
|
7316
|
+
i = consumed > i ? consumed : i + 1;
|
|
7317
|
+
continue;
|
|
7318
|
+
}
|
|
7319
|
+
if (ch === "\r") {
|
|
7320
|
+
this.cursorCol = 0;
|
|
7321
|
+
i++;
|
|
7322
|
+
continue;
|
|
7323
|
+
}
|
|
7324
|
+
if (ch === "\n") {
|
|
7325
|
+
this.newLine();
|
|
7326
|
+
i++;
|
|
7327
|
+
continue;
|
|
7328
|
+
}
|
|
7329
|
+
if (ch === "\b") {
|
|
7330
|
+
this.cursorCol = Math.max(0, this.cursorCol - 1);
|
|
7331
|
+
i++;
|
|
7332
|
+
continue;
|
|
7333
|
+
}
|
|
7334
|
+
if (ch === " ") {
|
|
7335
|
+
const nextStop = Math.min(this.cols - 1, this.cursorCol + (8 - (this.cursorCol % 8 || 8)));
|
|
7336
|
+
while (this.cursorCol < nextStop) this.putChar(" ");
|
|
7337
|
+
i++;
|
|
7338
|
+
continue;
|
|
7339
|
+
}
|
|
7340
|
+
if (ch >= " " && ch !== "\x7F") {
|
|
7341
|
+
this.putChar(ch);
|
|
7342
|
+
}
|
|
7343
|
+
i++;
|
|
7344
|
+
}
|
|
7345
|
+
}
|
|
7346
|
+
getText() {
|
|
7347
|
+
const raw = this.lines.map((line) => line.join("").replace(/\s+$/, ""));
|
|
7348
|
+
let start = 0;
|
|
7349
|
+
let end = raw.length;
|
|
7350
|
+
while (start < end && raw[start] === "") start++;
|
|
7351
|
+
while (end > start && raw[end - 1] === "") end--;
|
|
7352
|
+
return raw.slice(start, end).join("\n");
|
|
7353
|
+
}
|
|
7354
|
+
consumeEscape(data, start) {
|
|
7355
|
+
const next = data[start + 1];
|
|
7356
|
+
if (!next) return start + 1;
|
|
7357
|
+
if (next === "[") {
|
|
7358
|
+
let end = start + 2;
|
|
7359
|
+
while (end < data.length && !/[@-~]/.test(data[end])) end++;
|
|
7360
|
+
if (end >= data.length) return data.length;
|
|
7361
|
+
this.applyCsi(data.slice(start + 2, end), data[end]);
|
|
7362
|
+
return end + 1;
|
|
7363
|
+
}
|
|
7364
|
+
if (next === "]") {
|
|
7365
|
+
let end = start + 2;
|
|
7366
|
+
while (end < data.length) {
|
|
7367
|
+
if (data[end] === "\x07") return end + 1;
|
|
7368
|
+
if (data[end] === "\x1B" && data[end + 1] === "\\") return end + 2;
|
|
7369
|
+
end++;
|
|
7370
|
+
}
|
|
7371
|
+
return data.length;
|
|
7372
|
+
}
|
|
7373
|
+
if (next === "7") {
|
|
7374
|
+
this.savedRow = this.cursorRow;
|
|
7375
|
+
this.savedCol = this.cursorCol;
|
|
7376
|
+
return start + 2;
|
|
7377
|
+
}
|
|
7378
|
+
if (next === "8") {
|
|
7379
|
+
this.cursorRow = this.savedRow;
|
|
7380
|
+
this.cursorCol = this.savedCol;
|
|
7381
|
+
return start + 2;
|
|
7382
|
+
}
|
|
7383
|
+
return start + 2;
|
|
7384
|
+
}
|
|
7385
|
+
applyCsi(paramText, finalChar) {
|
|
7386
|
+
const privateMode = paramText.startsWith("?");
|
|
7387
|
+
const normalized = privateMode ? paramText.slice(1) : paramText;
|
|
7388
|
+
const params = normalized.length > 0 ? normalized.split(";").map((p) => parseInt(p || "0", 10) || 0) : [0];
|
|
7389
|
+
switch (finalChar) {
|
|
7390
|
+
case "A":
|
|
7391
|
+
this.cursorRow = clamp(this.cursorRow - (params[0] || 1), 0, this.rows - 1);
|
|
7392
|
+
return;
|
|
7393
|
+
case "B":
|
|
7394
|
+
this.cursorRow = clamp(this.cursorRow + (params[0] || 1), 0, this.rows - 1);
|
|
7395
|
+
return;
|
|
7396
|
+
case "C":
|
|
7397
|
+
this.cursorCol = clamp(this.cursorCol + (params[0] || 1), 0, this.cols - 1);
|
|
7398
|
+
return;
|
|
7399
|
+
case "D":
|
|
7400
|
+
this.cursorCol = clamp(this.cursorCol - (params[0] || 1), 0, this.cols - 1);
|
|
7401
|
+
return;
|
|
7402
|
+
case "E":
|
|
7403
|
+
this.cursorRow = clamp(this.cursorRow + (params[0] || 1), 0, this.rows - 1);
|
|
7404
|
+
this.cursorCol = 0;
|
|
7405
|
+
return;
|
|
7406
|
+
case "F":
|
|
7407
|
+
this.cursorRow = clamp(this.cursorRow - (params[0] || 1), 0, this.rows - 1);
|
|
7408
|
+
this.cursorCol = 0;
|
|
7409
|
+
return;
|
|
7410
|
+
case "G":
|
|
7411
|
+
this.cursorCol = clamp((params[0] || 1) - 1, 0, this.cols - 1);
|
|
7412
|
+
return;
|
|
7413
|
+
case "H":
|
|
7414
|
+
case "f": {
|
|
7415
|
+
const row = (params[0] || 1) - 1;
|
|
7416
|
+
const col = (params[1] || 1) - 1;
|
|
7417
|
+
this.cursorRow = clamp(row, 0, this.rows - 1);
|
|
7418
|
+
this.cursorCol = clamp(col, 0, this.cols - 1);
|
|
7419
|
+
return;
|
|
7420
|
+
}
|
|
7421
|
+
case "J": {
|
|
7422
|
+
const mode = params[0] || 0;
|
|
7423
|
+
if (mode === 2 || mode === 3) {
|
|
7424
|
+
this.reset(this.rows, this.cols);
|
|
7425
|
+
} else if (mode === 0) {
|
|
7426
|
+
this.clearToEndOfScreen();
|
|
7427
|
+
} else if (mode === 1) {
|
|
7428
|
+
this.clearToStartOfScreen();
|
|
7429
|
+
}
|
|
7430
|
+
return;
|
|
7431
|
+
}
|
|
7432
|
+
case "K": {
|
|
7433
|
+
const mode = params[0] || 0;
|
|
7434
|
+
if (mode === 2) this.clearLine(this.cursorRow, 0, this.cols - 1);
|
|
7435
|
+
else if (mode === 1) this.clearLine(this.cursorRow, 0, this.cursorCol);
|
|
7436
|
+
else this.clearLine(this.cursorRow, this.cursorCol, this.cols - 1);
|
|
7437
|
+
return;
|
|
7438
|
+
}
|
|
7439
|
+
case "m":
|
|
7440
|
+
return;
|
|
7441
|
+
case "s":
|
|
7442
|
+
this.savedRow = this.cursorRow;
|
|
7443
|
+
this.savedCol = this.cursorCol;
|
|
7444
|
+
return;
|
|
7445
|
+
case "u":
|
|
7446
|
+
this.cursorRow = this.savedRow;
|
|
7447
|
+
this.cursorCol = this.savedCol;
|
|
7448
|
+
return;
|
|
7449
|
+
case "h":
|
|
7450
|
+
case "l":
|
|
7451
|
+
if (privateMode && (normalized === "1049" || normalized === "47")) {
|
|
7452
|
+
this.reset(this.rows, this.cols);
|
|
7453
|
+
}
|
|
7454
|
+
return;
|
|
7455
|
+
default:
|
|
7456
|
+
return;
|
|
7457
|
+
}
|
|
7458
|
+
}
|
|
7459
|
+
putChar(ch) {
|
|
7460
|
+
if (this.cursorRow < 0 || this.cursorRow >= this.rows) return;
|
|
7461
|
+
if (this.cursorCol < 0) this.cursorCol = 0;
|
|
7462
|
+
if (this.cursorCol >= this.cols) this.newLine();
|
|
7463
|
+
this.lines[this.cursorRow][this.cursorCol] = ch;
|
|
7464
|
+
this.cursorCol++;
|
|
7465
|
+
if (this.cursorCol >= this.cols) this.newLine();
|
|
7466
|
+
}
|
|
7467
|
+
newLine() {
|
|
7468
|
+
this.cursorCol = 0;
|
|
7469
|
+
if (this.cursorRow >= this.rows - 1) {
|
|
7470
|
+
this.lines.shift();
|
|
7471
|
+
this.lines.push(Array.from({ length: this.cols }, () => " "));
|
|
7472
|
+
} else {
|
|
7473
|
+
this.cursorRow++;
|
|
7474
|
+
}
|
|
7475
|
+
}
|
|
7476
|
+
clearLine(row, start, end) {
|
|
7477
|
+
if (row < 0 || row >= this.rows) return;
|
|
7478
|
+
for (let c = clamp(start, 0, this.cols - 1); c <= clamp(end, 0, this.cols - 1); c++) {
|
|
7479
|
+
this.lines[row][c] = " ";
|
|
7480
|
+
}
|
|
7481
|
+
}
|
|
7482
|
+
clearToEndOfScreen() {
|
|
7483
|
+
this.clearLine(this.cursorRow, this.cursorCol, this.cols - 1);
|
|
7484
|
+
for (let r = this.cursorRow + 1; r < this.rows; r++) {
|
|
7485
|
+
this.clearLine(r, 0, this.cols - 1);
|
|
7486
|
+
}
|
|
7487
|
+
}
|
|
7488
|
+
clearToStartOfScreen() {
|
|
7489
|
+
for (let r = 0; r < this.cursorRow; r++) {
|
|
7490
|
+
this.clearLine(r, 0, this.cols - 1);
|
|
7491
|
+
}
|
|
7492
|
+
this.clearLine(this.cursorRow, 0, this.cursorCol);
|
|
7493
|
+
}
|
|
7494
|
+
makeLines(rows, cols) {
|
|
7495
|
+
return Array.from({ length: rows }, () => Array.from({ length: cols }, () => " "));
|
|
7496
|
+
}
|
|
7497
|
+
};
|
|
7498
|
+
}
|
|
7499
|
+
});
|
|
7500
|
+
|
|
7239
7501
|
// ../daemon-core/src/cli-adapters/provider-cli-adapter.ts
|
|
7240
7502
|
var provider_cli_adapter_exports = {};
|
|
7241
7503
|
__export(provider_cli_adapter_exports, {
|
|
@@ -7308,28 +7570,19 @@ function parsePatternEntry(x) {
|
|
|
7308
7570
|
}
|
|
7309
7571
|
return null;
|
|
7310
7572
|
}
|
|
7311
|
-
function coercePatternArray(raw
|
|
7312
|
-
if (!Array.isArray(raw)) return [
|
|
7313
|
-
|
|
7314
|
-
return parsed.length > 0 ? parsed : [...fallbacks];
|
|
7315
|
-
}
|
|
7316
|
-
function defaultCleanOutput(raw, _lastUserInput) {
|
|
7317
|
-
return stripAnsi(raw).trim();
|
|
7573
|
+
function coercePatternArray(raw) {
|
|
7574
|
+
if (!Array.isArray(raw)) return [];
|
|
7575
|
+
return raw.map(parsePatternEntry).filter((r) => r != null);
|
|
7318
7576
|
}
|
|
7319
7577
|
function normalizeCliProviderForRuntime(raw) {
|
|
7320
7578
|
const patterns = raw?.patterns || {};
|
|
7321
7579
|
return {
|
|
7322
|
-
...raw,
|
|
7323
7580
|
patterns: {
|
|
7324
|
-
|
|
7325
|
-
|
|
7326
|
-
approval: coercePatternArray(patterns.approval, FALLBACK_APPROVAL),
|
|
7327
|
-
ready: coercePatternArray(patterns.ready, [])
|
|
7328
|
-
},
|
|
7329
|
-
cleanOutput: typeof raw?.cleanOutput === "function" ? raw.cleanOutput : defaultCleanOutput
|
|
7581
|
+
approval: coercePatternArray(patterns.approval)
|
|
7582
|
+
}
|
|
7330
7583
|
};
|
|
7331
7584
|
}
|
|
7332
|
-
var os11, path9, import_child_process5, pty,
|
|
7585
|
+
var os11, path9, import_child_process5, pty, ProviderCliAdapter;
|
|
7333
7586
|
var init_provider_cli_adapter = __esm({
|
|
7334
7587
|
"../daemon-core/src/cli-adapters/provider-cli-adapter.ts"() {
|
|
7335
7588
|
"use strict";
|
|
@@ -7337,6 +7590,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
7337
7590
|
path9 = __toESM(require("path"));
|
|
7338
7591
|
import_child_process5 = require("child_process");
|
|
7339
7592
|
init_logger();
|
|
7593
|
+
init_terminal_screen();
|
|
7340
7594
|
try {
|
|
7341
7595
|
pty = require("node-pty");
|
|
7342
7596
|
if (os11.platform() !== "win32") {
|
|
@@ -7358,40 +7612,10 @@ var init_provider_cli_adapter = __esm({
|
|
|
7358
7612
|
} catch {
|
|
7359
7613
|
LOG.error("CLI", "[ProviderCliAdapter] node-pty not found. Terminal features disabled.");
|
|
7360
7614
|
}
|
|
7361
|
-
|
|
7362
|
-
/Type your message/i,
|
|
7363
|
-
/for\s*shortcuts/i,
|
|
7364
|
-
// Claude Code prompt
|
|
7365
|
-
/\?\s*for\s*help/i,
|
|
7366
|
-
// Claude Code help prompt
|
|
7367
|
-
/Press enter/i,
|
|
7368
|
-
/^[>›❯]\s*$/i,
|
|
7369
|
-
// Prompt char as the complete evaluated string
|
|
7370
|
-
/[>›❯]\s*$/
|
|
7371
|
-
// Prompt char at the very end of evaluated string
|
|
7372
|
-
];
|
|
7373
|
-
FALLBACK_GENERATING = [
|
|
7374
|
-
/[\u2800-\u28ff]/,
|
|
7375
|
-
// Braille spinner blocks (universal TUI)
|
|
7376
|
-
/esc to (cancel|interrupt|stop)/i,
|
|
7377
|
-
// Common TUI generation status line
|
|
7378
|
-
/generating\.\.\./i,
|
|
7379
|
-
/Claude is (?:thinking|processing|working)/i
|
|
7380
|
-
// Specific Claude Code status
|
|
7381
|
-
];
|
|
7382
|
-
FALLBACK_APPROVAL = [
|
|
7383
|
-
/Allow\s*once/i,
|
|
7384
|
-
// ANSI strip may remove spaces
|
|
7385
|
-
/Always\s*allow/i,
|
|
7386
|
-
/\(y\/n\)/i,
|
|
7387
|
-
/\[Y\/n\]/i,
|
|
7388
|
-
/Yes,?\s*don'?t\s*ask/i
|
|
7389
|
-
// "Yes, don't ask again" (Claude Code)
|
|
7390
|
-
];
|
|
7391
|
-
ProviderCliAdapter = class {
|
|
7615
|
+
ProviderCliAdapter = class _ProviderCliAdapter {
|
|
7392
7616
|
constructor(provider, workingDir, extraArgs = []) {
|
|
7393
7617
|
this.extraArgs = extraArgs;
|
|
7394
|
-
this.provider =
|
|
7618
|
+
this.provider = provider;
|
|
7395
7619
|
this.cliType = provider.type;
|
|
7396
7620
|
this.cliName = provider.name;
|
|
7397
7621
|
this.workingDir = workingDir.startsWith("~") ? workingDir.replace(/^~/, os11.homedir()) : workingDir;
|
|
@@ -7408,6 +7632,13 @@ var init_provider_cli_adapter = __esm({
|
|
|
7408
7632
|
};
|
|
7409
7633
|
const rawKeys = provider.approvalKeys;
|
|
7410
7634
|
this.approvalKeys = rawKeys && typeof rawKeys === "object" ? rawKeys : {};
|
|
7635
|
+
this.cliScripts = provider.scripts || {};
|
|
7636
|
+
const scriptNames = Object.keys(this.cliScripts).filter((k) => typeof this.cliScripts[k] === "function");
|
|
7637
|
+
if (scriptNames.length > 0) {
|
|
7638
|
+
LOG.info("CLI", `[${this.cliType}] CLI scripts: [${scriptNames.join(", ")}]`);
|
|
7639
|
+
} else {
|
|
7640
|
+
LOG.warn("CLI", `[${this.cliType}] \u26A0 No CLI scripts loaded! Provider needs scripts/{version}/scripts.js`);
|
|
7641
|
+
}
|
|
7411
7642
|
}
|
|
7412
7643
|
cliType;
|
|
7413
7644
|
cliName;
|
|
@@ -7415,6 +7646,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
7415
7646
|
provider;
|
|
7416
7647
|
ptyProcess = null;
|
|
7417
7648
|
messages = [];
|
|
7649
|
+
structuredMessages = [];
|
|
7418
7650
|
currentStatus = "starting";
|
|
7419
7651
|
onStatusChange = null;
|
|
7420
7652
|
responseBuffer = "";
|
|
@@ -7425,7 +7657,6 @@ var init_provider_cli_adapter = __esm({
|
|
|
7425
7657
|
idleTimeout = null;
|
|
7426
7658
|
ready = false;
|
|
7427
7659
|
startupBuffer = "";
|
|
7428
|
-
/** After spawn: briefly skip generating/settle so splash/redraw does not flip status; not used to gate sendMessage */
|
|
7429
7660
|
startupParseGate = false;
|
|
7430
7661
|
spawnAt = 0;
|
|
7431
7662
|
// PTY I/O
|
|
@@ -7443,11 +7674,20 @@ var init_provider_cli_adapter = __esm({
|
|
|
7443
7674
|
// Output settle debounce — fires after PTY output goes quiet
|
|
7444
7675
|
settleTimer = null;
|
|
7445
7676
|
settledBuffer = "";
|
|
7446
|
-
// snapshot of recentOutputBuffer at settle time
|
|
7447
7677
|
// Resize redraw suppression
|
|
7448
7678
|
resizeSuppressUntil = 0;
|
|
7449
7679
|
// Debug: status transition history
|
|
7450
7680
|
statusHistory = [];
|
|
7681
|
+
// ─── CLI Scripts (script-based parsing) ───
|
|
7682
|
+
cliScripts;
|
|
7683
|
+
/** Full accumulated ANSI-stripped PTY output */
|
|
7684
|
+
accumulatedBuffer = "";
|
|
7685
|
+
/** Full accumulated raw PTY output (with ANSI) */
|
|
7686
|
+
accumulatedRawBuffer = "";
|
|
7687
|
+
/** Current visible terminal screen snapshot */
|
|
7688
|
+
terminalScreen = new TerminalScreen(40, 120);
|
|
7689
|
+
/** Max accumulated buffer size (last 50KB) */
|
|
7690
|
+
static MAX_ACCUMULATED_BUFFER = 5e4;
|
|
7451
7691
|
setStatus(status, trigger) {
|
|
7452
7692
|
const prev = this.currentStatus;
|
|
7453
7693
|
if (prev === status) return;
|
|
@@ -7456,10 +7696,16 @@ var init_provider_cli_adapter = __esm({
|
|
|
7456
7696
|
if (this.statusHistory.length > 50) this.statusHistory.shift();
|
|
7457
7697
|
LOG.info("CLI", `[${this.cliType}] status: ${prev} \u2192 ${status}${trigger ? ` (${trigger})` : ""}`);
|
|
7458
7698
|
}
|
|
7459
|
-
// Resolved timeouts
|
|
7699
|
+
// Resolved timeouts
|
|
7460
7700
|
timeouts;
|
|
7461
|
-
// Provider approval key mapping
|
|
7701
|
+
// Provider approval key mapping
|
|
7462
7702
|
approvalKeys;
|
|
7703
|
+
/** Inject CLI scripts after construction (e.g. when resolved by ProviderLoader) */
|
|
7704
|
+
setCliScripts(scripts) {
|
|
7705
|
+
this.cliScripts = scripts;
|
|
7706
|
+
const scriptNames = Object.keys(scripts).filter((k) => typeof scripts[k] === "function");
|
|
7707
|
+
LOG.info("CLI", `[${this.cliType}] CLI scripts injected: [${scriptNames.join(", ")}]`);
|
|
7708
|
+
}
|
|
7463
7709
|
// ─── Lifecycle ─────────────────────────────────
|
|
7464
7710
|
setServerConn(serverConn) {
|
|
7465
7711
|
this.serverConn = serverConn;
|
|
@@ -7548,15 +7794,19 @@ var init_provider_cli_adapter = __esm({
|
|
|
7548
7794
|
this.spawnAt = Date.now();
|
|
7549
7795
|
this.startupParseGate = true;
|
|
7550
7796
|
this.startupBuffer = "";
|
|
7797
|
+
this.terminalScreen.reset(40, 120);
|
|
7551
7798
|
this.ready = true;
|
|
7552
7799
|
this.setStatus("idle", "pty_ready");
|
|
7553
7800
|
this.onStatusChange?.();
|
|
7554
7801
|
}
|
|
7555
|
-
// ─── Output
|
|
7802
|
+
// ─── Output Handling ────────────────────────────
|
|
7556
7803
|
handleOutput(rawData) {
|
|
7557
7804
|
if (Date.now() < this.resizeSuppressUntil) return;
|
|
7805
|
+
this.terminalScreen.write(rawData);
|
|
7558
7806
|
const cleanData = stripAnsi(rawData);
|
|
7559
|
-
|
|
7807
|
+
if (this.isWaitingForResponse && cleanData) {
|
|
7808
|
+
this.responseBuffer = (this.responseBuffer + cleanData).slice(-8e3);
|
|
7809
|
+
}
|
|
7560
7810
|
if (cleanData.trim()) {
|
|
7561
7811
|
if (this.serverConn) {
|
|
7562
7812
|
this.serverConn.sendMessage("log", { message: cleanData.trim(), level: "info" });
|
|
@@ -7565,9 +7815,10 @@ var init_provider_cli_adapter = __esm({
|
|
|
7565
7815
|
}
|
|
7566
7816
|
}
|
|
7567
7817
|
this.recentOutputBuffer = (this.recentOutputBuffer + cleanData).slice(-1e3);
|
|
7818
|
+
this.accumulatedBuffer = (this.accumulatedBuffer + cleanData).slice(-_ProviderCliAdapter.MAX_ACCUMULATED_BUFFER);
|
|
7819
|
+
this.accumulatedRawBuffer = (this.accumulatedRawBuffer + rawData).slice(-_ProviderCliAdapter.MAX_ACCUMULATED_BUFFER);
|
|
7568
7820
|
if (this.startupParseGate) {
|
|
7569
7821
|
this.startupBuffer += cleanData;
|
|
7570
|
-
LOG.info("CLI", `[${this.cliType}] startup chunk (${cleanData.length} chars): ${cleanData.slice(0, 200).replace(/\n/g, "\\n")}`);
|
|
7571
7822
|
const dialogPatterns = [
|
|
7572
7823
|
/Do you want to connect/i,
|
|
7573
7824
|
/Do you trust the files/i,
|
|
@@ -7582,60 +7833,17 @@ var init_provider_cli_adapter = __esm({
|
|
|
7582
7833
|
}
|
|
7583
7834
|
const elapsed = Date.now() - this.spawnAt;
|
|
7584
7835
|
const bufCap = this.startupBuffer.length > 12e3;
|
|
7585
|
-
const
|
|
7586
|
-
|
|
7836
|
+
const scriptStatus = this.runDetectStatus(this.startupBuffer);
|
|
7837
|
+
const isReady = scriptStatus === "idle" || elapsed > 8e3 || bufCap;
|
|
7838
|
+
if (isReady) {
|
|
7587
7839
|
this.startupParseGate = false;
|
|
7588
|
-
|
|
7589
|
-
LOG.info("CLI", `[${this.cliType}] \u2713 Startup gate end (prompt matched)`);
|
|
7590
|
-
} else {
|
|
7591
|
-
LOG.info("CLI", `[${this.cliType}] startup gate end (${elapsed}ms, cap=${bufCap}, prompt=${promptMatched})`);
|
|
7592
|
-
}
|
|
7840
|
+
LOG.info("CLI", `[${this.cliType}] Startup gate end (${elapsed}ms, scriptStatus=${scriptStatus})`);
|
|
7593
7841
|
} else {
|
|
7594
7842
|
return;
|
|
7595
7843
|
}
|
|
7596
7844
|
}
|
|
7597
|
-
if (cleanData.trim().length > 5) {
|
|
7598
|
-
LOG.debug("CLI", `[${this.cliType}] output chunk (${cleanData.length}): ${cleanData.slice(0, 300).replace(/\n/g, "\\n")}`);
|
|
7599
|
-
}
|
|
7600
|
-
if (!this.isWaitingForResponse) {
|
|
7601
|
-
if (patterns.generating.some((p) => p.test(cleanData))) {
|
|
7602
|
-
if (this.settleTimer) {
|
|
7603
|
-
clearTimeout(this.settleTimer);
|
|
7604
|
-
this.settleTimer = null;
|
|
7605
|
-
}
|
|
7606
|
-
this.isWaitingForResponse = true;
|
|
7607
|
-
this.responseBuffer = "";
|
|
7608
|
-
this.setStatus("generating", "autonomous_gen");
|
|
7609
|
-
this.onStatusChange?.();
|
|
7610
|
-
}
|
|
7611
|
-
}
|
|
7612
|
-
if (this.isWaitingForResponse) {
|
|
7613
|
-
this.responseBuffer += cleanData;
|
|
7614
|
-
if (this.idleTimeout) clearTimeout(this.idleTimeout);
|
|
7615
|
-
if (patterns.generating.some((p) => p.test(cleanData))) {
|
|
7616
|
-
this.setStatus("generating", "still_generating");
|
|
7617
|
-
this.idleTimeout = setTimeout(() => {
|
|
7618
|
-
if (this.isWaitingForResponse) this.finishResponse();
|
|
7619
|
-
}, this.timeouts.generatingIdle);
|
|
7620
|
-
this.onStatusChange?.();
|
|
7621
|
-
if (this.settleTimer) {
|
|
7622
|
-
clearTimeout(this.settleTimer);
|
|
7623
|
-
this.settleTimer = null;
|
|
7624
|
-
}
|
|
7625
|
-
return;
|
|
7626
|
-
}
|
|
7627
|
-
}
|
|
7628
|
-
if (this.currentStatus === "waiting_approval") {
|
|
7629
|
-
this.approvalTransitionBuffer = (this.approvalTransitionBuffer + cleanData).slice(-500);
|
|
7630
|
-
this.scheduleSettle();
|
|
7631
|
-
return;
|
|
7632
|
-
}
|
|
7633
7845
|
this.scheduleSettle();
|
|
7634
7846
|
}
|
|
7635
|
-
/**
|
|
7636
|
-
* Fired after output goes quiet for outputSettle ms.
|
|
7637
|
-
* Evaluates the stabilised buffer for approval, prompt (idle), or timeout.
|
|
7638
|
-
*/
|
|
7639
7847
|
scheduleSettle() {
|
|
7640
7848
|
if (this.settleTimer) clearTimeout(this.settleTimer);
|
|
7641
7849
|
this.settleTimer = setTimeout(() => {
|
|
@@ -7645,59 +7853,25 @@ var init_provider_cli_adapter = __esm({
|
|
|
7645
7853
|
}, this.timeouts.outputSettle);
|
|
7646
7854
|
}
|
|
7647
7855
|
evaluateSettled() {
|
|
7648
|
-
const
|
|
7649
|
-
const
|
|
7650
|
-
if (
|
|
7651
|
-
|
|
7652
|
-
|
|
7653
|
-
if (genResume) {
|
|
7654
|
-
if (this.approvalExitTimeout) {
|
|
7655
|
-
clearTimeout(this.approvalExitTimeout);
|
|
7656
|
-
this.approvalExitTimeout = null;
|
|
7657
|
-
}
|
|
7658
|
-
this.setStatus("generating", "approval_gen_resume");
|
|
7659
|
-
this.activeModal = null;
|
|
7660
|
-
this.recentOutputBuffer = "";
|
|
7661
|
-
this.approvalTransitionBuffer = "";
|
|
7662
|
-
this.lastApprovalResolvedAt = Date.now();
|
|
7663
|
-
this.onStatusChange?.();
|
|
7664
|
-
} else if (promptResume) {
|
|
7665
|
-
if (this.approvalExitTimeout) {
|
|
7666
|
-
clearTimeout(this.approvalExitTimeout);
|
|
7667
|
-
this.approvalExitTimeout = null;
|
|
7668
|
-
}
|
|
7669
|
-
this.activeModal = null;
|
|
7670
|
-
this.recentOutputBuffer = "";
|
|
7671
|
-
this.approvalTransitionBuffer = "";
|
|
7672
|
-
this.lastApprovalResolvedAt = Date.now();
|
|
7673
|
-
this.finishResponse();
|
|
7674
|
-
}
|
|
7675
|
-
return;
|
|
7676
|
-
}
|
|
7677
|
-
const hasApproval = patterns.approval.some((p) => p.test(buf));
|
|
7678
|
-
if (hasApproval) {
|
|
7856
|
+
const tail = this.settledBuffer;
|
|
7857
|
+
const scriptStatus = this.runDetectStatus(tail);
|
|
7858
|
+
if (!scriptStatus) return;
|
|
7859
|
+
const prevStatus = this.currentStatus;
|
|
7860
|
+
if (scriptStatus === "waiting_approval") {
|
|
7679
7861
|
const inCooldown = this.lastApprovalResolvedAt && Date.now() - this.lastApprovalResolvedAt < this.timeouts.approvalCooldown;
|
|
7680
7862
|
if (!inCooldown) {
|
|
7681
|
-
const ctxLines = buf.split("\n").map((l) => l.trim()).filter((l) => l && !/^[─═╭╮╰╯│]+$/.test(l));
|
|
7682
7863
|
this.isWaitingForResponse = true;
|
|
7683
|
-
this.setStatus("waiting_approval", "
|
|
7684
|
-
|
|
7685
|
-
this.
|
|
7686
|
-
this.activeModal = {
|
|
7687
|
-
message: ctxLines.slice(-5).join(" ").slice(0, 200) || "Approval required",
|
|
7688
|
-
buttons: this.cliType === "claude-cli" ? ["Yes (y)", "Always allow (a)", "Deny (Esc)"] : ["Allow once", "Always allow", "Deny"]
|
|
7689
|
-
};
|
|
7864
|
+
this.setStatus("waiting_approval", "script_detect");
|
|
7865
|
+
const modal = this.runParseApproval(tail);
|
|
7866
|
+
this.activeModal = modal || { message: "Approval required", buttons: ["Allow", "Deny"] };
|
|
7690
7867
|
if (this.idleTimeout) clearTimeout(this.idleTimeout);
|
|
7691
7868
|
if (this.approvalExitTimeout) clearTimeout(this.approvalExitTimeout);
|
|
7692
7869
|
this.approvalExitTimeout = setTimeout(() => {
|
|
7693
7870
|
if (this.currentStatus === "waiting_approval") {
|
|
7694
|
-
LOG.warn("CLI", `[${this.cliType}] Approval timeout \u2014 auto-
|
|
7871
|
+
LOG.warn("CLI", `[${this.cliType}] Approval timeout \u2014 auto-clearing`);
|
|
7695
7872
|
this.activeModal = null;
|
|
7696
7873
|
this.lastApprovalResolvedAt = Date.now();
|
|
7697
|
-
this.
|
|
7698
|
-
this.approvalTransitionBuffer = "";
|
|
7699
|
-
this.approvalExitTimeout = null;
|
|
7700
|
-
this.setStatus(this.isWaitingForResponse ? "generating" : "idle", "approval_cleared");
|
|
7874
|
+
this.setStatus("idle", "approval_timeout");
|
|
7701
7875
|
this.onStatusChange?.();
|
|
7702
7876
|
}
|
|
7703
7877
|
}, 6e4);
|
|
@@ -7705,19 +7879,42 @@ var init_provider_cli_adapter = __esm({
|
|
|
7705
7879
|
return;
|
|
7706
7880
|
}
|
|
7707
7881
|
}
|
|
7708
|
-
if (
|
|
7709
|
-
|
|
7710
|
-
|
|
7711
|
-
|
|
7712
|
-
|
|
7713
|
-
|
|
7714
|
-
this.
|
|
7715
|
-
|
|
7716
|
-
|
|
7717
|
-
|
|
7718
|
-
|
|
7882
|
+
if (scriptStatus === "generating") {
|
|
7883
|
+
if (prevStatus === "waiting_approval") {
|
|
7884
|
+
if (this.approvalExitTimeout) {
|
|
7885
|
+
clearTimeout(this.approvalExitTimeout);
|
|
7886
|
+
this.approvalExitTimeout = null;
|
|
7887
|
+
}
|
|
7888
|
+
this.activeModal = null;
|
|
7889
|
+
this.lastApprovalResolvedAt = Date.now();
|
|
7890
|
+
}
|
|
7891
|
+
if (!this.isWaitingForResponse) {
|
|
7892
|
+
this.isWaitingForResponse = true;
|
|
7893
|
+
this.responseBuffer = "";
|
|
7719
7894
|
}
|
|
7895
|
+
this.setStatus("generating", "script_detect");
|
|
7896
|
+
if (this.idleTimeout) clearTimeout(this.idleTimeout);
|
|
7897
|
+
this.idleTimeout = setTimeout(() => {
|
|
7898
|
+
if (this.isWaitingForResponse) this.finishResponse();
|
|
7899
|
+
}, this.timeouts.generatingIdle);
|
|
7720
7900
|
this.onStatusChange?.();
|
|
7901
|
+
return;
|
|
7902
|
+
}
|
|
7903
|
+
if (scriptStatus === "idle") {
|
|
7904
|
+
if (prevStatus === "waiting_approval") {
|
|
7905
|
+
if (this.approvalExitTimeout) {
|
|
7906
|
+
clearTimeout(this.approvalExitTimeout);
|
|
7907
|
+
this.approvalExitTimeout = null;
|
|
7908
|
+
}
|
|
7909
|
+
this.activeModal = null;
|
|
7910
|
+
this.lastApprovalResolvedAt = Date.now();
|
|
7911
|
+
}
|
|
7912
|
+
if (this.isWaitingForResponse) {
|
|
7913
|
+
this.finishResponse();
|
|
7914
|
+
} else if (prevStatus !== "idle") {
|
|
7915
|
+
this.setStatus("idle", "script_detect");
|
|
7916
|
+
this.onStatusChange?.();
|
|
7917
|
+
}
|
|
7721
7918
|
}
|
|
7722
7919
|
}
|
|
7723
7920
|
finishResponse() {
|
|
@@ -7733,25 +7930,50 @@ var init_provider_cli_adapter = __esm({
|
|
|
7733
7930
|
clearTimeout(this.approvalExitTimeout);
|
|
7734
7931
|
this.approvalExitTimeout = null;
|
|
7735
7932
|
}
|
|
7736
|
-
const lastUserText = this.messages.filter((m) => m.role === "user").pop()?.content;
|
|
7737
|
-
let response = this.provider.cleanOutput(this.responseBuffer, lastUserText);
|
|
7738
|
-
if (lastUserText && response) {
|
|
7739
|
-
const userTrimmed = lastUserText.trim();
|
|
7740
|
-
response = response.split("\n").filter((l) => l.trim() !== userTrimmed).join("\n").trim();
|
|
7741
|
-
}
|
|
7742
|
-
if (response) {
|
|
7743
|
-
this.messages.push({ role: "assistant", content: response, timestamp: Date.now() });
|
|
7744
|
-
if (this.messages.length > 200) this.messages = this.messages.slice(-200);
|
|
7745
|
-
LOG.info("CLI", `[${this.cliType}] Response (${response.length} chars)`);
|
|
7746
|
-
}
|
|
7747
7933
|
this.responseBuffer = "";
|
|
7748
7934
|
this.isWaitingForResponse = false;
|
|
7749
7935
|
this.activeModal = null;
|
|
7750
7936
|
this.setStatus("idle", "response_finished");
|
|
7751
7937
|
this.onStatusChange?.();
|
|
7752
7938
|
}
|
|
7753
|
-
// ───
|
|
7939
|
+
// ─── Script Execution ──────────────────────────
|
|
7940
|
+
runDetectStatus(text) {
|
|
7941
|
+
if (!this.cliScripts?.detectStatus) return null;
|
|
7942
|
+
try {
|
|
7943
|
+
return this.cliScripts.detectStatus({ tail: text.slice(-500) });
|
|
7944
|
+
} catch (e) {
|
|
7945
|
+
LOG.warn("CLI", `[${this.cliType}] detectStatus error: ${e.message}`);
|
|
7946
|
+
return null;
|
|
7947
|
+
}
|
|
7948
|
+
}
|
|
7949
|
+
runParseApproval(tail) {
|
|
7950
|
+
if (!this.cliScripts?.parseApproval) return null;
|
|
7951
|
+
try {
|
|
7952
|
+
return this.cliScripts.parseApproval({
|
|
7953
|
+
buffer: this.terminalScreen.getText() || this.accumulatedBuffer,
|
|
7954
|
+
rawBuffer: this.accumulatedRawBuffer,
|
|
7955
|
+
tail
|
|
7956
|
+
});
|
|
7957
|
+
} catch (e) {
|
|
7958
|
+
LOG.warn("CLI", `[${this.cliType}] parseApproval error: ${e.message}`);
|
|
7959
|
+
return null;
|
|
7960
|
+
}
|
|
7961
|
+
}
|
|
7962
|
+
// ─── Public API (CliAdapter) ───────────────────
|
|
7754
7963
|
getStatus() {
|
|
7964
|
+
const scriptResult = this.getScriptParsedStatus();
|
|
7965
|
+
if (scriptResult) {
|
|
7966
|
+
return {
|
|
7967
|
+
status: this.currentStatus,
|
|
7968
|
+
messages: (scriptResult.messages || []).map((m) => ({
|
|
7969
|
+
role: m.role,
|
|
7970
|
+
content: m.content,
|
|
7971
|
+
timestamp: m.timestamp
|
|
7972
|
+
})),
|
|
7973
|
+
workingDir: this.workingDir,
|
|
7974
|
+
activeModal: this.activeModal
|
|
7975
|
+
};
|
|
7976
|
+
}
|
|
7755
7977
|
return {
|
|
7756
7978
|
status: this.currentStatus,
|
|
7757
7979
|
messages: [...this.messages],
|
|
@@ -7759,11 +7981,71 @@ var init_provider_cli_adapter = __esm({
|
|
|
7759
7981
|
activeModal: this.activeModal
|
|
7760
7982
|
};
|
|
7761
7983
|
}
|
|
7984
|
+
/**
|
|
7985
|
+
* Script-based full parse — returns ReadChatResult.
|
|
7986
|
+
* Called by command handler / dashboard for rich content rendering.
|
|
7987
|
+
*/
|
|
7988
|
+
getScriptParsedStatus() {
|
|
7989
|
+
if (!this.cliScripts?.parseOutput) return null;
|
|
7990
|
+
try {
|
|
7991
|
+
const input = {
|
|
7992
|
+
buffer: this.accumulatedBuffer,
|
|
7993
|
+
rawBuffer: this.accumulatedRawBuffer,
|
|
7994
|
+
recentBuffer: this.recentOutputBuffer,
|
|
7995
|
+
screenText: this.terminalScreen.getText(),
|
|
7996
|
+
messages: [...this.structuredMessages.length > 0 ? this.structuredMessages : this.messages],
|
|
7997
|
+
partialResponse: this.responseBuffer
|
|
7998
|
+
};
|
|
7999
|
+
const result = this.cliScripts.parseOutput(input);
|
|
8000
|
+
if (result && typeof result === "object") {
|
|
8001
|
+
if (Array.isArray(result.messages)) {
|
|
8002
|
+
this.structuredMessages = result.messages.map((m) => ({
|
|
8003
|
+
role: m.role,
|
|
8004
|
+
content: m.content,
|
|
8005
|
+
timestamp: m.timestamp
|
|
8006
|
+
}));
|
|
8007
|
+
}
|
|
8008
|
+
return result;
|
|
8009
|
+
}
|
|
8010
|
+
} catch (e) {
|
|
8011
|
+
LOG.warn("CLI", `[${this.cliType}] parseOutput error: ${e.message}`);
|
|
8012
|
+
}
|
|
8013
|
+
return null;
|
|
8014
|
+
}
|
|
8015
|
+
/** Whether this adapter has CLI scripts loaded */
|
|
8016
|
+
hasCliScripts() {
|
|
8017
|
+
return typeof this.cliScripts?.detectStatus === "function";
|
|
8018
|
+
}
|
|
8019
|
+
/**
|
|
8020
|
+
* Resolves an action (like 'fix' lint error) from the dashboard.
|
|
8021
|
+
* Uses resolveAction script if available, otherwise falls back to standard text.
|
|
8022
|
+
*/
|
|
8023
|
+
async resolveAction(data) {
|
|
8024
|
+
let promptText = "";
|
|
8025
|
+
if (this.cliScripts && typeof this.cliScripts.resolveAction === "function") {
|
|
8026
|
+
try {
|
|
8027
|
+
promptText = this.cliScripts.resolveAction(data);
|
|
8028
|
+
} catch (e) {
|
|
8029
|
+
LOG.warn("CLI", `[${this.cliType}] resolveAction error: ${e.message}`);
|
|
8030
|
+
}
|
|
8031
|
+
}
|
|
8032
|
+
if (!promptText && data) {
|
|
8033
|
+
promptText = `Please fix the following issue:
|
|
8034
|
+
${data.title || ""}
|
|
8035
|
+
${data.explanation || ""}
|
|
8036
|
+
|
|
8037
|
+
${data.message || ""}`.trim();
|
|
8038
|
+
}
|
|
8039
|
+
if (promptText) {
|
|
8040
|
+
await this.sendMessage(promptText);
|
|
8041
|
+
}
|
|
8042
|
+
}
|
|
7762
8043
|
async sendMessage(text) {
|
|
7763
8044
|
if (!this.ptyProcess) throw new Error(`${this.cliName} is not running`);
|
|
7764
8045
|
if (!this.ready) throw new Error(`${this.cliName} not ready (status: ${this.currentStatus})`);
|
|
7765
8046
|
if (this.isWaitingForResponse) return;
|
|
7766
8047
|
this.messages.push({ role: "user", content: text, timestamp: Date.now() });
|
|
8048
|
+
this.structuredMessages.push({ role: "user", content: text, timestamp: Date.now() });
|
|
7767
8049
|
this.isWaitingForResponse = true;
|
|
7768
8050
|
this.responseBuffer = "";
|
|
7769
8051
|
this.setStatus("generating", "sendMessage");
|
|
@@ -7775,8 +8057,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
7775
8057
|
}
|
|
7776
8058
|
getPartialResponse() {
|
|
7777
8059
|
if (!this.isWaitingForResponse) return "";
|
|
7778
|
-
|
|
7779
|
-
return partial2 || (this.isWaitingForResponse ? "(generating...)" : "");
|
|
8060
|
+
return this.responseBuffer;
|
|
7780
8061
|
}
|
|
7781
8062
|
cancel() {
|
|
7782
8063
|
this.shutdown();
|
|
@@ -7808,6 +8089,10 @@ var init_provider_cli_adapter = __esm({
|
|
|
7808
8089
|
}
|
|
7809
8090
|
clearHistory() {
|
|
7810
8091
|
this.messages = [];
|
|
8092
|
+
this.structuredMessages = [];
|
|
8093
|
+
this.accumulatedBuffer = "";
|
|
8094
|
+
this.accumulatedRawBuffer = "";
|
|
8095
|
+
this.terminalScreen.reset();
|
|
7811
8096
|
this.onStatusChange?.();
|
|
7812
8097
|
}
|
|
7813
8098
|
isProcessing() {
|
|
@@ -7819,11 +8104,6 @@ var init_provider_cli_adapter = __esm({
|
|
|
7819
8104
|
writeRaw(data) {
|
|
7820
8105
|
this.ptyProcess?.write(data);
|
|
7821
8106
|
}
|
|
7822
|
-
/**
|
|
7823
|
-
* Resolve an approval modal by navigating to the button at `buttonIndex` and pressing Enter.
|
|
7824
|
-
* Index 0 = first option (already selected by default — just Enter).
|
|
7825
|
-
* Index N = press Arrow Down N times, then Enter.
|
|
7826
|
-
*/
|
|
7827
8107
|
resolveModal(buttonIndex) {
|
|
7828
8108
|
if (!this.ptyProcess || this.currentStatus !== "waiting_approval") return;
|
|
7829
8109
|
if (buttonIndex in this.approvalKeys) {
|
|
@@ -7838,25 +8118,13 @@ var init_provider_cli_adapter = __esm({
|
|
|
7838
8118
|
if (this.ptyProcess) {
|
|
7839
8119
|
try {
|
|
7840
8120
|
this.ptyProcess.resize(cols, rows);
|
|
8121
|
+
this.terminalScreen.resize(rows, cols);
|
|
7841
8122
|
this.resizeSuppressUntil = Date.now() + 300;
|
|
7842
8123
|
} catch {
|
|
7843
8124
|
}
|
|
7844
8125
|
}
|
|
7845
8126
|
}
|
|
7846
|
-
/**
|
|
7847
|
-
* Full debug state — exposes all internal buffers, status, and patterns for debugging.
|
|
7848
|
-
* Used by DevServer /api/cli/debug endpoint.
|
|
7849
|
-
*/
|
|
7850
8127
|
getDebugState() {
|
|
7851
|
-
const sb = this.startupBuffer;
|
|
7852
|
-
const testOnStartup = (p) => {
|
|
7853
|
-
const flags = p.flags.includes("g") ? p.flags.replace(/g/g, "") : p.flags;
|
|
7854
|
-
return new RegExp(p.source, flags).test(sb);
|
|
7855
|
-
};
|
|
7856
|
-
const promptDiagnostics = this.provider.patterns.prompt.map((p) => ({
|
|
7857
|
-
pattern: p.toString(),
|
|
7858
|
-
matchedAgainstStartupBuffer: testOnStartup(p)
|
|
7859
|
-
}));
|
|
7860
8128
|
return {
|
|
7861
8129
|
type: this.cliType,
|
|
7862
8130
|
name: this.cliName,
|
|
@@ -7866,32 +8134,20 @@ var init_provider_cli_adapter = __esm({
|
|
|
7866
8134
|
spawnAt: this.spawnAt,
|
|
7867
8135
|
workingDir: this.workingDir,
|
|
7868
8136
|
messages: this.messages.slice(-20),
|
|
8137
|
+
structuredMessages: this.structuredMessages.slice(-20),
|
|
7869
8138
|
messageCount: this.messages.length,
|
|
7870
|
-
|
|
7871
|
-
startupBuffer: sb.slice(-4e3),
|
|
7872
|
-
startupBufferLength: sb.length,
|
|
7873
|
-
promptDiagnostics,
|
|
8139
|
+
startupBuffer: this.startupBuffer.slice(-4e3),
|
|
7874
8140
|
recentOutputBuffer: this.recentOutputBuffer.slice(-500),
|
|
7875
8141
|
settledBuffer: this.settledBuffer.slice(-500),
|
|
7876
|
-
|
|
7877
|
-
approvalTransitionBuffer: this.approvalTransitionBuffer.slice(-500),
|
|
7878
|
-
// State
|
|
8142
|
+
accumulatedBufferLength: this.accumulatedBuffer.length,
|
|
7879
8143
|
isWaitingForResponse: this.isWaitingForResponse,
|
|
7880
8144
|
activeModal: this.activeModal,
|
|
7881
8145
|
lastApprovalResolvedAt: this.lastApprovalResolvedAt,
|
|
7882
8146
|
resizeSuppressUntil: this.resizeSuppressUntil,
|
|
7883
|
-
|
|
7884
|
-
|
|
7885
|
-
prompt: this.provider.patterns.prompt.map((p) => p.toString()),
|
|
7886
|
-
generating: this.provider.patterns.generating.map((p) => p.toString()),
|
|
7887
|
-
approval: this.provider.patterns.approval.map((p) => p.toString()),
|
|
7888
|
-
ready: this.provider.patterns.ready.map((p) => p.toString())
|
|
7889
|
-
},
|
|
7890
|
-
// Status history
|
|
8147
|
+
hasCliScripts: this.hasCliScripts(),
|
|
8148
|
+
scriptNames: Object.keys(this.cliScripts).filter((k) => typeof this.cliScripts[k] === "function"),
|
|
7891
8149
|
statusHistory: this.statusHistory.slice(-30),
|
|
7892
|
-
// Timeouts config
|
|
7893
8150
|
timeouts: this.timeouts,
|
|
7894
|
-
// PTY alive
|
|
7895
8151
|
ptyAlive: !!this.ptyProcess
|
|
7896
8152
|
};
|
|
7897
8153
|
}
|
|
@@ -7957,21 +8213,27 @@ var init_cli_provider_instance = __esm({
|
|
|
7957
8213
|
async onTick() {
|
|
7958
8214
|
}
|
|
7959
8215
|
getState() {
|
|
7960
|
-
const
|
|
8216
|
+
const rawStatus = this.adapter.getStatus();
|
|
8217
|
+
const parsedStatus = this.adapter.getScriptParsedStatus();
|
|
8218
|
+
const adapterStatus = parsedStatus ? {
|
|
8219
|
+
...rawStatus,
|
|
8220
|
+
messages: parsedStatus.messages || rawStatus.messages,
|
|
8221
|
+
activeModal: parsedStatus.activeModal || rawStatus.activeModal
|
|
8222
|
+
} : rawStatus;
|
|
7961
8223
|
const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
|
|
7962
|
-
const recentMessages = adapterStatus.messages.slice(-50).map((m) =>
|
|
7963
|
-
|
|
7964
|
-
|
|
7965
|
-
|
|
7966
|
-
}));
|
|
8224
|
+
const recentMessages = adapterStatus.messages.slice(-50).map((m) => {
|
|
8225
|
+
const content = typeof m.content === "string" && m.content.length > 8e3 ? m.content.slice(0, 8e3) + "\n... (truncated)" : m.content;
|
|
8226
|
+
return { ...m, content };
|
|
8227
|
+
});
|
|
7967
8228
|
const partial2 = this.adapter.getPartialResponse();
|
|
7968
8229
|
if (adapterStatus.status === "generating" && partial2) {
|
|
7969
8230
|
const cleaned = partial2.trim();
|
|
7970
8231
|
if (cleaned && cleaned !== "(generating...)") {
|
|
7971
8232
|
recentMessages.push({
|
|
7972
8233
|
role: "assistant",
|
|
7973
|
-
content: (cleaned.length >
|
|
7974
|
-
timestamp: Date.now()
|
|
8234
|
+
content: (cleaned.length > 8e3 ? cleaned.slice(0, 8e3) + "..." : cleaned) + "...",
|
|
8235
|
+
timestamp: Date.now(),
|
|
8236
|
+
meta: { streaming: true }
|
|
7975
8237
|
});
|
|
7976
8238
|
}
|
|
7977
8239
|
}
|
|
@@ -8010,6 +8272,8 @@ var init_cli_provider_instance = __esm({
|
|
|
8010
8272
|
this.adapter.sendMessage(data.text);
|
|
8011
8273
|
} else if (event === "server_connected" && data?.serverConn) {
|
|
8012
8274
|
this.adapter.setServerConn(data.serverConn);
|
|
8275
|
+
} else if (event === "resolve_action" && data) {
|
|
8276
|
+
this.adapter.resolveAction(data);
|
|
8013
8277
|
}
|
|
8014
8278
|
}
|
|
8015
8279
|
dispose() {
|
|
@@ -25396,7 +25660,8 @@ var init_cli_manager = __esm({
|
|
|
25396
25660
|
const provider = this.providerLoader.getMeta(normalizedType);
|
|
25397
25661
|
if (provider && provider.category === "cli" && provider.patterns && provider.spawn) {
|
|
25398
25662
|
console.log(import_chalk.default.cyan(` \u{1F4E6} Using provider: ${provider.name} (${provider.type})`));
|
|
25399
|
-
|
|
25663
|
+
const resolvedProvider = this.providerLoader.resolve(normalizedType) || provider;
|
|
25664
|
+
return new ProviderCliAdapter(resolvedProvider, workingDir, cliArgs);
|
|
25400
25665
|
}
|
|
25401
25666
|
throw new Error(`No CLI provider found for '${cliType}'. Create a provider.js in providers/cli/${cliType}/`);
|
|
25402
25667
|
}
|
|
@@ -25481,7 +25746,8 @@ ${installInfo}`
|
|
|
25481
25746
|
}
|
|
25482
25747
|
const instanceManager = this.deps.getInstanceManager();
|
|
25483
25748
|
if (provider && instanceManager) {
|
|
25484
|
-
const
|
|
25749
|
+
const resolvedProvider = this.providerLoader.resolve(cliType, { version: cliInfo.version }) || provider;
|
|
25750
|
+
const cliInstance = new CliProviderInstance(resolvedProvider, resolvedDir, cliArgs, key);
|
|
25485
25751
|
try {
|
|
25486
25752
|
await instanceManager.addInstance(key, cliInstance, {
|
|
25487
25753
|
serverConn: this.deps.getServerConn(),
|
|
@@ -28746,6 +29012,46 @@ var init_dev_server = __esm({
|
|
|
28746
29012
|
}
|
|
28747
29013
|
}
|
|
28748
29014
|
// ─── Phase 2: Auto-Implement Backend ───
|
|
29015
|
+
getDefaultAutoImplReference(category, type) {
|
|
29016
|
+
if (category === "cli") {
|
|
29017
|
+
return type === "codex-cli" ? "claude-cli" : "codex-cli";
|
|
29018
|
+
}
|
|
29019
|
+
return "antigravity";
|
|
29020
|
+
}
|
|
29021
|
+
resolveAutoImplReference(category, requestedReference, targetType) {
|
|
29022
|
+
const desired = requestedReference || this.getDefaultAutoImplReference(category, targetType);
|
|
29023
|
+
const ref = this.providerLoader.resolve(desired) || this.providerLoader.getMeta(desired);
|
|
29024
|
+
if (ref?.category === category) return desired;
|
|
29025
|
+
const all = this.providerLoader.getAll();
|
|
29026
|
+
const fallback = all.find((p) => p.category === category && p.type !== targetType);
|
|
29027
|
+
return fallback?.type || null;
|
|
29028
|
+
}
|
|
29029
|
+
loadAutoImplReferenceScripts(category, referenceType) {
|
|
29030
|
+
if (!referenceType) return {};
|
|
29031
|
+
const builtinDir = this.providerLoader.getPrimaryBuiltinDir();
|
|
29032
|
+
const refDir = path12.join(builtinDir, category, referenceType);
|
|
29033
|
+
if (!fs9.existsSync(refDir)) return {};
|
|
29034
|
+
const referenceScripts = {};
|
|
29035
|
+
const scriptsDir = path12.join(refDir, "scripts");
|
|
29036
|
+
if (!fs9.existsSync(scriptsDir)) return referenceScripts;
|
|
29037
|
+
const versions = fs9.readdirSync(scriptsDir).filter((d) => {
|
|
29038
|
+
try {
|
|
29039
|
+
return fs9.statSync(path12.join(scriptsDir, d)).isDirectory();
|
|
29040
|
+
} catch {
|
|
29041
|
+
return false;
|
|
29042
|
+
}
|
|
29043
|
+
}).sort().reverse();
|
|
29044
|
+
if (versions.length === 0) return referenceScripts;
|
|
29045
|
+
const latestDir = path12.join(scriptsDir, versions[0]);
|
|
29046
|
+
for (const file2 of fs9.readdirSync(latestDir)) {
|
|
29047
|
+
if (!file2.endsWith(".js")) continue;
|
|
29048
|
+
try {
|
|
29049
|
+
referenceScripts[file2] = fs9.readFileSync(path12.join(latestDir, file2), "utf-8");
|
|
29050
|
+
} catch {
|
|
29051
|
+
}
|
|
29052
|
+
}
|
|
29053
|
+
return referenceScripts;
|
|
29054
|
+
}
|
|
28749
29055
|
async handleAutoImplement(type, req, res) {
|
|
28750
29056
|
const body = await this.readBody(req);
|
|
28751
29057
|
const { agent = "claude-cli", functions, reference = "antigravity", model, comment } = body;
|
|
@@ -28768,36 +29074,26 @@ var init_dev_server = __esm({
|
|
|
28768
29074
|
return;
|
|
28769
29075
|
}
|
|
28770
29076
|
try {
|
|
28771
|
-
this.
|
|
29077
|
+
const resolvedReference = this.resolveAutoImplReference(provider.category, reference, type);
|
|
29078
|
+
this.sendAutoImplSSE({
|
|
29079
|
+
event: "progress",
|
|
29080
|
+
data: {
|
|
29081
|
+
function: "_init",
|
|
29082
|
+
status: "analyzing",
|
|
29083
|
+
message: provider.category === "cli" ? "Initializing agent (granting CLI PTY debug access)..." : "Initializing agent (granting DOM access)..."
|
|
29084
|
+
}
|
|
29085
|
+
});
|
|
28772
29086
|
const domContext = null;
|
|
28773
|
-
this.sendAutoImplSSE({
|
|
28774
|
-
|
|
28775
|
-
|
|
28776
|
-
|
|
28777
|
-
|
|
28778
|
-
|
|
28779
|
-
if (fs9.existsSync(scriptsDir)) {
|
|
28780
|
-
const versions = fs9.readdirSync(scriptsDir).filter((d) => {
|
|
28781
|
-
try {
|
|
28782
|
-
return fs9.statSync(path12.join(scriptsDir, d)).isDirectory();
|
|
28783
|
-
} catch {
|
|
28784
|
-
return false;
|
|
28785
|
-
}
|
|
28786
|
-
}).sort().reverse();
|
|
28787
|
-
if (versions.length > 0) {
|
|
28788
|
-
const latestDir = path12.join(scriptsDir, versions[0]);
|
|
28789
|
-
for (const file2 of fs9.readdirSync(latestDir)) {
|
|
28790
|
-
if (file2.endsWith(".js")) {
|
|
28791
|
-
try {
|
|
28792
|
-
referenceScripts[file2] = fs9.readFileSync(path12.join(latestDir, file2), "utf-8");
|
|
28793
|
-
} catch {
|
|
28794
|
-
}
|
|
28795
|
-
}
|
|
28796
|
-
}
|
|
28797
|
-
}
|
|
29087
|
+
this.sendAutoImplSSE({
|
|
29088
|
+
event: "progress",
|
|
29089
|
+
data: {
|
|
29090
|
+
function: "_init",
|
|
29091
|
+
status: "loading_reference",
|
|
29092
|
+
message: `Loading reference script (${resolvedReference || "none"})...`
|
|
28798
29093
|
}
|
|
28799
|
-
}
|
|
28800
|
-
const
|
|
29094
|
+
});
|
|
29095
|
+
const referenceScripts = this.loadAutoImplReferenceScripts(provider.category, resolvedReference);
|
|
29096
|
+
const prompt = this.buildAutoImplPrompt(type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference);
|
|
28801
29097
|
const tmpDir = path12.join(os14.tmpdir(), "adhdev-autoimpl");
|
|
28802
29098
|
if (!fs9.existsSync(tmpDir)) fs9.mkdirSync(tmpDir, { recursive: true });
|
|
28803
29099
|
const promptFile = path12.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
|
|
@@ -28815,7 +29111,7 @@ var init_dev_server = __esm({
|
|
|
28815
29111
|
}
|
|
28816
29112
|
const agentCategory = agentProvider?.category;
|
|
28817
29113
|
if (agentCategory === "acp") {
|
|
28818
|
-
this.sendAutoImplSSE({ event: "progress", data: { function: "_init", status: "spawning", message: `ACP
|
|
29114
|
+
this.sendAutoImplSSE({ event: "progress", data: { function: "_init", status: "spawning", message: `Spawning ACP agent: ${spawn3.command} ${(spawn3.args || []).join(" ")}` } });
|
|
28819
29115
|
this.autoImplStatus = { running: true, type, progress: [] };
|
|
28820
29116
|
const { ClientSideConnection: ClientSideConnection2, ndJsonStream: ndJsonStream2, PROTOCOL_VERSION: PROTOCOL_VERSION2 } = await Promise.resolve().then(() => (init_acp(), acp_exports));
|
|
28821
29117
|
const { Readable: Readable2, Writable: Writable2 } = await import("stream");
|
|
@@ -28902,7 +29198,7 @@ var init_dev_server = __esm({
|
|
|
28902
29198
|
this.autoImplProcess = null;
|
|
28903
29199
|
this.autoImplStatus.running = false;
|
|
28904
29200
|
const success2 = code === 0;
|
|
28905
|
-
this.sendAutoImplSSE({ event: "complete", data: { success: success2, exitCode: code, functions, message: success2 ? "\u2705 ACP Auto-implement
|
|
29201
|
+
this.sendAutoImplSSE({ event: "complete", data: { success: success2, exitCode: code, functions, message: success2 ? "\u2705 ACP Auto-implement complete" : `\u274C ACP agent exited (code: ${code})` } });
|
|
28906
29202
|
try {
|
|
28907
29203
|
this.providerLoader.reload();
|
|
28908
29204
|
} catch {
|
|
@@ -28917,16 +29213,16 @@ var init_dev_server = __esm({
|
|
|
28917
29213
|
try {
|
|
28918
29214
|
this.sendAutoImplSSE({ event: "progress", data: { function: "_init", status: "initializing", message: "ACP initialize..." } });
|
|
28919
29215
|
await connection.initialize({ protocolVersion: PROTOCOL_VERSION2, clientCapabilities: {} });
|
|
28920
|
-
this.sendAutoImplSSE({ event: "progress", data: { function: "_init", status: "session", message: "ACP session
|
|
29216
|
+
this.sendAutoImplSSE({ event: "progress", data: { function: "_init", status: "session", message: "Creating ACP session..." } });
|
|
28921
29217
|
const session = await connection.newSession({ cwd: providerDir, mcpServers: [] });
|
|
28922
29218
|
const sessionId = session?.sessionId;
|
|
28923
29219
|
if (!sessionId) throw new Error("No sessionId returned from session/new");
|
|
28924
|
-
this.sendAutoImplSSE({ event: "progress", data: { function: "_init", status: "prompting", message:
|
|
29220
|
+
this.sendAutoImplSSE({ event: "progress", data: { function: "_init", status: "prompting", message: `Sending prompt (${prompt.length} chars)...` } });
|
|
28925
29221
|
await connection.prompt({
|
|
28926
29222
|
sessionId,
|
|
28927
29223
|
prompt: [{ type: "text", text: prompt }]
|
|
28928
29224
|
});
|
|
28929
|
-
this.sendAutoImplSSE({ event: "progress", data: { function: "_done", status: "complete", message: "\u2705 ACP
|
|
29225
|
+
this.sendAutoImplSSE({ event: "progress", data: { function: "_done", status: "complete", message: "\u2705 ACP prompt processing complete" } });
|
|
28930
29226
|
} catch (e) {
|
|
28931
29227
|
this.sendAutoImplSSE({ event: "output", data: { chunk: `[ACP Error] ${e.message}
|
|
28932
29228
|
`, stream: "stderr" } });
|
|
@@ -28978,7 +29274,7 @@ var init_dev_server = __esm({
|
|
|
28978
29274
|
const escapedArgs = baseArgs.map((a) => `'${a.replace(/'/g, "'\\''")}'`).join(" ");
|
|
28979
29275
|
shellCmd = `cat '${promptFile}' | ${command} ${escapedArgs}`;
|
|
28980
29276
|
}
|
|
28981
|
-
this.sendAutoImplSSE({ event: "progress", data: { function: "_init", status: "spawning", message:
|
|
29277
|
+
this.sendAutoImplSSE({ event: "progress", data: { function: "_init", status: "spawning", message: `Spawning agent: ${shellCmd.substring(0, 200)}... (prompt: ${prompt.length} chars)` } });
|
|
28982
29278
|
this.autoImplStatus = { running: true, type, progress: [] };
|
|
28983
29279
|
const spawnedAt = Date.now();
|
|
28984
29280
|
let child;
|
|
@@ -29074,7 +29370,7 @@ var init_dev_server = __esm({
|
|
|
29074
29370
|
const success2 = code === 0;
|
|
29075
29371
|
this.sendAutoImplSSE({
|
|
29076
29372
|
event: "complete",
|
|
29077
|
-
data: { success: success2, exitCode: code, functions, message: success2 ? "\u2705 Auto-implement
|
|
29373
|
+
data: { success: success2, exitCode: code, functions, message: success2 ? "\u2705 Auto-implement complete" : `\u274C Agent exited (code: ${code})` }
|
|
29078
29374
|
});
|
|
29079
29375
|
try {
|
|
29080
29376
|
this.providerLoader.reload();
|
|
@@ -29109,7 +29405,7 @@ var init_dev_server = __esm({
|
|
|
29109
29405
|
success: success2,
|
|
29110
29406
|
exitCode: code,
|
|
29111
29407
|
functions,
|
|
29112
|
-
message: success2 ? "\u2705 Auto-implement
|
|
29408
|
+
message: success2 ? "\u2705 Auto-implement complete" : `\u274C Agent exited (code: ${code})`
|
|
29113
29409
|
}
|
|
29114
29410
|
});
|
|
29115
29411
|
try {
|
|
@@ -29137,7 +29433,10 @@ var init_dev_server = __esm({
|
|
|
29137
29433
|
this.json(res, 500, { error: `Auto-implement failed: ${e.message}` });
|
|
29138
29434
|
}
|
|
29139
29435
|
}
|
|
29140
|
-
buildAutoImplPrompt(type, provider, providerDir, functions, domContext, referenceScripts, userComment) {
|
|
29436
|
+
buildAutoImplPrompt(type, provider, providerDir, functions, domContext, referenceScripts, userComment, referenceType) {
|
|
29437
|
+
if (provider.category === "cli") {
|
|
29438
|
+
return this.buildCliAutoImplPrompt(type, provider, providerDir, functions, referenceScripts, userComment, referenceType);
|
|
29439
|
+
}
|
|
29141
29440
|
const lines = [];
|
|
29142
29441
|
lines.push("You are implementing browser automation scripts for an IDE provider.");
|
|
29143
29442
|
lines.push("Be concise. Do NOT explain your reasoning. Just edit files directly.");
|
|
@@ -29200,7 +29499,7 @@ var init_dev_server = __esm({
|
|
|
29200
29499
|
setMode: "set_mode.js"
|
|
29201
29500
|
};
|
|
29202
29501
|
if (Object.keys(referenceScripts).length > 0) {
|
|
29203
|
-
lines.push(
|
|
29502
|
+
lines.push(`## Reference Implementation (from ${referenceType || "antigravity"} provider)`);
|
|
29204
29503
|
lines.push("These are WORKING scripts from another IDE. Adapt the PATTERNS (not selectors) for the target IDE.");
|
|
29205
29504
|
lines.push("");
|
|
29206
29505
|
for (const fn of functions) {
|
|
@@ -29349,6 +29648,150 @@ var init_dev_server = __esm({
|
|
|
29349
29648
|
lines.push("Start NOW. Do not ask for permission. Explore the DOM -> Code -> Test.");
|
|
29350
29649
|
return lines.join("\n");
|
|
29351
29650
|
}
|
|
29651
|
+
buildCliAutoImplPrompt(type, provider, providerDir, functions, referenceScripts, userComment, referenceType) {
|
|
29652
|
+
const lines = [];
|
|
29653
|
+
lines.push("You are implementing PTY parsing scripts for a CLI provider.");
|
|
29654
|
+
lines.push("Be concise. Do NOT explain your reasoning. Edit files directly and verify with the local DevServer.");
|
|
29655
|
+
lines.push("");
|
|
29656
|
+
lines.push(`# Target: ${provider.name || type} (${type})`);
|
|
29657
|
+
lines.push(`Provider directory: \`${providerDir}\``);
|
|
29658
|
+
lines.push("Provider category: `cli`");
|
|
29659
|
+
lines.push("");
|
|
29660
|
+
lines.push("## Current Target Files");
|
|
29661
|
+
lines.push("These are the files you need to edit. Replace TODO or heuristic-only logic with working PTY-aware implementations.");
|
|
29662
|
+
lines.push("");
|
|
29663
|
+
const scriptsDir = path12.join(providerDir, "scripts");
|
|
29664
|
+
if (fs9.existsSync(scriptsDir)) {
|
|
29665
|
+
const versions = fs9.readdirSync(scriptsDir).filter((d) => {
|
|
29666
|
+
try {
|
|
29667
|
+
return fs9.statSync(path12.join(scriptsDir, d)).isDirectory();
|
|
29668
|
+
} catch {
|
|
29669
|
+
return false;
|
|
29670
|
+
}
|
|
29671
|
+
}).sort().reverse();
|
|
29672
|
+
if (versions.length > 0) {
|
|
29673
|
+
const vDir = path12.join(scriptsDir, versions[0]);
|
|
29674
|
+
lines.push(`Scripts version directory: \`${vDir}\``);
|
|
29675
|
+
lines.push("");
|
|
29676
|
+
for (const file2 of fs9.readdirSync(vDir)) {
|
|
29677
|
+
if (!file2.endsWith(".js")) continue;
|
|
29678
|
+
try {
|
|
29679
|
+
const content = fs9.readFileSync(path12.join(vDir, file2), "utf-8");
|
|
29680
|
+
lines.push(`### \`${file2}\``);
|
|
29681
|
+
lines.push("```javascript");
|
|
29682
|
+
lines.push(content);
|
|
29683
|
+
lines.push("```");
|
|
29684
|
+
lines.push("");
|
|
29685
|
+
} catch {
|
|
29686
|
+
}
|
|
29687
|
+
}
|
|
29688
|
+
}
|
|
29689
|
+
}
|
|
29690
|
+
const funcToFile = {
|
|
29691
|
+
parseOutput: "parse_output.js",
|
|
29692
|
+
detectStatus: "detect_status.js",
|
|
29693
|
+
parseApproval: "parse_approval.js"
|
|
29694
|
+
};
|
|
29695
|
+
if (Object.keys(referenceScripts).length > 0) {
|
|
29696
|
+
lines.push(`## Reference Implementation (from ${referenceType || "another CLI"} provider)`);
|
|
29697
|
+
lines.push("These are working CLI PTY parser scripts. Reuse the parsing shape and runtime contract, but adapt to the target CLI screen.");
|
|
29698
|
+
lines.push("");
|
|
29699
|
+
for (const fn of functions) {
|
|
29700
|
+
const fileName = funcToFile[fn];
|
|
29701
|
+
if (fileName && referenceScripts[fileName]) {
|
|
29702
|
+
lines.push(`### ${fn} \u2192 \`${fileName}\``);
|
|
29703
|
+
lines.push("```javascript");
|
|
29704
|
+
lines.push(referenceScripts[fileName]);
|
|
29705
|
+
lines.push("```");
|
|
29706
|
+
lines.push("");
|
|
29707
|
+
}
|
|
29708
|
+
}
|
|
29709
|
+
if (referenceScripts["scripts.js"]) {
|
|
29710
|
+
lines.push("### Router \u2192 `scripts.js`");
|
|
29711
|
+
lines.push("```javascript");
|
|
29712
|
+
lines.push(referenceScripts["scripts.js"]);
|
|
29713
|
+
lines.push("```");
|
|
29714
|
+
lines.push("");
|
|
29715
|
+
}
|
|
29716
|
+
}
|
|
29717
|
+
lines.push("## Runtime Contract");
|
|
29718
|
+
lines.push("The daemon runtime is already implemented in `packages/daemon-core/src/cli-adapters/provider-cli-adapter.ts`.");
|
|
29719
|
+
lines.push("Your scripts receive PTY-derived input and must return plain JS objects.");
|
|
29720
|
+
lines.push("");
|
|
29721
|
+
lines.push("| Function | Input | Return |");
|
|
29722
|
+
lines.push("|---|---|---|");
|
|
29723
|
+
lines.push("| `parseOutput` | `{ buffer, rawBuffer, recentBuffer, screenText, messages, partialResponse }` | `{ id, status, title, messages, activeModal }` |");
|
|
29724
|
+
lines.push("| `detectStatus` | `{ tail }` | `idle`, `generating`, `waiting_approval`, or `error` |");
|
|
29725
|
+
lines.push("| `parseApproval` | `{ buffer, rawBuffer, tail }` | `{ message, buttons }` or `null` |");
|
|
29726
|
+
lines.push("");
|
|
29727
|
+
lines.push("## Rules");
|
|
29728
|
+
lines.push("1. These scripts run in Node.js CommonJS, not in the browser. Do NOT use DOM APIs.");
|
|
29729
|
+
lines.push("2. Prefer `screenText` for current visible UI state. That is the PTY equivalent of parsing the current IDE DOM.");
|
|
29730
|
+
lines.push("3. Use `messages` as prior transcript state so redraws do not duplicate old turns on every parse.");
|
|
29731
|
+
lines.push("4. Use `partialResponse` for the actively streaming assistant text when status is `generating`.");
|
|
29732
|
+
lines.push("5. `detectStatus` must stay lightweight and tail-based. Do not scan the entire history there.");
|
|
29733
|
+
lines.push("6. `parseApproval` should understand the live approval area and return clean button labels.");
|
|
29734
|
+
lines.push("7. Use `rawBuffer` only when ANSI/control-sequence artifacts matter. Do not depend on raw escape noise unless necessary.");
|
|
29735
|
+
lines.push("8. Keep exports compatible with the existing `scripts.js` router (`module.exports = function ...`).");
|
|
29736
|
+
lines.push("9. Do not rewrite unrelated provider config. Only touch the scripts needed for this task unless a tiny supporting change is required.");
|
|
29737
|
+
lines.push("");
|
|
29738
|
+
lines.push("## Task");
|
|
29739
|
+
lines.push(`Edit files in \`${providerDir}\` to implement: **${functions.join(", ")}**`);
|
|
29740
|
+
lines.push("");
|
|
29741
|
+
lines.push("## Verification API");
|
|
29742
|
+
lines.push("Use the DevServer CLI debug endpoints, not DOM/CDP routes.");
|
|
29743
|
+
lines.push("");
|
|
29744
|
+
lines.push("### 1. Launch the target CLI");
|
|
29745
|
+
lines.push("```bash");
|
|
29746
|
+
lines.push(`curl -sS -X POST http://127.0.0.1:${DEV_SERVER_PORT}/api/cli/launch \\`);
|
|
29747
|
+
lines.push(' -H "Content-Type: application/json" \\');
|
|
29748
|
+
lines.push(` -d '{"type":"${type}","workingDir":"${providerDir.replace(/\\/g, "\\\\")}"}'`);
|
|
29749
|
+
lines.push("```");
|
|
29750
|
+
lines.push("");
|
|
29751
|
+
lines.push("### 2. Inspect parsed + raw adapter state");
|
|
29752
|
+
lines.push("```bash");
|
|
29753
|
+
lines.push(`curl -sS http://127.0.0.1:${DEV_SERVER_PORT}/api/cli/debug/${type}`);
|
|
29754
|
+
lines.push(`curl -sS http://127.0.0.1:${DEV_SERVER_PORT}/api/cli/status`);
|
|
29755
|
+
lines.push("```");
|
|
29756
|
+
lines.push("");
|
|
29757
|
+
lines.push("### 3. Send a rich test prompt");
|
|
29758
|
+
lines.push("```bash");
|
|
29759
|
+
lines.push(`curl -sS -X POST http://127.0.0.1:${DEV_SERVER_PORT}/api/cli/send \\`);
|
|
29760
|
+
lines.push(' -H "Content-Type: application/json" \\');
|
|
29761
|
+
lines.push(` -d '{"type":"${type}","text":"Write a short python snippet, include a markdown table, and briefly explain what you did."}'`);
|
|
29762
|
+
lines.push("```");
|
|
29763
|
+
lines.push("");
|
|
29764
|
+
lines.push("### 4. If approval appears, resolve it");
|
|
29765
|
+
lines.push("```bash");
|
|
29766
|
+
lines.push(`curl -sS -X POST http://127.0.0.1:${DEV_SERVER_PORT}/api/cli/resolve \\`);
|
|
29767
|
+
lines.push(' -H "Content-Type: application/json" \\');
|
|
29768
|
+
lines.push(` -d '{"type":"${type}","buttonIndex":0}'`);
|
|
29769
|
+
lines.push("```");
|
|
29770
|
+
lines.push("");
|
|
29771
|
+
lines.push("### 5. Stop the CLI when finished");
|
|
29772
|
+
lines.push("```bash");
|
|
29773
|
+
lines.push(`curl -sS -X POST http://127.0.0.1:${DEV_SERVER_PORT}/api/cli/stop \\`);
|
|
29774
|
+
lines.push(' -H "Content-Type: application/json" \\');
|
|
29775
|
+
lines.push(` -d '{"type":"${type}"}'`);
|
|
29776
|
+
lines.push("```");
|
|
29777
|
+
lines.push("");
|
|
29778
|
+
lines.push("## Required Validation");
|
|
29779
|
+
lines.push("1. Confirm `detectStatus` changes sensibly between startup, generating, approval, and idle.");
|
|
29780
|
+
lines.push("2. Confirm `parseOutput` produces a stable transcript without duplicating past turns when the PTY redraws.");
|
|
29781
|
+
lines.push("3. Confirm the latest assistant message streams through `partialResponse` while generation is in progress.");
|
|
29782
|
+
lines.push("4. Confirm approval parsing returns meaningful button labels when the CLI requests permission.");
|
|
29783
|
+
lines.push("5. Re-run the debug endpoints after edits. Do NOT finish until the parsed result looks correct.");
|
|
29784
|
+
lines.push("");
|
|
29785
|
+
if (userComment) {
|
|
29786
|
+
lines.push("## \u26A0\uFE0F User Instructions (HIGH PRIORITY)");
|
|
29787
|
+
lines.push("The user has provided the following additional instructions. Follow them strictly:");
|
|
29788
|
+
lines.push("");
|
|
29789
|
+
lines.push(userComment);
|
|
29790
|
+
lines.push("");
|
|
29791
|
+
}
|
|
29792
|
+
lines.push("Start NOW. Launch the CLI, inspect PTY state, edit the scripts, and verify via the CLI debug endpoints.");
|
|
29793
|
+
return lines.join("\n");
|
|
29794
|
+
}
|
|
29352
29795
|
handleAutoImplSSE(type, req, res) {
|
|
29353
29796
|
res.writeHead(200, {
|
|
29354
29797
|
"Content-Type": "text/event-stream",
|
|
@@ -29376,7 +29819,7 @@ data: ${JSON.stringify(p.data)}
|
|
|
29376
29819
|
setTimeout(() => {
|
|
29377
29820
|
if (this.autoImplProcess) this.autoImplProcess.kill("SIGKILL");
|
|
29378
29821
|
}, 3e3);
|
|
29379
|
-
this.sendAutoImplSSE({ event: "complete", data: { success: false, exitCode: -1, message: "\u26D4
|
|
29822
|
+
this.sendAutoImplSSE({ event: "complete", data: { success: false, exitCode: -1, message: "\u26D4 Aborted by user" } });
|
|
29380
29823
|
this.autoImplProcess = null;
|
|
29381
29824
|
this.autoImplStatus.running = false;
|
|
29382
29825
|
this.json(res, 200, { cancelled: true });
|
|
@@ -31188,11 +31631,12 @@ ${e?.stack || ""}`);
|
|
|
31188
31631
|
});
|
|
31189
31632
|
|
|
31190
31633
|
// src/screenshot-controller.ts
|
|
31191
|
-
var ScreenshotController;
|
|
31634
|
+
var import_sharp, ScreenshotController;
|
|
31192
31635
|
var init_screenshot_controller = __esm({
|
|
31193
31636
|
"src/screenshot-controller.ts"() {
|
|
31194
31637
|
"use strict";
|
|
31195
31638
|
init_src();
|
|
31639
|
+
import_sharp = __toESM(require("sharp"));
|
|
31196
31640
|
ScreenshotController = class _ScreenshotController {
|
|
31197
31641
|
deps;
|
|
31198
31642
|
timer = null;
|
|
@@ -31219,12 +31663,16 @@ var init_screenshot_controller = __esm({
|
|
|
31219
31663
|
this.profileDirect = {
|
|
31220
31664
|
minInterval: Math.max(300, planMinIntervalMs),
|
|
31221
31665
|
maxInterval: Math.max(2e3, planMinIntervalMs),
|
|
31222
|
-
quality: 25
|
|
31666
|
+
quality: 25,
|
|
31667
|
+
maxLongEdge: 1728,
|
|
31668
|
+
firstFrameLongEdge: 1920
|
|
31223
31669
|
};
|
|
31224
31670
|
this.profileRelay = {
|
|
31225
31671
|
minInterval: Math.max(700, planMinIntervalMs),
|
|
31226
31672
|
maxInterval: Math.max(3e3, planMinIntervalMs),
|
|
31227
|
-
quality: 12
|
|
31673
|
+
quality: 12,
|
|
31674
|
+
maxLongEdge: 1152,
|
|
31675
|
+
firstFrameLongEdge: 1280
|
|
31228
31676
|
};
|
|
31229
31677
|
this.currentInterval = this.profileDirect.maxInterval;
|
|
31230
31678
|
this.dailyBudgetMinutes = planLimits?.dailyScreenshotMinutes ?? -1;
|
|
@@ -31297,6 +31745,7 @@ var init_screenshot_controller = __esm({
|
|
|
31297
31745
|
const sizeMatch = buf.length === this.lastSize;
|
|
31298
31746
|
const hashMatch = hash2 === this.lastHash;
|
|
31299
31747
|
const anyNeedsFirstFrame = this.deps.hasAnyNeedingFirstFrame();
|
|
31748
|
+
const resizeTarget = anyNeedsFirstFrame ? profile.firstFrameLongEdge : profile.maxLongEdge;
|
|
31300
31749
|
if (sizeMatch && hashMatch && !anyNeedsFirstFrame) {
|
|
31301
31750
|
this.staticFrameCount++;
|
|
31302
31751
|
if (this.staticFrameCount >= this.STATIC_THRESHOLD) {
|
|
@@ -31306,13 +31755,14 @@ var init_screenshot_controller = __esm({
|
|
|
31306
31755
|
LOG.debug("Screenshot", `skip (unchanged, static=${this.staticFrameCount}, interval=${this.currentInterval}ms, ${isRelay ? "RELAY" : "DIRECT"})`);
|
|
31307
31756
|
}
|
|
31308
31757
|
} else {
|
|
31758
|
+
const normalizedBuf = await this.normalizeBuffer(buf, resizeTarget, profile.quality);
|
|
31309
31759
|
this.lastSize = buf.length;
|
|
31310
31760
|
this.lastHash = hash2;
|
|
31311
31761
|
this.staticFrameCount = 0;
|
|
31312
31762
|
this.currentInterval = profile.minInterval;
|
|
31313
|
-
const sent = this.deps.sendScreenshotBuffer(
|
|
31763
|
+
const sent = this.deps.sendScreenshotBuffer(normalizedBuf);
|
|
31314
31764
|
if (this.debugCount <= 3 || anyNeedsFirstFrame) {
|
|
31315
|
-
LOG.debug("Screenshot", `sent: ${
|
|
31765
|
+
LOG.debug("Screenshot", `sent: ${normalizedBuf.length} bytes, delivered=${sent}, interval=${this.currentInterval}ms, ${isRelay ? "RELAY" : "DIRECT"}${anyNeedsFirstFrame ? " (first-frame)" : ""}`);
|
|
31316
31766
|
}
|
|
31317
31767
|
}
|
|
31318
31768
|
} else {
|
|
@@ -31360,6 +31810,28 @@ var init_screenshot_controller = __esm({
|
|
|
31360
31810
|
}
|
|
31361
31811
|
return h;
|
|
31362
31812
|
}
|
|
31813
|
+
/** Normalize screenshot resolution before transport so UX feels consistent across machines/DPI. */
|
|
31814
|
+
async normalizeBuffer(buf, maxLongEdge, quality) {
|
|
31815
|
+
try {
|
|
31816
|
+
const image = (0, import_sharp.default)(buf, { failOn: "none" });
|
|
31817
|
+
const meta3 = await image.metadata();
|
|
31818
|
+
const width = meta3.width || 0;
|
|
31819
|
+
const height = meta3.height || 0;
|
|
31820
|
+
if (!width || !height) return buf;
|
|
31821
|
+
const longEdge = Math.max(width, height);
|
|
31822
|
+
if (longEdge <= maxLongEdge) return buf;
|
|
31823
|
+
return await image.resize({
|
|
31824
|
+
width: width >= height ? maxLongEdge : void 0,
|
|
31825
|
+
height: height > width ? maxLongEdge : void 0,
|
|
31826
|
+
fit: "inside",
|
|
31827
|
+
withoutEnlargement: true,
|
|
31828
|
+
kernel: import_sharp.default.kernel.lanczos3
|
|
31829
|
+
}).webp({ quality, effort: 4 }).toBuffer();
|
|
31830
|
+
} catch (e) {
|
|
31831
|
+
LOG.debug("Screenshot", `normalize skipped: ${e?.message || e}`);
|
|
31832
|
+
return buf;
|
|
31833
|
+
}
|
|
31834
|
+
}
|
|
31363
31835
|
};
|
|
31364
31836
|
}
|
|
31365
31837
|
});
|
|
@@ -31422,7 +31894,7 @@ var init_adhdev_daemon = __esm({
|
|
|
31422
31894
|
fs11 = __toESM(require("fs"));
|
|
31423
31895
|
path14 = __toESM(require("path"));
|
|
31424
31896
|
import_chalk2 = __toESM(require("chalk"));
|
|
31425
|
-
pkgVersion = "0.6.
|
|
31897
|
+
pkgVersion = "0.6.55";
|
|
31426
31898
|
if (pkgVersion === "unknown") {
|
|
31427
31899
|
try {
|
|
31428
31900
|
const possiblePaths = [
|
|
@@ -32823,6 +33295,42 @@ function registerDaemonCommands(program2, pkgVersion3) {
|
|
|
32823
33295
|
// src/cli/provider-commands.ts
|
|
32824
33296
|
var import_chalk6 = __toESM(require("chalk"));
|
|
32825
33297
|
init_cdp_utils();
|
|
33298
|
+
var IDE_AUTO_FIX_FUNCTIONS = [
|
|
33299
|
+
"openPanel",
|
|
33300
|
+
"sendMessage",
|
|
33301
|
+
"readChat",
|
|
33302
|
+
"newSession",
|
|
33303
|
+
"listSessions",
|
|
33304
|
+
"switchSession",
|
|
33305
|
+
"resolveAction",
|
|
33306
|
+
"listModels",
|
|
33307
|
+
"setModel",
|
|
33308
|
+
"listModes",
|
|
33309
|
+
"setMode",
|
|
33310
|
+
"focusEditor"
|
|
33311
|
+
];
|
|
33312
|
+
var CLI_AUTO_FIX_FUNCTIONS = [
|
|
33313
|
+
"parseOutput",
|
|
33314
|
+
"detectStatus",
|
|
33315
|
+
"parseApproval"
|
|
33316
|
+
];
|
|
33317
|
+
var AUTO_FIX_SUPPORTED_CATEGORIES = /* @__PURE__ */ new Set(["ide", "extension", "cli"]);
|
|
33318
|
+
function getAutoFixFunctions(category) {
|
|
33319
|
+
if (category === "cli") return CLI_AUTO_FIX_FUNCTIONS;
|
|
33320
|
+
return IDE_AUTO_FIX_FUNCTIONS;
|
|
33321
|
+
}
|
|
33322
|
+
function getDefaultAutoFixReference(category, type, providers) {
|
|
33323
|
+
if (category === "cli") {
|
|
33324
|
+
const preferred = ["codex-cli", "claude-cli", "gemini-cli"];
|
|
33325
|
+
const picked = preferred.find(
|
|
33326
|
+
(ref) => ref !== type && providers.some((p) => p.type === ref && p.category === "cli")
|
|
33327
|
+
);
|
|
33328
|
+
if (picked) return picked;
|
|
33329
|
+
const fallback = providers.find((p) => p.category === "cli" && p.type !== type);
|
|
33330
|
+
return fallback?.type || "codex-cli";
|
|
33331
|
+
}
|
|
33332
|
+
return "antigravity";
|
|
33333
|
+
}
|
|
32826
33334
|
function hideCommand2(command) {
|
|
32827
33335
|
command.hideHelp?.();
|
|
32828
33336
|
return command;
|
|
@@ -33097,7 +33605,7 @@ function registerProviderCommands(program2) {
|
|
|
33097
33605
|
process.exit(1);
|
|
33098
33606
|
}
|
|
33099
33607
|
});
|
|
33100
|
-
provider.command("fix [type] [scripts...]").description("Auto-implement provider scripts using AI
|
|
33608
|
+
provider.command("fix [type] [scripts...]").description("Auto-implement provider scripts using AI for IDE DOM or CLI PTY parsing").option("-a, --agent <agent>", "AI agent to use (e.g. claude-cli, gemini-cli, codex-cli, or any ACP provider like cline-acp)", "codex-cli").option("-m, --model <model>", "Model override (e.g. claude-sonnet-3.5, gemini-2.0-pro)").option("-r, --reference <ref>", "Reference provider to learn from").option("-c, --comment <text>", "Additional instructions for the AI agent").action(async (typeArg, scripts, options) => {
|
|
33101
33609
|
try {
|
|
33102
33610
|
const http3 = await import("http");
|
|
33103
33611
|
const inquirer2 = (await import("inquirer")).default;
|
|
@@ -33112,17 +33620,17 @@ function registerProviderCommands(program2) {
|
|
|
33112
33620
|
};
|
|
33113
33621
|
let type = typeArg;
|
|
33114
33622
|
if (!type) {
|
|
33115
|
-
const
|
|
33116
|
-
if (
|
|
33117
|
-
console.log(import_chalk6.default.red("\n\u2717 No IDE providers found.\n"));
|
|
33623
|
+
const supportedProviders = allProviders.filter((p) => AUTO_FIX_SUPPORTED_CATEGORIES.has(p.category));
|
|
33624
|
+
if (supportedProviders.length === 0) {
|
|
33625
|
+
console.log(import_chalk6.default.red("\n\u2717 No IDE/extension/CLI providers found.\n"));
|
|
33118
33626
|
process.exit(1);
|
|
33119
33627
|
}
|
|
33120
33628
|
const typeAnswer = await inquirer2.prompt([{
|
|
33121
33629
|
type: "list",
|
|
33122
33630
|
name: "selected",
|
|
33123
|
-
message: "Select the
|
|
33124
|
-
choices:
|
|
33125
|
-
name:
|
|
33631
|
+
message: "Select the provider you want to fix:",
|
|
33632
|
+
choices: supportedProviders.map((p) => ({
|
|
33633
|
+
name: `[${p.category}] ${p.name} ${isUserProvider(p) ? import_chalk6.default.yellow("[user]") : import_chalk6.default.gray("[upstream]")}`,
|
|
33126
33634
|
value: p.type
|
|
33127
33635
|
}))
|
|
33128
33636
|
}]);
|
|
@@ -33133,6 +33641,18 @@ function registerProviderCommands(program2) {
|
|
|
33133
33641
|
process.exit(1);
|
|
33134
33642
|
}
|
|
33135
33643
|
const providerToFix = allProviders.find((p) => p.type === type);
|
|
33644
|
+
if (!providerToFix) {
|
|
33645
|
+
console.log(import_chalk6.default.red(`
|
|
33646
|
+
\u2717 Unknown provider: ${type}
|
|
33647
|
+
`));
|
|
33648
|
+
process.exit(1);
|
|
33649
|
+
}
|
|
33650
|
+
if (!AUTO_FIX_SUPPORTED_CATEGORIES.has(providerToFix.category)) {
|
|
33651
|
+
console.log(import_chalk6.default.red(`
|
|
33652
|
+
\u2717 Provider category '${providerToFix.category}' is not supported by adhdev provider fix.
|
|
33653
|
+
`));
|
|
33654
|
+
process.exit(1);
|
|
33655
|
+
}
|
|
33136
33656
|
if (providerToFix && !isUserProvider(providerToFix)) {
|
|
33137
33657
|
console.log(import_chalk6.default.yellow(`
|
|
33138
33658
|
\u26A0\uFE0F [${type}] is an upstream provider.`));
|
|
@@ -33193,7 +33713,7 @@ function registerProviderCommands(program2) {
|
|
|
33193
33713
|
}
|
|
33194
33714
|
let agentName = options.agent || "codex-cli";
|
|
33195
33715
|
const modelName = options.model;
|
|
33196
|
-
const reference = options.reference ||
|
|
33716
|
+
const reference = options.reference || getDefaultAutoFixReference(providerToFix.category, type, allProviders);
|
|
33197
33717
|
if (!typeArg && agentName === "codex-cli") {
|
|
33198
33718
|
const agentAnswer = await inquirer2.prompt([{
|
|
33199
33719
|
type: "list",
|
|
@@ -33210,23 +33730,20 @@ function registerProviderCommands(program2) {
|
|
|
33210
33730
|
}
|
|
33211
33731
|
console.log(import_chalk6.default.bold(`
|
|
33212
33732
|
\u{1F916} Starting Auto-Implement Agent for [${import_chalk6.default.cyan(type)}]`));
|
|
33213
|
-
console.log(import_chalk6.default.gray(` Agent: ${agentName}${modelName ? ` (model: ${modelName})` : ""} | Reference: ${reference}
|
|
33733
|
+
console.log(import_chalk6.default.gray(` Category: ${providerToFix.category} | Agent: ${agentName}${modelName ? ` (model: ${modelName})` : ""} | Reference: ${reference}
|
|
33214
33734
|
`));
|
|
33215
|
-
const allFunctions =
|
|
33216
|
-
"openPanel",
|
|
33217
|
-
"sendMessage",
|
|
33218
|
-
"readChat",
|
|
33219
|
-
"newSession",
|
|
33220
|
-
"listSessions",
|
|
33221
|
-
"switchSession",
|
|
33222
|
-
"resolveAction",
|
|
33223
|
-
"listModels",
|
|
33224
|
-
"setModel",
|
|
33225
|
-
"listModes",
|
|
33226
|
-
"setMode",
|
|
33227
|
-
"focusEditor"
|
|
33228
|
-
];
|
|
33735
|
+
const allFunctions = getAutoFixFunctions(providerToFix.category);
|
|
33229
33736
|
let functionsToFix = scripts;
|
|
33737
|
+
if (functionsToFix.length > 0) {
|
|
33738
|
+
const invalid = functionsToFix.filter((fn) => !allFunctions.includes(fn));
|
|
33739
|
+
if (invalid.length > 0) {
|
|
33740
|
+
console.log(import_chalk6.default.red(`
|
|
33741
|
+
\u2717 Unsupported scripts for ${providerToFix.category} provider [${type}]: ${invalid.join(", ")}`));
|
|
33742
|
+
console.log(import_chalk6.default.gray(` Valid scripts: ${allFunctions.join(", ")}
|
|
33743
|
+
`));
|
|
33744
|
+
process.exit(1);
|
|
33745
|
+
}
|
|
33746
|
+
}
|
|
33230
33747
|
if (!scripts || scripts.length === 0) {
|
|
33231
33748
|
const inquirer3 = (await import("inquirer")).default;
|
|
33232
33749
|
const answer = await inquirer3.prompt([{
|