@adhdev/daemon-core 1.0.1 → 1.0.3-rc.1
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.js +25 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +25 -6
- package/dist/index.mjs.map +1 -1
- package/dist/providers/spec/cli-adapter.d.ts +13 -0
- package/package.json +3 -3
- package/src/cli-adapters/terminal-backends/ghostty-vt-backend.ts +1 -0
- package/src/cli-adapters/terminal-screen.ts +1 -0
- package/src/providers/spec/cli-adapter.ts +29 -2
|
@@ -63,6 +63,14 @@ export declare class SpecCliAdapter implements CliAdapter {
|
|
|
63
63
|
* MCP config), so this routing keeps the dashboard honest until
|
|
64
64
|
* hermes ships a runtime MCP override. */
|
|
65
65
|
private spawnedEnv;
|
|
66
|
+
/** Wall clock at the moment an approval modal was last resolved (auto-approve,
|
|
67
|
+
* dashboard, or mesh_approve) via a successful button press. Powers
|
|
68
|
+
* isApprovalRecentlyResolved() — the second suppression signal the mesh event
|
|
69
|
+
* forwarder uses to drop a duplicate agent:waiting_approval re-emitted across
|
|
70
|
+
* the approval↔busy TUI flap window (AUTOAPPROVE-FLAP). Mirrors the
|
|
71
|
+
* cli-state-engine's lastApprovalResolvedAt for the spec-driven adapter path
|
|
72
|
+
* (claude-cli specs/4.0.json), which previously stubbed the method to false. */
|
|
73
|
+
private lastApprovalResolvedAt;
|
|
66
74
|
constructor(specPath: string, workingDir: string, cliArgs: string[], extraEnv: Record<string, string>, transportFactory?: PtyTransportFactory);
|
|
67
75
|
spawn(): Promise<void>;
|
|
68
76
|
sendMessage(text: string): Promise<void>;
|
|
@@ -78,6 +86,11 @@ export declare class SpecCliAdapter implements CliAdapter {
|
|
|
78
86
|
isAlive(): boolean;
|
|
79
87
|
private static readonly TERMINAL_SNAPSHOT_DEFAULT_MAX_BYTES;
|
|
80
88
|
private static readonly TERMINAL_SNAPSHOT_ABSOLUTE_MAX_BYTES;
|
|
89
|
+
/** Window during which isApprovalRecentlyResolved() reports a just-resolved
|
|
90
|
+
* approval. Matches CliProviderInstance.APPROVAL_LOCAL_RESOLUTION_COOLDOWN_MS
|
|
91
|
+
* (8000) — the same auto-approve suppression window signal1 uses — so a modal
|
|
92
|
+
* re-emitted within the approval↔busy flap is suppressed by signal2 too. */
|
|
93
|
+
private static readonly APPROVAL_RESOLVED_COOLDOWN_MS;
|
|
81
94
|
/**
|
|
82
95
|
* MESH-READ-TERMINAL (feature 2: RAW terminal read). Least-privilege read
|
|
83
96
|
* of the CURRENT rendered viewport for mesh_read_terminal on the spec path
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adhdev/daemon-core",
|
|
3
|
-
"version": "1.0.1",
|
|
3
|
+
"version": "1.0.3-rc.1",
|
|
4
4
|
"description": "ADHDev daemon core — CDP, IDE detection, providers, command execution",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
"author": "vilmire",
|
|
48
48
|
"license": "AGPL-3.0-or-later",
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@adhdev/mesh-shared": "0.
|
|
51
|
-
"@adhdev/session-host-core": "
|
|
50
|
+
"@adhdev/mesh-shared": "1.0.3-rc.1",
|
|
51
|
+
"@adhdev/session-host-core": "1.0.3-rc.1",
|
|
52
52
|
"@agentclientprotocol/sdk": "^0.16.1",
|
|
53
53
|
"ajv": "^8.20.0",
|
|
54
54
|
"ajv-formats": "^3.0.1",
|
|
@@ -157,6 +157,7 @@ export class GhosttyVtTerminalBackend implements TerminalViewportBackend {
|
|
|
157
157
|
|
|
158
158
|
getCursorPosition(): { col: number; row: number } {
|
|
159
159
|
if (this.disposed) return { col: 0, row: 0 };
|
|
160
|
+
if (typeof this.terminal.getCursorPosition !== 'function') return { col: 0, row: 0 };
|
|
160
161
|
return this.terminal.getCursorPosition();
|
|
161
162
|
}
|
|
162
163
|
|
|
@@ -127,6 +127,14 @@ export class SpecCliAdapter implements CliAdapter {
|
|
|
127
127
|
* MCP config), so this routing keeps the dashboard honest until
|
|
128
128
|
* hermes ships a runtime MCP override. */
|
|
129
129
|
private spawnedEnv: Record<string, string> = {};
|
|
130
|
+
/** Wall clock at the moment an approval modal was last resolved (auto-approve,
|
|
131
|
+
* dashboard, or mesh_approve) via a successful button press. Powers
|
|
132
|
+
* isApprovalRecentlyResolved() — the second suppression signal the mesh event
|
|
133
|
+
* forwarder uses to drop a duplicate agent:waiting_approval re-emitted across
|
|
134
|
+
* the approval↔busy TUI flap window (AUTOAPPROVE-FLAP). Mirrors the
|
|
135
|
+
* cli-state-engine's lastApprovalResolvedAt for the spec-driven adapter path
|
|
136
|
+
* (claude-cli specs/4.0.json), which previously stubbed the method to false. */
|
|
137
|
+
private lastApprovalResolvedAt = 0;
|
|
130
138
|
|
|
131
139
|
constructor(
|
|
132
140
|
specPath: string,
|
|
@@ -312,6 +320,11 @@ export class SpecCliAdapter implements CliAdapter {
|
|
|
312
320
|
// the char count still looks safe.
|
|
313
321
|
private static readonly TERMINAL_SNAPSHOT_DEFAULT_MAX_BYTES = 32 * 1024;
|
|
314
322
|
private static readonly TERMINAL_SNAPSHOT_ABSOLUTE_MAX_BYTES = 64 * 1024;
|
|
323
|
+
/** Window during which isApprovalRecentlyResolved() reports a just-resolved
|
|
324
|
+
* approval. Matches CliProviderInstance.APPROVAL_LOCAL_RESOLUTION_COOLDOWN_MS
|
|
325
|
+
* (8000) — the same auto-approve suppression window signal1 uses — so a modal
|
|
326
|
+
* re-emitted within the approval↔busy flap is suppressed by signal2 too. */
|
|
327
|
+
private static readonly APPROVAL_RESOLVED_COOLDOWN_MS = 8000;
|
|
315
328
|
|
|
316
329
|
/**
|
|
317
330
|
* MESH-READ-TERMINAL (feature 2: RAW terminal read). Least-privilege read
|
|
@@ -455,7 +468,18 @@ export class SpecCliAdapter implements CliAdapter {
|
|
|
455
468
|
// clickModalButton returns whether the FSM actually found a button for `target`
|
|
456
469
|
// and dispatched its confirm keys — surfaced so mesh_approve can distinguish a
|
|
457
470
|
// real press from a silent miss (the exact false-success the mis-map produced).
|
|
458
|
-
|
|
471
|
+
const pressed = this.driver.clickModalButton(target);
|
|
472
|
+
// AUTOAPPROVE-FLAP (signal2): stamp the resolve time ONLY on a real press of an
|
|
473
|
+
// approval-class modal. This is the resolution path for auto-approve, dashboard,
|
|
474
|
+
// and mesh_approve alike, so isApprovalRecentlyResolved() then suppresses a
|
|
475
|
+
// duplicate agent:waiting_approval re-emitted across the approval↔busy flap.
|
|
476
|
+
// Gate on the authoritative FSM status (approval) — a picker/confirm press must
|
|
477
|
+
// NOT arm the approval cooldown. A silent miss (pressed=false) leaves the modal
|
|
478
|
+
// unresolved, so it must not stamp either.
|
|
479
|
+
if (pressed && this.latestState?.status === 'approval') {
|
|
480
|
+
this.lastApprovalResolvedAt = Date.now();
|
|
481
|
+
}
|
|
482
|
+
return pressed;
|
|
459
483
|
}
|
|
460
484
|
|
|
461
485
|
async resolveAction(data: unknown): Promise<void> {
|
|
@@ -494,7 +518,10 @@ export class SpecCliAdapter implements CliAdapter {
|
|
|
494
518
|
this.statusCallback?.();
|
|
495
519
|
}
|
|
496
520
|
|
|
497
|
-
isApprovalRecentlyResolved(): boolean {
|
|
521
|
+
isApprovalRecentlyResolved(): boolean {
|
|
522
|
+
return !!(this.lastApprovalResolvedAt
|
|
523
|
+
&& (Date.now() - this.lastApprovalResolvedAt) < SpecCliAdapter.APPROVAL_RESOLVED_COOLDOWN_MS);
|
|
524
|
+
}
|
|
498
525
|
clearHistory(): void { /* no transcript buffer yet */ }
|
|
499
526
|
updateRuntimeSettings(): void { /* no runtime settings in spec model yet */ }
|
|
500
527
|
setServerConn(): void { /* server conn unused by SpecDriver */ }
|