@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.js
CHANGED
|
@@ -409,10 +409,10 @@ function readInjected(value) {
|
|
|
409
409
|
}
|
|
410
410
|
function getDaemonBuildInfo() {
|
|
411
411
|
if (cached) return cached;
|
|
412
|
-
const commit = readInjected(true ? "
|
|
413
|
-
const commitShort = readInjected(true ? "
|
|
414
|
-
const version = readInjected(true ? "0.9.82-rc.
|
|
415
|
-
const builtAt = readInjected(true ? "2026-07-
|
|
412
|
+
const commit = readInjected(true ? "4d9f330890bc663a858fde1c84931144b825f8b2" : void 0) ?? "unknown";
|
|
413
|
+
const commitShort = readInjected(true ? "4d9f3308" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
414
|
+
const version = readInjected(true ? "0.9.82-rc.450" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
415
|
+
const builtAt = readInjected(true ? "2026-07-03T08:51:21.732Z" : void 0);
|
|
416
416
|
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
417
417
|
return cached;
|
|
418
418
|
}
|
|
@@ -19275,6 +19275,15 @@ function validateCondition(c, sectionIds, path44) {
|
|
|
19275
19275
|
}
|
|
19276
19276
|
if ("stable_ms" in w) {
|
|
19277
19277
|
if (typeof w.stable_ms !== "number") errs.push(`${path44}.stable_ms must be a number`);
|
|
19278
|
+
if (w.section && !sectionIds.has(w.section)) errs.push(`${path44}.section "${w.section}" unknown`);
|
|
19279
|
+
if (w.ignore_lines !== void 0) {
|
|
19280
|
+
if (typeof w.ignore_lines !== "string") errs.push(`${path44}.ignore_lines must be a string`);
|
|
19281
|
+
else try {
|
|
19282
|
+
new RegExp(w.ignore_lines, "m");
|
|
19283
|
+
} catch (e) {
|
|
19284
|
+
errs.push(`${path44}.ignore_lines invalid regex: ${e.message}`);
|
|
19285
|
+
}
|
|
19286
|
+
}
|
|
19278
19287
|
return errs;
|
|
19279
19288
|
}
|
|
19280
19289
|
errs.push(`${path44} is not a recognized condition`);
|
|
@@ -19577,10 +19586,13 @@ var init_evaluator = __esm({
|
|
|
19577
19586
|
var fsm_evaluator_exports = {};
|
|
19578
19587
|
__export(fsm_evaluator_exports, {
|
|
19579
19588
|
evaluateConditionPreview: () => evaluateConditionPreview,
|
|
19580
|
-
evaluateFsm: () => evaluateFsm
|
|
19589
|
+
evaluateFsm: () => evaluateFsm,
|
|
19590
|
+
stableRegionKey: () => stableRegionKey
|
|
19581
19591
|
});
|
|
19582
|
-
function
|
|
19583
|
-
|
|
19592
|
+
function stableRegionKey(cond) {
|
|
19593
|
+
const region = cond.section ? `section:${cond.section}` : cond.cursor_above && cond.cursor_above > 0 ? cond.cursor_above : WHOLE_SCREEN;
|
|
19594
|
+
if (!cond.ignore_lines) return region;
|
|
19595
|
+
return `${region}#ignore:${cond.ignore_lines}`;
|
|
19584
19596
|
}
|
|
19585
19597
|
function isRegex(c) {
|
|
19586
19598
|
return "matches" in c;
|
|
@@ -19628,13 +19640,14 @@ function evalCond(cond, sections, fullScreen, cursor, prevLines, clock, legacyTr
|
|
|
19628
19640
|
return { kind: "elapsed", result, detail: `elapsed ${age}ms / ${cond.elapsed_ms}ms`, remainingMs };
|
|
19629
19641
|
}
|
|
19630
19642
|
if (isStable(cond)) {
|
|
19631
|
-
const key2 =
|
|
19643
|
+
const key2 = stableRegionKey(cond);
|
|
19632
19644
|
const lastChanged = clock.regionLastChangedAt.get(key2) ?? clock.stateEnteredAt;
|
|
19633
19645
|
const stableFor = clock.now - lastChanged;
|
|
19634
19646
|
const result = stableFor >= cond.stable_ms;
|
|
19635
19647
|
const remainingMs = result ? 0 : cond.stable_ms - stableFor;
|
|
19636
|
-
const where =
|
|
19637
|
-
|
|
19648
|
+
const where = cond.section ? `section=${cond.section}` : cond.cursor_above && cond.cursor_above > 0 ? `cursor_above=${cond.cursor_above}` : "screen";
|
|
19649
|
+
const ign = cond.ignore_lines ? " (ignore_lines)" : "";
|
|
19650
|
+
return { kind: "stable", result, detail: `stable ${where}${ign} ${stableFor}ms / ${cond.stable_ms}ms`, remainingMs };
|
|
19638
19651
|
}
|
|
19639
19652
|
if (isRegex(cond) || isChanged(cond)) {
|
|
19640
19653
|
const result = evaluateCondition(cond, sections, fullScreen, cursor, prevLines, legacyTrace, stateId);
|
|
@@ -38201,8 +38214,10 @@ var FsmDriver = class {
|
|
|
38201
38214
|
// ── Clock bookkeeping for time conditions.
|
|
38202
38215
|
startedAtMs = 0;
|
|
38203
38216
|
prevScreenLines = [];
|
|
38204
|
-
/** Per
|
|
38205
|
-
*
|
|
38217
|
+
/** Per stable region → last time that region's content changed. Drives
|
|
38218
|
+
* stable_ms conditions. Key = stableRegionKey(cond): numeric cursor_above
|
|
38219
|
+
* (−1 = whole screen), or a `section:<id>` / `<region>#ignore:<pat>` string
|
|
38220
|
+
* when the clause scopes to a section or declares an ignore_lines filter. */
|
|
38206
38221
|
regionLastChangedAt = /* @__PURE__ */ new Map();
|
|
38207
38222
|
/** Timer that re-runs evaluate() when a time-condition would flip true
|
|
38208
38223
|
* with no PTY frame to trigger it. */
|
|
@@ -38628,36 +38643,55 @@ var FsmDriver = class {
|
|
|
38628
38643
|
}
|
|
38629
38644
|
return out;
|
|
38630
38645
|
}
|
|
38631
|
-
/** Track which
|
|
38632
|
-
* stable_ms conditions can measure quiet time. We record every
|
|
38633
|
-
*
|
|
38634
|
-
* screen
|
|
38646
|
+
/** Track which stable regions changed since the previous frame so
|
|
38647
|
+
* stable_ms conditions can measure quiet time. We record every distinct
|
|
38648
|
+
* stable region referenced in the current state (numeric cursor_above /
|
|
38649
|
+
* whole-screen -1, and named `section:<id>` regions) plus, for each, the
|
|
38650
|
+
* optional `ignore_lines` filter that folds into its key.
|
|
38651
|
+
*
|
|
38652
|
+
* `ignore_lines` is the content-aware fix for the busy→idle wedge: lines
|
|
38653
|
+
* matching it are stripped from BOTH frames before the comparison, so a
|
|
38654
|
+
* benign residual ticker (bare token counter / elapsed timer that repaints
|
|
38655
|
+
* every frame post-generation) no longer resets the clock — while an active
|
|
38656
|
+
* spinner line, which does NOT match the benign pattern, still does (the
|
|
38657
|
+
* FALSEIDLE2 / FALSEBUSY-B whole-screen invariant is preserved). */
|
|
38635
38658
|
trackRegionChanges(currentLines, cursor, now) {
|
|
38636
38659
|
if (this.prevScreenLines.length === 0) return;
|
|
38637
|
-
const
|
|
38638
|
-
|
|
38639
|
-
|
|
38640
|
-
|
|
38641
|
-
|
|
38642
|
-
|
|
38643
|
-
|
|
38660
|
+
const descs = this.stableRegionDescriptors();
|
|
38661
|
+
const needsSections = descs.some((d) => !!d.section);
|
|
38662
|
+
const curSections = needsSections ? resolveSections(this.spec.sections ?? {}, currentLines) : [];
|
|
38663
|
+
const prevSections = needsSections ? resolveSections(this.spec.sections ?? {}, this.prevScreenLines) : [];
|
|
38664
|
+
for (const d of descs) {
|
|
38665
|
+
let curLines;
|
|
38666
|
+
let prevLines;
|
|
38667
|
+
if (d.section) {
|
|
38668
|
+
curLines = sliceSectionLines(currentLines, curSections, d.section);
|
|
38669
|
+
prevLines = sliceSectionLines(this.prevScreenLines, prevSections, d.section);
|
|
38670
|
+
} else if (!d.cursor_above || d.cursor_above <= 0) {
|
|
38671
|
+
curLines = currentLines;
|
|
38672
|
+
prevLines = this.prevScreenLines;
|
|
38644
38673
|
} else {
|
|
38645
|
-
const start = Math.max(0, cursor.row -
|
|
38646
|
-
|
|
38647
|
-
|
|
38648
|
-
}
|
|
38649
|
-
|
|
38650
|
-
|
|
38651
|
-
|
|
38652
|
-
|
|
38653
|
-
|
|
38654
|
-
|
|
38655
|
-
|
|
38656
|
-
|
|
38674
|
+
const start = Math.max(0, cursor.row - d.cursor_above);
|
|
38675
|
+
curLines = currentLines.slice(start, cursor.row);
|
|
38676
|
+
prevLines = this.prevScreenLines.slice(start, cursor.row);
|
|
38677
|
+
}
|
|
38678
|
+
const cur = filterIgnoredLines(curLines, d.ignoreRe).join("\n");
|
|
38679
|
+
const prev = filterIgnoredLines(prevLines, d.ignoreRe).join("\n");
|
|
38680
|
+
if (cur !== prev) this.regionLastChangedAt.set(d.key, now);
|
|
38681
|
+
}
|
|
38682
|
+
}
|
|
38683
|
+
/** Every distinct stable-region descriptor referenced by stable_ms
|
|
38684
|
+
* conditions in the current state's outgoing transitions, plus the plain
|
|
38685
|
+
* whole-screen key (-1) that other machinery (stall watchdog) reads.
|
|
38686
|
+
* De-duplicated by key. Cached lazily per spec load would be nicer but the
|
|
38687
|
+
* set is tiny. */
|
|
38688
|
+
stableRegionDescriptors() {
|
|
38689
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
38690
|
+
byKey.set(-1, { key: -1 });
|
|
38657
38691
|
for (const t of outgoingTransitions(this.spec, this.currentStateId)) {
|
|
38658
|
-
|
|
38692
|
+
collectStableDescriptors(t.when, byKey);
|
|
38659
38693
|
}
|
|
38660
|
-
return
|
|
38694
|
+
return [...byKey.values()];
|
|
38661
38695
|
}
|
|
38662
38696
|
/** Schedule a re-evaluation for the soonest pending time-condition on any
|
|
38663
38697
|
* outgoing transition (elapsed_ms / stable_ms / min_hold_ms). Without
|
|
@@ -39154,26 +39188,45 @@ function findStable(c) {
|
|
|
39154
39188
|
}
|
|
39155
39189
|
return null;
|
|
39156
39190
|
}
|
|
39157
|
-
function
|
|
39191
|
+
function collectStableDescriptors(when, byKey) {
|
|
39158
39192
|
if (!when) return;
|
|
39159
39193
|
const w = when;
|
|
39160
39194
|
if ("stable_ms" in w) {
|
|
39161
|
-
|
|
39195
|
+
const key2 = stableRegionKey(w);
|
|
39196
|
+
if (!byKey.has(key2)) {
|
|
39197
|
+
let ignoreRe;
|
|
39198
|
+
if (w.ignore_lines) {
|
|
39199
|
+
try {
|
|
39200
|
+
ignoreRe = new RegExp(w.ignore_lines, "m");
|
|
39201
|
+
} catch {
|
|
39202
|
+
}
|
|
39203
|
+
}
|
|
39204
|
+
byKey.set(key2, { key: key2, section: w.section, cursor_above: w.cursor_above, ignoreRe });
|
|
39205
|
+
}
|
|
39162
39206
|
return;
|
|
39163
39207
|
}
|
|
39164
39208
|
if ("all" in w) {
|
|
39165
|
-
for (const c of w.all)
|
|
39209
|
+
for (const c of w.all) collectStableDescriptors(c, byKey);
|
|
39166
39210
|
return;
|
|
39167
39211
|
}
|
|
39168
39212
|
if ("any" in w) {
|
|
39169
|
-
for (const c of w.any)
|
|
39213
|
+
for (const c of w.any) collectStableDescriptors(c, byKey);
|
|
39170
39214
|
return;
|
|
39171
39215
|
}
|
|
39172
39216
|
if ("not" in w) {
|
|
39173
|
-
|
|
39217
|
+
collectStableDescriptors(w.not, byKey);
|
|
39174
39218
|
return;
|
|
39175
39219
|
}
|
|
39176
39220
|
}
|
|
39221
|
+
function sliceSectionLines(lines, sections, id) {
|
|
39222
|
+
const sec = sections.find((s2) => s2.id === id);
|
|
39223
|
+
if (!sec) return [];
|
|
39224
|
+
return lines.slice(sec.fromLine, sec.toLine);
|
|
39225
|
+
}
|
|
39226
|
+
function filterIgnoredLines(lines, ignoreRe) {
|
|
39227
|
+
if (!ignoreRe) return lines;
|
|
39228
|
+
return lines.filter((l) => !ignoreRe.test(l));
|
|
39229
|
+
}
|
|
39177
39230
|
|
|
39178
39231
|
// src/providers/spec/cli-adapter.ts
|
|
39179
39232
|
init_evaluator();
|