@adhdev/daemon-core 0.5.62 → 0.5.63
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/index.d.ts +11 -1
- package/dist/index.js +93 -66
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/providers/_builtin/cli/claude-cli/provider.json +4 -1
- package/providers/_builtin/registry.json +1 -1
- package/src/cli-adapters/provider-cli-adapter.ts +103 -71
- package/src/providers/extension-provider-instance.ts +9 -18
package/dist/index.d.ts
CHANGED
|
@@ -2484,7 +2484,7 @@ declare const DAEMON_WS_PATH = "/ipc";
|
|
|
2484
2484
|
* binary: string — binary name
|
|
2485
2485
|
* spawn: { command, args, shell, env }
|
|
2486
2486
|
* patterns: { prompt, generating, approval, ready }
|
|
2487
|
-
* timeouts?: { idleFinish, generatingIdle, maxResponse, approvalCooldown, ... }
|
|
2487
|
+
* timeouts?: { idleFinish, generatingIdle, maxResponse, approvalCooldown, outputSettle, ... }
|
|
2488
2488
|
* cleanOutput(raw, lastUserInput): string
|
|
2489
2489
|
*/
|
|
2490
2490
|
|
|
@@ -2534,6 +2534,8 @@ interface CliProviderModule {
|
|
|
2534
2534
|
maxResponse?: number;
|
|
2535
2535
|
/** shutdown after kill wait (default 1000ms) */
|
|
2536
2536
|
shutdownGrace?: number;
|
|
2537
|
+
/** Output settle debounce before evaluating idle/approval (default 300ms) */
|
|
2538
|
+
outputSettle?: number;
|
|
2537
2539
|
};
|
|
2538
2540
|
cleanOutput(raw: string, lastUserInput?: string): string;
|
|
2539
2541
|
}
|
|
@@ -2563,6 +2565,8 @@ declare class ProviderCliAdapter implements CliAdapter {
|
|
|
2563
2565
|
private lastApprovalResolvedAt;
|
|
2564
2566
|
private approvalTransitionBuffer;
|
|
2565
2567
|
private approvalExitTimeout;
|
|
2568
|
+
private settleTimer;
|
|
2569
|
+
private settledBuffer;
|
|
2566
2570
|
private resizeSuppressUntil;
|
|
2567
2571
|
private statusHistory;
|
|
2568
2572
|
private setStatus;
|
|
@@ -2574,6 +2578,12 @@ declare class ProviderCliAdapter implements CliAdapter {
|
|
|
2574
2578
|
setOnPtyData(callback: (data: string) => void): void;
|
|
2575
2579
|
spawn(): Promise<void>;
|
|
2576
2580
|
private handleOutput;
|
|
2581
|
+
/**
|
|
2582
|
+
* Fired after output goes quiet for outputSettle ms.
|
|
2583
|
+
* Evaluates the stabilised buffer for approval, prompt (idle), or timeout.
|
|
2584
|
+
*/
|
|
2585
|
+
private scheduleSettle;
|
|
2586
|
+
private evaluateSettled;
|
|
2577
2587
|
private finishResponse;
|
|
2578
2588
|
getStatus(): CliSessionStatus;
|
|
2579
2589
|
sendMessage(text: string): Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -2236,29 +2236,18 @@ var ExtensionProviderInstance = class {
|
|
|
2236
2236
|
return this.instanceId;
|
|
2237
2237
|
}
|
|
2238
2238
|
// ─── status transition detect ──────────────────────────────
|
|
2239
|
-
|
|
2239
|
+
// NOTE: Extension transitions are TRACKED but NOT emitted as events.
|
|
2240
|
+
// The parent IdeProviderInstance already emits identical events
|
|
2241
|
+
// (generating_started, generating_completed, waiting_approval)
|
|
2242
|
+
// via its own detectAgentTransitions(). Emitting here would cause
|
|
2243
|
+
// duplicate toasts with slightly different content.
|
|
2244
|
+
detectTransition(newStatus, _data) {
|
|
2240
2245
|
const now = Date.now();
|
|
2241
2246
|
const agentStatus = newStatus === "streaming" || newStatus === "generating" ? "generating" : newStatus === "waiting_approval" ? "waiting_approval" : "idle";
|
|
2242
2247
|
if (agentStatus !== this.lastAgentStatus) {
|
|
2243
|
-
const chatTitle = this.provider.name;
|
|
2244
2248
|
if (this.lastAgentStatus === "idle" && agentStatus === "generating") {
|
|
2245
2249
|
this.generatingStartedAt = now;
|
|
2246
|
-
this.pushEvent({ event: "agent:generating_started", chatTitle, timestamp: now });
|
|
2247
|
-
} else if (agentStatus === "waiting_approval") {
|
|
2248
|
-
if (!this.generatingStartedAt) this.generatingStartedAt = now;
|
|
2249
|
-
const msg = data?.activeModal?.message || data?.modalMessage;
|
|
2250
|
-
this.pushEvent({
|
|
2251
|
-
event: "agent:waiting_approval",
|
|
2252
|
-
chatTitle,
|
|
2253
|
-
timestamp: now,
|
|
2254
|
-
ideType: this.ideType,
|
|
2255
|
-
agentType: this.type,
|
|
2256
|
-
modalMessage: msg,
|
|
2257
|
-
modalButtons: data?.activeModal?.buttons || data?.modalButtons
|
|
2258
|
-
});
|
|
2259
2250
|
} else if (agentStatus === "idle" && (this.lastAgentStatus === "generating" || this.lastAgentStatus === "waiting_approval")) {
|
|
2260
|
-
const duration = this.generatingStartedAt ? Math.round((now - this.generatingStartedAt) / 1e3) : 0;
|
|
2261
|
-
this.pushEvent({ event: "agent:generating_completed", chatTitle, duration, timestamp: now });
|
|
2262
2251
|
this.generatingStartedAt = 0;
|
|
2263
2252
|
}
|
|
2264
2253
|
this.lastAgentStatus = agentStatus;
|
|
@@ -7039,7 +7028,8 @@ var ProviderCliAdapter = class {
|
|
|
7039
7028
|
generatingIdle: t.generatingIdle ?? 6e3,
|
|
7040
7029
|
idleFinish: t.idleFinish ?? 5e3,
|
|
7041
7030
|
maxResponse: t.maxResponse ?? 3e5,
|
|
7042
|
-
shutdownGrace: t.shutdownGrace ?? 1e3
|
|
7031
|
+
shutdownGrace: t.shutdownGrace ?? 1e3,
|
|
7032
|
+
outputSettle: t.outputSettle ?? 300
|
|
7043
7033
|
};
|
|
7044
7034
|
const rawKeys = provider.approvalKeys;
|
|
7045
7035
|
this.approvalKeys = rawKeys && typeof rawKeys === "object" ? rawKeys : {};
|
|
@@ -7072,6 +7062,10 @@ var ProviderCliAdapter = class {
|
|
|
7072
7062
|
// Approval state machine
|
|
7073
7063
|
approvalTransitionBuffer = "";
|
|
7074
7064
|
approvalExitTimeout = null;
|
|
7065
|
+
// Output settle debounce — fires after PTY output goes quiet
|
|
7066
|
+
settleTimer = null;
|
|
7067
|
+
settledBuffer = "";
|
|
7068
|
+
// snapshot of recentOutputBuffer at settle time
|
|
7075
7069
|
// Resize redraw suppression
|
|
7076
7070
|
resizeSuppressUntil = 0;
|
|
7077
7071
|
// Debug: status transition history
|
|
@@ -7213,39 +7207,57 @@ var ProviderCliAdapter = class {
|
|
|
7213
7207
|
if (cleanData.trim().length > 5) {
|
|
7214
7208
|
LOG.debug("CLI", `[${this.cliType}] output chunk (${cleanData.length}): ${cleanData.slice(0, 300).replace(/\n/g, "\\n")}`);
|
|
7215
7209
|
}
|
|
7216
|
-
|
|
7217
|
-
|
|
7218
|
-
|
|
7219
|
-
|
|
7220
|
-
|
|
7210
|
+
if (!this.isWaitingForResponse) {
|
|
7211
|
+
if (patterns.generating.some((p) => p.test(cleanData))) {
|
|
7212
|
+
if (this.settleTimer) {
|
|
7213
|
+
clearTimeout(this.settleTimer);
|
|
7214
|
+
this.settleTimer = null;
|
|
7215
|
+
}
|
|
7221
7216
|
this.isWaitingForResponse = true;
|
|
7222
|
-
this.
|
|
7223
|
-
this.
|
|
7224
|
-
this.
|
|
7225
|
-
|
|
7226
|
-
|
|
7227
|
-
|
|
7228
|
-
|
|
7229
|
-
|
|
7230
|
-
|
|
7231
|
-
this.
|
|
7232
|
-
|
|
7233
|
-
|
|
7234
|
-
|
|
7235
|
-
this.lastApprovalResolvedAt = Date.now();
|
|
7236
|
-
this.recentOutputBuffer = "";
|
|
7237
|
-
this.approvalTransitionBuffer = "";
|
|
7238
|
-
this.approvalExitTimeout = null;
|
|
7239
|
-
this.setStatus(this.isWaitingForResponse ? "generating" : "idle", "approval_cleared");
|
|
7240
|
-
this.onStatusChange?.();
|
|
7241
|
-
}
|
|
7242
|
-
}, 6e4);
|
|
7217
|
+
this.responseBuffer = "";
|
|
7218
|
+
this.setStatus("generating", "autonomous_gen");
|
|
7219
|
+
this.onStatusChange?.();
|
|
7220
|
+
}
|
|
7221
|
+
}
|
|
7222
|
+
if (this.isWaitingForResponse) {
|
|
7223
|
+
this.responseBuffer += cleanData;
|
|
7224
|
+
if (this.idleTimeout) clearTimeout(this.idleTimeout);
|
|
7225
|
+
if (patterns.generating.some((p) => p.test(cleanData))) {
|
|
7226
|
+
this.setStatus("generating", "still_generating");
|
|
7227
|
+
this.idleTimeout = setTimeout(() => {
|
|
7228
|
+
if (this.isWaitingForResponse) this.finishResponse();
|
|
7229
|
+
}, this.timeouts.generatingIdle);
|
|
7243
7230
|
this.onStatusChange?.();
|
|
7231
|
+
if (this.settleTimer) {
|
|
7232
|
+
clearTimeout(this.settleTimer);
|
|
7233
|
+
this.settleTimer = null;
|
|
7234
|
+
}
|
|
7244
7235
|
return;
|
|
7245
7236
|
}
|
|
7246
7237
|
}
|
|
7247
7238
|
if (this.currentStatus === "waiting_approval") {
|
|
7248
7239
|
this.approvalTransitionBuffer = (this.approvalTransitionBuffer + cleanData).slice(-500);
|
|
7240
|
+
this.scheduleSettle();
|
|
7241
|
+
return;
|
|
7242
|
+
}
|
|
7243
|
+
this.scheduleSettle();
|
|
7244
|
+
}
|
|
7245
|
+
/**
|
|
7246
|
+
* Fired after output goes quiet for outputSettle ms.
|
|
7247
|
+
* Evaluates the stabilised buffer for approval, prompt (idle), or timeout.
|
|
7248
|
+
*/
|
|
7249
|
+
scheduleSettle() {
|
|
7250
|
+
if (this.settleTimer) clearTimeout(this.settleTimer);
|
|
7251
|
+
this.settleTimer = setTimeout(() => {
|
|
7252
|
+
this.settleTimer = null;
|
|
7253
|
+
this.settledBuffer = this.recentOutputBuffer;
|
|
7254
|
+
this.evaluateSettled();
|
|
7255
|
+
}, this.timeouts.outputSettle);
|
|
7256
|
+
}
|
|
7257
|
+
evaluateSettled() {
|
|
7258
|
+
const { patterns } = this.provider;
|
|
7259
|
+
const buf = this.settledBuffer;
|
|
7260
|
+
if (this.currentStatus === "waiting_approval") {
|
|
7249
7261
|
const genResume = patterns.generating.some((p) => p.test(this.approvalTransitionBuffer));
|
|
7250
7262
|
const promptResume = patterns.prompt.some((p) => p.test(this.approvalTransitionBuffer));
|
|
7251
7263
|
if (genResume) {
|
|
@@ -7272,33 +7284,43 @@ var ProviderCliAdapter = class {
|
|
|
7272
7284
|
}
|
|
7273
7285
|
return;
|
|
7274
7286
|
}
|
|
7275
|
-
|
|
7276
|
-
|
|
7287
|
+
const hasApproval = patterns.approval.some((p) => p.test(buf));
|
|
7288
|
+
if (hasApproval) {
|
|
7289
|
+
const inCooldown = this.lastApprovalResolvedAt && Date.now() - this.lastApprovalResolvedAt < this.timeouts.approvalCooldown;
|
|
7290
|
+
if (!inCooldown) {
|
|
7291
|
+
const ctxLines = buf.split("\n").map((l) => l.trim()).filter((l) => l && !/^[─═╭╮╰╯│]+$/.test(l));
|
|
7277
7292
|
this.isWaitingForResponse = true;
|
|
7278
|
-
this.
|
|
7279
|
-
this.
|
|
7293
|
+
this.setStatus("waiting_approval", "approval_pattern");
|
|
7294
|
+
this.recentOutputBuffer = "";
|
|
7295
|
+
this.approvalTransitionBuffer = "";
|
|
7296
|
+
this.activeModal = {
|
|
7297
|
+
message: ctxLines.slice(-5).join(" ").slice(0, 200) || "Approval required",
|
|
7298
|
+
buttons: this.cliType === "claude-cli" ? ["Yes (y)", "Always allow (a)", "Deny (Esc)"] : ["Allow once", "Always allow", "Deny"]
|
|
7299
|
+
};
|
|
7300
|
+
if (this.idleTimeout) clearTimeout(this.idleTimeout);
|
|
7301
|
+
if (this.approvalExitTimeout) clearTimeout(this.approvalExitTimeout);
|
|
7302
|
+
this.approvalExitTimeout = setTimeout(() => {
|
|
7303
|
+
if (this.currentStatus === "waiting_approval") {
|
|
7304
|
+
LOG.warn("CLI", `[${this.cliType}] Approval timeout \u2014 auto-exiting waiting_approval`);
|
|
7305
|
+
this.activeModal = null;
|
|
7306
|
+
this.lastApprovalResolvedAt = Date.now();
|
|
7307
|
+
this.recentOutputBuffer = "";
|
|
7308
|
+
this.approvalTransitionBuffer = "";
|
|
7309
|
+
this.approvalExitTimeout = null;
|
|
7310
|
+
this.setStatus(this.isWaitingForResponse ? "generating" : "idle", "approval_cleared");
|
|
7311
|
+
this.onStatusChange?.();
|
|
7312
|
+
}
|
|
7313
|
+
}, 6e4);
|
|
7280
7314
|
this.onStatusChange?.();
|
|
7315
|
+
return;
|
|
7281
7316
|
}
|
|
7282
7317
|
}
|
|
7283
7318
|
if (this.isWaitingForResponse) {
|
|
7284
|
-
|
|
7285
|
-
if (
|
|
7286
|
-
|
|
7287
|
-
if (
|
|
7288
|
-
this.
|
|
7289
|
-
this.idleTimeout = setTimeout(() => {
|
|
7290
|
-
if (this.isWaitingForResponse) this.finishResponse();
|
|
7291
|
-
}, this.timeouts.generatingIdle);
|
|
7292
|
-
this.onStatusChange?.();
|
|
7293
|
-
return;
|
|
7294
|
-
}
|
|
7295
|
-
const trailingLines = cleanData.split("\n").slice(-2).join("\n");
|
|
7296
|
-
if (patterns.prompt.some((p) => p.test(trailingLines))) {
|
|
7297
|
-
const hasApprovalHere = patterns.approval.some((p) => p.test(this.recentOutputBuffer));
|
|
7298
|
-
if (!hasApprovalHere) {
|
|
7299
|
-
this.finishResponse();
|
|
7300
|
-
}
|
|
7301
|
-
} else {
|
|
7319
|
+
const trailingLines = buf.split("\n").slice(-3).join("\n");
|
|
7320
|
+
if (patterns.prompt.some((p) => p.test(trailingLines)) && !hasApproval) {
|
|
7321
|
+
this.finishResponse();
|
|
7322
|
+
} else if (!patterns.generating.some((p) => p.test(buf))) {
|
|
7323
|
+
if (this.idleTimeout) clearTimeout(this.idleTimeout);
|
|
7302
7324
|
this.idleTimeout = setTimeout(() => {
|
|
7303
7325
|
if (this.isWaitingForResponse && this.responseBuffer.trim()) {
|
|
7304
7326
|
this.finishResponse();
|
|
@@ -7370,6 +7392,10 @@ var ProviderCliAdapter = class {
|
|
|
7370
7392
|
this.shutdown();
|
|
7371
7393
|
}
|
|
7372
7394
|
shutdown() {
|
|
7395
|
+
if (this.settleTimer) {
|
|
7396
|
+
clearTimeout(this.settleTimer);
|
|
7397
|
+
this.settleTimer = null;
|
|
7398
|
+
}
|
|
7373
7399
|
if (this.approvalExitTimeout) {
|
|
7374
7400
|
clearTimeout(this.approvalExitTimeout);
|
|
7375
7401
|
this.approvalExitTimeout = null;
|
|
@@ -7441,6 +7467,7 @@ var ProviderCliAdapter = class {
|
|
|
7441
7467
|
// Buffers
|
|
7442
7468
|
startupBuffer: this.startupBuffer.slice(-500),
|
|
7443
7469
|
recentOutputBuffer: this.recentOutputBuffer.slice(-500),
|
|
7470
|
+
settledBuffer: this.settledBuffer.slice(-500),
|
|
7444
7471
|
responseBuffer: this.responseBuffer.slice(-500),
|
|
7445
7472
|
approvalTransitionBuffer: this.approvalTransitionBuffer.slice(-500),
|
|
7446
7473
|
// State
|