@alevental/cccp 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/.claude/skills/cccp-pipeline/SKILL.md +562 -0
- package/.claude/skills/cccp-run/SKILL.md +111 -0
- package/README.md +280 -0
- package/dist/activity-bus.d.ts +9 -0
- package/dist/activity-bus.js +10 -0
- package/dist/activity-bus.js.map +1 -0
- package/dist/agent-resolver.d.ts +29 -0
- package/dist/agent-resolver.js +122 -0
- package/dist/agent-resolver.js.map +1 -0
- package/dist/agent.d.ts +39 -0
- package/dist/agent.js +117 -0
- package/dist/agent.js.map +1 -0
- package/dist/autoresearch.d.ts +11 -0
- package/dist/autoresearch.js +295 -0
- package/dist/autoresearch.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +157 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +126 -0
- package/dist/config.js +76 -0
- package/dist/config.js.map +1 -0
- package/dist/context.d.ts +24 -0
- package/dist/context.js +82 -0
- package/dist/context.js.map +1 -0
- package/dist/contract.d.ts +26 -0
- package/dist/contract.js +65 -0
- package/dist/contract.js.map +1 -0
- package/dist/db.d.ts +70 -0
- package/dist/db.js +358 -0
- package/dist/db.js.map +1 -0
- package/dist/dispatcher.d.ts +9 -0
- package/dist/dispatcher.js +7 -0
- package/dist/dispatcher.js.map +1 -0
- package/dist/errors.d.ts +16 -0
- package/dist/errors.js +30 -0
- package/dist/errors.js.map +1 -0
- package/dist/evaluator.d.ts +23 -0
- package/dist/evaluator.js +49 -0
- package/dist/evaluator.js.map +1 -0
- package/dist/gate/auto-approve.d.ts +9 -0
- package/dist/gate/auto-approve.js +11 -0
- package/dist/gate/auto-approve.js.map +1 -0
- package/dist/gate/gate-strategy.d.ts +22 -0
- package/dist/gate/gate-strategy.js +2 -0
- package/dist/gate/gate-strategy.js.map +1 -0
- package/dist/gate/gate-watcher.d.ts +15 -0
- package/dist/gate/gate-watcher.js +64 -0
- package/dist/gate/gate-watcher.js.map +1 -0
- package/dist/logger.d.ts +24 -0
- package/dist/logger.js +22 -0
- package/dist/logger.js.map +1 -0
- package/dist/mcp/gate-notifier.d.ts +26 -0
- package/dist/mcp/gate-notifier.js +161 -0
- package/dist/mcp/gate-notifier.js.map +1 -0
- package/dist/mcp/mcp-config.d.ts +25 -0
- package/dist/mcp/mcp-config.js +80 -0
- package/dist/mcp/mcp-config.js.map +1 -0
- package/dist/mcp/mcp-server.d.ts +1 -0
- package/dist/mcp/mcp-server.js +262 -0
- package/dist/mcp/mcp-server.js.map +1 -0
- package/dist/pge.d.ts +12 -0
- package/dist/pge.js +361 -0
- package/dist/pge.js.map +1 -0
- package/dist/pipeline.d.ts +6 -0
- package/dist/pipeline.js +120 -0
- package/dist/pipeline.js.map +1 -0
- package/dist/prompt.d.ts +67 -0
- package/dist/prompt.js +121 -0
- package/dist/prompt.js.map +1 -0
- package/dist/runner.d.ts +11 -0
- package/dist/runner.js +494 -0
- package/dist/runner.js.map +1 -0
- package/dist/scaffold/index.d.ts +14 -0
- package/dist/scaffold/index.js +260 -0
- package/dist/scaffold/index.js.map +1 -0
- package/dist/scaffold/templates.d.ts +47 -0
- package/dist/scaffold/templates.js +2177 -0
- package/dist/scaffold/templates.js.map +1 -0
- package/dist/stage-helpers.d.ts +7 -0
- package/dist/stage-helpers.js +27 -0
- package/dist/stage-helpers.js.map +1 -0
- package/dist/state.d.ts +43 -0
- package/dist/state.js +177 -0
- package/dist/state.js.map +1 -0
- package/dist/stream/stream-tail.d.ts +17 -0
- package/dist/stream/stream-tail.js +95 -0
- package/dist/stream/stream-tail.js.map +1 -0
- package/dist/stream/stream.d.ts +142 -0
- package/dist/stream/stream.js +251 -0
- package/dist/stream/stream.js.map +1 -0
- package/dist/temp-tracker.d.ts +6 -0
- package/dist/temp-tracker.js +24 -0
- package/dist/temp-tracker.js.map +1 -0
- package/dist/tui/cmux.d.ts +22 -0
- package/dist/tui/cmux.js +82 -0
- package/dist/tui/cmux.js.map +1 -0
- package/dist/tui/components.d.ts +21 -0
- package/dist/tui/components.js +108 -0
- package/dist/tui/components.js.map +1 -0
- package/dist/tui/dashboard.d.ts +6 -0
- package/dist/tui/dashboard.js +125 -0
- package/dist/tui/dashboard.js.map +1 -0
- package/dist/tui/detail-log.d.ts +10 -0
- package/dist/tui/detail-log.js +171 -0
- package/dist/tui/detail-log.js.map +1 -0
- package/dist/types.d.ts +273 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/examples/agents/diff-evaluator.md +57 -0
- package/examples/agents/prompt-tuner.md +30 -0
- package/examples/agents/summarizer.md +14 -0
- package/examples/autoresearch-artifacts/expected-output.md +17 -0
- package/examples/autoresearch-artifacts/prompt.md +35 -0
- package/examples/autoresearch-artifacts/source-material.md +28 -0
- package/examples/business-case.yaml +41 -0
- package/examples/cccp.yaml +48 -0
- package/examples/content-calendar.yaml +59 -0
- package/examples/customer-feedback-loop.yaml +44 -0
- package/examples/design-sprint.yaml +54 -0
- package/examples/feature-development.yaml +96 -0
- package/examples/growth-experiment.yaml +49 -0
- package/examples/incident-runbook.yaml +43 -0
- package/examples/product-launch.yaml +85 -0
- package/examples/prompt-tuning.yaml +25 -0
- package/examples/quarterly-planning.yaml +51 -0
- package/examples/sprint-cycle.yaml +67 -0
- package/package.json +47 -0
package/README.md
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
# CCCP
|
|
2
|
+
|
|
3
|
+
**Claude Code and Cmux Pipeline Reagent** — deterministic YAML-based pipeline orchestration for workflows built around [Claude Code](https://docs.anthropic.com/en/docs/claude-code) and [cmux](https://github.com/manaflow-ai/cmux).
|
|
4
|
+
|
|
5
|
+
## The problem
|
|
6
|
+
|
|
7
|
+
Complex multi-stage workflows (SDLC pipelines, research pipelines, content pipelines) rely on Claude as a "file-routing state machine" — dispatching agents, reading evaluations, routing on PASS/FAIL. Over long runs, context degrades: Claude forgets iteration counts, skips sub-stages, misreads evaluations, or loses routing logic.
|
|
8
|
+
|
|
9
|
+
## The solution
|
|
10
|
+
|
|
11
|
+
CCCP moves the state machine into deterministic TypeScript code. It reads YAML pipeline definitions, dispatches agents via `claude -p` (each with fresh context), parses evaluations with regex, and routes without interpretation. A cmux split-pane dashboard shows live progress. Human approval gates are handled via an MCP server.
|
|
12
|
+
|
|
13
|
+
- Uses Max subscription — no API keys needed
|
|
14
|
+
- Each agent gets a fresh context window
|
|
15
|
+
- Evaluation routing is regex, not interpretation
|
|
16
|
+
- State persists to disk — resume after crashes
|
|
17
|
+
- Works with any project, any agents, any workflow
|
|
18
|
+
|
|
19
|
+
## Install
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
git clone <repo-url> && cd cccp
|
|
23
|
+
npm install
|
|
24
|
+
npm link # makes `cccp` available globally
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Quick start
|
|
28
|
+
|
|
29
|
+
Scaffold a project:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
cd my-project
|
|
33
|
+
cccp init
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
This creates:
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
cccp.yaml # project config (agent paths, MCP profiles)
|
|
40
|
+
pipelines/example.yaml # example pipeline
|
|
41
|
+
agents/ # example agent definitions
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Preview what the pipeline will do:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
cccp run -f pipelines/example.yaml -p my-project --dry-run
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Run it for real:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
cccp run -f pipelines/example.yaml -p my-project
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Pipeline YAML
|
|
57
|
+
|
|
58
|
+
Pipelines are sequences of typed stages:
|
|
59
|
+
|
|
60
|
+
```yaml
|
|
61
|
+
name: my-pipeline
|
|
62
|
+
description: What this pipeline does.
|
|
63
|
+
|
|
64
|
+
stages:
|
|
65
|
+
# Simple agent dispatch
|
|
66
|
+
- name: research
|
|
67
|
+
type: agent
|
|
68
|
+
agent: researcher
|
|
69
|
+
output: "{artifact_dir}/research.md"
|
|
70
|
+
|
|
71
|
+
# Plan-Generate-Evaluate with retry loop
|
|
72
|
+
- name: design
|
|
73
|
+
type: pge
|
|
74
|
+
task: "Design the system architecture."
|
|
75
|
+
inputs:
|
|
76
|
+
- "{artifact_dir}/research.md"
|
|
77
|
+
planner:
|
|
78
|
+
agent: architect
|
|
79
|
+
operation: task-planning
|
|
80
|
+
generator:
|
|
81
|
+
agent: architect
|
|
82
|
+
operation: design # optional sub-operation
|
|
83
|
+
mcp_profile: base # optional MCP server profile
|
|
84
|
+
evaluator:
|
|
85
|
+
agent: reviewer
|
|
86
|
+
contract:
|
|
87
|
+
deliverable: "{artifact_dir}/design.md"
|
|
88
|
+
guidance: "System must be modular with documented data flow."
|
|
89
|
+
max_iterations: 3
|
|
90
|
+
on_fail: stop # stop | skip | human_gate
|
|
91
|
+
|
|
92
|
+
# Human approval gate
|
|
93
|
+
- name: approval
|
|
94
|
+
type: human_gate
|
|
95
|
+
prompt: "Review the design. Approve to proceed."
|
|
96
|
+
artifacts:
|
|
97
|
+
- "{artifact_dir}/design.md"
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Stage types
|
|
101
|
+
|
|
102
|
+
| Type | What it does |
|
|
103
|
+
|------|-------------|
|
|
104
|
+
| `agent` | Dispatch one agent, collect output |
|
|
105
|
+
| `pge` | Dispatch planner -> evaluator writes contract -> dispatch generator -> dispatch evaluator -> parse `### Overall: PASS/FAIL` -> retry generator/evaluator on FAIL up to `max_iterations` |
|
|
106
|
+
| `human_gate` | Block until approved via MCP tool call or state file edit |
|
|
107
|
+
|
|
108
|
+
### Variables
|
|
109
|
+
|
|
110
|
+
Built-in variables available in all string fields:
|
|
111
|
+
|
|
112
|
+
| Variable | Value |
|
|
113
|
+
|----------|-------|
|
|
114
|
+
| `{project}` | Project name from `--project` |
|
|
115
|
+
| `{project_dir}` | Project directory |
|
|
116
|
+
| `{artifact_dir}` | Resolved artifact output directory |
|
|
117
|
+
| `{pipeline_name}` | Pipeline name |
|
|
118
|
+
| `{iteration}` | Current PGE iteration (1-based) |
|
|
119
|
+
|
|
120
|
+
## Agents
|
|
121
|
+
|
|
122
|
+
CCCP ships no agents — you bring your own. Agents are markdown files that become the `--system-prompt-file` for `claude -p`.
|
|
123
|
+
|
|
124
|
+
**Flat file agent** (`agents/implementer.md`):
|
|
125
|
+
```markdown
|
|
126
|
+
---
|
|
127
|
+
name: implementer
|
|
128
|
+
description: Implements code changes.
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
# Implementer Agent
|
|
132
|
+
|
|
133
|
+
Your instructions here...
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**Directory agent with operations** (`agents/architect/`):
|
|
137
|
+
```
|
|
138
|
+
agents/architect/
|
|
139
|
+
agent.md # base instructions (always included)
|
|
140
|
+
health-assessment.md # operation: health-assessment
|
|
141
|
+
plan-authoring.md # operation: plan-authoring
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Reference an operation in the pipeline:
|
|
145
|
+
```yaml
|
|
146
|
+
generator:
|
|
147
|
+
agent: architect
|
|
148
|
+
operation: plan-authoring
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Agent search paths
|
|
152
|
+
|
|
153
|
+
CCCP searches for agents in order (first match wins):
|
|
154
|
+
|
|
155
|
+
1. `agents/` relative to the pipeline YAML file
|
|
156
|
+
2. `<project>/.claude/agents/`
|
|
157
|
+
3. `<project>/agents/`
|
|
158
|
+
4. Paths listed in `cccp.yaml` → `agent_paths`
|
|
159
|
+
|
|
160
|
+
## Project config (`cccp.yaml`)
|
|
161
|
+
|
|
162
|
+
Place at your project root:
|
|
163
|
+
|
|
164
|
+
```yaml
|
|
165
|
+
agent_paths:
|
|
166
|
+
- ./agents
|
|
167
|
+
- ./vendor/shared-agents
|
|
168
|
+
|
|
169
|
+
mcp_profiles:
|
|
170
|
+
base:
|
|
171
|
+
servers:
|
|
172
|
+
qmd:
|
|
173
|
+
command: qmd
|
|
174
|
+
args: [serve, --stdio]
|
|
175
|
+
design:
|
|
176
|
+
extends: base
|
|
177
|
+
servers:
|
|
178
|
+
figma:
|
|
179
|
+
command: npx
|
|
180
|
+
args: [-y, figma-console-mcp]
|
|
181
|
+
|
|
182
|
+
artifact_dir: docs/projects/{project}/{pipeline_name}
|
|
183
|
+
default_mcp_profile: base
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
MCP profiles use `extends` for inheritance. Each agent gets only the servers its profile specifies via `--strict-mcp-config`.
|
|
187
|
+
|
|
188
|
+
## Evaluation format
|
|
189
|
+
|
|
190
|
+
Evaluator agents must produce files containing this line:
|
|
191
|
+
|
|
192
|
+
```markdown
|
|
193
|
+
### Overall: PASS
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
or
|
|
197
|
+
|
|
198
|
+
```markdown
|
|
199
|
+
### Overall: FAIL
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
CCCP reads only this line. Everything else in the evaluation (criterion tables, iteration guidance) is for the generator agent on retry.
|
|
203
|
+
|
|
204
|
+
## CLI reference
|
|
205
|
+
|
|
206
|
+
```
|
|
207
|
+
cccp run -f <pipeline.yaml> -p <project> [options]
|
|
208
|
+
--dry-run Show what would execute without running agents
|
|
209
|
+
--headless Auto-approve all human gates
|
|
210
|
+
-d, --project-dir Project directory (default: cwd)
|
|
211
|
+
-a, --artifact-dir Override artifact output directory
|
|
212
|
+
-v, --var key=value Set pipeline variables (repeatable)
|
|
213
|
+
|
|
214
|
+
cccp resume -p <project> -r <run-id-prefix> [--headless]
|
|
215
|
+
Resume an interrupted pipeline from the last incomplete stage
|
|
216
|
+
|
|
217
|
+
cccp dashboard -r <run-id-prefix>
|
|
218
|
+
Launch the TUI dashboard to monitor a running pipeline
|
|
219
|
+
|
|
220
|
+
cccp gate-server
|
|
221
|
+
Start the MCP server for pipeline gate interaction
|
|
222
|
+
|
|
223
|
+
cccp init [--dir <path>]
|
|
224
|
+
Scaffold cccp.yaml, example pipeline, and example agents
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## Gate interaction
|
|
228
|
+
|
|
229
|
+
When a pipeline hits a `human_gate` stage, it writes a pending gate to the SQLite state database (`.cccp/cccp.db`) and waits.
|
|
230
|
+
|
|
231
|
+
**Option 1: MCP server** — Register the gate server in your project's `.mcp.json`:
|
|
232
|
+
|
|
233
|
+
```json
|
|
234
|
+
{
|
|
235
|
+
"mcpServers": {
|
|
236
|
+
"cccp-gate": {
|
|
237
|
+
"command": "npx",
|
|
238
|
+
"args": ["tsx", "/path/to/cccp/src/cli.ts", "gate-server"]
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Then from Claude Code: call `pipeline_status` to see what's pending, `pipeline_gate_respond` to approve/reject.
|
|
245
|
+
|
|
246
|
+
**Option 2: Headless** — `cccp run --headless` auto-approves all gates.
|
|
247
|
+
|
|
248
|
+
## State & resume
|
|
249
|
+
|
|
250
|
+
Pipeline state is persisted to a SQLite database at `{projectDir}/.cccp/cccp.db` after every transition (stage start, planner dispatch, contract dispatch, generator dispatch, evaluator dispatch, routing decision). If a run is interrupted:
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
cccp resume -p my-project -r <run-id-prefix>
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
Completed stages are skipped. PGE stages resume at the correct iteration and sub-step.
|
|
257
|
+
|
|
258
|
+
## cmux integration
|
|
259
|
+
|
|
260
|
+
When running inside a [cmux](https://github.com/manaflow-ai/cmux) workspace (`CMUX_WORKSPACE_ID` is set), CCCP automatically:
|
|
261
|
+
|
|
262
|
+
- Updates the sidebar status pill with current stage
|
|
263
|
+
- Sets the progress bar
|
|
264
|
+
- Sends desktop notifications for gates and pipeline completion
|
|
265
|
+
- Can open the dashboard in a cmux split pane
|
|
266
|
+
|
|
267
|
+
Without cmux, CCCP falls back to plain terminal output.
|
|
268
|
+
|
|
269
|
+
## Development
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
npm test # run all tests (143 tests)
|
|
273
|
+
npm run typecheck # tsc --noEmit
|
|
274
|
+
npm run test:watch # watch mode
|
|
275
|
+
npm run build # compile TypeScript to dist/
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## License
|
|
279
|
+
|
|
280
|
+
MIT
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { EventEmitter } from "node:events";
|
|
2
|
+
/**
|
|
3
|
+
* Module-level singleton event bus for passing agent activity updates
|
|
4
|
+
* from the runner to the TUI dashboard within the same process.
|
|
5
|
+
*
|
|
6
|
+
* The runner publishes: activityBus.emit("activity", agentActivity)
|
|
7
|
+
* The dashboard subscribes: activityBus.on("activity", handler)
|
|
8
|
+
*/
|
|
9
|
+
export declare const activityBus: EventEmitter<[never]>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { EventEmitter } from "node:events";
|
|
2
|
+
/**
|
|
3
|
+
* Module-level singleton event bus for passing agent activity updates
|
|
4
|
+
* from the runner to the TUI dashboard within the same process.
|
|
5
|
+
*
|
|
6
|
+
* The runner publishes: activityBus.emit("activity", agentActivity)
|
|
7
|
+
* The dashboard subscribes: activityBus.on("activity", handler)
|
|
8
|
+
*/
|
|
9
|
+
export const activityBus = new EventEmitter();
|
|
10
|
+
//# sourceMappingURL=activity-bus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activity-bus.js","sourceRoot":"","sources":["../src/activity-bus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,YAAY,EAAE,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface ResolvedAgent {
|
|
2
|
+
/** Absolute path to the agent's main markdown file. */
|
|
3
|
+
agentPath: string;
|
|
4
|
+
/** Absolute path to the operation file (if applicable). */
|
|
5
|
+
operationPath?: string;
|
|
6
|
+
/** Whether this is a directory-style agent. */
|
|
7
|
+
isDirectory: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Resolve an agent name to file path(s) by searching configured directories.
|
|
11
|
+
*
|
|
12
|
+
* Search order (first match wins):
|
|
13
|
+
* 1. Each directory in `searchPaths`, in order
|
|
14
|
+
*
|
|
15
|
+
* For each search directory, tries:
|
|
16
|
+
* - `<dir>/<agent>.md` — flat-file agent
|
|
17
|
+
* - `<dir>/<agent>/agent.md` — directory-style agent
|
|
18
|
+
*
|
|
19
|
+
* If an `operation` is specified and the agent is directory-style:
|
|
20
|
+
* - Also resolves `<dir>/<agent>/<operation>.md`
|
|
21
|
+
*
|
|
22
|
+
* If the agent name already ends in `.md` or contains a path separator,
|
|
23
|
+
* it's treated as a direct path (absolute or relative to projectDir).
|
|
24
|
+
*/
|
|
25
|
+
export declare function resolveAgent(agentName: string, searchPaths: string[], operation?: string, projectDir?: string): Promise<ResolvedAgent>;
|
|
26
|
+
/**
|
|
27
|
+
* List all available operations for a directory-style agent.
|
|
28
|
+
*/
|
|
29
|
+
export declare function listOperations(agentName: string, searchPaths: string[]): Promise<string[]>;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { access, readdir } from "node:fs/promises";
|
|
2
|
+
import { resolve, join, basename, dirname } from "node:path";
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Resolution logic
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
/**
|
|
7
|
+
* Resolve an agent name to file path(s) by searching configured directories.
|
|
8
|
+
*
|
|
9
|
+
* Search order (first match wins):
|
|
10
|
+
* 1. Each directory in `searchPaths`, in order
|
|
11
|
+
*
|
|
12
|
+
* For each search directory, tries:
|
|
13
|
+
* - `<dir>/<agent>.md` — flat-file agent
|
|
14
|
+
* - `<dir>/<agent>/agent.md` — directory-style agent
|
|
15
|
+
*
|
|
16
|
+
* If an `operation` is specified and the agent is directory-style:
|
|
17
|
+
* - Also resolves `<dir>/<agent>/<operation>.md`
|
|
18
|
+
*
|
|
19
|
+
* If the agent name already ends in `.md` or contains a path separator,
|
|
20
|
+
* it's treated as a direct path (absolute or relative to projectDir).
|
|
21
|
+
*/
|
|
22
|
+
export async function resolveAgent(agentName, searchPaths, operation, projectDir) {
|
|
23
|
+
// Direct path — skip search if agent looks like a path.
|
|
24
|
+
if (agentName.includes("/") || agentName.endsWith(".md")) {
|
|
25
|
+
return resolveDirectPath(agentName, operation, projectDir);
|
|
26
|
+
}
|
|
27
|
+
// Search configured paths.
|
|
28
|
+
for (const searchDir of searchPaths) {
|
|
29
|
+
// Try flat file: <dir>/<agent>.md
|
|
30
|
+
const flatPath = join(searchDir, `${agentName}.md`);
|
|
31
|
+
if (await fileExists(flatPath)) {
|
|
32
|
+
if (operation) {
|
|
33
|
+
// Flat file agents don't have operations — check if there's a
|
|
34
|
+
// sibling directory with the operation file.
|
|
35
|
+
const opPath = join(searchDir, agentName, `${operation}.md`);
|
|
36
|
+
if (await fileExists(opPath)) {
|
|
37
|
+
// There's actually a directory-style agent alongside the flat file.
|
|
38
|
+
const dirAgentPath = join(searchDir, agentName, "agent.md");
|
|
39
|
+
if (await fileExists(dirAgentPath)) {
|
|
40
|
+
return {
|
|
41
|
+
agentPath: dirAgentPath,
|
|
42
|
+
operationPath: opPath,
|
|
43
|
+
isDirectory: true,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
throw new Error(`Agent "${agentName}" is a flat file and does not support operation "${operation}"`);
|
|
48
|
+
}
|
|
49
|
+
return { agentPath: flatPath, isDirectory: false };
|
|
50
|
+
}
|
|
51
|
+
// Try directory: <dir>/<agent>/agent.md
|
|
52
|
+
const dirAgentPath = join(searchDir, agentName, "agent.md");
|
|
53
|
+
if (await fileExists(dirAgentPath)) {
|
|
54
|
+
let operationPath;
|
|
55
|
+
if (operation) {
|
|
56
|
+
operationPath = join(searchDir, agentName, `${operation}.md`);
|
|
57
|
+
if (!(await fileExists(operationPath))) {
|
|
58
|
+
throw new Error(`Operation "${operation}" not found for agent "${agentName}" at: ${operationPath}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
agentPath: dirAgentPath,
|
|
63
|
+
operationPath,
|
|
64
|
+
isDirectory: true,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
const searched = searchPaths.map((p) => ` - ${p}`).join("\n");
|
|
69
|
+
throw new Error(`Agent "${agentName}" not found. Searched:\n${searched}`);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* List all available operations for a directory-style agent.
|
|
73
|
+
*/
|
|
74
|
+
export async function listOperations(agentName, searchPaths) {
|
|
75
|
+
for (const searchDir of searchPaths) {
|
|
76
|
+
const agentDir = join(searchDir, agentName);
|
|
77
|
+
try {
|
|
78
|
+
const entries = await readdir(agentDir);
|
|
79
|
+
return entries
|
|
80
|
+
.filter((e) => e.endsWith(".md") && e !== "agent.md")
|
|
81
|
+
.map((e) => e.replace(/\.md$/, ""));
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return [];
|
|
88
|
+
}
|
|
89
|
+
// ---------------------------------------------------------------------------
|
|
90
|
+
// Helpers
|
|
91
|
+
// ---------------------------------------------------------------------------
|
|
92
|
+
async function resolveDirectPath(agentPath, operation, projectDir) {
|
|
93
|
+
const absPath = projectDir
|
|
94
|
+
? resolve(projectDir, agentPath)
|
|
95
|
+
: resolve(agentPath);
|
|
96
|
+
if (!(await fileExists(absPath))) {
|
|
97
|
+
throw new Error(`Agent file not found: ${absPath}`);
|
|
98
|
+
}
|
|
99
|
+
// Check if it's a directory-style agent (path ends with agent.md).
|
|
100
|
+
const isDir = basename(absPath) === "agent.md";
|
|
101
|
+
let operationPath;
|
|
102
|
+
if (operation) {
|
|
103
|
+
if (!isDir) {
|
|
104
|
+
throw new Error(`Agent at "${absPath}" is a flat file and does not support operation "${operation}"`);
|
|
105
|
+
}
|
|
106
|
+
operationPath = resolve(dirname(absPath), `${operation}.md`);
|
|
107
|
+
if (!(await fileExists(operationPath))) {
|
|
108
|
+
throw new Error(`Operation "${operation}" not found at: ${operationPath}`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return { agentPath: absPath, operationPath, isDirectory: isDir };
|
|
112
|
+
}
|
|
113
|
+
async function fileExists(path) {
|
|
114
|
+
try {
|
|
115
|
+
await access(path);
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=agent-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-resolver.js","sourceRoot":"","sources":["../src/agent-resolver.ts"],"names":[],"mappings":"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"}
|
package/dist/agent.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { AgentResult } from "./types.js";
|
|
2
|
+
export interface DispatchOptions {
|
|
3
|
+
/** The user prompt (task context) passed via -p. */
|
|
4
|
+
userPrompt: string;
|
|
5
|
+
/** Path to the system prompt file (agent markdown). */
|
|
6
|
+
systemPromptFile: string;
|
|
7
|
+
/** Path to MCP config JSON file, if any. */
|
|
8
|
+
mcpConfigFile?: string;
|
|
9
|
+
/** Explicit list of allowed tools. */
|
|
10
|
+
allowedTools?: string[];
|
|
11
|
+
/** Expected output file path (to check existence after). */
|
|
12
|
+
expectedOutput?: string;
|
|
13
|
+
/** Working directory for the subprocess. */
|
|
14
|
+
cwd: string;
|
|
15
|
+
/** If true, print the command instead of running it. */
|
|
16
|
+
dryRun?: boolean;
|
|
17
|
+
/** Agent name (for stream logging). */
|
|
18
|
+
agentName?: string;
|
|
19
|
+
/** Directory for stream log files (.stream.jsonl). */
|
|
20
|
+
streamLogDir?: string;
|
|
21
|
+
/** Callback for stream activity updates. */
|
|
22
|
+
onActivity?: (activity: import("./stream/stream.js").AgentActivity) => void;
|
|
23
|
+
/** Claude config directory (CLAUDE_CONFIG_DIR). */
|
|
24
|
+
claudeConfigDir?: string;
|
|
25
|
+
/** Permission mode for the agent subprocess (default: bypassPermissions). */
|
|
26
|
+
permissionMode?: string;
|
|
27
|
+
/** Suppress agent stderr (when TUI dashboard is rendering). */
|
|
28
|
+
quiet?: boolean;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Dispatch an agent by spawning `claude` as a child process.
|
|
32
|
+
*
|
|
33
|
+
* Agents inherit the project's CLAUDE.md, hooks, and auth context.
|
|
34
|
+
* The agent's markdown definition is appended via --append-system-prompt-file.
|
|
35
|
+
*
|
|
36
|
+
* Returns an AgentResult with exit code, output existence check, and duration.
|
|
37
|
+
* In dry-run mode, prints the command and returns a synthetic success result.
|
|
38
|
+
*/
|
|
39
|
+
export declare function dispatchAgent(opts: DispatchOptions): Promise<AgentResult>;
|
package/dist/agent.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { access } from "node:fs/promises";
|
|
3
|
+
import { StreamParser } from "./stream/stream.js";
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
// Build the claude CLI argument list
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
function buildArgs(opts) {
|
|
8
|
+
const args = [
|
|
9
|
+
"-p",
|
|
10
|
+
opts.userPrompt,
|
|
11
|
+
"--append-system-prompt-file",
|
|
12
|
+
opts.systemPromptFile,
|
|
13
|
+
"--output-format",
|
|
14
|
+
"stream-json",
|
|
15
|
+
"--verbose",
|
|
16
|
+
];
|
|
17
|
+
if (opts.mcpConfigFile) {
|
|
18
|
+
args.push("--mcp-config", opts.mcpConfigFile);
|
|
19
|
+
args.push("--strict-mcp-config");
|
|
20
|
+
}
|
|
21
|
+
if (opts.allowedTools?.length) {
|
|
22
|
+
args.push("--allowedTools", opts.allowedTools.join(","));
|
|
23
|
+
}
|
|
24
|
+
// Permission mode — default to bypassPermissions for pipeline agents.
|
|
25
|
+
const mode = opts.permissionMode ?? "bypassPermissions";
|
|
26
|
+
args.push("--permission-mode", mode);
|
|
27
|
+
return args;
|
|
28
|
+
}
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// Dispatch
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
/**
|
|
33
|
+
* Dispatch an agent by spawning `claude` as a child process.
|
|
34
|
+
*
|
|
35
|
+
* Agents inherit the project's CLAUDE.md, hooks, and auth context.
|
|
36
|
+
* The agent's markdown definition is appended via --append-system-prompt-file.
|
|
37
|
+
*
|
|
38
|
+
* Returns an AgentResult with exit code, output existence check, and duration.
|
|
39
|
+
* In dry-run mode, prints the command and returns a synthetic success result.
|
|
40
|
+
*/
|
|
41
|
+
export async function dispatchAgent(opts) {
|
|
42
|
+
const args = buildArgs(opts);
|
|
43
|
+
if (opts.dryRun) {
|
|
44
|
+
console.log("\n[dry-run] Would execute:");
|
|
45
|
+
console.log(` claude ${args.map((a) => (a.includes(" ") ? `"${a}"` : a)).join(" ")}`);
|
|
46
|
+
console.log(` cwd: ${opts.cwd}`);
|
|
47
|
+
if (opts.claudeConfigDir) {
|
|
48
|
+
console.log(` CLAUDE_CONFIG_DIR: ${opts.claudeConfigDir}`);
|
|
49
|
+
}
|
|
50
|
+
if (opts.expectedOutput) {
|
|
51
|
+
console.log(` expected output: ${opts.expectedOutput}`);
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
exitCode: 0,
|
|
55
|
+
outputPath: opts.expectedOutput,
|
|
56
|
+
outputExists: false,
|
|
57
|
+
durationMs: 0,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
const start = Date.now();
|
|
61
|
+
const agentName = opts.agentName ?? "agent";
|
|
62
|
+
// Set up stream parser for event processing and logging.
|
|
63
|
+
const parser = new StreamParser(agentName);
|
|
64
|
+
if (opts.streamLogDir) {
|
|
65
|
+
const logPath = `${opts.streamLogDir}/${agentName}.stream.jsonl`;
|
|
66
|
+
await parser.startLog(logPath);
|
|
67
|
+
}
|
|
68
|
+
if (opts.onActivity) {
|
|
69
|
+
parser.on("activity", opts.onActivity);
|
|
70
|
+
}
|
|
71
|
+
// Build environment — inherit parent env, set CLAUDE_CONFIG_DIR if configured.
|
|
72
|
+
const env = { ...process.env };
|
|
73
|
+
if (opts.claudeConfigDir) {
|
|
74
|
+
env.CLAUDE_CONFIG_DIR = opts.claudeConfigDir;
|
|
75
|
+
}
|
|
76
|
+
const exitCode = await new Promise((resolve, reject) => {
|
|
77
|
+
const child = spawn("claude", args, {
|
|
78
|
+
cwd: opts.cwd,
|
|
79
|
+
env,
|
|
80
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
81
|
+
});
|
|
82
|
+
// Feed stdout through stream parser.
|
|
83
|
+
child.stdout.on("data", (chunk) => {
|
|
84
|
+
parser.feed(chunk.toString());
|
|
85
|
+
});
|
|
86
|
+
// Stderr goes to parent stderr (unless TUI is active).
|
|
87
|
+
if (!opts.quiet) {
|
|
88
|
+
child.stderr.pipe(process.stderr);
|
|
89
|
+
}
|
|
90
|
+
child.on("error", (err) => {
|
|
91
|
+
parser.flush();
|
|
92
|
+
reject(new Error(`Failed to spawn claude: ${err.message}`));
|
|
93
|
+
});
|
|
94
|
+
child.on("close", (code) => {
|
|
95
|
+
parser.flush();
|
|
96
|
+
resolve(code ?? 1);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
const durationMs = Date.now() - start;
|
|
100
|
+
let outputExists = false;
|
|
101
|
+
if (opts.expectedOutput) {
|
|
102
|
+
try {
|
|
103
|
+
await access(opts.expectedOutput);
|
|
104
|
+
outputExists = true;
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
outputExists = false;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
exitCode,
|
|
112
|
+
outputPath: opts.expectedOutput,
|
|
113
|
+
outputExists,
|
|
114
|
+
durationMs,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AutoresearchStage, AutoresearchResult, RunContext, PipelineState } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Execute a full Adjust-Execute-Evaluate cycle for an autoresearch stage.
|
|
4
|
+
*
|
|
5
|
+
* 1. [iter > 1] Dispatch adjuster → modifies the artifact
|
|
6
|
+
* 2. Dispatch executor → produces output using current artifact
|
|
7
|
+
* 3. Dispatch evaluator → compares output against ground truth
|
|
8
|
+
* 4. Parse evaluation (regex on ### Overall: PASS/FAIL)
|
|
9
|
+
* 5. Route: PASS → done, FAIL + max reached → escalate, FAIL → continue
|
|
10
|
+
*/
|
|
11
|
+
export declare function runAutoresearchCycle(stage: AutoresearchStage, ctx: RunContext, state: PipelineState, onProgress?: (eventType?: string, eventData?: Record<string, unknown>) => Promise<void>): Promise<AutoresearchResult>;
|