devlyn-cli 4.2.9 → 4.2.10

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.
@@ -312,6 +312,7 @@
312
312
  "36b58dbdc26e51abc05a60872c4582faeebd67e9fe5626a3933467ba07c68dc4",
313
313
  "40237cd5259dbcf7c490f130e844a9e32eea48a8edabd50800edee5029bf95a4",
314
314
  "5536f8391ec4442f1b793dba8dd5d7820d45f4b6dadf1111cbac9d54469a01ca",
315
+ "573a6059a7383b37affd9c2e8bc6c88a4fb54117628a5a0746406cc32111e9aa",
315
316
  "5824f07e455fe1c3942bf595a12e935258d4c0a851ca1bf741db915603d1c4e0",
316
317
  "5954e371659ae1010757f0eec4b80dd65a899f9fcf76d4d84d9a75476a963218",
317
318
  "65770e3f20c3a3afd2822e9acdcfc80b827f84a7737010b79332da70d431b05d",
@@ -486,19 +486,26 @@ def queue_view(anchor, recorded):
486
486
  tracked.update(rel for rel in git(anchor, "ls-tree", "-r", "-z", "--name-only", head, "--", "docs/specs").split("\0")
487
487
  if re.fullmatch(r"docs/specs/[^/]+/queue\.md", rel))
488
488
  for rel in sorted(tracked, key=lambda rel: rel.split("/")[2]):
489
- loop, data = rel.split("/")[2], (anchor / rel).read_bytes() if (anchor / rel).is_file() else None
490
- if loop not in recorded:
491
- # A directory name alone proves nothing. A task row in the checkout or HEAD proves this is a loop queue;
492
- # HEAD keeps that proof when the checkout loses its rows. Strict decoding/parsing follows only that proof.
493
- known = False
494
- for candidate in (data, show(anchor, head, rel) if head else None):
495
- for line in (candidate or b"").decode("utf-8", errors="replace").splitlines():
496
- match = ROW_RE.fullmatch(line)
497
- item = ITEM_RE.fullmatch(match["text"].rstrip()) if match else None
498
- if item and item["loop"] == loop and bool(item["rest"]) == (match["mark"] == "F"):
499
- known = True
500
- if known:
501
- loops[loop] = parse_loop(data, loop, anchor / rel)
489
+ loop, data, read_error = rel.split("/")[2], None, None
490
+ if loop in recorded:
491
+ continue
492
+ try:
493
+ data = (anchor / rel).read_bytes() if (anchor / rel).is_file() else None
494
+ except OSError as exc:
495
+ read_error = exc
496
+ # A directory name alone proves nothing. A task row in the checkout or HEAD proves this is a loop queue; HEAD
497
+ # keeps that proof when the checkout loses its rows or cannot be read. Only a proven queue is parsed or blocks.
498
+ known = False
499
+ for candidate in (data, show(anchor, head, rel) if head else None):
500
+ for line in (candidate or b"").decode("utf-8", errors="replace").splitlines():
501
+ match = ROW_RE.fullmatch(line)
502
+ item = ITEM_RE.fullmatch(match["text"].rstrip()) if match else None
503
+ if item and item["loop"] == loop and bool(item["rest"]) == (match["mark"] == "F"):
504
+ known = True
505
+ if known:
506
+ if read_error is not None:
507
+ raise LoopError(f"{anchor / rel}: {read_error}") from read_error
508
+ loops[loop] = parse_loop(data, loop, anchor / rel)
502
509
  claims = {}
503
510
  for loop, (_, target) in loops.items():
504
511
  if target:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devlyn-cli",
3
- "version": "4.2.9",
3
+ "version": "4.2.10",
4
4
  "description": "Loop & harness engineering for AI coding agents (Claude Code, Codex, and any AGENTS.md-driven agent) — core engineering principles for CLAUDE.md/AGENTS.md and a loop designer that splits one intent into tasks agents drain hands-free",
5
5
  "homepage": "https://github.com/fysoul17/devlyn-cli#readme",
6
6
  "bin": {