@adhdev/daemon-core 0.9.82-rc.449 → 0.9.82-rc.450
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 +95 -42
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +95 -42
- package/dist/index.mjs.map +1 -1
- package/dist/providers/spec/fsm-driver.d.ts +26 -10
- package/dist/providers/spec/fsm-evaluator.d.ts +20 -3
- package/dist/providers/spec/fsm-types.d.ts +31 -3
- package/package.json +2 -2
- package/src/providers/spec/fsm-driver.ts +92 -30
- package/src/providers/spec/fsm-evaluator.ts +26 -8
- package/src/providers/spec/fsm-loader.ts +9 -1
- package/src/providers/spec/fsm-types.ts +31 -3
package/dist/index.mjs
CHANGED
|
@@ -404,10 +404,10 @@ function readInjected(value) {
|
|
|
404
404
|
}
|
|
405
405
|
function getDaemonBuildInfo() {
|
|
406
406
|
if (cached) return cached;
|
|
407
|
-
const commit = readInjected(true ? "
|
|
408
|
-
const commitShort = readInjected(true ? "
|
|
409
|
-
const version = readInjected(true ? "0.9.82-rc.
|
|
410
|
-
const builtAt = readInjected(true ? "2026-07-
|
|
407
|
+
const commit = readInjected(true ? "4d9f330890bc663a858fde1c84931144b825f8b2" : void 0) ?? "unknown";
|
|
408
|
+
const commitShort = readInjected(true ? "4d9f3308" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
409
|
+
const version = readInjected(true ? "0.9.82-rc.450" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
410
|
+
const builtAt = readInjected(true ? "2026-07-03T08:51:21.732Z" : void 0);
|
|
411
411
|
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
412
412
|
return cached;
|
|
413
413
|
}
|
|
@@ -19271,6 +19271,15 @@ function validateCondition(c, sectionIds, path44) {
|
|
|
19271
19271
|
}
|
|
19272
19272
|
if ("stable_ms" in w) {
|
|
19273
19273
|
if (typeof w.stable_ms !== "number") errs.push(`${path44}.stable_ms must be a number`);
|
|
19274
|
+
if (w.section && !sectionIds.has(w.section)) errs.push(`${path44}.section "${w.section}" unknown`);
|
|
19275
|
+
if (w.ignore_lines !== void 0) {
|
|
19276
|
+
if (typeof w.ignore_lines !== "string") errs.push(`${path44}.ignore_lines must be a string`);
|
|
19277
|
+
else try {
|
|
19278
|
+
new RegExp(w.ignore_lines, "m");
|
|
19279
|
+
} catch (e) {
|
|
19280
|
+
errs.push(`${path44}.ignore_lines invalid regex: ${e.message}`);
|
|
19281
|
+
}
|
|
19282
|
+
}
|
|
19274
19283
|
return errs;
|
|
19275
19284
|
}
|
|
19276
19285
|
errs.push(`${path44} is not a recognized condition`);
|
|
@@ -19571,10 +19580,13 @@ var init_evaluator = __esm({
|
|
|
19571
19580
|
var fsm_evaluator_exports = {};
|
|
19572
19581
|
__export(fsm_evaluator_exports, {
|
|
19573
19582
|
evaluateConditionPreview: () => evaluateConditionPreview,
|
|
19574
|
-
evaluateFsm: () => evaluateFsm
|
|
19583
|
+
evaluateFsm: () => evaluateFsm,
|
|
19584
|
+
stableRegionKey: () => stableRegionKey
|
|
19575
19585
|
});
|
|
19576
|
-
function
|
|
19577
|
-
|
|
19586
|
+
function stableRegionKey(cond) {
|
|
19587
|
+
const region = cond.section ? `section:${cond.section}` : cond.cursor_above && cond.cursor_above > 0 ? cond.cursor_above : WHOLE_SCREEN;
|
|
19588
|
+
if (!cond.ignore_lines) return region;
|
|
19589
|
+
return `${region}#ignore:${cond.ignore_lines}`;
|
|
19578
19590
|
}
|
|
19579
19591
|
function isRegex(c) {
|
|
19580
19592
|
return "matches" in c;
|
|
@@ -19622,13 +19634,14 @@ function evalCond(cond, sections, fullScreen, cursor, prevLines, clock, legacyTr
|
|
|
19622
19634
|
return { kind: "elapsed", result, detail: `elapsed ${age}ms / ${cond.elapsed_ms}ms`, remainingMs };
|
|
19623
19635
|
}
|
|
19624
19636
|
if (isStable(cond)) {
|
|
19625
|
-
const key2 =
|
|
19637
|
+
const key2 = stableRegionKey(cond);
|
|
19626
19638
|
const lastChanged = clock.regionLastChangedAt.get(key2) ?? clock.stateEnteredAt;
|
|
19627
19639
|
const stableFor = clock.now - lastChanged;
|
|
19628
19640
|
const result = stableFor >= cond.stable_ms;
|
|
19629
19641
|
const remainingMs = result ? 0 : cond.stable_ms - stableFor;
|
|
19630
|
-
const where =
|
|
19631
|
-
|
|
19642
|
+
const where = cond.section ? `section=${cond.section}` : cond.cursor_above && cond.cursor_above > 0 ? `cursor_above=${cond.cursor_above}` : "screen";
|
|
19643
|
+
const ign = cond.ignore_lines ? " (ignore_lines)" : "";
|
|
19644
|
+
return { kind: "stable", result, detail: `stable ${where}${ign} ${stableFor}ms / ${cond.stable_ms}ms`, remainingMs };
|
|
19632
19645
|
}
|
|
19633
19646
|
if (isRegex(cond) || isChanged(cond)) {
|
|
19634
19647
|
const result = evaluateCondition(cond, sections, fullScreen, cursor, prevLines, legacyTrace, stateId);
|
|
@@ -37788,8 +37801,10 @@ var FsmDriver = class {
|
|
|
37788
37801
|
// ── Clock bookkeeping for time conditions.
|
|
37789
37802
|
startedAtMs = 0;
|
|
37790
37803
|
prevScreenLines = [];
|
|
37791
|
-
/** Per
|
|
37792
|
-
*
|
|
37804
|
+
/** Per stable region → last time that region's content changed. Drives
|
|
37805
|
+
* stable_ms conditions. Key = stableRegionKey(cond): numeric cursor_above
|
|
37806
|
+
* (−1 = whole screen), or a `section:<id>` / `<region>#ignore:<pat>` string
|
|
37807
|
+
* when the clause scopes to a section or declares an ignore_lines filter. */
|
|
37793
37808
|
regionLastChangedAt = /* @__PURE__ */ new Map();
|
|
37794
37809
|
/** Timer that re-runs evaluate() when a time-condition would flip true
|
|
37795
37810
|
* with no PTY frame to trigger it. */
|
|
@@ -38215,36 +38230,55 @@ var FsmDriver = class {
|
|
|
38215
38230
|
}
|
|
38216
38231
|
return out;
|
|
38217
38232
|
}
|
|
38218
|
-
/** Track which
|
|
38219
|
-
* stable_ms conditions can measure quiet time. We record every
|
|
38220
|
-
*
|
|
38221
|
-
* screen
|
|
38233
|
+
/** Track which stable regions changed since the previous frame so
|
|
38234
|
+
* stable_ms conditions can measure quiet time. We record every distinct
|
|
38235
|
+
* stable region referenced in the current state (numeric cursor_above /
|
|
38236
|
+
* whole-screen -1, and named `section:<id>` regions) plus, for each, the
|
|
38237
|
+
* optional `ignore_lines` filter that folds into its key.
|
|
38238
|
+
*
|
|
38239
|
+
* `ignore_lines` is the content-aware fix for the busy→idle wedge: lines
|
|
38240
|
+
* matching it are stripped from BOTH frames before the comparison, so a
|
|
38241
|
+
* benign residual ticker (bare token counter / elapsed timer that repaints
|
|
38242
|
+
* every frame post-generation) no longer resets the clock — while an active
|
|
38243
|
+
* spinner line, which does NOT match the benign pattern, still does (the
|
|
38244
|
+
* FALSEIDLE2 / FALSEBUSY-B whole-screen invariant is preserved). */
|
|
38222
38245
|
trackRegionChanges(currentLines, cursor, now) {
|
|
38223
38246
|
if (this.prevScreenLines.length === 0) return;
|
|
38224
|
-
const
|
|
38225
|
-
|
|
38226
|
-
|
|
38227
|
-
|
|
38228
|
-
|
|
38229
|
-
|
|
38230
|
-
|
|
38247
|
+
const descs = this.stableRegionDescriptors();
|
|
38248
|
+
const needsSections = descs.some((d) => !!d.section);
|
|
38249
|
+
const curSections = needsSections ? resolveSections(this.spec.sections ?? {}, currentLines) : [];
|
|
38250
|
+
const prevSections = needsSections ? resolveSections(this.spec.sections ?? {}, this.prevScreenLines) : [];
|
|
38251
|
+
for (const d of descs) {
|
|
38252
|
+
let curLines;
|
|
38253
|
+
let prevLines;
|
|
38254
|
+
if (d.section) {
|
|
38255
|
+
curLines = sliceSectionLines(currentLines, curSections, d.section);
|
|
38256
|
+
prevLines = sliceSectionLines(this.prevScreenLines, prevSections, d.section);
|
|
38257
|
+
} else if (!d.cursor_above || d.cursor_above <= 0) {
|
|
38258
|
+
curLines = currentLines;
|
|
38259
|
+
prevLines = this.prevScreenLines;
|
|
38231
38260
|
} else {
|
|
38232
|
-
const start = Math.max(0, cursor.row -
|
|
38233
|
-
|
|
38234
|
-
|
|
38235
|
-
}
|
|
38236
|
-
|
|
38237
|
-
|
|
38238
|
-
|
|
38239
|
-
|
|
38240
|
-
|
|
38241
|
-
|
|
38242
|
-
|
|
38243
|
-
|
|
38261
|
+
const start = Math.max(0, cursor.row - d.cursor_above);
|
|
38262
|
+
curLines = currentLines.slice(start, cursor.row);
|
|
38263
|
+
prevLines = this.prevScreenLines.slice(start, cursor.row);
|
|
38264
|
+
}
|
|
38265
|
+
const cur = filterIgnoredLines(curLines, d.ignoreRe).join("\n");
|
|
38266
|
+
const prev = filterIgnoredLines(prevLines, d.ignoreRe).join("\n");
|
|
38267
|
+
if (cur !== prev) this.regionLastChangedAt.set(d.key, now);
|
|
38268
|
+
}
|
|
38269
|
+
}
|
|
38270
|
+
/** Every distinct stable-region descriptor referenced by stable_ms
|
|
38271
|
+
* conditions in the current state's outgoing transitions, plus the plain
|
|
38272
|
+
* whole-screen key (-1) that other machinery (stall watchdog) reads.
|
|
38273
|
+
* De-duplicated by key. Cached lazily per spec load would be nicer but the
|
|
38274
|
+
* set is tiny. */
|
|
38275
|
+
stableRegionDescriptors() {
|
|
38276
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
38277
|
+
byKey.set(-1, { key: -1 });
|
|
38244
38278
|
for (const t of outgoingTransitions(this.spec, this.currentStateId)) {
|
|
38245
|
-
|
|
38279
|
+
collectStableDescriptors(t.when, byKey);
|
|
38246
38280
|
}
|
|
38247
|
-
return
|
|
38281
|
+
return [...byKey.values()];
|
|
38248
38282
|
}
|
|
38249
38283
|
/** Schedule a re-evaluation for the soonest pending time-condition on any
|
|
38250
38284
|
* outgoing transition (elapsed_ms / stable_ms / min_hold_ms). Without
|
|
@@ -38741,26 +38775,45 @@ function findStable(c) {
|
|
|
38741
38775
|
}
|
|
38742
38776
|
return null;
|
|
38743
38777
|
}
|
|
38744
|
-
function
|
|
38778
|
+
function collectStableDescriptors(when, byKey) {
|
|
38745
38779
|
if (!when) return;
|
|
38746
38780
|
const w = when;
|
|
38747
38781
|
if ("stable_ms" in w) {
|
|
38748
|
-
|
|
38782
|
+
const key2 = stableRegionKey(w);
|
|
38783
|
+
if (!byKey.has(key2)) {
|
|
38784
|
+
let ignoreRe;
|
|
38785
|
+
if (w.ignore_lines) {
|
|
38786
|
+
try {
|
|
38787
|
+
ignoreRe = new RegExp(w.ignore_lines, "m");
|
|
38788
|
+
} catch {
|
|
38789
|
+
}
|
|
38790
|
+
}
|
|
38791
|
+
byKey.set(key2, { key: key2, section: w.section, cursor_above: w.cursor_above, ignoreRe });
|
|
38792
|
+
}
|
|
38749
38793
|
return;
|
|
38750
38794
|
}
|
|
38751
38795
|
if ("all" in w) {
|
|
38752
|
-
for (const c of w.all)
|
|
38796
|
+
for (const c of w.all) collectStableDescriptors(c, byKey);
|
|
38753
38797
|
return;
|
|
38754
38798
|
}
|
|
38755
38799
|
if ("any" in w) {
|
|
38756
|
-
for (const c of w.any)
|
|
38800
|
+
for (const c of w.any) collectStableDescriptors(c, byKey);
|
|
38757
38801
|
return;
|
|
38758
38802
|
}
|
|
38759
38803
|
if ("not" in w) {
|
|
38760
|
-
|
|
38804
|
+
collectStableDescriptors(w.not, byKey);
|
|
38761
38805
|
return;
|
|
38762
38806
|
}
|
|
38763
38807
|
}
|
|
38808
|
+
function sliceSectionLines(lines, sections, id) {
|
|
38809
|
+
const sec = sections.find((s2) => s2.id === id);
|
|
38810
|
+
if (!sec) return [];
|
|
38811
|
+
return lines.slice(sec.fromLine, sec.toLine);
|
|
38812
|
+
}
|
|
38813
|
+
function filterIgnoredLines(lines, ignoreRe) {
|
|
38814
|
+
if (!ignoreRe) return lines;
|
|
38815
|
+
return lines.filter((l) => !ignoreRe.test(l));
|
|
38816
|
+
}
|
|
38764
38817
|
|
|
38765
38818
|
// src/providers/spec/cli-adapter.ts
|
|
38766
38819
|
init_evaluator();
|