work-kit-cli 0.2.8 → 0.4.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.
- package/README.md +24 -13
- package/cli/src/commands/bootstrap.test.ts +40 -0
- package/cli/src/commands/bootstrap.ts +77 -13
- package/cli/src/commands/cancel.ts +1 -16
- package/cli/src/commands/complete.ts +92 -98
- package/cli/src/commands/completions.ts +2 -2
- package/cli/src/commands/doctor.ts +1 -1
- package/cli/src/commands/extract.ts +217 -0
- package/cli/src/commands/init.test.ts +50 -0
- package/cli/src/commands/init.ts +70 -35
- package/cli/src/commands/learn.test.ts +217 -0
- package/cli/src/commands/learn.ts +104 -0
- package/cli/src/commands/loopback.ts +8 -11
- package/cli/src/commands/next.ts +93 -60
- package/cli/src/commands/observe.ts +16 -21
- package/cli/src/commands/pause-resume.test.ts +142 -0
- package/cli/src/commands/pause.ts +34 -0
- package/cli/src/commands/report.ts +217 -0
- package/cli/src/commands/resume.ts +126 -0
- package/cli/src/commands/setup.ts +280 -0
- package/cli/src/commands/status.ts +8 -6
- package/cli/src/commands/uninstall.ts +8 -3
- package/cli/src/commands/workflow.ts +43 -33
- package/cli/src/config/agent-map.ts +9 -9
- package/cli/src/config/constants.ts +54 -0
- package/cli/src/config/loopback-routes.ts +13 -13
- package/cli/src/config/model-routing.test.ts +190 -0
- package/cli/src/config/model-routing.ts +208 -0
- package/cli/src/config/project-config.test.ts +127 -0
- package/cli/src/config/project-config.ts +106 -0
- package/cli/src/config/{phases.ts → workflow.ts} +40 -23
- package/cli/src/context/prompt-builder.ts +10 -9
- package/cli/src/index.ts +130 -9
- package/cli/src/observer/data.ts +196 -65
- package/cli/src/observer/renderer.ts +127 -107
- package/cli/src/observer/watcher.ts +28 -16
- package/cli/src/state/helpers.test.ts +28 -28
- package/cli/src/state/helpers.ts +37 -25
- package/cli/src/state/schema.ts +135 -45
- package/cli/src/state/store.ts +127 -7
- package/cli/src/state/validators.test.ts +13 -13
- package/cli/src/state/validators.ts +3 -4
- package/cli/src/utils/colors.ts +2 -0
- package/cli/src/utils/fs.ts +13 -0
- package/cli/src/utils/json.ts +20 -0
- package/cli/src/utils/knowledge.ts +471 -0
- package/cli/src/utils/time.ts +27 -0
- package/cli/src/{engine → workflow}/loopbacks.test.ts +2 -2
- package/cli/src/workflow/loopbacks.ts +42 -0
- package/cli/src/workflow/parallel.ts +64 -0
- package/cli/src/workflow/transitions.test.ts +129 -0
- package/cli/src/{engine → workflow}/transitions.ts +18 -22
- package/package.json +2 -2
- package/skills/auto-kit/SKILL.md +44 -27
- package/skills/cancel-kit/SKILL.md +4 -4
- package/skills/full-kit/SKILL.md +45 -28
- package/skills/pause-kit/SKILL.md +25 -0
- package/skills/resume-kit/SKILL.md +64 -0
- package/skills/wk-bootstrap/SKILL.md +11 -5
- package/skills/wk-build/SKILL.md +12 -11
- package/skills/wk-build/{stages → steps}/commit.md +1 -1
- package/skills/wk-build/{stages → steps}/core.md +3 -3
- package/skills/wk-build/{stages → steps}/integration.md +2 -2
- package/skills/wk-build/{stages → steps}/migration.md +1 -1
- package/skills/wk-build/{stages → steps}/red.md +1 -1
- package/skills/wk-build/{stages → steps}/refactor.md +1 -1
- package/skills/wk-build/{stages → steps}/setup.md +1 -1
- package/skills/wk-build/{stages → steps}/ui.md +1 -1
- package/skills/wk-deploy/SKILL.md +7 -6
- package/skills/wk-deploy/{stages → steps}/merge.md +1 -1
- package/skills/wk-deploy/{stages → steps}/monitor.md +1 -1
- package/skills/wk-deploy/{stages → steps}/remediate.md +1 -1
- package/skills/wk-plan/SKILL.md +15 -14
- package/skills/wk-plan/{stages → steps}/architecture.md +1 -1
- package/skills/wk-plan/{stages → steps}/audit.md +2 -2
- package/skills/wk-plan/{stages → steps}/blueprint.md +2 -2
- package/skills/wk-plan/{stages → steps}/clarify.md +1 -1
- package/skills/wk-plan/{stages → steps}/investigate.md +1 -1
- package/skills/wk-plan/{stages → steps}/scope.md +1 -1
- package/skills/wk-plan/{stages → steps}/sketch.md +1 -1
- package/skills/wk-plan/{stages → steps}/ux-flow.md +1 -1
- package/skills/wk-review/SKILL.md +11 -10
- package/skills/wk-review/{stages → steps}/compliance.md +1 -1
- package/skills/wk-review/{stages → steps}/handoff.md +2 -2
- package/skills/wk-review/{stages → steps}/performance.md +1 -1
- package/skills/wk-review/{stages → steps}/security.md +1 -1
- package/skills/wk-review/{stages → steps}/self-review.md +1 -1
- package/skills/wk-test/SKILL.md +9 -8
- package/skills/wk-test/steps/e2e.md +56 -0
- package/skills/wk-test/{stages → steps}/validate.md +1 -1
- package/skills/wk-test/{stages → steps}/verify.md +1 -1
- package/skills/wk-wrap-up/SKILL.md +19 -5
- package/skills/wk-wrap-up/steps/knowledge.md +76 -0
- package/skills/wk-wrap-up/steps/summary.md +86 -0
- package/cli/src/engine/loopbacks.ts +0 -32
- package/cli/src/engine/parallel.ts +0 -60
- package/cli/src/engine/transitions.test.ts +0 -129
- package/skills/wk-test/stages/e2e.md +0 -53
- /package/cli/src/{engine/phases.ts → workflow/gates.ts} +0 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { describe, it } from "node:test";
|
|
2
|
+
import * as assert from "node:assert/strict";
|
|
3
|
+
import { nextStepInPhase, isPhaseComplete, determineNextStep } from "./transitions.js";
|
|
4
|
+
import type { WorkKitState, PhaseName, PhaseState, StepState } from "../state/schema.js";
|
|
5
|
+
import { PHASE_NAMES, STEPS_BY_PHASE } from "../state/schema.js";
|
|
6
|
+
|
|
7
|
+
function makeState(): WorkKitState {
|
|
8
|
+
const phases = {} as Record<PhaseName, PhaseState>;
|
|
9
|
+
for (const phase of PHASE_NAMES) {
|
|
10
|
+
const steps: Record<string, StepState> = {};
|
|
11
|
+
for (const s of STEPS_BY_PHASE[phase]) {
|
|
12
|
+
steps[s] = { status: "pending" };
|
|
13
|
+
}
|
|
14
|
+
phases[phase] = { status: "pending", steps };
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
version: 2,
|
|
18
|
+
slug: "test",
|
|
19
|
+
branch: "feature/test",
|
|
20
|
+
started: "2026-01-01",
|
|
21
|
+
mode: "full-kit",
|
|
22
|
+
status: "in-progress",
|
|
23
|
+
currentPhase: "plan",
|
|
24
|
+
currentStep: "clarify",
|
|
25
|
+
phases,
|
|
26
|
+
loopbacks: [],
|
|
27
|
+
metadata: { worktreeRoot: "/tmp/test", mainRepoRoot: "/tmp/test" },
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
describe("nextStepInPhase", () => {
|
|
32
|
+
it("returns first pending step", () => {
|
|
33
|
+
const state = makeState();
|
|
34
|
+
const result = nextStepInPhase(state, "plan");
|
|
35
|
+
assert.equal(result, "clarify");
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("returns null when all complete or skipped", () => {
|
|
39
|
+
const state = makeState();
|
|
40
|
+
for (const s of Object.values(state.phases.plan.steps)) {
|
|
41
|
+
s.status = "completed";
|
|
42
|
+
}
|
|
43
|
+
const result = nextStepInPhase(state, "plan");
|
|
44
|
+
assert.equal(result, null);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("skips completed steps and returns next pending", () => {
|
|
48
|
+
const state = makeState();
|
|
49
|
+
state.phases.plan.steps.clarify.status = "completed";
|
|
50
|
+
state.phases.plan.steps.investigate.status = "completed";
|
|
51
|
+
const result = nextStepInPhase(state, "plan");
|
|
52
|
+
assert.equal(result, "sketch");
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
describe("isPhaseComplete", () => {
|
|
57
|
+
it("returns true when all complete or skipped", () => {
|
|
58
|
+
const state = makeState();
|
|
59
|
+
for (const s of Object.values(state.phases.plan.steps)) {
|
|
60
|
+
s.status = "completed";
|
|
61
|
+
}
|
|
62
|
+
assert.equal(isPhaseComplete(state, "plan"), true);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it("returns true with mix of completed and skipped", () => {
|
|
66
|
+
const state = makeState();
|
|
67
|
+
let first = true;
|
|
68
|
+
for (const s of Object.values(state.phases.plan.steps)) {
|
|
69
|
+
s.status = first ? "skipped" : "completed";
|
|
70
|
+
first = false;
|
|
71
|
+
}
|
|
72
|
+
assert.equal(isPhaseComplete(state, "plan"), true);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it("returns false when some steps are pending", () => {
|
|
76
|
+
const state = makeState();
|
|
77
|
+
assert.equal(isPhaseComplete(state, "plan"), false);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
describe("determineNextStep", () => {
|
|
82
|
+
it("returns complete when state is completed", () => {
|
|
83
|
+
const state = makeState();
|
|
84
|
+
state.status = "completed";
|
|
85
|
+
const result = determineNextStep(state);
|
|
86
|
+
assert.equal(result.type, "complete");
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it("returns phase-boundary when no current phase", () => {
|
|
90
|
+
const state = makeState();
|
|
91
|
+
state.currentPhase = null;
|
|
92
|
+
const result = determineNextStep(state);
|
|
93
|
+
assert.equal(result.type, "phase-boundary");
|
|
94
|
+
assert.equal(result.phase, "plan");
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it("returns step for current phase with pending work", () => {
|
|
98
|
+
const state = makeState();
|
|
99
|
+
state.currentPhase = "plan";
|
|
100
|
+
state.phases.plan.status = "in-progress";
|
|
101
|
+
const result = determineNextStep(state);
|
|
102
|
+
assert.equal(result.type, "step");
|
|
103
|
+
assert.equal(result.phase, "plan");
|
|
104
|
+
assert.equal(result.step, "clarify");
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it("auto-proceeds to next phase by default when current phase is complete", () => {
|
|
108
|
+
const state = makeState();
|
|
109
|
+
state.currentPhase = "plan";
|
|
110
|
+
for (const s of Object.values(state.phases.plan.steps)) {
|
|
111
|
+
s.status = "completed";
|
|
112
|
+
}
|
|
113
|
+
const result = determineNextStep(state);
|
|
114
|
+
assert.equal(result.type, "phase-boundary");
|
|
115
|
+
assert.equal(result.phase, "build");
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it("returns wait-for-user when gated and current phase is complete", () => {
|
|
119
|
+
const state = makeState();
|
|
120
|
+
state.gated = true;
|
|
121
|
+
state.currentPhase = "plan";
|
|
122
|
+
for (const s of Object.values(state.phases.plan.steps)) {
|
|
123
|
+
s.status = "completed";
|
|
124
|
+
}
|
|
125
|
+
const result = determineNextStep(state);
|
|
126
|
+
assert.equal(result.type, "wait-for-user");
|
|
127
|
+
assert.equal(result.phase, "build");
|
|
128
|
+
});
|
|
129
|
+
});
|
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
import { WorkKitState, PhaseName,
|
|
2
|
-
import { PHASE_ORDER } from "../config/
|
|
1
|
+
import { WorkKitState, PhaseName, STEPS_BY_PHASE } from "../state/schema.js";
|
|
2
|
+
import { PHASE_ORDER } from "../config/workflow.js";
|
|
3
3
|
|
|
4
4
|
export interface NextStep {
|
|
5
|
-
type: "
|
|
5
|
+
type: "step" | "phase-boundary" | "complete" | "wait-for-user";
|
|
6
6
|
phase?: PhaseName;
|
|
7
|
-
|
|
7
|
+
step?: string;
|
|
8
8
|
message?: string;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
* Find the next pending
|
|
12
|
+
* Find the next pending step within a phase.
|
|
13
13
|
*/
|
|
14
|
-
export function
|
|
14
|
+
export function nextStepInPhase(state: WorkKitState, phase: PhaseName): string | null {
|
|
15
15
|
const phaseState = state.phases[phase];
|
|
16
|
-
const
|
|
16
|
+
const steps = STEPS_BY_PHASE[phase];
|
|
17
17
|
|
|
18
|
-
for (const
|
|
19
|
-
const
|
|
20
|
-
if (
|
|
21
|
-
return
|
|
18
|
+
for (const step of steps) {
|
|
19
|
+
const stepState = phaseState.steps[step];
|
|
20
|
+
if (stepState && (stepState.status === "pending" || stepState.status === "in-progress" || stepState.status === "waiting")) {
|
|
21
|
+
return step;
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
return null;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
|
-
* Check if all non-skipped
|
|
28
|
+
* Check if all non-skipped steps in a phase are completed.
|
|
29
29
|
*/
|
|
30
30
|
export function isPhaseComplete(state: WorkKitState, phase: PhaseName): boolean {
|
|
31
31
|
const phaseState = state.phases[phase];
|
|
32
|
-
return Object.values(phaseState.
|
|
33
|
-
(
|
|
32
|
+
return Object.values(phaseState.steps).every(
|
|
33
|
+
(s) => s.status === "completed" || s.status === "skipped"
|
|
34
34
|
);
|
|
35
35
|
}
|
|
36
36
|
|
|
@@ -58,7 +58,6 @@ export function determineNextStep(state: WorkKitState): NextStep {
|
|
|
58
58
|
const currentPhase = state.currentPhase;
|
|
59
59
|
|
|
60
60
|
if (!currentPhase) {
|
|
61
|
-
// Find the next phase
|
|
62
61
|
const next = nextPhase(state);
|
|
63
62
|
if (!next) {
|
|
64
63
|
return { type: "complete", message: "All phases complete" };
|
|
@@ -68,7 +67,6 @@ export function determineNextStep(state: WorkKitState): NextStep {
|
|
|
68
67
|
|
|
69
68
|
// Check if current phase is complete
|
|
70
69
|
if (isPhaseComplete(state, currentPhase)) {
|
|
71
|
-
// Find next phase
|
|
72
70
|
const phaseIndex = PHASE_ORDER.indexOf(currentPhase);
|
|
73
71
|
const remainingPhases = PHASE_ORDER.slice(phaseIndex + 1);
|
|
74
72
|
|
|
@@ -76,14 +74,12 @@ export function determineNextStep(state: WorkKitState): NextStep {
|
|
|
76
74
|
const ps = state.phases[phase];
|
|
77
75
|
if (ps.status !== "skipped") {
|
|
78
76
|
if (state.gated) {
|
|
79
|
-
// Gated mode — wait for user confirmation before crossing
|
|
80
77
|
return {
|
|
81
78
|
type: "wait-for-user",
|
|
82
79
|
phase,
|
|
83
80
|
message: `${currentPhase} phase complete. Ready to start ${phase}. Proceed?`,
|
|
84
81
|
};
|
|
85
82
|
}
|
|
86
|
-
// Default — auto-proceed to next phase
|
|
87
83
|
return { type: "phase-boundary", phase, message: `${currentPhase} complete → starting ${phase}` };
|
|
88
84
|
}
|
|
89
85
|
}
|
|
@@ -91,10 +87,10 @@ export function determineNextStep(state: WorkKitState): NextStep {
|
|
|
91
87
|
return { type: "complete", message: "All phases complete" };
|
|
92
88
|
}
|
|
93
89
|
|
|
94
|
-
// Find next
|
|
95
|
-
const
|
|
96
|
-
if (
|
|
97
|
-
return { type: "
|
|
90
|
+
// Find next step within current phase
|
|
91
|
+
const next = nextStepInPhase(state, currentPhase);
|
|
92
|
+
if (next) {
|
|
93
|
+
return { type: "step", phase: currentPhase, step: next };
|
|
98
94
|
}
|
|
99
95
|
|
|
100
96
|
return { type: "complete", message: `${currentPhase} phase complete` };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "work-kit-cli",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Structured development workflow for Claude Code. Two modes, 6 phases, 27
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "Structured development workflow for Claude Code. Two modes, 6 phases, 27 steps.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"work-kit": "cli/bin/work-kit.mjs",
|
package/skills/auto-kit/SKILL.md
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
name: auto-kit
|
|
3
3
|
description: "Smart pipeline that analyzes the request and builds a dynamic workflow. Usage: /auto-kit <description> to start, /auto-kit to continue."
|
|
4
4
|
user-invocable: true
|
|
5
|
-
argument-hint: "[--gated] [description]"
|
|
5
|
+
argument-hint: "[--gated] [--opus|--sonnet|--haiku|--inherit] [description]"
|
|
6
6
|
allowed-tools: Agent, Bash, Read, Write, Edit, Glob, Grep
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
You are the **Work Orchestrator (Auto Mode)**. You analyze the request first, then build a tailored workflow with only the phases and
|
|
9
|
+
You are the **Work Orchestrator (Auto Mode)**. You analyze the request first, then build a tailored workflow with only the phases and steps that are actually needed.
|
|
10
10
|
|
|
11
11
|
Best for: bug fixes, small changes, refactors, or well-understood tasks.
|
|
12
12
|
|
|
@@ -14,7 +14,7 @@ Best for: bug fixes, small changes, refactors, or well-understood tasks.
|
|
|
14
14
|
|
|
15
15
|
Before starting, verify the CLI is installed:
|
|
16
16
|
```bash
|
|
17
|
-
|
|
17
|
+
work-kit doctor
|
|
18
18
|
```
|
|
19
19
|
|
|
20
20
|
If `work-kit` is not found, ask the user to install it:
|
|
@@ -22,7 +22,7 @@ If `work-kit` is not found, ask the user to install it:
|
|
|
22
22
|
|
|
23
23
|
Do not proceed until `doctor` reports all checks passed.
|
|
24
24
|
|
|
25
|
-
## All Available
|
|
25
|
+
## All Available Steps
|
|
26
26
|
|
|
27
27
|
These are the building blocks you pick from:
|
|
28
28
|
|
|
@@ -47,13 +47,13 @@ Before creating the worktree, perform a quick analysis:
|
|
|
47
47
|
- **feature** — new capability (small to medium scope)
|
|
48
48
|
- **large-feature** — new capability (large scope, multiple systems)
|
|
49
49
|
3. **Scan the codebase** — quick look at affected areas (not a full investigation)
|
|
50
|
-
4. **Build the workflow** — select only the
|
|
50
|
+
4. **Build the workflow** — select only the steps needed
|
|
51
51
|
|
|
52
52
|
### Step 2: Build Dynamic Workflow
|
|
53
53
|
|
|
54
|
-
Based on the classification, select
|
|
54
|
+
Based on the classification, select steps. Use this table as a starting point, then adjust based on the specific request:
|
|
55
55
|
|
|
56
|
-
|
|
|
56
|
+
| Step | bug-fix | small-change | refactor | feature | large-feature |
|
|
57
57
|
|------------------------|---------|--------------|----------|---------|---------------|
|
|
58
58
|
| **Plan: Clarify** | YES | YES | YES | YES | YES |
|
|
59
59
|
| **Plan: Investigate** | YES | skip | YES | YES | YES |
|
|
@@ -91,38 +91,55 @@ The table is a guide, not a rigid rule. Adjust based on the actual request:
|
|
|
91
91
|
|
|
92
92
|
### Step 3: Initialize
|
|
93
93
|
|
|
94
|
-
1.
|
|
94
|
+
1. Parse flags out of the user's input before building the init command:
|
|
95
|
+
- `--gated` → append `--gated`
|
|
96
|
+
- `--opus` → append `--model-policy opus`
|
|
97
|
+
- `--sonnet` → append `--model-policy sonnet`
|
|
98
|
+
- `--haiku` → append `--model-policy haiku`
|
|
99
|
+
- `--inherit` → append `--model-policy inherit` (no model override; lets Claude Code's default pick)
|
|
100
|
+
- No model flag → omit `--model-policy` (defaults to `auto` = work-kit step-level routing)
|
|
101
|
+
|
|
102
|
+
Strip recognized flags from the description text. Only one model flag at a time — if the user passes more than one, report the conflict and stop.
|
|
103
|
+
|
|
104
|
+
2. Create a git worktree and initialize state with the CLI:
|
|
95
105
|
```bash
|
|
96
106
|
git worktree add worktrees/<slug> -b feature/<slug>
|
|
97
107
|
cd worktrees/<slug>
|
|
98
|
-
|
|
108
|
+
work-kit init --mode auto --description "<description>" --classification <classification> [--gated] [--model-policy <value>]
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Examples:
|
|
112
|
+
```
|
|
113
|
+
/auto-kit fix login bug → work-kit init --mode auto --description "fix login bug" --classification bug-fix
|
|
114
|
+
/auto-kit --inherit fix the typo → work-kit init --mode auto --description "fix the typo" --classification small-change --model-policy inherit
|
|
115
|
+
/auto-kit --haiku tweak copy → work-kit init --mode auto --description "tweak copy" --classification small-change --model-policy haiku
|
|
99
116
|
```
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
117
|
+
|
|
118
|
+
3. Show the workflow to the user: `work-kit workflow` (output now includes the resolved model per step and the active policy; review it before approving)
|
|
119
|
+
4. User can adjust: `work-kit workflow --add review/security` or `work-kit workflow --remove test/e2e`
|
|
120
|
+
5. **Wait for approval** — user can add/remove steps before proceeding
|
|
121
|
+
6. Once approved, start the execution loop
|
|
105
122
|
|
|
106
123
|
## Continuing Work (`/auto-kit` with no args)
|
|
107
124
|
|
|
108
|
-
1. Run `
|
|
125
|
+
1. Run `work-kit bootstrap` to detect session state
|
|
109
126
|
2. Parse the JSON response:
|
|
110
127
|
- If `active: false` — no session found, ask the user for a description and start new work
|
|
111
128
|
- If `recovery` is set — report the recovery suggestion to the user before continuing
|
|
112
|
-
- If `active: true` — report current state (slug, phase,
|
|
129
|
+
- If `active: true` — report current state (slug, phase, step) to the user
|
|
113
130
|
3. `cd` into the worktree directory
|
|
114
|
-
4. Run `
|
|
131
|
+
4. Run `work-kit next` to get the next action
|
|
115
132
|
5. Follow the execution loop below
|
|
116
133
|
|
|
117
134
|
## Step Validation
|
|
118
135
|
|
|
119
136
|
All validation is handled by the CLI. The `next` command enforces order, phase boundaries, and prerequisites automatically.
|
|
120
137
|
|
|
121
|
-
To add/remove steps mid-work: `
|
|
138
|
+
To add/remove steps mid-work: `work-kit workflow --add <phase/step>` or `--remove <phase/step>`. Completed steps cannot be removed.
|
|
122
139
|
|
|
123
140
|
## Agent Architecture
|
|
124
141
|
|
|
125
|
-
Same as full-kit: each phase runs as a **fresh agent** to keep context focused. The difference is that each agent only runs the
|
|
142
|
+
Same as full-kit: each phase runs as a **fresh agent** to keep context focused. The difference is that each agent only runs the steps in the `## Workflow` checklist.
|
|
126
143
|
|
|
127
144
|
```
|
|
128
145
|
Orchestrator (main agent — you)
|
|
@@ -177,23 +194,23 @@ Orchestrator (main agent — you)
|
|
|
177
194
|
|
|
178
195
|
Each phase writes a `### <Phase>: Final` section — a self-contained summary. The next agent reads **only** the Final sections it needs.
|
|
179
196
|
|
|
180
|
-
If a phase has fewer
|
|
197
|
+
If a phase has fewer steps in the workflow, the Final section still covers the same output — just with less detail where steps were skipped.
|
|
181
198
|
|
|
182
199
|
## Execution Loop
|
|
183
200
|
|
|
184
201
|
The CLI manages all state transitions, prerequisites, and loopbacks. Follow this loop:
|
|
185
202
|
|
|
186
|
-
1. Run `
|
|
203
|
+
1. Run `work-kit next` to get the next action
|
|
187
204
|
2. Parse the JSON response
|
|
188
205
|
3. Follow the action type:
|
|
189
|
-
- **`spawn_agent`**: Use the Agent tool with the provided `agentPrompt`. Pass `skillFile` path for reference. After the agent completes: `
|
|
190
|
-
- **`spawn_parallel_agents`**: Spawn all agents in the `agents` array in parallel using the Agent tool. Wait for all to complete. Then spawn `thenSequential` if provided. After all complete: `
|
|
191
|
-
- **`wait_for_user`**: Report the message to the user and stop. Wait for them to say "proceed" before running `
|
|
192
|
-
- **`loopback`**: Report the loopback to the user, then run `
|
|
206
|
+
- **`spawn_agent`**: Use the Agent tool with the provided `agentPrompt`. Pass `skillFile` path for reference. **If the action includes a `model` field, pass it as the Agent tool's `model` parameter; if the field is absent, do not set `model` (let Claude Code's default pick).** After the agent completes: `work-kit complete <phase>/<step> --outcome <outcome>`
|
|
207
|
+
- **`spawn_parallel_agents`**: Spawn all agents in the `agents` array in parallel using the Agent tool. **For each agent, pass its `model` field as the Agent tool's `model` parameter when present; omit when absent.** Wait for all to complete. Then spawn `thenSequential` if provided (same rule for its `model` field). After all complete: `work-kit complete <onComplete target>`
|
|
208
|
+
- **`wait_for_user`**: Report the message to the user and stop. Wait for them to say "proceed" before running `work-kit next` again.
|
|
209
|
+
- **`loopback`**: Report the loopback to the user, then run `work-kit next` to continue from the target.
|
|
193
210
|
- **`complete`**: Done — run wrap-up if not already done.
|
|
194
211
|
- **`error`**: Report the error and suggestion to the user. Stop.
|
|
195
|
-
4. After each agent completes: `
|
|
196
|
-
5. Then `
|
|
212
|
+
4. After each agent completes: `work-kit complete <phase>/<step> --outcome <outcome>`
|
|
213
|
+
5. Then `work-kit next` again to continue
|
|
197
214
|
|
|
198
215
|
## Loop-Back Rules
|
|
199
216
|
|
|
@@ -13,7 +13,7 @@ Cancels the active work-kit session and cleans up all artifacts.
|
|
|
13
13
|
|
|
14
14
|
1. Finds the active work-kit session (via `bootstrap`)
|
|
15
15
|
2. Confirms with the user before proceeding
|
|
16
|
-
3. Runs `
|
|
16
|
+
3. Runs `work-kit cancel` to:
|
|
17
17
|
- Remove `.work-kit/` state directory
|
|
18
18
|
- Remove the git worktree
|
|
19
19
|
- Delete the feature branch
|
|
@@ -21,14 +21,14 @@ Cancels the active work-kit session and cleans up all artifacts.
|
|
|
21
21
|
|
|
22
22
|
## Instructions
|
|
23
23
|
|
|
24
|
-
1. Run `
|
|
24
|
+
1. Run `work-kit bootstrap` to detect the active session
|
|
25
25
|
2. If no active session: tell the user there's nothing to cancel
|
|
26
26
|
3. If active: show the user what will be cancelled:
|
|
27
27
|
- Slug and branch name
|
|
28
|
-
- Current phase and
|
|
28
|
+
- Current phase and step
|
|
29
29
|
- Any uncommitted work in the worktree will be lost
|
|
30
30
|
4. **Ask the user to confirm** — do not proceed without explicit confirmation
|
|
31
31
|
5. `cd` into the worktree directory
|
|
32
|
-
6. Run `
|
|
32
|
+
6. Run `work-kit cancel`
|
|
33
33
|
7. `cd` back to the main repo root
|
|
34
34
|
8. Report the result to the user
|
package/skills/full-kit/SKILL.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: full-kit
|
|
3
|
-
description: "Full pipeline for feature development. Runs all phases and
|
|
3
|
+
description: "Full pipeline for feature development. Runs all phases and steps in order. Usage: /full-kit <description> to start, /full-kit to continue."
|
|
4
4
|
user-invocable: true
|
|
5
|
-
argument-hint: "[--gated] [description]"
|
|
5
|
+
argument-hint: "[--gated] [--opus|--sonnet|--haiku|--inherit] [description]"
|
|
6
6
|
allowed-tools: Agent, Bash, Read, Write, Edit, Glob, Grep
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
You are the **Work Orchestrator (Full Mode)**. You run the complete lifecycle of a feature through every phase and
|
|
9
|
+
You are the **Work Orchestrator (Full Mode)**. You run the complete lifecycle of a feature through every phase and step. No shortcuts.
|
|
10
10
|
|
|
11
11
|
Best for: large features, new systems, or when you want maximum rigor.
|
|
12
12
|
|
|
@@ -14,7 +14,7 @@ Best for: large features, new systems, or when you want maximum rigor.
|
|
|
14
14
|
|
|
15
15
|
Before starting, verify the CLI is installed:
|
|
16
16
|
```bash
|
|
17
|
-
|
|
17
|
+
work-kit doctor
|
|
18
18
|
```
|
|
19
19
|
|
|
20
20
|
If `work-kit` is not found, ask the user to install it:
|
|
@@ -33,46 +33,63 @@ Do not proceed until `doctor` reports all checks passed.
|
|
|
33
33
|
|
|
34
34
|
## Starting New Work (`/full-kit <description>`)
|
|
35
35
|
|
|
36
|
-
1.
|
|
36
|
+
1. Parse flags out of the user's input before building the init command:
|
|
37
|
+
- `--gated` → append `--gated` to init
|
|
38
|
+
- `--opus` → append `--model-policy opus`
|
|
39
|
+
- `--sonnet` → append `--model-policy sonnet`
|
|
40
|
+
- `--haiku` → append `--model-policy haiku`
|
|
41
|
+
- `--inherit` → append `--model-policy inherit` (no model override; lets Claude Code's default pick)
|
|
42
|
+
- No model flag → omit `--model-policy` (defaults to `auto` = work-kit step-level routing)
|
|
43
|
+
|
|
44
|
+
Strip any recognized flags from the description text before passing it through. Only one model flag may be set at a time — if the user passes more than one, report the conflict and stop.
|
|
45
|
+
|
|
46
|
+
2. Create a git worktree and initialize state:
|
|
37
47
|
```bash
|
|
38
48
|
git worktree add worktrees/<slug> -b feature/<slug>
|
|
39
49
|
cd worktrees/<slug>
|
|
40
|
-
|
|
50
|
+
work-kit init --mode full --description "<description>" [--gated] [--model-policy <value>]
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Examples:
|
|
54
|
+
```
|
|
55
|
+
/full-kit add user avatar → work-kit init --mode full --description "add user avatar"
|
|
56
|
+
/full-kit --opus add user avatar → work-kit init --mode full --description "add user avatar" --model-policy opus
|
|
57
|
+
/full-kit --gated --inherit fix login → work-kit init --mode full --description "fix login" --gated --model-policy inherit
|
|
41
58
|
```
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
59
|
+
|
|
60
|
+
3. Parse the JSON response and follow the action
|
|
61
|
+
4. Continue with the execution loop below
|
|
45
62
|
|
|
46
63
|
## Continuing Work (`/full-kit` with no args)
|
|
47
64
|
|
|
48
|
-
1. Run `
|
|
65
|
+
1. Run `work-kit bootstrap` to detect session state
|
|
49
66
|
2. Parse the JSON response:
|
|
50
67
|
- If `active: false` — no session found, ask the user for a description and start new work
|
|
51
68
|
- If `recovery` is set — report the recovery suggestion to the user before continuing
|
|
52
|
-
- If `active: true` — report current state (slug, phase,
|
|
69
|
+
- If `active: true` — report current state (slug, phase, step) to the user
|
|
53
70
|
3. `cd` into the worktree directory
|
|
54
|
-
4. Run `
|
|
71
|
+
4. Run `work-kit next` to get the next action
|
|
55
72
|
5. Follow the execution loop below
|
|
56
73
|
|
|
57
74
|
## Execution Loop
|
|
58
75
|
|
|
59
76
|
The CLI manages all state transitions, prerequisites, and loopbacks. Follow this loop:
|
|
60
77
|
|
|
61
|
-
1. Run `
|
|
78
|
+
1. Run `work-kit next` to get the next action
|
|
62
79
|
2. Parse the JSON response
|
|
63
80
|
3. Follow the action type:
|
|
64
|
-
- **`spawn_agent`**: Use the Agent tool with the provided `agentPrompt`. Pass `skillFile` path for reference. After the agent completes: `
|
|
65
|
-
- **`spawn_parallel_agents`**: Spawn all agents in the `agents` array in parallel using the Agent tool. Wait for all to complete. Then spawn `thenSequential` if provided. After all complete: `
|
|
66
|
-
- **`wait_for_user`**: Report the message to the user and stop. Wait for them to say "proceed" before running `
|
|
67
|
-
- **`loopback`**: Report the loopback to the user, then run `
|
|
81
|
+
- **`spawn_agent`**: Use the Agent tool with the provided `agentPrompt`. Pass `skillFile` path for reference. **If the action includes a `model` field, pass it as the Agent tool's `model` parameter; if the field is absent, do not set `model` (let Claude Code's default pick).** After the agent completes: `work-kit complete <phase>/<step> --outcome <outcome>`
|
|
82
|
+
- **`spawn_parallel_agents`**: Spawn all agents in the `agents` array in parallel using the Agent tool. **For each agent, pass its `model` field as the Agent tool's `model` parameter when present; omit when absent.** Wait for all to complete. Then spawn `thenSequential` if provided (same rule for its `model` field). After all complete: `work-kit complete <onComplete target>`
|
|
83
|
+
- **`wait_for_user`**: Report the message to the user and stop. Wait for them to say "proceed" before running `work-kit next` again. (Only appears in `--gated` mode.)
|
|
84
|
+
- **`loopback`**: Report the loopback to the user, then run `work-kit next` to continue from the target.
|
|
68
85
|
- **`complete`**: Done — run wrap-up if not already done.
|
|
69
86
|
- **`error`**: Report the error and suggestion to the user. Stop.
|
|
70
|
-
4. After each agent completes: `
|
|
71
|
-
5. Then `
|
|
87
|
+
4. After each agent completes: `work-kit complete <phase>/<step> --outcome <outcome>`
|
|
88
|
+
5. Then `work-kit next` again to continue
|
|
72
89
|
|
|
73
90
|
## Phase Prerequisites
|
|
74
91
|
|
|
75
|
-
Prerequisites are enforced by the CLI (`
|
|
92
|
+
Prerequisites are enforced by the CLI (`work-kit validate <phase>`). You don't need to check manually — the `next` command handles it.
|
|
76
93
|
|
|
77
94
|
| Phase | Requires |
|
|
78
95
|
|----------|-----------------------------------|
|
|
@@ -90,12 +107,12 @@ Each phase runs as a **fresh agent** (sub-agent spawned by the orchestrator). Th
|
|
|
90
107
|
```
|
|
91
108
|
Orchestrator (main agent — you)
|
|
92
109
|
│
|
|
93
|
-
├── Agent: Plan (single agent, all 8
|
|
110
|
+
├── Agent: Plan (single agent, all 8 steps)
|
|
94
111
|
│ ├── reads: ## Description, ## Criteria, codebase
|
|
95
112
|
│ ├── runs: Clarify → Investigate → ... → Audit
|
|
96
113
|
│ └── writes: ### Plan: Final (Blueprint, Architecture, Scope, Constraints)
|
|
97
114
|
│
|
|
98
|
-
├── Agent: Build (single agent, all 8
|
|
115
|
+
├── Agent: Build (single agent, all 8 steps)
|
|
99
116
|
│ ├── reads: ### Plan: Final, ## Criteria
|
|
100
117
|
│ ├── runs: Setup → Migration → ... → Commit
|
|
101
118
|
│ └── writes: ### Build: Final (PR, files changed, test status, deviations)
|
|
@@ -116,7 +133,7 @@ Orchestrator (main agent — you)
|
|
|
116
133
|
│ ├── then: Handoff (reads all 4 results → ship decision)
|
|
117
134
|
│ └── writes: ### Review: Final (decision, issues, concerns)
|
|
118
135
|
│
|
|
119
|
-
├── Agent: Deploy (single agent, all 3
|
|
136
|
+
├── Agent: Deploy (single agent, all 3 steps)
|
|
120
137
|
│ ├── reads: ### Review: Final, ### Build: Final
|
|
121
138
|
│ ├── runs: Merge → Monitor → Remediate
|
|
122
139
|
│ └── writes: ### Deploy: Final (merge/deploy status)
|
|
@@ -145,7 +162,7 @@ Orchestrator (main agent — you)
|
|
|
145
162
|
|
|
146
163
|
### Phase Handoff via Final Sections
|
|
147
164
|
|
|
148
|
-
Each phase writes a `### <Phase>: Final` section — a self-contained summary of that phase's output. The next phase's agent reads **only** the Final sections it needs, not the
|
|
165
|
+
Each phase writes a `### <Phase>: Final` section — a self-contained summary of that phase's output. The next phase's agent reads **only** the Final sections it needs, not the step working notes.
|
|
149
166
|
|
|
150
167
|
```
|
|
151
168
|
state.md grows like this:
|
|
@@ -168,14 +185,14 @@ state.md grows like this:
|
|
|
168
185
|
For each phase:
|
|
169
186
|
1. **Check prerequisites** — verify the required prior phase is marked complete in state.md
|
|
170
187
|
2. **Spawn a fresh agent** for the phase — pass it the phase skill file and the relevant Final sections from state.md
|
|
171
|
-
3. The agent reads each
|
|
172
|
-
4. The agent updates `.work-kit/state.md` after each
|
|
188
|
+
3. The agent reads each step file when directed (e.g., `.claude/skills/wk-plan/steps/clarify.md`)
|
|
189
|
+
4. The agent updates `.work-kit/state.md` after each step completes
|
|
173
190
|
5. The agent writes the `### <Phase>: Final` section before exiting
|
|
174
191
|
6. After the agent completes, summarize results to the user and wait for confirmation
|
|
175
192
|
|
|
176
193
|
## Loop-Back Rules
|
|
177
194
|
|
|
178
|
-
Some
|
|
195
|
+
Some steps can route backwards based on their outcome:
|
|
179
196
|
|
|
180
197
|
- **Plan Audit** → "revise" → re-run Blueprint
|
|
181
198
|
- **Build Refactor** → "broken" → re-run Core
|
|
@@ -183,7 +200,7 @@ Some sub-stages can route backwards based on their outcome:
|
|
|
183
200
|
- **Deploy Merge** → "fix_needed" → re-run Build (from Core)
|
|
184
201
|
- **Deploy Remediate** → "fix_and_redeploy" → re-run Build (from Core)
|
|
185
202
|
|
|
186
|
-
On loop-back: add a `## Loop-back context` section to state.md with what needs to change and why, then resume at the target
|
|
203
|
+
On loop-back: add a `## Loop-back context` section to state.md with what needs to change and why, then resume at the target step.
|
|
187
204
|
|
|
188
205
|
## Completion
|
|
189
206
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pause-kit
|
|
3
|
+
description: "Pause the active work-kit session. Use when stepping away mid-flight. Usage: /pause-kit [reason]"
|
|
4
|
+
user-invocable: true
|
|
5
|
+
argument-hint: "[reason]"
|
|
6
|
+
allowed-tools: Bash, Read
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
You are pausing the active work-kit session so it can be resumed cleanly later.
|
|
10
|
+
|
|
11
|
+
## Steps
|
|
12
|
+
|
|
13
|
+
1. Run `work-kit bootstrap` to confirm a session is active. If no session is active, tell the user there is nothing to pause and stop.
|
|
14
|
+
2. `cd` into the worktree path reported by bootstrap.
|
|
15
|
+
3. Run:
|
|
16
|
+
```bash
|
|
17
|
+
work-kit pause${ARGUMENTS:+ --reason "$ARGUMENTS"}
|
|
18
|
+
```
|
|
19
|
+
4. Parse the JSON response.
|
|
20
|
+
5. Report the message to the user. Tell them they can run `/resume-kit` (or `work-kit resume`) when ready.
|
|
21
|
+
|
|
22
|
+
## Notes
|
|
23
|
+
|
|
24
|
+
- Pausing only flips state to `paused` and records `pausedAt` — no files are deleted, no git operations happen.
|
|
25
|
+
- The orchestrator (`/full-kit`, `/auto-kit`) refuses to advance a paused session until it is resumed.
|