@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.
- package/bundles/antigravity-plugin/CADDIS-GLOSSARY.md +1 -0
- package/bundles/antigravity-plugin/guard_agy.py +184 -0
- package/bundles/antigravity-plugin/plugin.json +1 -1
- package/bundles/antigravity-plugin/repo_freshness.py +132 -5
- package/bundles/antigravity-plugin/scripts/caddis_budget.py +283 -0
- package/bundles/antigravity-plugin/scripts/caddis_checkout_guard.py +227 -0
- package/bundles/antigravity-plugin/scripts/caddis_docs_pr.py +284 -0
- package/bundles/antigravity-plugin/scripts/caddis_exit.py +2 -0
- package/bundles/antigravity-plugin/scripts/caddis_fleet.py +439 -0
- package/bundles/antigravity-plugin/scripts/caddis_frontmatter.py +1 -0
- package/bundles/antigravity-plugin/scripts/caddis_gate.py +255 -195
- package/bundles/antigravity-plugin/scripts/caddis_glossary.py +3 -3
- package/bundles/antigravity-plugin/scripts/caddis_governor.py +48 -4
- package/bundles/antigravity-plugin/scripts/caddis_inventory.py +38 -0
- package/bundles/antigravity-plugin/scripts/caddis_lanes.py +411 -127
- package/bundles/antigravity-plugin/scripts/caddis_lineage_publish.py +458 -0
- package/bundles/antigravity-plugin/scripts/caddis_merge_chain.py +237 -0
- package/bundles/antigravity-plugin/scripts/caddis_notify.py +125 -0
- package/bundles/antigravity-plugin/scripts/caddis_prod_check.py +380 -0
- package/bundles/antigravity-plugin/scripts/caddis_redact.py +99 -0
- package/bundles/antigravity-plugin/scripts/caddis_relay_git.py +2 -2
- package/bundles/antigravity-plugin/scripts/caddis_review.py +1309 -0
- package/bundles/antigravity-plugin/scripts/caddis_roadmap.py +2109 -0
- package/bundles/antigravity-plugin/scripts/caddis_roadmap_page.py +676 -0
- package/bundles/antigravity-plugin/scripts/caddis_roadmap_run.py +2605 -0
- package/bundles/antigravity-plugin/scripts/caddis_routing.py +7 -6
- package/bundles/antigravity-plugin/scripts/caddis_rows.py +476 -0
- package/bundles/antigravity-plugin/scripts/caddis_spawn.py +8 -9
- package/bundles/antigravity-plugin/scripts/caddis_spend.py +415 -0
- package/bundles/antigravity-plugin/scripts/caddis_tidy.py +357 -20
- package/bundles/antigravity-plugin/scripts/caddis_todo.py +55 -0
- package/bundles/antigravity-plugin/scripts/caddis_workstreams.py +178 -19
- package/bundles/antigravity-plugin/scripts/caddis_worktree_close.py +349 -0
- package/bundles/antigravity-plugin/scripts/check_doc_coverage.py +0 -56
- package/bundles/antigravity-plugin/scripts/claudster_doctor.py +1 -1
- package/bundles/antigravity-plugin/scripts/enforcement_inventory.py +0 -1
- package/bundles/antigravity-plugin/scripts/oss_review.py +2 -2
- package/bundles/antigravity-plugin/scripts/roadmap-recheck.ps1 +89 -0
- package/bundles/antigravity-plugin/scripts/roadmap-run.ps1 +88 -0
- package/bundles/antigravity-plugin/scripts/setup_project_ai.py +43 -1
- package/bundles/antigravity-plugin/session_end_agy.py +3 -3
- package/bundles/antigravity-plugin/skills/_registry.md +4 -6
- package/bundles/antigravity-plugin/skills/best-practices/agents/best-practices-referencer.md +1 -1
- package/bundles/antigravity-plugin/skills/best-practices/agents/codebase-context-builder.md +1 -1
- package/bundles/antigravity-plugin/skills/best-practices/agents/task-intent-analyzer.md +1 -1
- package/bundles/antigravity-plugin/skills/catchup/SKILL.md +11 -0
- package/bundles/antigravity-plugin/skills/cloud-phases/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/cross-review/SKILL.md +5 -2
- package/bundles/antigravity-plugin/skills/feature-plan/SKILL.md +35 -83
- package/bundles/antigravity-plugin/skills/fleet-close/SKILL.md +167 -0
- package/bundles/antigravity-plugin/skills/fleet-open/SKILL.md +110 -0
- package/bundles/antigravity-plugin/skills/gh-cli/SKILL.md +2 -1
- package/bundles/antigravity-plugin/skills/handoff/SKILL.md +177 -48
- package/bundles/antigravity-plugin/skills/implement/SKILL.md +87 -147
- package/bundles/antigravity-plugin/skills/migrate-dir/SKILL.md +4 -3
- package/bundles/antigravity-plugin/skills/mmr/SKILL.md +5 -2
- package/bundles/antigravity-plugin/skills/office-documents-official/SKILL.md +24 -0
- package/bundles/antigravity-plugin/skills/park/SKILL.md +0 -1
- package/bundles/antigravity-plugin/skills/pr-merge/SKILL.md +28 -20
- package/bundles/antigravity-plugin/skills/prd/SKILL.md +2 -10
- package/bundles/antigravity-plugin/skills/refactoring/SKILL.md +2 -1
- package/bundles/antigravity-plugin/skills/review-pr/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/roadmap/SKILL.md +260 -0
- package/bundles/antigravity-plugin/skills/roadmap/assets/plan-resume-prompt.md +77 -0
- package/bundles/antigravity-plugin/skills/roadmap/assets/render-check.template.mjs +68 -0
- package/bundles/antigravity-plugin/skills/roadmap/assets/review-protocol.md +78 -0
- package/bundles/antigravity-plugin/skills/roadmap/assets/roadmap.template.md +32 -0
- package/bundles/antigravity-plugin/skills/roadmap/assets/value-check.template.py +161 -0
- package/bundles/antigravity-plugin/skills/ship/SKILL.md +16 -16
- package/bundles/antigravity-plugin/skills/ship-merge/SKILL.md +15 -5
- package/bundles/antigravity-plugin/skills/ship-pr/SKILL.md +36 -16
- package/bundles/antigravity-plugin/skills/spawn-session/SKILL.md +4 -8
- package/bundles/antigravity-plugin/warm_start_agy.py +1 -3
- package/bundles/antigravity-plugin-extras/plugin.json +1 -1
- package/bundles/antigravity-plugin-extras/skills/_registry.md +1 -2
- package/bundles/antigravity-plugin-extras/skills/agent-orchestration/SKILL.md +5 -5
- package/bundles/antigravity-plugin-extras/skills/cross-review/SKILL.md +5 -2
- package/bundles/antigravity-plugin-extras/skills/runner-move/SKILL.md +214 -0
- package/bundles/codex/.codex/skills/coding/refactoring/SKILL.md +2 -1
- package/bundles/codex/.codex/skills/devops/gh-cli/SKILL.md +2 -1
- package/bundles/codex/.codex/skills/docs/office-documents-official/SKILL.md +24 -0
- package/bundles/codex/.codex/skills/workflow/best-practices/agents/best-practices-referencer.md +1 -1
- package/bundles/codex/.codex/skills/workflow/best-practices/agents/codebase-context-builder.md +1 -1
- package/bundles/codex/.codex/skills/workflow/best-practices/agents/task-intent-analyzer.md +1 -1
- package/bundles/codex/.codex/skills/workflow/roadmap/SKILL.md +260 -0
- package/bundles/codex/.codex/skills/workflow/roadmap/assets/plan-resume-prompt.md +77 -0
- package/bundles/codex/.codex/skills/workflow/roadmap/assets/render-check.template.mjs +68 -0
- package/bundles/codex/.codex/skills/workflow/roadmap/assets/review-protocol.md +78 -0
- package/bundles/codex/.codex/skills/workflow/roadmap/assets/roadmap.template.md +32 -0
- package/bundles/codex/.codex/skills/workflow/roadmap/assets/value-check.template.py +161 -0
- package/bundles/codex/AGENTS.md +5 -4
- package/bundles/manifest.json +3 -3
- package/package.json +1 -1
- package/bundles/antigravity-plugin/skills/advisory-hub/SKILL.md +0 -233
- package/bundles/antigravity-plugin/skills/advisory-hub/reference/context-template.md +0 -214
- package/bundles/antigravity-plugin/skills/advisory-hub/reference/hub-handbook.md +0 -233
- package/bundles/antigravity-plugin/skills/advisory-hub/reference/report-contract.md +0 -94
- package/bundles/antigravity-plugin/skills/advisory-hub/reference/succession.md +0 -118
- package/bundles/antigravity-plugin/skills/resume/SKILL.md +0 -6
- package/bundles/antigravity-plugin/skills/review/SKILL.md +0 -6
- package/bundles/antigravity-plugin/skills/spawn-hub/SKILL.md +0 -341
- package/bundles/antigravity-plugin/skills/statusline/SKILL.md +0 -6
- package/bundles/antigravity-plugin/skills/validate-phase/SKILL.md +0 -143
- package/bundles/antigravity-plugin-extras/skills/data-lineage/SKILL.md +0 -158
- package/bundles/antigravity-plugin-extras/skills/data-lineage/scripts/convert_doc_to_confluence.py +0 -1430
- package/bundles/antigravity-plugin-extras/skills/golden-plan/SKILL.md +0 -586
- package/bundles/codex/.codex/skills/workflow/advisory-hub/SKILL.md +0 -233
- package/bundles/codex/.codex/skills/workflow/advisory-hub/reference/context-template.md +0 -214
- package/bundles/codex/.codex/skills/workflow/advisory-hub/reference/hub-handbook.md +0 -233
- package/bundles/codex/.codex/skills/workflow/advisory-hub/reference/report-contract.md +0 -94
- 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
|
-
|
|
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 (
|
|
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
|