tickmarkr 2.3.0 → 2.4.1

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.
Files changed (72) hide show
  1. package/dist/adapters/catalog-remote.d.ts +12 -4
  2. package/dist/adapters/catalog-remote.js +97 -45
  3. package/dist/adapters/catalog.js +5 -3
  4. package/dist/adapters/claude-code.d.ts +1 -1
  5. package/dist/adapters/claude-code.js +8 -5
  6. package/dist/adapters/codex.js +6 -7
  7. package/dist/adapters/model-lints.d.ts +9 -5
  8. package/dist/adapters/model-lints.js +56 -15
  9. package/dist/adapters/model-windows.js +11 -0
  10. package/dist/adapters/prompt.js +1 -0
  11. package/dist/adapters/qwen.d.ts +5 -0
  12. package/dist/adapters/qwen.js +153 -0
  13. package/dist/adapters/registry.js +13 -1
  14. package/dist/adapters/types.d.ts +1 -0
  15. package/dist/adapters/types.js +1 -0
  16. package/dist/cli/commands/compile.d.ts +3 -0
  17. package/dist/cli/commands/compile.js +91 -34
  18. package/dist/cli/commands/doctor.d.ts +4 -3
  19. package/dist/cli/commands/doctor.js +28 -9
  20. package/dist/cli/commands/fleet.d.ts +4 -0
  21. package/dist/cli/commands/fleet.js +60 -15
  22. package/dist/cli/commands/init.js +12 -13
  23. package/dist/cli/commands/plan.js +75 -11
  24. package/dist/cli/commands/run.js +20 -1
  25. package/dist/cli/commands/status.d.ts +1 -0
  26. package/dist/cli/commands/status.js +59 -16
  27. package/dist/cli/commands/verify.d.ts +1 -0
  28. package/dist/cli/commands/verify.js +5 -0
  29. package/dist/cli/commands/version.js +2 -2
  30. package/dist/cli/index.d.ts +1 -1
  31. package/dist/cli/index.js +2 -2
  32. package/dist/compile/collateral.d.ts +14 -12
  33. package/dist/compile/collateral.js +32 -33
  34. package/dist/compile/index.d.ts +4 -1
  35. package/dist/compile/index.js +53 -8
  36. package/dist/compile/native.d.ts +4 -2
  37. package/dist/compile/native.js +63 -6
  38. package/dist/compile/ownership.js +41 -10
  39. package/dist/config/config.d.ts +1 -0
  40. package/dist/config/config.js +51 -5
  41. package/dist/drivers/herdr.d.ts +2 -0
  42. package/dist/drivers/herdr.js +43 -4
  43. package/dist/drivers/orca.d.ts +18 -1
  44. package/dist/drivers/orca.js +163 -15
  45. package/dist/drivers/types.d.ts +10 -0
  46. package/dist/gates/baseline.d.ts +26 -2
  47. package/dist/gates/baseline.js +115 -13
  48. package/dist/gates/review.d.ts +6 -4
  49. package/dist/gates/review.js +26 -31
  50. package/dist/gates/run-gates.d.ts +5 -2
  51. package/dist/gates/run-gates.js +34 -17
  52. package/dist/graph/graph.d.ts +20 -0
  53. package/dist/graph/graph.js +66 -1
  54. package/dist/route/preference.d.ts +6 -0
  55. package/dist/route/preference.js +40 -0
  56. package/dist/route/router.js +15 -2
  57. package/dist/run/consult.d.ts +1 -0
  58. package/dist/run/consult.js +35 -7
  59. package/dist/run/daemon.d.ts +9 -0
  60. package/dist/run/daemon.js +266 -59
  61. package/dist/run/git.d.ts +4 -0
  62. package/dist/run/git.js +51 -6
  63. package/dist/run/journal.d.ts +1 -1
  64. package/dist/run/journal.js +5 -2
  65. package/dist/run/lock.d.ts +6 -0
  66. package/dist/run/lock.js +41 -1
  67. package/dist/tui/ink/fleet-app.d.ts +4 -0
  68. package/dist/tui/ink/fleet-app.js +45 -16
  69. package/package.json +59 -1
  70. package/skills/tickmarkr-overseer/SKILL.md +39 -4
  71. package/skills/tickmarkr-overseer/scripts/grade-ci.sh +79 -0
  72. package/skills/tickmarkr-overseer/scripts/watch-context.sh +90 -4
@@ -36,7 +36,7 @@
36
36
  # TKR_AUTO_CLEAR=1 at act-pct WITH a fresh handoff, auto-clear orchestrator/overseer; other roles wake only.
37
37
  # TKR_REBRIEF=<path> the file the re-briefed seat is told to read (defaults to the handoff).
38
38
  # TKR_HANDOFF_MAX_AGE_S how fresh "fresh" is (default 900).
39
- # TKR_CLEAR_SETTLE_S seconds to let a cleared seat settle before the re-brief (default 6).
39
+ # TKR_CLEAR_SETTLE_S seconds allowed for the cleared banner percentage to drop (default 6).
40
40
  # TKR_BLIND_ALARM_S seconds unreadable before CONTEXT_BLIND alarms (default 120).
41
41
  # TKR_CONTEXT_WINDOW context window in tokens. Set it when the banner does not name one;
42
42
  # NEVER guessed — a wrong denominator makes every warn and act line wrong.
@@ -234,6 +234,82 @@ context_pct() {
234
234
  banner_pct
235
235
  }
236
236
 
237
+ status_of() {
238
+ herdr agent get "$TARGET" 2>/dev/null \
239
+ | sed -n 's/.*"agent_status":"\([a-z_]*\)".*/\1/p' | head -1
240
+ }
241
+
242
+ # A clear is a SEND, so it inherits the verified-send precondition: the target must be between turns
243
+ # and its live prompt line must contain no typed draft. Claude Code's autosuggest is text in the plain
244
+ # rendering but is wrapped in SGR dim in the ANSI rendering; it is decoration, not a draft. Parse the
245
+ # Esc-prefixed SGR bytes instead of treating every visible character after the prompt glyph as state.
246
+ prompt_is_empty_or_dim() {
247
+ herdr agent read "$TARGET" --source visible --lines 14 --format ansi 2>/dev/null | python3 -c '
248
+ import re, sys
249
+ screen = sys.stdin.read().splitlines()
250
+ ansi = re.compile(r"\x1b\[([0-9;]*)m")
251
+ prompt = None
252
+ for line in screen:
253
+ plain = ansi.sub("", line).lstrip()
254
+ if plain.startswith(("❯", "›")):
255
+ prompt = line
256
+ if prompt is None:
257
+ sys.exit(1)
258
+ glyph = min((i for i in (prompt.find("❯"), prompt.find("›")) if i >= 0), default=-1)
259
+ if glyph < 0:
260
+ sys.exit(1)
261
+ payload = prompt[glyph + 1:]
262
+ dim = False
263
+ pos = 0
264
+ for match in ansi.finditer(payload):
265
+ if payload[pos:match.start()].strip() and not dim:
266
+ sys.exit(1)
267
+ codes = [int(c) if c else 0 for c in match.group(1).split(";")]
268
+ if 0 in codes:
269
+ dim = False
270
+ if 2 in codes:
271
+ dim = True
272
+ if 22 in codes:
273
+ dim = False
274
+ pos = match.end()
275
+ if payload[pos:].strip() and not dim:
276
+ sys.exit(1)
277
+ ' 2>/dev/null
278
+ }
279
+
280
+ clear_target_ready() {
281
+ CLEAR_STATUS=$(status_of)
282
+ case "$CLEAR_STATUS" in
283
+ idle|done) ;;
284
+ *) CLEAR_REASON="status=${CLEAR_STATUS:-unreadable}"; return 1 ;;
285
+ esac
286
+ if ! prompt_is_empty_or_dim; then
287
+ CLEAR_REASON="status=$CLEAR_STATUS prompt=typed-or-unreadable"
288
+ return 1
289
+ fi
290
+ return 0
291
+ }
292
+
293
+ # `/clear` has landed only when a fresh banner read says its context percentage is lower. The JSONL
294
+ # source deliberately does not participate in this receipt: it names the pre-clear session and can
295
+ # remain at the old fill while the new prompt is already visible. No drop means no re-brief and no
296
+ # CONTEXT_CLEARED claim.
297
+ wait_for_clear_receipt() {
298
+ local before="$1" waited=0 after
299
+ case "$SETTLE" in *[!0-9]*|'') return 1 ;; esac
300
+ while :; do
301
+ after=$(banner_pct 2>/dev/null) || after=""
302
+ if printf '%s\n' "$after" | grep -qE '^[0-9]+$' \
303
+ && [ "$after" -lt "$before" ] 2>/dev/null; then
304
+ printf '%s\n' "$after"
305
+ return 0
306
+ fi
307
+ [ "$waited" -lt "$SETTLE" ] || return 1
308
+ sleep 1
309
+ waited=$((waited + 1))
310
+ done
311
+ }
312
+
237
313
  handoff_fresh() {
238
314
  [ -n "$HANDOFF" ] || return 1
239
315
  [ -f "$HANDOFF" ] || return 1
@@ -245,13 +321,23 @@ handoff_fresh() {
245
321
  }
246
322
 
247
323
  act_on() {
248
- local P="$1"
324
+ local P="$1" BEFORE AFTER
249
325
  if handoff_fresh; then
250
326
  if [ "${TKR_AUTO_CLEAR:-0}" = "1" ] && { [ "$ROLE" = "orchestrator" ] || [ "$ROLE" = "overseer" ]; }; then
327
+ if ! clear_target_ready; then
328
+ echo "CONTEXT_ACT_DEFERRED $TARGET at ${P}% — ${CLEAR_REASON}; waiting for idle and an empty/dim-only prompt line"
329
+ return 0
330
+ fi
331
+ BEFORE=$(banner_pct 2>/dev/null) || BEFORE=""
332
+ case "$BEFORE" in ''|*[!0-9]*) echo "CONTEXT_CLEAR_UNVERIFIED $TARGET — no numeric banner baseline; not clearing"; return 0 ;; esac
251
333
  herdr agent prompt "$TARGET" "/clear" >/dev/null 2>&1
252
- sleep "$SETTLE"
334
+ if ! AFTER=$(wait_for_clear_receipt "$BEFORE"); then
335
+ echo "CONTEXT_CLEAR_UNVERIFIED $TARGET at ${P}% — banner did not re-read below ${BEFORE}% within ${SETTLE}s"
336
+ echo " no re-brief sent and CONTEXT_CLEARED withheld; inspect the seat before acting again"
337
+ exit 0
338
+ fi
253
339
  herdr agent prompt "$TARGET" "Read ${REBRIEF} and continue exactly where it says. Your context was cleared at ${P}% against that handoff; it is current as of $(date '+%H:%M'). The same-process clear kept every background task alive: kill only this seat's recorded watcher pids first, verify the process table twice, then re-arm. Do not reconstruct from memory — everything you need is on disk." >/dev/null 2>&1
254
- echo "CONTEXT_CLEARED $TARGET at ${P}% — handoff fresh, re-briefed from ${REBRIEF}"
340
+ echo "CONTEXT_CLEARED $TARGET ${P}% -> ${AFTER}% — banner re-read lower, handoff fresh, re-briefed from ${REBRIEF}"
255
341
  exit 0
256
342
  fi
257
343
  echo "CONTEXT_ACT $TARGET ${P}% (>= ${ACT}) — handoff is FRESH, a clear is SAFE now"