crewforth 0.0.1 → 3.0.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +3784 -0
- package/LICENSE +21 -0
- package/README.md +37 -7
- package/VERSION +1 -0
- package/adopt.sh +1670 -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 +465 -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/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 +6693 -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 +1431 -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 +150 -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 +36 -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 +23 -0
- package/kit/skills/crew-ship/SKILL.md +19 -0
- package/kit/skills/crew-skill/SKILL.md +61 -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 +748 -0
- package/bin/crewforth.js +0 -10
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: trace-scan
|
|
3
|
+
description: |
|
|
4
|
+
Trace scan (§4.1/§4.2): before a commit, scans the staged changes and the message for AI traces (co-author
|
|
5
|
+
trailers, footers, robot emoji, tool names) and vendor template names. The git hooks apply it automatically.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Trace Scan (trace-scan)
|
|
9
|
+
|
|
10
|
+
<!-- routing-eval reads the next line; why it sits in the body: AGENT_TEMPLATE.md -->
|
|
11
|
+
Trigger phrases: "scan traces", "trace scan", "AI trace", "check vendor name", "pre-commit audit"
|
|
12
|
+
|
|
13
|
+
Purpose: to bind §4.1/§4.2 to a *gate* rather than to *memory*. If the rule lives only in text,
|
|
14
|
+
a trace leaks sooner or later; this skill + the hooks stop the leak at commit time.
|
|
15
|
+
|
|
16
|
+
## When
|
|
17
|
+
- Before every commit (automatic: `pre-commit` + `commit-msg` hooks).
|
|
18
|
+
- Before crew-commit-agent proposes a message (manual verification).
|
|
19
|
+
|
|
20
|
+
## How
|
|
21
|
+
Pattern list: `./.claude/hooks/trace-blocklist.txt` (grep -iE, one pattern per line).
|
|
22
|
+
- **Defaults are high-hit:** co-author trailers, auto-generation footers, robot emoji, and AI-assistant/tool
|
|
23
|
+
brand names. Standalone words that occur too often (model/assistant) are DELIBERATELY excluded. See trace-blocklist.txt for the exact list.
|
|
24
|
+
- **Vendor name is project-specific:** ADD the name of the third-party template in use to the list (§4.2).
|
|
25
|
+
|
|
26
|
+
Manual scan (a quick look without the hook):
|
|
27
|
+
```bash
|
|
28
|
+
git diff --cached --unified=0 | grep -E '^\+' | grep -Ev '^\+\+\+' \
|
|
29
|
+
| grep -iEf .claude/hooks/trace-blocklist.txt
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Hook setup
|
|
33
|
+
`start.sh` sets `git config core.hooksPath .claude/hooks` (if there is a git repo). The hooks live
|
|
34
|
+
under `.claude` → they are in gitignore and stay local (§4.3). To do it later for a repo:
|
|
35
|
+
```bash
|
|
36
|
+
git config core.hooksPath .claude/hooks
|
|
37
|
+
chmod +x .claude/hooks/pre-commit .claude/hooks/commit-msg
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Rules
|
|
41
|
+
- If there is a finding, the commit STOPS; the phrase is removed and the real rationale is written in the project's commit language (CLAUDE.md).
|
|
42
|
+
- Skipping with `--no-verify` only on an EXPLICIT request (§4.5); the hook is not skipped silently.
|
|
43
|
+
- On a false positive, narrow/remove the pattern — the list is set up by the project owner.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: worktree
|
|
3
|
+
description: |
|
|
4
|
+
Isolate risky or parallel file-mutating work in a git worktree so the main tree's uncommitted changes are never
|
|
5
|
+
clobbered. For fan-out agents that edit files, throwaway experiments, or any change you may want to discard cleanly.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Worktree Isolation
|
|
9
|
+
|
|
10
|
+
<!-- routing-eval reads the next line; why it sits in the body: AGENT_TEMPLATE.md -->
|
|
11
|
+
Trigger phrases: "worktree", "git worktree", "isolate the changes", "sandbox this work", "parallel file edits"
|
|
12
|
+
|
|
13
|
+
One rule: **never let risky or parallel work run on top of uncommitted changes in the shared tree.** A git worktree
|
|
14
|
+
gives a second working copy of the same repo on its own branch — you experiment or fan out agents there, and the main
|
|
15
|
+
tree (with your in-progress edits) is physically untouched. Throw the worktree away and nothing you cared about is lost.
|
|
16
|
+
|
|
17
|
+
> **Crewforth adaptation (local, .claude/):** this exists because verification/fan-out subagents have discarded a session's
|
|
18
|
+
> **uncommitted** work by running a destructive git command over the shared tree. Those commands (`reset --hard`,
|
|
19
|
+
> `clean -f`, `checkout -- .`, `restore`) are §4.5-gated — but the real fix is to not put them near unsaved work.
|
|
20
|
+
> The Agent tool's `isolation: "worktree"` does this automatically for parallel mutating agents; reach for it there.
|
|
21
|
+
|
|
22
|
+
## When to isolate
|
|
23
|
+
- **Fan-out that writes files** — two+ agents editing the same repo in parallel would collide; give each its own worktree.
|
|
24
|
+
- **A throwaway experiment** — you might keep it or bin it; a worktree makes "bin it" a one-liner, not a `reset --hard`.
|
|
25
|
+
- **A dirty tree you can't commit yet** — you have unsaved work but need to try something risky; isolate rather than stash-and-pray.
|
|
26
|
+
- Skip it for a single, in-place edit on a clean tree — a worktree is overhead there.
|
|
27
|
+
|
|
28
|
+
## How
|
|
29
|
+
1. **Detect** — are you already in a worktree? `[ "$(git rev-parse --git-dir)" != "$(git rev-parse --git-common-dir)" ]` is true inside one; don't nest.
|
|
30
|
+
2. **Create** — `git worktree add ../wt-<name> -b <branch>` (new branch) or `git worktree add ../wt-<name> <existing>`. It shares the object store, so it's cheap.
|
|
31
|
+
3. **Work there** — cd into it; edits, builds, and agent runs stay local to that copy.
|
|
32
|
+
4. **Fold back or discard** — keep: commit on its branch, then merge. Discard: `git worktree remove ../wt-<name>` (add `--force` only if you mean to drop its changes).
|
|
33
|
+
5. **Clean up** — `git worktree prune` removes stale entries. Never leave orphaned worktrees around.
|
|
34
|
+
|
|
35
|
+
## Invariant rules
|
|
36
|
+
1. **Isolate before risk, don't revert after** — a worktree replaces "run `checkout -- .` to undo"; the undo is `worktree remove`.
|
|
37
|
+
2. **One worktree per parallel writer** — never two agents mutating the same tree at once.
|
|
38
|
+
3. **Don't nest** — creating a worktree from inside a worktree; detect first.
|
|
39
|
+
4. **Commit or isolate before delegating file-mutating work** — a subagent must never be able to discard the main tree's unsaved changes.
|
|
40
|
+
5. **Remove what you add** — no orphaned worktrees; `remove` + `prune` when done.
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
# Crewforth Studio
|
|
2
|
+
|
|
3
|
+
A visual orchestration panel for Claude Code: which agent is running, what it is
|
|
4
|
+
doing right now, what it has spent, and which gates fired.
|
|
5
|
+
|
|
6
|
+
Studio **is installed into your project**, because it lives inside the payload:
|
|
7
|
+
this directory is `kit/studio/`, and `kit/` is what every
|
|
8
|
+
channel already ships. `start.sh` and `adopt.sh` copy it to `.claude/studio/`,
|
|
9
|
+
beside `agents`, `skills`, `commands`, `hooks` and `eval` — the sixth of six.
|
|
10
|
+
|
|
11
|
+
That was the other way round until a real project updated with `/crew-update`,
|
|
12
|
+
ran the documented command and got ENOENT: the project had no `package.json`,
|
|
13
|
+
and nothing had ever installed the panel into it. Excluding it from every
|
|
14
|
+
channel was a decision; a documented command that cannot work is a defect.
|
|
15
|
+
|
|
16
|
+
## Run
|
|
17
|
+
|
|
18
|
+
From any project that has Crewforth:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
/crew-studio # the command; probes node, starts it, reports the URL
|
|
22
|
+
node .claude/studio/server/index.js --open # the same thing without the picker
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**`node` may not be on your PATH, and that is on purpose.** When Crewforth fetched the runtime for you
|
|
26
|
+
(`ensure-node.sh --install`), it promised to touch nothing outside `~/.claude/studio-runtime` — no PATH edit,
|
|
27
|
+
no shell profile, no admin rights. Measured on a stock Windows 11 machine: after a successful install
|
|
28
|
+
`node --version` reports v24.21.0 through the full path while `command -v node` finds nothing, which is the
|
|
29
|
+
promise being kept rather than a broken install. So every `node …` line on this page means "the node Crewforth
|
|
30
|
+
can find". Ask for it instead of assuming it:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
NODE="$(bash .claude/studio/ensure-node.sh)" # prints an absolute path, exits 1 if there is none
|
|
34
|
+
"$NODE" .claude/studio/server/index.js --open
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
`/crew-studio` does exactly this for you, which is why it is the first line above and not the second.
|
|
38
|
+
|
|
39
|
+
Other flags, same file:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
node .claude/studio/server/index.js --port 8080
|
|
43
|
+
node .claude/studio/server/index.js --selftest # offline checks, no browser
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Started per project, scoped to the machine.** Studio reads
|
|
47
|
+
`~/.claude/projects`, which holds every session on this machine. The count is
|
|
48
|
+
whatever that directory holds; the panel prints it rather than claiming it here,
|
|
49
|
+
because a number measured on one machine describes only that machine. So a
|
|
50
|
+
running panel already sees a kit-installed project without being started inside
|
|
51
|
+
it, and the working directory only decides which project the panel opens on.
|
|
52
|
+
Run it from wherever is convenient, or run it once and leave it up.
|
|
53
|
+
|
|
54
|
+
`--open` exists so the URL is not copied by hand: the token is generated per run
|
|
55
|
+
and the panel refuses requests without it. When a browser cannot be opened — over
|
|
56
|
+
SSH, or headless — the server says so rather than looking like it worked, and
|
|
57
|
+
`/crew-studio` reports the URL either way.
|
|
58
|
+
|
|
59
|
+
**Both editions carry the panel, in different places.** A full install has it
|
|
60
|
+
at `.claude/studio/`; the plugin edition has it at `studio/` in the plugin's own
|
|
61
|
+
root. One `/crew-studio` file serves both, and its first step tells them apart
|
|
62
|
+
by reading `${CLAUDE_PLUGIN_ROOT}/studio/server/index.js` literally: Claude Code
|
|
63
|
+
replaces that placeholder before the command is read, and only when the command
|
|
64
|
+
came from the plugin. A real absolute path is the plugin's panel; the
|
|
65
|
+
placeholder left standing means a full install. Neither path on disk means an
|
|
66
|
+
install older than the panel, which `/crew-update` brings up to date.
|
|
67
|
+
In the plugin the command is namespaced: `/crewforth:crew-studio`.
|
|
68
|
+
|
|
69
|
+
**What the plugin edition cannot show.** A plugin install puts no
|
|
70
|
+
`.claude/VERSION`, `kit.conf` or Crewforth scripts into a project. That project's row
|
|
71
|
+
in the list has no version badge, and for the project the panel was opened from, the
|
|
72
|
+
inspector's gates, stats and board tabs say "Not measured" with the reason rather
|
|
73
|
+
than zero. The gates tab can still list what the gate log observed: the plugin's
|
|
74
|
+
Bash guard records its blocks, approval prompts and pre-authorised git actions,
|
|
75
|
+
and its gate-file write guard its blocks, in `.claude/gate-log.tsv` when the
|
|
76
|
+
project has a `.claude/` directory, the file is git-ignored or the project is
|
|
77
|
+
not a repo, and `CREW_GATE_LOG` does not send the log elsewhere.
|
|
78
|
+
Everything else — the live
|
|
79
|
+
agent graph, owned sessions, the permission bridge — works the same in both
|
|
80
|
+
editions.
|
|
81
|
+
|
|
82
|
+
**The suite is not here.** It lives in `packaging/studio-test/`, beside the
|
|
83
|
+
repo's other gates, and asserts things about this *repository* — the root
|
|
84
|
+
`package.json`, the payload beside it — which an installed project does not
|
|
85
|
+
have. Keeping it under `kit/` would also have shipped 104 KB of test
|
|
86
|
+
code through all four channels only for the installer to delete it on arrival.
|
|
87
|
+
The installed diagnostic is `--selftest`, which lives in `server/index.js`.
|
|
88
|
+
|
|
89
|
+
There is no install step. Studio has **zero dependencies** — `node:http` and
|
|
90
|
+
`node:child_process` are the whole stack, matching Crewforth's own promise. If
|
|
91
|
+
`node_modules` ever appears here, something has gone wrong.
|
|
92
|
+
|
|
93
|
+
Requires Node 18+. In Crewforth's own repository `bash packaging/verify.sh studio`
|
|
94
|
+
runs the same checks CI runs; a machine without node reports a skip rather than a
|
|
95
|
+
pass, and a missing `kit/studio/` is a failure rather than a skip.
|
|
96
|
+
|
|
97
|
+
## What it does
|
|
98
|
+
|
|
99
|
+
**Watches.** The delegation graph of any session on this machine, live: one node
|
|
100
|
+
per agent, what it is doing right now, what it has spent, what it reported.
|
|
101
|
+
Nodes are draggable and their positions are remembered; a workflow run is a
|
|
102
|
+
container you can fold.
|
|
103
|
+
|
|
104
|
+
**Talks.** Sessions the panel starts are driven over stdin/stdout, so you can
|
|
105
|
+
write to one and watch its agents appear beneath it. They are given a session id
|
|
106
|
+
up front, which means their transcripts land where every other session's do and
|
|
107
|
+
the graph reads them without a special case.
|
|
108
|
+
|
|
109
|
+
**Shows every conversation, drives only its own.** Selecting any session opens
|
|
110
|
+
what was said in it, read from the transcript. A session the panel did not start
|
|
111
|
+
has no channel to write to, so that pane says so and offers the two things that
|
|
112
|
+
do work: continue it here, or open it in a real terminal.
|
|
113
|
+
|
|
114
|
+
**Asks before it acts.** Every tool call in an owned session is parked by a
|
|
115
|
+
PreToolUse hook and shown in the panel — the command itself, not just the tool's
|
|
116
|
+
name — until you allow it, allow that tool for the session, or deny it.
|
|
117
|
+
|
|
118
|
+
**Runs several at once.** Each session the panel starts is a tab that keeps its
|
|
119
|
+
own stream open whether or not it is on screen, so work continuing in the
|
|
120
|
+
background is continuing, not replayed when you look back.
|
|
121
|
+
|
|
122
|
+
**Hands a session to a real terminal.** The panel cannot drive a session it did
|
|
123
|
+
not start, so for an observed one it offers the only thing that is true: a
|
|
124
|
+
button that opens it where it can be driven. What it will run is shown before
|
|
125
|
+
anything launches.
|
|
126
|
+
|
|
127
|
+
**Reaches other machines.** Transcripts are local files and nothing enumerates
|
|
128
|
+
another machine's sessions, so a peer is another Studio.
|
|
129
|
+
|
|
130
|
+
## What it reads
|
|
131
|
+
|
|
132
|
+
| Source | What it gives |
|
|
133
|
+
|---|---|
|
|
134
|
+
| `claude agents --json` | Live sessions on this machine: name, cwd, busy/waiting/idle, what it is waiting for |
|
|
135
|
+
| `<session>.jsonl` and `<session>/subagents/` | The delegation graph, nested workflow runs included |
|
|
136
|
+
| `.claude/VERSION` per project | Which projects run an old Crewforth, against the npm dist-tags feed |
|
|
137
|
+
|
|
138
|
+
That call spawns a process, so it is cached rather than repeated. The browser
|
|
139
|
+
polls every 2 s and the server caches for 1 s, which bounds the cost at one
|
|
140
|
+
spawn per poll. What the spawn costs is a property of the machine, not of this
|
|
141
|
+
file — two machines here measured 131 ms and 164 ms medians — so `--selftest`
|
|
142
|
+
measures it wherever it runs and prints that number instead of quoting one.
|
|
143
|
+
|
|
144
|
+
More sources land in later sprints: the transcript tree (per-agent live JSONL),
|
|
145
|
+
the owned-session event stream, `gate-log.tsv`, and the team board.
|
|
146
|
+
|
|
147
|
+
## Two honesty rules
|
|
148
|
+
|
|
149
|
+
These are load-bearing, not stylistic.
|
|
150
|
+
|
|
151
|
+
**"Not measured" is never drawn as zero.** If the `claude` CLI is missing or a
|
|
152
|
+
read fails, the panel says so and names the reason. An empty list would read as
|
|
153
|
+
a quiet, healthy machine — which is the kind of lie this panel exists to stop
|
|
154
|
+
telling.
|
|
155
|
+
|
|
156
|
+
**Unknown data is never coerced into something familiar.** An unrecognised
|
|
157
|
+
status keeps a neutral ring; an unrecognised field is carried through untouched
|
|
158
|
+
rather than dropped. Claude Code's event shapes are undocumented and move with
|
|
159
|
+
the version, so the panel is built to notice that rather than to guess.
|
|
160
|
+
|
|
161
|
+
## Sessions on other machines
|
|
162
|
+
|
|
163
|
+
The fleet lists them under **Reachable elsewhere**, with the time they were
|
|
164
|
+
seen. That wording is the whole of it: this is a snapshot, not a feed.
|
|
165
|
+
|
|
166
|
+
Only a session connected to Remote Control can see peers on other machines.
|
|
167
|
+
Measured: a headless session's `ListAgents` returns the local peers where a
|
|
168
|
+
connected one returns those plus five remote, and passing `--remote-control` to
|
|
169
|
+
a headless session does not change that — the flag starts an *interactive*
|
|
170
|
+
session. There is no documented API or non-interactive command that enumerates
|
|
171
|
+
them; `/list-agents` is an in-session tool, `--cloud` refuses without a TTY, and
|
|
172
|
+
the Claude API's `/v1/sessions` belongs to Managed Agents, a different product.
|
|
173
|
+
|
|
174
|
+
So the panel does not try to be that session. It reads what one already wrote:
|
|
175
|
+
a connected session's `ListAgents` result lands in its transcript as structured
|
|
176
|
+
text, and that is where this comes from. When no session here has ever asked,
|
|
177
|
+
that is reported as not measured — which is not the same as having no peers.
|
|
178
|
+
|
|
179
|
+
Listed, not opened. Those sessions' transcripts are on those machines' disks,
|
|
180
|
+
so the panel can name them but cannot draw their graphs. For that, run Studio
|
|
181
|
+
there too:
|
|
182
|
+
|
|
183
|
+
## Other machines
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
# on the other machine
|
|
187
|
+
node .claude/studio/server/index.js
|
|
188
|
+
|
|
189
|
+
# here — forward its port, then point at the forwarded one
|
|
190
|
+
ssh -N -L 7778:127.0.0.1:7777 other-machine
|
|
191
|
+
node .claude/studio/server/index.js --peer http://127.0.0.1:7778 --name mac
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Sessions, projects, graphs and agent reports from a peer appear alongside local
|
|
195
|
+
ones, tagged with the machine they came from. A peer that cannot be reached is
|
|
196
|
+
reported as unreachable, never as empty.
|
|
197
|
+
|
|
198
|
+
Nothing listens on a network interface in this arrangement: both Studios stay on
|
|
199
|
+
loopback and the tunnel does the crossing.
|
|
200
|
+
|
|
201
|
+
## What Crewforth already measured
|
|
202
|
+
|
|
203
|
+
The panel does not recompute any of it. Selecting the session node opens what
|
|
204
|
+
Crewforth's own tools say, including when they say they cannot answer:
|
|
205
|
+
|
|
206
|
+
| Tab | Source |
|
|
207
|
+
|---|---|
|
|
208
|
+
| gates | `gate-report.sh --json` for the rule inventory, `.claude/gate-log.tsv` for what fired |
|
|
209
|
+
| stats | `session-stats.sh --raw` — fifteen metrics over this transcript |
|
|
210
|
+
| board | `board.sh status` |
|
|
211
|
+
|
|
212
|
+
One distinction is carried all the way to the screen. A gate event from a
|
|
213
|
+
session the panel started arrives through `--include-hook-events` and carries
|
|
214
|
+
the moment it happened, so it is listed under **Happened**. A line in
|
|
215
|
+
`gate-log.tsv` does not — that format has no timestamp column — so those are
|
|
216
|
+
listed under **Observed**, with the reason written out. Drawing the second as
|
|
217
|
+
the first would be the first untrue thing in this panel.
|
|
218
|
+
|
|
219
|
+
`gate-report.sh` finds the hooks relative to where it runs: `./.claude/hooks`
|
|
220
|
+
in an installed project, `./hooks` otherwise. Both layouts are handed what they
|
|
221
|
+
expect rather than the script being asked to guess. Where it still cannot
|
|
222
|
+
answer — a directory with no Crewforth install, a project with no log — that is reported as
|
|
223
|
+
not measured, never as zero.
|
|
224
|
+
|
|
225
|
+
## The permission gate
|
|
226
|
+
|
|
227
|
+
A hook injected through `--settings` parks each tool call, writes it into a
|
|
228
|
+
spool, and waits for the panel's answer. Exit 0 allows, exit 2 blocks.
|
|
229
|
+
|
|
230
|
+
It answers at 45 seconds against a 90-second harness timeout, and that gap is
|
|
231
|
+
the whole design. Measured here: a hook killed at its timeout emits nothing and
|
|
232
|
+
**the tool proceeds** — `permission_denials` came back 0 and the command ran. A
|
|
233
|
+
hook the harness never has to kill fails closed instead, so a shut panel is a
|
|
234
|
+
denial rather than an opening.
|
|
235
|
+
|
|
236
|
+
The waiting costs no processes. A bounded read on a fifo held open read-write
|
|
237
|
+
blocks for its timeout and never sees EOF; the alternative, a `sleep` per poll,
|
|
238
|
+
spends seconds of fork overhead on Git Bash. Both the fifo and the shell's
|
|
239
|
+
support for fractional timeouts are probed with exactly what the loop will run —
|
|
240
|
+
bash 3.2 ignores a fractional `-t` and turns the poll into a hot spin, which is
|
|
241
|
+
how the first version passed while spinning 185,000 times in five seconds.
|
|
242
|
+
|
|
243
|
+
Interactive prompts have a limit worth stating: `AskUserQuestion`, `ExitPlanMode`
|
|
244
|
+
and `EnterPlanMode` are absent from a headless session's 78-tool list, in every
|
|
245
|
+
permission mode, while an interactive session has them. So there is no
|
|
246
|
+
structured choice to render. When a reply offers options in prose the panel
|
|
247
|
+
makes them clickable, which sends that text — a shortcut for typing it, not a
|
|
248
|
+
channel that does not exist.
|
|
249
|
+
|
|
250
|
+
## Security
|
|
251
|
+
|
|
252
|
+
The server binds to `127.0.0.1` only, and the host is deliberately not
|
|
253
|
+
configurable — it reads a developer's live sessions and can start new ones.
|
|
254
|
+
|
|
255
|
+
A token is always required for `/api/`. Supply one, or let the server generate
|
|
256
|
+
one and print it with the URL:
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
CREW_STUDIO_TOKEN=$(uuidgen) node .claude/studio/server/index.js
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
Anything that changes state needs, on top of the token, a header no cross-origin
|
|
263
|
+
page can attach without a preflight this server never answers. Permission modes
|
|
264
|
+
are an allow-list — `plan` (the default), `acceptEdits`, `default` — so a mode
|
|
265
|
+
that skips Crewforth's gates cannot be requested, and the panel never has to name
|
|
266
|
+
one to refuse it.
|