@shenlee/devcrew 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.
Files changed (64) hide show
  1. package/CONTRIBUTING.md +21 -0
  2. package/LICENSE +186 -0
  3. package/README.md +142 -0
  4. package/README.zh-CN.md +156 -0
  5. package/SECURITY.md +19 -0
  6. package/dist/packages/adapters/src/index.js +234 -0
  7. package/dist/packages/cli/src/index.js +76 -0
  8. package/dist/packages/core/src/active-run.js +24 -0
  9. package/dist/packages/core/src/artifacts.js +120 -0
  10. package/dist/packages/core/src/config.js +51 -0
  11. package/dist/packages/core/src/index.js +11 -0
  12. package/dist/packages/core/src/paths.js +51 -0
  13. package/dist/packages/core/src/standards.js +61 -0
  14. package/dist/packages/core/src/store.js +24 -0
  15. package/dist/packages/core/src/types.js +48 -0
  16. package/dist/packages/core/src/validation.js +52 -0
  17. package/dist/packages/core/src/verification.js +157 -0
  18. package/dist/packages/core/src/version.js +2 -0
  19. package/dist/packages/core/src/workflow.js +166 -0
  20. package/dist/packages/orchestrator/src/index.js +376 -0
  21. package/dist/packages/plugins/src/index.js +173 -0
  22. package/dist/packages/service/src/index.js +2 -0
  23. package/dist/packages/service/src/stdio.js +100 -0
  24. package/dist/packages/service/src/tools.js +177 -0
  25. package/docs/claude-code.md +37 -0
  26. package/docs/codex.md +80 -0
  27. package/docs/quickstart.md +64 -0
  28. package/docs/roles.md +43 -0
  29. package/docs/workflow.md +70 -0
  30. package/examples/README.md +11 -0
  31. package/examples/feature-request.md +13 -0
  32. package/examples/greenfield-request.md +14 -0
  33. package/package.json +60 -0
  34. package/packages/adapters/src/index.ts +404 -0
  35. package/packages/cli/src/index.ts +88 -0
  36. package/packages/core/src/active-run.ts +31 -0
  37. package/packages/core/src/artifacts.ts +148 -0
  38. package/packages/core/src/config.ts +56 -0
  39. package/packages/core/src/index.ts +11 -0
  40. package/packages/core/src/paths.ts +66 -0
  41. package/packages/core/src/standards.ts +70 -0
  42. package/packages/core/src/store.ts +28 -0
  43. package/packages/core/src/types.ts +182 -0
  44. package/packages/core/src/validation.ts +79 -0
  45. package/packages/core/src/verification.ts +163 -0
  46. package/packages/core/src/version.ts +2 -0
  47. package/packages/core/src/workflow.ts +214 -0
  48. package/packages/orchestrator/src/index.ts +469 -0
  49. package/packages/plugins/assets/composer-icon.png +0 -0
  50. package/packages/plugins/assets/logo.png +0 -0
  51. package/packages/plugins/src/index.ts +211 -0
  52. package/packages/service/src/index.ts +2 -0
  53. package/packages/service/src/stdio.ts +121 -0
  54. package/packages/service/src/tools.ts +215 -0
  55. package/plugins/devcrew-codex/.codex-plugin/plugin.json +41 -0
  56. package/plugins/devcrew-codex/.mcp.json +16 -0
  57. package/plugins/devcrew-codex/agents/architect.toml +6 -0
  58. package/plugins/devcrew-codex/agents/implementer.toml +6 -0
  59. package/plugins/devcrew-codex/agents/pm.toml +6 -0
  60. package/plugins/devcrew-codex/agents/tester.toml +6 -0
  61. package/plugins/devcrew-codex/assets/composer-icon.png +0 -0
  62. package/plugins/devcrew-codex/assets/logo.png +0 -0
  63. package/plugins/devcrew-codex/skills/devcrew/SKILL.md +17 -0
  64. package/scripts/smoke-codex-plugin.mjs +331 -0
@@ -0,0 +1,177 @@
1
+ import { approveWorkflow, getArtifact, getActiveRunId, getWorkflowStatus, setActiveRun, } from "../../core/src/index.js";
2
+ import { answerOrchestratedWorkflow, continueOrchestratedWorkflow, rejectOrchestratedWorkflow, startOrchestratedWorkflow, } from "../../orchestrator/src/index.js";
3
+ const cwdProperty = { type: "string", description: "Repository working directory." };
4
+ const runIdProperty = { type: "string", description: "DevCrew run id." };
5
+ const hostValues = ["codex", "claude"];
6
+ function inferHost(env = process.env) {
7
+ const host = env.DEVCREW_HOST;
8
+ return host === "claude" || host === "codex" ? host : "codex";
9
+ }
10
+ async function withActiveRun(args) {
11
+ if (typeof args.runId === "string" && args.runId.trim()) {
12
+ return args;
13
+ }
14
+ if (typeof args.cwd !== "string" || !args.cwd.trim()) {
15
+ return args;
16
+ }
17
+ return { ...args, runId: await getActiveRunId(args.cwd) };
18
+ }
19
+ function withInferredHost(args) {
20
+ if (typeof args.host === "string" && hostValues.includes(args.host)) {
21
+ return args;
22
+ }
23
+ return { ...args, host: inferHost() };
24
+ }
25
+ export function listDevCrewTools() {
26
+ return [
27
+ {
28
+ name: "devcrew_start",
29
+ description: "Create a new gated DevCrew workflow run.",
30
+ inputSchema: {
31
+ type: "object",
32
+ required: ["cwd", "mode", "request"],
33
+ properties: {
34
+ cwd: cwdProperty,
35
+ host: { type: "string", enum: ["codex", "claude"], description: "Optional host override. Defaults to DEVCREW_HOST or codex." },
36
+ mode: { type: "string", enum: ["feature", "greenfield"] },
37
+ executionMode: {
38
+ type: "string",
39
+ enum: ["plan", "apply"],
40
+ description: "Execution mode. Defaults to plan; apply must be explicit.",
41
+ },
42
+ request: { type: "string" },
43
+ backend: { type: "string", enum: ["codex", "claude", "local"] },
44
+ },
45
+ },
46
+ },
47
+ {
48
+ name: "devcrew_status",
49
+ description: "Read the status of a DevCrew workflow run.",
50
+ inputSchema: {
51
+ type: "object",
52
+ required: ["cwd"],
53
+ properties: { cwd: cwdProperty, runId: runIdProperty },
54
+ },
55
+ },
56
+ {
57
+ name: "devcrew_answer",
58
+ description: "Record requester clarification input for the current gate.",
59
+ inputSchema: {
60
+ type: "object",
61
+ required: ["cwd", "answer"],
62
+ properties: { cwd: cwdProperty, runId: runIdProperty, answer: { type: "string" } },
63
+ },
64
+ },
65
+ {
66
+ name: "devcrew_approve",
67
+ description: "Approve the current workflow gate and advance to the next phase.",
68
+ inputSchema: {
69
+ type: "object",
70
+ required: ["cwd", "gate"],
71
+ properties: {
72
+ cwd: cwdProperty,
73
+ runId: runIdProperty,
74
+ gate: { type: "string", enum: ["requirements", "architecture", "implementation", "testing"] },
75
+ note: { type: "string" },
76
+ },
77
+ },
78
+ },
79
+ {
80
+ name: "devcrew_reject",
81
+ description: "Reject the current workflow gate and record feedback.",
82
+ inputSchema: {
83
+ type: "object",
84
+ required: ["cwd", "gate", "feedback"],
85
+ properties: {
86
+ cwd: cwdProperty,
87
+ runId: runIdProperty,
88
+ gate: { type: "string", enum: ["requirements", "architecture", "implementation", "testing"] },
89
+ feedback: { type: "string" },
90
+ },
91
+ },
92
+ },
93
+ {
94
+ name: "devcrew_continue",
95
+ description: "Continue a run after the previous gate was approved.",
96
+ inputSchema: {
97
+ type: "object",
98
+ required: ["cwd"],
99
+ properties: { cwd: cwdProperty, runId: runIdProperty },
100
+ },
101
+ },
102
+ {
103
+ name: "devcrew_artifact",
104
+ description: "Read a generated workflow artifact.",
105
+ inputSchema: {
106
+ type: "object",
107
+ required: ["cwd", "name"],
108
+ properties: {
109
+ cwd: cwdProperty,
110
+ runId: runIdProperty,
111
+ name: {
112
+ type: "string",
113
+ enum: ["requirements", "architecture", "implementation-plan", "implementation-review", "test-report", "acceptance"],
114
+ },
115
+ },
116
+ },
117
+ },
118
+ ];
119
+ }
120
+ function summarizeState(state) {
121
+ const pendingGate = Object.entries(state.gates).find(([, status]) => status === "pending")?.[0] ?? "none";
122
+ const role = state.roles.at(-1);
123
+ const roleFallback = role?.usedFallback === true ? (role.backend === "local" ? "local" : "sdk") : role ? "none" : "none";
124
+ return `Run ${state.runId}: phase=${state.phase}, status=${state.status}, execution_mode=${state.executionMode}, pending_gate=${pendingGate}, role_fallback=${roleFallback}`;
125
+ }
126
+ function success(text, structuredContent) {
127
+ return {
128
+ isError: false,
129
+ content: [{ type: "text", text }],
130
+ structuredContent,
131
+ };
132
+ }
133
+ function failure(error) {
134
+ const message = error instanceof Error ? error.message : String(error);
135
+ return {
136
+ isError: true,
137
+ content: [{ type: "text", text: message }],
138
+ structuredContent: { error: message },
139
+ };
140
+ }
141
+ export async function callDevCrewTool(name, args) {
142
+ try {
143
+ if (name === "devcrew_start") {
144
+ const state = await startOrchestratedWorkflow(withInferredHost(args));
145
+ await setActiveRun(state.cwd, state.runId);
146
+ return success(`${summarizeState(state)}. Review ${state.artifacts.requirements}`, { state });
147
+ }
148
+ if (name === "devcrew_status") {
149
+ const state = await getWorkflowStatus((await withActiveRun(args)));
150
+ return success(summarizeState(state), { state });
151
+ }
152
+ if (name === "devcrew_answer") {
153
+ const state = await answerOrchestratedWorkflow((await withActiveRun(args)));
154
+ return success(`${summarizeState(state)}. Answer recorded.`, { state });
155
+ }
156
+ if (name === "devcrew_approve") {
157
+ const state = await approveWorkflow((await withActiveRun(args)));
158
+ return success(`${summarizeState(state)}. Gate approved.`, { state });
159
+ }
160
+ if (name === "devcrew_reject") {
161
+ const state = await rejectOrchestratedWorkflow((await withActiveRun(args)));
162
+ return success(`${summarizeState(state)}. Gate rejected.`, { state });
163
+ }
164
+ if (name === "devcrew_continue") {
165
+ const state = await continueOrchestratedWorkflow((await withActiveRun(args)));
166
+ return success(`${summarizeState(state)}.`, { state });
167
+ }
168
+ if (name === "devcrew_artifact") {
169
+ const artifact = await getArtifact((await withActiveRun(args)));
170
+ return success(artifact.content, { artifact });
171
+ }
172
+ throw new Error(`Unknown DevCrew tool: ${name}`);
173
+ }
174
+ catch (error) {
175
+ return failure(error);
176
+ }
177
+ }
@@ -0,0 +1,37 @@
1
+ # Claude Code Setup
2
+
3
+ Run:
4
+
5
+ ```bash
6
+ devcrew init /path/to/repo
7
+ devcrew doctor /path/to/repo
8
+ ```
9
+
10
+ The Claude Code plugin is generated at:
11
+
12
+ ```text
13
+ plugins/devcrew-claude/
14
+ ```
15
+
16
+ It contains:
17
+
18
+ - `.claude-plugin/plugin.json`
19
+ - `skills/devcrew/SKILL.md`
20
+ - `agents/*.md`
21
+ - `.mcp.json`
22
+
23
+ For local plugin testing:
24
+
25
+ ```bash
26
+ claude --plugin-dir plugins/devcrew-claude
27
+ ```
28
+
29
+ Then ask Claude Code to use DevCrew for a feature or product workflow. The generated `.mcp.json` starts the version-locked npm package with `npx -y @shenlee/devcrew@0.1.0 serve --stdio`.
30
+
31
+ Claude Code permissions, hooks, and approval settings remain authoritative. DevCrew inherits the host boundary.
32
+
33
+ For apply mode, `@anthropic-ai/claude-agent-sdk` must be resolvable from the installed DevCrew package. Published DevCrew packages declare it as an optional dependency, which npm installs by default. If `devcrew doctor` reports it as missing, reinstall DevCrew with optional dependencies enabled:
34
+
35
+ ```bash
36
+ npm install -g @shenlee/devcrew --include=optional
37
+ ```
package/docs/codex.md ADDED
@@ -0,0 +1,80 @@
1
+ # Codex Setup
2
+
3
+ ## Plugin marketplace install
4
+
5
+ Add the DevCrew marketplace:
6
+
7
+ ```bash
8
+ codex plugin marketplace add lishen802/devcrew
9
+ ```
10
+
11
+ Restart Codex, open the plugin directory, select the DevCrew marketplace, and install the DevCrew plugin.
12
+
13
+ The plugin launches the MCP server with:
14
+
15
+ ```bash
16
+ npx -y @shenlee/devcrew@0.1.0 serve --stdio
17
+ ```
18
+
19
+ Use this path when you want to use DevCrew without cloning the repository first. The version is locked to the published npm package that matches the plugin manifest.
20
+
21
+ ## Local development install
22
+
23
+ Run:
24
+
25
+ ```bash
26
+ devcrew init /path/to/repo
27
+ devcrew doctor /path/to/repo
28
+ ```
29
+
30
+ The Codex plugin is generated at:
31
+
32
+ ```text
33
+ plugins/devcrew-codex/
34
+ ```
35
+
36
+ It contains:
37
+
38
+ - `.codex-plugin/plugin.json`
39
+ - `skills/devcrew/SKILL.md`
40
+ - `.mcp.json`
41
+ - role agent TOML templates under `agents/`
42
+
43
+ For local development, point a Codex marketplace entry at the generated plugin folder, or copy the plugin into your existing local marketplace workflow.
44
+
45
+ The DevCrew skill tells Codex to use these MCP tools:
46
+
47
+ - `devcrew_start`
48
+ - `devcrew_status`
49
+ - `devcrew_answer`
50
+ - `devcrew_approve`
51
+ - `devcrew_reject`
52
+ - `devcrew_continue`
53
+ - `devcrew_artifact`
54
+
55
+ Codex sandbox and approval settings remain authoritative. DevCrew does not bypass them.
56
+
57
+ For apply mode, `@openai/codex-sdk` must be resolvable from the installed DevCrew package. Published DevCrew packages declare it as an optional dependency, which npm installs by default. If `devcrew doctor` reports it as missing, reinstall DevCrew with optional dependencies enabled:
58
+
59
+ ```bash
60
+ npm install -g @shenlee/devcrew --include=optional
61
+ ```
62
+
63
+ ## Marketplace smoke test
64
+
65
+ After publishing the npm package version referenced by the plugin, run the real marketplace smoke test:
66
+
67
+ ```bash
68
+ npm run smoke:codex-plugin
69
+ ```
70
+
71
+ The smoke test creates an isolated `CODEX_HOME`, adds the `lishen802/devcrew` marketplace, installs `devcrew@devcrew`, starts the installed plugin's MCP server from `.mcp.json`, and runs a complete plan-mode workflow through JSON-RPC.
72
+
73
+ Useful options:
74
+
75
+ ```bash
76
+ node scripts/smoke-codex-plugin.mjs --keep-temp
77
+ node scripts/smoke-codex-plugin.mjs --source lishen802/devcrew --ref main
78
+ ```
79
+
80
+ The default path is intentionally production-like: it uses the GitHub marketplace and the version-locked npm package from the installed plugin. It requires network access, Codex CLI, Node.js, and a published `@shenlee/devcrew` npm version matching the plugin manifest.
@@ -0,0 +1,64 @@
1
+ # Quickstart
2
+
3
+ ## 1. Install
4
+
5
+ From npm:
6
+
7
+ ```bash
8
+ npm install -g @shenlee/devcrew
9
+ ```
10
+
11
+ For local development:
12
+
13
+ ```bash
14
+ npm install
15
+ npm run validate
16
+ npm link
17
+ ```
18
+
19
+ ## 2. Initialize A Repository
20
+
21
+ ```bash
22
+ devcrew init /path/to/repo
23
+ ```
24
+
25
+ This creates:
26
+
27
+ - `.devcrew/config.json`
28
+ - `.devcrew/standards.md`
29
+ - `docs/devcrew/`
30
+ - `plugins/devcrew-codex/`
31
+ - `plugins/devcrew-claude/`
32
+
33
+ ## 3. Start The MCP Service
34
+
35
+ ```bash
36
+ devcrew serve --stdio
37
+ ```
38
+
39
+ Normally the generated plugin starts this command for the host agent.
40
+ Codex and Claude plugin bundles use `npx -y @shenlee/devcrew@0.1.0 serve --stdio` so the MCP service is locked to the published package version.
41
+
42
+ ## 4. Run A Workflow
43
+
44
+ Ask the host agent:
45
+
46
+ ```text
47
+ Use DevCrew for this request: add release notes generation to this repository.
48
+ ```
49
+
50
+ Expected flow:
51
+
52
+ 1. Agent calls `devcrew_start`.
53
+ 2. Agent reads `requirements.md`.
54
+ 3. You approve or reject requirements.
55
+ 4. Agent calls `devcrew_continue`.
56
+ 5. Repeat for architecture, implementation plan, and test report.
57
+
58
+ ## 5. Review Artifacts
59
+
60
+ Artifacts are written under:
61
+
62
+ ```text
63
+ docs/devcrew/<run-id>/
64
+ ```
package/docs/roles.md ADDED
@@ -0,0 +1,43 @@
1
+ # Role Customization
2
+
3
+ DevCrew ships with five roles.
4
+
5
+ ## conductor
6
+
7
+ Owns workflow progression, gate discipline, and artifact routing.
8
+
9
+ ## pm
10
+
11
+ Clarifies product goals, users, boundaries, success criteria, and requester approvals.
12
+
13
+ ## architect
14
+
15
+ Designs technical architecture, interfaces, deployment considerations, and review criteria.
16
+
17
+ ## implementer
18
+
19
+ Builds according to approved requirements and architecture while following discovered project standards.
20
+
21
+ ## tester
22
+
23
+ Verifies behavior, runs or specifies validation commands, and prepares acceptance evidence.
24
+
25
+ ## Project Standards
26
+
27
+ Put explicit standards in:
28
+
29
+ ```text
30
+ .devcrew/standards.md
31
+ ```
32
+
33
+ DevCrew also discovers:
34
+
35
+ - `AGENTS.md`
36
+ - `CLAUDE.md`
37
+ - README files
38
+ - `package.json`
39
+ - `pyproject.toml`
40
+ - `go.mod`
41
+ - `Cargo.toml`
42
+
43
+ Explicit DevCrew standards are included first.
@@ -0,0 +1,70 @@
1
+ # Workflow Model
2
+
3
+ DevCrew uses a gated state machine plus an orchestrator layer.
4
+
5
+ The core state machine persists run state and gate transitions. The orchestrator
6
+ executes the role for the current phase, writes that role's Markdown artifact,
7
+ records the role result in state, and then opens the phase gate for requester
8
+ approval.
9
+
10
+ ## Modes
11
+
12
+ - `feature`: existing repository work. The workflow emphasizes current conventions, code review, and regression tests.
13
+ - `greenfield`: new product work. The workflow emphasizes product boundary, minimal architecture, and a shippable first slice.
14
+
15
+ ## Phases
16
+
17
+ 1. `requirements`: product manager clarifies scope, users, success criteria, and non-goals.
18
+ 2. `architecture`: architect defines technical approach, interfaces, deployment notes, and review criteria.
19
+ 3. `implementation`: implementer creates the implementation plan and coding checklist. DevCrew also writes `implementation-review.md` with changed files, captured diff, and architecture compliance review prompts before opening the implementation gate.
20
+ 4. `testing`: tester records validation strategy and acceptance evidence.
21
+ 5. `acceptance`: generated after the testing gate is approved.
22
+
23
+ `devcrew_start` runs the PM role for `requirements`. After the requester approves
24
+ a gate, `devcrew_continue` runs the role for the next phase before setting that
25
+ phase's gate to `pending`.
26
+
27
+ `devcrew_start` records the created run as the active run for the repository.
28
+ Subsequent MCP calls can omit `runId`; DevCrew resolves it from
29
+ `.devcrew/active-run.json`. Plugin MCP configs set `DEVCREW_HOST`, so `host`
30
+ can also be omitted unless the caller needs an explicit override.
31
+
32
+ ## Gates
33
+
34
+ Each main phase has a gate:
35
+
36
+ - `requirements`
37
+ - `architecture`
38
+ - `implementation`
39
+ - `testing`
40
+
41
+ The requester approves or rejects each gate. Rejection records feedback and returns the workflow to `awaiting_input`.
42
+
43
+ ## State And Artifacts
44
+
45
+ Runtime state is stored in:
46
+
47
+ ```text
48
+ .devcrew/runs/<run-id>/state.json
49
+ ```
50
+
51
+ The active run pointer is stored in:
52
+
53
+ ```text
54
+ .devcrew/active-run.json
55
+ ```
56
+
57
+ Reviewable artifacts are stored in:
58
+
59
+ ```text
60
+ docs/devcrew/<run-id>/
61
+ ```
62
+
63
+ The standard artifact set is:
64
+
65
+ - `requirements.md`
66
+ - `architecture.md`
67
+ - `implementation-plan.md`
68
+ - `implementation-review.md`
69
+ - `test-report.md`
70
+ - `acceptance.md`
@@ -0,0 +1,11 @@
1
+ # Examples
2
+
3
+ ## Existing Project Feature
4
+
5
+ See [feature-request.md](feature-request.md).
6
+
7
+ ## Greenfield Product
8
+
9
+ See [greenfield-request.md](greenfield-request.md).
10
+
11
+ Both examples are meant to be submitted to Codex or Claude Code after installing the generated DevCrew plugin.
@@ -0,0 +1,13 @@
1
+ # Feature Workflow Example
2
+
3
+ ```text
4
+ Use DevCrew in feature mode.
5
+
6
+ Request:
7
+ Add project-level release notes generation. The tool should scan merged pull request titles and produce a Markdown changelog section.
8
+
9
+ Constraints:
10
+ - Follow existing package scripts.
11
+ - Do not add a database.
12
+ - Include tests for empty input and grouped changes.
13
+ ```
@@ -0,0 +1,14 @@
1
+ # Greenfield Workflow Example
2
+
3
+ ```text
4
+ Use DevCrew in greenfield mode.
5
+
6
+ Request:
7
+ Build a tiny issue tracker for a small engineering team.
8
+
9
+ Constraints:
10
+ - Local-first MVP.
11
+ - Users can create, list, close, and reopen issues.
12
+ - Store data in a JSON file for v1.
13
+ - Include a CLI and tests.
14
+ ```
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@shenlee/devcrew",
3
+ "version": "0.1.0",
4
+ "description": "Multi-host agent workflow service for Codex and Claude Code.",
5
+ "type": "module",
6
+ "license": "Apache-2.0",
7
+ "homepage": "https://github.com/lishen802/devcrew#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/lishen802/devcrew.git"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/lishen802/devcrew/issues"
14
+ },
15
+ "keywords": [
16
+ "codex",
17
+ "claude-code",
18
+ "mcp",
19
+ "agents",
20
+ "workflow",
21
+ "plugin"
22
+ ],
23
+ "bin": {
24
+ "devcrew": "dist/packages/cli/src/index.js"
25
+ },
26
+ "files": [
27
+ "dist/packages",
28
+ "packages",
29
+ "plugins/devcrew-codex",
30
+ "scripts",
31
+ "docs",
32
+ "examples",
33
+ "README.md",
34
+ "LICENSE",
35
+ "CONTRIBUTING.md",
36
+ "SECURITY.md"
37
+ ],
38
+ "scripts": {
39
+ "build": "tsc -p tsconfig.json",
40
+ "test": "node --import tsx --test tests/*.test.ts",
41
+ "validate": "npm run build && npm test",
42
+ "smoke:codex-plugin": "node scripts/smoke-codex-plugin.mjs",
43
+ "prepack": "npm run build"
44
+ },
45
+ "publishConfig": {
46
+ "access": "public"
47
+ },
48
+ "devDependencies": {
49
+ "@types/node": "^20.19.0",
50
+ "tsx": "^4.20.0",
51
+ "typescript": "^5.8.0"
52
+ },
53
+ "engines": {
54
+ "node": ">=20"
55
+ },
56
+ "optionalDependencies": {
57
+ "@anthropic-ai/claude-agent-sdk": "0.3.163",
58
+ "@openai/codex-sdk": "0.137.0"
59
+ }
60
+ }