adhdev 0.6.52 → 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 +828 -315
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +752 -281
- 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" };
|
|
@@ -5998,7 +6019,7 @@ var init_provider_loader = __esm({
|
|
|
5998
6019
|
// ─── Private ───────────────────────────────────
|
|
5999
6020
|
/**
|
|
6000
6021
|
* Find the on-disk directory for a provider by type.
|
|
6001
|
-
*
|
|
6022
|
+
* Canonical shape: root/category/type.
|
|
6002
6023
|
*/
|
|
6003
6024
|
findProviderDirInternal(type) {
|
|
6004
6025
|
const provider = this.providers.get(type);
|
|
@@ -6007,9 +6028,8 @@ var init_provider_loader = __esm({
|
|
|
6007
6028
|
const searchRoots = this.getProviderRoots();
|
|
6008
6029
|
for (const root of searchRoots) {
|
|
6009
6030
|
if (!fs5.existsSync(root)) continue;
|
|
6010
|
-
|
|
6011
|
-
|
|
6012
|
-
}
|
|
6031
|
+
const candidate = this.getProviderDir(root, cat, type);
|
|
6032
|
+
if (fs5.existsSync(path6.join(candidate, "provider.json"))) return candidate;
|
|
6013
6033
|
const catDir = path6.join(root, cat);
|
|
6014
6034
|
if (fs5.existsSync(catDir)) {
|
|
6015
6035
|
try {
|
|
@@ -6184,8 +6204,9 @@ var init_provider_loader = __esm({
|
|
|
6184
6204
|
}
|
|
6185
6205
|
}
|
|
6186
6206
|
compareVersions(a, b) {
|
|
6187
|
-
const
|
|
6188
|
-
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);
|
|
6189
6210
|
for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
|
|
6190
6211
|
const va = pa[i] || 0;
|
|
6191
6212
|
const vb = pb[i] || 0;
|
|
@@ -7237,6 +7258,246 @@ var init_reporter = __esm({
|
|
|
7237
7258
|
}
|
|
7238
7259
|
});
|
|
7239
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
|
+
|
|
7240
7501
|
// ../daemon-core/src/cli-adapters/provider-cli-adapter.ts
|
|
7241
7502
|
var provider_cli_adapter_exports = {};
|
|
7242
7503
|
__export(provider_cli_adapter_exports, {
|
|
@@ -7309,28 +7570,19 @@ function parsePatternEntry(x) {
|
|
|
7309
7570
|
}
|
|
7310
7571
|
return null;
|
|
7311
7572
|
}
|
|
7312
|
-
function coercePatternArray(raw
|
|
7313
|
-
if (!Array.isArray(raw)) return [
|
|
7314
|
-
|
|
7315
|
-
return parsed.length > 0 ? parsed : [...fallbacks];
|
|
7316
|
-
}
|
|
7317
|
-
function defaultCleanOutput(raw, _lastUserInput) {
|
|
7318
|
-
return stripAnsi(raw).trim();
|
|
7573
|
+
function coercePatternArray(raw) {
|
|
7574
|
+
if (!Array.isArray(raw)) return [];
|
|
7575
|
+
return raw.map(parsePatternEntry).filter((r) => r != null);
|
|
7319
7576
|
}
|
|
7320
7577
|
function normalizeCliProviderForRuntime(raw) {
|
|
7321
7578
|
const patterns = raw?.patterns || {};
|
|
7322
7579
|
return {
|
|
7323
|
-
...raw,
|
|
7324
7580
|
patterns: {
|
|
7325
|
-
|
|
7326
|
-
|
|
7327
|
-
approval: coercePatternArray(patterns.approval, FALLBACK_APPROVAL),
|
|
7328
|
-
ready: coercePatternArray(patterns.ready, [])
|
|
7329
|
-
},
|
|
7330
|
-
cleanOutput: typeof raw?.cleanOutput === "function" ? raw.cleanOutput : defaultCleanOutput
|
|
7581
|
+
approval: coercePatternArray(patterns.approval)
|
|
7582
|
+
}
|
|
7331
7583
|
};
|
|
7332
7584
|
}
|
|
7333
|
-
var os11, path9, import_child_process5, pty,
|
|
7585
|
+
var os11, path9, import_child_process5, pty, ProviderCliAdapter;
|
|
7334
7586
|
var init_provider_cli_adapter = __esm({
|
|
7335
7587
|
"../daemon-core/src/cli-adapters/provider-cli-adapter.ts"() {
|
|
7336
7588
|
"use strict";
|
|
@@ -7338,6 +7590,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
7338
7590
|
path9 = __toESM(require("path"));
|
|
7339
7591
|
import_child_process5 = require("child_process");
|
|
7340
7592
|
init_logger();
|
|
7593
|
+
init_terminal_screen();
|
|
7341
7594
|
try {
|
|
7342
7595
|
pty = require("node-pty");
|
|
7343
7596
|
if (os11.platform() !== "win32") {
|
|
@@ -7359,40 +7612,10 @@ var init_provider_cli_adapter = __esm({
|
|
|
7359
7612
|
} catch {
|
|
7360
7613
|
LOG.error("CLI", "[ProviderCliAdapter] node-pty not found. Terminal features disabled.");
|
|
7361
7614
|
}
|
|
7362
|
-
|
|
7363
|
-
/Type your message/i,
|
|
7364
|
-
/for\s*shortcuts/i,
|
|
7365
|
-
// Claude Code prompt
|
|
7366
|
-
/\?\s*for\s*help/i,
|
|
7367
|
-
// Claude Code help prompt
|
|
7368
|
-
/Press enter/i,
|
|
7369
|
-
/^[>›❯]\s*$/i,
|
|
7370
|
-
// Prompt char as the complete evaluated string
|
|
7371
|
-
/[>›❯]\s*$/
|
|
7372
|
-
// Prompt char at the very end of evaluated string
|
|
7373
|
-
];
|
|
7374
|
-
FALLBACK_GENERATING = [
|
|
7375
|
-
/[\u2800-\u28ff]/,
|
|
7376
|
-
// Braille spinner blocks (universal TUI)
|
|
7377
|
-
/esc to (cancel|interrupt|stop)/i,
|
|
7378
|
-
// Common TUI generation status line
|
|
7379
|
-
/generating\.\.\./i,
|
|
7380
|
-
/Claude is (?:thinking|processing|working)/i
|
|
7381
|
-
// Specific Claude Code status
|
|
7382
|
-
];
|
|
7383
|
-
FALLBACK_APPROVAL = [
|
|
7384
|
-
/Allow\s*once/i,
|
|
7385
|
-
// ANSI strip may remove spaces
|
|
7386
|
-
/Always\s*allow/i,
|
|
7387
|
-
/\(y\/n\)/i,
|
|
7388
|
-
/\[Y\/n\]/i,
|
|
7389
|
-
/Yes,?\s*don'?t\s*ask/i
|
|
7390
|
-
// "Yes, don't ask again" (Claude Code)
|
|
7391
|
-
];
|
|
7392
|
-
ProviderCliAdapter = class {
|
|
7615
|
+
ProviderCliAdapter = class _ProviderCliAdapter {
|
|
7393
7616
|
constructor(provider, workingDir, extraArgs = []) {
|
|
7394
7617
|
this.extraArgs = extraArgs;
|
|
7395
|
-
this.provider =
|
|
7618
|
+
this.provider = provider;
|
|
7396
7619
|
this.cliType = provider.type;
|
|
7397
7620
|
this.cliName = provider.name;
|
|
7398
7621
|
this.workingDir = workingDir.startsWith("~") ? workingDir.replace(/^~/, os11.homedir()) : workingDir;
|
|
@@ -7409,6 +7632,13 @@ var init_provider_cli_adapter = __esm({
|
|
|
7409
7632
|
};
|
|
7410
7633
|
const rawKeys = provider.approvalKeys;
|
|
7411
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
|
+
}
|
|
7412
7642
|
}
|
|
7413
7643
|
cliType;
|
|
7414
7644
|
cliName;
|
|
@@ -7416,6 +7646,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
7416
7646
|
provider;
|
|
7417
7647
|
ptyProcess = null;
|
|
7418
7648
|
messages = [];
|
|
7649
|
+
structuredMessages = [];
|
|
7419
7650
|
currentStatus = "starting";
|
|
7420
7651
|
onStatusChange = null;
|
|
7421
7652
|
responseBuffer = "";
|
|
@@ -7426,7 +7657,6 @@ var init_provider_cli_adapter = __esm({
|
|
|
7426
7657
|
idleTimeout = null;
|
|
7427
7658
|
ready = false;
|
|
7428
7659
|
startupBuffer = "";
|
|
7429
|
-
/** After spawn: briefly skip generating/settle so splash/redraw does not flip status; not used to gate sendMessage */
|
|
7430
7660
|
startupParseGate = false;
|
|
7431
7661
|
spawnAt = 0;
|
|
7432
7662
|
// PTY I/O
|
|
@@ -7444,11 +7674,20 @@ var init_provider_cli_adapter = __esm({
|
|
|
7444
7674
|
// Output settle debounce — fires after PTY output goes quiet
|
|
7445
7675
|
settleTimer = null;
|
|
7446
7676
|
settledBuffer = "";
|
|
7447
|
-
// snapshot of recentOutputBuffer at settle time
|
|
7448
7677
|
// Resize redraw suppression
|
|
7449
7678
|
resizeSuppressUntil = 0;
|
|
7450
7679
|
// Debug: status transition history
|
|
7451
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;
|
|
7452
7691
|
setStatus(status, trigger) {
|
|
7453
7692
|
const prev = this.currentStatus;
|
|
7454
7693
|
if (prev === status) return;
|
|
@@ -7457,10 +7696,16 @@ var init_provider_cli_adapter = __esm({
|
|
|
7457
7696
|
if (this.statusHistory.length > 50) this.statusHistory.shift();
|
|
7458
7697
|
LOG.info("CLI", `[${this.cliType}] status: ${prev} \u2192 ${status}${trigger ? ` (${trigger})` : ""}`);
|
|
7459
7698
|
}
|
|
7460
|
-
// Resolved timeouts
|
|
7699
|
+
// Resolved timeouts
|
|
7461
7700
|
timeouts;
|
|
7462
|
-
// Provider approval key mapping
|
|
7701
|
+
// Provider approval key mapping
|
|
7463
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
|
+
}
|
|
7464
7709
|
// ─── Lifecycle ─────────────────────────────────
|
|
7465
7710
|
setServerConn(serverConn) {
|
|
7466
7711
|
this.serverConn = serverConn;
|
|
@@ -7549,15 +7794,19 @@ var init_provider_cli_adapter = __esm({
|
|
|
7549
7794
|
this.spawnAt = Date.now();
|
|
7550
7795
|
this.startupParseGate = true;
|
|
7551
7796
|
this.startupBuffer = "";
|
|
7797
|
+
this.terminalScreen.reset(40, 120);
|
|
7552
7798
|
this.ready = true;
|
|
7553
7799
|
this.setStatus("idle", "pty_ready");
|
|
7554
7800
|
this.onStatusChange?.();
|
|
7555
7801
|
}
|
|
7556
|
-
// ─── Output
|
|
7802
|
+
// ─── Output Handling ────────────────────────────
|
|
7557
7803
|
handleOutput(rawData) {
|
|
7558
7804
|
if (Date.now() < this.resizeSuppressUntil) return;
|
|
7805
|
+
this.terminalScreen.write(rawData);
|
|
7559
7806
|
const cleanData = stripAnsi(rawData);
|
|
7560
|
-
|
|
7807
|
+
if (this.isWaitingForResponse && cleanData) {
|
|
7808
|
+
this.responseBuffer = (this.responseBuffer + cleanData).slice(-8e3);
|
|
7809
|
+
}
|
|
7561
7810
|
if (cleanData.trim()) {
|
|
7562
7811
|
if (this.serverConn) {
|
|
7563
7812
|
this.serverConn.sendMessage("log", { message: cleanData.trim(), level: "info" });
|
|
@@ -7566,9 +7815,10 @@ var init_provider_cli_adapter = __esm({
|
|
|
7566
7815
|
}
|
|
7567
7816
|
}
|
|
7568
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);
|
|
7569
7820
|
if (this.startupParseGate) {
|
|
7570
7821
|
this.startupBuffer += cleanData;
|
|
7571
|
-
LOG.info("CLI", `[${this.cliType}] startup chunk (${cleanData.length} chars): ${cleanData.slice(0, 200).replace(/\n/g, "\\n")}`);
|
|
7572
7822
|
const dialogPatterns = [
|
|
7573
7823
|
/Do you want to connect/i,
|
|
7574
7824
|
/Do you trust the files/i,
|
|
@@ -7583,60 +7833,17 @@ var init_provider_cli_adapter = __esm({
|
|
|
7583
7833
|
}
|
|
7584
7834
|
const elapsed = Date.now() - this.spawnAt;
|
|
7585
7835
|
const bufCap = this.startupBuffer.length > 12e3;
|
|
7586
|
-
const
|
|
7587
|
-
|
|
7836
|
+
const scriptStatus = this.runDetectStatus(this.startupBuffer);
|
|
7837
|
+
const isReady = scriptStatus === "idle" || elapsed > 8e3 || bufCap;
|
|
7838
|
+
if (isReady) {
|
|
7588
7839
|
this.startupParseGate = false;
|
|
7589
|
-
|
|
7590
|
-
LOG.info("CLI", `[${this.cliType}] \u2713 Startup gate end (prompt matched)`);
|
|
7591
|
-
} else {
|
|
7592
|
-
LOG.info("CLI", `[${this.cliType}] startup gate end (${elapsed}ms, cap=${bufCap}, prompt=${promptMatched})`);
|
|
7593
|
-
}
|
|
7840
|
+
LOG.info("CLI", `[${this.cliType}] Startup gate end (${elapsed}ms, scriptStatus=${scriptStatus})`);
|
|
7594
7841
|
} else {
|
|
7595
7842
|
return;
|
|
7596
7843
|
}
|
|
7597
7844
|
}
|
|
7598
|
-
if (cleanData.trim().length > 5) {
|
|
7599
|
-
LOG.debug("CLI", `[${this.cliType}] output chunk (${cleanData.length}): ${cleanData.slice(0, 300).replace(/\n/g, "\\n")}`);
|
|
7600
|
-
}
|
|
7601
|
-
if (!this.isWaitingForResponse) {
|
|
7602
|
-
if (patterns.generating.some((p) => p.test(cleanData))) {
|
|
7603
|
-
if (this.settleTimer) {
|
|
7604
|
-
clearTimeout(this.settleTimer);
|
|
7605
|
-
this.settleTimer = null;
|
|
7606
|
-
}
|
|
7607
|
-
this.isWaitingForResponse = true;
|
|
7608
|
-
this.responseBuffer = "";
|
|
7609
|
-
this.setStatus("generating", "autonomous_gen");
|
|
7610
|
-
this.onStatusChange?.();
|
|
7611
|
-
}
|
|
7612
|
-
}
|
|
7613
|
-
if (this.isWaitingForResponse) {
|
|
7614
|
-
this.responseBuffer += cleanData;
|
|
7615
|
-
if (this.idleTimeout) clearTimeout(this.idleTimeout);
|
|
7616
|
-
if (patterns.generating.some((p) => p.test(cleanData))) {
|
|
7617
|
-
this.setStatus("generating", "still_generating");
|
|
7618
|
-
this.idleTimeout = setTimeout(() => {
|
|
7619
|
-
if (this.isWaitingForResponse) this.finishResponse();
|
|
7620
|
-
}, this.timeouts.generatingIdle);
|
|
7621
|
-
this.onStatusChange?.();
|
|
7622
|
-
if (this.settleTimer) {
|
|
7623
|
-
clearTimeout(this.settleTimer);
|
|
7624
|
-
this.settleTimer = null;
|
|
7625
|
-
}
|
|
7626
|
-
return;
|
|
7627
|
-
}
|
|
7628
|
-
}
|
|
7629
|
-
if (this.currentStatus === "waiting_approval") {
|
|
7630
|
-
this.approvalTransitionBuffer = (this.approvalTransitionBuffer + cleanData).slice(-500);
|
|
7631
|
-
this.scheduleSettle();
|
|
7632
|
-
return;
|
|
7633
|
-
}
|
|
7634
7845
|
this.scheduleSettle();
|
|
7635
7846
|
}
|
|
7636
|
-
/**
|
|
7637
|
-
* Fired after output goes quiet for outputSettle ms.
|
|
7638
|
-
* Evaluates the stabilised buffer for approval, prompt (idle), or timeout.
|
|
7639
|
-
*/
|
|
7640
7847
|
scheduleSettle() {
|
|
7641
7848
|
if (this.settleTimer) clearTimeout(this.settleTimer);
|
|
7642
7849
|
this.settleTimer = setTimeout(() => {
|
|
@@ -7646,59 +7853,25 @@ var init_provider_cli_adapter = __esm({
|
|
|
7646
7853
|
}, this.timeouts.outputSettle);
|
|
7647
7854
|
}
|
|
7648
7855
|
evaluateSettled() {
|
|
7649
|
-
const
|
|
7650
|
-
const
|
|
7651
|
-
if (
|
|
7652
|
-
|
|
7653
|
-
|
|
7654
|
-
if (genResume) {
|
|
7655
|
-
if (this.approvalExitTimeout) {
|
|
7656
|
-
clearTimeout(this.approvalExitTimeout);
|
|
7657
|
-
this.approvalExitTimeout = null;
|
|
7658
|
-
}
|
|
7659
|
-
this.setStatus("generating", "approval_gen_resume");
|
|
7660
|
-
this.activeModal = null;
|
|
7661
|
-
this.recentOutputBuffer = "";
|
|
7662
|
-
this.approvalTransitionBuffer = "";
|
|
7663
|
-
this.lastApprovalResolvedAt = Date.now();
|
|
7664
|
-
this.onStatusChange?.();
|
|
7665
|
-
} else if (promptResume) {
|
|
7666
|
-
if (this.approvalExitTimeout) {
|
|
7667
|
-
clearTimeout(this.approvalExitTimeout);
|
|
7668
|
-
this.approvalExitTimeout = null;
|
|
7669
|
-
}
|
|
7670
|
-
this.activeModal = null;
|
|
7671
|
-
this.recentOutputBuffer = "";
|
|
7672
|
-
this.approvalTransitionBuffer = "";
|
|
7673
|
-
this.lastApprovalResolvedAt = Date.now();
|
|
7674
|
-
this.finishResponse();
|
|
7675
|
-
}
|
|
7676
|
-
return;
|
|
7677
|
-
}
|
|
7678
|
-
const hasApproval = patterns.approval.some((p) => p.test(buf));
|
|
7679
|
-
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") {
|
|
7680
7861
|
const inCooldown = this.lastApprovalResolvedAt && Date.now() - this.lastApprovalResolvedAt < this.timeouts.approvalCooldown;
|
|
7681
7862
|
if (!inCooldown) {
|
|
7682
|
-
const ctxLines = buf.split("\n").map((l) => l.trim()).filter((l) => l && !/^[─═╭╮╰╯│]+$/.test(l));
|
|
7683
7863
|
this.isWaitingForResponse = true;
|
|
7684
|
-
this.setStatus("waiting_approval", "
|
|
7685
|
-
|
|
7686
|
-
this.
|
|
7687
|
-
this.activeModal = {
|
|
7688
|
-
message: ctxLines.slice(-5).join(" ").slice(0, 200) || "Approval required",
|
|
7689
|
-
buttons: this.cliType === "claude-cli" ? ["Yes (y)", "Always allow (a)", "Deny (Esc)"] : ["Allow once", "Always allow", "Deny"]
|
|
7690
|
-
};
|
|
7864
|
+
this.setStatus("waiting_approval", "script_detect");
|
|
7865
|
+
const modal = this.runParseApproval(tail);
|
|
7866
|
+
this.activeModal = modal || { message: "Approval required", buttons: ["Allow", "Deny"] };
|
|
7691
7867
|
if (this.idleTimeout) clearTimeout(this.idleTimeout);
|
|
7692
7868
|
if (this.approvalExitTimeout) clearTimeout(this.approvalExitTimeout);
|
|
7693
7869
|
this.approvalExitTimeout = setTimeout(() => {
|
|
7694
7870
|
if (this.currentStatus === "waiting_approval") {
|
|
7695
|
-
LOG.warn("CLI", `[${this.cliType}] Approval timeout \u2014 auto-
|
|
7871
|
+
LOG.warn("CLI", `[${this.cliType}] Approval timeout \u2014 auto-clearing`);
|
|
7696
7872
|
this.activeModal = null;
|
|
7697
7873
|
this.lastApprovalResolvedAt = Date.now();
|
|
7698
|
-
this.
|
|
7699
|
-
this.approvalTransitionBuffer = "";
|
|
7700
|
-
this.approvalExitTimeout = null;
|
|
7701
|
-
this.setStatus(this.isWaitingForResponse ? "generating" : "idle", "approval_cleared");
|
|
7874
|
+
this.setStatus("idle", "approval_timeout");
|
|
7702
7875
|
this.onStatusChange?.();
|
|
7703
7876
|
}
|
|
7704
7877
|
}, 6e4);
|
|
@@ -7706,19 +7879,42 @@ var init_provider_cli_adapter = __esm({
|
|
|
7706
7879
|
return;
|
|
7707
7880
|
}
|
|
7708
7881
|
}
|
|
7709
|
-
if (
|
|
7710
|
-
|
|
7711
|
-
|
|
7712
|
-
|
|
7713
|
-
|
|
7714
|
-
|
|
7715
|
-
this.
|
|
7716
|
-
|
|
7717
|
-
|
|
7718
|
-
|
|
7719
|
-
|
|
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 = "";
|
|
7720
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);
|
|
7721
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
|
+
}
|
|
7722
7918
|
}
|
|
7723
7919
|
}
|
|
7724
7920
|
finishResponse() {
|
|
@@ -7734,25 +7930,50 @@ var init_provider_cli_adapter = __esm({
|
|
|
7734
7930
|
clearTimeout(this.approvalExitTimeout);
|
|
7735
7931
|
this.approvalExitTimeout = null;
|
|
7736
7932
|
}
|
|
7737
|
-
const lastUserText = this.messages.filter((m) => m.role === "user").pop()?.content;
|
|
7738
|
-
let response = this.provider.cleanOutput(this.responseBuffer, lastUserText);
|
|
7739
|
-
if (lastUserText && response) {
|
|
7740
|
-
const userTrimmed = lastUserText.trim();
|
|
7741
|
-
response = response.split("\n").filter((l) => l.trim() !== userTrimmed).join("\n").trim();
|
|
7742
|
-
}
|
|
7743
|
-
if (response) {
|
|
7744
|
-
this.messages.push({ role: "assistant", content: response, timestamp: Date.now() });
|
|
7745
|
-
if (this.messages.length > 200) this.messages = this.messages.slice(-200);
|
|
7746
|
-
LOG.info("CLI", `[${this.cliType}] Response (${response.length} chars)`);
|
|
7747
|
-
}
|
|
7748
7933
|
this.responseBuffer = "";
|
|
7749
7934
|
this.isWaitingForResponse = false;
|
|
7750
7935
|
this.activeModal = null;
|
|
7751
7936
|
this.setStatus("idle", "response_finished");
|
|
7752
7937
|
this.onStatusChange?.();
|
|
7753
7938
|
}
|
|
7754
|
-
// ───
|
|
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) ───────────────────
|
|
7755
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
|
+
}
|
|
7756
7977
|
return {
|
|
7757
7978
|
status: this.currentStatus,
|
|
7758
7979
|
messages: [...this.messages],
|
|
@@ -7760,11 +7981,71 @@ var init_provider_cli_adapter = __esm({
|
|
|
7760
7981
|
activeModal: this.activeModal
|
|
7761
7982
|
};
|
|
7762
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
|
+
}
|
|
7763
8043
|
async sendMessage(text) {
|
|
7764
8044
|
if (!this.ptyProcess) throw new Error(`${this.cliName} is not running`);
|
|
7765
8045
|
if (!this.ready) throw new Error(`${this.cliName} not ready (status: ${this.currentStatus})`);
|
|
7766
8046
|
if (this.isWaitingForResponse) return;
|
|
7767
8047
|
this.messages.push({ role: "user", content: text, timestamp: Date.now() });
|
|
8048
|
+
this.structuredMessages.push({ role: "user", content: text, timestamp: Date.now() });
|
|
7768
8049
|
this.isWaitingForResponse = true;
|
|
7769
8050
|
this.responseBuffer = "";
|
|
7770
8051
|
this.setStatus("generating", "sendMessage");
|
|
@@ -7776,8 +8057,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
7776
8057
|
}
|
|
7777
8058
|
getPartialResponse() {
|
|
7778
8059
|
if (!this.isWaitingForResponse) return "";
|
|
7779
|
-
|
|
7780
|
-
return partial2 || (this.isWaitingForResponse ? "(generating...)" : "");
|
|
8060
|
+
return this.responseBuffer;
|
|
7781
8061
|
}
|
|
7782
8062
|
cancel() {
|
|
7783
8063
|
this.shutdown();
|
|
@@ -7809,6 +8089,10 @@ var init_provider_cli_adapter = __esm({
|
|
|
7809
8089
|
}
|
|
7810
8090
|
clearHistory() {
|
|
7811
8091
|
this.messages = [];
|
|
8092
|
+
this.structuredMessages = [];
|
|
8093
|
+
this.accumulatedBuffer = "";
|
|
8094
|
+
this.accumulatedRawBuffer = "";
|
|
8095
|
+
this.terminalScreen.reset();
|
|
7812
8096
|
this.onStatusChange?.();
|
|
7813
8097
|
}
|
|
7814
8098
|
isProcessing() {
|
|
@@ -7820,11 +8104,6 @@ var init_provider_cli_adapter = __esm({
|
|
|
7820
8104
|
writeRaw(data) {
|
|
7821
8105
|
this.ptyProcess?.write(data);
|
|
7822
8106
|
}
|
|
7823
|
-
/**
|
|
7824
|
-
* Resolve an approval modal by navigating to the button at `buttonIndex` and pressing Enter.
|
|
7825
|
-
* Index 0 = first option (already selected by default — just Enter).
|
|
7826
|
-
* Index N = press Arrow Down N times, then Enter.
|
|
7827
|
-
*/
|
|
7828
8107
|
resolveModal(buttonIndex) {
|
|
7829
8108
|
if (!this.ptyProcess || this.currentStatus !== "waiting_approval") return;
|
|
7830
8109
|
if (buttonIndex in this.approvalKeys) {
|
|
@@ -7839,25 +8118,13 @@ var init_provider_cli_adapter = __esm({
|
|
|
7839
8118
|
if (this.ptyProcess) {
|
|
7840
8119
|
try {
|
|
7841
8120
|
this.ptyProcess.resize(cols, rows);
|
|
8121
|
+
this.terminalScreen.resize(rows, cols);
|
|
7842
8122
|
this.resizeSuppressUntil = Date.now() + 300;
|
|
7843
8123
|
} catch {
|
|
7844
8124
|
}
|
|
7845
8125
|
}
|
|
7846
8126
|
}
|
|
7847
|
-
/**
|
|
7848
|
-
* Full debug state — exposes all internal buffers, status, and patterns for debugging.
|
|
7849
|
-
* Used by DevServer /api/cli/debug endpoint.
|
|
7850
|
-
*/
|
|
7851
8127
|
getDebugState() {
|
|
7852
|
-
const sb = this.startupBuffer;
|
|
7853
|
-
const testOnStartup = (p) => {
|
|
7854
|
-
const flags = p.flags.includes("g") ? p.flags.replace(/g/g, "") : p.flags;
|
|
7855
|
-
return new RegExp(p.source, flags).test(sb);
|
|
7856
|
-
};
|
|
7857
|
-
const promptDiagnostics = this.provider.patterns.prompt.map((p) => ({
|
|
7858
|
-
pattern: p.toString(),
|
|
7859
|
-
matchedAgainstStartupBuffer: testOnStartup(p)
|
|
7860
|
-
}));
|
|
7861
8128
|
return {
|
|
7862
8129
|
type: this.cliType,
|
|
7863
8130
|
name: this.cliName,
|
|
@@ -7867,32 +8134,20 @@ var init_provider_cli_adapter = __esm({
|
|
|
7867
8134
|
spawnAt: this.spawnAt,
|
|
7868
8135
|
workingDir: this.workingDir,
|
|
7869
8136
|
messages: this.messages.slice(-20),
|
|
8137
|
+
structuredMessages: this.structuredMessages.slice(-20),
|
|
7870
8138
|
messageCount: this.messages.length,
|
|
7871
|
-
|
|
7872
|
-
startupBuffer: sb.slice(-4e3),
|
|
7873
|
-
startupBufferLength: sb.length,
|
|
7874
|
-
promptDiagnostics,
|
|
8139
|
+
startupBuffer: this.startupBuffer.slice(-4e3),
|
|
7875
8140
|
recentOutputBuffer: this.recentOutputBuffer.slice(-500),
|
|
7876
8141
|
settledBuffer: this.settledBuffer.slice(-500),
|
|
7877
|
-
|
|
7878
|
-
approvalTransitionBuffer: this.approvalTransitionBuffer.slice(-500),
|
|
7879
|
-
// State
|
|
8142
|
+
accumulatedBufferLength: this.accumulatedBuffer.length,
|
|
7880
8143
|
isWaitingForResponse: this.isWaitingForResponse,
|
|
7881
8144
|
activeModal: this.activeModal,
|
|
7882
8145
|
lastApprovalResolvedAt: this.lastApprovalResolvedAt,
|
|
7883
8146
|
resizeSuppressUntil: this.resizeSuppressUntil,
|
|
7884
|
-
|
|
7885
|
-
|
|
7886
|
-
prompt: this.provider.patterns.prompt.map((p) => p.toString()),
|
|
7887
|
-
generating: this.provider.patterns.generating.map((p) => p.toString()),
|
|
7888
|
-
approval: this.provider.patterns.approval.map((p) => p.toString()),
|
|
7889
|
-
ready: this.provider.patterns.ready.map((p) => p.toString())
|
|
7890
|
-
},
|
|
7891
|
-
// Status history
|
|
8147
|
+
hasCliScripts: this.hasCliScripts(),
|
|
8148
|
+
scriptNames: Object.keys(this.cliScripts).filter((k) => typeof this.cliScripts[k] === "function"),
|
|
7892
8149
|
statusHistory: this.statusHistory.slice(-30),
|
|
7893
|
-
// Timeouts config
|
|
7894
8150
|
timeouts: this.timeouts,
|
|
7895
|
-
// PTY alive
|
|
7896
8151
|
ptyAlive: !!this.ptyProcess
|
|
7897
8152
|
};
|
|
7898
8153
|
}
|
|
@@ -7958,21 +8213,27 @@ var init_cli_provider_instance = __esm({
|
|
|
7958
8213
|
async onTick() {
|
|
7959
8214
|
}
|
|
7960
8215
|
getState() {
|
|
7961
|
-
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;
|
|
7962
8223
|
const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
|
|
7963
|
-
const recentMessages = adapterStatus.messages.slice(-50).map((m) =>
|
|
7964
|
-
|
|
7965
|
-
|
|
7966
|
-
|
|
7967
|
-
}));
|
|
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
|
+
});
|
|
7968
8228
|
const partial2 = this.adapter.getPartialResponse();
|
|
7969
8229
|
if (adapterStatus.status === "generating" && partial2) {
|
|
7970
8230
|
const cleaned = partial2.trim();
|
|
7971
8231
|
if (cleaned && cleaned !== "(generating...)") {
|
|
7972
8232
|
recentMessages.push({
|
|
7973
8233
|
role: "assistant",
|
|
7974
|
-
content: (cleaned.length >
|
|
7975
|
-
timestamp: Date.now()
|
|
8234
|
+
content: (cleaned.length > 8e3 ? cleaned.slice(0, 8e3) + "..." : cleaned) + "...",
|
|
8235
|
+
timestamp: Date.now(),
|
|
8236
|
+
meta: { streaming: true }
|
|
7976
8237
|
});
|
|
7977
8238
|
}
|
|
7978
8239
|
}
|
|
@@ -8011,6 +8272,8 @@ var init_cli_provider_instance = __esm({
|
|
|
8011
8272
|
this.adapter.sendMessage(data.text);
|
|
8012
8273
|
} else if (event === "server_connected" && data?.serverConn) {
|
|
8013
8274
|
this.adapter.setServerConn(data.serverConn);
|
|
8275
|
+
} else if (event === "resolve_action" && data) {
|
|
8276
|
+
this.adapter.resolveAction(data);
|
|
8014
8277
|
}
|
|
8015
8278
|
}
|
|
8016
8279
|
dispose() {
|
|
@@ -25397,7 +25660,8 @@ var init_cli_manager = __esm({
|
|
|
25397
25660
|
const provider = this.providerLoader.getMeta(normalizedType);
|
|
25398
25661
|
if (provider && provider.category === "cli" && provider.patterns && provider.spawn) {
|
|
25399
25662
|
console.log(import_chalk.default.cyan(` \u{1F4E6} Using provider: ${provider.name} (${provider.type})`));
|
|
25400
|
-
|
|
25663
|
+
const resolvedProvider = this.providerLoader.resolve(normalizedType) || provider;
|
|
25664
|
+
return new ProviderCliAdapter(resolvedProvider, workingDir, cliArgs);
|
|
25401
25665
|
}
|
|
25402
25666
|
throw new Error(`No CLI provider found for '${cliType}'. Create a provider.js in providers/cli/${cliType}/`);
|
|
25403
25667
|
}
|
|
@@ -25482,7 +25746,8 @@ ${installInfo}`
|
|
|
25482
25746
|
}
|
|
25483
25747
|
const instanceManager = this.deps.getInstanceManager();
|
|
25484
25748
|
if (provider && instanceManager) {
|
|
25485
|
-
const
|
|
25749
|
+
const resolvedProvider = this.providerLoader.resolve(cliType, { version: cliInfo.version }) || provider;
|
|
25750
|
+
const cliInstance = new CliProviderInstance(resolvedProvider, resolvedDir, cliArgs, key);
|
|
25486
25751
|
try {
|
|
25487
25752
|
await instanceManager.addInstance(key, cliInstance, {
|
|
25488
25753
|
serverConn: this.deps.getServerConn(),
|
|
@@ -28747,6 +29012,46 @@ var init_dev_server = __esm({
|
|
|
28747
29012
|
}
|
|
28748
29013
|
}
|
|
28749
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
|
+
}
|
|
28750
29055
|
async handleAutoImplement(type, req, res) {
|
|
28751
29056
|
const body = await this.readBody(req);
|
|
28752
29057
|
const { agent = "claude-cli", functions, reference = "antigravity", model, comment } = body;
|
|
@@ -28769,36 +29074,26 @@ var init_dev_server = __esm({
|
|
|
28769
29074
|
return;
|
|
28770
29075
|
}
|
|
28771
29076
|
try {
|
|
28772
|
-
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
|
+
});
|
|
28773
29086
|
const domContext = null;
|
|
28774
|
-
this.sendAutoImplSSE({
|
|
28775
|
-
|
|
28776
|
-
|
|
28777
|
-
|
|
28778
|
-
|
|
28779
|
-
|
|
28780
|
-
if (fs9.existsSync(scriptsDir)) {
|
|
28781
|
-
const versions = fs9.readdirSync(scriptsDir).filter((d) => {
|
|
28782
|
-
try {
|
|
28783
|
-
return fs9.statSync(path12.join(scriptsDir, d)).isDirectory();
|
|
28784
|
-
} catch {
|
|
28785
|
-
return false;
|
|
28786
|
-
}
|
|
28787
|
-
}).sort().reverse();
|
|
28788
|
-
if (versions.length > 0) {
|
|
28789
|
-
const latestDir = path12.join(scriptsDir, versions[0]);
|
|
28790
|
-
for (const file2 of fs9.readdirSync(latestDir)) {
|
|
28791
|
-
if (file2.endsWith(".js")) {
|
|
28792
|
-
try {
|
|
28793
|
-
referenceScripts[file2] = fs9.readFileSync(path12.join(latestDir, file2), "utf-8");
|
|
28794
|
-
} catch {
|
|
28795
|
-
}
|
|
28796
|
-
}
|
|
28797
|
-
}
|
|
28798
|
-
}
|
|
29087
|
+
this.sendAutoImplSSE({
|
|
29088
|
+
event: "progress",
|
|
29089
|
+
data: {
|
|
29090
|
+
function: "_init",
|
|
29091
|
+
status: "loading_reference",
|
|
29092
|
+
message: `Loading reference script (${resolvedReference || "none"})...`
|
|
28799
29093
|
}
|
|
28800
|
-
}
|
|
28801
|
-
const
|
|
29094
|
+
});
|
|
29095
|
+
const referenceScripts = this.loadAutoImplReferenceScripts(provider.category, resolvedReference);
|
|
29096
|
+
const prompt = this.buildAutoImplPrompt(type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference);
|
|
28802
29097
|
const tmpDir = path12.join(os14.tmpdir(), "adhdev-autoimpl");
|
|
28803
29098
|
if (!fs9.existsSync(tmpDir)) fs9.mkdirSync(tmpDir, { recursive: true });
|
|
28804
29099
|
const promptFile = path12.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
|
|
@@ -28816,7 +29111,7 @@ var init_dev_server = __esm({
|
|
|
28816
29111
|
}
|
|
28817
29112
|
const agentCategory = agentProvider?.category;
|
|
28818
29113
|
if (agentCategory === "acp") {
|
|
28819
|
-
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(" ")}` } });
|
|
28820
29115
|
this.autoImplStatus = { running: true, type, progress: [] };
|
|
28821
29116
|
const { ClientSideConnection: ClientSideConnection2, ndJsonStream: ndJsonStream2, PROTOCOL_VERSION: PROTOCOL_VERSION2 } = await Promise.resolve().then(() => (init_acp(), acp_exports));
|
|
28822
29117
|
const { Readable: Readable2, Writable: Writable2 } = await import("stream");
|
|
@@ -28903,7 +29198,7 @@ var init_dev_server = __esm({
|
|
|
28903
29198
|
this.autoImplProcess = null;
|
|
28904
29199
|
this.autoImplStatus.running = false;
|
|
28905
29200
|
const success2 = code === 0;
|
|
28906
|
-
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})` } });
|
|
28907
29202
|
try {
|
|
28908
29203
|
this.providerLoader.reload();
|
|
28909
29204
|
} catch {
|
|
@@ -28918,16 +29213,16 @@ var init_dev_server = __esm({
|
|
|
28918
29213
|
try {
|
|
28919
29214
|
this.sendAutoImplSSE({ event: "progress", data: { function: "_init", status: "initializing", message: "ACP initialize..." } });
|
|
28920
29215
|
await connection.initialize({ protocolVersion: PROTOCOL_VERSION2, clientCapabilities: {} });
|
|
28921
|
-
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..." } });
|
|
28922
29217
|
const session = await connection.newSession({ cwd: providerDir, mcpServers: [] });
|
|
28923
29218
|
const sessionId = session?.sessionId;
|
|
28924
29219
|
if (!sessionId) throw new Error("No sessionId returned from session/new");
|
|
28925
|
-
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)...` } });
|
|
28926
29221
|
await connection.prompt({
|
|
28927
29222
|
sessionId,
|
|
28928
29223
|
prompt: [{ type: "text", text: prompt }]
|
|
28929
29224
|
});
|
|
28930
|
-
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" } });
|
|
28931
29226
|
} catch (e) {
|
|
28932
29227
|
this.sendAutoImplSSE({ event: "output", data: { chunk: `[ACP Error] ${e.message}
|
|
28933
29228
|
`, stream: "stderr" } });
|
|
@@ -28979,7 +29274,7 @@ var init_dev_server = __esm({
|
|
|
28979
29274
|
const escapedArgs = baseArgs.map((a) => `'${a.replace(/'/g, "'\\''")}'`).join(" ");
|
|
28980
29275
|
shellCmd = `cat '${promptFile}' | ${command} ${escapedArgs}`;
|
|
28981
29276
|
}
|
|
28982
|
-
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)` } });
|
|
28983
29278
|
this.autoImplStatus = { running: true, type, progress: [] };
|
|
28984
29279
|
const spawnedAt = Date.now();
|
|
28985
29280
|
let child;
|
|
@@ -29075,7 +29370,7 @@ var init_dev_server = __esm({
|
|
|
29075
29370
|
const success2 = code === 0;
|
|
29076
29371
|
this.sendAutoImplSSE({
|
|
29077
29372
|
event: "complete",
|
|
29078
|
-
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})` }
|
|
29079
29374
|
});
|
|
29080
29375
|
try {
|
|
29081
29376
|
this.providerLoader.reload();
|
|
@@ -29110,7 +29405,7 @@ var init_dev_server = __esm({
|
|
|
29110
29405
|
success: success2,
|
|
29111
29406
|
exitCode: code,
|
|
29112
29407
|
functions,
|
|
29113
|
-
message: success2 ? "\u2705 Auto-implement
|
|
29408
|
+
message: success2 ? "\u2705 Auto-implement complete" : `\u274C Agent exited (code: ${code})`
|
|
29114
29409
|
}
|
|
29115
29410
|
});
|
|
29116
29411
|
try {
|
|
@@ -29138,7 +29433,10 @@ var init_dev_server = __esm({
|
|
|
29138
29433
|
this.json(res, 500, { error: `Auto-implement failed: ${e.message}` });
|
|
29139
29434
|
}
|
|
29140
29435
|
}
|
|
29141
|
-
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
|
+
}
|
|
29142
29440
|
const lines = [];
|
|
29143
29441
|
lines.push("You are implementing browser automation scripts for an IDE provider.");
|
|
29144
29442
|
lines.push("Be concise. Do NOT explain your reasoning. Just edit files directly.");
|
|
@@ -29201,7 +29499,7 @@ var init_dev_server = __esm({
|
|
|
29201
29499
|
setMode: "set_mode.js"
|
|
29202
29500
|
};
|
|
29203
29501
|
if (Object.keys(referenceScripts).length > 0) {
|
|
29204
|
-
lines.push(
|
|
29502
|
+
lines.push(`## Reference Implementation (from ${referenceType || "antigravity"} provider)`);
|
|
29205
29503
|
lines.push("These are WORKING scripts from another IDE. Adapt the PATTERNS (not selectors) for the target IDE.");
|
|
29206
29504
|
lines.push("");
|
|
29207
29505
|
for (const fn of functions) {
|
|
@@ -29350,6 +29648,150 @@ var init_dev_server = __esm({
|
|
|
29350
29648
|
lines.push("Start NOW. Do not ask for permission. Explore the DOM -> Code -> Test.");
|
|
29351
29649
|
return lines.join("\n");
|
|
29352
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
|
+
}
|
|
29353
29795
|
handleAutoImplSSE(type, req, res) {
|
|
29354
29796
|
res.writeHead(200, {
|
|
29355
29797
|
"Content-Type": "text/event-stream",
|
|
@@ -29377,7 +29819,7 @@ data: ${JSON.stringify(p.data)}
|
|
|
29377
29819
|
setTimeout(() => {
|
|
29378
29820
|
if (this.autoImplProcess) this.autoImplProcess.kill("SIGKILL");
|
|
29379
29821
|
}, 3e3);
|
|
29380
|
-
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" } });
|
|
29381
29823
|
this.autoImplProcess = null;
|
|
29382
29824
|
this.autoImplStatus.running = false;
|
|
29383
29825
|
this.json(res, 200, { cancelled: true });
|
|
@@ -31189,11 +31631,12 @@ ${e?.stack || ""}`);
|
|
|
31189
31631
|
});
|
|
31190
31632
|
|
|
31191
31633
|
// src/screenshot-controller.ts
|
|
31192
|
-
var ScreenshotController;
|
|
31634
|
+
var import_sharp, ScreenshotController;
|
|
31193
31635
|
var init_screenshot_controller = __esm({
|
|
31194
31636
|
"src/screenshot-controller.ts"() {
|
|
31195
31637
|
"use strict";
|
|
31196
31638
|
init_src();
|
|
31639
|
+
import_sharp = __toESM(require("sharp"));
|
|
31197
31640
|
ScreenshotController = class _ScreenshotController {
|
|
31198
31641
|
deps;
|
|
31199
31642
|
timer = null;
|
|
@@ -31220,12 +31663,16 @@ var init_screenshot_controller = __esm({
|
|
|
31220
31663
|
this.profileDirect = {
|
|
31221
31664
|
minInterval: Math.max(300, planMinIntervalMs),
|
|
31222
31665
|
maxInterval: Math.max(2e3, planMinIntervalMs),
|
|
31223
|
-
quality: 25
|
|
31666
|
+
quality: 25,
|
|
31667
|
+
maxLongEdge: 1728,
|
|
31668
|
+
firstFrameLongEdge: 1920
|
|
31224
31669
|
};
|
|
31225
31670
|
this.profileRelay = {
|
|
31226
31671
|
minInterval: Math.max(700, planMinIntervalMs),
|
|
31227
31672
|
maxInterval: Math.max(3e3, planMinIntervalMs),
|
|
31228
|
-
quality: 12
|
|
31673
|
+
quality: 12,
|
|
31674
|
+
maxLongEdge: 1152,
|
|
31675
|
+
firstFrameLongEdge: 1280
|
|
31229
31676
|
};
|
|
31230
31677
|
this.currentInterval = this.profileDirect.maxInterval;
|
|
31231
31678
|
this.dailyBudgetMinutes = planLimits?.dailyScreenshotMinutes ?? -1;
|
|
@@ -31298,6 +31745,7 @@ var init_screenshot_controller = __esm({
|
|
|
31298
31745
|
const sizeMatch = buf.length === this.lastSize;
|
|
31299
31746
|
const hashMatch = hash2 === this.lastHash;
|
|
31300
31747
|
const anyNeedsFirstFrame = this.deps.hasAnyNeedingFirstFrame();
|
|
31748
|
+
const resizeTarget = anyNeedsFirstFrame ? profile.firstFrameLongEdge : profile.maxLongEdge;
|
|
31301
31749
|
if (sizeMatch && hashMatch && !anyNeedsFirstFrame) {
|
|
31302
31750
|
this.staticFrameCount++;
|
|
31303
31751
|
if (this.staticFrameCount >= this.STATIC_THRESHOLD) {
|
|
@@ -31307,13 +31755,14 @@ var init_screenshot_controller = __esm({
|
|
|
31307
31755
|
LOG.debug("Screenshot", `skip (unchanged, static=${this.staticFrameCount}, interval=${this.currentInterval}ms, ${isRelay ? "RELAY" : "DIRECT"})`);
|
|
31308
31756
|
}
|
|
31309
31757
|
} else {
|
|
31758
|
+
const normalizedBuf = await this.normalizeBuffer(buf, resizeTarget, profile.quality);
|
|
31310
31759
|
this.lastSize = buf.length;
|
|
31311
31760
|
this.lastHash = hash2;
|
|
31312
31761
|
this.staticFrameCount = 0;
|
|
31313
31762
|
this.currentInterval = profile.minInterval;
|
|
31314
|
-
const sent = this.deps.sendScreenshotBuffer(
|
|
31763
|
+
const sent = this.deps.sendScreenshotBuffer(normalizedBuf);
|
|
31315
31764
|
if (this.debugCount <= 3 || anyNeedsFirstFrame) {
|
|
31316
|
-
LOG.debug("Screenshot", `sent: ${
|
|
31765
|
+
LOG.debug("Screenshot", `sent: ${normalizedBuf.length} bytes, delivered=${sent}, interval=${this.currentInterval}ms, ${isRelay ? "RELAY" : "DIRECT"}${anyNeedsFirstFrame ? " (first-frame)" : ""}`);
|
|
31317
31766
|
}
|
|
31318
31767
|
}
|
|
31319
31768
|
} else {
|
|
@@ -31361,6 +31810,28 @@ var init_screenshot_controller = __esm({
|
|
|
31361
31810
|
}
|
|
31362
31811
|
return h;
|
|
31363
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
|
+
}
|
|
31364
31835
|
};
|
|
31365
31836
|
}
|
|
31366
31837
|
});
|
|
@@ -31423,7 +31894,7 @@ var init_adhdev_daemon = __esm({
|
|
|
31423
31894
|
fs11 = __toESM(require("fs"));
|
|
31424
31895
|
path14 = __toESM(require("path"));
|
|
31425
31896
|
import_chalk2 = __toESM(require("chalk"));
|
|
31426
|
-
pkgVersion = "0.6.
|
|
31897
|
+
pkgVersion = "0.6.55";
|
|
31427
31898
|
if (pkgVersion === "unknown") {
|
|
31428
31899
|
try {
|
|
31429
31900
|
const possiblePaths = [
|
|
@@ -32824,6 +33295,42 @@ function registerDaemonCommands(program2, pkgVersion3) {
|
|
|
32824
33295
|
// src/cli/provider-commands.ts
|
|
32825
33296
|
var import_chalk6 = __toESM(require("chalk"));
|
|
32826
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
|
+
}
|
|
32827
33334
|
function hideCommand2(command) {
|
|
32828
33335
|
command.hideHelp?.();
|
|
32829
33336
|
return command;
|
|
@@ -33098,7 +33605,7 @@ function registerProviderCommands(program2) {
|
|
|
33098
33605
|
process.exit(1);
|
|
33099
33606
|
}
|
|
33100
33607
|
});
|
|
33101
|
-
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) => {
|
|
33102
33609
|
try {
|
|
33103
33610
|
const http3 = await import("http");
|
|
33104
33611
|
const inquirer2 = (await import("inquirer")).default;
|
|
@@ -33113,17 +33620,17 @@ function registerProviderCommands(program2) {
|
|
|
33113
33620
|
};
|
|
33114
33621
|
let type = typeArg;
|
|
33115
33622
|
if (!type) {
|
|
33116
|
-
const
|
|
33117
|
-
if (
|
|
33118
|
-
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"));
|
|
33119
33626
|
process.exit(1);
|
|
33120
33627
|
}
|
|
33121
33628
|
const typeAnswer = await inquirer2.prompt([{
|
|
33122
33629
|
type: "list",
|
|
33123
33630
|
name: "selected",
|
|
33124
|
-
message: "Select the
|
|
33125
|
-
choices:
|
|
33126
|
-
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]")}`,
|
|
33127
33634
|
value: p.type
|
|
33128
33635
|
}))
|
|
33129
33636
|
}]);
|
|
@@ -33134,6 +33641,18 @@ function registerProviderCommands(program2) {
|
|
|
33134
33641
|
process.exit(1);
|
|
33135
33642
|
}
|
|
33136
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
|
+
}
|
|
33137
33656
|
if (providerToFix && !isUserProvider(providerToFix)) {
|
|
33138
33657
|
console.log(import_chalk6.default.yellow(`
|
|
33139
33658
|
\u26A0\uFE0F [${type}] is an upstream provider.`));
|
|
@@ -33194,7 +33713,7 @@ function registerProviderCommands(program2) {
|
|
|
33194
33713
|
}
|
|
33195
33714
|
let agentName = options.agent || "codex-cli";
|
|
33196
33715
|
const modelName = options.model;
|
|
33197
|
-
const reference = options.reference ||
|
|
33716
|
+
const reference = options.reference || getDefaultAutoFixReference(providerToFix.category, type, allProviders);
|
|
33198
33717
|
if (!typeArg && agentName === "codex-cli") {
|
|
33199
33718
|
const agentAnswer = await inquirer2.prompt([{
|
|
33200
33719
|
type: "list",
|
|
@@ -33211,23 +33730,20 @@ function registerProviderCommands(program2) {
|
|
|
33211
33730
|
}
|
|
33212
33731
|
console.log(import_chalk6.default.bold(`
|
|
33213
33732
|
\u{1F916} Starting Auto-Implement Agent for [${import_chalk6.default.cyan(type)}]`));
|
|
33214
|
-
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}
|
|
33215
33734
|
`));
|
|
33216
|
-
const allFunctions =
|
|
33217
|
-
"openPanel",
|
|
33218
|
-
"sendMessage",
|
|
33219
|
-
"readChat",
|
|
33220
|
-
"newSession",
|
|
33221
|
-
"listSessions",
|
|
33222
|
-
"switchSession",
|
|
33223
|
-
"resolveAction",
|
|
33224
|
-
"listModels",
|
|
33225
|
-
"setModel",
|
|
33226
|
-
"listModes",
|
|
33227
|
-
"setMode",
|
|
33228
|
-
"focusEditor"
|
|
33229
|
-
];
|
|
33735
|
+
const allFunctions = getAutoFixFunctions(providerToFix.category);
|
|
33230
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
|
+
}
|
|
33231
33747
|
if (!scripts || scripts.length === 0) {
|
|
33232
33748
|
const inquirer3 = (await import("inquirer")).default;
|
|
33233
33749
|
const answer = await inquirer3.prompt([{
|
|
@@ -33302,7 +33818,8 @@ function registerProviderCommands(program2) {
|
|
|
33302
33818
|
const loader2 = new ProviderLoader3();
|
|
33303
33819
|
loader2.loadAll();
|
|
33304
33820
|
const providerMeta = loader2.getMeta(type);
|
|
33305
|
-
|
|
33821
|
+
if (!providerMeta) throw new Error(`Unknown provider: ${type}`);
|
|
33822
|
+
const targetDir = loader2.getUserProviderDir(providerMeta.category, type);
|
|
33306
33823
|
const fsMock = await import("fs");
|
|
33307
33824
|
const logFile2 = pathMod.join(targetDir, `auto-impl.log`);
|
|
33308
33825
|
fsMock.writeFileSync(logFile2, `=== Auto-Impl Started ===
|
|
@@ -33486,17 +34003,13 @@ function registerProviderCommands(program2) {
|
|
|
33486
34003
|
const loader = new ProviderLoader2();
|
|
33487
34004
|
loader.loadAll();
|
|
33488
34005
|
const providerMeta = loader.getMeta(type);
|
|
34006
|
+
if (!providerMeta) {
|
|
34007
|
+
return { error: `Provider '${type}' not found` };
|
|
34008
|
+
}
|
|
33489
34009
|
const possiblePaths = [
|
|
33490
|
-
|
|
33491
|
-
|
|
33492
|
-
|
|
33493
|
-
pathMod.join(loader.getBuiltinProviderDir(providerMeta.category, type), "provider.js")
|
|
33494
|
-
] : [],
|
|
33495
|
-
pathMod.join(loader.getUserDir(), type, "provider.js"),
|
|
33496
|
-
pathMod.join(loader.getUpstreamDir(), "ide", type, "provider.js"),
|
|
33497
|
-
pathMod.join(loader.getUpstreamDir(), "extension", type, "provider.js"),
|
|
33498
|
-
pathMod.join(loader.getPrimaryBuiltinDir(), "ide", type, "provider.js"),
|
|
33499
|
-
pathMod.join(loader.getPrimaryBuiltinDir(), "extension", type, "provider.js")
|
|
34010
|
+
pathMod.join(loader.getUserProviderDir(providerMeta.category, type), "provider.js"),
|
|
34011
|
+
pathMod.join(loader.getUpstreamProviderDir(providerMeta.category, type), "provider.js"),
|
|
34012
|
+
pathMod.join(loader.getBuiltinProviderDir(providerMeta.category, type), "provider.js")
|
|
33500
34013
|
];
|
|
33501
34014
|
for (const p of possiblePaths) {
|
|
33502
34015
|
if (fsMod.existsSync(p)) {
|