crewforth 0.0.1 → 3.0.0-rc.2
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/CHANGELOG.md +3805 -0
- package/LICENSE +21 -0
- package/README.md +37 -7
- package/VERSION +1 -0
- package/adopt.sh +1739 -0
- package/bin/cli.js +497 -0
- package/kit/AGENT_TEMPLATE.md +92 -0
- package/kit/CLAUDE.md +228 -0
- package/kit/README.md +107 -0
- package/kit/agents/crew-backend-expert.md +95 -0
- package/kit/agents/crew-commit-agent.md +96 -0
- package/kit/agents/crew-database-expert.md +84 -0
- package/kit/agents/crew-devops-expert.md +82 -0
- package/kit/agents/crew-frontend-expert.md +85 -0
- package/kit/agents/crew-performance-expert.md +78 -0
- package/kit/agents/crew-planner.md +60 -0
- package/kit/agents/crew-privacy-agent.md +71 -0
- package/kit/agents/crew-review-agent.md +95 -0
- package/kit/agents/crew-security-expert.md +73 -0
- package/kit/agents/crew-session-manager.md +77 -0
- package/kit/agents/crew-test-expert.md +64 -0
- package/kit/eval/doctor.sh +639 -0
- package/kit/eval/gate-report.sh +137 -0
- package/kit/eval/golden-holdout.txt +53 -0
- package/kit/eval/golden-routing.txt +199 -0
- package/kit/eval/lib/crew-env.sh +14 -0
- package/kit/eval/lib/settings-json.awk +154 -0
- package/kit/eval/lib/skill-listing.awk +43 -0
- package/kit/eval/lib/star.sh +70 -0
- package/kit/eval/parser-conformance.sh +612 -0
- package/kit/eval/preflight.sh +186 -0
- package/kit/eval/routing-eval.sh +209 -0
- package/kit/eval/scan-skill.sh +162 -0
- package/kit/eval/smoke-test.sh +6736 -0
- package/kit/eval/update-guard.sh +81 -0
- package/kit/eval/utilization.sh +130 -0
- package/kit/hooks/board-sync.sh +106 -0
- package/kit/hooks/board.sh +962 -0
- package/kit/hooks/commit-msg +49 -0
- package/kit/hooks/context-usage.sh +353 -0
- package/kit/hooks/floor-blocklist.txt +124 -0
- package/kit/hooks/guard-bash.sh +1433 -0
- package/kit/hooks/guard-commit-scan.sh +511 -0
- package/kit/hooks/guard-write.sh +513 -0
- package/kit/hooks/pre-commit +577 -0
- package/kit/hooks/route-hint.sh +185 -0
- package/kit/hooks/secret-blocklist.txt +82 -0
- package/kit/hooks/session-guard.sh +149 -0
- package/kit/hooks/session-rehydrate.sh +41 -0
- package/kit/hooks/session-stats.sh +252 -0
- package/kit/hooks/session-update-check.sh +236 -0
- package/kit/hooks/skill-trust.sh +163 -0
- package/kit/hooks/trace-blocklist.txt +53 -0
- package/kit/settings.json +132 -0
- package/kit/skills/a11y/SKILL.md +44 -0
- package/kit/skills/adr/SKILL.md +74 -0
- package/kit/skills/api-design/SKILL.md +50 -0
- package/kit/skills/automode-policy/SKILL.md +91 -0
- package/kit/skills/automode-policy/references/policy.json +13 -0
- package/kit/skills/automode-policy/scripts/apply.sh +84 -0
- package/kit/skills/automode-policy/scripts/check.sh +102 -0
- package/kit/skills/backend-architecture/SKILL.md +103 -0
- package/kit/skills/brainstorm/SKILL.md +47 -0
- package/kit/skills/ci-pipeline/SKILL.md +38 -0
- package/kit/skills/commit-message/SKILL.md +82 -0
- package/kit/skills/commit-message/references/examples.md +8 -0
- package/kit/skills/confidence-check/SKILL.md +86 -0
- package/kit/skills/crew-board/SKILL.md +55 -0
- package/kit/skills/crew-brainstorm/SKILL.md +19 -0
- package/kit/skills/crew-code-review/SKILL.md +151 -0
- package/kit/skills/crew-code-review/references/history-search.md +19 -0
- package/kit/skills/crew-code-review/references/panel-mode.md +32 -0
- package/kit/skills/crew-code-review/references/receiving.md +23 -0
- package/kit/skills/crew-doctor/SKILL.md +46 -0
- package/kit/skills/crew-gates/SKILL.md +25 -0
- package/kit/skills/crew-handoff/SKILL.md +14 -0
- package/kit/skills/crew-plan/SKILL.md +18 -0
- package/kit/skills/crew-review/SKILL.md +26 -0
- package/kit/skills/crew-ship/SKILL.md +19 -0
- package/kit/skills/crew-skill/SKILL.md +62 -0
- package/kit/skills/crew-studio/SKILL.md +129 -0
- package/kit/skills/crew-update/SKILL.md +43 -0
- package/kit/skills/db-migration/SKILL.md +120 -0
- package/kit/skills/db-migration/references/backup-restore.md +33 -0
- package/kit/skills/db-migration/references/raw-sql.md +30 -0
- package/kit/skills/db-migration/references/tool-matrix.md +35 -0
- package/kit/skills/dependency-audit/SKILL.md +61 -0
- package/kit/skills/dependency-upgrade/SKILL.md +82 -0
- package/kit/skills/deploy/SKILL.md +100 -0
- package/kit/skills/deploy/references/proxy-ssl.md +56 -0
- package/kit/skills/deploy/references/rollback.md +18 -0
- package/kit/skills/deploy/references/scripts.md +9 -0
- package/kit/skills/deploy/references/topology-a.md +128 -0
- package/kit/skills/deploy/references/topology-b.md +44 -0
- package/kit/skills/docs-writer/SKILL.md +53 -0
- package/kit/skills/docs-writer/references/coauthoring.md +34 -0
- package/kit/skills/eval-grader/SKILL.md +75 -0
- package/kit/skills/eval-grader/references/method.md +51 -0
- package/kit/skills/frontend/SKILL.md +56 -0
- package/kit/skills/frontend/references/verify-contract.md +41 -0
- package/kit/skills/frontend-design/SKILL.md +71 -0
- package/kit/skills/frontend-design/references/design-review.md +34 -0
- package/kit/skills/frontend-rn-expo/SKILL.md +25 -0
- package/kit/skills/handoff/SKILL.md +71 -0
- package/kit/skills/handoff/references/cold-reader.md +51 -0
- package/kit/skills/i18n-integrity/SKILL.md +31 -0
- package/kit/skills/incident-runbook/SKILL.md +40 -0
- package/kit/skills/incident-runbook/references/postmortem.md +16 -0
- package/kit/skills/iterate/SKILL.md +40 -0
- package/kit/skills/mcp-builder/SKILL.md +54 -0
- package/kit/skills/mcp-builder/references/building.md +71 -0
- package/kit/skills/observability/SKILL.md +50 -0
- package/kit/skills/performance/SKILL.md +38 -0
- package/kit/skills/performance/references/bottlenecks.md +10 -0
- package/kit/skills/privacy-compliance/SKILL.md +75 -0
- package/kit/skills/red-team/SKILL.md +48 -0
- package/kit/skills/reflect/SKILL.md +57 -0
- package/kit/skills/release/SKILL.md +44 -0
- package/kit/skills/security-scan/SKILL.md +99 -0
- package/kit/skills/security-scan/references/ai-agents.md +107 -0
- package/kit/skills/security-scan/references/fronts.md +99 -0
- package/kit/skills/security-scan/references/prompting.md +23 -0
- package/kit/skills/security-scan/references/reporting.md +75 -0
- package/kit/skills/security-scan/references/verify.md +131 -0
- package/kit/skills/sonarqube-check/SKILL.md +108 -0
- package/kit/skills/sonarqube-check/references/local-engines.md +32 -0
- package/kit/skills/sonarqube-check/references/stand-up-server.md +25 -0
- package/kit/skills/spec-planning/SKILL.md +92 -0
- package/kit/skills/systematic-debugging/SKILL.md +57 -0
- package/kit/skills/systematic-debugging/references/techniques.md +44 -0
- package/kit/skills/teamboard/SKILL.md +88 -0
- package/kit/skills/teamboard/references/setup.md +37 -0
- package/kit/skills/testing/SKILL.md +49 -0
- package/kit/skills/testing/references/flaky-triage.md +51 -0
- package/kit/skills/threat-model/SKILL.md +57 -0
- package/kit/skills/threat-model/references/interview.md +51 -0
- package/kit/skills/threat-model/references/schema.md +42 -0
- package/kit/skills/token-budget/SKILL.md +51 -0
- package/kit/skills/trace-scan/SKILL.md +43 -0
- package/kit/skills/worktree/SKILL.md +40 -0
- package/kit/studio/README.md +266 -0
- package/kit/studio/ensure-node.sh +471 -0
- package/kit/studio/package.json +14 -0
- package/kit/studio/server/hooks/studio-gate.sh +169 -0
- package/kit/studio/server/index.js +902 -0
- package/kit/studio/server/lib/crew-env.js +11 -0
- package/kit/studio/server/lib/fleet.js +146 -0
- package/kit/studio/server/lib/graph.js +533 -0
- package/kit/studio/server/lib/instance.js +135 -0
- package/kit/studio/server/lib/kit-telemetry.js +182 -0
- package/kit/studio/server/lib/kit.js +158 -0
- package/kit/studio/server/lib/palette.js +118 -0
- package/kit/studio/server/lib/peers.js +72 -0
- package/kit/studio/server/lib/permissions.js +150 -0
- package/kit/studio/server/lib/projects.js +294 -0
- package/kit/studio/server/lib/roster.js +191 -0
- package/kit/studio/server/lib/session.js +309 -0
- package/kit/studio/server/lib/terminal.js +91 -0
- package/kit/studio/server/lib/transcript.js +100 -0
- package/kit/studio/web/app.js +1098 -0
- package/kit/studio/web/canvas.js +1179 -0
- package/kit/studio/web/chat.js +543 -0
- package/kit/studio/web/index.html +86 -0
- package/kit/studio/web/md.js +110 -0
- package/kit/studio/web/storage-migrate.js +23 -0
- package/kit/studio/web/style.css +1453 -0
- package/package.json +46 -8
- package/start.sh +764 -0
- package/bin/crewforth.js +0 -10
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: crew-code-review
|
|
3
|
+
description: |
|
|
4
|
+
Code review discipline: review only what changed, rank each finding by severity and category, and
|
|
5
|
+
fact-check it first. crew-review-agent applies it.
|
|
6
|
+
Use when reviewing a change set, and when acting on a review someone else wrote.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Code Review
|
|
10
|
+
|
|
11
|
+
<!-- routing-eval reads the next line; why it sits in the body: AGENT_TEMPLATE.md -->
|
|
12
|
+
Trigger phrases: "code-review", "review the code", "review the PR", "review my changes", "do a review"
|
|
13
|
+
|
|
14
|
+
> **Crewforth adaptation (local, .claude/):** applied by `crew-review-agent` (read-only). §4 applies, and no
|
|
15
|
+
> vendor or template name reaches an artifact (§4.2).
|
|
16
|
+
|
|
17
|
+
A review runs in four steps — **group, plan, review, fact-check** — and reports few findings that are right rather
|
|
18
|
+
than many that might be. Every step below says what it produces.
|
|
19
|
+
|
|
20
|
+
## 1. Scope
|
|
21
|
+
- **Review the lines this change adds or edits.** Deleted code is context for understanding them, not a target.
|
|
22
|
+
- Code that is correct, or that the change did not touch, gets no comment.
|
|
23
|
+
- **An empty result is a result.** Do not invent findings to show the review happened.
|
|
24
|
+
- **Be sure before you write.** A finding you are not sure of is not a finding yet: read the surrounding code until
|
|
25
|
+
you are. A false alarm costs more than a small miss — it spends the attention the next real problem needs.
|
|
26
|
+
|
|
27
|
+
## 2. Group the files
|
|
28
|
+
Read together what has to be understood together: an interface and its implementations, the code that produces
|
|
29
|
+
something and the code that consumes it, the same resource in its language or environment variants. Look across
|
|
30
|
+
each group for a contract that broke between two files, or an update that reached one of them and not the other.
|
|
31
|
+
Then look at **every file in the group on its own** — a small or secondary file is where a missed update hides.
|
|
32
|
+
|
|
33
|
+
## 3. Plan before you comment
|
|
34
|
+
Before the first finding, write two things down:
|
|
35
|
+
- **What changed**, in one line.
|
|
36
|
+
- **The risks**, ordered by severity, each with what you will read to confirm or dismiss it ("the callers of
|
|
37
|
+
`settle()`", "the migration's down step"). No risk worth checking → write `(none)` and say so.
|
|
38
|
+
|
|
39
|
+
The plan is what keeps the review on the change instead of on whatever the eye lands on first.
|
|
40
|
+
|
|
41
|
+
## 4. Severity and category
|
|
42
|
+
Every finding carries one severity and one category.
|
|
43
|
+
|
|
44
|
+
| Severity | What it is | Blocks the commit? |
|
|
45
|
+
|---|---|---|
|
|
46
|
+
| `critical` | a security hole, lost or corrupted data, a crash | **yes** |
|
|
47
|
+
| `high` | a core function stops working, or works wrongly | **yes** |
|
|
48
|
+
| `medium` | performance, maintainability, an unhandled edge case | no |
|
|
49
|
+
| `low` | readability and style | no |
|
|
50
|
+
|
|
51
|
+
Category: `bug` · `security` · `performance` · `maintainability` · `test` · `style` · `docs`.
|
|
52
|
+
|
|
53
|
+
**A blocker is a `critical` or `high` finding** — nothing else stops the commit, and the review is clean when none
|
|
54
|
+
is left open.
|
|
55
|
+
|
|
56
|
+
## 5. Style, names and code comments
|
|
57
|
+
- Style and naming are `low`, never block, and fit in one sentence.
|
|
58
|
+
- **Code comments are out of scope unless asked for**, with one exception: a comment that says something **false**
|
|
59
|
+
about what the code does is a `low` / `docs` finding, because the next reader will believe it.
|
|
60
|
+
|
|
61
|
+
## 6. Finding format
|
|
62
|
+
`file:line · severity · category · what you observed · what to do instead`
|
|
63
|
+
|
|
64
|
+
What to do instead is the reason the finding exists; a finding without it is an opinion.
|
|
65
|
+
|
|
66
|
+
## 7. What a change must not quietly do
|
|
67
|
+
**Verifier integrity:** flag any change that makes a check pass by *weakening the check* — deleting or loosening
|
|
68
|
+
an assertion, lowering a threshold, skipping a test, editing the test instead of the code — rather than fixing
|
|
69
|
+
the behavior. A test or gate that grades itself lax is worse than none; a verifier must stay external and grounded.
|
|
70
|
+
|
|
71
|
+
**Subject integrity:** the inverse case — the check is untouched, but what it checked is gone. Flag a change that
|
|
72
|
+
deletes or stubs the code path, so the check passes over behavior that no longer runs; narrows the run to a
|
|
73
|
+
subset (fewer cases, one platform, a filtered input set) where the property happens to hold; turns an all-of
|
|
74
|
+
requirement into an any-of one; or relaxes the rule the code is there to enforce — a widened type, a dropped
|
|
75
|
+
uniqueness or referential constraint, an exception list holding exactly the failing case. Ask not "does it pass
|
|
76
|
+
now" but **"does the system still do what this check was protecting"**. Retiring a genuinely obsolete check is
|
|
77
|
+
legitimate: say so in the diff and name what covers it now.
|
|
78
|
+
|
|
79
|
+
## 8. Two-stage verdict (fact-check before you report)
|
|
80
|
+
Finding a problem and confirming it are two acts. A first-pass "this looks wrong" is a **candidate**, not a verdict.
|
|
81
|
+
Before a finding is reported — especially a blocker — run a second pass that tries to *disprove* it:
|
|
82
|
+
- Does it hold on the real code, or did the first read miss context (a guard upstream, a caller that never reaches
|
|
83
|
+
this path, a framework default)? Re-read the surrounding code; do not rank on the snippet alone.
|
|
84
|
+
- Is the severity honest, or is a `low` dressed up as a blocker?
|
|
85
|
+
- For any **"fixed" / "passes" claim**: the *real* check ran and passed — test exit code, build, lint/quality gate —
|
|
86
|
+
not "I re-read it and it looks fixed". A verifier that is the model's own say-so is not a verifier (§7, Verifier
|
|
87
|
+
integrity). Cite the evidence: which check, what result.
|
|
88
|
+
|
|
89
|
+
**The disprove pass is asymmetric.**
|
|
90
|
+
- **Only evidence removes a finding.** It is dropped when the code shows it is wrong. "I could not confirm it",
|
|
91
|
+
"it seems unlikely" or "it is not worth it" lower its severity; they do not delete it.
|
|
92
|
+
- **Some findings are never dropped in this pass:** memory safety; concurrency; a declaration that does not match
|
|
93
|
+
its definition; a change in behaviour or compatibility — a message, field, status or default that callers
|
|
94
|
+
used to get and now silently lose; a parameter that is accepted and then ignored. In these, the model's
|
|
95
|
+
confidence that all is well is the signal least worth trusting.
|
|
96
|
+
|
|
97
|
+
**"Independent" costs a separate context.** A second pass in the same context has already read the first one's
|
|
98
|
+
reasoning, so it cannot be blind to it — and its agreement is the first pass nodding at itself. For a **blocker**,
|
|
99
|
+
run the disprove pass as its own subagent, handed the claim and the `file:line` but not your argument. If you did
|
|
100
|
+
not isolate it, label the verdict as a single pass rather than calling it independent. The full contract —
|
|
101
|
+
isolation, one lens per verifier, and why unanimity for the same reason is a monoculture — lives in
|
|
102
|
+
`security-scan/references/verify.md`; it is one discipline, not two.
|
|
103
|
+
|
|
104
|
+
## 9. Check the history before you call a finding new
|
|
105
|
+
A confirmed finding may still not be new, and one that was fixed once and came back needs a different fix. Search
|
|
106
|
+
**by code, not by commit message** — a message states intent, not content. The exact git forms (`-S` vs `-G`, the
|
|
107
|
+
`merge-base` bound, why `--follow` does not combine): **`references/history-search.md`**.
|
|
108
|
+
|
|
109
|
+
If a commit removed the guard, check, or test this diff would restore, the finding is a **re-introduced regression** —
|
|
110
|
+
the question becomes "what removed the fix, and does that reason still hold", the removing commit is cited in the
|
|
111
|
+
finding, and the deleted test is restored rather than a new one written.
|
|
112
|
+
|
|
113
|
+
## Panel mode (high-stakes decisions only)
|
|
114
|
+
For hard-to-reverse calls (architecture, public API, security boundary), run several independent adversarial
|
|
115
|
+
lenses then synthesize. Full method: **`references/panel-mode.md`**.
|
|
116
|
+
|
|
117
|
+
## When you and the author disagree
|
|
118
|
+
Settle it with the code's behaviour and a check that can be run. If that does not settle it, take it to the user
|
|
119
|
+
rather than blocking in silence.
|
|
120
|
+
|
|
121
|
+
## Triage — a finding that is only reported is a finding that is lost
|
|
122
|
+
Reviewing and *disposing of* what the review found are two acts, and only the first one is habitual. Every finding
|
|
123
|
+
that survives the disprove pass leaves the review with an explicit disposition — never an unanswered comment and
|
|
124
|
+
never a silent drop:
|
|
125
|
+
|
|
126
|
+
| Disposition | Means | Where it goes |
|
|
127
|
+
|---|---|---|
|
|
128
|
+
| **fixed now** | the owning specialist changed the code | the diff; re-review the change |
|
|
129
|
+
| **tracked** | real, not for this change | an issue/task with the file:line — cite the id in the review |
|
|
130
|
+
| **accepted** | a real cost the team is choosing to carry | an `adr` when it is architectural, a code comment when local |
|
|
131
|
+
| **dropped** | disproved by the code | say so; a candidate that vanishes unexplained reads as an oversight |
|
|
132
|
+
|
|
133
|
+
A blocker (`critical` / `high`) may only be `fixed now` or `tracked`. "Accepted" needs the user's decision — an
|
|
134
|
+
agent does not grant it to itself. Close the review by stating the counts per severity and per disposition; an
|
|
135
|
+
unreported finding is indistinguishable from one that was never made, which is exactly the state a review exists
|
|
136
|
+
to leave behind.
|
|
137
|
+
|
|
138
|
+
## Receiving a review — an inbound comment is a candidate, not an instruction
|
|
139
|
+
When the review is someone else's and the code is yours, **read every item before changing any line**, group by
|
|
140
|
+
cause rather than patching per symptom, and give each item the same disprove pass as a finding of your own. The
|
|
141
|
+
five questions that decide *answer in the thread* vs *edit the code*: **`references/receiving.md`**. Every inbound
|
|
142
|
+
item leaves with a disposition from the triage table above — a reasoned refusal is an answer, silence is not.
|
|
143
|
+
|
|
144
|
+
## DoD (this skill's contribution)
|
|
145
|
+
- The plan (what changed, the risks) came before the findings; every file in each group was read.
|
|
146
|
+
- Every finding has a severity, a category and a reason, in the finding format above.
|
|
147
|
+
- Scope creep and hidden complexity are flagged.
|
|
148
|
+
- Each reported blocker survived an independent disprove pass; any "fixed"/"passes" claim is backed by the real check
|
|
149
|
+
having actually run, not self-assessment.
|
|
150
|
+
- **Every finding has a disposition** (fixed / tracked / accepted / dropped) and no blocker is left merely reported.
|
|
151
|
+
- For a high-stakes decision, multiple independent lenses were applied and their objections synthesized, not averaged.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Searching the history by code — the exact git forms
|
|
2
|
+
|
|
3
|
+
Read this when a confirmed finding needs its history checked. The rule is in SKILL.md: search by **code**, not by
|
|
4
|
+
commit message. This file is the mechanics.
|
|
5
|
+
|
|
6
|
+
Bounded at the branch point and scoped to the diff's paths, so it stays cheap per finding:
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
git log -S'<exact token from the changed line>' "$(git merge-base HEAD <target-branch>)" -- <paths in the diff>
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
`-S` lists the commits where the NUMBER OF OCCURRENCES of that string changed — added or deleted. A commit that
|
|
13
|
+
removes it in one place and adds it back in another leaves the count unchanged and does not appear, which is
|
|
14
|
+
exactly the "was the guard moved?" case: reach for `-G'<regex>'` there, which matches added or removed lines
|
|
15
|
+
against a regular expression regardless of count. `--follow` continues across renames but works on a single
|
|
16
|
+
path only, so it does not combine with the multi-path form above.
|
|
17
|
+
|
|
18
|
+
**`--grep` does not answer this.** A commit message states intent, not content: it misses fixes worded differently
|
|
19
|
+
and matches commits that changed nothing relevant. Use it only to read a commit you already found by content.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Panel mode — adversarial expert panel
|
|
2
|
+
|
|
3
|
+
For a **consequential, hard-to-reverse** decision (an architecture choice, a public API contract, a security
|
|
4
|
+
boundary) a single-lens review under-covers. Run an **adversarial expert panel**: evaluate the change from
|
|
5
|
+
**several independent lenses in parallel**, each arguing on its own terms, then synthesize.
|
|
6
|
+
- **Distinct lenses, not repetition:** e.g. *correctness/edge cases · security & privacy · maintainability &
|
|
7
|
+
altitude (YAGNI) · operational cost/perf*. Give each lens a real advocate whose job is to find where the
|
|
8
|
+
change fails on *that* axis — diversity catches failure modes redundancy can't.
|
|
9
|
+
- **Adversarial by default:** each lens tries to refute "this is the right change", not to bless it. A concern
|
|
10
|
+
raised by one lens isn't overruled by the others' approval — it's recorded and weighed.
|
|
11
|
+
- **Synthesize, don't average:** collect every lens's findings, keep the sharpest objection from each, and
|
|
12
|
+
reach one decision (proceed / proceed-with-changes / reject) with the reasoning. This is the distilled
|
|
13
|
+
judge-panel pattern — reserve it for high stakes; routine diffs get the single-lens review above (don't
|
|
14
|
+
burn a panel on a one-liner).
|
|
15
|
+
|
|
16
|
+
## The lenses (named, first-class)
|
|
17
|
+
|
|
18
|
+
Pick the lenses that fit the change — not all six every time. Each is a distinct advocate; assign one concern per
|
|
19
|
+
lens so they don't collapse into the same review twice.
|
|
20
|
+
|
|
21
|
+
| Lens | Asks | Fails the change when |
|
|
22
|
+
|---|---|---|
|
|
23
|
+
| **Correctness** | Does it do the right thing on every path? | An edge case, race, off-by-one, or error path is unhandled |
|
|
24
|
+
| **Security & privacy** | Can it be abused; does data leak? | Injection, missing authz, secret exposure, PII beyond purpose (→ `security-scan`, `privacy-compliance`) |
|
|
25
|
+
| **Simplicity & altitude** | Is it more than the problem needs? | Over-engineering, speculative generality, YAGNI, wrong abstraction level |
|
|
26
|
+
| **Contract & compatibility** | What breaks downstream? | A public API / schema / event shape changes without a migration or version (→ `api-design`) |
|
|
27
|
+
| **Operability** | What happens at 3am in prod? | No logs/metrics on the new path, silent failure, no rollback (→ `observability`, `incident-runbook`) |
|
|
28
|
+
| **Verifier integrity** | Is the *check* still honest? | A test/assertion/threshold was weakened to pass, instead of the behavior being fixed |
|
|
29
|
+
|
|
30
|
+
**Adversarial pairing:** the strongest panel pits lenses that pull against each other — Simplicity vs. Contract
|
|
31
|
+
(don't over-build, but don't break callers), Correctness vs. Operability (handle every case, but stay debuggable).
|
|
32
|
+
When two lenses conflict, that tension IS the decision to surface — resolve it explicitly, don't let one silently win.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Receiving a review — an inbound comment is a candidate, not an instruction
|
|
2
|
+
|
|
3
|
+
Read this on the skill's other mode: the review is someone else's and the code is yours — a teammate's comments, a
|
|
4
|
+
quality gate's report, a bot's PR review.
|
|
5
|
+
|
|
6
|
+
**Read every item before changing any line.** Comments are written one per symptom, and two of them
|
|
7
|
+
often share one cause; applying them in arrival order yields a patch per symptom instead of one fix at the cause.
|
|
8
|
+
Group by cause, then decide.
|
|
9
|
+
|
|
10
|
+
Each item then earns the same disprove pass as a finding of your own. Any "no" below is a reason to answer in the
|
|
11
|
+
thread, not to edit:
|
|
12
|
+
1. **Defect or preference?** Give each comment a severity and a category from SKILL.md — inbound prose arrives
|
|
13
|
+
unranked, you rank it, and only a `critical` or `high` blocks.
|
|
14
|
+
2. **Does it hold where the reviewer did not look?** Check the call sites and callers the comment never opened.
|
|
15
|
+
3. **Does it contradict a decision already recorded?** An `adr` or a documented constraint outranks the comment —
|
|
16
|
+
reopen the decision, do not quietly edit around it.
|
|
17
|
+
4. **Does the real check still pass with it applied?** Run it, don't re-read it. A suggestion that turns a check
|
|
18
|
+
red is reported back, and never satisfied by weakening the check (Verifier integrity, in SKILL.md).
|
|
19
|
+
5. **Is it against the current revision?** A comment on an older one may already be answered by a later commit.
|
|
20
|
+
|
|
21
|
+
Every inbound item leaves with a disposition from SKILL.md's triage table; none is left merely read. **A reasoned
|
|
22
|
+
refusal is an answer** — say why in the thread and let the reviewer press it or drop it. Not doing it quietly is not
|
|
23
|
+
an answer: it reads as agreement, and the same comment returns on the next review.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: crew-doctor
|
|
3
|
+
description: Health-check the install — hooks executable, core.hooksPath set, gates wired, discipline loaded.
|
|
4
|
+
metadata:
|
|
5
|
+
kind: command
|
|
6
|
+
---
|
|
7
|
+
# /crew-doctor
|
|
8
|
+
Verify Crewforth is actually *active* in this project (not just present on disk):
|
|
9
|
+
1. Run `bash .claude/eval/doctor.sh`.
|
|
10
|
+
2. Read its report. It checks: VERSION present · every hook executable · the required git hooks (pre-commit,
|
|
11
|
+
commit-msg) present · **guard-bash actually blocks a force-push** (catches a hook that is present but neutered) ·
|
|
12
|
+
`core.hooksPath` points at `.claude/hooks` (else the §4.1/§4.2 commit trace + secret/bloat scan never runs) ·
|
|
13
|
+
`settings.json` valid and wiring the PreToolUse / UserPromptSubmit / Stop gates to **non-empty** hook arrays
|
|
14
|
+
(an empty `[]` wires nothing); SessionStart (rehydration) is reported as a warning if absent · **`./CLAUDE.md`
|
|
15
|
+
actually imports `.claude/DISCIPLINE.md`** — without that line the discipline sits on disk and never loads, which
|
|
16
|
+
every other check is blind to.
|
|
17
|
+
3. For each ❌, apply the printed fix. Anything that changes git config or file permissions needs approval first —
|
|
18
|
+
show the exact command and wait.
|
|
19
|
+
4. Read the **Readiness** block too. It is advisory (never changes the verdict) and asks a different question — is
|
|
20
|
+
this *project* set up to be worked on by agents: CLAUDE.md project section filled in · a project-specific skill
|
|
21
|
+
alongside Crewforth's generic ones · a devcontainer to sandbox agent commands · an MCP server · CLAUDE.md not
|
|
22
|
+
drifted behind the code. Report the gaps as suggestions, not as failures, and never "fix" them unasked — adding
|
|
23
|
+
a devcontainer or an MCP server is the user's call.
|
|
24
|
+
5. Summarise: **healthy**, or the precise fixes applied/needed, plus the readiness score. If it's not a git repo,
|
|
25
|
+
note that the commit-time gates need `git init` + `git config core.hooksPath .claude/hooks`.
|
|
26
|
+
If the output contains a line starting with ⭐, pass it to the user verbatim as the LAST line of your summary —
|
|
27
|
+
it prints once per Crewforth version, and it is meant for the user, not for you.
|
|
28
|
+
|
|
29
|
+
If `.claude/eval/doctor.sh` doesn't exist, this is not a full (start.sh / adopt.sh) install — Crewforth is likely
|
|
30
|
+
running as a **plugin**, whose hooks are managed by Claude Code itself; there's nothing for the doctor to check,
|
|
31
|
+
with one exception: the skill listing, which a plugin cannot size for itself (its settings cannot set
|
|
32
|
+
`skillListingBudgetFraction`). Count it the way the full install's doctor does:
|
|
33
|
+
`LC_ALL=C awk -f "${CLAUDE_PLUGIN_ROOT}/eval/lib/skill-listing.awk" "${CLAUDE_PLUGIN_ROOT}"/skills/*/SKILL.md`
|
|
34
|
+
(prints characters, then skills). At the default fraction a 200,000-token model has 8,000 characters for the whole
|
|
35
|
+
listing, and Claude Code's own skills take about 5,900 of them (measured on v2.1.282). If Crewforth's number plus
|
|
36
|
+
5,900 is over 8,000, tell the user plainly: on such a model the least-used skills lose their descriptions and stop
|
|
37
|
+
being picked; one line in `~/.claude/settings.json` fixes it — `"skillListingBudgetFraction": 0.04`; the cost is
|
|
38
|
+
that the listing is then sent whole every turn, about (that total ÷ 4) tokens, (tokens ÷ 2,000)% of a 200k window.
|
|
39
|
+
It is their call — show the line and the cost, do not edit their settings. On a 1,000,000-token model the default
|
|
40
|
+
already fits.
|
|
41
|
+
|
|
42
|
+
**The eval scripts are installer-only, by decision.** `eval/` — `doctor.sh`, `smoke-test.sh`, `routing-eval.sh`,
|
|
43
|
+
`scan-skill.sh`, `utilization.sh` — ships with `start.sh` and `adopt.sh` and NOT with the plugin edition. The eval
|
|
44
|
+
scripts are developer instruments: they inspect an installation from outside it, and the plugin edition has no
|
|
45
|
+
installation to inspect. Say this plainly when someone asks why `/crew-doctor` reports only the listing on a plugin install,
|
|
46
|
+
rather than treating it as a defect. The Studio panel ships in both editions (`/crew-studio`).
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: crew-gates
|
|
3
|
+
description: Gate report — what the tool-level gates actually did, and which rules nothing has tripped.
|
|
4
|
+
argument-hint: "[--log <path>]"
|
|
5
|
+
disable-model-invocation: true
|
|
6
|
+
metadata:
|
|
7
|
+
kind: command
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
Run the report and read it back to the user:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
bash .claude/eval/gate-report.sh $ARGUMENTS
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Then interpret it in two sentences, in the user's language:
|
|
17
|
+
|
|
18
|
+
- **Exit 3 (no log).** Say plainly that gate activity is *not measured* — not that the gates never fired. Offer
|
|
19
|
+
the one-line opt-in the report prints. Do not present the rule count as if it were evidence of anything.
|
|
20
|
+
- **Exit 0.** Lead with the verdict split (how often the gates asked vs blocked). Then the notable rules: a rule
|
|
21
|
+
firing repeatedly is worth a conversation ("something keeps reaching for this"), and the not-observed list is
|
|
22
|
+
a prompt to check whether a rule *can* still match, not a delete list. `smoke-test` is what proves a rule can
|
|
23
|
+
fire; this only shows what tripped it.
|
|
24
|
+
|
|
25
|
+
Never infer that a gate works because it appears in the report, or that it is broken because it does not.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: crew-handoff
|
|
3
|
+
description: Session handover — SESSION_STATE.md + /clear suggestion.
|
|
4
|
+
metadata:
|
|
5
|
+
kind: command
|
|
6
|
+
---
|
|
7
|
+
# /crew-handoff
|
|
8
|
+
applies the `handoff` skill:
|
|
9
|
+
1. Read the measured fill: the `🔋 Session` line, or `bash .claude/hooks/context-usage.sh --verbose`.
|
|
10
|
+
2. Write an actionable handover to `docs/SESSION_STATE.md`: Done · In progress (exactly where) · Next step · Open decisions · File pointers · Blockers.
|
|
11
|
+
3. Preserve decision rationale; the next session should not start from scratch.
|
|
12
|
+
4. **Cold-reader pass** (`handoff/references/cold-reader.md`): the questions are written from the work BEFORE the
|
|
13
|
+
file, then answered from the file alone. Anything unanswerable goes back into the handover and is re-checked.
|
|
14
|
+
5. Once written — and only once every question is answerable — suggest `/clear`.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: crew-plan
|
|
3
|
+
description: Spec-first planning — break down ambiguously scoped work with crew-planner.
|
|
4
|
+
argument-hint: "[task/feature description]"
|
|
5
|
+
metadata:
|
|
6
|
+
kind: command
|
|
7
|
+
---
|
|
8
|
+
# /crew-plan
|
|
9
|
+
Argument: $ARGUMENTS
|
|
10
|
+
|
|
11
|
+
Delegate to the @agent-crew-planner agent (spec-planning skill). For ambiguously scoped work:
|
|
12
|
+
1. Clarify the goal + what's out of scope.
|
|
13
|
+
2. Split into vertical slices; give each task a measurable acceptance criterion.
|
|
14
|
+
3. Order by dependency + put the riskiest first.
|
|
15
|
+
4. Ask about ambiguities with **explicit options**; write down the assumptions.
|
|
16
|
+
|
|
17
|
+
Write the output to `docs/PLAN.md`, return a summary + pointer to the main thread (token-budget).
|
|
18
|
+
Do NOT write code — this is a planning step.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: crew-review
|
|
3
|
+
description: Review pass — review + security + quality gates.
|
|
4
|
+
metadata:
|
|
5
|
+
kind: command
|
|
6
|
+
---
|
|
7
|
+
# /crew-review
|
|
8
|
+
Run the change set through the review trio (read-only). **The audits go out in parallel; the reviewer closes.**
|
|
9
|
+
1. **At once, in ONE message** — several `Agent` calls, because none of these writes code and so there is
|
|
10
|
+
nothing to serialise:
|
|
11
|
+
- @agent-crew-security-expert (security-scan) — auth/IDOR/injection/secret; findings with severity.
|
|
12
|
+
- @agent-crew-performance-expert (`performance`) — hot path, query/loop, render, payload. Reports
|
|
13
|
+
**candidates** (reasoned) and **findings** (measured) separately; an unmeasured claim is never a verdict.
|
|
14
|
+
- @agent-crew-privacy-agent (`privacy-compliance`) — **when the diff touches personal data**: legal basis,
|
|
15
|
+
minimisation, retention, transfer.
|
|
16
|
+
2. (if SonarQube is in use) **sonarqube-check** — 0/0/0/0 gate (language-agnostic).
|
|
17
|
+
3. **Last, once 1-2 leave no blocker:** @agent-crew-review-agent (crew-code-review) — "does it improve overall
|
|
18
|
+
code health": the plan (what changed, the risks), then findings with a severity and a category. "Clean" means
|
|
19
|
+
what crew-code-review means by it: **no critical or high finding open**. A medium or low audit finding does not
|
|
20
|
+
hold the reviewer back; hand it over in the reviewer's prompt and keep it in the report. A critical or high one
|
|
21
|
+
stops here: report it, leave the fix to its owner, and run the reviewer on the fixed diff. It is the closing
|
|
22
|
+
reviewer in every writing agent's Coordination ("at closure, report findings to crew-review-agent"), so it
|
|
23
|
+
reads a diff the audits have already cleared of blockers — not the other way round.
|
|
24
|
+
|
|
25
|
+
Each agent returns a **short summary** to the main thread; raw output goes to `docs/` if needed. Do NOT modify code;
|
|
26
|
+
collect findings in severity order, and leave the fix to the relevant expert.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: crew-ship
|
|
3
|
+
description: DoD gate + commit proposal (waits for approval).
|
|
4
|
+
metadata:
|
|
5
|
+
kind: command
|
|
6
|
+
---
|
|
7
|
+
# /crew-ship
|
|
8
|
+
Closure flow — in order:
|
|
9
|
+
1. **DoD gate:** was `/simplify` applied · are tests green (@agent-crew-test-expert) · (if SonarQube is used) `sonarqube-check` 0/0/0/0.
|
|
10
|
+
If any one is red, **STOP**, report what is missing; no deferral.
|
|
11
|
+
2. If clean, @agent-crew-commit-agent (commit-message) **proposes** an atomic Conventional Commit from the staged diff.
|
|
12
|
+
3. Commit runs ONLY if the user says "commit" (§4.4). "Done" is not approval.
|
|
13
|
+
4. **Close the board item too** (`teamboard`), when one is held. Closing work is one movement: ask what shipped,
|
|
14
|
+
run `board.sh done <id> "<note>"`, name the items it unblocked, and offer the next one as options. Do not
|
|
15
|
+
leave this to the user to remember — a claim nobody closes reads to the whole team as still in progress, and
|
|
16
|
+
the items behind it stay unclaimable. If a decision came out of this work that changes how other items must
|
|
17
|
+
be done, record it with `board.sh decide` in the same breath; it is worthless in a session nobody else reads.
|
|
18
|
+
|
|
19
|
+
No destructive operations (§4.5). No AI trace / vendor name in the message (§4.1/§4.2 — the hook already scans).
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: crew-skill
|
|
3
|
+
description: Author or change a Crewforth component (skill / agent / command) against the template and its gates.
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
metadata:
|
|
6
|
+
kind: command
|
|
7
|
+
---
|
|
8
|
+
# /crew-skill
|
|
9
|
+
|
|
10
|
+
`AGENT_TEMPLATE.md` states the contract for a component. Full installs carry it (refreshed on `update`); the
|
|
11
|
+
plugin edition does not. No gate routes to it, so this command is the route, and it ends in the gates.
|
|
12
|
+
|
|
13
|
+
**A component is not finished when it is written. It is finished when the suite says so.**
|
|
14
|
+
|
|
15
|
+
## 1. Decide the shape before writing anything
|
|
16
|
+
Read `.claude/AGENT_TEMPLATE.md`. Then answer, in one line each:
|
|
17
|
+
|
|
18
|
+
- **What is the smallest form that works?** A rule in an existing skill's body beats a new skill; a new skill beats
|
|
19
|
+
a new agent. Every new skill costs its NAME in every session, forever, for every user — and its description too,
|
|
20
|
+
until the listing overflows its budget, at which point descriptions start being dropped from the skills you
|
|
21
|
+
invoke least. Say what that buys.
|
|
22
|
+
- **Who reaches it?** An agent, a command, or the discipline's trigger map. If the answer is "the model will notice
|
|
23
|
+
the description", stop — that is the dark component §3b exists to catch.
|
|
24
|
+
- **Read or write?** A component that reports and a component that changes files do not belong together: different
|
|
25
|
+
risk, different done-criterion. Split them.
|
|
26
|
+
- **Is it stack-neutral?** Anything shipped to every profile names no language, framework or vendor as *the* case.
|
|
27
|
+
The example you have in mind is not the scope.
|
|
28
|
+
|
|
29
|
+
## 2. Write it
|
|
30
|
+
- Skill: `.claude/skills/<name>/SKILL.md` — the directory name and the `name:` field must match. Keep the body
|
|
31
|
+
lean; depth goes to `references/*.md` and is loaded on demand.
|
|
32
|
+
- Agent: a thin trigger — *who and when*. The *how* lives in the skill it applies; do not copy the method in.
|
|
33
|
+
- The `description` says **when to reach for this**, not what its author knows.
|
|
34
|
+
|
|
35
|
+
## 3. Register it — the cascade, in this order
|
|
36
|
+
Skipping one of these is how a component ships half-installed:
|
|
37
|
+
1. **Route it.** Name it in an agent body, a command, or the trigger map. §3b checks exactly this.
|
|
38
|
+
2. **Golden case.** Add a positive line to `.claude/eval/golden-routing.txt` — and a **negative** one
|
|
39
|
+
(`prompt|!target`) for a neighbour it must NOT steal.
|
|
40
|
+
3. **Catalog + counts** *(Crewforth repository only — `packaging/` is not installed anywhere)*.
|
|
41
|
+
Add the Turkish summary line (`packaging/skill-summaries.tr.tsv`; agents and commands have their own `.tr.tsv`),
|
|
42
|
+
which the site build requires (`cd site && npm ci && npm run build`), and the diagrams if the component set changed:
|
|
43
|
+
`node packaging/gen-diagrams.mjs` writes `assets/`, and smoke fails while any of them is stale.
|
|
44
|
+
4. **Plugin edition** *(Crewforth repository only)*. `bash packaging/build-plugin.sh` — in the same commit, or the
|
|
45
|
+
release stops at the sync gate.
|
|
46
|
+
5. **Budget.** A new skill moves `BUDGET_SKILL_LISTING` (the skill listing in characters, counted like Claude Code
|
|
47
|
+
counts it; `/crew-doctor` reports the same number). Raise it in the same commit with the justification comment the
|
|
48
|
+
file's convention requires. Never raise it to make a red gate green without saying why.
|
|
49
|
+
|
|
50
|
+
## 4. Prove it — run all four, in this order
|
|
51
|
+
```
|
|
52
|
+
bash .claude/eval/scan-skill.sh .claude/skills/<name> # supply-chain: SAFE, and rc=3 means NOT scanned
|
|
53
|
+
bash .claude/eval/routing-eval.sh # the golden case, positive and negative
|
|
54
|
+
bash .claude/eval/smoke-test.sh # structure, budget, §3b routed, cross-links
|
|
55
|
+
CREW_NO_STAR=1 bash .claude/eval/doctor.sh # the live install still healthy (star line off here)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
In the plugin edition none of the four commands above exist — it ships no `eval/` at all — so there the proof is
|
|
59
|
+
the Crewforth repository's own suite, not a local run.
|
|
60
|
+
|
|
61
|
+
**Do not finish while §3b is red.** "It works when I invoke it by name" is not the claim being tested — the claim
|
|
62
|
+
is that something reaches it without being told to. If the suite skips a case, that is not a pass: chase why.
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: crew-studio
|
|
3
|
+
description: Open Crewforth Studio — the visual panel for what agents are doing, what they spent, and which gates fired.
|
|
4
|
+
argument-hint: "[--port <n>]"
|
|
5
|
+
disable-model-invocation: true
|
|
6
|
+
metadata:
|
|
7
|
+
kind: command
|
|
8
|
+
---
|
|
9
|
+
# /crew-studio
|
|
10
|
+
|
|
11
|
+
Start the panel and hand the user its URL. Never leave a half-started server behind: if any step below
|
|
12
|
+
fails, say which one and stop — do not improvise a different launch.
|
|
13
|
+
|
|
14
|
+
1. **Resolve the panel.** Both editions carry it, in different places, and this one file serves both.
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
PLUGIN_PANEL=${CLAUDE_PLUGIN_ROOT}/studio/server/index.js
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Claude Code replaces `${CLAUDE_PLUGIN_ROOT}` in this text **before you read it**, and only when this
|
|
21
|
+
command came from the plugin. So read the line above literally:
|
|
22
|
+
|
|
23
|
+
- It names a real absolute path → **plugin edition**. That is the panel. Use it.
|
|
24
|
+
- It still contains the characters `${CLAUDE_PLUGIN_ROOT}` → this is a **full install**. The panel is
|
|
25
|
+
`.claude/studio/server/index.js`.
|
|
26
|
+
|
|
27
|
+
The variable is not in the shell's environment — it is text substituted into this file — so never try
|
|
28
|
+
to read it with `printenv` or let a shell expand it. Never write the unbraced `$CLAUDE_PLUGIN_ROOT`
|
|
29
|
+
either; only the braced form is substituted, and the unbraced one reaches bash unset and collapses the
|
|
30
|
+
path to `/studio/server/index.js`.
|
|
31
|
+
|
|
32
|
+
Neither path is there? Then this is an install older than the release that added the panel:
|
|
33
|
+
`npx crewforth@latest update --here --yes` at the project root, or `/crew-update`.
|
|
34
|
+
Then stop. Do not go hunting for the panel anywhere else on disk.
|
|
35
|
+
|
|
36
|
+
**What the plugin edition cannot show.** A plugin install puts no `.claude/VERSION`, `kit.conf` or Crewforth
|
|
37
|
+
scripts into a project. So that project's row in the list has no version badge (each row reads its own
|
|
38
|
+
project), and for the project you opened the panel from, the inspector's gates, stats and board tabs
|
|
39
|
+
say "Not measured" with the reason, rather than zero. The gates tab can still list observed entries
|
|
40
|
+
below that. The plugin's Bash guard logs its blocks, approval prompts and `CLAUDE_GIT_OK` pre-authorised
|
|
41
|
+
git actions, and its gate-file write guard logs its blocks, to `.claude/gate-log.tsv` when the project
|
|
42
|
+
has a `.claude/` directory and the file is git-ignored or the project is not a repo. With `CREW_GATE_LOG`
|
|
43
|
+
set they write wherever it points instead, and the panel reads only the project's own
|
|
44
|
+
`.claude/gate-log.tsv`, so a log sent anywhere else does not show. The commit scan and the board gate
|
|
45
|
+
refuse without writing a line. Say this once when you hand over the URL, so an honest blank is not
|
|
46
|
+
read as a broken panel. Everything else — the live agent graph, owned sessions, the permission bridge —
|
|
47
|
+
works the same in both editions.
|
|
48
|
+
|
|
49
|
+
2. **Resolve a runtime — do not ask whether a name resolves.** `ensure-node.sh` sits one level ABOVE the panel
|
|
50
|
+
— beside the `server/` directory, not inside it. Both spellings, in full, so there is nothing to guess:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
bash .claude/studio/ensure-node.sh --explain # full install
|
|
54
|
+
bash ${CLAUDE_PLUGIN_ROOT}/studio/ensure-node.sh --explain # plugin edition (step 1 decided which)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
It prints the absolute path of a Node 18+ that actually runs, and exits 1 when there is none. Use that path;
|
|
58
|
+
do not assume it is `node`. It looks in places PATH does not reach — a version manager puts node on
|
|
59
|
+
PATH from a login shell only, so "nvm is installed" and "this shell can see node" are different
|
|
60
|
+
facts. And it runs what it finds rather than trusting the name: the Windows Store ships a stub that
|
|
61
|
+
satisfies `command -v`, prints nothing and exits 49.
|
|
62
|
+
|
|
63
|
+
**No `ensure-node.sh` beside the panel?** Then the panel predates the fetcher. Fall back to running
|
|
64
|
+
`node --version` and reading the output — 18+ required — and tell the user `/crew-update` brings the
|
|
65
|
+
fetcher along with everything else.
|
|
66
|
+
|
|
67
|
+
3. **No runtime? Crewforth gets one — after the user says so.** Show them what it would do, then ask:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
bash <the same path as step 2> --plan # url, size, checksum source, target directory
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
It fetches the current Node LTS from nodejs.org into `~/.claude/studio-runtime`, verifies it against
|
|
74
|
+
the published SHA-256 and refuses to install on a mismatch. Nothing else on the machine is touched:
|
|
75
|
+
no admin rights, no package manager, no PATH or profile edit. Deleting that one directory undoes it.
|
|
76
|
+
|
|
77
|
+
Ask with `AskUserQuestion`, and offer the alternative honestly — some people would rather their own
|
|
78
|
+
package manager owned it (`winget install OpenJS.NodeJS.LTS`, `brew install node`, or their distro's).
|
|
79
|
+
On yes:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
bash <the same path as step 2> --install # prints the node path on success
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Never run `--install --yes` on the user's behalf without that answer, and never install anything
|
|
86
|
+
system-wide.
|
|
87
|
+
|
|
88
|
+
4. **Start it in the background**, from the project root, with the node from step 2 or 3:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
"$NODE" <panel> --open
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
It prints a tokenised URL (`http://127.0.0.1:7777/?token=…`) and keeps running. **Report that URL**
|
|
95
|
+
whether or not a browser opened — over SSH or headless nothing can open, and a running server with no
|
|
96
|
+
way in is the worst outcome here. Tell the user it runs until they stop it, and how (Ctrl-C in that
|
|
97
|
+
shell, or kill the process). Do not hold it in a foreground tool call.
|
|
98
|
+
|
|
99
|
+
5. **Port already in use.** Start it anyway and read what it says — the panel checks whether the holder is
|
|
100
|
+
another crewforth-studio first, and there is nothing for you to decide before it does. Two answers:
|
|
101
|
+
|
|
102
|
+
- `already running on port <n> (pid …) — reusing it`, followed by a tokenised URL and exit 0. That is a
|
|
103
|
+
panel someone else started, usually another session in this project. **Report that URL**; it is the same
|
|
104
|
+
panel, and the token in it is the running instance's own. Tell the user it belongs to whoever started it,
|
|
105
|
+
so closing this shell does not stop it.
|
|
106
|
+
- `held by something that is not a crewforth-studio panel` and exit 1. Then retry once with `--port <n+1>` and
|
|
107
|
+
report the new URL. If that port is taken too, stop and say both are taken rather than walking up the
|
|
108
|
+
range — something is listening that the user should look at.
|
|
109
|
+
|
|
110
|
+
The record that makes the first answer possible lives in `~/.claude/studio-runtime/instance-<port>.json`,
|
|
111
|
+
0600, and holds the token. A panel that was killed leaves one behind; the next start probes it, gets no
|
|
112
|
+
answer, and deletes it — so a stale file reports as the second answer, never as a URL that does not open.
|
|
113
|
+
|
|
114
|
+
**Quoting the panel's output.** It prints two things that belong to this machine and nowhere else: the machine
|
|
115
|
+
NAME, and a URL carrying a freshly generated token. Handing both to the user is the whole point — they are
|
|
116
|
+
sitting at that machine. Putting either into anything that leaves it is not: a commit message, a PR, a
|
|
117
|
+
CHANGELOG, an issue, a report to another session. The name is a §4.3 private term, and the token is a
|
|
118
|
+
credential, loopback-scoped but still live for as long as that panel runs. So when you quote panel output
|
|
119
|
+
anywhere but to the user, drop the machine line and replace the token with `…`. `.private-terms.txt` catches
|
|
120
|
+
the name only if someone thought to add it; nothing catches the token.
|
|
121
|
+
|
|
122
|
+
**What the panel's scope actually is.** It reads `~/.claude/projects` — every Claude Code session on this
|
|
123
|
+
machine, not this project's. Starting it from a project root only decides which project it opens on. Say
|
|
124
|
+
that when you hand over the URL, so nobody reports "it shows other projects" as a bug.
|
|
125
|
+
|
|
126
|
+
Offline diagnostic, no browser and no tokens: `"$NODE" <panel> --selftest`.
|
|
127
|
+
|
|
128
|
+
**In the plugin edition this command is namespaced** — `/crewforth:crew-studio`, not
|
|
129
|
+
`/crew-studio`. Measured: the bare name does not resolve for a plugin command.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: crew-update
|
|
3
|
+
description: Check for a newer version, update, report what changed, then prompt /clear to reload.
|
|
4
|
+
metadata:
|
|
5
|
+
kind: command
|
|
6
|
+
---
|
|
7
|
+
# /crew-update
|
|
8
|
+
Bring the Crewforth install up to the latest published version:
|
|
9
|
+
1. **Detect install type.** If `.claude/VERSION` exists → a full install (steps below). If Crewforth runs as a
|
|
10
|
+
**plugin** (no `.claude/VERSION`), it updates through the plugin system: run
|
|
11
|
+
`claude plugin update crewforth@crewforth`, tell the user it applies when they restart Claude Code, and stop here.
|
|
12
|
+
2. **Current version:** read `.claude/VERSION`.
|
|
13
|
+
3. **Latest version:** `npm view crewforth version` (needs network). If it can't be reached,
|
|
14
|
+
say so and stop — don't guess.
|
|
15
|
+
4. **Compare.** Already on the latest → report "up to date (vX)" and stop. Otherwise show **old → new**.
|
|
16
|
+
5. **Before:** run `bash .claude/eval/update-guard.sh pre`. It records what is on disk (in `.claude/.state/`, nothing
|
|
17
|
+
else) and prints one of three verdicts:
|
|
18
|
+
- `clean` → nothing to report, go on.
|
|
19
|
+
- `UNCOMMITTED:` with the changed paths in `.claude/` and `CLAUDE.md` → show the user that list and **ask** —
|
|
20
|
+
with your question tool — whether to go ahead (the update rewrites Crewforth-owned files under `.claude/`), commit
|
|
21
|
+
or stash first, or stop. Continue only on their yes.
|
|
22
|
+
- `NOT IN GIT:` (a private install gitignores `.claude/` and `CLAUDE.md`, so edits there cannot be detected) →
|
|
23
|
+
pass its two lines to the user and go on; there is nothing to commit.
|
|
24
|
+
6. **Update** — this rewrites Crewforth-owned files under `.claude/` (your `./CLAUDE.md` and project skills are
|
|
25
|
+
preserved). **Show this plan first, then run:** `npx --yes crewforth@latest update --here --yes`.
|
|
26
|
+
Two DIFFERENT `--yes` flags, both required for a non-interactive run: the one **before** the package name is
|
|
27
|
+
**npx's own** — it auto-confirms npx's `Ok to proceed?` install prompt, which reads the real TTY and IGNORES piped
|
|
28
|
+
input, so without it the command hangs before Crewforth even starts. The `--here --yes` **after** the package go to
|
|
29
|
+
the updater (`--here` = apply on the current branch, `--yes` = accept the smart defaults). Together they let it run
|
|
30
|
+
to completion instead of blocking on a prompt your shell can't answer.
|
|
31
|
+
If you'd rather review each handover decision yourself, tell the user to run `npx crewforth@latest update`
|
|
32
|
+
(no flags) in **their own terminal**, where both the npx and the interactive prompts work.
|
|
33
|
+
7. **After:** run `bash .claude/eval/update-guard.sh post` and show the user its lists — added, changed, moved,
|
|
34
|
+
removed.
|
|
35
|
+
8. **Verify:** run `/crew-doctor` (or `bash .claude/eval/doctor.sh`) so a bad/partial update surfaces immediately.
|
|
36
|
+
If the updater's or doctor's output contains a line starting with ⭐, pass it to the user verbatim as the LAST
|
|
37
|
+
line of your summary — it prints once per Crewforth version, and it is meant for the user, not for you.
|
|
38
|
+
9. **Report** old → new + the headline changes. Take them from `.claude/.state/whats-new.md` — the updater writes
|
|
39
|
+
there the installed package's own CHANGELOG sections between the old and the new version. Do not fetch release
|
|
40
|
+
notes from the network. No file → say no release notes were included.
|
|
41
|
+
10. **Reload (manual — a command can't do it itself):** the discipline in the running session is still the OLD one.
|
|
42
|
+
Tell the user to run **`/clear`** (or quit and relaunch Claude Code): a new session loads the updated
|
|
43
|
+
`.claude/DISCIPLINE.md`.
|