@caddis/cli 0.2.4 → 0.2.5
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/README.md +11 -0
- package/bundles/antigravity-plugin/agents/claude-md-curator.md +7 -4
- package/bundles/antigravity-plugin/plugin.json +1 -1
- package/bundles/antigravity-plugin/skills/_registry.md +6 -0
- package/bundles/antigravity-plugin/skills/advisory-hub/SKILL.md +183 -0
- package/bundles/antigravity-plugin/skills/advisory-hub/reference/context-template.md +214 -0
- package/bundles/antigravity-plugin/skills/advisory-hub/reference/hub-handbook.md +233 -0
- package/bundles/antigravity-plugin/skills/advisory-hub/reference/report-contract.md +94 -0
- package/bundles/antigravity-plugin/skills/advisory-hub/reference/succession.md +96 -0
- package/bundles/antigravity-plugin/skills/brainstorming/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/code-review/SKILL.md +7 -0
- package/bundles/antigravity-plugin/skills/context-curator/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/cross-review/SKILL.md +71 -14
- package/bundles/antigravity-plugin/skills/dashboard-perf-sweep/SKILL.md +18 -18
- package/bundles/antigravity-plugin/skills/feature-plan/SKILL.md +164 -9
- package/bundles/antigravity-plugin/skills/gate-preflight/SKILL.md +34 -0
- package/bundles/antigravity-plugin/skills/gate-review/SKILL.md +36 -0
- package/bundles/antigravity-plugin/skills/golden-plan/SKILL.md +22 -13
- package/bundles/antigravity-plugin/skills/handoff/SKILL.md +78 -0
- package/bundles/antigravity-plugin/skills/implement/SKILL.md +182 -3
- package/bundles/antigravity-plugin/skills/mermaid-diagrams/SKILL.md +57 -1
- package/bundles/antigravity-plugin/skills/park/SKILL.md +126 -0
- package/bundles/antigravity-plugin/skills/prd/SKILL.md +4 -2
- package/bundles/antigravity-plugin/skills/preflight/SKILL.md +5 -0
- package/bundles/antigravity-plugin/skills/spawn-hub/SKILL.md +287 -0
- package/bundles/antigravity-plugin/skills/validate-phase/SKILL.md +112 -0
- package/bundles/antigravity-plugin/skills/writing-plans/SKILL.md +7 -4
- package/bundles/antigravity-plugin/warm_start_agy.py +28 -2
- package/bundles/antigravity-plugin-extras/plugin.json +1 -1
- package/bundles/antigravity-plugin-extras/skills/agent-orchestration/SKILL.md +9 -9
- package/bundles/antigravity-plugin-extras/skills/cross-review/SKILL.md +56 -6
- package/bundles/antigravity-plugin-extras/skills/requesting-code-review/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/schema-migration/SKILL.md +2 -2
- package/bundles/antigravity-plugin-extras/skills/state-tracking/SKILL.md +4 -4
- package/bundles/manifest.json +3 -3
- package/dist/cli.js +55 -4
- package/package.json +1 -1
|
@@ -14,6 +14,27 @@ issue. This skill runs that second reviewer over the current changes and acts on
|
|
|
14
14
|
- On a risky diff (auth, crypto, data-touching, concurrency) where a second opinion is cheap insurance.
|
|
15
15
|
- NOT a replacement for the in-repo `/caddis:code-review` — this is the *cross-vendor* complement.
|
|
16
16
|
|
|
17
|
+
## Check the key FIRST, and ask if it is missing
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
python "$TOOL" --check-config
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Exit 0 prints which providers have a key. **Exit 3 means nothing is configured — stop and ask the
|
|
24
|
+
user before reading any diff.** Do not proceed, and do not silently skip the review.
|
|
25
|
+
|
|
26
|
+
Ask with `AskUserQuestion` which provider to set up, then write the key to `~/.caddis/keys.env` as
|
|
27
|
+
`DEEPSEEK_API_KEY=<key>` (or the matching variable). That file sits outside every git repo, so it
|
|
28
|
+
cannot be committed by accident. **Never put a key in the repo, in a command, or in a reply.**
|
|
29
|
+
|
|
30
|
+
This used to fail mid-task with a commit pending — the worst moment to go hunting for a credential.
|
|
31
|
+
A command that fails once at an inconvenient moment does not get retried, so the safety check is
|
|
32
|
+
quietly lost and nothing records the loss. The script stays non-interactive because it also runs
|
|
33
|
+
headless, where a stdin prompt hangs instead of asking; the asking is the agent's job.
|
|
34
|
+
|
|
35
|
+
If a key exists for a *different* provider than the one requested, the error names it and gives the
|
|
36
|
+
exact flag (`--provider glm`). Read the message before concluding anything is missing.
|
|
37
|
+
|
|
17
38
|
## Prerequisites (one-time)
|
|
18
39
|
Only the key is mandatory — the tool ships **provider presets** (default `deepseek`, the cheapest + most
|
|
19
40
|
architecturally distinct-from-Claude option; a review costs well under a cent):
|
|
@@ -28,16 +49,41 @@ churn — the preset table in `oss_review.py` is the one place to edit a rename,
|
|
|
28
49
|
`REVIEW_BASE_URL` always win, so you can point at any new id without touching code.
|
|
29
50
|
|
|
30
51
|
## How to run
|
|
31
|
-
From the repo root.
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
52
|
+
From the repo root. Resolve the tool path deterministically — check only these two exact
|
|
53
|
+
locations, in order, and **never search the filesystem for it** (see Rules below):
|
|
54
|
+
```bash
|
|
55
|
+
# THE PLUGIN COPY WINS. It is the one `caddis update` refreshes; a vendored copy is a snapshot
|
|
56
|
+
# of whatever caddis shipped the day someone copied it, and it never updates again.
|
|
57
|
+
if [ -f "${CLAUDE_PLUGIN_ROOT}/scripts/oss_review.py" ]; then
|
|
58
|
+
TOOL="${CLAUDE_PLUGIN_ROOT}/scripts/oss_review.py"
|
|
59
|
+
# A vendored copy that DIFFERS is a live hazard, not a curiosity — say so, do not stay silent.
|
|
60
|
+
if [ -f ".github/tools/oss_review.py" ] && ! diff -q ".github/tools/oss_review.py" "$TOOL" >/dev/null 2>&1; then
|
|
61
|
+
echo "[cross-review] WARNING: .github/tools/oss_review.py differs from the caddis copy and is"
|
|
62
|
+
echo " being IGNORED. Delete it, or keep the local change deliberately."
|
|
63
|
+
fi
|
|
64
|
+
elif [ -f ".github/tools/oss_review.py" ]; then
|
|
65
|
+
TOOL=".github/tools/oss_review.py" # no plugin present — the vendored copy is all there is
|
|
66
|
+
else
|
|
67
|
+
echo "oss_review.py not found at either known location — report this and stop. Do NOT search for it."
|
|
68
|
+
exit 3
|
|
69
|
+
fi
|
|
35
70
|
```
|
|
36
|
-
|
|
37
|
-
|
|
71
|
+
|
|
72
|
+
> **Why the plugin copy is first.** It used to be second. On 2026-08-10 a repo ran a stale vendored
|
|
73
|
+
> `oss_review.py` and got `REVIEW: CLEAN` on a database write path that was never reviewed. The bug
|
|
74
|
+
> had been fixed on 2026-08-01 — the fix just never reached the caller, because a file someone
|
|
75
|
+
> copied weeks earlier silently won. `caddis_gate.py vendor-drift` now fails on the same condition.
|
|
76
|
+
```
|
|
77
|
+
python "$TOOL" # review the working tree (staged+unstaged)
|
|
78
|
+
python "$TOOL" --range origin/main..HEAD # review a branch's commits
|
|
38
79
|
```
|
|
39
80
|
Optional flags: `--cwd <repo>`, `--base-url <url>`, `--model <id>` (override the env).
|
|
40
81
|
|
|
82
|
+
**Diff-size ceiling.** A diff over `REVIEW_MAX_DIFF_CHARS` (default 60,000 chars) is **split into batches** on whole-file boundaries and each batch reviewed separately (verdict is CLEAN only if every batch is). Exit 2 now means a *single unsplittable file* over the ceiling, or too many batches — not an ordinary large diff. Previously it was refused with exit 2
|
|
83
|
+
*before* any LLM call — an oversized diff has been observed to come back either an empty response, or
|
|
84
|
+
worse, a `REVIEW: CLEAN` with zero real engagement. If you hit this, narrow `--range` or review in
|
|
85
|
+
smaller chunks; don't just raise `--max-diff-chars` without knowing the endpoint's real limit.
|
|
86
|
+
|
|
41
87
|
## Interpret the exit code
|
|
42
88
|
- **0 — REVIEW: CLEAN** → no blocking issues. Proceed.
|
|
43
89
|
- **1 — REVIEW: BLOCKING** → the reviewer found blocking issues. **Read the printed findings, then FIX
|
|
@@ -52,3 +98,7 @@ Optional flags: `--cwd <repo>`, `--base-url <url>`, `--model <id>` (override the
|
|
|
52
98
|
the main thread after reading the findings.
|
|
53
99
|
- Treat exit 2/3 as blocking-unknown, never as approval (the tool is fail-closed by design).
|
|
54
100
|
- Different vendor ⇒ different style; weigh its findings on merit, don't cargo-cult them.
|
|
101
|
+
- **Never use `find`, `Get-ChildItem -Recurse`, or any other filesystem-wide search to locate
|
|
102
|
+
`oss_review.py`.** Check only the two paths above. On Git Bash under Windows, `find /` (or any
|
|
103
|
+
search rooted at `/`) walks every mounted drive, not just the repo — it can hang or take minutes.
|
|
104
|
+
If neither path exists, stop and report it; don't go hunting for the file.
|
|
@@ -58,7 +58,7 @@ HEAD_SHA=$(git rev-parse HEAD)
|
|
|
58
58
|
|
|
59
59
|
[Dispatch superpowers:code-reviewer subagent]
|
|
60
60
|
WHAT_WAS_IMPLEMENTED: Verification and repair functions for conversation index
|
|
61
|
-
PLAN_OR_REQUIREMENTS: Task 2 from
|
|
61
|
+
PLAN_OR_REQUIREMENTS: Task 2 from .caddis/plans/deployment-plan.md
|
|
62
62
|
BASE_SHA: a7981ec
|
|
63
63
|
HEAD_SHA: 3df7661
|
|
64
64
|
DESCRIPTION: Added verifyIndex() and repairIndex() with 4 issue types
|
|
@@ -24,7 +24,7 @@ Systematically migrate an application from a legacy database schema to a new sch
|
|
|
24
24
|
1. **Read-Only** — Never execute DDL or DML (`CREATE`, `ALTER`, `INSERT`, `UPDATE`, `DELETE`) against the database. All analysis is SELECT-only.
|
|
25
25
|
2. **No SQL Aliases** — Proposed queries must use direct `Table.Column` notation. Aliases obscure the mapping and make future changes harder to trace.
|
|
26
26
|
3. **No Assumptions** — Every column mapping must be verified against the actual schema DDL. If a mapping is ambiguous or a source column has no clear target, flag it as a **GAP** rather than guessing.
|
|
27
|
-
4. **Scratchpad Protocol** — If context becomes large, save intermediate findings to `.
|
|
27
|
+
4. **Scratchpad Protocol** — If context becomes large, save intermediate findings to `.caddis/plans/temp_migration_scratchpad.md` to preserve state across reasoning steps.
|
|
28
28
|
|
|
29
29
|
---
|
|
30
30
|
|
|
@@ -255,7 +255,7 @@ Produce a single, comprehensive document suitable for use as an **Implementation
|
|
|
255
255
|
```
|
|
256
256
|
|
|
257
257
|
### Output Location
|
|
258
|
-
Place the final report at the path specified by the user (default: `.
|
|
258
|
+
Place the final report at the path specified by the user (default: `.caddis/agent-docs/migration_report.md` — it is an agent-produced report, not a backlog item).
|
|
259
259
|
|
|
260
260
|
---
|
|
261
261
|
|
|
@@ -23,7 +23,7 @@ State tracking uses two distinct documents with different write semantics:
|
|
|
23
23
|
|
|
24
24
|
| Document | Write mode | Purpose |
|
|
25
25
|
|----------|-----------|---------|
|
|
26
|
-
| **Plan Tracker** (`.
|
|
26
|
+
| **Plan Tracker** (`.caddis/plans/tracker/<slug>-tracker.md`) | Overwrite each row | Per-phase completion record, linked to commits |
|
|
27
27
|
| **CURRENT_STATE** (`.github/agent-docs/CURRENT_STATE.md`) | Overwrite head section | Single-view of right now: what phase, what's done, what's blocked |
|
|
28
28
|
| **Session Log** (inline in CURRENT_STATE, append-only) | Append only | Chronological audit trail — never rewrite past entries |
|
|
29
29
|
|
|
@@ -42,8 +42,8 @@ Replace this section wholesale each time:
|
|
|
42
42
|
```markdown
|
|
43
43
|
## Current Status
|
|
44
44
|
|
|
45
|
-
**Plan:** `.
|
|
46
|
-
**Tracker:** `.
|
|
45
|
+
**Plan:** `.caddis/plans/<feature-slug>.md`
|
|
46
|
+
**Tracker:** `.caddis/plans/tracker/<feature-slug>-tracker.md`
|
|
47
47
|
**Last updated:** YYYY-MM-DDTHH:MM:SSZ
|
|
48
48
|
**Active agent:** @[Agent] (model: [Model])
|
|
49
49
|
**Current phase:** Phase N — [Name]
|
|
@@ -116,7 +116,7 @@ The canonical template is at `.github/agent-docs/CURRENT_STATE.md`. Copy it for
|
|
|
116
116
|
## Integration with Golden-Plan
|
|
117
117
|
|
|
118
118
|
When running a golden-plan:
|
|
119
|
-
- The plan tracker (`.
|
|
119
|
+
- The plan tracker (`.caddis/plans/tracker/<slug>-tracker.md`) is the commitment ledger.
|
|
120
120
|
- CURRENT_STATE.md is the working scratch-pad for the current session.
|
|
121
121
|
- After completing a phase, update BOTH the tracker row AND the CURRENT_STATE current-status section.
|
|
122
122
|
- When all tracker rows are `Complete`, follow the Plan Completion Protocol in golden-plan: move the plan to `plans/done/`, set `status: done`.
|
package/bundles/manifest.json
CHANGED
package/dist/cli.js
CHANGED
|
@@ -4527,6 +4527,32 @@ var init_drive = __esm({
|
|
|
4527
4527
|
}
|
|
4528
4528
|
});
|
|
4529
4529
|
|
|
4530
|
+
// src/util/semver.ts
|
|
4531
|
+
function compareVersions(a, b3) {
|
|
4532
|
+
const pa = parse(a);
|
|
4533
|
+
const pb = parse(b3);
|
|
4534
|
+
if (!pa || !pb) return null;
|
|
4535
|
+
for (let i = 0; i < Math.max(pa.length, pb.length); i += 1) {
|
|
4536
|
+
const da = pa[i] ?? 0;
|
|
4537
|
+
const db = pb[i] ?? 0;
|
|
4538
|
+
if (da > db) return 1;
|
|
4539
|
+
if (da < db) return -1;
|
|
4540
|
+
}
|
|
4541
|
+
return 0;
|
|
4542
|
+
}
|
|
4543
|
+
function parse(v) {
|
|
4544
|
+
if (!v || v === "unknown") return null;
|
|
4545
|
+
const core = v.trim().replace(/^v/, "").split(/[-+]/)[0] ?? "";
|
|
4546
|
+
const parts = core.split(".");
|
|
4547
|
+
if (parts.length === 0 || parts.some((p2) => p2 === "" || !/^\d+$/.test(p2))) return null;
|
|
4548
|
+
return parts.map((p2) => Number.parseInt(p2, 10));
|
|
4549
|
+
}
|
|
4550
|
+
var init_semver = __esm({
|
|
4551
|
+
"src/util/semver.ts"() {
|
|
4552
|
+
"use strict";
|
|
4553
|
+
}
|
|
4554
|
+
});
|
|
4555
|
+
|
|
4530
4556
|
// src/commands/report.ts
|
|
4531
4557
|
async function checkCliUpdate(currentVersion) {
|
|
4532
4558
|
const result = await run("npm", ["view", "@caddis/cli", "version"], { timeout: 5e3 });
|
|
@@ -4541,7 +4567,10 @@ function classify(adapter, detection, status4, poolVersion) {
|
|
|
4541
4567
|
if (!status4.installed) return "missing";
|
|
4542
4568
|
if (!status4.version) return "unknown";
|
|
4543
4569
|
if (poolVersion === "unknown") return "unknown";
|
|
4544
|
-
|
|
4570
|
+
const order = compareVersions(status4.version, poolVersion);
|
|
4571
|
+
if (order === null) return status4.version === poolVersion ? "current" : "stale";
|
|
4572
|
+
if (order === 0) return "current";
|
|
4573
|
+
return order > 0 ? "ahead" : "stale";
|
|
4545
4574
|
}
|
|
4546
4575
|
async function gather(adapters, options = {}) {
|
|
4547
4576
|
const manifest = bundleManifest();
|
|
@@ -4578,6 +4607,7 @@ function actionable(report, includeCurrent = false) {
|
|
|
4578
4607
|
return report.agents.filter((entry) => {
|
|
4579
4608
|
if (!entry.detection.present || !entry.adapter.supported) return false;
|
|
4580
4609
|
if (includeCurrent) return true;
|
|
4610
|
+
if (entry.drift === "ahead") return false;
|
|
4581
4611
|
return entry.drift !== "current" || entry.extrasDrift === "stale" || entry.extrasDrift === "unknown";
|
|
4582
4612
|
});
|
|
4583
4613
|
}
|
|
@@ -4586,6 +4616,7 @@ var init_report = __esm({
|
|
|
4586
4616
|
"use strict";
|
|
4587
4617
|
init_exec();
|
|
4588
4618
|
init_pkg();
|
|
4619
|
+
init_semver();
|
|
4589
4620
|
}
|
|
4590
4621
|
});
|
|
4591
4622
|
|
|
@@ -4671,10 +4702,18 @@ async function update(options) {
|
|
|
4671
4702
|
const targets = actionable(report, options.force === true);
|
|
4672
4703
|
if (targets.length === 0) {
|
|
4673
4704
|
const supportedPresent = report.agents.filter((e2) => e2.detection.present && e2.adapter.supported);
|
|
4705
|
+
const ahead = report.agents.filter((e2) => e2.drift === "ahead");
|
|
4674
4706
|
line("");
|
|
4675
|
-
|
|
4676
|
-
|
|
4677
|
-
)
|
|
4707
|
+
if (supportedPresent.length === 0) {
|
|
4708
|
+
line(` ${color.yellow("No supported agent found.")} caddis v0.1 drives Claude Code and agy.`);
|
|
4709
|
+
} else if (ahead.length > 0) {
|
|
4710
|
+
line(
|
|
4711
|
+
` ${color.green("Nothing to do.")} ${ahead.length} agent(s) are NEWER than this package's bundled pool (${report.poolVersion}) \u2014 driving them would be a DOWNGRADE, so they were left alone.`
|
|
4712
|
+
);
|
|
4713
|
+
line(` Update the CLI itself (${color.cyan("npm i -g @caddis/cli")}), or ${color.cyan("--force")} to roll back deliberately.`);
|
|
4714
|
+
} else {
|
|
4715
|
+
line(` ${color.green("Everything is already current.")} Use --force to re-drive anyway.`);
|
|
4716
|
+
}
|
|
4678
4717
|
return 0;
|
|
4679
4718
|
}
|
|
4680
4719
|
line("");
|
|
@@ -4805,6 +4844,7 @@ function renderSummary(report, findings) {
|
|
|
4805
4844
|
function markFor(drift) {
|
|
4806
4845
|
switch (drift) {
|
|
4807
4846
|
case "current":
|
|
4847
|
+
case "ahead":
|
|
4808
4848
|
return "ok";
|
|
4809
4849
|
case "stale":
|
|
4810
4850
|
case "missing":
|
|
@@ -4820,6 +4860,8 @@ function describe(entry, poolVersion) {
|
|
|
4820
4860
|
switch (entry.drift) {
|
|
4821
4861
|
case "current":
|
|
4822
4862
|
return `caddis ${entry.status.version} ${color.dim("(current)")}`;
|
|
4863
|
+
case "ahead":
|
|
4864
|
+
return `caddis ${color.green(entry.status.version ?? "?")} ${color.dim("\u2014 newer than this CLI bundles")} ${color.dim(`(${poolVersion}); left alone, update @caddis/cli to catch up`)}`;
|
|
4823
4865
|
case "stale":
|
|
4824
4866
|
return `caddis ${color.yellow(entry.status.version ?? "?")} ${color.dim("\u2192")} ${color.bold(poolVersion)} available`;
|
|
4825
4867
|
case "unknown":
|
|
@@ -4986,10 +5028,17 @@ async function status3(options) {
|
|
|
4986
5028
|
const stale = report.agents.filter(
|
|
4987
5029
|
(entry) => entry.drift === "stale" || entry.drift === "missing" || entry.extrasDrift === "stale"
|
|
4988
5030
|
);
|
|
5031
|
+
const ahead = report.agents.filter((entry) => entry.drift === "ahead");
|
|
4989
5032
|
if (stale.length > 0) {
|
|
4990
5033
|
line(` ${color.yellow(`${stale.length} agent(s) behind`)} \u2014 run ${color.cyan("caddis update")} (or ${color.cyan("caddis doctor")} for detail)`);
|
|
4991
5034
|
line("");
|
|
4992
5035
|
}
|
|
5036
|
+
if (ahead.length > 0) {
|
|
5037
|
+
line(
|
|
5038
|
+
` ${ahead.length} agent(s) are NEWER than this CLI's bundled pool (${report.poolVersion}) \u2014 left alone. Update the CLI itself (${color.cyan("npm i -g @caddis/cli")}) to catch up.`
|
|
5039
|
+
);
|
|
5040
|
+
line("");
|
|
5041
|
+
}
|
|
4993
5042
|
return 0;
|
|
4994
5043
|
}
|
|
4995
5044
|
function toRow(entry) {
|
|
@@ -5010,6 +5059,8 @@ function stateLabel(drift, disabled) {
|
|
|
5010
5059
|
return disabled ? color.yellow("current, disabled") : color.green("current");
|
|
5011
5060
|
case "stale":
|
|
5012
5061
|
return color.yellow("update available");
|
|
5062
|
+
case "ahead":
|
|
5063
|
+
return color.green("newer than CLI pool");
|
|
5013
5064
|
case "unknown":
|
|
5014
5065
|
return color.yellow("version unknown");
|
|
5015
5066
|
case "missing":
|
package/package.json
CHANGED