@adhdev/daemon-core 0.9.82-rc.197 → 0.9.82-rc.198
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 +115 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +117 -16
- package/dist/index.mjs.map +1 -1
- package/dist/providers/spec/driver.d.ts +19 -0
- package/dist/providers/spec/types.d.ts +6 -0
- package/package.json +1 -1
- package/src/commands/router.ts +19 -0
- package/src/providers/spec/cli-adapter.ts +4 -0
- package/src/providers/spec/driver.ts +85 -3
- package/src/providers/spec/types.ts +6 -0
package/dist/index.mjs
CHANGED
|
@@ -14689,8 +14689,8 @@ async function detectIDEs(providerLoader) {
|
|
|
14689
14689
|
if (existsSync15(bundledCli)) resolvedCli = bundledCli;
|
|
14690
14690
|
}
|
|
14691
14691
|
if (!resolvedCli && appPath && os29 === "win32") {
|
|
14692
|
-
const { dirname:
|
|
14693
|
-
const appDir =
|
|
14692
|
+
const { dirname: dirname12 } = await import("path");
|
|
14693
|
+
const appDir = dirname12(appPath);
|
|
14694
14694
|
const candidates = [
|
|
14695
14695
|
`${appDir}\\\\bin\\\\${def.cli}.cmd`,
|
|
14696
14696
|
`${appDir}\\\\bin\\\\${def.cli}`,
|
|
@@ -27173,7 +27173,15 @@ var SpecDriver = class {
|
|
|
27173
27173
|
* explicit wake-up there's nothing to trigger the busy → idle
|
|
27174
27174
|
* downshift. */
|
|
27175
27175
|
busyExpiryTimer = null;
|
|
27176
|
+
/** Pending idle-commit timer. Armed when the evaluator first returns idle;
|
|
27177
|
+
* fires after idle_hold_ms if no non-idle reading has cancelled it. */
|
|
27178
|
+
idleHoldTimer = null;
|
|
27179
|
+
/** State snapshot captured when the idle hold was armed — emitted on commit. */
|
|
27180
|
+
pendingIdleState = null;
|
|
27176
27181
|
specWatcher = null;
|
|
27182
|
+
/** Ring buffer of committed state transitions (max 50). */
|
|
27183
|
+
stateHistory = [];
|
|
27184
|
+
prevStateAt = 0;
|
|
27177
27185
|
/** Subscribe to outbound events. Returns an unsubscribe fn. */
|
|
27178
27186
|
subscribe(listener) {
|
|
27179
27187
|
this.listeners.add(listener);
|
|
@@ -27224,9 +27232,40 @@ var SpecDriver = class {
|
|
|
27224
27232
|
shutdown() {
|
|
27225
27233
|
for (const t of this.delegateTimers.values()) clearTimeout(t);
|
|
27226
27234
|
this.delegateTimers.clear();
|
|
27235
|
+
this.cancelIdleHold();
|
|
27236
|
+
if (this.busyExpiryTimer) {
|
|
27237
|
+
clearTimeout(this.busyExpiryTimer);
|
|
27238
|
+
this.busyExpiryTimer = null;
|
|
27239
|
+
}
|
|
27227
27240
|
this.specWatcher?.close();
|
|
27228
27241
|
this.adapter.kill();
|
|
27229
27242
|
}
|
|
27243
|
+
cancelIdleHold() {
|
|
27244
|
+
if (this.idleHoldTimer) {
|
|
27245
|
+
clearTimeout(this.idleHoldTimer);
|
|
27246
|
+
this.idleHoldTimer = null;
|
|
27247
|
+
}
|
|
27248
|
+
this.pendingIdleState = null;
|
|
27249
|
+
}
|
|
27250
|
+
pushHistory(stateId, label) {
|
|
27251
|
+
const now = Date.now();
|
|
27252
|
+
const durationMs = this.prevStateAt > 0 ? now - this.prevStateAt : 0;
|
|
27253
|
+
this.prevStateAt = now;
|
|
27254
|
+
this.stateHistory.push({ stateId, label, at: now, durationMs });
|
|
27255
|
+
if (this.stateHistory.length > 50) this.stateHistory.shift();
|
|
27256
|
+
}
|
|
27257
|
+
getStateHistory() {
|
|
27258
|
+
return this.stateHistory;
|
|
27259
|
+
}
|
|
27260
|
+
getLastBusyAt() {
|
|
27261
|
+
return this.lastBusyAt;
|
|
27262
|
+
}
|
|
27263
|
+
hasIdleHoldPending() {
|
|
27264
|
+
return this.idleHoldTimer !== null;
|
|
27265
|
+
}
|
|
27266
|
+
getSpecPath() {
|
|
27267
|
+
return this.opts.specPath;
|
|
27268
|
+
}
|
|
27230
27269
|
// ────────────────────────────────────────────────────────────────────
|
|
27231
27270
|
// Loading & adapter wiring
|
|
27232
27271
|
// ────────────────────────────────────────────────────────────────────
|
|
@@ -27250,7 +27289,10 @@ var SpecDriver = class {
|
|
|
27250
27289
|
}
|
|
27251
27290
|
armSpecWatcher() {
|
|
27252
27291
|
try {
|
|
27253
|
-
|
|
27292
|
+
const dir = path19.dirname(this.opts.specPath);
|
|
27293
|
+
const base = path19.basename(this.opts.specPath);
|
|
27294
|
+
this.specWatcher = fs10.watch(dir, { persistent: false }, (_event, filename) => {
|
|
27295
|
+
if (filename && filename !== base) return;
|
|
27254
27296
|
const res = loadSpec(this.opts.specPath);
|
|
27255
27297
|
if (!res.ok) {
|
|
27256
27298
|
this.emit({ kind: "spec_error", errors: res.errors });
|
|
@@ -27334,7 +27376,46 @@ var SpecDriver = class {
|
|
|
27334
27376
|
if (evState.id === "busy") {
|
|
27335
27377
|
this.lastBusyAt = Date.now();
|
|
27336
27378
|
this.lastBusyState = evState;
|
|
27379
|
+
this.cancelIdleHold();
|
|
27337
27380
|
this.scheduleBusyExpiry(busyWakeMs);
|
|
27381
|
+
} else if (evState.id !== this.currentStateId && evState.id !== "busy") {
|
|
27382
|
+
if (evState.id !== (this.spec.default_state ?? "idle")) {
|
|
27383
|
+
this.cancelIdleHold();
|
|
27384
|
+
}
|
|
27385
|
+
}
|
|
27386
|
+
const idleHoldMs = this.spec.debounce?.idle_hold_ms ?? 0;
|
|
27387
|
+
const isIdleState = evState.id === (this.spec.default_state ?? "idle");
|
|
27388
|
+
if (isIdleState && idleHoldMs > 0 && this.currentStateId !== evState.id) {
|
|
27389
|
+
if (!this.idleHoldTimer) {
|
|
27390
|
+
this.pendingIdleState = evState;
|
|
27391
|
+
this.idleHoldTimer = setTimeout(() => {
|
|
27392
|
+
this.idleHoldTimer = null;
|
|
27393
|
+
const committed = this.pendingIdleState;
|
|
27394
|
+
this.pendingIdleState = null;
|
|
27395
|
+
if (!committed) return;
|
|
27396
|
+
LOG.debug("SpecDriver", `[${this.opts.specPath.split("/").slice(-3).join("/")}] idleHold committed after ${idleHoldMs}ms`);
|
|
27397
|
+
this.currentStateId = committed.id;
|
|
27398
|
+
this.currentEval = ev;
|
|
27399
|
+
this.pushHistory(committed.id, committed.label);
|
|
27400
|
+
this.emit({
|
|
27401
|
+
kind: "state_changed",
|
|
27402
|
+
state: committed,
|
|
27403
|
+
modal: null,
|
|
27404
|
+
controls: ev.controls.map((c) => ({ id: c.id, label: c.label, action_type: c.actionType }))
|
|
27405
|
+
});
|
|
27406
|
+
this.armOrCancelDelegateTimers(committed.id);
|
|
27407
|
+
if (this.opts.emitTrace) this.emit({ kind: "spec_trace", entries: ev.trace });
|
|
27408
|
+
}, idleHoldMs);
|
|
27409
|
+
}
|
|
27410
|
+
this.currentEval = ev;
|
|
27411
|
+
const graceMs2 = this.spec.debounce?.startup_grace_ms ?? STARTUP_GRACE_MS;
|
|
27412
|
+
if (!this.idleSeenOnce && Date.now() - this.startedAtMs >= graceMs2) {
|
|
27413
|
+
this.idleSeenOnce = true;
|
|
27414
|
+
const queued = this.pendingSends.splice(0);
|
|
27415
|
+
for (const text of queued) setTimeout(() => this.actuallySendMessage(text), 50);
|
|
27416
|
+
}
|
|
27417
|
+
if (this.pickerInProgress) this.tryAdvancePicker(screen);
|
|
27418
|
+
return;
|
|
27338
27419
|
}
|
|
27339
27420
|
const changed = forceEmit || evState.id !== this.currentStateId || !shallowSameModal(ev, this.currentEval) || !shallowSameControls(ev, this.currentEval);
|
|
27340
27421
|
if (this.pickerInProgress) this.tryAdvancePicker(screen);
|
|
@@ -27350,6 +27431,7 @@ var SpecDriver = class {
|
|
|
27350
27431
|
}
|
|
27351
27432
|
if (changed) {
|
|
27352
27433
|
this.currentStateId = evState.id;
|
|
27434
|
+
this.pushHistory(evState.id, evState.label);
|
|
27353
27435
|
this.emit({
|
|
27354
27436
|
kind: "state_changed",
|
|
27355
27437
|
state: evState,
|
|
@@ -27783,7 +27865,11 @@ var SpecCliAdapter = class {
|
|
|
27783
27865
|
activeInteractivePrompt: this.activeInteractivePrompt,
|
|
27784
27866
|
exited: this.exited,
|
|
27785
27867
|
screen,
|
|
27786
|
-
sections
|
|
27868
|
+
sections,
|
|
27869
|
+
stateHistory: this.driver.getStateHistory(),
|
|
27870
|
+
idleHoldPending: this.driver.hasIdleHoldPending(),
|
|
27871
|
+
lastBusyAt: this.driver.getLastBusyAt(),
|
|
27872
|
+
specPath: this.driver.getSpecPath()
|
|
27787
27873
|
};
|
|
27788
27874
|
}
|
|
27789
27875
|
getRuntimeMetadata() {
|
|
@@ -33327,17 +33413,17 @@ function parseTranscriptFile(filePath, sessionId, workspaceFallback) {
|
|
|
33327
33413
|
}
|
|
33328
33414
|
function readSession(sessionPath) {
|
|
33329
33415
|
if (!sessionPath || !path25.isAbsolute(sessionPath)) return null;
|
|
33330
|
-
const
|
|
33331
|
-
if (!isSafeSessionId(
|
|
33416
|
+
const basename14 = path25.basename(sessionPath, ".jsonl");
|
|
33417
|
+
if (!isSafeSessionId(basename14)) return null;
|
|
33332
33418
|
if (!fs14.existsSync(sessionPath)) return null;
|
|
33333
33419
|
const sourceMtimeMs = statMtimeMs(sessionPath);
|
|
33334
|
-
const messages = parseTranscriptFile(sessionPath,
|
|
33420
|
+
const messages = parseTranscriptFile(sessionPath, basename14);
|
|
33335
33421
|
if (messages.length === 0) return null;
|
|
33336
33422
|
const firstSystem = messages.find((m) => m.kind === "session_start");
|
|
33337
33423
|
const workspace = firstSystem?.workspace || firstSystem?.content || void 0;
|
|
33338
33424
|
return {
|
|
33339
33425
|
messages,
|
|
33340
|
-
providerSessionId:
|
|
33426
|
+
providerSessionId: basename14,
|
|
33341
33427
|
source: "provider-native",
|
|
33342
33428
|
sourcePath: sessionPath,
|
|
33343
33429
|
sourceMtimeMs,
|
|
@@ -33539,8 +33625,8 @@ function readSession2(sessionPath) {
|
|
|
33539
33625
|
if (!fs15.existsSync(sessionPath)) return null;
|
|
33540
33626
|
const meta = readSessionMeta(sessionPath);
|
|
33541
33627
|
const metaId = String(meta?.id ?? "").trim();
|
|
33542
|
-
const
|
|
33543
|
-
const uuidMatch =
|
|
33628
|
+
const basename14 = path26.basename(sessionPath, ".jsonl");
|
|
33629
|
+
const uuidMatch = basename14.match(/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/i);
|
|
33544
33630
|
const filenameUuid2 = uuidMatch ? uuidMatch[1] : "";
|
|
33545
33631
|
if (metaId && filenameUuid2 && metaId !== filenameUuid2) return null;
|
|
33546
33632
|
const sessionId = metaId || filenameUuid2;
|
|
@@ -40752,6 +40838,21 @@ var DaemonCommandRouter = class {
|
|
|
40752
40838
|
} : null
|
|
40753
40839
|
};
|
|
40754
40840
|
}
|
|
40841
|
+
case "get_spec_debug": {
|
|
40842
|
+
const sessionId = typeof args?.targetSessionId === "string" ? args.targetSessionId.trim() : typeof args?.sessionId === "string" ? args.sessionId.trim() : "";
|
|
40843
|
+
if (!sessionId) return { success: false, error: "targetSessionId required" };
|
|
40844
|
+
const target = this.deps.sessionRegistry.get(sessionId);
|
|
40845
|
+
if (!target) return { success: false, error: "Session not found", sessionId };
|
|
40846
|
+
const adapter = this.deps.cliManager.findAdapter(target.providerType, { instanceKey: sessionId })?.adapter;
|
|
40847
|
+
const snapshot = adapter && typeof adapter.getDebugSnapshot === "function" ? adapter.getDebugSnapshot() : null;
|
|
40848
|
+
return {
|
|
40849
|
+
success: true,
|
|
40850
|
+
sessionId,
|
|
40851
|
+
providerType: target.providerType,
|
|
40852
|
+
isSpecProvider: snapshot !== null,
|
|
40853
|
+
snapshot
|
|
40854
|
+
};
|
|
40855
|
+
}
|
|
40755
40856
|
// ── User-level coordinator-prompt files (~/.adhdev/coordinator-prompts/).
|
|
40756
40857
|
// These live on this daemon's filesystem and never sync to the
|
|
40757
40858
|
// cloud / other daemons — they're per-machine config. The
|
|
@@ -42079,7 +42180,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
42079
42180
|
};
|
|
42080
42181
|
}
|
|
42081
42182
|
const { existsSync: existsSync39, readFileSync: readFileSync33, writeFileSync: writeFileSync21, copyFileSync: copyFileSync4, mkdirSync: mkdirSync19 } = await import("fs");
|
|
42082
|
-
const { dirname:
|
|
42183
|
+
const { dirname: dirname12 } = await import("path");
|
|
42083
42184
|
const mcpConfigPath = coordinatorSetup.configPath;
|
|
42084
42185
|
const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
|
|
42085
42186
|
let hermesBaseConfig = null;
|
|
@@ -42114,7 +42215,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
42114
42215
|
};
|
|
42115
42216
|
}
|
|
42116
42217
|
try {
|
|
42117
|
-
mkdirSync19(
|
|
42218
|
+
mkdirSync19(dirname12(mcpConfigPath), { recursive: true });
|
|
42118
42219
|
} catch (error) {
|
|
42119
42220
|
const message = `Could not prepare MCP config path for automatic setup: ${error?.message || error}`;
|
|
42120
42221
|
LOG.error("MeshCoordinator", message);
|
|
@@ -42124,7 +42225,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
42124
42225
|
const hadExistingMcpConfig = existsSync39(mcpConfigPath);
|
|
42125
42226
|
let existingMcpConfig = hermesBaseConfig?.config || {};
|
|
42126
42227
|
if (hermesBaseConfig) {
|
|
42127
|
-
copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome,
|
|
42228
|
+
copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname12(mcpConfigPath));
|
|
42128
42229
|
}
|
|
42129
42230
|
if (hadExistingMcpConfig) {
|
|
42130
42231
|
try {
|
|
@@ -42162,7 +42263,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
42162
42263
|
const cliArgs = [];
|
|
42163
42264
|
const launchEnv = {};
|
|
42164
42265
|
if (configFormat === "hermes_config_yaml") {
|
|
42165
|
-
launchEnv.HERMES_HOME =
|
|
42266
|
+
launchEnv.HERMES_HOME = dirname12(mcpConfigPath);
|
|
42166
42267
|
launchEnv.HERMES_IGNORE_USER_CONFIG = "";
|
|
42167
42268
|
}
|
|
42168
42269
|
let autoImportContextFilePath;
|
|
@@ -51104,11 +51205,11 @@ init_parse_session();
|
|
|
51104
51205
|
// src/providers/sdk/v1/fixture-tooling/replay.ts
|
|
51105
51206
|
init_provider_cli_shared();
|
|
51106
51207
|
import { readFileSync as readFileSync31 } from "fs";
|
|
51107
|
-
import { dirname as
|
|
51208
|
+
import { dirname as dirname10, resolve as resolve21 } from "path";
|
|
51108
51209
|
|
|
51109
51210
|
// src/providers/sdk/v1/validators/taint.ts
|
|
51110
51211
|
import { readFileSync as readFileSync32, existsSync as existsSync38 } from "fs";
|
|
51111
|
-
import { resolve as resolve22, dirname as
|
|
51212
|
+
import { resolve as resolve22, dirname as dirname11, join as join43 } from "path";
|
|
51112
51213
|
|
|
51113
51214
|
// src/providers/sdk/v1/validators/index.ts
|
|
51114
51215
|
init_manifest();
|