@caddis/cli 0.2.0 → 0.2.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.
package/README.md CHANGED
@@ -121,6 +121,21 @@ caddis update --extras # add extras to an existing install
121
121
  The first run. Detects, shows exactly what it is about to run, asks, then installs. `--yes` skips
122
122
  the prompt for CI.
123
123
 
124
+ ### Removing caddis
125
+
126
+ **There is no `caddis remove`.** This CLI installs and updates; it never uninstalls. Removal goes
127
+ through each agent's own command — the same principle as everything else here:
128
+
129
+ ```bash
130
+ claude plugin uninstall caddis@caddis # Claude Code
131
+ claude plugin uninstall caddis-extras@caddis
132
+ agy plugin uninstall caddis # agy
133
+ agy plugin uninstall caddis-extras
134
+ ```
135
+
136
+ `npm uninstall -g @caddis/cli` removes **only this CLI**, not the caddis plugins it installed into
137
+ your agents. Uninstall those first if you want caddis gone entirely.
138
+
124
139
  ---
125
140
 
126
141
  ## Flags
@@ -34,11 +34,9 @@ import os
34
34
  import re
35
35
  import sys
36
36
 
37
- # Functional identity, mirrored from scripts/claudster_config.py. Read order: the current dir first,
38
- # the pre-rename dir as a one-version fallback.
39
- _ARTIFACT_DIRS = (".caddis", ".claudster")
37
+ # Functional identity, mirrored from scripts/claudster_config.py.
38
+ _ARTIFACT_DIR = ".caddis"
40
39
  _ENV_PREFIX = "CADDIS"
41
- _LEGACY_ENV_PREFIX = "CLAUDSTER"
42
40
 
43
41
  # ── protected-path rules (write → deny) ──────────────────────────────────────
44
42
  _SECRET_BASENAMES = {"id_rsa", "id_dsa", "id_ecdsa", "id_ed25519", "credentials",
@@ -221,12 +219,9 @@ _TRUTHY = {"1", "true", "yes", "on"}
221
219
 
222
220
 
223
221
  def _config_path(root: str) -> str | None:
224
- """The repo's ``config.toml`` — ``.caddis`` preferred, legacy ``.claudster`` as fallback."""
225
- for name in _ARTIFACT_DIRS:
226
- cfg = os.path.join(str(root), name, "config.toml")
227
- if os.path.isfile(cfg):
228
- return cfg
229
- return None
222
+ """The repo's ``.caddis/config.toml``, or ``None`` if it doesn't exist."""
223
+ cfg = os.path.join(str(root), _ARTIFACT_DIR, "config.toml")
224
+ return cfg if os.path.isfile(cfg) else None
230
225
 
231
226
 
232
227
  def _load_guard_config(root: str) -> dict:
@@ -253,11 +248,8 @@ def guard_disabled(root: str) -> bool:
253
248
  """True when the guard is turned off entirely (all tiers bypassed).
254
249
 
255
250
  Precedence: the env var wins (global); otherwise the per-repo `[guard]` table — `enabled = false`
256
- or `mode = "off"`. Any parse problem → not disabled (fail safe). CADDIS_GUARD_DISABLED is the
257
- current name; the pre-rename CLAUDSTER_GUARD_DISABLED is read only when the new name is unset."""
258
- _disabled = os.environ.get(f"{_ENV_PREFIX}_GUARD_DISABLED")
259
- if _disabled is None:
260
- _disabled = os.environ.get(f"{_LEGACY_ENV_PREFIX}_GUARD_DISABLED", "")
251
+ or `mode = "off"`. Any parse problem → not disabled (fail safe). Env var: CADDIS_GUARD_DISABLED."""
252
+ _disabled = os.environ.get(f"{_ENV_PREFIX}_GUARD_DISABLED", "")
261
253
  if _disabled.strip().lower() in _TRUTHY:
262
254
  return True
263
255
  section = _load_guard_config(root)
@@ -271,11 +263,8 @@ def guard_disabled(root: str) -> bool:
271
263
  def deny_only(root: str) -> bool:
272
264
  """True when the guard keeps DENY (silent hard-block) but suppresses the ASK tier (ask -> allow =
273
265
  silence), so it NEVER prompts — for autonomous / no-prompt workflows that still want a catastrophe
274
- net. Env `CADDIS_GUARD_MODE=deny-only` (`CLAUDSTER_GUARD_MODE` fallback); config `[guard] mode =
275
- "deny-only"`. Read silently."""
276
- _mode = os.environ.get(f"{_ENV_PREFIX}_GUARD_MODE")
277
- if _mode is None:
278
- _mode = os.environ.get(f"{_LEGACY_ENV_PREFIX}_GUARD_MODE", "")
266
+ net. Env `CADDIS_GUARD_MODE=deny-only`; config `[guard] mode = "deny-only"`. Read silently."""
267
+ _mode = os.environ.get(f"{_ENV_PREFIX}_GUARD_MODE", "")
279
268
  if _mode.strip().lower() == "deny-only":
280
269
  return True
281
270
  section = _load_guard_config(root)
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "caddis",
3
- "version": "1.3.39",
3
+ "version": "1.3.40",
4
4
  "description": "caddis — agent-agnostic dev harness as an Antigravity (agy) plugin: TDD skills + commands, single-sourced with the Claude Code plugin."
5
5
  }
@@ -2,8 +2,8 @@
2
2
  """caddis `session_end` hook for agy (Antigravity) — Stop event.
3
3
 
4
4
  Ports claude-harness/hooks/session_end.py to agy's contract. On Stop, appends ONE session-end record to
5
- the workspace's usage log (`<workspace>/.caddis/usage-log.jsonl`, or `.claudster/` if the repo still lives
6
- there). Self-contained (the agy bundle does not ship claudster_config.py), stdlib-only, and fully defensive:
5
+ the workspace's usage log (`<workspace>/.caddis/usage-log.jsonl`). Self-contained (the agy bundle does not
6
+ ship claudster_config.py), stdlib-only, and fully defensive:
7
7
  a Stop hook must never fail the turn, and must not print a non-JSON line to stdout (agy parses Stop-hook
8
8
  stdout as a `{"decision":…}` object — a stray string trips its "unsupported hook decision" path). So this
9
9
  does a pure side effect and prints NOTHING.
@@ -19,11 +19,6 @@ from datetime import datetime, timezone
19
19
 
20
20
 
21
21
  def _artifact_root(root: str) -> str:
22
- """Write where the repo lives: prefer .caddis, keep .claudster if that's what the repo has."""
23
- for name in (".caddis", ".claudster"):
24
- path = os.path.join(str(root), name)
25
- if os.path.isdir(path):
26
- return path
27
22
  return os.path.join(str(root), ".caddis")
28
23
 
29
24
 
@@ -12,7 +12,7 @@ complement to `/caddis:code-review`, not a replacement.
12
12
 
13
13
  ## Prerequisite (one-time)
14
14
  A provider key must be resolvable. Precedence: `REVIEW_API_KEY` > the provider's own env var
15
- (`DEEPSEEK_API_KEY` / `GLM_API_KEY`) > `OSS_API_KEY` > the keys file (`~/.claudster/keys.env`,
15
+ (`DEEPSEEK_API_KEY` / `GLM_API_KEY`) > `OSS_API_KEY` > the keys file (`~/.caddis/keys.env`,
16
16
  overridable via `CADDIS_KEYS_FILE`). If your keys file is populated, no env setup is needed.
17
17
  Details: the `coding/cross-review` skill and the **Providers & keys** guide.
18
18
 
@@ -46,8 +46,8 @@ plan A on the workstream stack — so its exact resume point survives and `/resu
46
46
  > per-branch file automatically when it exists, then `.caddis/relay.md`, then the legacy
47
47
  > `.claude/relay/<branch>.md` and root `relay.md` (back-compat during the migration).
48
48
  >
49
- > **Write where the repo lives:** if this repo still has a `.claudster/` (and no `.caddis/`), write
50
- > the relay THERE — don't create a second artifact dir. `/caddis:migrate-dir` converts the repo.
49
+ > A repo still on the pre-rename `.claudster/` won't see this relay until it's converted —
50
+ > `/caddis:migrate-dir` does that.
51
51
 
52
52
  ```markdown
53
53
  # Relay — <feature>
@@ -35,7 +35,7 @@ alias claude-glm="<path-to>/claude-harness/scripts/claude-oss.sh"
35
35
  ```
36
36
  Resolve `<path-to>` per the same plugin-vs-source rule as the generator itself (`${CLAUDE_PLUGIN_ROOT}`
37
37
  for a plugin install, the harness checkout path for caddis). Also set `CADDIS_KEYS_FILE`
38
- (default `~/.claudster/keys.env`) with the provider keys — see `docs/guide/providers-and-keys.md`.
38
+ (default `~/.caddis/keys.env`) with the provider keys — see `docs/guide/providers-and-keys.md`.
39
39
 
40
40
  ## After the deterministic step — deploy private harness skills (optional)
41
41
 
@@ -45,9 +45,7 @@ such a source on disk; it is a no-op for everyone else. Point `CADDIS_HARNESS_SR
45
45
  (the folder containing your private `skills/private/`) and run:
46
46
 
47
47
  ```powershell
48
- # CADDIS_HARNESS_SRC is current; CLAUDSTER_HARNESS_SRC is read as a one-version fallback.
49
- $harnessSrc = if ($env:CADDIS_HARNESS_SRC) { $env:CADDIS_HARNESS_SRC } else { $env:CLAUDSTER_HARNESS_SRC }
50
- $src = if ($harnessSrc) { Join-Path $harnessSrc "skills\private" } else { $null }
48
+ $src = if ($env:CADDIS_HARNESS_SRC) { Join-Path $env:CADDIS_HARNESS_SRC "skills\private" } else { $null }
51
49
  $dest = ".github\skills\private"
52
50
  if ($src -and (Test-Path $src)) {
53
51
  New-Item -ItemType Directory -Force $dest | Out-Null
@@ -39,7 +39,7 @@ paired with `OSS_BASE_URL`/`OSS_MODEL`).
39
39
  ## Key resolution (never hardcoded)
40
40
  Precedence, highest wins:
41
41
  1. the provider's env var (`GLM_API_KEY` / `DEEPSEEK_API_KEY` / `OPENROUTER_API_KEY`) or generic `OSS_API_KEY`;
42
- 2. a keys file at `$CADDIS_KEYS_FILE` (default `~/.claudster/keys.env`, `KEY=VALUE` lines, `#` comments);
42
+ 2. a keys file at `$CADDIS_KEYS_FILE` (default `~/.caddis/keys.env`, `KEY=VALUE` lines, `#` comments);
43
43
  3. missing → the launcher exits non-zero with an actionable message naming the exact env var to set.
44
44
 
45
45
  The resolver is `claude-harness/scripts/oss_model.py` (`resolve(provider, env)`) — the one place a
@@ -25,7 +25,7 @@ import os
25
25
  import subprocess
26
26
  import sys
27
27
 
28
- _ARTIFACT_DIRS = (".caddis", ".claudster")
28
+ _ARTIFACT_DIRS = (".caddis",)
29
29
 
30
30
  INJECT_MAX_LINES = 120 # same budget as the Claude Code hook
31
31
  INJECT_MAX_CHARS = 24000 # hard backstop: an ephemeralMessage should never be a context bomb
@@ -59,8 +59,8 @@ def resolve_relay(root: str) -> str:
59
59
  """First existing relay doc for `root`, else "".
60
60
 
61
61
  Preference order mirrors inject_relay.py:
62
- 1. <artifact-dir>/relay/<branch>.md (per-branch team mode — .caddis, then .claudster)
63
- 2. <artifact-dir>/relay.md (solo/default — .caddis, then .claudster)
62
+ 1. .caddis/relay/<branch>.md (per-branch team mode)
63
+ 2. .caddis/relay.md (solo/default)
64
64
  3. .claude/relay/<branch>.md (legacy per-branch)
65
65
  4. relay.md (legacy repo root)
66
66
  """
@@ -1,7 +1,7 @@
1
1
  {
2
- "poolVersion": "1.3.39",
2
+ "poolVersion": "1.3.40",
3
3
  "bundles": {
4
- "antigravity-plugin": "1.3.39",
4
+ "antigravity-plugin": "1.3.40",
5
5
  "antigravity-plugin-extras": "1.3.13"
6
6
  }
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@caddis/cli",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Install, update and diagnose the caddis dev harness across every coding agent you use (Claude Code, agy/Antigravity, and more).",
5
5
  "keywords": [
6
6
  "caddis",