@adhdev/daemon-core 0.9.82-rc.202 → 0.9.82-rc.204

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adhdev/daemon-core",
3
- "version": "0.9.82-rc.202",
3
+ "version": "0.9.82-rc.204",
4
4
  "description": "ADHDev daemon core — CDP, IDE detection, providers, command execution",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -324,21 +324,11 @@ export class SpecCliAdapter implements CliAdapter {
324
324
  let sections: Record<string, string> | undefined;
325
325
  try {
326
326
  screen = this.driver.snapshot();
327
- const lines = screen.split('\n');
328
- sections = {};
329
- for (const sec of this.spec.layout?.sections ?? []) {
330
- const from = (sec as any).from_top;
331
- const fromBottom = (sec as any).from_bottom;
332
- let start = 0;
333
- let end = lines.length;
334
- if (typeof from === 'number') start = Math.max(0, from);
335
- else if (typeof fromBottom === 'number') start = Math.max(0, lines.length - fromBottom);
336
- const until = (sec as any).until;
337
- if (until && typeof until === 'object' && typeof until.section === 'string') {
338
- const ref = (this.spec.layout?.sections ?? []).find((s: any) => s.id === until.section) as any;
339
- if (ref && typeof ref.from_bottom === 'number') end = Math.max(start, lines.length - ref.from_bottom);
340
- }
341
- sections[(sec as any).id] = lines.slice(start, end).join('\n');
327
+ const driverSections = this.driver.getSections?.();
328
+ if (driverSections) {
329
+ sections = Object.fromEntries(driverSections.map(s => [s.id, s.text]));
330
+ } else {
331
+ sections = this.readCurrentScreenSections(screen);
342
332
  }
343
333
  } catch { /* best-effort */ }
344
334
  // Read native transcript messages for the debug snapshot
@@ -281,7 +281,11 @@ export function evaluate(
281
281
  cursor?: { row: number; col: number },
282
282
  ): SpecEvaluation {
283
283
  const trace: TraceEntry[] = [];
284
- const lines = screenText.split('\n');
284
+ const lines = screenText.split('\n').map(l => l.endsWith('\r') ? l.slice(0, -1) : l);
285
+ // Use \r-stripped text for all regex matching so that anchor patterns
286
+ // like ^[─╌]+$ and full-screen when-regex work correctly against PTY
287
+ // output where lines end with \r\n rather than plain \n.
288
+ const cleanScreen = lines.join('\n');
285
289
  const sections = resolveSections(spec, lines);
286
290
  for (const s of sections) {
287
291
  trace.push({ kind: 'section', text: `section[${s.id}] lines [${s.fromLine}, ${s.toLine}) (${s.toLine - s.fromLine} lines)` });
@@ -294,9 +298,9 @@ export function evaluate(
294
298
  let modal: ModalSnapshot | null = null;
295
299
 
296
300
  for (const st of spec.states) {
297
- const { matched, title } = matchState(st, sections, screenText, trace, cursor);
301
+ const { matched, title } = matchState(st, sections, cleanScreen, trace, cursor);
298
302
  if (!matched) continue;
299
- const extractedModal = extractModal(st, sections, screenText, title, trace);
303
+ const extractedModal = extractModal(st, sections, cleanScreen, title, trace);
300
304
  // If the state declares modal_buttons but extraction failed (button
301
305
  // count below min_count, or text-was-mistaken-for-modal), do not
302
306
  // promote the state. Otherwise we would surface a phantom approval
@@ -77,7 +77,8 @@
77
77
  "section": { "type": "string", "minLength": 1 },
78
78
  "regex": { "type": "string", "minLength": 1 },
79
79
  "flags": { "type": "string" },
80
- "hold_ms": { "type": "integer", "minimum": 0 }
80
+ "hold_ms": { "type": "integer", "minimum": 0 },
81
+ "force_after_ms": { "type": "integer", "minimum": 0 }
81
82
  }
82
83
  }
83
84
  }
@@ -98,6 +99,22 @@
98
99
  "id": { "type": "string", "minLength": 1, "pattern": "^[a-z][a-z0-9_]*$" },
99
100
  "from_top": { "$ref": "#/definitions/size" },
100
101
  "from_bottom": { "$ref": "#/definitions/size" },
102
+ "lines": { "type": "integer", "minimum": 1 },
103
+ "anchor_regex": { "type": "string", "minLength": 1 },
104
+ "anchor_flags": { "type": "string" },
105
+ "anchor_last": { "type": "boolean" },
106
+ "anchor_context": {
107
+ "type": "object",
108
+ "additionalProperties": false,
109
+ "properties": {
110
+ "prev": { "type": "string" },
111
+ "prev_flags": { "type": "string" },
112
+ "next": { "type": "string" },
113
+ "next_flags": { "type": "string" }
114
+ }
115
+ },
116
+ "until_regex": { "type": "string", "minLength": 1 },
117
+ "until_regex_flags": { "type": "string" },
101
118
  "until": {
102
119
  "type": "object",
103
120
  "additionalProperties": false,