@adhdev/daemon-core 0.9.82-rc.197 → 0.9.82-rc.199
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.js
CHANGED
|
@@ -15005,8 +15005,8 @@ async function detectIDEs(providerLoader) {
|
|
|
15005
15005
|
if ((0, import_fs11.existsSync)(bundledCli)) resolvedCli = bundledCli;
|
|
15006
15006
|
}
|
|
15007
15007
|
if (!resolvedCli && appPath && os29 === "win32") {
|
|
15008
|
-
const { dirname:
|
|
15009
|
-
const appDir =
|
|
15008
|
+
const { dirname: dirname12 } = await import("path");
|
|
15009
|
+
const appDir = dirname12(appPath);
|
|
15010
15010
|
const candidates = [
|
|
15011
15011
|
`${appDir}\\\\bin\\\\${def.cli}.cmd`,
|
|
15012
15012
|
`${appDir}\\\\bin\\\\${def.cli}`,
|
|
@@ -27489,7 +27489,15 @@ var SpecDriver = class {
|
|
|
27489
27489
|
* explicit wake-up there's nothing to trigger the busy → idle
|
|
27490
27490
|
* downshift. */
|
|
27491
27491
|
busyExpiryTimer = null;
|
|
27492
|
+
/** Pending idle-commit timer. Armed when the evaluator first returns idle;
|
|
27493
|
+
* fires after idle_hold_ms if no non-idle reading has cancelled it. */
|
|
27494
|
+
idleHoldTimer = null;
|
|
27495
|
+
/** State snapshot captured when the idle hold was armed — emitted on commit. */
|
|
27496
|
+
pendingIdleState = null;
|
|
27492
27497
|
specWatcher = null;
|
|
27498
|
+
/** Ring buffer of committed state transitions (max 50). */
|
|
27499
|
+
stateHistory = [];
|
|
27500
|
+
prevStateAt = 0;
|
|
27493
27501
|
/** Subscribe to outbound events. Returns an unsubscribe fn. */
|
|
27494
27502
|
subscribe(listener) {
|
|
27495
27503
|
this.listeners.add(listener);
|
|
@@ -27540,9 +27548,40 @@ var SpecDriver = class {
|
|
|
27540
27548
|
shutdown() {
|
|
27541
27549
|
for (const t of this.delegateTimers.values()) clearTimeout(t);
|
|
27542
27550
|
this.delegateTimers.clear();
|
|
27551
|
+
this.cancelIdleHold();
|
|
27552
|
+
if (this.busyExpiryTimer) {
|
|
27553
|
+
clearTimeout(this.busyExpiryTimer);
|
|
27554
|
+
this.busyExpiryTimer = null;
|
|
27555
|
+
}
|
|
27543
27556
|
this.specWatcher?.close();
|
|
27544
27557
|
this.adapter.kill();
|
|
27545
27558
|
}
|
|
27559
|
+
cancelIdleHold() {
|
|
27560
|
+
if (this.idleHoldTimer) {
|
|
27561
|
+
clearTimeout(this.idleHoldTimer);
|
|
27562
|
+
this.idleHoldTimer = null;
|
|
27563
|
+
}
|
|
27564
|
+
this.pendingIdleState = null;
|
|
27565
|
+
}
|
|
27566
|
+
pushHistory(stateId, label) {
|
|
27567
|
+
const now = Date.now();
|
|
27568
|
+
const durationMs = this.prevStateAt > 0 ? now - this.prevStateAt : 0;
|
|
27569
|
+
this.prevStateAt = now;
|
|
27570
|
+
this.stateHistory.push({ stateId, label, at: now, durationMs });
|
|
27571
|
+
if (this.stateHistory.length > 50) this.stateHistory.shift();
|
|
27572
|
+
}
|
|
27573
|
+
getStateHistory() {
|
|
27574
|
+
return this.stateHistory;
|
|
27575
|
+
}
|
|
27576
|
+
getLastBusyAt() {
|
|
27577
|
+
return this.lastBusyAt;
|
|
27578
|
+
}
|
|
27579
|
+
hasIdleHoldPending() {
|
|
27580
|
+
return this.idleHoldTimer !== null;
|
|
27581
|
+
}
|
|
27582
|
+
getSpecPath() {
|
|
27583
|
+
return this.opts.specPath;
|
|
27584
|
+
}
|
|
27546
27585
|
// ────────────────────────────────────────────────────────────────────
|
|
27547
27586
|
// Loading & adapter wiring
|
|
27548
27587
|
// ────────────────────────────────────────────────────────────────────
|
|
@@ -27566,7 +27605,10 @@ var SpecDriver = class {
|
|
|
27566
27605
|
}
|
|
27567
27606
|
armSpecWatcher() {
|
|
27568
27607
|
try {
|
|
27569
|
-
|
|
27608
|
+
const dir = path19.dirname(this.opts.specPath);
|
|
27609
|
+
const base = path19.basename(this.opts.specPath);
|
|
27610
|
+
this.specWatcher = fs10.watch(dir, { persistent: false }, (_event, filename) => {
|
|
27611
|
+
if (filename && filename !== base) return;
|
|
27570
27612
|
const res = loadSpec(this.opts.specPath);
|
|
27571
27613
|
if (!res.ok) {
|
|
27572
27614
|
this.emit({ kind: "spec_error", errors: res.errors });
|
|
@@ -27650,7 +27692,46 @@ var SpecDriver = class {
|
|
|
27650
27692
|
if (evState.id === "busy") {
|
|
27651
27693
|
this.lastBusyAt = Date.now();
|
|
27652
27694
|
this.lastBusyState = evState;
|
|
27695
|
+
this.cancelIdleHold();
|
|
27653
27696
|
this.scheduleBusyExpiry(busyWakeMs);
|
|
27697
|
+
} else if (evState.id !== this.currentStateId && evState.id !== "busy") {
|
|
27698
|
+
if (evState.id !== (this.spec.default_state ?? "idle")) {
|
|
27699
|
+
this.cancelIdleHold();
|
|
27700
|
+
}
|
|
27701
|
+
}
|
|
27702
|
+
const idleHoldMs = this.spec.debounce?.idle_hold_ms ?? 0;
|
|
27703
|
+
const isIdleState = evState.id === (this.spec.default_state ?? "idle");
|
|
27704
|
+
if (isIdleState && idleHoldMs > 0 && this.currentStateId !== evState.id) {
|
|
27705
|
+
if (!this.idleHoldTimer) {
|
|
27706
|
+
this.pendingIdleState = evState;
|
|
27707
|
+
this.idleHoldTimer = setTimeout(() => {
|
|
27708
|
+
this.idleHoldTimer = null;
|
|
27709
|
+
const committed = this.pendingIdleState;
|
|
27710
|
+
this.pendingIdleState = null;
|
|
27711
|
+
if (!committed) return;
|
|
27712
|
+
LOG.debug("SpecDriver", `[${this.opts.specPath.split("/").slice(-3).join("/")}] idleHold committed after ${idleHoldMs}ms`);
|
|
27713
|
+
this.currentStateId = committed.id;
|
|
27714
|
+
this.currentEval = ev;
|
|
27715
|
+
this.pushHistory(committed.id, committed.label);
|
|
27716
|
+
this.emit({
|
|
27717
|
+
kind: "state_changed",
|
|
27718
|
+
state: committed,
|
|
27719
|
+
modal: null,
|
|
27720
|
+
controls: ev.controls.map((c) => ({ id: c.id, label: c.label, action_type: c.actionType }))
|
|
27721
|
+
});
|
|
27722
|
+
this.armOrCancelDelegateTimers(committed.id);
|
|
27723
|
+
if (this.opts.emitTrace) this.emit({ kind: "spec_trace", entries: ev.trace });
|
|
27724
|
+
}, idleHoldMs);
|
|
27725
|
+
}
|
|
27726
|
+
this.currentEval = ev;
|
|
27727
|
+
const graceMs2 = this.spec.debounce?.startup_grace_ms ?? STARTUP_GRACE_MS;
|
|
27728
|
+
if (!this.idleSeenOnce && Date.now() - this.startedAtMs >= graceMs2) {
|
|
27729
|
+
this.idleSeenOnce = true;
|
|
27730
|
+
const queued = this.pendingSends.splice(0);
|
|
27731
|
+
for (const text of queued) setTimeout(() => this.actuallySendMessage(text), 50);
|
|
27732
|
+
}
|
|
27733
|
+
if (this.pickerInProgress) this.tryAdvancePicker(screen);
|
|
27734
|
+
return;
|
|
27654
27735
|
}
|
|
27655
27736
|
const changed = forceEmit || evState.id !== this.currentStateId || !shallowSameModal(ev, this.currentEval) || !shallowSameControls(ev, this.currentEval);
|
|
27656
27737
|
if (this.pickerInProgress) this.tryAdvancePicker(screen);
|
|
@@ -27666,6 +27747,7 @@ var SpecDriver = class {
|
|
|
27666
27747
|
}
|
|
27667
27748
|
if (changed) {
|
|
27668
27749
|
this.currentStateId = evState.id;
|
|
27750
|
+
this.pushHistory(evState.id, evState.label);
|
|
27669
27751
|
this.emit({
|
|
27670
27752
|
kind: "state_changed",
|
|
27671
27753
|
state: evState,
|
|
@@ -28099,7 +28181,11 @@ var SpecCliAdapter = class {
|
|
|
28099
28181
|
activeInteractivePrompt: this.activeInteractivePrompt,
|
|
28100
28182
|
exited: this.exited,
|
|
28101
28183
|
screen,
|
|
28102
|
-
sections
|
|
28184
|
+
sections,
|
|
28185
|
+
stateHistory: this.driver.getStateHistory(),
|
|
28186
|
+
idleHoldPending: this.driver.hasIdleHoldPending(),
|
|
28187
|
+
lastBusyAt: this.driver.getLastBusyAt(),
|
|
28188
|
+
specPath: this.driver.getSpecPath()
|
|
28103
28189
|
};
|
|
28104
28190
|
}
|
|
28105
28191
|
getRuntimeMetadata() {
|
|
@@ -33638,17 +33724,17 @@ function parseTranscriptFile(filePath, sessionId, workspaceFallback) {
|
|
|
33638
33724
|
}
|
|
33639
33725
|
function readSession(sessionPath) {
|
|
33640
33726
|
if (!sessionPath || !path25.isAbsolute(sessionPath)) return null;
|
|
33641
|
-
const
|
|
33642
|
-
if (!isSafeSessionId(
|
|
33727
|
+
const basename14 = path25.basename(sessionPath, ".jsonl");
|
|
33728
|
+
if (!isSafeSessionId(basename14)) return null;
|
|
33643
33729
|
if (!fs14.existsSync(sessionPath)) return null;
|
|
33644
33730
|
const sourceMtimeMs = statMtimeMs(sessionPath);
|
|
33645
|
-
const messages = parseTranscriptFile(sessionPath,
|
|
33731
|
+
const messages = parseTranscriptFile(sessionPath, basename14);
|
|
33646
33732
|
if (messages.length === 0) return null;
|
|
33647
33733
|
const firstSystem = messages.find((m) => m.kind === "session_start");
|
|
33648
33734
|
const workspace = firstSystem?.workspace || firstSystem?.content || void 0;
|
|
33649
33735
|
return {
|
|
33650
33736
|
messages,
|
|
33651
|
-
providerSessionId:
|
|
33737
|
+
providerSessionId: basename14,
|
|
33652
33738
|
source: "provider-native",
|
|
33653
33739
|
sourcePath: sessionPath,
|
|
33654
33740
|
sourceMtimeMs,
|
|
@@ -33850,8 +33936,8 @@ function readSession2(sessionPath) {
|
|
|
33850
33936
|
if (!fs15.existsSync(sessionPath)) return null;
|
|
33851
33937
|
const meta = readSessionMeta(sessionPath);
|
|
33852
33938
|
const metaId = String(meta?.id ?? "").trim();
|
|
33853
|
-
const
|
|
33854
|
-
const uuidMatch =
|
|
33939
|
+
const basename14 = path26.basename(sessionPath, ".jsonl");
|
|
33940
|
+
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);
|
|
33855
33941
|
const filenameUuid2 = uuidMatch ? uuidMatch[1] : "";
|
|
33856
33942
|
if (metaId && filenameUuid2 && metaId !== filenameUuid2) return null;
|
|
33857
33943
|
const sessionId = metaId || filenameUuid2;
|
|
@@ -41063,6 +41149,21 @@ var DaemonCommandRouter = class {
|
|
|
41063
41149
|
} : null
|
|
41064
41150
|
};
|
|
41065
41151
|
}
|
|
41152
|
+
case "get_spec_debug": {
|
|
41153
|
+
const sessionId = typeof args?.targetSessionId === "string" ? args.targetSessionId.trim() : typeof args?.sessionId === "string" ? args.sessionId.trim() : "";
|
|
41154
|
+
if (!sessionId) return { success: false, error: "targetSessionId required" };
|
|
41155
|
+
const target = this.deps.sessionRegistry.get(sessionId);
|
|
41156
|
+
if (!target) return { success: false, error: "Session not found", sessionId };
|
|
41157
|
+
const adapter = this.deps.cliManager.findAdapter(target.providerType, { instanceKey: sessionId })?.adapter;
|
|
41158
|
+
const snapshot = adapter && typeof adapter.getDebugSnapshot === "function" ? adapter.getDebugSnapshot() : null;
|
|
41159
|
+
return {
|
|
41160
|
+
success: true,
|
|
41161
|
+
sessionId,
|
|
41162
|
+
providerType: target.providerType,
|
|
41163
|
+
isSpecProvider: snapshot !== null,
|
|
41164
|
+
snapshot
|
|
41165
|
+
};
|
|
41166
|
+
}
|
|
41066
41167
|
// ── User-level coordinator-prompt files (~/.adhdev/coordinator-prompts/).
|
|
41067
41168
|
// These live on this daemon's filesystem and never sync to the
|
|
41068
41169
|
// cloud / other daemons — they're per-machine config. The
|
|
@@ -42390,7 +42491,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
42390
42491
|
};
|
|
42391
42492
|
}
|
|
42392
42493
|
const { existsSync: existsSync39, readFileSync: readFileSync33, writeFileSync: writeFileSync21, copyFileSync: copyFileSync4, mkdirSync: mkdirSync19 } = await import("fs");
|
|
42393
|
-
const { dirname:
|
|
42494
|
+
const { dirname: dirname12 } = await import("path");
|
|
42394
42495
|
const mcpConfigPath = coordinatorSetup.configPath;
|
|
42395
42496
|
const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
|
|
42396
42497
|
let hermesBaseConfig = null;
|
|
@@ -42425,7 +42526,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
42425
42526
|
};
|
|
42426
42527
|
}
|
|
42427
42528
|
try {
|
|
42428
|
-
mkdirSync19(
|
|
42529
|
+
mkdirSync19(dirname12(mcpConfigPath), { recursive: true });
|
|
42429
42530
|
} catch (error) {
|
|
42430
42531
|
const message = `Could not prepare MCP config path for automatic setup: ${error?.message || error}`;
|
|
42431
42532
|
LOG.error("MeshCoordinator", message);
|
|
@@ -42435,7 +42536,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
42435
42536
|
const hadExistingMcpConfig = existsSync39(mcpConfigPath);
|
|
42436
42537
|
let existingMcpConfig = hermesBaseConfig?.config || {};
|
|
42437
42538
|
if (hermesBaseConfig) {
|
|
42438
|
-
copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome,
|
|
42539
|
+
copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname12(mcpConfigPath));
|
|
42439
42540
|
}
|
|
42440
42541
|
if (hadExistingMcpConfig) {
|
|
42441
42542
|
try {
|
|
@@ -42473,7 +42574,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
42473
42574
|
const cliArgs = [];
|
|
42474
42575
|
const launchEnv = {};
|
|
42475
42576
|
if (configFormat === "hermes_config_yaml") {
|
|
42476
|
-
launchEnv.HERMES_HOME =
|
|
42577
|
+
launchEnv.HERMES_HOME = dirname12(mcpConfigPath);
|
|
42477
42578
|
launchEnv.HERMES_IGNORE_USER_CONFIG = "";
|
|
42478
42579
|
}
|
|
42479
42580
|
let autoImportContextFilePath;
|