@caddis/cli 0.4.33 → 0.4.35
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/agents/code-reviewer.md +4 -0
- package/bundles/antigravity-plugin/plugin.json +1 -1
- package/bundles/antigravity-plugin/scripts/caddis_file_lock.py +121 -0
- package/bundles/antigravity-plugin/scripts/caddis_frontmatter.py +12 -0
- package/bundles/antigravity-plugin/scripts/caddis_gate.py +185 -4
- package/bundles/antigravity-plugin/scripts/caddis_inventory.py +9 -9
- package/bundles/antigravity-plugin/scripts/caddis_relay_git.py +159 -0
- package/bundles/antigravity-plugin/scripts/caddis_tidy.py +579 -40
- package/bundles/antigravity-plugin/scripts/caddis_todo.py +462 -0
- package/bundles/antigravity-plugin/scripts/caddis_workstreams.py +631 -0
- package/bundles/antigravity-plugin/scripts/check_doc_coverage.py +27 -13
- package/bundles/antigravity-plugin/scripts/oss_review.py +30 -3
- package/bundles/antigravity-plugin/scripts/setup_project_ai.py +5 -0
- package/bundles/antigravity-plugin/scripts/usage_review.py +2 -2
- package/bundles/antigravity-plugin/session_end_agy.py +16 -1
- package/bundles/antigravity-plugin/skills/_registry.md +34 -32
- package/bundles/antigravity-plugin/skills/adopt-app/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/advisory-hub/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/api-design/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/backend-development/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/catchup/SKILL.md +31 -33
- package/bundles/antigravity-plugin/skills/ci-cd-pipeline/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/code-documentation/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/code-review/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/codebase-audit/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/confluence-hla/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/cross-review/SKILL.md +9 -1
- package/bundles/antigravity-plugin/skills/css-architecture/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/dashboard-perf-sweep/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/database-design/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/db-diagram/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/decide/SKILL.md +61 -0
- package/bundles/antigravity-plugin/skills/digress/SKILL.md +41 -23
- package/bundles/antigravity-plugin/skills/error-handling/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/explainer-doc/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/feature-plan/SKILL.md +5 -0
- package/bundles/antigravity-plugin/skills/frontend-design/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/gate-preflight/SKILL.md +12 -0
- package/bundles/antigravity-plugin/skills/handoff/SKILL.md +74 -13
- package/bundles/antigravity-plugin/skills/implement/SKILL.md +21 -0
- package/bundles/antigravity-plugin/skills/mermaid-diagrams/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/mmr/SKILL.md +8 -0
- package/bundles/antigravity-plugin/skills/particle-art/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/playwright/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/port-to-github/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/pr-merge/SKILL.md +15 -0
- package/bundles/antigravity-plugin/skills/python/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/rca/SKILL.md +97 -0
- package/bundles/antigravity-plugin/skills/react-dev/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/safe-cleanup/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/ship/SKILL.md +19 -4
- package/bundles/antigravity-plugin/skills/ship-merge/SKILL.md +15 -0
- package/bundles/antigravity-plugin/skills/skill-creator/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/sql/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/tech-explainer/SKILL.md +7 -12
- package/bundles/antigravity-plugin/skills/technical-writing/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/test-strategy/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/ui-review/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/using-git-worktrees/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/warm-editorial-ui/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/webapp-testing/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/windows-deployment/SKILL.md +1 -1
- package/bundles/antigravity-plugin/warm_start_agy.py +138 -42
- package/bundles/antigravity-plugin-extras/plugin.json +1 -1
- package/bundles/antigravity-plugin-extras/skills/_registry.md +61 -61
- package/bundles/antigravity-plugin-extras/skills/agent-md-refactor/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/agent-orchestration/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/algorithmic-art/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/api-client-patterns/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/architecture-diagram/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/architecture-document/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/artifacts-builder/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/ascii-art/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/aws-cdk-development/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/aws-cost-operations/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/aws-serverless-eda/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/backend-to-frontend-handoff/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/banner-design/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/brand-design/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/brand-guidelines/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/brand-voice/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/building-ai-agent-on-cloudflare/SKILL.md +3 -7
- package/bundles/antigravity-plugin-extras/skills/building-mcp-server-on-cloudflare/SKILL.md +3 -7
- package/bundles/antigravity-plugin-extras/skills/canvas-design/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/changelog-generator/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/code-explainer/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/component-testing/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/cross-review/SKILL.md +10 -2
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/data-loader/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/data-validation/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/deploy-local/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/design-md/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/design-system-tokens/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/developer-growth-analysis/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/doc-coauthoring/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/documentation-analyzer/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/enterprise-dashboard-aesthetic-system/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/file-organizer/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/game-changing-features/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/golden-nuggets/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/golden-plan/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/hld/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/internal-comms/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/jira-issues/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/lld/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/llm-application-dev/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/mcp-builder/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/monorepo/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/nextjs-app-router/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/observability/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/performance-testing/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/popular-web-designs/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/prd-to-code/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/react-useeffect/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/receiving-code-review/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/responsive-mobile-native/SKILL.md +4 -9
- package/bundles/antigravity-plugin-extras/skills/safe-cleanup/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/schema-migration/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/setup-project-ai/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/shadcn-radix/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/sketch/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/streamlit-dev/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/theme-factory/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/ui-styling-patterns/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/understand-anything/SKILL.md +5 -9
- package/bundles/antigravity-plugin-extras/skills/update-readme/SKILL.md +1 -1
- package/bundles/antigravity-plugin-extras/skills/word-cloud/SKILL.md +1 -1
- package/bundles/codex/.codex/skills/coding/api-design/SKILL.md +1 -1
- package/bundles/codex/.codex/skills/coding/backend-development/SKILL.md +1 -1
- package/bundles/codex/.codex/skills/coding/code-review/SKILL.md +1 -1
- package/bundles/codex/.codex/skills/coding/codebase-audit/SKILL.md +1 -1
- package/bundles/codex/.codex/skills/coding/dashboard-perf-sweep/SKILL.md +1 -1
- package/bundles/codex/.codex/skills/coding/error-handling/SKILL.md +1 -1
- package/bundles/codex/.codex/skills/coding/python/SKILL.md +1 -1
- package/bundles/codex/.codex/skills/coding/sql/SKILL.md +1 -1
- package/bundles/codex/.codex/skills/data/database-design/SKILL.md +1 -1
- package/bundles/codex/.codex/skills/data/db-diagram/SKILL.md +1 -1
- package/bundles/codex/.codex/skills/devops/adopt-app/SKILL.md +1 -1
- package/bundles/codex/.codex/skills/devops/ci-cd-pipeline/SKILL.md +1 -1
- package/bundles/codex/.codex/skills/devops/port-to-github/SKILL.md +1 -1
- package/bundles/codex/.codex/skills/devops/safe-cleanup/SKILL.md +1 -1
- package/bundles/codex/.codex/skills/devops/using-git-worktrees/SKILL.md +1 -1
- package/bundles/codex/.codex/skills/devops/windows-deployment/SKILL.md +1 -1
- package/bundles/codex/.codex/skills/docs/code-documentation/SKILL.md +1 -1
- package/bundles/codex/.codex/skills/docs/confluence-hla/SKILL.md +1 -1
- package/bundles/codex/.codex/skills/docs/explainer-doc/SKILL.md +1 -1
- package/bundles/codex/.codex/skills/docs/tech-explainer/SKILL.md +7 -12
- package/bundles/codex/.codex/skills/docs/technical-writing/SKILL.md +1 -1
- package/bundles/codex/.codex/skills/frontend/css-architecture/SKILL.md +1 -1
- package/bundles/codex/.codex/skills/frontend/frontend-design/SKILL.md +1 -1
- package/bundles/codex/.codex/skills/frontend/react-dev/SKILL.md +1 -1
- package/bundles/codex/.codex/skills/frontend/ui-review/SKILL.md +1 -1
- package/bundles/codex/.codex/skills/frontend/warm-editorial-ui/SKILL.md +1 -1
- package/bundles/codex/.codex/skills/media/mermaid-diagrams/SKILL.md +1 -1
- package/bundles/codex/.codex/skills/media/particle-art/SKILL.md +1 -1
- package/bundles/codex/.codex/skills/testing/playwright/SKILL.md +1 -1
- package/bundles/codex/.codex/skills/testing/test-strategy/SKILL.md +1 -1
- package/bundles/codex/.codex/skills/testing/webapp-testing/SKILL.md +1 -1
- package/bundles/codex/.codex/skills/workflow/advisory-hub/SKILL.md +1 -1
- package/bundles/codex/.codex/skills/workflow/skill-creator/SKILL.md +1 -1
- package/bundles/codex/AGENTS.md +5 -1
- package/bundles/manifest.json +3 -3
- package/package.json +1 -1
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rca
|
|
3
|
+
description: Record a root cause in one step — .caddis/rca/<date>-<slug>.md — or close one with the fixing commit
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /caddis:rca — record a root cause, or close one
|
|
7
|
+
|
|
8
|
+
A root cause found mid-task gets forgotten by the next session that hits the same symptom. This
|
|
9
|
+
command writes one down in a single step, and closes it later with the commit that fixed it.
|
|
10
|
+
|
|
11
|
+
The request is **$ARGUMENTS**.
|
|
12
|
+
|
|
13
|
+
## Mode select
|
|
14
|
+
|
|
15
|
+
| `$ARGUMENTS` | Do this |
|
|
16
|
+
|---|---|
|
|
17
|
+
| starts with `done ` | Go to **Close mode** |
|
|
18
|
+
| anything else | Go to **File mode** — the text is the symptom |
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## File mode
|
|
23
|
+
|
|
24
|
+
### Step 1 — build the slug
|
|
25
|
+
Lower-case the symptom text, replace each run of characters outside `a-z0-9` with one `-`, trim
|
|
26
|
+
`-` from both ends, cap at 60 characters (`Login fails: 401!` → `login-fails-401`). If nothing is left after cleaning, **stop and ask the user for a shorter title** — the
|
|
27
|
+
one question this command may ask.
|
|
28
|
+
|
|
29
|
+
### Step 2 — pick the path
|
|
30
|
+
`.caddis/rca/<YYYY-MM-DD>-<slug>.md`, using today's date (UTC). Create `.caddis/rca/` first if it
|
|
31
|
+
does not exist.
|
|
32
|
+
|
|
33
|
+
**If that exact path already exists, refuse — never overwrite it.** Print the existing path and
|
|
34
|
+
stop; the user can open it directly, or pick different (more specific) symptom text so the slug
|
|
35
|
+
comes out differently.
|
|
36
|
+
|
|
37
|
+
### Step 3 — write the file
|
|
38
|
+
|
|
39
|
+
```markdown
|
|
40
|
+
---
|
|
41
|
+
type: rca
|
|
42
|
+
status: open
|
|
43
|
+
found: <YYYY-MM-DD>
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
# <symptom, verbatim>
|
|
47
|
+
|
|
48
|
+
## Symptom
|
|
49
|
+
<what was observed — the exact error, command, or behaviour>
|
|
50
|
+
|
|
51
|
+
## Root cause
|
|
52
|
+
<why it happened, not just what happened>
|
|
53
|
+
|
|
54
|
+
## Fix
|
|
55
|
+
<what changed to remove the cause>
|
|
56
|
+
|
|
57
|
+
## How verified
|
|
58
|
+
<the command or check that proves the fix, and its result>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Leave a section as its one-line prompt if the answer is not known yet — `/rca done` below is where
|
|
62
|
+
it gets filled in for real.
|
|
63
|
+
|
|
64
|
+
### Step 4 — verify
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_gate.py" docs-check --root .
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Exit 0 means the header is valid. Do not report the item as filed until this passes.
|
|
71
|
+
|
|
72
|
+
### Step 5 — report
|
|
73
|
+
One line: the path. Nothing else.
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## Close mode — `done <file>`
|
|
78
|
+
|
|
79
|
+
`<file>` is a path under `.caddis/rca/`, optionally followed by a commit SHA.
|
|
80
|
+
|
|
81
|
+
1. If the file does not exist, say so and change nothing.
|
|
82
|
+
2. If its header does not carry `type: rca`, say so and change nothing.
|
|
83
|
+
3. If its `status:` is already `done`, say so and change nothing — closing an already-closed RCA is
|
|
84
|
+
a no-op, not a re-close.
|
|
85
|
+
4. Otherwise set `status: done` and add `commit: <short SHA>` to the header. The SHA is whatever the
|
|
86
|
+
user gave after the filename in `$ARGUMENTS`; if none was given, use `git rev-parse --short HEAD`.
|
|
87
|
+
It must match `^[0-9a-f]{7,40}$`; if it does not, say so and change nothing.
|
|
88
|
+
5. Fill in **Root cause**, **Fix**, and **How verified** only with facts from this session or the
|
|
89
|
+
fixing commit. A section you do not know stays as its Step 3 prompt; never guess.
|
|
90
|
+
6. Run the Step 4 docs-check. If it does not exit 0, restore the file and report the error.
|
|
91
|
+
7. Report the path and the recorded commit. Nothing else.
|
|
92
|
+
|
|
93
|
+
## Rules
|
|
94
|
+
- **Never** overwrite an existing RCA file. A repeat symptom is either the same file (edit it by
|
|
95
|
+
hand) or genuinely different (use different symptom text so the slug comes out different).
|
|
96
|
+
- This command records facts about what already happened; it does not investigate or fix anything
|
|
97
|
+
itself.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: react-dev
|
|
3
3
|
version: 1.0.0
|
|
4
|
-
description:
|
|
4
|
+
description: "Type-safe React 18-19 with TypeScript: components, generic components, hooks, events, Server Components, TanStack Router and React Router. Use when React TypeScript or React 19 is involved."
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# React TypeScript
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: safe-cleanup
|
|
3
|
-
description: Use BEFORE deleting
|
|
3
|
+
description: Use BEFORE deleting a directory tree, scratchpad or git worktree, or "tidying up" generated folders, especially on Windows, where deleting through a junction or symlink destroys its target; and to verify a venv or node_modules survived.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Safe Cleanup
|
|
@@ -9,10 +9,11 @@ Ship the current working changes via this repo's actual delivery pipeline. The p
|
|
|
9
9
|
repo, so **detect it first**, then follow the matching lane. Preflight, staging, and commit are
|
|
10
10
|
identical across lanes; only monitoring and validation differ.
|
|
11
11
|
|
|
12
|
-
> **This is the express lane** —
|
|
13
|
-
>
|
|
14
|
-
> reviewed lane instead: `/ship-pr`** (open a
|
|
15
|
-
> (merge the green PR behind a deploy-confirm,
|
|
12
|
+
> **This is the express lane** — it pushes straight to the default branch with no review pause.
|
|
13
|
+
> Right for a hotfix. On a repo where that push deploys to production, Step 2c stops it before the
|
|
14
|
+
> push and the owner merges. **For feature work, use the reviewed lane instead: `/ship-pr`** (open a
|
|
15
|
+
> PR, monitor CI, stop at green) **→ `/ship-merge`** (merge the green PR behind a deploy-confirm,
|
|
16
|
+
> validate, clean up).
|
|
16
17
|
|
|
17
18
|
Optional message: **$ARGUMENTS** (if empty, derive a conventional commit message from staged changes)
|
|
18
19
|
|
|
@@ -63,6 +64,19 @@ over 400 changed lines. No judgement in any of those — deliberately, because j
|
|
|
63
64
|
what failed.
|
|
64
65
|
<!-- /shared:cross-review-trigger -->
|
|
65
66
|
|
|
67
|
+
**2c. DEPLOY BOUNDARY** — before the push; nothing skips it:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_gate.py" deploy-boundary --repo .
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Exit **0** (no deploy signal found) — push. Exit **1** (a push to the default branch deploys to
|
|
74
|
+
production), exit **3** (it cannot tell), or any other non-zero code — **stop. Do not merge or push to
|
|
75
|
+
the default branch.** The commit stays local. If it sits on the default branch, move it to a feature
|
|
76
|
+
branch first (`git switch -c <feature-branch>`). Then open a PR with `/ship-pr` and hand the merge
|
|
77
|
+
to the owner with the PR link. Show the gate's output and end the command. This holds whatever confirmation was given:
|
|
78
|
+
`--yes`, a confirm flag, "just merge it" or an earlier approval cannot bypass it.
|
|
79
|
+
|
|
66
80
|
**3. PUSH** — to the repo's default branch (confirm the branch first; don't assume `main`):
|
|
67
81
|
```
|
|
68
82
|
git push origin <branch>
|
|
@@ -113,6 +127,7 @@ Release tag: <tag> → <sha> | n/a
|
|
|
113
127
|
|
|
114
128
|
## Rules
|
|
115
129
|
- Never push before preflight gates are green.
|
|
130
|
+
- Never push to the default branch unless `deploy-boundary` exited 0 on this run.
|
|
116
131
|
- Never use `git add -A` without reviewing `git status` first.
|
|
117
132
|
- Do not edit a workflow file (`.gitea/workflows/` or `.github/workflows/`) to make a failing gate
|
|
118
133
|
pass — fix the source.
|
|
@@ -28,6 +28,20 @@ Resolve the target PR from `$ARGUMENTS`, else the current branch's open PR. No o
|
|
|
28
28
|
that and point at `/ship-pr`. Read `AGENTS.md` + the workflow file(s) for the repo's real deploy
|
|
29
29
|
job names and default branch — never assume.
|
|
30
30
|
|
|
31
|
+
## Step 0b — Deploy boundary (before the confirm; nothing skips it)
|
|
32
|
+
|
|
33
|
+
Run it before asking for any confirmation, in a checkout of the PR's own repository. If the
|
|
34
|
+
PR belongs to another repository, treat that as exit **3**.
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_gate.py" deploy-boundary --repo .
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Exit **0** — go on to Step 1. Exit **1** (a push to the default branch deploys to production), exit
|
|
41
|
+
**3** (it cannot tell), or any other non-zero code — **stop. Do not merge.** Hand the merge to the
|
|
42
|
+
owner with the PR link. Show the gate's output and end the command. This holds whatever confirmation
|
|
43
|
+
was given: `--yes`, a confirm flag, "just merge it" or an earlier approval cannot bypass it.
|
|
44
|
+
|
|
31
45
|
## Step 1 — Refuse unless green + mergeable + reviewed
|
|
32
46
|
|
|
33
47
|
All of, per the repo's own rules:
|
|
@@ -94,6 +108,7 @@ Cleanup: remote branch ✗ deleted / local ✗ deleted / backup ref droppe
|
|
|
94
108
|
|
|
95
109
|
## Rules
|
|
96
110
|
- Never merge without: green required checks **and** the explicit human deploy-confirm.
|
|
111
|
+
- Never merge unless `deploy-boundary` exited 0 on this run. No confirmation overrides it.
|
|
97
112
|
- Never delete a branch before its deploy is validated green.
|
|
98
113
|
- Never `git add -A` without reviewing `git status`; never edit a workflow file to make a gate pass.
|
|
99
114
|
- Local-only lane: no PR, no merge — refuse and point at `/ship`.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: skill-creator
|
|
3
3
|
context: fork
|
|
4
|
-
description: Create
|
|
4
|
+
description: Create, edit and improve skills, run evals and benchmarks, and optimize a skill's description for triggering accuracy.
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Skill Creator
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: sql
|
|
3
|
-
description: Write
|
|
3
|
+
description: "Write optimized, secure, readable SQL: performance, NULL handling, dialect-specific notes."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# SQL Expert Skill
|
|
@@ -2,18 +2,13 @@
|
|
|
2
2
|
name: tech-explainer
|
|
3
3
|
context: fork
|
|
4
4
|
description: >-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
it", "make a doc with diagrams explaining the stack", or is about to summarise an investigation, a
|
|
13
|
-
benchmark, a postmortem, an architecture, or a disagreement for a reader who will not read the raw
|
|
14
|
-
data. NOT for handing off work to be BUILT by a vendor or another team (use explainer-doc for that —
|
|
15
|
-
it produces an actionable spec); NOT for READMEs or API docs (use technical-writing). This one
|
|
16
|
-
produces UNDERSTANDING: the reader must finish able to argue with you on the merits.
|
|
5
|
+
Plain-language explainer, with ranked Mermaid diagrams and Simplified Technical English, for a
|
|
6
|
+
reader who did NOT do the investigation (manager, stakeholder). Use when the user says "explain
|
|
7
|
+
this to X", "explainer", "write this up for someone non-technical", "plain English", "simplified
|
|
8
|
+
technical english", "STE", "explain our findings", "write up the benchmark results", "answer my
|
|
9
|
+
manager's recommendations", "why is it slow — document it", "make a doc with diagrams explaining
|
|
10
|
+
the stack", or summarises an investigation for a reader who won't read the raw data. Not for build
|
|
11
|
+
hand-offs (explainer-doc) or READMEs.
|
|
17
12
|
---
|
|
18
13
|
|
|
19
14
|
# tech-explainer — make a stranger understand, and able to push back
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: technical-writing
|
|
3
3
|
context: fork
|
|
4
|
-
description:
|
|
4
|
+
description: Documentation best practices for READMEs, API docs, architecture docs, runbooks and developer guides. Use when writing or reviewing docs or setting documentation standards.
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Technical Writing Skill
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: test-strategy
|
|
3
3
|
context: fork
|
|
4
|
-
description:
|
|
4
|
+
description: "Plan what to test: test types, coverage goals, test pyramid, quality gates. Produces a prioritized TEST-STRATEGY.md for the Tester agent."
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Test Strategy Skill
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ui-review
|
|
3
|
-
description: Review UI
|
|
3
|
+
description: Review a UI against design requirements, WCAG 2.2 AA and brand guidelines. Use when validating UI before release.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# UI Review Skill
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: using-git-worktrees
|
|
3
|
-
description: Use when starting feature work that needs isolation from current workspace or before executing implementation
|
|
3
|
+
description: "Use when starting feature work that needs isolation from the current workspace, or before executing an implementation plan: creates an isolated git worktree safely."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Using Git Worktrees
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: warm-editorial-ui
|
|
3
|
-
description: Apply the "Warm Editorial Refinement" design system
|
|
3
|
+
description: Apply the "Warm Editorial Refinement" design system (warm cream/charcoal surfaces, Bahnschrift + Plus Jakarta Sans, layered shadows), the canonical template for new frontend builds. Use for apps, dashboards or UI in the abc-project style, or on "use our design system", "apply our template", "make it look like abc-project", "use the warm editorial style", "use our brand template", "add dark mode", or a new tool for XYZ Brand.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Warm Editorial Refinement — Design System
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: webapp-testing
|
|
3
3
|
context: fork
|
|
4
|
-
description:
|
|
4
|
+
description: "Test local web apps with Playwright: verify frontend behavior, debug UI, capture screenshots and browser logs."
|
|
5
5
|
license: Complete terms in LICENSE.txt
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: windows-deployment
|
|
3
|
-
description: "Deploy FastAPI + React/Vite apps to Windows Server with NSSM services,
|
|
3
|
+
description: "Deploy FastAPI + React/Vite apps to Windows Server with NSSM services, IIS or nginx reverse proxy and git-pull. Use for Windows prod deploys, NSSM, reverse proxy setup, dev/prod config, or prod troubleshooting."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Windows Server Deployment Skill
|
|
@@ -91,38 +91,97 @@ def _first_existing(paths: list[str]) -> str:
|
|
|
91
91
|
return ""
|
|
92
92
|
|
|
93
93
|
|
|
94
|
-
def
|
|
95
|
-
|
|
94
|
+
def scan_relays(root: str) -> list[tuple[str, dict]]:
|
|
95
|
+
results: list[tuple[str, dict]] = []
|
|
96
|
+
try:
|
|
97
|
+
from caddis_frontmatter import parse
|
|
98
|
+
except Exception:
|
|
99
|
+
_here = os.path.dirname(os.path.abspath(__file__))
|
|
100
|
+
for p in (
|
|
101
|
+
# Source tree: caddis_frontmatter.py is authored in claude-harness/scripts/.
|
|
102
|
+
os.path.join(os.path.dirname(_here), "scripts"),
|
|
103
|
+
# agy plugin: this file sits at the plugin root; scripts are in <plugin>/scripts/.
|
|
104
|
+
os.path.join(_here, "scripts"),
|
|
105
|
+
# Source tree, top-level scripts/ (harmless if the module is not there).
|
|
106
|
+
os.path.join(os.path.dirname(os.path.dirname(_here)), "scripts"),
|
|
107
|
+
):
|
|
108
|
+
if os.path.isdir(p) and p not in sys.path:
|
|
109
|
+
sys.path.insert(0, p)
|
|
110
|
+
try:
|
|
111
|
+
from caddis_frontmatter import parse
|
|
112
|
+
except Exception:
|
|
113
|
+
def parse(t): return {}
|
|
114
|
+
|
|
115
|
+
for d in _ARTIFACT_DIRS:
|
|
116
|
+
relay_dir = os.path.join(root, d, "relay")
|
|
117
|
+
if not os.path.isdir(relay_dir):
|
|
118
|
+
continue
|
|
119
|
+
try:
|
|
120
|
+
entries = list(os.scandir(relay_dir)) # exhausting it closes the handle
|
|
121
|
+
except OSError:
|
|
122
|
+
continue
|
|
123
|
+
for entry in entries:
|
|
124
|
+
if entry.is_file() and entry.name.endswith(".md"):
|
|
125
|
+
try:
|
|
126
|
+
with open(entry.path, encoding="utf-8", errors="ignore") as handle:
|
|
127
|
+
text = handle.read()
|
|
128
|
+
meta = parse(text)
|
|
129
|
+
results.append((entry.path, meta))
|
|
130
|
+
except Exception:
|
|
131
|
+
continue
|
|
132
|
+
return results
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def resolve_relay(root: str, session_id: str = "") -> tuple[str, str | None]:
|
|
136
|
+
"""First existing relay doc for `root` and matched workstream name, else ("", None).
|
|
137
|
+
|
|
138
|
+
1. Session ID match takes precedence (matching meta['session_id'] with session_id).
|
|
139
|
+
2. Otherwise, if current branch is non-default, match relays by branch/workstream name.
|
|
140
|
+
If exactly 1 match: inject full relay.
|
|
141
|
+
3. If default branch or multiple/no matches: inject index (.caddis/relay.md).
|
|
142
|
+
"""
|
|
143
|
+
relays = scan_relays(root)
|
|
144
|
+
|
|
145
|
+
# 1. Session ID match takes precedence
|
|
146
|
+
if session_id:
|
|
147
|
+
for path, meta in relays:
|
|
148
|
+
if meta.get("session_id") and str(meta.get("session_id")) == str(session_id):
|
|
149
|
+
ws = meta.get("workstream") or os.path.splitext(os.path.basename(path))[0]
|
|
150
|
+
return path, ws
|
|
151
|
+
|
|
152
|
+
# 2. Branch lookup (best-effort)
|
|
96
153
|
try:
|
|
97
154
|
branch = subprocess.run(
|
|
98
155
|
["git", "-C", root, "rev-parse", "--abbrev-ref", "HEAD"],
|
|
99
156
|
capture_output=True, text=True, timeout=3,
|
|
100
157
|
).stdout.strip()
|
|
101
158
|
except Exception:
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
if
|
|
123
|
-
|
|
124
|
-
candidates
|
|
125
|
-
|
|
159
|
+
branch = ""
|
|
160
|
+
|
|
161
|
+
default_branches = {"main", "master", "trunk", "develop", "HEAD", ""}
|
|
162
|
+
slug = "" # set below for a non-default branch; also read by the legacy fallback
|
|
163
|
+
if branch and branch not in default_branches:
|
|
164
|
+
slug = "".join(c if (c.isalnum() or c in "-_.") else "-" for c in branch)
|
|
165
|
+
matched = []
|
|
166
|
+
for path, meta in relays:
|
|
167
|
+
ws = meta.get("workstream")
|
|
168
|
+
b = meta.get("branch")
|
|
169
|
+
stem = os.path.splitext(os.path.basename(path))[0]
|
|
170
|
+
if (b and b in (branch, slug)) or (ws and ws in (branch, slug)) or stem in (branch, slug):
|
|
171
|
+
matched.append((path, ws or stem))
|
|
172
|
+
if len(matched) == 1:
|
|
173
|
+
return matched[0]
|
|
174
|
+
|
|
175
|
+
# 3. Fallback: index (.caddis/relay.md) or legacy files
|
|
176
|
+
# Index, then the legacy per-branch .claude/relay/<branch>.md, then a root relay.md --
|
|
177
|
+
# the order used before workstream relays existed.
|
|
178
|
+
legacy_branch = []
|
|
179
|
+
if branch and branch not in default_branches:
|
|
180
|
+
legacy_branch = [os.path.join(root, ".claude", "relay", f"{slug}.md")]
|
|
181
|
+
candidates = ([os.path.join(root, d, "relay.md") for d in _ARTIFACT_DIRS] + legacy_branch
|
|
182
|
+
+ [os.path.join(root, "relay.md")])
|
|
183
|
+
idx_path = _first_existing(candidates)
|
|
184
|
+
return idx_path, None
|
|
126
185
|
|
|
127
186
|
|
|
128
187
|
def truncate_relay(text: str) -> str:
|
|
@@ -270,25 +329,60 @@ def main() -> None:
|
|
|
270
329
|
conversation = str(data.get("conversationId") or "").strip()
|
|
271
330
|
|
|
272
331
|
blocks = []
|
|
332
|
+
open_work_blocks = []
|
|
273
333
|
for root in roots:
|
|
274
|
-
|
|
275
|
-
if not relay:
|
|
334
|
+
if conversation and _already_injected(root, conversation):
|
|
276
335
|
continue
|
|
336
|
+
relay, matched_ws = resolve_relay(root, conversation)
|
|
337
|
+
text = ""
|
|
338
|
+
if relay:
|
|
339
|
+
try:
|
|
340
|
+
with open(relay, encoding="utf-8") as handle:
|
|
341
|
+
text = handle.read().strip()
|
|
342
|
+
except Exception as _exc:
|
|
343
|
+
_hook_note("agy relay read", _exc, root)
|
|
344
|
+
if text:
|
|
345
|
+
# Label the block ONLY when there is more than one root. A single-root session
|
|
346
|
+
# must produce byte-identical output to before this change.
|
|
347
|
+
if len(roots) > 1:
|
|
348
|
+
blocks.append("relay for " + os.path.basename(root.rstrip("/\\")) + ":")
|
|
349
|
+
blocks.append(truncate_relay(text))
|
|
350
|
+
|
|
351
|
+
# Open-work rows as plain text without seeding instruction. Shown with or without a
|
|
352
|
+
# relay: to-dos and plan phases exist before the first handoff writes one.
|
|
353
|
+
shown_open_work = False
|
|
277
354
|
try:
|
|
278
|
-
|
|
355
|
+
from pathlib import Path as _Path
|
|
356
|
+
# agy plugin: warm_start_agy.py sits at the plugin root, scripts in <plugin>/scripts.
|
|
357
|
+
# Source tree: claude-harness/agy -> <repo>/scripts, where caddis_todo.py is authored.
|
|
358
|
+
_here = os.path.dirname(os.path.abspath(__file__))
|
|
359
|
+
for _sc in (os.path.join(os.path.dirname(os.path.dirname(_here)), "scripts"),
|
|
360
|
+
os.path.join(_here, "scripts")):
|
|
361
|
+
if os.path.isdir(_sc) and _sc not in sys.path:
|
|
362
|
+
sys.path.insert(0, _sc)
|
|
363
|
+
import caddis_todo
|
|
364
|
+
open_items = caddis_todo.open_work(_Path(root), matched_ws)
|
|
365
|
+
if open_items:
|
|
366
|
+
# Same budget as the Claude Code hook: next 5 phases, 5 ad-hoc items.
|
|
367
|
+
phases = [r for r in open_items if r.get("kind") == "phase"][:5]
|
|
368
|
+
todos = [r for r in open_items if r.get("kind") != "phase"][:5]
|
|
369
|
+
shown = phases + todos
|
|
370
|
+
ow_lines = ["## Open work"]
|
|
371
|
+
if len(open_items) > len(shown):
|
|
372
|
+
ow_lines.append(f"(+{len(open_items) - len(shown)} more open items — run /catchup to see them.)")
|
|
373
|
+
for row in shown:
|
|
374
|
+
ow_lines.append(f"- {row['id']} [{row['kind']}] {' '.join(str(row['title']).split())[:100]}")
|
|
375
|
+
if len(roots) > 1:
|
|
376
|
+
open_work_blocks.append("open work for " + os.path.basename(root.rstrip("/\\")) + ":\n" + "\n".join(ow_lines))
|
|
377
|
+
else:
|
|
378
|
+
open_work_blocks.append("\n".join(ow_lines))
|
|
379
|
+
shown_open_work = True
|
|
279
380
|
except Exception as _exc:
|
|
280
|
-
_hook_note("agy
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
if conversation and
|
|
285
|
-
continue
|
|
286
|
-
# Label the block ONLY when there is more than one root. A single-root session
|
|
287
|
-
# must produce byte-identical output to before this change.
|
|
288
|
-
if len(roots) > 1:
|
|
289
|
-
blocks.append("relay for " + os.path.basename(root.rstrip("/\\")) + ":")
|
|
290
|
-
blocks.append(truncate_relay(text))
|
|
291
|
-
if conversation:
|
|
381
|
+
_hook_note("agy open work injection", _exc, root)
|
|
382
|
+
|
|
383
|
+
# A relay that exists but failed to read must not be marked injected just because
|
|
384
|
+
# open work was shown: the next invocation retries the relay.
|
|
385
|
+
if conversation and (text or (not relay and shown_open_work)):
|
|
292
386
|
_mark_injected(root, conversation)
|
|
293
387
|
|
|
294
388
|
# agy has no SessionStart event, so this first invocation is also where the freshness
|
|
@@ -298,12 +392,14 @@ def main() -> None:
|
|
|
298
392
|
for root in roots:
|
|
299
393
|
fresh.extend(freshness_lines(root))
|
|
300
394
|
|
|
301
|
-
if not blocks and not fresh:
|
|
395
|
+
if not blocks and not fresh and not open_work_blocks:
|
|
302
396
|
return
|
|
303
397
|
parts = []
|
|
304
398
|
if blocks:
|
|
305
399
|
parts.append(RELAY_FRAME_HEADER + "\n" + "\n\n".join(blocks)
|
|
306
400
|
+ "\n\n" + RELAY_FRAME_FOOTER)
|
|
401
|
+
if open_work_blocks:
|
|
402
|
+
parts.append("\n\n".join(open_work_blocks))
|
|
307
403
|
if fresh:
|
|
308
404
|
parts.append("\n".join(fresh))
|
|
309
405
|
payload = json.dumps({"injectSteps": [{"ephemeralMessage": "\n\n".join(parts)}]})
|