@adhdev/daemon-core 0.9.82-rc.207 → 0.9.82-rc.209
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-adapters/terminal-backends/ghostty-vt-backend.d.ts +1 -3
- package/dist/cli-adapters/terminal-backends/types.d.ts +1 -2
- package/dist/cli-adapters/terminal-screen.d.ts +2 -11
- package/dist/index.js +156 -212
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +141 -197
- package/dist/index.mjs.map +1 -1
- package/dist/providers/spec/adapter.d.ts +11 -19
- package/dist/providers/spec/driver.d.ts +14 -0
- package/dist/providers/spec/schema.gen.d.ts +24 -1
- package/dist/providers/spec/types.d.ts +8 -1
- package/dist/shared-types-extra.d.ts +1 -3
- package/package.json +1 -3
- package/src/cli-adapters/provider-cli-adapter.ts +3 -2
- package/src/cli-adapters/terminal-backends/ghostty-vt-backend.ts +11 -34
- package/src/cli-adapters/terminal-backends/types.ts +1 -3
- package/src/cli-adapters/terminal-screen.ts +11 -81
- package/src/commands/mesh-coordinator.ts +3 -2
- package/src/daemon/dev-auto-implement.ts +3 -2
- package/src/providers/spec/adapter.ts +40 -78
- package/src/providers/spec/cli-adapter.ts +2 -0
- package/src/providers/spec/driver.ts +71 -7
- package/src/providers/spec/evaluator.ts +44 -14
- package/src/providers/spec/loader.ts +6 -1
- package/src/providers/spec/schema.gen.ts +17 -1
- package/src/providers/spec/types.ts +5 -1
- package/src/shared-types-extra.ts +1 -3
- package/dist/cli-adapters/terminal-backends/xterm-backend.d.ts +0 -17
- package/src/cli-adapters/terminal-backends/ghostty-vt-backend.d.ts +0 -16
- package/src/cli-adapters/terminal-backends/xterm-backend.ts +0 -104
package/dist/index.mjs
CHANGED
|
@@ -1958,6 +1958,7 @@ __export(mesh_coordinator_exports, {
|
|
|
1958
1958
|
import { createHash as createHash2 } from "crypto";
|
|
1959
1959
|
import { existsSync as existsSync6, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
|
|
1960
1960
|
import * as os4 from "os";
|
|
1961
|
+
import { DEFAULT_SESSION_HOST_COLS, DEFAULT_SESSION_HOST_ROWS } from "@adhdev/session-host-core";
|
|
1961
1962
|
import { basename as basename2, isAbsolute as isAbsolute4, join as join7, resolve as resolve7 } from "path";
|
|
1962
1963
|
function isHermesProvider(provider, cliType) {
|
|
1963
1964
|
const type = cliType?.trim() || provider?.type?.trim() || "";
|
|
@@ -2299,8 +2300,8 @@ async function execUnderPty(command, args, options = {}) {
|
|
|
2299
2300
|
try {
|
|
2300
2301
|
child = ptyLib.spawn(command, args, {
|
|
2301
2302
|
name: "xterm-256color",
|
|
2302
|
-
cols:
|
|
2303
|
-
rows:
|
|
2303
|
+
cols: DEFAULT_SESSION_HOST_COLS,
|
|
2304
|
+
rows: DEFAULT_SESSION_HOST_ROWS,
|
|
2304
2305
|
cwd: options.cwd ?? process.cwd(),
|
|
2305
2306
|
env
|
|
2306
2307
|
});
|
|
@@ -7043,11 +7044,9 @@ function getBindingCandidates() {
|
|
|
7043
7044
|
const explicit = process.env.ADHDEV_GHOSTTY_VT_BINDING?.trim();
|
|
7044
7045
|
return explicit ? [explicit] : DEFAULT_BINDING_CANDIDATES;
|
|
7045
7046
|
}
|
|
7046
|
-
function loadGhosttyVtBinding(
|
|
7047
|
+
function loadGhosttyVtBinding() {
|
|
7047
7048
|
if (cachedBinding !== void 0) {
|
|
7048
|
-
if (!cachedBinding &&
|
|
7049
|
-
throw cachedBindingError;
|
|
7050
|
-
}
|
|
7049
|
+
if (!cachedBinding && cachedBindingError) throw cachedBindingError;
|
|
7051
7050
|
return cachedBinding;
|
|
7052
7051
|
}
|
|
7053
7052
|
const errors = [];
|
|
@@ -7068,18 +7067,9 @@ function loadGhosttyVtBinding(required) {
|
|
|
7068
7067
|
}
|
|
7069
7068
|
cachedBinding = null;
|
|
7070
7069
|
cachedBindingError = new Error(
|
|
7071
|
-
`ghostty-vt
|
|
7070
|
+
`ghostty-vt binding unavailable (${errors.join("; ") || "no candidates tried"})`
|
|
7072
7071
|
);
|
|
7073
|
-
|
|
7074
|
-
return null;
|
|
7075
|
-
}
|
|
7076
|
-
function resolveTerminalBackendPreference() {
|
|
7077
|
-
const raw = process.env.ADHDEV_TERMINAL_BACKEND?.trim().toLowerCase();
|
|
7078
|
-
if (raw === "ghostty-vt" || raw === "xterm" || raw === "auto") return raw;
|
|
7079
|
-
return "auto";
|
|
7080
|
-
}
|
|
7081
|
-
function isGhosttyVtBackendAvailable() {
|
|
7082
|
-
return !!loadGhosttyVtBinding(false);
|
|
7072
|
+
throw cachedBindingError;
|
|
7083
7073
|
}
|
|
7084
7074
|
var DEFAULT_BINDING_CANDIDATES, cachedBinding, cachedBindingError, GhosttyVtTerminalBackend;
|
|
7085
7075
|
var init_ghostty_vt_backend = __esm({
|
|
@@ -7093,10 +7083,7 @@ var init_ghostty_vt_backend = __esm({
|
|
|
7093
7083
|
kind = "ghostty-vt";
|
|
7094
7084
|
terminal;
|
|
7095
7085
|
constructor(options) {
|
|
7096
|
-
const binding = loadGhosttyVtBinding(
|
|
7097
|
-
if (!binding) {
|
|
7098
|
-
throw new Error("ghostty-vt backend requested but no binding is available");
|
|
7099
|
-
}
|
|
7086
|
+
const binding = loadGhosttyVtBinding();
|
|
7100
7087
|
this.terminal = binding.createTerminal({
|
|
7101
7088
|
cols: Math.max(1, options.cols | 0),
|
|
7102
7089
|
rows: Math.max(1, options.rows | 0),
|
|
@@ -7130,141 +7117,26 @@ var init_ghostty_vt_backend = __esm({
|
|
|
7130
7117
|
}
|
|
7131
7118
|
});
|
|
7132
7119
|
|
|
7133
|
-
// src/cli-adapters/terminal-backends/xterm-backend.ts
|
|
7134
|
-
function loadTerminalCtor() {
|
|
7135
|
-
if (!TerminalCtor) {
|
|
7136
|
-
const mod = __require("@xterm/xterm");
|
|
7137
|
-
TerminalCtor = mod.Terminal || mod.default?.Terminal || mod.default;
|
|
7138
|
-
if (!TerminalCtor) {
|
|
7139
|
-
throw new Error("@xterm/xterm Terminal export not found");
|
|
7140
|
-
}
|
|
7141
|
-
}
|
|
7142
|
-
return TerminalCtor;
|
|
7143
|
-
}
|
|
7144
|
-
var TerminalCtor, XtermTerminalBackend;
|
|
7145
|
-
var init_xterm_backend = __esm({
|
|
7146
|
-
"src/cli-adapters/terminal-backends/xterm-backend.ts"() {
|
|
7147
|
-
"use strict";
|
|
7148
|
-
TerminalCtor = null;
|
|
7149
|
-
XtermTerminalBackend = class {
|
|
7150
|
-
kind = "xterm";
|
|
7151
|
-
rows;
|
|
7152
|
-
cols;
|
|
7153
|
-
terminal;
|
|
7154
|
-
constructor(options) {
|
|
7155
|
-
this.rows = Math.max(1, options.rows | 0);
|
|
7156
|
-
this.cols = Math.max(1, options.cols | 0);
|
|
7157
|
-
this.terminal = this.createTerminal(options.scrollback);
|
|
7158
|
-
}
|
|
7159
|
-
resize(rows, cols) {
|
|
7160
|
-
this.rows = Math.max(1, rows | 0);
|
|
7161
|
-
this.cols = Math.max(1, cols | 0);
|
|
7162
|
-
this.terminal.resize(this.cols, this.rows);
|
|
7163
|
-
}
|
|
7164
|
-
write(data) {
|
|
7165
|
-
if (!data) return;
|
|
7166
|
-
this.terminal.write(data);
|
|
7167
|
-
}
|
|
7168
|
-
getText() {
|
|
7169
|
-
const buffer = this.terminal.buffer.active;
|
|
7170
|
-
const start = Math.max(0, buffer.viewportY || 0);
|
|
7171
|
-
const end = Math.max(start, Math.min(buffer.length || 0, start + this.rows));
|
|
7172
|
-
const lines = [];
|
|
7173
|
-
for (let i = start; i < end; i++) {
|
|
7174
|
-
const line = buffer.getLine(i);
|
|
7175
|
-
const raw = line ? line.translateToString(false) : "";
|
|
7176
|
-
lines.push(raw.replace(/\s+$/, ""));
|
|
7177
|
-
}
|
|
7178
|
-
let first = 0;
|
|
7179
|
-
let last = lines.length;
|
|
7180
|
-
while (first < last && !lines[first]?.trim()) first++;
|
|
7181
|
-
while (last > first && !lines[last - 1]?.trim()) last--;
|
|
7182
|
-
return lines.slice(first, last).join("\n");
|
|
7183
|
-
}
|
|
7184
|
-
getCursorPosition() {
|
|
7185
|
-
const buffer = this.terminal.buffer.active;
|
|
7186
|
-
return {
|
|
7187
|
-
col: Math.max(0, buffer.cursorX || 0),
|
|
7188
|
-
row: Math.max(0, buffer.cursorY || 0)
|
|
7189
|
-
};
|
|
7190
|
-
}
|
|
7191
|
-
dispose() {
|
|
7192
|
-
this.terminal.dispose();
|
|
7193
|
-
}
|
|
7194
|
-
createTerminal(scrollback) {
|
|
7195
|
-
const Terminal2 = loadTerminalCtor();
|
|
7196
|
-
return new Terminal2({
|
|
7197
|
-
cols: this.cols,
|
|
7198
|
-
rows: this.rows,
|
|
7199
|
-
scrollback
|
|
7200
|
-
});
|
|
7201
|
-
}
|
|
7202
|
-
};
|
|
7203
|
-
}
|
|
7204
|
-
});
|
|
7205
|
-
|
|
7206
7120
|
// src/cli-adapters/terminal-screen.ts
|
|
7121
|
+
import { DEFAULT_SESSION_HOST_COLS as DEFAULT_SESSION_HOST_COLS2, DEFAULT_SESSION_HOST_ROWS as DEFAULT_SESSION_HOST_ROWS2 } from "@adhdev/session-host-core";
|
|
7207
7122
|
function getTerminalBackendRuntimeStatus() {
|
|
7208
|
-
|
|
7209
|
-
const ghosttyAvailable = isGhosttyVtBackendAvailable();
|
|
7210
|
-
const backend = preference === "ghostty-vt" || preference === "auto" && ghosttyAvailable ? "ghostty-vt" : "xterm";
|
|
7211
|
-
return { backend, preference, ghosttyAvailable };
|
|
7212
|
-
}
|
|
7213
|
-
function createTerminalBackend(options, preference) {
|
|
7214
|
-
const ghosttyAvailable = isGhosttyVtBackendAvailable();
|
|
7215
|
-
if (preference === "ghostty-vt") {
|
|
7216
|
-
const backend2 = new GhosttyVtTerminalBackend(options);
|
|
7217
|
-
logTerminalBackendSelection(preference, ghosttyAvailable, backend2.kind);
|
|
7218
|
-
return backend2;
|
|
7219
|
-
}
|
|
7220
|
-
if (preference === "auto" && ghosttyAvailable) {
|
|
7221
|
-
const backend2 = new GhosttyVtTerminalBackend(options);
|
|
7222
|
-
logTerminalBackendSelection(preference, ghosttyAvailable, backend2.kind);
|
|
7223
|
-
return backend2;
|
|
7224
|
-
}
|
|
7225
|
-
const backend = new XtermTerminalBackend(options);
|
|
7226
|
-
logTerminalBackendSelection(preference, ghosttyAvailable, backend.kind);
|
|
7227
|
-
return backend;
|
|
7228
|
-
}
|
|
7229
|
-
function logTerminalBackendSelection(preference, ghosttyAvailable, backendKind) {
|
|
7230
|
-
const key = `${preference}:${ghosttyAvailable}:${backendKind}`;
|
|
7231
|
-
if (loggedTerminalBackends.has(key)) return;
|
|
7232
|
-
loggedTerminalBackends.add(key);
|
|
7233
|
-
if (backendKind === "xterm" && preference !== "xterm" && !ghosttyAvailable) {
|
|
7234
|
-
const message = `[terminal-screen] ghostty-vt unavailable; using xterm fallback (preference=${preference})`;
|
|
7235
|
-
if (preference === "auto") {
|
|
7236
|
-
LOG.info("Terminal", message);
|
|
7237
|
-
} else {
|
|
7238
|
-
LOG.warn("Terminal", message);
|
|
7239
|
-
}
|
|
7240
|
-
return;
|
|
7241
|
-
}
|
|
7242
|
-
LOG.info(
|
|
7243
|
-
"Terminal",
|
|
7244
|
-
`[terminal-screen] backend=${backendKind} preference=${preference} ghosttyAvailable=${ghosttyAvailable}`
|
|
7245
|
-
);
|
|
7123
|
+
return { backend: "ghostty-vt" };
|
|
7246
7124
|
}
|
|
7247
|
-
var DEFAULT_SCROLLBACK,
|
|
7125
|
+
var DEFAULT_SCROLLBACK, TerminalScreen;
|
|
7248
7126
|
var init_terminal_screen = __esm({
|
|
7249
7127
|
"src/cli-adapters/terminal-screen.ts"() {
|
|
7250
7128
|
"use strict";
|
|
7251
|
-
init_logger();
|
|
7252
7129
|
init_ghostty_vt_backend();
|
|
7253
|
-
init_xterm_backend();
|
|
7254
7130
|
DEFAULT_SCROLLBACK = 2e3;
|
|
7255
|
-
loggedTerminalBackends = /* @__PURE__ */ new Set();
|
|
7256
7131
|
TerminalScreen = class {
|
|
7257
|
-
backendKind;
|
|
7132
|
+
backendKind = "ghostty-vt";
|
|
7258
7133
|
rows;
|
|
7259
7134
|
cols;
|
|
7260
|
-
preference;
|
|
7261
7135
|
terminal;
|
|
7262
|
-
constructor(rows =
|
|
7136
|
+
constructor(rows = DEFAULT_SESSION_HOST_ROWS2, cols = DEFAULT_SESSION_HOST_COLS2) {
|
|
7263
7137
|
this.rows = Math.max(1, rows | 0);
|
|
7264
7138
|
this.cols = Math.max(1, cols | 0);
|
|
7265
|
-
this.preference = resolveTerminalBackendPreference();
|
|
7266
7139
|
this.terminal = this.createBackend();
|
|
7267
|
-
this.backendKind = this.terminal.kind;
|
|
7268
7140
|
}
|
|
7269
7141
|
reset(rows = this.rows, cols = this.cols) {
|
|
7270
7142
|
this.rows = Math.max(1, rows | 0);
|
|
@@ -7290,11 +7162,11 @@ var init_terminal_screen = __esm({
|
|
|
7290
7162
|
this.terminal.dispose();
|
|
7291
7163
|
}
|
|
7292
7164
|
createBackend() {
|
|
7293
|
-
return
|
|
7165
|
+
return new GhosttyVtTerminalBackend({
|
|
7294
7166
|
cols: this.cols,
|
|
7295
7167
|
rows: this.rows,
|
|
7296
7168
|
scrollback: DEFAULT_SCROLLBACK
|
|
7297
|
-
}
|
|
7169
|
+
});
|
|
7298
7170
|
}
|
|
7299
7171
|
};
|
|
7300
7172
|
}
|
|
@@ -7313,6 +7185,10 @@ var init_spawn_env = __esm({
|
|
|
7313
7185
|
});
|
|
7314
7186
|
|
|
7315
7187
|
// src/cli-adapters/pty-transport.ts
|
|
7188
|
+
var pty_transport_exports = {};
|
|
7189
|
+
__export(pty_transport_exports, {
|
|
7190
|
+
NodePtyTransportFactory: () => NodePtyTransportFactory
|
|
7191
|
+
});
|
|
7316
7192
|
import * as os11 from "os";
|
|
7317
7193
|
function loadNodePty() {
|
|
7318
7194
|
if (cachedPty !== void 0) return cachedPty;
|
|
@@ -9503,7 +9379,7 @@ var init_provider_cli_config = __esm({
|
|
|
9503
9379
|
// src/cli-adapters/provider-cli-runtime.ts
|
|
9504
9380
|
import * as os13 from "os";
|
|
9505
9381
|
import * as path17 from "path";
|
|
9506
|
-
import { DEFAULT_SESSION_HOST_COLS, DEFAULT_SESSION_HOST_ROWS } from "@adhdev/session-host-core";
|
|
9382
|
+
import { DEFAULT_SESSION_HOST_COLS as DEFAULT_SESSION_HOST_COLS3, DEFAULT_SESSION_HOST_ROWS as DEFAULT_SESSION_HOST_ROWS3 } from "@adhdev/session-host-core";
|
|
9507
9383
|
function resolveCliSpawnPlan(options) {
|
|
9508
9384
|
const { provider, runtimeSettings, workingDir, extraArgs, extraEnv } = options;
|
|
9509
9385
|
const { spawn: spawnConfig } = provider;
|
|
@@ -9541,8 +9417,8 @@ function resolveCliSpawnPlan(options) {
|
|
|
9541
9417
|
isWin,
|
|
9542
9418
|
useShell,
|
|
9543
9419
|
ptyOptions: {
|
|
9544
|
-
cols:
|
|
9545
|
-
rows:
|
|
9420
|
+
cols: DEFAULT_SESSION_HOST_COLS3,
|
|
9421
|
+
rows: DEFAULT_SESSION_HOST_ROWS3,
|
|
9546
9422
|
cwd: workingDir,
|
|
9547
9423
|
env
|
|
9548
9424
|
}
|
|
@@ -9608,6 +9484,7 @@ __export(provider_cli_adapter_exports, {
|
|
|
9608
9484
|
normalizeCliProviderForRuntime: () => normalizeCliProviderForRuntime
|
|
9609
9485
|
});
|
|
9610
9486
|
import * as os14 from "os";
|
|
9487
|
+
import { DEFAULT_SESSION_HOST_COLS as DEFAULT_SESSION_HOST_COLS4, DEFAULT_SESSION_HOST_ROWS as DEFAULT_SESSION_HOST_ROWS4 } from "@adhdev/session-host-core";
|
|
9611
9488
|
function appendBoundedText(current, chunk, maxChars) {
|
|
9612
9489
|
if (!chunk) return current.length <= maxChars ? current : current.slice(-maxChars);
|
|
9613
9490
|
if (maxChars <= 0) return "";
|
|
@@ -9774,7 +9651,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
9774
9651
|
/** Full accumulated raw PTY output (with ANSI) */
|
|
9775
9652
|
accumulatedRawBuffer = "";
|
|
9776
9653
|
/** Current visible terminal screen snapshot */
|
|
9777
|
-
terminalScreen = new TerminalScreen(
|
|
9654
|
+
terminalScreen = new TerminalScreen(DEFAULT_SESSION_HOST_ROWS4, DEFAULT_SESSION_HOST_COLS4);
|
|
9778
9655
|
static MAX_RESPONSE_BUFFER = 8e3;
|
|
9779
9656
|
static MAX_RECENT_OUTPUT_BUFFER = 1e3;
|
|
9780
9657
|
responseBufferDroppedChars = 0;
|
|
@@ -9987,7 +9864,7 @@ ${lastSnapshot}`;
|
|
|
9987
9864
|
clearTimeout(this.startupSettleTimer);
|
|
9988
9865
|
this.startupSettleTimer = null;
|
|
9989
9866
|
}
|
|
9990
|
-
this.resetTerminalScreen(
|
|
9867
|
+
this.resetTerminalScreen(DEFAULT_SESSION_HOST_ROWS4, DEFAULT_SESSION_HOST_COLS4);
|
|
9991
9868
|
this.pendingTerminalQueryTail = "";
|
|
9992
9869
|
this.ready = false;
|
|
9993
9870
|
await this.ptyProcess.ready;
|
|
@@ -26078,33 +25955,33 @@ import * as os15 from "os";
|
|
|
26078
25955
|
import * as path19 from "path";
|
|
26079
25956
|
|
|
26080
25957
|
// src/providers/spec/adapter.ts
|
|
26081
|
-
|
|
26082
|
-
import
|
|
26083
|
-
var TerminalCtor2 = xtermHeadlessNs.Terminal ?? xtermHeadlessNs.default?.Terminal;
|
|
25958
|
+
init_terminal_screen();
|
|
25959
|
+
import { DEFAULT_SESSION_HOST_COLS as DEFAULT_SESSION_HOST_COLS5, DEFAULT_SESSION_HOST_ROWS as DEFAULT_SESSION_HOST_ROWS5 } from "@adhdev/session-host-core";
|
|
26084
25960
|
var TerminalAdapter = class {
|
|
26085
25961
|
constructor(opts, handlers) {
|
|
26086
25962
|
this.opts = opts;
|
|
26087
25963
|
this.handlers = handlers;
|
|
26088
|
-
this.cols = opts.cols ??
|
|
26089
|
-
this.rows = opts.rows ??
|
|
25964
|
+
this.cols = opts.cols ?? DEFAULT_SESSION_HOST_COLS5;
|
|
25965
|
+
this.rows = opts.rows ?? DEFAULT_SESSION_HOST_ROWS5;
|
|
26090
25966
|
this.screenDebounceMs = opts.screenChangeDebounceMs ?? 80;
|
|
26091
25967
|
this.tickIntervalMs = opts.tickIntervalMs ?? 0;
|
|
26092
|
-
|
|
26093
|
-
this.
|
|
25968
|
+
const { NodePtyTransportFactory: NodePtyTransportFactory2 } = (init_pty_transport(), __toCommonJS(pty_transport_exports));
|
|
25969
|
+
this.factory = opts.transportFactory ?? new NodePtyTransportFactory2();
|
|
25970
|
+
this.screen = new TerminalScreen(this.rows, this.cols);
|
|
26094
25971
|
}
|
|
26095
|
-
term;
|
|
26096
|
-
pty = null;
|
|
26097
|
-
factory;
|
|
26098
|
-
cols;
|
|
26099
25972
|
rows;
|
|
25973
|
+
cols;
|
|
26100
25974
|
screenDebounceMs;
|
|
26101
25975
|
tickIntervalMs;
|
|
25976
|
+
factory;
|
|
25977
|
+
screen;
|
|
25978
|
+
pty = null;
|
|
26102
25979
|
screenTimer = null;
|
|
26103
25980
|
tickTimer = null;
|
|
26104
25981
|
lastScreen = "";
|
|
26105
25982
|
start() {
|
|
26106
25983
|
this.pty = this.factory.spawn(this.opts.binary, this.opts.args ?? [], {
|
|
26107
|
-
cwd: this.opts.cwd,
|
|
25984
|
+
cwd: this.opts.cwd ?? process.cwd(),
|
|
26108
25985
|
env: { ...process.env, ...this.opts.env ?? {} },
|
|
26109
25986
|
cols: this.cols,
|
|
26110
25987
|
rows: this.rows
|
|
@@ -26120,24 +25997,21 @@ var TerminalAdapter = class {
|
|
|
26120
25997
|
this.tickTimer = setInterval(() => this.handlers.tick?.(), this.tickIntervalMs);
|
|
26121
25998
|
}
|
|
26122
25999
|
}
|
|
26123
|
-
send_keys(s) {
|
|
26124
|
-
this.pty?.write(s);
|
|
26125
|
-
}
|
|
26126
26000
|
resize(cols, rows) {
|
|
26127
26001
|
this.cols = cols;
|
|
26128
26002
|
this.rows = rows;
|
|
26129
26003
|
this.pty?.resize(cols, rows);
|
|
26130
|
-
this.
|
|
26004
|
+
this.screen.resize(rows, cols);
|
|
26131
26005
|
}
|
|
26132
26006
|
snapshot() {
|
|
26133
26007
|
return this.lastScreen || this.computeScreen();
|
|
26134
26008
|
}
|
|
26135
26009
|
getCursorPosition() {
|
|
26136
|
-
const
|
|
26137
|
-
return {
|
|
26138
|
-
|
|
26139
|
-
|
|
26140
|
-
|
|
26010
|
+
const pos = this.screen.getCursorPosition();
|
|
26011
|
+
return { row: pos.row, col: pos.col };
|
|
26012
|
+
}
|
|
26013
|
+
send_keys(text) {
|
|
26014
|
+
this.pty?.write(text);
|
|
26141
26015
|
}
|
|
26142
26016
|
kill() {
|
|
26143
26017
|
this.stopTimers();
|
|
@@ -26146,14 +26020,14 @@ var TerminalAdapter = class {
|
|
|
26146
26020
|
} catch {
|
|
26147
26021
|
}
|
|
26148
26022
|
this.pty = null;
|
|
26149
|
-
this.
|
|
26023
|
+
this.screen.dispose();
|
|
26150
26024
|
}
|
|
26151
26025
|
onChunk(chunk) {
|
|
26152
26026
|
try {
|
|
26153
26027
|
this.handlers.on_pty_data?.(chunk);
|
|
26154
26028
|
} catch {
|
|
26155
26029
|
}
|
|
26156
|
-
this.
|
|
26030
|
+
this.screen.write(chunk);
|
|
26157
26031
|
if (this.screenTimer) return;
|
|
26158
26032
|
this.screenTimer = setTimeout(() => {
|
|
26159
26033
|
this.screenTimer = null;
|
|
@@ -26167,15 +26041,7 @@ var TerminalAdapter = class {
|
|
|
26167
26041
|
}, this.screenDebounceMs);
|
|
26168
26042
|
}
|
|
26169
26043
|
computeScreen() {
|
|
26170
|
-
|
|
26171
|
-
const out = [];
|
|
26172
|
-
for (let y = 0; y < buf.length; y += 1) {
|
|
26173
|
-
const line = buf.getLine(y);
|
|
26174
|
-
if (!line) continue;
|
|
26175
|
-
out.push(line.translateToString(true));
|
|
26176
|
-
}
|
|
26177
|
-
while (out.length > 0 && out[out.length - 1].trim() === "") out.pop();
|
|
26178
|
-
return out.join("\n");
|
|
26044
|
+
return this.screen.getText();
|
|
26179
26045
|
}
|
|
26180
26046
|
stopTimers() {
|
|
26181
26047
|
if (this.screenTimer) {
|
|
@@ -26189,6 +26055,9 @@ var TerminalAdapter = class {
|
|
|
26189
26055
|
}
|
|
26190
26056
|
};
|
|
26191
26057
|
|
|
26058
|
+
// src/providers/spec/driver.ts
|
|
26059
|
+
import { DEFAULT_SESSION_HOST_COLS as DEFAULT_SESSION_HOST_COLS6, DEFAULT_SESSION_HOST_ROWS as DEFAULT_SESSION_HOST_ROWS6 } from "@adhdev/session-host-core";
|
|
26060
|
+
|
|
26192
26061
|
// src/providers/spec/evaluator.ts
|
|
26193
26062
|
function resolveSize(size, total) {
|
|
26194
26063
|
if (size === void 0) return 0;
|
|
@@ -26316,12 +26185,10 @@ function matchState(state, sections, fullScreen, trace, cursor) {
|
|
|
26316
26185
|
}
|
|
26317
26186
|
return { matched: true, title };
|
|
26318
26187
|
}
|
|
26319
|
-
function
|
|
26320
|
-
if (!state.modal_buttons) return null;
|
|
26321
|
-
const hay = sectionText(sections, state.modal_buttons.section, fullScreen);
|
|
26188
|
+
function extractButtonsWithPattern(rule, hay, keyTemplate, continuationLines) {
|
|
26322
26189
|
const buttons = [];
|
|
26323
|
-
if (
|
|
26324
|
-
const re = compileLinePattern(
|
|
26190
|
+
if (continuationLines) {
|
|
26191
|
+
const re = compileLinePattern(rule);
|
|
26325
26192
|
const lines = hay.split("\n");
|
|
26326
26193
|
for (let i = 0; i < lines.length; i += 1) {
|
|
26327
26194
|
const m = re.exec(lines[i]);
|
|
@@ -26339,24 +26206,40 @@ function extractModal(state, sections, fullScreen, title, trace) {
|
|
|
26339
26206
|
j += 1;
|
|
26340
26207
|
}
|
|
26341
26208
|
if (buttons.some((b) => b.index === idx)) continue;
|
|
26342
|
-
const key =
|
|
26209
|
+
const key = keyTemplate.replace(/\{index\}/g, String(idx));
|
|
26343
26210
|
buttons.push({ index: idx, label, key });
|
|
26344
26211
|
i = j - 1;
|
|
26345
26212
|
}
|
|
26346
26213
|
} else {
|
|
26347
|
-
const re = compilePattern(
|
|
26214
|
+
const re = compilePattern(rule);
|
|
26348
26215
|
let m;
|
|
26349
26216
|
while ((m = re.exec(hay)) !== null) {
|
|
26350
26217
|
const idx = Number(m[1]);
|
|
26351
26218
|
const label = String(m[2] ?? "").trim();
|
|
26352
26219
|
if (!Number.isFinite(idx) || idx <= 0 || !label) continue;
|
|
26353
26220
|
if (buttons.some((b) => b.index === idx)) continue;
|
|
26354
|
-
const key =
|
|
26221
|
+
const key = keyTemplate.replace(/\{index\}/g, String(idx));
|
|
26355
26222
|
buttons.push({ index: idx, label, key });
|
|
26356
26223
|
}
|
|
26357
26224
|
}
|
|
26358
26225
|
buttons.sort((a, b) => a.index - b.index);
|
|
26226
|
+
return buttons;
|
|
26227
|
+
}
|
|
26228
|
+
function extractModal(state, sections, fullScreen, title, trace) {
|
|
26229
|
+
if (!state.modal_buttons) return null;
|
|
26230
|
+
const hay = sectionText(sections, state.modal_buttons.section, fullScreen);
|
|
26359
26231
|
const minCount = state.modal_buttons.min_count ?? 2;
|
|
26232
|
+
const keyTemplate = state.modal_buttons.key_for_index;
|
|
26233
|
+
const continuationLines = state.modal_buttons.continuation_lines ?? false;
|
|
26234
|
+
const candidates = state.modal_buttons.patterns?.length ? state.modal_buttons.patterns : state.modal_buttons.pattern ? [{ pattern: state.modal_buttons.pattern, flags: state.modal_buttons.flags }] : [];
|
|
26235
|
+
let buttons = [];
|
|
26236
|
+
for (const candidate of candidates) {
|
|
26237
|
+
const result = extractButtonsWithPattern(candidate, hay, keyTemplate, continuationLines);
|
|
26238
|
+
if (result.length >= minCount) {
|
|
26239
|
+
buttons = result;
|
|
26240
|
+
break;
|
|
26241
|
+
}
|
|
26242
|
+
}
|
|
26360
26243
|
if (buttons.length < minCount) {
|
|
26361
26244
|
trace.push({ kind: "modal", text: `modal_buttons matched ${buttons.length}/${minCount} required \u2014 discarded` });
|
|
26362
26245
|
return null;
|
|
@@ -26734,9 +26617,12 @@ var SCHEMA = {
|
|
|
26734
26617
|
"type": "object",
|
|
26735
26618
|
"additionalProperties": false,
|
|
26736
26619
|
"required": [
|
|
26737
|
-
"pattern",
|
|
26738
26620
|
"key_for_index"
|
|
26739
26621
|
],
|
|
26622
|
+
"oneOf": [
|
|
26623
|
+
{ "required": ["pattern"] },
|
|
26624
|
+
{ "required": ["patterns"] }
|
|
26625
|
+
],
|
|
26740
26626
|
"properties": {
|
|
26741
26627
|
"section": {
|
|
26742
26628
|
"type": "string"
|
|
@@ -26748,6 +26634,19 @@ var SCHEMA = {
|
|
|
26748
26634
|
"flags": {
|
|
26749
26635
|
"type": "string"
|
|
26750
26636
|
},
|
|
26637
|
+
"patterns": {
|
|
26638
|
+
"type": "array",
|
|
26639
|
+
"minItems": 1,
|
|
26640
|
+
"items": {
|
|
26641
|
+
"type": "object",
|
|
26642
|
+
"additionalProperties": false,
|
|
26643
|
+
"required": ["pattern"],
|
|
26644
|
+
"properties": {
|
|
26645
|
+
"pattern": { "type": "string", "minLength": 1 },
|
|
26646
|
+
"flags": { "type": "string" }
|
|
26647
|
+
}
|
|
26648
|
+
}
|
|
26649
|
+
},
|
|
26751
26650
|
"key_for_index": {
|
|
26752
26651
|
"type": "string",
|
|
26753
26652
|
"minLength": 1
|
|
@@ -27035,7 +26934,12 @@ function validateRefs(spec) {
|
|
|
27035
26934
|
if (s.modal_buttons.section && !sectionIds.has(s.modal_buttons.section)) {
|
|
27036
26935
|
errs.push(`states[${s.id}].modal_buttons.section "${s.modal_buttons.section}" unknown`);
|
|
27037
26936
|
}
|
|
27038
|
-
|
|
26937
|
+
if (s.modal_buttons.pattern) {
|
|
26938
|
+
compileRegex2(s.modal_buttons.pattern, s.modal_buttons.flags ?? "m", `states[${s.id}].modal_buttons.pattern`, errs);
|
|
26939
|
+
}
|
|
26940
|
+
for (const [pi, p] of (s.modal_buttons.patterns ?? []).entries()) {
|
|
26941
|
+
compileRegex2(p.pattern, p.flags ?? "m", `states[${s.id}].modal_buttons.patterns[${pi}]`, errs);
|
|
26942
|
+
}
|
|
27039
26943
|
}
|
|
27040
26944
|
}
|
|
27041
26945
|
for (const c of spec.control_bar ?? []) {
|
|
@@ -27105,8 +27009,8 @@ function matchesCompletionIdleRule(spec, ev, screen) {
|
|
|
27105
27009
|
if (!haystack) return null;
|
|
27106
27010
|
try {
|
|
27107
27011
|
const regex = new RegExp(rule.regex, rule.flags || "");
|
|
27108
|
-
const
|
|
27109
|
-
return
|
|
27012
|
+
const matched = regex.test(haystack);
|
|
27013
|
+
return matched ? rule.regex : null;
|
|
27110
27014
|
} catch {
|
|
27111
27015
|
return null;
|
|
27112
27016
|
}
|
|
@@ -27168,6 +27072,14 @@ var SpecDriver = class {
|
|
|
27168
27072
|
* because the evaluator already moved past busy by the time the hold
|
|
27169
27073
|
* kicks in. */
|
|
27170
27074
|
lastBusyState = null;
|
|
27075
|
+
/** Timestamp of the last time we entered a modal state (approval/picker or
|
|
27076
|
+
* any non-busy non-idle state). Used to suppress brief busy blips that
|
|
27077
|
+
* appear while the modal is still on screen — Claude Code streams body
|
|
27078
|
+
* text that transiently shows a spinner even while an approval modal is
|
|
27079
|
+
* visible, causing rapid approval→busy→approval flicker on the dashboard. */
|
|
27080
|
+
lastModalAt = 0;
|
|
27081
|
+
/** The modal state snapshot held across busy blips. */
|
|
27082
|
+
lastModalState = null;
|
|
27171
27083
|
completionIdleFirstSeenAt = 0;
|
|
27172
27084
|
completionIdleKey = "";
|
|
27173
27085
|
/** Timer that re-runs evaluate() once the hold window expires. Needed
|
|
@@ -27281,6 +27193,17 @@ var SpecDriver = class {
|
|
|
27281
27193
|
getSpecPath() {
|
|
27282
27194
|
return this.opts.specPath;
|
|
27283
27195
|
}
|
|
27196
|
+
getCompletionIdleDebounceState() {
|
|
27197
|
+
if (!this.completionIdleKey || !this.completionIdleFirstSeenAt) return null;
|
|
27198
|
+
const rule = this.spec.debounce?.completion_idle_after;
|
|
27199
|
+
if (!rule) return null;
|
|
27200
|
+
return {
|
|
27201
|
+
active: true,
|
|
27202
|
+
ageMs: Date.now() - this.completionIdleFirstSeenAt,
|
|
27203
|
+
holdMs: rule.hold_ms ?? 0,
|
|
27204
|
+
forceAfterMs: typeof rule.force_after_ms === "number" ? rule.force_after_ms : 0
|
|
27205
|
+
};
|
|
27206
|
+
}
|
|
27284
27207
|
getScreen() {
|
|
27285
27208
|
return this.adapter.snapshot();
|
|
27286
27209
|
}
|
|
@@ -27309,8 +27232,8 @@ var SpecDriver = class {
|
|
|
27309
27232
|
args: [...baseArgs, ...extra],
|
|
27310
27233
|
cwd: this.opts.workingDir,
|
|
27311
27234
|
env: { ...this.spec.env ?? {}, ...this.opts.extraEnv ?? {} },
|
|
27312
|
-
cols: this.opts.cols ??
|
|
27313
|
-
rows: this.opts.rows ??
|
|
27235
|
+
cols: this.opts.cols ?? DEFAULT_SESSION_HOST_COLS6,
|
|
27236
|
+
rows: this.opts.rows ?? DEFAULT_SESSION_HOST_ROWS6,
|
|
27314
27237
|
transportFactory: this.opts.transportFactory
|
|
27315
27238
|
};
|
|
27316
27239
|
}
|
|
@@ -27367,6 +27290,14 @@ var SpecDriver = class {
|
|
|
27367
27290
|
evState = this.lastBusyState ?? evState;
|
|
27368
27291
|
}
|
|
27369
27292
|
}
|
|
27293
|
+
const idleStateId = this.spec.default_state ?? "idle";
|
|
27294
|
+
const isModalState = (id) => id !== null && id !== "busy" && id !== idleStateId;
|
|
27295
|
+
if (isModalState(this.currentStateId) && evState.id === "busy") {
|
|
27296
|
+
const ageMs = Date.now() - this.lastModalAt;
|
|
27297
|
+
if (ageMs < busyHoldMs && this.lastModalState) {
|
|
27298
|
+
evState = this.lastModalState;
|
|
27299
|
+
}
|
|
27300
|
+
}
|
|
27370
27301
|
const completionIdleRule = this.spec.debounce?.completion_idle_after;
|
|
27371
27302
|
let busyWakeMs = busyHoldMs;
|
|
27372
27303
|
if (evState.id === "busy" && completionIdleRule) {
|
|
@@ -27406,11 +27337,21 @@ var SpecDriver = class {
|
|
|
27406
27337
|
this.lastBusyAt = Date.now();
|
|
27407
27338
|
this.lastBusyState = evState;
|
|
27408
27339
|
this.cancelIdleHold();
|
|
27340
|
+
if (!this.completionIdleKey) {
|
|
27341
|
+
this.completionIdleFirstSeenAt = 0;
|
|
27342
|
+
}
|
|
27409
27343
|
this.scheduleBusyExpiry(busyWakeMs);
|
|
27410
27344
|
} else if (evState.id !== this.currentStateId && evState.id !== "busy") {
|
|
27411
27345
|
if (evState.id !== (this.spec.default_state ?? "idle")) {
|
|
27412
27346
|
this.cancelIdleHold();
|
|
27413
27347
|
}
|
|
27348
|
+
if (isModalState(evState.id)) {
|
|
27349
|
+
this.lastModalAt = Date.now();
|
|
27350
|
+
this.lastModalState = evState;
|
|
27351
|
+
} else {
|
|
27352
|
+
this.lastModalAt = 0;
|
|
27353
|
+
this.lastModalState = null;
|
|
27354
|
+
}
|
|
27414
27355
|
}
|
|
27415
27356
|
const idleHoldMs = this.spec.debounce?.idle_hold_ms ?? 0;
|
|
27416
27357
|
const isIdleState = evState.id === (this.spec.default_state ?? "idle");
|
|
@@ -27657,7 +27598,7 @@ function guessExt(mime) {
|
|
|
27657
27598
|
}
|
|
27658
27599
|
function extractMatchedRules(ev) {
|
|
27659
27600
|
if (!Array.isArray(ev.trace)) return [];
|
|
27660
|
-
return ev.trace.filter((t) => t.
|
|
27601
|
+
return ev.trace.filter((t) => t.kind === "state_match").map((t) => t.text).filter(Boolean);
|
|
27661
27602
|
}
|
|
27662
27603
|
|
|
27663
27604
|
// src/providers/spec/native-history-executor.ts
|
|
@@ -28638,6 +28579,8 @@ var SpecCliAdapter = class {
|
|
|
28638
28579
|
idleHoldPending: this.driver.hasIdleHoldPending(),
|
|
28639
28580
|
lastBusyAt: this.driver.getLastBusyAt(),
|
|
28640
28581
|
specPath: this.driver.getSpecPath(),
|
|
28582
|
+
cursorPosition: this.driver.getCursorPosition(),
|
|
28583
|
+
completionIdleDebounce: this.driver.getCompletionIdleDebounceState(),
|
|
28641
28584
|
// Extended fields
|
|
28642
28585
|
name: this.cliName,
|
|
28643
28586
|
status: this.getStatus().status,
|
|
@@ -47095,6 +47038,7 @@ async function handleCliRaw(ctx, req, res) {
|
|
|
47095
47038
|
import * as fs26 from "fs";
|
|
47096
47039
|
import * as path38 from "path";
|
|
47097
47040
|
import * as os28 from "os";
|
|
47041
|
+
import { DEFAULT_SESSION_HOST_COLS as DEFAULT_SESSION_HOST_COLS7, DEFAULT_SESSION_HOST_ROWS as DEFAULT_SESSION_HOST_ROWS7 } from "@adhdev/session-host-core";
|
|
47098
47042
|
function getAutoImplPid(ctx) {
|
|
47099
47043
|
const pid = ctx.autoImplProcess?.pid;
|
|
47100
47044
|
return typeof pid === "number" && pid > 0 ? pid : null;
|
|
@@ -47492,8 +47436,8 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
47492
47436
|
const isWin2 = os28.platform() === "win32";
|
|
47493
47437
|
child = pty.spawn(isWin2 ? "cmd.exe" : process.env.SHELL || "/bin/zsh", [isWin2 ? "/c" : "-c", shellCmd], {
|
|
47494
47438
|
name: "xterm-256color",
|
|
47495
|
-
cols:
|
|
47496
|
-
rows:
|
|
47439
|
+
cols: DEFAULT_SESSION_HOST_COLS7,
|
|
47440
|
+
rows: DEFAULT_SESSION_HOST_ROWS7,
|
|
47497
47441
|
cwd: providerDir,
|
|
47498
47442
|
env: { ...process.env, ...spawn4.env || {} }
|
|
47499
47443
|
});
|