@abdullahsahmad/work-kit 0.1.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 +147 -0
- package/cli/bin/work-kit.mjs +18 -0
- package/cli/src/commands/complete.ts +123 -0
- package/cli/src/commands/completions.ts +137 -0
- package/cli/src/commands/context.ts +41 -0
- package/cli/src/commands/doctor.ts +79 -0
- package/cli/src/commands/init.test.ts +116 -0
- package/cli/src/commands/init.ts +184 -0
- package/cli/src/commands/loopback.ts +64 -0
- package/cli/src/commands/next.ts +172 -0
- package/cli/src/commands/observe.ts +144 -0
- package/cli/src/commands/setup.ts +159 -0
- package/cli/src/commands/status.ts +50 -0
- package/cli/src/commands/uninstall.ts +89 -0
- package/cli/src/commands/upgrade.ts +12 -0
- package/cli/src/commands/validate.ts +34 -0
- package/cli/src/commands/workflow.ts +125 -0
- package/cli/src/config/agent-map.ts +62 -0
- package/cli/src/config/loopback-routes.ts +45 -0
- package/cli/src/config/phases.ts +119 -0
- package/cli/src/context/extractor.test.ts +77 -0
- package/cli/src/context/extractor.ts +73 -0
- package/cli/src/context/prompt-builder.ts +70 -0
- package/cli/src/engine/loopbacks.test.ts +33 -0
- package/cli/src/engine/loopbacks.ts +32 -0
- package/cli/src/engine/parallel.ts +60 -0
- package/cli/src/engine/phases.ts +23 -0
- package/cli/src/engine/transitions.test.ts +117 -0
- package/cli/src/engine/transitions.ts +97 -0
- package/cli/src/index.ts +248 -0
- package/cli/src/observer/data.ts +237 -0
- package/cli/src/observer/renderer.ts +316 -0
- package/cli/src/observer/watcher.ts +99 -0
- package/cli/src/state/helpers.test.ts +91 -0
- package/cli/src/state/helpers.ts +65 -0
- package/cli/src/state/schema.ts +113 -0
- package/cli/src/state/store.ts +82 -0
- package/cli/src/state/validators.test.ts +105 -0
- package/cli/src/state/validators.ts +81 -0
- package/cli/src/utils/colors.ts +12 -0
- package/package.json +49 -0
- package/skills/auto-kit/SKILL.md +214 -0
- package/skills/build/SKILL.md +88 -0
- package/skills/build/stages/commit.md +43 -0
- package/skills/build/stages/core.md +48 -0
- package/skills/build/stages/integration.md +44 -0
- package/skills/build/stages/migration.md +41 -0
- package/skills/build/stages/red.md +44 -0
- package/skills/build/stages/refactor.md +48 -0
- package/skills/build/stages/setup.md +42 -0
- package/skills/build/stages/ui.md +51 -0
- package/skills/deploy/SKILL.md +62 -0
- package/skills/deploy/stages/merge.md +47 -0
- package/skills/deploy/stages/monitor.md +39 -0
- package/skills/deploy/stages/remediate.md +54 -0
- package/skills/full-kit/SKILL.md +195 -0
- package/skills/plan/SKILL.md +77 -0
- package/skills/plan/stages/architecture.md +53 -0
- package/skills/plan/stages/audit.md +58 -0
- package/skills/plan/stages/blueprint.md +60 -0
- package/skills/plan/stages/clarify.md +61 -0
- package/skills/plan/stages/investigate.md +47 -0
- package/skills/plan/stages/scope.md +46 -0
- package/skills/plan/stages/sketch.md +44 -0
- package/skills/plan/stages/ux-flow.md +49 -0
- package/skills/review/SKILL.md +104 -0
- package/skills/review/stages/compliance.md +48 -0
- package/skills/review/stages/handoff.md +59 -0
- package/skills/review/stages/performance.md +45 -0
- package/skills/review/stages/security.md +49 -0
- package/skills/review/stages/self-review.md +41 -0
- package/skills/test/SKILL.md +83 -0
- package/skills/test/stages/e2e.md +44 -0
- package/skills/test/stages/validate.md +51 -0
- package/skills/test/stages/verify.md +41 -0
- package/skills/wrap-up/SKILL.md +107 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { randomUUID } from "node:crypto";
|
|
4
|
+
import { WorkKitState } from "./schema.js";
|
|
5
|
+
|
|
6
|
+
const STATE_DIR = ".work-kit";
|
|
7
|
+
const STATE_FILE = "state.json";
|
|
8
|
+
|
|
9
|
+
// ── Worktree Discovery ───────────────────────────────────────────────
|
|
10
|
+
|
|
11
|
+
export function findWorktreeRoot(startDir?: string): string | null {
|
|
12
|
+
let dir = startDir || process.cwd();
|
|
13
|
+
while (true) {
|
|
14
|
+
if (fs.existsSync(path.join(dir, STATE_DIR, STATE_FILE))) {
|
|
15
|
+
return dir;
|
|
16
|
+
}
|
|
17
|
+
const parent = path.dirname(dir);
|
|
18
|
+
if (parent === dir) return null;
|
|
19
|
+
dir = parent;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function stateDir(worktreeRoot: string): string {
|
|
24
|
+
return path.join(worktreeRoot, STATE_DIR);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function statePath(worktreeRoot: string): string {
|
|
28
|
+
return path.join(worktreeRoot, STATE_DIR, STATE_FILE);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function stateMdPath(worktreeRoot: string): string {
|
|
32
|
+
return path.join(worktreeRoot, STATE_DIR, "state.md");
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// ── Read / Write ─────────────────────────────────────────────────────
|
|
36
|
+
|
|
37
|
+
export function stateExists(worktreeRoot: string): boolean {
|
|
38
|
+
return fs.existsSync(statePath(worktreeRoot));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function readState(worktreeRoot: string): WorkKitState {
|
|
42
|
+
const filePath = statePath(worktreeRoot);
|
|
43
|
+
if (!fs.existsSync(filePath)) {
|
|
44
|
+
throw new Error(`No state.json found at ${filePath}`);
|
|
45
|
+
}
|
|
46
|
+
const raw = fs.readFileSync(filePath, "utf-8");
|
|
47
|
+
try {
|
|
48
|
+
return JSON.parse(raw) as WorkKitState;
|
|
49
|
+
} catch {
|
|
50
|
+
throw new Error(`Corrupted state.json at ${filePath}. File contains invalid JSON.`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function writeState(worktreeRoot: string, state: WorkKitState): void {
|
|
55
|
+
const dir = stateDir(worktreeRoot);
|
|
56
|
+
if (!fs.existsSync(dir)) {
|
|
57
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
58
|
+
}
|
|
59
|
+
const target = statePath(worktreeRoot);
|
|
60
|
+
const tmp = target + "." + randomUUID().slice(0, 8) + ".tmp";
|
|
61
|
+
fs.writeFileSync(tmp, JSON.stringify(state, null, 2) + "\n", "utf-8");
|
|
62
|
+
fs.renameSync(tmp, target);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// ── State.md ─────────────────────────────────────────────────────────
|
|
66
|
+
|
|
67
|
+
export function writeStateMd(worktreeRoot: string, content: string): void {
|
|
68
|
+
const dir = stateDir(worktreeRoot);
|
|
69
|
+
if (!fs.existsSync(dir)) {
|
|
70
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
71
|
+
}
|
|
72
|
+
const target = stateMdPath(worktreeRoot);
|
|
73
|
+
const tmp = target + "." + randomUUID().slice(0, 8) + ".tmp";
|
|
74
|
+
fs.writeFileSync(tmp, content, "utf-8");
|
|
75
|
+
fs.renameSync(tmp, target);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function readStateMd(worktreeRoot: string): string | null {
|
|
79
|
+
const filePath = stateMdPath(worktreeRoot);
|
|
80
|
+
if (!fs.existsSync(filePath)) return null;
|
|
81
|
+
return fs.readFileSync(filePath, "utf-8");
|
|
82
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { describe, it } from "node:test";
|
|
2
|
+
import * as assert from "node:assert/strict";
|
|
3
|
+
import { validatePhasePrerequisites } from "./validators.js";
|
|
4
|
+
import type { WorkKitState, PhaseName, PhaseState, SubStageState } from "./schema.js";
|
|
5
|
+
import { PHASE_NAMES, SUBSTAGES_BY_PHASE } from "./schema.js";
|
|
6
|
+
|
|
7
|
+
function makeState(): WorkKitState {
|
|
8
|
+
const phases = {} as Record<PhaseName, PhaseState>;
|
|
9
|
+
for (const phase of PHASE_NAMES) {
|
|
10
|
+
const subStages: Record<string, SubStageState> = {};
|
|
11
|
+
for (const ss of SUBSTAGES_BY_PHASE[phase]) {
|
|
12
|
+
subStages[ss] = { status: "pending" };
|
|
13
|
+
}
|
|
14
|
+
phases[phase] = { status: "pending", subStages };
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
version: 1,
|
|
18
|
+
slug: "test",
|
|
19
|
+
branch: "feature/test",
|
|
20
|
+
started: "2026-01-01",
|
|
21
|
+
mode: "full-kit",
|
|
22
|
+
status: "in-progress",
|
|
23
|
+
currentPhase: "plan",
|
|
24
|
+
currentSubStage: "clarify",
|
|
25
|
+
phases,
|
|
26
|
+
loopbacks: [],
|
|
27
|
+
metadata: { worktreeRoot: "/tmp/test", mainRepoRoot: "/tmp/test" },
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function completePhase(state: WorkKitState, phase: PhaseName): void {
|
|
32
|
+
state.phases[phase].status = "completed";
|
|
33
|
+
state.phases[phase].completedAt = "2026-01-01";
|
|
34
|
+
for (const ss of Object.values(state.phases[phase].subStages)) {
|
|
35
|
+
ss.status = "completed";
|
|
36
|
+
ss.completedAt = "2026-01-01";
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
describe("validatePhasePrerequisites", () => {
|
|
41
|
+
it("plan has no prerequisites — valid", () => {
|
|
42
|
+
const state = makeState();
|
|
43
|
+
const result = validatePhasePrerequisites(state, "plan");
|
|
44
|
+
assert.equal(result.valid, true);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("build with plan incomplete — invalid", () => {
|
|
48
|
+
const state = makeState();
|
|
49
|
+
const result = validatePhasePrerequisites(state, "build");
|
|
50
|
+
assert.equal(result.valid, false);
|
|
51
|
+
assert.equal(result.missingPrerequisite, "plan");
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("build with plan complete — valid", () => {
|
|
55
|
+
const state = makeState();
|
|
56
|
+
completePhase(state, "plan");
|
|
57
|
+
const result = validatePhasePrerequisites(state, "build");
|
|
58
|
+
assert.equal(result.valid, true);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it("deploy with review complete but handoff not approved — invalid", () => {
|
|
62
|
+
const state = makeState();
|
|
63
|
+
completePhase(state, "plan");
|
|
64
|
+
completePhase(state, "build");
|
|
65
|
+
completePhase(state, "test");
|
|
66
|
+
completePhase(state, "review");
|
|
67
|
+
// handoff completed but without "approved" outcome
|
|
68
|
+
state.phases.review.subStages.handoff.outcome = "pending_review";
|
|
69
|
+
const result = validatePhasePrerequisites(state, "deploy");
|
|
70
|
+
assert.equal(result.valid, false);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it("deploy with review complete and handoff approved — valid", () => {
|
|
74
|
+
const state = makeState();
|
|
75
|
+
completePhase(state, "plan");
|
|
76
|
+
completePhase(state, "build");
|
|
77
|
+
completePhase(state, "test");
|
|
78
|
+
completePhase(state, "review");
|
|
79
|
+
state.phases.review.subStages.handoff.outcome = "approved";
|
|
80
|
+
const result = validatePhasePrerequisites(state, "deploy");
|
|
81
|
+
assert.equal(result.valid, true);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it("wrap-up with review complete — valid", () => {
|
|
85
|
+
const state = makeState();
|
|
86
|
+
completePhase(state, "plan");
|
|
87
|
+
completePhase(state, "build");
|
|
88
|
+
completePhase(state, "test");
|
|
89
|
+
completePhase(state, "review");
|
|
90
|
+
const result = validatePhasePrerequisites(state, "wrap-up");
|
|
91
|
+
assert.equal(result.valid, true);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it("wrap-up with deploy in-progress — invalid", () => {
|
|
95
|
+
const state = makeState();
|
|
96
|
+
completePhase(state, "plan");
|
|
97
|
+
completePhase(state, "build");
|
|
98
|
+
completePhase(state, "test");
|
|
99
|
+
completePhase(state, "review");
|
|
100
|
+
state.phases.deploy.status = "in-progress";
|
|
101
|
+
const result = validatePhasePrerequisites(state, "wrap-up");
|
|
102
|
+
assert.equal(result.valid, false);
|
|
103
|
+
assert.equal(result.missingPrerequisite, "deploy");
|
|
104
|
+
});
|
|
105
|
+
});
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { WorkKitState, PhaseName } from "./schema.js";
|
|
2
|
+
import { PHASE_PREREQUISITES } from "../config/phases.js";
|
|
3
|
+
|
|
4
|
+
export interface ValidationResult {
|
|
5
|
+
valid: boolean;
|
|
6
|
+
message: string;
|
|
7
|
+
missingPrerequisite?: PhaseName;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function validatePhasePrerequisites(state: WorkKitState, phase: PhaseName): ValidationResult {
|
|
11
|
+
const prereq = PHASE_PREREQUISITES[phase];
|
|
12
|
+
|
|
13
|
+
if (!prereq) {
|
|
14
|
+
return { valid: true, message: `${phase} has no prerequisites` };
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Special case: wrap-up can proceed after review OR deploy
|
|
18
|
+
if (phase === "wrap-up") {
|
|
19
|
+
const reviewDone = state.phases.review.status === "completed";
|
|
20
|
+
const deployStatus = state.phases.deploy.status;
|
|
21
|
+
|
|
22
|
+
if (!reviewDone) {
|
|
23
|
+
return {
|
|
24
|
+
valid: false,
|
|
25
|
+
message: `wrap-up requires review to be complete. Current: ${state.phases.review.status}`,
|
|
26
|
+
missingPrerequisite: "review",
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (deployStatus === "in-progress") {
|
|
31
|
+
return {
|
|
32
|
+
valid: false,
|
|
33
|
+
message: `wrap-up requires deploy to finish first. Current: ${deployStatus}`,
|
|
34
|
+
missingPrerequisite: "deploy",
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// deploy completed, skipped, or pending (never started) — all ok if review is done
|
|
39
|
+
return { valid: true, message: "Prerequisites met for wrap-up" };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Special case: deploy requires review complete AND handoff approved
|
|
43
|
+
if (phase === "deploy") {
|
|
44
|
+
const reviewState = state.phases.review;
|
|
45
|
+
if (reviewState.status !== "completed") {
|
|
46
|
+
return {
|
|
47
|
+
valid: false,
|
|
48
|
+
message: `deploy requires review to be complete. Current: ${reviewState.status}`,
|
|
49
|
+
missingPrerequisite: "review",
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
const handoff = reviewState.subStages["handoff"];
|
|
53
|
+
if (!handoff) {
|
|
54
|
+
return {
|
|
55
|
+
valid: false,
|
|
56
|
+
message: `deploy requires review/handoff to exist and be approved. Handoff sub-stage not found.`,
|
|
57
|
+
missingPrerequisite: "review",
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
if (handoff.outcome !== "approved") {
|
|
61
|
+
return {
|
|
62
|
+
valid: false,
|
|
63
|
+
message: `deploy requires review/handoff outcome to be "approved". Current: ${handoff.outcome || "none"}`,
|
|
64
|
+
missingPrerequisite: "review",
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
return { valid: true, message: "Prerequisites met for deploy" };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// General case
|
|
71
|
+
const prereqState = state.phases[prereq];
|
|
72
|
+
if (prereqState.status !== "completed") {
|
|
73
|
+
return {
|
|
74
|
+
valid: false,
|
|
75
|
+
message: `${phase} requires ${prereq} to be complete. Current: ${prereqState.status}`,
|
|
76
|
+
missingPrerequisite: prereq,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return { valid: true, message: `Prerequisites met for ${phase}` };
|
|
81
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const enabled = process.stdout.isTTY !== false && process.env.NO_COLOR === undefined;
|
|
2
|
+
|
|
3
|
+
const code = (n: number) => enabled ? `\x1b[${n}m` : "";
|
|
4
|
+
const reset = code(0);
|
|
5
|
+
|
|
6
|
+
export const bold = (s: string) => `${code(1)}${s}${reset}`;
|
|
7
|
+
export const dim = (s: string) => `${code(2)}${s}${reset}`;
|
|
8
|
+
export const green = (s: string) => `${code(32)}${s}${reset}`;
|
|
9
|
+
export const yellow = (s: string) => `${code(33)}${s}${reset}`;
|
|
10
|
+
export const red = (s: string) => `${code(31)}${s}${reset}`;
|
|
11
|
+
export const cyan = (s: string) => `${code(36)}${s}${reset}`;
|
|
12
|
+
export const bgYellow = (s: string) => `${code(43)}${code(30)}${s}${reset}`;
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@abdullahsahmad/work-kit",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Structured development workflow for Claude Code. Two modes, 6 phases, 27 sub-stages.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"work-kit": "cli/bin/work-kit.mjs"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"cli/bin/",
|
|
11
|
+
"cli/src/",
|
|
12
|
+
"skills/"
|
|
13
|
+
],
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=18.0.0"
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"start": "tsx cli/src/index.ts",
|
|
19
|
+
"doctor": "tsx cli/src/index.ts doctor",
|
|
20
|
+
"setup": "tsx cli/src/index.ts setup",
|
|
21
|
+
"build": "tsc --project cli/tsconfig.json",
|
|
22
|
+
"typecheck": "tsc --project cli/tsconfig.json --noEmit",
|
|
23
|
+
"test": "tsx --test cli/src/**/*.test.ts"
|
|
24
|
+
},
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "git+https://github.com/AbdullahSAhmad/work-kit.git"
|
|
28
|
+
},
|
|
29
|
+
"keywords": [
|
|
30
|
+
"claude-code",
|
|
31
|
+
"workflow",
|
|
32
|
+
"skills",
|
|
33
|
+
"development"
|
|
34
|
+
],
|
|
35
|
+
"author": "Abdullah Ahmad",
|
|
36
|
+
"license": "ISC",
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"commander": "^13.1.0",
|
|
39
|
+
"tsx": "^4.19.4"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@types/node": "^22.15.2",
|
|
43
|
+
"typescript": "^5.8.3"
|
|
44
|
+
},
|
|
45
|
+
"bugs": {
|
|
46
|
+
"url": "https://github.com/AbdullahSAhmad/work-kit/issues"
|
|
47
|
+
},
|
|
48
|
+
"homepage": "https://github.com/AbdullahSAhmad/work-kit#readme"
|
|
49
|
+
}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: auto-kit
|
|
3
|
+
description: "Smart pipeline that analyzes the request and builds a dynamic workflow. Usage: /auto-kit <description> to start, /auto-kit to continue."
|
|
4
|
+
user-invocable: true
|
|
5
|
+
argument-hint: "[description]"
|
|
6
|
+
allowed-tools: Agent, Bash, Read, Write, Edit, Glob, Grep
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
You are the **Work Orchestrator (Auto Mode)**. You analyze the request first, then build a tailored workflow with only the phases and sub-stages that are actually needed.
|
|
10
|
+
|
|
11
|
+
Best for: bug fixes, small changes, refactors, or well-understood tasks.
|
|
12
|
+
|
|
13
|
+
## Prerequisites
|
|
14
|
+
|
|
15
|
+
Before starting, verify the CLI is installed:
|
|
16
|
+
```bash
|
|
17
|
+
npx work-kit doctor
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
If `work-kit` is not found, ask the user to install it:
|
|
21
|
+
> work-kit CLI is required but not installed. Install it with: `npm install -g work-kit-cli`
|
|
22
|
+
|
|
23
|
+
Do not proceed until `doctor` reports all checks passed.
|
|
24
|
+
|
|
25
|
+
## All Available Sub-stages
|
|
26
|
+
|
|
27
|
+
These are the building blocks you pick from:
|
|
28
|
+
|
|
29
|
+
- **Plan:** Clarify, Investigate, Sketch, Scope, UX Flow, Architecture, Blueprint, Audit
|
|
30
|
+
- **Build:** Setup, Migration, Red, Core, UI, Refactor, Integration, Commit
|
|
31
|
+
- **Test:** Verify, E2E, Validate
|
|
32
|
+
- **Review:** Self-Review, Security, Performance, Compliance, Handoff
|
|
33
|
+
- **Deploy:** Merge, Monitor, Remediate (optional)
|
|
34
|
+
- **Wrap-up**
|
|
35
|
+
|
|
36
|
+
## Starting New Work (`/auto-kit <description>`)
|
|
37
|
+
|
|
38
|
+
### Step 1: Analyze
|
|
39
|
+
|
|
40
|
+
Before creating the worktree, perform a quick analysis:
|
|
41
|
+
|
|
42
|
+
1. **Read the description** — understand the type of work
|
|
43
|
+
2. **Classify the work** into one of these categories:
|
|
44
|
+
- **bug-fix** — fixing broken behavior
|
|
45
|
+
- **small-change** — config tweak, copy change, minor adjustment
|
|
46
|
+
- **refactor** — restructuring without behavior change
|
|
47
|
+
- **feature** — new capability (small to medium scope)
|
|
48
|
+
- **large-feature** — new capability (large scope, multiple systems)
|
|
49
|
+
3. **Scan the codebase** — quick look at affected areas (not a full investigation)
|
|
50
|
+
4. **Build the workflow** — select only the sub-stages needed
|
|
51
|
+
|
|
52
|
+
### Step 2: Build Dynamic Workflow
|
|
53
|
+
|
|
54
|
+
Based on the classification, select sub-stages. Use this table as a starting point, then adjust based on the specific request:
|
|
55
|
+
|
|
56
|
+
| Sub-stage | bug-fix | small-change | refactor | feature | large-feature |
|
|
57
|
+
|------------------------|---------|--------------|----------|---------|---------------|
|
|
58
|
+
| **Plan: Clarify** | YES | YES | YES | YES | YES |
|
|
59
|
+
| **Plan: Investigate** | YES | skip | YES | YES | YES |
|
|
60
|
+
| **Plan: Sketch** | skip | skip | skip | YES | YES |
|
|
61
|
+
| **Plan: Scope** | skip | skip | skip | YES | YES |
|
|
62
|
+
| **Plan: UX Flow** | skip | skip | skip | if UI | if UI |
|
|
63
|
+
| **Plan: Architecture** | skip | skip | skip | YES | YES |
|
|
64
|
+
| **Plan: Blueprint** | skip | skip | skip | YES | YES |
|
|
65
|
+
| **Plan: Audit** | skip | skip | skip | skip | YES |
|
|
66
|
+
| **Build: Setup** | skip | skip | skip | YES | YES |
|
|
67
|
+
| **Build: Migration** | skip | skip | skip | if DB | if DB |
|
|
68
|
+
| **Build: Red** | YES | skip | skip | YES | YES |
|
|
69
|
+
| **Build: Core** | YES | YES | YES | YES | YES |
|
|
70
|
+
| **Build: UI** | if UI | if UI | if UI | if UI | if UI |
|
|
71
|
+
| **Build: Refactor** | skip | skip | YES | skip | YES |
|
|
72
|
+
| **Build: Integration** | skip | skip | skip | YES | YES |
|
|
73
|
+
| **Build: Commit** | YES | YES | YES | YES | YES |
|
|
74
|
+
| **Test: Verify** | YES | YES | YES | YES | YES |
|
|
75
|
+
| **Test: E2E** | skip | skip | skip | if UI | YES |
|
|
76
|
+
| **Test: Validate** | YES | skip | skip | YES | YES |
|
|
77
|
+
| **Review: Self-Review**| YES | YES | YES | YES | YES |
|
|
78
|
+
| **Review: Security** | skip | skip | skip | YES | YES |
|
|
79
|
+
| **Review: Performance**| skip | skip | YES | skip | YES |
|
|
80
|
+
| **Review: Compliance** | skip | skip | skip | YES | YES |
|
|
81
|
+
| **Review: Handoff** | YES | YES | YES | YES | YES |
|
|
82
|
+
| **Deploy** | optional| optional | optional | optional| optional |
|
|
83
|
+
| **Wrap-up** | YES | YES | YES | YES | YES |
|
|
84
|
+
|
|
85
|
+
The table is a guide, not a rigid rule. Adjust based on the actual request:
|
|
86
|
+
- A bug fix that touches auth → add Security review
|
|
87
|
+
- A refactor that changes DB queries → add Migration, Performance review
|
|
88
|
+
- A small-change that affects public API → add Investigate, Blueprint
|
|
89
|
+
|
|
90
|
+
### Step 3: Initialize
|
|
91
|
+
|
|
92
|
+
1. Create a git worktree and initialize state with the CLI:
|
|
93
|
+
```bash
|
|
94
|
+
git worktree add worktrees/<slug> -b feature/<slug>
|
|
95
|
+
cd worktrees/<slug>
|
|
96
|
+
npx work-kit init --mode auto --description "<description>" --classification <classification>
|
|
97
|
+
```
|
|
98
|
+
2. Show the workflow to the user: `npx work-kit workflow`
|
|
99
|
+
3. User can adjust: `npx work-kit workflow --add review/security` or `npx work-kit workflow --remove test/e2e`
|
|
100
|
+
4. **Wait for approval** — user can add/remove steps before proceeding
|
|
101
|
+
5. Once approved, start the execution loop
|
|
102
|
+
|
|
103
|
+
## Continuing Work (`/auto-kit` with no args)
|
|
104
|
+
|
|
105
|
+
1. Find the active worktree — check `git worktree list` or look for `.work-kit/state.md`
|
|
106
|
+
2. Run `npx work-kit status` to see current state
|
|
107
|
+
3. Run `npx work-kit next` to get the next action
|
|
108
|
+
4. Follow the execution loop below
|
|
109
|
+
|
|
110
|
+
## Step Validation
|
|
111
|
+
|
|
112
|
+
All validation is handled by the CLI. The `next` command enforces order, phase boundaries, and prerequisites automatically.
|
|
113
|
+
|
|
114
|
+
To add/remove steps mid-work: `npx work-kit workflow --add <phase/sub-stage>` or `--remove <phase/sub-stage>`. Completed steps cannot be removed.
|
|
115
|
+
|
|
116
|
+
## Agent Architecture
|
|
117
|
+
|
|
118
|
+
Same as full-kit: each phase runs as a **fresh agent** to keep context focused. The difference is that each agent only runs the sub-stages in the `## Workflow` checklist.
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
Orchestrator (main agent — you)
|
|
122
|
+
│
|
|
123
|
+
├── Agent: Plan (runs only Plan steps from Workflow)
|
|
124
|
+
│ ├── reads: ## Description, ## Criteria, codebase
|
|
125
|
+
│ └── writes: ### Plan: Final
|
|
126
|
+
│
|
|
127
|
+
├── Agent: Build (runs only Build steps from Workflow)
|
|
128
|
+
│ ├── reads: ### Plan: Final, ## Criteria
|
|
129
|
+
│ └── writes: ### Build: Final
|
|
130
|
+
│
|
|
131
|
+
├── Agent: Test (runs only Test steps from Workflow)
|
|
132
|
+
│ ├── reads: ### Build: Final, ### Plan: Final, ## Criteria
|
|
133
|
+
│ ├── Verify + E2E as parallel sub-agents (if both in workflow)
|
|
134
|
+
│ ├── then Validate (if in workflow)
|
|
135
|
+
│ └── writes: ### Test: Final
|
|
136
|
+
│
|
|
137
|
+
├── Agent: Review (runs only Review steps from Workflow)
|
|
138
|
+
│ ├── reads: ### Plan: Final, ### Build: Final, ### Test: Final, ## Criteria
|
|
139
|
+
│ ├── Self-Review, Security, Performance, Compliance as parallel sub-agents (whichever are in workflow)
|
|
140
|
+
│ ├── then Handoff
|
|
141
|
+
│ └── writes: ### Review: Final
|
|
142
|
+
│
|
|
143
|
+
├── Agent: Deploy (if in workflow)
|
|
144
|
+
│ ├── reads: ### Review: Final, ### Build: Final
|
|
145
|
+
│ └── writes: ### Deploy: Final
|
|
146
|
+
│
|
|
147
|
+
└── Agent: Wrap-up
|
|
148
|
+
├── reads: full state.md
|
|
149
|
+
└── writes: summary + archive
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Agent Spawn Rules
|
|
153
|
+
|
|
154
|
+
| Phase | Agent type | What it reads from state.md |
|
|
155
|
+
|-------|-----------|----------------------------|
|
|
156
|
+
| Plan | Single agent | `## Description`, `## Criteria`, codebase |
|
|
157
|
+
| Build | Single agent | `### Plan: Final`, `## Criteria` |
|
|
158
|
+
| Test: Verify | Sub-agent (parallel) | `### Build: Final`, `## Criteria` |
|
|
159
|
+
| Test: E2E | Sub-agent (parallel) | `### Build: Final`, `### Plan: Final` |
|
|
160
|
+
| Test: Validate | Sequential after above | `### Test: Verify`, `### Test: E2E`, `## Criteria` |
|
|
161
|
+
| Review: Self-Review | Sub-agent (parallel) | `### Build: Final`, git diff |
|
|
162
|
+
| Review: Security | Sub-agent (parallel) | `### Build: Final`, git diff |
|
|
163
|
+
| Review: Performance | Sub-agent (parallel) | `### Build: Final`, git diff |
|
|
164
|
+
| Review: Compliance | Sub-agent (parallel) | `### Plan: Final`, `### Build: Final`, git diff |
|
|
165
|
+
| Review: Handoff | Sequential after above | All `### Review:` sections, `### Test: Final`, `## Criteria` |
|
|
166
|
+
| Deploy | Single agent | `### Review: Final`, `### Build: Final` |
|
|
167
|
+
| Wrap-up | Single agent | Full state.md |
|
|
168
|
+
|
|
169
|
+
### Phase Handoff via Final Sections
|
|
170
|
+
|
|
171
|
+
Each phase writes a `### <Phase>: Final` section — a self-contained summary. The next agent reads **only** the Final sections it needs.
|
|
172
|
+
|
|
173
|
+
If a phase has fewer sub-stages in the workflow, the Final section still covers the same output — just with less detail where sub-stages were skipped.
|
|
174
|
+
|
|
175
|
+
## Execution Loop
|
|
176
|
+
|
|
177
|
+
The CLI manages all state transitions, prerequisites, and loopbacks. Follow this loop:
|
|
178
|
+
|
|
179
|
+
1. Run `npx work-kit next` to get the next action
|
|
180
|
+
2. Parse the JSON response
|
|
181
|
+
3. Follow the action type:
|
|
182
|
+
- **`spawn_agent`**: Use the Agent tool with the provided `agentPrompt`. Pass `skillFile` path for reference. After the agent completes: `npx work-kit complete <phase>/<sub-stage> --outcome <outcome>`
|
|
183
|
+
- **`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: `npx work-kit complete <onComplete target>`
|
|
184
|
+
- **`wait_for_user`**: Report the message to the user and stop. Wait for them to say "proceed" before running `npx work-kit next` again.
|
|
185
|
+
- **`loopback`**: Report the loopback to the user, then run `npx work-kit next` to continue from the target.
|
|
186
|
+
- **`complete`**: Done — run wrap-up if not already done.
|
|
187
|
+
- **`error`**: Report the error and suggestion to the user. Stop.
|
|
188
|
+
4. After each agent completes: `npx work-kit complete <phase>/<sub-stage> --outcome <outcome>`
|
|
189
|
+
5. Then `npx work-kit next` again to continue
|
|
190
|
+
|
|
191
|
+
## Loop-Back Rules
|
|
192
|
+
|
|
193
|
+
Loop-backs only apply if the relevant step is in the workflow:
|
|
194
|
+
|
|
195
|
+
- **Plan Audit** → "revise" → re-run Blueprint
|
|
196
|
+
- **Build Refactor** → "broken" → re-run Core
|
|
197
|
+
- **Review Handoff** → "changes_requested" → re-run Build (from Core)
|
|
198
|
+
- **Deploy Merge** → "fix_needed" → re-run Build (from Core)
|
|
199
|
+
- **Deploy Remediate** → "fix_and_redeploy" → re-run Build (from Core)
|
|
200
|
+
|
|
201
|
+
On loop-back: uncheck the target step and any steps after it that need re-running. Add a `## Loop-back context` section to state.md with what needs to change and why.
|
|
202
|
+
|
|
203
|
+
## Completion
|
|
204
|
+
|
|
205
|
+
When all steps in `## Workflow` are checked:
|
|
206
|
+
|
|
207
|
+
Run **Wrap-up** — read `.claude/skills/wrap-up.md` and follow its instructions. It handles writing the work-kit summary, committing it, and cleaning up the worktree.
|
|
208
|
+
|
|
209
|
+
## Important
|
|
210
|
+
|
|
211
|
+
- **Always work inside the worktree directory** — `cd worktrees/<slug>` before running any commands
|
|
212
|
+
- **Commit state after each phase boundary** — `git add .work-kit/ && git commit -m "work-kit: complete <phase>"`
|
|
213
|
+
- **Human stays in control** — stop between phases, don't auto-proceed
|
|
214
|
+
- **One feature per session** — each session handles a single feature. To work on multiple features in parallel, use separate terminal sessions
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: build
|
|
3
|
+
description: "Run the Build phase — 8 sub-stages from Setup to Commit. Follows the Blueprint from Plan."
|
|
4
|
+
user-invocable: false
|
|
5
|
+
allowed-tools: Bash, Read, Write, Edit, Glob, Grep
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
You are the **Lead Developer**. Execute the implementation plan from the Blueprint precisely.
|
|
9
|
+
|
|
10
|
+
## Sub-stages (in order)
|
|
11
|
+
|
|
12
|
+
1. **Setup** — Create branch, install deps, scaffold
|
|
13
|
+
2. **Migration** — Database schema changes
|
|
14
|
+
3. **Red** — Write failing tests first (TDD red phase)
|
|
15
|
+
4. **Core** — Make tests pass — service layer, API, business logic (TDD green phase)
|
|
16
|
+
5. **UI** — Components, pages, interactions
|
|
17
|
+
6. **Refactor** — Improve code quality, keep tests green (TDD refactor phase)
|
|
18
|
+
7. **Integration** — Wire everything together, verify full data flow
|
|
19
|
+
8. **Commit** — Clean commits, push branch, create PR
|
|
20
|
+
|
|
21
|
+
## Execution
|
|
22
|
+
|
|
23
|
+
For each sub-stage:
|
|
24
|
+
1. Read the sub-stage file (e.g., `.claude/skills/build/stages/setup.md`)
|
|
25
|
+
2. Reference the Blueprint in `.work-kit/state.md` — follow its steps for this layer
|
|
26
|
+
3. Write actual code, run actual commands
|
|
27
|
+
4. Update `.work-kit/state.md` with outputs
|
|
28
|
+
5. Proceed to the next sub-stage
|
|
29
|
+
|
|
30
|
+
## Key Principle
|
|
31
|
+
|
|
32
|
+
**Follow the Blueprint.** The Plan phase already decided what to build and how. Your job is execution, not redesign. If you discover the Blueprint is wrong, note it and adapt minimally — don't redesign mid-build.
|
|
33
|
+
|
|
34
|
+
## Recording
|
|
35
|
+
|
|
36
|
+
Throughout every sub-stage, capture three things in the shared state.md sections:
|
|
37
|
+
|
|
38
|
+
- **`## Decisions`** — Whenever you choose between real alternatives, append: `**<context>**: chose <X> over <Y> — <why>`. Skip obvious choices.
|
|
39
|
+
- **`## Deviations`** — Whenever you diverge from the Blueprint, append: `**<Blueprint step>**: <what changed> — <why>`. Every deviation needs a reason.
|
|
40
|
+
|
|
41
|
+
These feed into the final work-kit log summary. If you don't record them here, they're lost.
|
|
42
|
+
|
|
43
|
+
## Loop-back
|
|
44
|
+
|
|
45
|
+
If **Refactor** returns "broken" (tests failing after refactor):
|
|
46
|
+
- Revert the refactoring that broke tests
|
|
47
|
+
- Go back to **Core** to fix
|
|
48
|
+
- Re-run **Refactor**
|
|
49
|
+
- Max 2 loops, then proceed with tests passing (skip further refactoring)
|
|
50
|
+
|
|
51
|
+
## Context Input
|
|
52
|
+
|
|
53
|
+
This phase runs as a **fresh agent**. Read only these sections from `.work-kit/state.md`:
|
|
54
|
+
- `### Plan: Final` — the Blueprint, Architecture, Scope, and Constraints
|
|
55
|
+
- `## Criteria` — what "done" looks like
|
|
56
|
+
- `## Description` — original request for context
|
|
57
|
+
|
|
58
|
+
Do NOT read the Plan sub-stage working notes (Clarify, Investigate, Sketch, etc.) — they're consumed by Plan: Final.
|
|
59
|
+
|
|
60
|
+
## Final Output
|
|
61
|
+
|
|
62
|
+
After all sub-stages are done, append a `### Build: Final` section to state.md. This is the **only section the Test agent reads**.
|
|
63
|
+
|
|
64
|
+
```markdown
|
|
65
|
+
### Build: Final
|
|
66
|
+
|
|
67
|
+
**PR:** #<number> — <title>
|
|
68
|
+
**PR URL:** <url>
|
|
69
|
+
**Branch:** feature/<slug>
|
|
70
|
+
|
|
71
|
+
**What was built:**
|
|
72
|
+
- <file>: <what was implemented>
|
|
73
|
+
- ...
|
|
74
|
+
|
|
75
|
+
**Test status:**
|
|
76
|
+
- New tests: <count> (all passing)
|
|
77
|
+
- Existing tests: all passing | <failures>
|
|
78
|
+
|
|
79
|
+
**Deviations from Blueprint:**
|
|
80
|
+
- <deviation and why — or "None">
|
|
81
|
+
|
|
82
|
+
**Known issues:**
|
|
83
|
+
- <anything the Test/Review agents should watch for — or "None">
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Then:
|
|
87
|
+
- Update state: `**Phase:** build (complete)`
|
|
88
|
+
- Commit state: `git add .work-kit/ && git commit -m "work-kit: complete build"`
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Build sub-stage: Create clean commits, push branch, create PR."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Commit
|
|
6
|
+
|
|
7
|
+
**Role:** Release Preparer
|
|
8
|
+
**Goal:** Clean git history, push, and open a PR.
|
|
9
|
+
|
|
10
|
+
## Instructions
|
|
11
|
+
|
|
12
|
+
1. Review all changes with `git diff` and `git status`
|
|
13
|
+
2. Stage changes in logical groups — don't dump everything in one commit
|
|
14
|
+
3. Write clear commit messages:
|
|
15
|
+
- First line: imperative, under 72 chars (e.g., "Add avatar upload service and API endpoint")
|
|
16
|
+
- Body: explain what and why, not how
|
|
17
|
+
4. Push the feature branch
|
|
18
|
+
5. Create a pull request:
|
|
19
|
+
- Title: concise summary of the feature
|
|
20
|
+
- Body: description, what changed, how to test
|
|
21
|
+
6. Record the PR URL
|
|
22
|
+
|
|
23
|
+
## Output (append to state.md)
|
|
24
|
+
|
|
25
|
+
```markdown
|
|
26
|
+
### Build: Commit
|
|
27
|
+
|
|
28
|
+
**Commits:**
|
|
29
|
+
- `<hash>` — <message summary>
|
|
30
|
+
- ...
|
|
31
|
+
|
|
32
|
+
**Branch Pushed:** feature/<slug>
|
|
33
|
+
**PR:** #<number> — <title>
|
|
34
|
+
**PR URL:** <url>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Rules
|
|
38
|
+
|
|
39
|
+
- Don't include `.work-kit/` state files in the PR commits — commit those separately
|
|
40
|
+
- Don't include unrelated changes
|
|
41
|
+
- If there are secrets or env files staged, remove them
|
|
42
|
+
- Prefer multiple focused commits over one giant commit
|
|
43
|
+
- PR description should be useful to a reviewer — not a wall of text
|