@shenlee/devcrew 0.1.2 → 0.1.4
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 +15 -7
- package/README.zh-CN.md +12 -7
- package/dist/packages/adapters/src/index.js +204 -10
- package/dist/packages/core/src/active-run.js +13 -1
- package/dist/packages/core/src/artifacts.js +14 -4
- package/dist/packages/core/src/config.js +88 -17
- package/dist/packages/core/src/index.js +1 -0
- package/dist/packages/core/src/lock.js +89 -0
- package/dist/packages/core/src/paths.js +10 -6
- package/dist/packages/core/src/store.js +40 -0
- package/dist/packages/core/src/types.js +4 -1
- package/dist/packages/core/src/validation.js +7 -1
- package/dist/packages/core/src/version.js +1 -1
- package/dist/packages/core/src/workflow.js +87 -12
- package/dist/packages/orchestrator/src/index.js +317 -18
- package/dist/packages/plugins/src/index.js +2 -32
- package/dist/packages/service/src/tools.js +117 -17
- package/docs/claude-code.md +18 -3
- package/docs/codex.md +22 -5
- package/docs/quickstart.md +1 -1
- package/docs/superpowers/plans/2026-07-13-safety-semantics.md +313 -0
- package/docs/superpowers/plans/2026-07-14-p0-remediation.md +213 -0
- package/docs/superpowers/plans/2026-07-14-reliability-recovery.md +208 -0
- package/docs/superpowers/plans/2026-07-14-structured-role-results.md +231 -0
- package/docs/superpowers/specs/2026-07-13-execution-boundaries-design.md +126 -0
- package/docs/superpowers/specs/2026-07-14-p0-remediation-design.md +52 -0
- package/docs/superpowers/specs/2026-07-14-reliability-recovery-design.md +92 -0
- package/docs/superpowers/specs/2026-07-14-structured-role-results-design.md +96 -0
- package/docs/workflow.md +28 -4
- package/package.json +1 -1
- package/packages/adapters/src/index.ts +250 -13
- package/packages/core/src/active-run.ts +13 -1
- package/packages/core/src/artifacts.ts +16 -4
- package/packages/core/src/config.ts +97 -18
- package/packages/core/src/index.ts +1 -0
- package/packages/core/src/lock.ts +104 -0
- package/packages/core/src/paths.ts +11 -6
- package/packages/core/src/store.ts +45 -1
- package/packages/core/src/types.ts +92 -2
- package/packages/core/src/validation.ts +10 -0
- package/packages/core/src/version.ts +1 -1
- package/packages/core/src/workflow.ts +101 -11
- package/packages/orchestrator/src/index.ts +349 -19
- package/packages/plugins/src/index.ts +2 -44
- package/packages/service/src/tools.ts +126 -15
- package/plugins/devcrew-codex/.codex-plugin/plugin.json +1 -1
- package/plugins/devcrew-codex/.mcp.json +1 -1
- package/plugins/devcrew-codex/skills/devcrew/SKILL.md +8 -7
- package/scripts/smoke-codex-plugin.mjs +1 -1
- package/plugins/devcrew-codex/agents/architect.toml +0 -12
- package/plugins/devcrew-codex/agents/implementer.toml +0 -12
- package/plugins/devcrew-codex/agents/pm.toml +0 -13
- package/plugins/devcrew-codex/agents/tester.toml +0 -12
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
import {
|
|
2
|
+
clearActiveRunIfMatches,
|
|
2
3
|
getArtifact,
|
|
3
4
|
getActiveRunId,
|
|
4
5
|
getWorkflowStatus,
|
|
6
|
+
recoverRepositoryLock,
|
|
5
7
|
setActiveRun,
|
|
8
|
+
withRepositoryLock,
|
|
6
9
|
type Host,
|
|
7
10
|
type RunState,
|
|
8
11
|
} from "../../core/src/index.js";
|
|
9
12
|
import {
|
|
13
|
+
abortOrchestratedWorkflow,
|
|
10
14
|
answerOrchestratedWorkflow,
|
|
11
15
|
approveOrchestratedWorkflow,
|
|
16
|
+
completeOrchestratedExecution,
|
|
12
17
|
continueOrchestratedWorkflow,
|
|
13
18
|
rejectOrchestratedWorkflow,
|
|
19
|
+
recoverOrchestratedWorkflow,
|
|
14
20
|
startOrchestratedWorkflow,
|
|
21
|
+
waiveOrchestratedVerification,
|
|
15
22
|
} from "../../orchestrator/src/index.js";
|
|
16
23
|
|
|
17
24
|
export interface DevCrewTool {
|
|
@@ -56,8 +63,24 @@ function withInferredHost(args: Record<string, unknown>): Record<string, unknown
|
|
|
56
63
|
return { ...args, host: inferHost() };
|
|
57
64
|
}
|
|
58
65
|
|
|
66
|
+
async function withMutationLock<T>(args: Record<string, unknown>, action: () => Promise<T>): Promise<T> {
|
|
67
|
+
if (typeof args.cwd !== "string" || !args.cwd.trim()) {
|
|
68
|
+
return action();
|
|
69
|
+
}
|
|
70
|
+
return withRepositoryLock(args.cwd, action);
|
|
71
|
+
}
|
|
72
|
+
|
|
59
73
|
export function listDevCrewTools(): DevCrewTool[] {
|
|
60
74
|
return [
|
|
75
|
+
{
|
|
76
|
+
name: "devcrew_abort",
|
|
77
|
+
description: "Abort a nonterminal run, preserve its audit evidence, and clean its isolated worktree when possible.",
|
|
78
|
+
inputSchema: {
|
|
79
|
+
type: "object",
|
|
80
|
+
required: ["cwd", "reason"],
|
|
81
|
+
properties: { cwd: cwdProperty, runId: runIdProperty, reason: { type: "string" } },
|
|
82
|
+
},
|
|
83
|
+
},
|
|
61
84
|
{
|
|
62
85
|
name: "devcrew_start",
|
|
63
86
|
description: "Create a new gated DevCrew workflow run.",
|
|
@@ -73,11 +96,25 @@ export function listDevCrewTools(): DevCrewTool[] {
|
|
|
73
96
|
enum: ["plan", "apply"],
|
|
74
97
|
description: "Execution mode. Defaults to plan; apply must be explicit.",
|
|
75
98
|
},
|
|
99
|
+
executionPolicy: {
|
|
100
|
+
type: "string",
|
|
101
|
+
enum: ["interactive-host", "headless-restricted", "headless-unattended"],
|
|
102
|
+
description: "Apply execution policy. Defaults to interactive-host; headless policies are explicit DevCrew SDK policies.",
|
|
103
|
+
},
|
|
76
104
|
request: { type: "string" },
|
|
77
105
|
backend: { type: "string", enum: ["codex", "claude", "local"] },
|
|
78
106
|
},
|
|
79
107
|
},
|
|
80
108
|
},
|
|
109
|
+
{
|
|
110
|
+
name: "devcrew_recover",
|
|
111
|
+
description: "Explicitly clear a confirmed stale lock and retry cleanup for a terminal run without executing an agent.",
|
|
112
|
+
inputSchema: {
|
|
113
|
+
type: "object",
|
|
114
|
+
required: ["cwd"],
|
|
115
|
+
properties: { cwd: cwdProperty, runId: runIdProperty },
|
|
116
|
+
},
|
|
117
|
+
},
|
|
81
118
|
{
|
|
82
119
|
name: "devcrew_status",
|
|
83
120
|
description: "Read the status of a DevCrew workflow run.",
|
|
@@ -105,7 +142,7 @@ export function listDevCrewTools(): DevCrewTool[] {
|
|
|
105
142
|
properties: {
|
|
106
143
|
cwd: cwdProperty,
|
|
107
144
|
runId: runIdProperty,
|
|
108
|
-
gate: { type: "string", enum: ["requirements", "architecture", "implementation", "testing"] },
|
|
145
|
+
gate: { type: "string", enum: ["requirements", "architecture", "implementation", "implementation-review", "testing"] },
|
|
109
146
|
note: { type: "string" },
|
|
110
147
|
},
|
|
111
148
|
},
|
|
@@ -119,7 +156,7 @@ export function listDevCrewTools(): DevCrewTool[] {
|
|
|
119
156
|
properties: {
|
|
120
157
|
cwd: cwdProperty,
|
|
121
158
|
runId: runIdProperty,
|
|
122
|
-
gate: { type: "string", enum: ["requirements", "architecture", "implementation", "testing"] },
|
|
159
|
+
gate: { type: "string", enum: ["requirements", "architecture", "implementation", "implementation-review", "testing"] },
|
|
123
160
|
feedback: { type: "string" },
|
|
124
161
|
},
|
|
125
162
|
},
|
|
@@ -133,6 +170,32 @@ export function listDevCrewTools(): DevCrewTool[] {
|
|
|
133
170
|
properties: { cwd: cwdProperty, runId: runIdProperty },
|
|
134
171
|
},
|
|
135
172
|
},
|
|
173
|
+
{
|
|
174
|
+
name: "devcrew_complete_execution",
|
|
175
|
+
description: "Record completion by the native host for an interactive-host execution or testing step.",
|
|
176
|
+
inputSchema: {
|
|
177
|
+
type: "object",
|
|
178
|
+
required: ["cwd", "summary"],
|
|
179
|
+
properties: {
|
|
180
|
+
cwd: cwdProperty,
|
|
181
|
+
runId: runIdProperty,
|
|
182
|
+
summary: { type: "string" },
|
|
183
|
+
verification: {
|
|
184
|
+
type: "array",
|
|
185
|
+
description: "Required only when completing testing: command, exitCode, output, startedAt, and completedAt for each validation command.",
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
name: "devcrew_waive_verification",
|
|
192
|
+
description: "Record a reasoned risk waiver after failed apply-mode verification, then reopen the testing gate for approval.",
|
|
193
|
+
inputSchema: {
|
|
194
|
+
type: "object",
|
|
195
|
+
required: ["cwd", "reason"],
|
|
196
|
+
properties: { cwd: cwdProperty, runId: runIdProperty, reason: { type: "string" } },
|
|
197
|
+
},
|
|
198
|
+
},
|
|
136
199
|
{
|
|
137
200
|
name: "devcrew_artifact",
|
|
138
201
|
description: "Read a generated workflow artifact.",
|
|
@@ -144,7 +207,7 @@ export function listDevCrewTools(): DevCrewTool[] {
|
|
|
144
207
|
runId: runIdProperty,
|
|
145
208
|
name: {
|
|
146
209
|
type: "string",
|
|
147
|
-
enum: ["requirements", "architecture", "implementation-plan", "implementation-review", "test-report", "acceptance"],
|
|
210
|
+
enum: ["requirements", "architecture", "implementation-plan", "implementation-review", "architecture-review", "test-report", "acceptance"],
|
|
148
211
|
},
|
|
149
212
|
},
|
|
150
213
|
},
|
|
@@ -157,7 +220,8 @@ function summarizeState(state: RunState): string {
|
|
|
157
220
|
const role = state.roles.at(-1);
|
|
158
221
|
const roleFallback =
|
|
159
222
|
role?.usedFallback === true ? (role.backend === "local" ? "local" : "sdk") : role ? "none" : "none";
|
|
160
|
-
|
|
223
|
+
const roleFormat = role?.format ?? "none";
|
|
224
|
+
return `Run ${state.runId}: phase=${state.phase}, status=${state.status}, execution_mode=${state.executionMode}, pending_gate=${pendingGate}, role_fallback=${roleFallback}, role_format=${roleFormat}`;
|
|
161
225
|
}
|
|
162
226
|
|
|
163
227
|
function success(text: string, structuredContent?: Record<string, unknown>): ToolResult {
|
|
@@ -180,29 +244,76 @@ function failure(error: unknown): ToolResult {
|
|
|
180
244
|
export async function callDevCrewTool(name: string, args: Record<string, unknown>): Promise<ToolResult> {
|
|
181
245
|
try {
|
|
182
246
|
if (name === "devcrew_start") {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
247
|
+
return await withMutationLock(args, async () => {
|
|
248
|
+
const state = await startOrchestratedWorkflow(withInferredHost(args) as never);
|
|
249
|
+
await setActiveRun(state.cwd, state.runId);
|
|
250
|
+
return success(`${summarizeState(state)}. Review ${state.artifacts.requirements}`, { state });
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
if (name === "devcrew_abort") {
|
|
254
|
+
return await withMutationLock(args, async () => {
|
|
255
|
+
const runArgs = await withActiveRun(args);
|
|
256
|
+
const state = await abortOrchestratedWorkflow(runArgs as never);
|
|
257
|
+
await clearActiveRunIfMatches(state.cwd, state.runId);
|
|
258
|
+
return success(`${summarizeState(state)}. Run aborted.`, { state });
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
if (name === "devcrew_recover") {
|
|
262
|
+
if (typeof args.cwd !== "string" || !args.cwd.trim()) {
|
|
263
|
+
throw new Error("cwd must be a non-empty string");
|
|
264
|
+
}
|
|
265
|
+
const recoveredLock = await recoverRepositoryLock(args.cwd);
|
|
266
|
+
if (typeof args.runId !== "string" || !args.runId.trim()) {
|
|
267
|
+
return success(
|
|
268
|
+
recoveredLock ? "Repository lock recovery completed." : "No stale repository lock was present.",
|
|
269
|
+
{ recoveredLock },
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
return await withMutationLock(args, async () => {
|
|
273
|
+
const runArgs = await withActiveRun(args);
|
|
274
|
+
const state = await recoverOrchestratedWorkflow(runArgs as never);
|
|
275
|
+
return success(`${summarizeState(state)}. Recovery cleanup completed.`, { state });
|
|
276
|
+
});
|
|
186
277
|
}
|
|
187
278
|
if (name === "devcrew_status") {
|
|
188
279
|
const state = await getWorkflowStatus((await withActiveRun(args)) as never);
|
|
189
280
|
return success(summarizeState(state), { state });
|
|
190
281
|
}
|
|
191
282
|
if (name === "devcrew_answer") {
|
|
192
|
-
|
|
193
|
-
|
|
283
|
+
return await withMutationLock(args, async () => {
|
|
284
|
+
const state = await answerOrchestratedWorkflow((await withActiveRun(args)) as never);
|
|
285
|
+
return success(`${summarizeState(state)}. Answer recorded.`, { state });
|
|
286
|
+
});
|
|
194
287
|
}
|
|
195
288
|
if (name === "devcrew_approve") {
|
|
196
|
-
|
|
197
|
-
|
|
289
|
+
return await withMutationLock(args, async () => {
|
|
290
|
+
const state = await approveOrchestratedWorkflow((await withActiveRun(args)) as never);
|
|
291
|
+
return success(`${summarizeState(state)}. Gate approved.`, { state });
|
|
292
|
+
});
|
|
198
293
|
}
|
|
199
294
|
if (name === "devcrew_reject") {
|
|
200
|
-
|
|
201
|
-
|
|
295
|
+
return await withMutationLock(args, async () => {
|
|
296
|
+
const state = await rejectOrchestratedWorkflow((await withActiveRun(args)) as never);
|
|
297
|
+
return success(`${summarizeState(state)}. Gate rejected.`, { state });
|
|
298
|
+
});
|
|
202
299
|
}
|
|
203
300
|
if (name === "devcrew_continue") {
|
|
204
|
-
|
|
205
|
-
|
|
301
|
+
return await withMutationLock(args, async () => {
|
|
302
|
+
const state = await continueOrchestratedWorkflow((await withActiveRun(args)) as never);
|
|
303
|
+
return success(`${summarizeState(state)}.`, { state });
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
if (name === "devcrew_complete_execution") {
|
|
307
|
+
return await withMutationLock(args, async () => {
|
|
308
|
+
const state = await completeOrchestratedExecution((await withActiveRun(args)) as never);
|
|
309
|
+
return success(`${summarizeState(state)}. Native host completion recorded.`, { state });
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
if (name === "devcrew_waive_verification") {
|
|
313
|
+
return await withMutationLock(args, async () => {
|
|
314
|
+
const state = await waiveOrchestratedVerification((await withActiveRun(args)) as never);
|
|
315
|
+
return success(`${summarizeState(state)}. Verification waiver recorded.`, { state });
|
|
316
|
+
});
|
|
206
317
|
}
|
|
207
318
|
if (name === "devcrew_artifact") {
|
|
208
319
|
const artifact = await getArtifact((await withActiveRun(args)) as never);
|
|
@@ -5,13 +5,14 @@ description: Run the DevCrew PM -> architecture -> implementation -> testing wor
|
|
|
5
5
|
|
|
6
6
|
Use the DevCrew MCP tools to manage the workflow:
|
|
7
7
|
|
|
8
|
-
1. Start with `devcrew_start` using the current repository cwd, mode, request, and optional executionMode
|
|
9
|
-
2. After start, DevCrew records the active run for this repository. For follow-up tools, omit runId unless you need to target a different run explicitly.
|
|
10
|
-
3.
|
|
11
|
-
4. Use `devcrew_status` to show the current phase and
|
|
8
|
+
1. Start with `devcrew_start` using the current repository cwd, mode, request, and optional `executionMode`. Host is inferred from the plugin's `DEVCREW_HOST`; pass host only for an explicit override. Omit `executionMode` unless the requester explicitly asks DevCrew to apply changes; the default safe mode is `plan`.
|
|
9
|
+
2. After start, DevCrew records the active run for this repository. For follow-up tools, omit `runId` unless you need to target a different run explicitly.
|
|
10
|
+
3. For `executionMode: "apply"`, choose an explicit `executionPolicy`. The default `interactive-host` pauses at implementation and testing for the host's native agent to work in DevCrew's isolated worktree. `headless-restricted` and `headless-unattended` are DevCrew SDK policies; they do not inherit the current host approval session.
|
|
11
|
+
4. Use `devcrew_status` to show the current phase, pending gate, and any execution instruction.
|
|
12
12
|
5. Use `devcrew_answer` when the requester gives clarification.
|
|
13
13
|
6. Use `devcrew_approve` or `devcrew_reject` for each gate.
|
|
14
|
-
7. Use `devcrew_continue` after approvals.
|
|
15
|
-
8.
|
|
14
|
+
7. Use `devcrew_continue` after approvals. Apply runs enter an `implementation-review` gate after execution: review the architect's `architecture-review` artifact before testing. For `interactive-host`, if status becomes `awaiting_execution`, perform the native-host work in the indicated worktree then call `devcrew_complete_execution`. For testing, include command, exit code, output, startedAt, and completedAt evidence.
|
|
15
|
+
8. Failed verification is not approvable. Revise through `devcrew_answer`, or use `devcrew_waive_verification` only when the requester explicitly accepts the recorded risk and provides a reason.
|
|
16
|
+
9. Use `devcrew_artifact` to read generated requirements, architecture, implementation-plan, implementation-review, architecture-review, test-report, or acceptance files.
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
Never describe a nested SDK session as inheriting the current host's approval decisions.
|
|
@@ -298,7 +298,7 @@ async function main() {
|
|
|
298
298
|
await client.request("initialize", {
|
|
299
299
|
protocolVersion: "2025-03-26",
|
|
300
300
|
capabilities: {},
|
|
301
|
-
clientInfo: { name: "devcrew-codex-plugin-smoke", version: "0.1.
|
|
301
|
+
clientInfo: { name: "devcrew-codex-plugin-smoke", version: "0.1.4" },
|
|
302
302
|
});
|
|
303
303
|
client.notify("notifications/initialized", {});
|
|
304
304
|
const tools = await client.request("tools/list", {});
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
name = "architect"
|
|
2
|
-
description = "technical architecture specialist. Designs implementation, deployment, interfaces, and review criteria."
|
|
3
|
-
developer_instructions = """
|
|
4
|
-
You are the DevCrew architect role. technical architecture specialist. Designs implementation, deployment, interfaces, and review criteria.
|
|
5
|
-
Return concise Markdown and keep inherited host permissions.
|
|
6
|
-
|
|
7
|
-
Produce these required sections:
|
|
8
|
-
- Technical Decisions (for each key decision record Decision, Options Considered, Choice, Rationale, and Trade-offs)
|
|
9
|
-
- Interface Contracts (for each interface give the signature, request/response schema, error contract, and data model)
|
|
10
|
-
- Data Flow and Deployment (data flow, deployment expectations, and rollback strategy)
|
|
11
|
-
- Architecture Review Checklist (how the design traces back to the approved requirements)
|
|
12
|
-
"""
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
name = "implementer"
|
|
2
|
-
description = "Implementation engineer. Writes code according to approved architecture and discovered standards."
|
|
3
|
-
developer_instructions = """
|
|
4
|
-
You are the DevCrew implementer role. Implementation engineer. Writes code according to approved architecture and discovered standards.
|
|
5
|
-
Return concise Markdown and keep inherited host permissions.
|
|
6
|
-
|
|
7
|
-
Produce these required sections:
|
|
8
|
-
- Implementation Summary (the smallest change that satisfies the approved architecture)
|
|
9
|
-
- Standards Compliance (follow discovered standards and lint/format rules; run available lint/format/typecheck and report results)
|
|
10
|
-
- Changed Files (every file you created or modified)
|
|
11
|
-
- Tests Added or Updated (tests covering success, edge, and failure paths)
|
|
12
|
-
"""
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
name = "pm"
|
|
2
|
-
description = "Product manager. Clarifies requirements, scope boundaries, success criteria, and requester approvals."
|
|
3
|
-
developer_instructions = """
|
|
4
|
-
You are the DevCrew pm role. Product manager. Clarifies requirements, scope boundaries, success criteria, and requester approvals.
|
|
5
|
-
Return concise Markdown and keep inherited host permissions.
|
|
6
|
-
|
|
7
|
-
Produce these required sections:
|
|
8
|
-
- Functional Scope (explicit In Scope and Out of Scope lists)
|
|
9
|
-
- Users and Scenarios (primary users and their key scenarios)
|
|
10
|
-
- Acceptance Criteria (testable criteria written as Given / When / Then)
|
|
11
|
-
- Priorities (classify each requirement as Must / Should / Could / Won't (MoSCoW))
|
|
12
|
-
- Open Questions (unresolved clarifications for the requester)
|
|
13
|
-
"""
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
name = "tester"
|
|
2
|
-
description = "Testing and acceptance specialist. Verifies functionality, regressions, and acceptance evidence."
|
|
3
|
-
developer_instructions = """
|
|
4
|
-
You are the DevCrew tester role. Testing and acceptance specialist. Verifies functionality, regressions, and acceptance evidence.
|
|
5
|
-
Return concise Markdown and keep inherited host permissions.
|
|
6
|
-
|
|
7
|
-
Produce these required sections:
|
|
8
|
-
- Test Cases (enumerate cases as a table with ID, Scenario, Type (happy/edge/failure/regression), and Expected result)
|
|
9
|
-
- Coverage (run the coverage command and report the coverage summary plus any gaps)
|
|
10
|
-
- Verification Evidence (exact commands, exit codes, and key output)
|
|
11
|
-
- Known Risks (residual risks and follow-ups)
|
|
12
|
-
"""
|