@caddis/cli 0.4.52 → 0.4.54

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 (111) hide show
  1. package/bundles/antigravity-plugin/CADDIS-GLOSSARY.md +1 -0
  2. package/bundles/antigravity-plugin/guard_agy.py +184 -0
  3. package/bundles/antigravity-plugin/plugin.json +1 -1
  4. package/bundles/antigravity-plugin/repo_freshness.py +132 -5
  5. package/bundles/antigravity-plugin/scripts/caddis_budget.py +283 -0
  6. package/bundles/antigravity-plugin/scripts/caddis_checkout_guard.py +227 -0
  7. package/bundles/antigravity-plugin/scripts/caddis_docs_pr.py +284 -0
  8. package/bundles/antigravity-plugin/scripts/caddis_exit.py +2 -0
  9. package/bundles/antigravity-plugin/scripts/caddis_fleet.py +439 -0
  10. package/bundles/antigravity-plugin/scripts/caddis_frontmatter.py +1 -0
  11. package/bundles/antigravity-plugin/scripts/caddis_gate.py +255 -195
  12. package/bundles/antigravity-plugin/scripts/caddis_glossary.py +3 -3
  13. package/bundles/antigravity-plugin/scripts/caddis_governor.py +48 -4
  14. package/bundles/antigravity-plugin/scripts/caddis_inventory.py +38 -0
  15. package/bundles/antigravity-plugin/scripts/caddis_lanes.py +411 -127
  16. package/bundles/antigravity-plugin/scripts/caddis_lineage_publish.py +458 -0
  17. package/bundles/antigravity-plugin/scripts/caddis_merge_chain.py +237 -0
  18. package/bundles/antigravity-plugin/scripts/caddis_notify.py +125 -0
  19. package/bundles/antigravity-plugin/scripts/caddis_prod_check.py +380 -0
  20. package/bundles/antigravity-plugin/scripts/caddis_redact.py +99 -0
  21. package/bundles/antigravity-plugin/scripts/caddis_relay_git.py +2 -2
  22. package/bundles/antigravity-plugin/scripts/caddis_review.py +1309 -0
  23. package/bundles/antigravity-plugin/scripts/caddis_roadmap.py +2109 -0
  24. package/bundles/antigravity-plugin/scripts/caddis_roadmap_page.py +676 -0
  25. package/bundles/antigravity-plugin/scripts/caddis_roadmap_run.py +2605 -0
  26. package/bundles/antigravity-plugin/scripts/caddis_routing.py +7 -6
  27. package/bundles/antigravity-plugin/scripts/caddis_rows.py +476 -0
  28. package/bundles/antigravity-plugin/scripts/caddis_spawn.py +8 -9
  29. package/bundles/antigravity-plugin/scripts/caddis_spend.py +415 -0
  30. package/bundles/antigravity-plugin/scripts/caddis_tidy.py +357 -20
  31. package/bundles/antigravity-plugin/scripts/caddis_todo.py +55 -0
  32. package/bundles/antigravity-plugin/scripts/caddis_workstreams.py +178 -19
  33. package/bundles/antigravity-plugin/scripts/caddis_worktree_close.py +349 -0
  34. package/bundles/antigravity-plugin/scripts/check_doc_coverage.py +0 -56
  35. package/bundles/antigravity-plugin/scripts/claudster_doctor.py +1 -1
  36. package/bundles/antigravity-plugin/scripts/enforcement_inventory.py +0 -1
  37. package/bundles/antigravity-plugin/scripts/oss_review.py +2 -2
  38. package/bundles/antigravity-plugin/scripts/roadmap-recheck.ps1 +89 -0
  39. package/bundles/antigravity-plugin/scripts/roadmap-run.ps1 +88 -0
  40. package/bundles/antigravity-plugin/scripts/setup_project_ai.py +43 -1
  41. package/bundles/antigravity-plugin/session_end_agy.py +3 -3
  42. package/bundles/antigravity-plugin/skills/_registry.md +4 -6
  43. package/bundles/antigravity-plugin/skills/best-practices/agents/best-practices-referencer.md +1 -1
  44. package/bundles/antigravity-plugin/skills/best-practices/agents/codebase-context-builder.md +1 -1
  45. package/bundles/antigravity-plugin/skills/best-practices/agents/task-intent-analyzer.md +1 -1
  46. package/bundles/antigravity-plugin/skills/catchup/SKILL.md +11 -0
  47. package/bundles/antigravity-plugin/skills/cloud-phases/SKILL.md +1 -1
  48. package/bundles/antigravity-plugin/skills/cross-review/SKILL.md +5 -2
  49. package/bundles/antigravity-plugin/skills/feature-plan/SKILL.md +35 -83
  50. package/bundles/antigravity-plugin/skills/fleet-close/SKILL.md +167 -0
  51. package/bundles/antigravity-plugin/skills/fleet-open/SKILL.md +110 -0
  52. package/bundles/antigravity-plugin/skills/gh-cli/SKILL.md +2 -1
  53. package/bundles/antigravity-plugin/skills/handoff/SKILL.md +177 -48
  54. package/bundles/antigravity-plugin/skills/implement/SKILL.md +87 -147
  55. package/bundles/antigravity-plugin/skills/migrate-dir/SKILL.md +4 -3
  56. package/bundles/antigravity-plugin/skills/mmr/SKILL.md +5 -2
  57. package/bundles/antigravity-plugin/skills/office-documents-official/SKILL.md +24 -0
  58. package/bundles/antigravity-plugin/skills/park/SKILL.md +0 -1
  59. package/bundles/antigravity-plugin/skills/pr-merge/SKILL.md +28 -20
  60. package/bundles/antigravity-plugin/skills/prd/SKILL.md +2 -10
  61. package/bundles/antigravity-plugin/skills/refactoring/SKILL.md +2 -1
  62. package/bundles/antigravity-plugin/skills/review-pr/SKILL.md +1 -1
  63. package/bundles/antigravity-plugin/skills/roadmap/SKILL.md +260 -0
  64. package/bundles/antigravity-plugin/skills/roadmap/assets/plan-resume-prompt.md +77 -0
  65. package/bundles/antigravity-plugin/skills/roadmap/assets/render-check.template.mjs +68 -0
  66. package/bundles/antigravity-plugin/skills/roadmap/assets/review-protocol.md +78 -0
  67. package/bundles/antigravity-plugin/skills/roadmap/assets/roadmap.template.md +32 -0
  68. package/bundles/antigravity-plugin/skills/roadmap/assets/value-check.template.py +161 -0
  69. package/bundles/antigravity-plugin/skills/ship/SKILL.md +16 -16
  70. package/bundles/antigravity-plugin/skills/ship-merge/SKILL.md +15 -5
  71. package/bundles/antigravity-plugin/skills/ship-pr/SKILL.md +36 -16
  72. package/bundles/antigravity-plugin/skills/spawn-session/SKILL.md +4 -8
  73. package/bundles/antigravity-plugin/warm_start_agy.py +1 -3
  74. package/bundles/antigravity-plugin-extras/plugin.json +1 -1
  75. package/bundles/antigravity-plugin-extras/skills/_registry.md +1 -2
  76. package/bundles/antigravity-plugin-extras/skills/agent-orchestration/SKILL.md +5 -5
  77. package/bundles/antigravity-plugin-extras/skills/cross-review/SKILL.md +5 -2
  78. package/bundles/antigravity-plugin-extras/skills/runner-move/SKILL.md +214 -0
  79. package/bundles/codex/.codex/skills/coding/refactoring/SKILL.md +2 -1
  80. package/bundles/codex/.codex/skills/devops/gh-cli/SKILL.md +2 -1
  81. package/bundles/codex/.codex/skills/docs/office-documents-official/SKILL.md +24 -0
  82. package/bundles/codex/.codex/skills/workflow/best-practices/agents/best-practices-referencer.md +1 -1
  83. package/bundles/codex/.codex/skills/workflow/best-practices/agents/codebase-context-builder.md +1 -1
  84. package/bundles/codex/.codex/skills/workflow/best-practices/agents/task-intent-analyzer.md +1 -1
  85. package/bundles/codex/.codex/skills/workflow/roadmap/SKILL.md +260 -0
  86. package/bundles/codex/.codex/skills/workflow/roadmap/assets/plan-resume-prompt.md +77 -0
  87. package/bundles/codex/.codex/skills/workflow/roadmap/assets/render-check.template.mjs +68 -0
  88. package/bundles/codex/.codex/skills/workflow/roadmap/assets/review-protocol.md +78 -0
  89. package/bundles/codex/.codex/skills/workflow/roadmap/assets/roadmap.template.md +32 -0
  90. package/bundles/codex/.codex/skills/workflow/roadmap/assets/value-check.template.py +161 -0
  91. package/bundles/codex/AGENTS.md +5 -4
  92. package/bundles/manifest.json +3 -3
  93. package/package.json +1 -1
  94. package/bundles/antigravity-plugin/skills/advisory-hub/SKILL.md +0 -233
  95. package/bundles/antigravity-plugin/skills/advisory-hub/reference/context-template.md +0 -214
  96. package/bundles/antigravity-plugin/skills/advisory-hub/reference/hub-handbook.md +0 -233
  97. package/bundles/antigravity-plugin/skills/advisory-hub/reference/report-contract.md +0 -94
  98. package/bundles/antigravity-plugin/skills/advisory-hub/reference/succession.md +0 -118
  99. package/bundles/antigravity-plugin/skills/resume/SKILL.md +0 -6
  100. package/bundles/antigravity-plugin/skills/review/SKILL.md +0 -6
  101. package/bundles/antigravity-plugin/skills/spawn-hub/SKILL.md +0 -341
  102. package/bundles/antigravity-plugin/skills/statusline/SKILL.md +0 -6
  103. package/bundles/antigravity-plugin/skills/validate-phase/SKILL.md +0 -143
  104. package/bundles/antigravity-plugin-extras/skills/data-lineage/SKILL.md +0 -158
  105. package/bundles/antigravity-plugin-extras/skills/data-lineage/scripts/convert_doc_to_confluence.py +0 -1430
  106. package/bundles/antigravity-plugin-extras/skills/golden-plan/SKILL.md +0 -586
  107. package/bundles/codex/.codex/skills/workflow/advisory-hub/SKILL.md +0 -233
  108. package/bundles/codex/.codex/skills/workflow/advisory-hub/reference/context-template.md +0 -214
  109. package/bundles/codex/.codex/skills/workflow/advisory-hub/reference/hub-handbook.md +0 -233
  110. package/bundles/codex/.codex/skills/workflow/advisory-hub/reference/report-contract.md +0 -94
  111. package/bundles/codex/.codex/skills/workflow/advisory-hub/reference/succession.md +0 -118
@@ -426,13 +426,46 @@ def close_job(job: int) -> None:
426
426
 
427
427
  # ── other platforms ─────────────────────────────────────────────────────────
428
428
 
429
- def posix_argv(argv: list[str], limits: JobLimits, which=shutil.which, cpu_count=os.cpu_count) -> list[str] | None:
429
+ _SYSTEMD_USER_OK: bool | None = None
430
+
431
+
432
+ def systemd_user_usable(run=subprocess.run) -> bool:
433
+ """True when `systemd-run --user --scope` can actually start a scope here.
434
+
435
+ The binary can exist with no user D-Bus session behind it: a claude.ai cloud container on
436
+ 2026-10-11 had systemd-run on PATH and every call exited 1 with "Failed to connect to bus: No
437
+ medium found". Treating "on PATH" as "works" then made every governed lane fail without
438
+ running. Probe once with a harmless `true`, using the same property kinds as the real call (an
439
+ old systemd can reject `MemoryMax`); any failure means the cap does not exist."""
440
+ try:
441
+ done = run(["systemd-run", "--user", "--scope", "--quiet",
442
+ "-p", "CPUQuota=50%", "-p", "MemoryMax=512M", "-p", "TasksMax=64", "--", "true"],
443
+ capture_output=True, text=True, timeout=15)
444
+ except (OSError, subprocess.SubprocessError):
445
+ return False
446
+ return done.returncode == 0
447
+
448
+
449
+ def _systemd_user_usable_cached() -> bool:
450
+ global _SYSTEMD_USER_OK
451
+ if _SYSTEMD_USER_OK is None:
452
+ _SYSTEMD_USER_OK = systemd_user_usable()
453
+ return _SYSTEMD_USER_OK
454
+
455
+
456
+ def posix_argv(argv: list[str], limits: JobLimits, which=shutil.which, cpu_count=os.cpu_count,
457
+ usable=None) -> list[str] | None:
430
458
  """systemd user scope limits. Weaker than a Job Object: user scopes do not nest (a lane scope is
431
459
  a sibling of its session scope), an agent can call `systemd-run --user` itself, and CPUQuota is
432
460
  silently ignored when the cpu controller is not delegated to the user manager. TasksMax counts
433
- THREADS, not processes, so on Linux `max_processes` is a thread limit."""
461
+ THREADS, not processes, so on Linux `max_processes` is a thread limit.
462
+
463
+ None when systemd-run is missing OR present but unusable (`usable`, default: one cached probe);
464
+ the caller then refuses unless --allow-uncapped, exactly as for a missing binary."""
434
465
  if not which("systemd-run"):
435
466
  return None
467
+ if not (usable or _systemd_user_usable_cached)():
468
+ return None
436
469
  return ["systemd-run", "--user", "--scope", "--quiet",
437
470
  "-p", f"CPUQuota={limits.cpu_percent * (cpu_count() or 1)}%",
438
471
  "-p", f"MemoryMax={limits.memory_mb}M",
@@ -456,6 +489,17 @@ def _run_child(argv: list[str], env: dict) -> int:
456
489
  return 130
457
490
 
458
491
 
492
+ def cap_available() -> bool:
493
+ """True when this host can cap a governed child: a Job Object on native Windows, a usable
494
+ systemd user scope on posix. Tests that launch a real governed lane skip when this is False."""
495
+ kind = _host_kind()
496
+ if kind == "windows":
497
+ return True
498
+ if kind == "non-native-windows":
499
+ return False
500
+ return posix_argv(["true"], JobLimits(100, 1024, 64)) is not None
501
+
502
+
459
503
  def _host_kind() -> str:
460
504
  """Return "windows" (native Python), "non-native-windows" (MSYS2/Cygwin on Windows) or "posix"."""
461
505
  if sys.platform in ("cygwin", "msys") or (os.name == "nt" and sys.platform != "win32"):
@@ -502,7 +546,7 @@ def exec_governed(argv: list[str], scope: str, budget: Path | None = None,
502
546
  wrapped = posix_argv(argv, limits)
503
547
  if wrapped is None:
504
548
  if not allow_uncapped:
505
- raise GovernorError("no systemd-run on this platform, so no cap can be applied; "
549
+ raise GovernorError("no usable systemd-run on this platform (missing, or `systemd-run --user` cannot reach a user D-Bus session, as in many containers), so no cap can be applied; "
506
550
  "pass --allow-uncapped to run at lower priority only")
507
551
  try:
508
552
  os.nice(10)
@@ -534,7 +578,7 @@ def main(argv: list[str] | None = None) -> int:
534
578
  p_exec.add_argument("--machine-budget", type=Path, help=argparse.SUPPRESS) # additional ceiling only
535
579
  p_exec.add_argument("--job-name", help=argparse.SUPPRESS)
536
580
  p_exec.add_argument("--allow-uncapped", action="store_true",
537
- help="where no cap can be applied (no systemd-run, macOS), run at lower priority anyway")
581
+ help="where no cap can be applied (systemd-run missing or unusable, macOS), run at lower priority anyway")
538
582
  p_show = sub.add_parser("show", help="print the effective limits")
539
583
  p_show.add_argument("--budget", type=Path)
540
584
  p_show.add_argument("--machine-budget", type=Path, help=argparse.SUPPRESS)
@@ -44,6 +44,7 @@ import json
44
44
  import re
45
45
  import subprocess
46
46
  import sys
47
+ import time
47
48
  from dataclasses import dataclass, field
48
49
  from pathlib import Path
49
50
 
@@ -105,6 +106,7 @@ class Inventory:
105
106
  comms_open: list[dict] = field(default_factory=list)
106
107
  scripts: list[dict] = field(default_factory=list)
107
108
  stale_artifacts: list[dict] = field(default_factory=list)
109
+ stale_plans: list[dict] = field(default_factory=list)
108
110
  environment_map: str = "missing"
109
111
  tests: str = "not measured — run the suite, never quote a remembered number"
110
112
 
@@ -275,6 +277,37 @@ def stale_artifacts(root: Path) -> list[dict]:
275
277
  return out
276
278
 
277
279
 
280
+ def stale_plans(root: Path, days: int = 14) -> list[dict]:
281
+ """Top-level plans in `status: doing` or `status: current` whose last git commit is older
282
+ than `days` days."""
283
+ d = root / ART / "plans"
284
+ if not d.is_dir() or not (root / ".git").exists():
285
+ return []
286
+ now = time.time()
287
+ cutoff = days * 86400
288
+ out: list[dict] = []
289
+ for f in sorted(d.glob("*.md")):
290
+ if f.name.lower() == "readme.md":
291
+ continue
292
+ fm = frontmatter(f)
293
+ status = (fm.get("status") or "").strip()
294
+ if status.lower() not in ("doing", "current"):
295
+ continue
296
+ rel = f"{ART}/plans/{f.name}"
297
+ ts = _run(["git", "log", "-1", "--format=%ct", "--", rel], root)
298
+ if not ts.isdigit():
299
+ continue
300
+ age_seconds = now - int(ts)
301
+ if age_seconds > cutoff:
302
+ out.append({
303
+ "file": rel,
304
+ "title": title_of(f),
305
+ "status": status,
306
+ "days": int(age_seconds // 86400),
307
+ })
308
+ return out
309
+
310
+
278
311
  def collect(root: Path, with_tests: bool = False) -> Inventory:
279
312
  inv = Inventory(repo=root.name)
280
313
  inv.branch = _run(["git", "rev-parse", "--abbrev-ref", "HEAD"], root)
@@ -288,6 +321,7 @@ def collect(root: Path, with_tests: bool = False) -> Inventory:
288
321
  inv.comms_open = scan_comms(root)
289
322
  inv.scripts = scan_scripts(root)
290
323
  inv.stale_artifacts = stale_artifacts(root)
324
+ inv.stale_plans = stale_plans(root)
291
325
  inv.environment_map = environment_map_state(root)
292
326
  if with_tests:
293
327
  # Run it. A handover once claimed 20 tests when there were 19, and the incoming Hub found
@@ -402,6 +436,10 @@ def render_md(inv: Inventory) -> str:
402
436
  "Each of these was committed BEFORE the script that builds it last changed, so it may",
403
437
  "describe a state that no longer exists. Rebuild before quoting any of them.", ""]
404
438
  L += _table(inv.stale_artifacts, [("Artefact", "artifact"), ("Built by", "generator")])
439
+ if inv.stale_plans:
440
+ L += ["## Stale plans (status doing/current, no commit in 14 days)", ""]
441
+ L += _table(inv.stale_plans, [("File", "file"), ("Title", "title"),
442
+ ("Status", "status"), ("Days", "days")])
405
443
  for kind, rows in inv.artifacts.items():
406
444
  if not rows:
407
445
  continue