@brainervirus/workit-claude-code 8.22.3 → 8.24.0

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "workit",
3
3
  "displayName": "Workit",
4
- "version": "8.22.3",
4
+ "version": "8.24.0",
5
5
  "description": "Workflow rails for agentic coding: task context on every session, branch policy on shell commands, and the workit method skills",
6
6
  "author": {
7
7
  "name": "BrainerVirus"
package/README.md CHANGED
@@ -40,7 +40,7 @@ export CLAUDE_CODE_PLUGIN_DIRS="$HOME/path/to/workit/packages/workit-claude-code
40
40
  | `hooks/hooks.json` | SessionStart (startup/resume/clear/compact/fork), UserPromptSubmit, PreToolUse (Bash, PowerShell, Edit/Write/MultiEdit/NotebookEdit), SubagentStart |
41
41
  | `bin/workit-hook.mjs` | Hook launcher: source with Bun in a checkout, `dist/workit-hook.js` when installed; answers plain shell commands and edits in task-less checkouts with `{}` before loading the runtime; fails open (`{}` + one stderr line) when neither can run |
42
42
  | `bin/workit` | `workit` on the Bash tool's PATH (same source/dist switch) |
43
- | `agents/` | `verifier`, `reviewer` (read-only), `implementer` (`isolation: worktree`) |
43
+ | `agents/` | `verifier`, `reviewer` (read-only), `implementer` (works in the lead's `workit fanout worktree create` worktree; no `isolation`) |
44
44
  | `skills/` | Generated by `scripts/build.ts` from `packages/workit-core/skills` (not committed) |
45
45
  | `evals/` | Opt-in `claude plugin eval` suite (nightly / `eval` label, not a PR gate) |
46
46
 
@@ -1,36 +1,43 @@
1
1
  ---
2
2
  name: implementer
3
- description: Implements one scoped workit brief in an isolated git worktree and reports what changed and how it was checked. Use to delegate a well-defined slice (goal, scope, acceptance, verify, forbidden, report) so it can run in parallel with other work.
4
- isolation: worktree
3
+ description: Implements one scoped workit brief in the git worktree its lead made with `workit fanout worktree create`, and reports what changed and how it was checked. Use to delegate a well-defined slice (goal, scope, acceptance, verify, forbidden, report, worktree) so it can run in parallel with other work.
5
4
  ---
6
5
 
7
- You are a workit implementer working in your own git worktree.
6
+ You are a workit implementer. You work only in the git worktree your brief
7
+ names (its WORKTREE line), which the lead made with
8
+ `workit fanout worktree create <slice>` before spawning you; never in the
9
+ lead's checkout.
8
10
 
9
11
  Refuse to start without a complete brief. It must state: goal, scope (files
10
12
  or areas you may touch), acceptance (observable outcomes), verify (exact
11
13
  commands), timebox, forbidden (what you must not touch or do), report (what to
12
- hand back), standing orders and mode (`new` or `resume`). If a field is
13
- missing, report which and stop.
14
+ hand back), standing orders, mode (`new` or `resume`) and the worktree path.
15
+ If a field is missing, report which and stop.
14
16
 
15
- 1. Your worktree starts on a branch name chosen by Claude Code, which may break
16
- the repository's branch policy. First command, `MODE: new`:
17
- `workit git branch <branch> --base <base>` with the brief's branch and base.
18
- `MODE: resume` (you replace a stopped worker): `git switch <branch>` and
19
- continue from its head; never `workit git branch`, the branch exists. A hook denies
20
- protected or non-compliant names; follow the unblock it prints.
21
- 2. Stay inside the scope. Anything outside it is a follow-up in the report,
17
+ 1. Run each git and check command against the worktree, one verb per call:
18
+ `workit --cwd <worktree> git commit …`, `workit --cwd <worktree> check <name>`.
19
+ Never `cd <worktree> && …` chains, `$VAR` paths or compound commands. Edit
20
+ files by their path under the worktree. Workit's hooks deny an edit or a
21
+ mutating git command outside it.
22
+ 2. The worktree is already on the brief's branch. If it is not: `MODE: new`,
23
+ `workit --cwd <worktree> git branch <branch> --base <base>`; `MODE: resume`
24
+ (you replace a stopped worker), `git -C <worktree> switch <branch>` and
25
+ continue from its head. A hook denies protected or non-compliant names;
26
+ follow the unblock it prints.
27
+ 3. Stay inside the scope. Anything outside it is a follow-up in the report,
22
28
  not a diff. Follow the workit-implement skill (`/workit:implement`).
23
- 3. Decide ambiguities yourself and record them:
29
+ 4. Decide ambiguities yourself and record them:
24
30
  `workit ledger ruling "<what>" --why "<why>" --cost-if-wrong "<cost>"`.
25
31
  Stop only for an irreversible or security-sensitive action, or a side effect
26
32
  outside your worktree.
27
- 4. Commit in small steps with
28
- `workit git commit -m "<conventional message>" -- <paths in scope>`.
29
- 5. Run every verify command as `workit check …` and keep the real exit codes.
30
- 6. Never record a verdict on your own work and never pass `--self`: a separate
33
+ 5. Commit in small steps with
34
+ `workit --cwd <worktree> git commit -m "<conventional message>" -- <paths in scope>`.
35
+ 6. Run every verify command as `workit --cwd <worktree> check …` and keep the
36
+ real exit codes.
37
+ 7. Never record a verdict on your own work and never pass `--self`: a separate
31
38
  verifier judges it. Never push, open a PR, rebase or merge unless the brief
32
39
  says so.
33
40
 
34
- Report: branch and head SHA, files changed, each verify command with its exit
35
- code, each acceptance item met or not, rulings recorded, and any deviation from
36
- the brief.
41
+ Report: worktree, branch and head SHA, files changed, each verify command with
42
+ its exit code, each acceptance item met or not, rulings recorded, and any
43
+ deviation from the brief.
@@ -49,6 +49,11 @@ const WORKIT_DELIVERY =
49
49
  /(?:^|[\s;&|(])(?:\S*[\\/])?workit(?:-cli)?\s+(?:pr (?:create|merge)|ci wait|git push)\b/;
50
50
  const MAYBE_GATED =
51
51
  /\b(?:git|gh|glab)\b|>|\b(?:tee|touch|mkdir|rm|rmdir|mv|cp|truncate|install|ln|patch|dd|sed|perl|set-content|add-content|out-file|new-item|ni|remove-item|del|copy-item|move-item)\b/i;
52
+ // What an implementer's confinement also judges (hooks/worktree-confine.ts):
53
+ // writers the edit analysis cannot see, `-c` scripts, `$(…)` and Workit's
54
+ // lead-owned fanout verbs.
55
+ const IMPLEMENTER_GATED =
56
+ /\b(?:unlink|chmod|chown|chgrp|shred|chattr|setfacl|rsync|find|xargs|g?awk|python[\d.]*|node|bun|deno|ruby|php|sh|bash|zsh|dash|ksh|workit)\b|\$\(|`/i;
52
57
  const SHELLS = new Set(["Bash", "PowerShell"]);
53
58
  const HEAVY_WORDS = new Set(
54
59
  (
@@ -208,13 +213,17 @@ const fastAllow = (() => {
208
213
  if (value?.hook_event_name !== "PreToolUse") return false;
209
214
  if (mentionsIssued(JSON.stringify(value.tool_input ?? {}))) return false;
210
215
  if (standingPending(String(value.cwd ?? "."), value.session_id, value.agent_id)) return false;
216
+ // An implementer's writes are confined to its Workit worktree with or
217
+ // without a task store (hooks/worktree-confine.ts).
218
+ const implementer = value.agent_type === "workit:implementer";
211
219
  if (SHELLS.has(value.tool_name) && typeof command === "string") {
212
220
  if (WORKIT_DELIVERY.test(command)) return false;
213
221
  if (maybeHeavy(command, String(value.cwd ?? "."))) return false;
214
- if (!MAYBE_GATED.test(command)) return true;
215
- return !RAW_TOOLS.test(command) && !hasTaskStore(String(value.cwd ?? "."));
222
+ if (!MAYBE_GATED.test(command) && !(implementer && IMPLEMENTER_GATED.test(command)))
223
+ return true;
224
+ return !implementer && !RAW_TOOLS.test(command) && !hasTaskStore(String(value.cwd ?? "."));
216
225
  }
217
- return EDITS.has(value.tool_name) && !hasTaskStore(String(value.cwd ?? "."));
226
+ return EDITS.has(value.tool_name) && !implementer && !hasTaskStore(String(value.cwd ?? "."));
218
227
  } catch {
219
228
  return false;
220
229
  }