@oisincoveney/pipeline 1.0.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/commands/work-next.md +20 -0
- package/README.md +224 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +189843 -0
- package/dist/install-commands.d.ts +23 -0
- package/dist/mastra/backlog.d.ts +50 -0
- package/dist/mastra/gates.d.ts +22 -0
- package/dist/mastra/index.d.ts +22 -0
- package/dist/mastra/pipeline-primitive.d.ts +17 -0
- package/dist/mastra/pipeline-primitive.js +187349 -0
- package/dist/mastra/runner.d.ts +18 -0
- package/dist/mastra/runner.js +7298 -0
- package/dist/mastra/steps/green.d.ts +17 -0
- package/dist/mastra/steps/knowledge-inject.d.ts +12 -0
- package/dist/mastra/steps/learn.d.ts +10 -0
- package/dist/mastra/steps/red.d.ts +17 -0
- package/dist/mastra/steps/research.d.ts +15 -0
- package/dist/mastra/steps/verify.d.ts +17 -0
- package/dist/mastra/workflows/pipeline.d.ts +70 -0
- package/docs/slash-command-adapter-contract.md +74 -0
- package/package.json +70 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type AgentAdapter, type Harness } from "../runner.js";
|
|
2
|
+
interface GreenOptions {
|
|
3
|
+
agentAdapter?: AgentAdapter;
|
|
4
|
+
contextFile: string | null;
|
|
5
|
+
harness: Harness;
|
|
6
|
+
maxRetries?: number;
|
|
7
|
+
prompt: string;
|
|
8
|
+
worktreePath: string;
|
|
9
|
+
}
|
|
10
|
+
interface GreenResult {
|
|
11
|
+
failingTests: string[];
|
|
12
|
+
greenGatePassed: boolean;
|
|
13
|
+
testOutput: string;
|
|
14
|
+
typecheckOutput: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function runGreen(opts: GreenOptions): Promise<GreenResult>;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const KNOWLEDGE_CONTEXT_FILE = "knowledge-context.md";
|
|
2
|
+
export declare const MAX_KNOWLEDGE_CONTEXT_CHARS = 64000;
|
|
3
|
+
interface KnowledgeContextOptions {
|
|
4
|
+
maxChars?: number;
|
|
5
|
+
}
|
|
6
|
+
interface KnowledgeContextFile {
|
|
7
|
+
context: string;
|
|
8
|
+
contextFile: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function buildKnowledgeContext(worktreePath: string, options?: KnowledgeContextOptions): string;
|
|
11
|
+
export declare function writeKnowledgeContextFile(worktreePath: string, options?: KnowledgeContextOptions): Promise<KnowledgeContextFile>;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { GateViolation } from "../gates.js";
|
|
2
|
+
interface LearnOptions {
|
|
3
|
+
outcome: "PASS" | "FAIL";
|
|
4
|
+
taskDescription: string;
|
|
5
|
+
testOutput: string;
|
|
6
|
+
violations: GateViolation[];
|
|
7
|
+
worktreePath: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function runLearn(opts: LearnOptions): Promise<void>;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type AgentAdapter, type Harness } from "../runner.js";
|
|
2
|
+
interface RedOptions {
|
|
3
|
+
agentAdapter?: AgentAdapter;
|
|
4
|
+
contextFile: string | null;
|
|
5
|
+
harness: Harness;
|
|
6
|
+
maxRetries?: number;
|
|
7
|
+
prompt: string;
|
|
8
|
+
worktreePath: string;
|
|
9
|
+
}
|
|
10
|
+
interface RedResult {
|
|
11
|
+
failingTests: string[];
|
|
12
|
+
output: string;
|
|
13
|
+
reason: string;
|
|
14
|
+
redGatePassed: boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare function runRed(opts: RedOptions): Promise<RedResult>;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type AgentAdapter, type Harness } from "../runner.js";
|
|
2
|
+
interface ResearchOptions {
|
|
3
|
+
agentAdapter?: AgentAdapter;
|
|
4
|
+
contextFile: string | null;
|
|
5
|
+
harness: Harness;
|
|
6
|
+
maxRetries?: number;
|
|
7
|
+
prompt: string;
|
|
8
|
+
worktreePath: string;
|
|
9
|
+
}
|
|
10
|
+
interface ResearchResult {
|
|
11
|
+
exitCode: number;
|
|
12
|
+
output: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function runResearch(opts: ResearchOptions): Promise<ResearchResult>;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { GateViolation } from "../gates.js";
|
|
2
|
+
import { type AgentAdapter, type Harness } from "../runner.js";
|
|
3
|
+
interface VerifyOptions {
|
|
4
|
+
agentAdapter?: AgentAdapter;
|
|
5
|
+
contextFile: string | null;
|
|
6
|
+
harness: Harness;
|
|
7
|
+
prompt: string;
|
|
8
|
+
worktreePath: string;
|
|
9
|
+
}
|
|
10
|
+
interface VerifyResult {
|
|
11
|
+
llmEvidence: string[];
|
|
12
|
+
llmVerdict: "PASS" | "FAIL";
|
|
13
|
+
passed: boolean;
|
|
14
|
+
violations: GateViolation[];
|
|
15
|
+
}
|
|
16
|
+
export declare function runVerify(opts: VerifyOptions): Promise<VerifyResult>;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
declare const withVerify: z.ZodObject<{
|
|
3
|
+
task: z.ZodString;
|
|
4
|
+
harness: z.ZodEnum<{
|
|
5
|
+
claude: "claude";
|
|
6
|
+
opencode: "opencode";
|
|
7
|
+
codex: "codex";
|
|
8
|
+
pi: "pi";
|
|
9
|
+
}>;
|
|
10
|
+
worktreePath: z.ZodString;
|
|
11
|
+
context: z.ZodString;
|
|
12
|
+
contextFile: z.ZodString;
|
|
13
|
+
researchOutput: z.ZodString;
|
|
14
|
+
redGatePassed: z.ZodBoolean;
|
|
15
|
+
redGateReason: z.ZodString;
|
|
16
|
+
redTestOutput: z.ZodString;
|
|
17
|
+
failingTests: z.ZodArray<z.ZodString>;
|
|
18
|
+
greenGatePassed: z.ZodBoolean;
|
|
19
|
+
testOutput: z.ZodString;
|
|
20
|
+
typecheckOutput: z.ZodString;
|
|
21
|
+
verifyPassed: z.ZodBoolean;
|
|
22
|
+
llmVerdict: z.ZodEnum<{
|
|
23
|
+
PASS: "PASS";
|
|
24
|
+
FAIL: "FAIL";
|
|
25
|
+
}>;
|
|
26
|
+
llmEvidence: z.ZodArray<z.ZodString>;
|
|
27
|
+
violations: z.ZodArray<z.ZodObject<{
|
|
28
|
+
file: z.ZodString;
|
|
29
|
+
message: z.ZodString;
|
|
30
|
+
line: z.ZodOptional<z.ZodNumber>;
|
|
31
|
+
}, z.core.$strip>>;
|
|
32
|
+
}, z.core.$strip>;
|
|
33
|
+
declare const pipelineOutput: z.ZodObject<{
|
|
34
|
+
outcome: z.ZodEnum<{
|
|
35
|
+
PASS: "PASS";
|
|
36
|
+
FAIL: "FAIL";
|
|
37
|
+
}>;
|
|
38
|
+
failureDetails: z.ZodArray<z.ZodObject<{
|
|
39
|
+
gate: z.ZodEnum<{
|
|
40
|
+
RED: "RED";
|
|
41
|
+
GREEN: "GREEN";
|
|
42
|
+
VERIFY: "VERIFY";
|
|
43
|
+
}>;
|
|
44
|
+
reason: z.ZodString;
|
|
45
|
+
evidence: z.ZodArray<z.ZodString>;
|
|
46
|
+
}, z.core.$strip>>;
|
|
47
|
+
}, z.core.$strip>;
|
|
48
|
+
type PipelineOutput = z.infer<typeof pipelineOutput>;
|
|
49
|
+
type PipelineEvaluationInput = z.infer<typeof withVerify>;
|
|
50
|
+
export declare function evaluatePipelineOutcome(inputData: PipelineEvaluationInput): PipelineOutput;
|
|
51
|
+
export declare const pipelineWorkflow: import("@mastra/core/workflows").Workflow<import("@mastra/core/workflows").DefaultEngineType, import("@mastra/core/workflows").Step<string, unknown, unknown, unknown, unknown, unknown, any, unknown>[], "ralph-loop", unknown, {
|
|
52
|
+
task: string;
|
|
53
|
+
harness: "claude" | "opencode" | "codex" | "pi";
|
|
54
|
+
worktreePath: string;
|
|
55
|
+
}, {
|
|
56
|
+
outcome: "PASS" | "FAIL";
|
|
57
|
+
failureDetails: {
|
|
58
|
+
gate: "RED" | "GREEN" | "VERIFY";
|
|
59
|
+
reason: string;
|
|
60
|
+
evidence: string[];
|
|
61
|
+
}[];
|
|
62
|
+
}, {
|
|
63
|
+
outcome: "PASS" | "FAIL";
|
|
64
|
+
failureDetails: {
|
|
65
|
+
gate: "RED" | "GREEN" | "VERIFY";
|
|
66
|
+
reason: string;
|
|
67
|
+
evidence: string[];
|
|
68
|
+
}[];
|
|
69
|
+
}, unknown>;
|
|
70
|
+
export {};
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Slash Command Adapter Contract
|
|
2
|
+
|
|
3
|
+
The reusable primitive is `runPipelinePrimitive(input, adapters)` from
|
|
4
|
+
`src/mastra/pipeline-primitive.ts`. Slash-command hosts call that primitive with
|
|
5
|
+
an in-process `AgentAdapter`; the shell CLI calls the same primitive with the
|
|
6
|
+
subprocess adapter from `src/mastra/runner.ts`.
|
|
7
|
+
|
|
8
|
+
For normal project installation, run:
|
|
9
|
+
|
|
10
|
+
```sh
|
|
11
|
+
bunx @oisincoveney/pipeline install-commands --host all
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
The installer writes generated command files into the current repository. Re-run
|
|
15
|
+
it after package updates. It is idempotent, supports `--dry-run`, supports
|
|
16
|
+
`--check`, and refuses to overwrite manually edited files unless `--force` is
|
|
17
|
+
passed.
|
|
18
|
+
|
|
19
|
+
## Primitive Input
|
|
20
|
+
|
|
21
|
+
Slash commands must supply:
|
|
22
|
+
|
|
23
|
+
- `task`: the command arguments or selected ticket text.
|
|
24
|
+
- `worktreePath`: the repository root or task worktree the host is currently
|
|
25
|
+
editing.
|
|
26
|
+
- `harness`: the host name, one of `claude`, `codex`, `opencode`, or `pi`.
|
|
27
|
+
|
|
28
|
+
## Agent Adapter
|
|
29
|
+
|
|
30
|
+
The host adapter implements:
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
interface AgentAdapter {
|
|
34
|
+
run(request: {
|
|
35
|
+
contextFile: string | null;
|
|
36
|
+
harness: "claude" | "codex" | "opencode" | "pi";
|
|
37
|
+
prompt: string;
|
|
38
|
+
role: "researcher" | "test-writer" | "code-writer" | "verifier";
|
|
39
|
+
worktreePath: string;
|
|
40
|
+
}): Promise<{ exitCode: number; stdout: string }>;
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The primitive owns the phase order and gates. The adapter only maps each role to
|
|
45
|
+
the host's native execution mechanism.
|
|
46
|
+
|
|
47
|
+
## Host Mappings
|
|
48
|
+
|
|
49
|
+
| Host | Task input | Target path | Agent execution | Phase reporting |
|
|
50
|
+
| --- | --- | --- | --- | --- |
|
|
51
|
+
| Host | Generated file | Invocation |
|
|
52
|
+
| --- | --- | --- |
|
|
53
|
+
| Claude Code | `.claude/commands/work-next.md` | `/work-next <ticket id or task description>` |
|
|
54
|
+
| OpenCode | `.opencode/commands/work-next.md` | `/work-next <ticket id or task description>` |
|
|
55
|
+
| Pi | `.pi/prompts/work-next.md` | `/work-next <ticket id or task description>` |
|
|
56
|
+
| Codex | `.agents/skills/work-next/SKILL.md` | `/use work-next <ticket id or task description>` |
|
|
57
|
+
|
|
58
|
+
Codex currently does not support project-defined custom slash commands in the
|
|
59
|
+
same way as Claude Code and OpenCode, so the installer generates a project skill
|
|
60
|
+
instead of pretending that `/work-next` is available.
|
|
61
|
+
|
|
62
|
+
## Phase Reporter
|
|
63
|
+
|
|
64
|
+
Slash hosts may pass:
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
interface PipelinePhaseReporter {
|
|
68
|
+
started?(phase: "research" | "red" | "green" | "verify" | "learn"): void | Promise<void>;
|
|
69
|
+
completed?(phase: "research" | "red" | "green" | "verify" | "learn"): void | Promise<void>;
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Use this for native UI updates. The primitive returns the same
|
|
74
|
+
`{ outcome, failureDetails }` shape used by the CLI.
|
package/package.json
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"dependencies": {
|
|
3
|
+
"@mastra/core": "^1.35.0",
|
|
4
|
+
"@mastra/libsql": "^1.11.0",
|
|
5
|
+
"@mastra/memory": "^1.18.2",
|
|
6
|
+
"commander": "^14.0.3",
|
|
7
|
+
"execa": "^9.5.2",
|
|
8
|
+
"zod": "^4.4.3"
|
|
9
|
+
},
|
|
10
|
+
"devDependencies": {
|
|
11
|
+
"@biomejs/biome": "2.4.15",
|
|
12
|
+
"@types/node": "^25.9.1",
|
|
13
|
+
"jscpd": "^4.0.5",
|
|
14
|
+
"mastra": "^1.9.3",
|
|
15
|
+
"typescript": "^6.0.3",
|
|
16
|
+
"ultracite": "7.7.0",
|
|
17
|
+
"vitest": "^3.2.0"
|
|
18
|
+
},
|
|
19
|
+
"name": "@oisincoveney/pipeline",
|
|
20
|
+
"publishConfig": {
|
|
21
|
+
"access": "public"
|
|
22
|
+
},
|
|
23
|
+
"bin": {
|
|
24
|
+
"oisin-pipeline": "dist/index.js",
|
|
25
|
+
"work-next": "dist/index.js"
|
|
26
|
+
},
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"import": "./dist/index.js"
|
|
31
|
+
},
|
|
32
|
+
"./pipeline-primitive": {
|
|
33
|
+
"types": "./dist/mastra/pipeline-primitive.d.ts",
|
|
34
|
+
"import": "./dist/mastra/pipeline-primitive.js"
|
|
35
|
+
},
|
|
36
|
+
"./runner": {
|
|
37
|
+
"types": "./dist/mastra/runner.d.ts",
|
|
38
|
+
"import": "./dist/mastra/runner.js"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"files": [
|
|
42
|
+
".claude/commands",
|
|
43
|
+
"dist",
|
|
44
|
+
"docs",
|
|
45
|
+
"README.md"
|
|
46
|
+
],
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build:cli": "rm -rf dist && bun build src/index.ts --outfile dist/index.js --target node && bun build src/mastra/pipeline-primitive.ts --outfile dist/mastra/pipeline-primitive.js --target node && bun build src/mastra/runner.ts --outfile dist/mastra/runner.js --target node && tsc -p tsconfig.types.json",
|
|
49
|
+
"test": "vitest run",
|
|
50
|
+
"typecheck": "tsc --noEmit",
|
|
51
|
+
"work-next": "bun src/index.ts work-next",
|
|
52
|
+
"dev": "mastra dev",
|
|
53
|
+
"build": "bun run build:cli && mastra build",
|
|
54
|
+
"start": "mastra start",
|
|
55
|
+
"check": "ultracite check",
|
|
56
|
+
"fix": "ultracite fix",
|
|
57
|
+
"prepack": "bun run build:cli"
|
|
58
|
+
},
|
|
59
|
+
"type": "module",
|
|
60
|
+
"version": "1.0.0",
|
|
61
|
+
"description": "",
|
|
62
|
+
"main": "index.js",
|
|
63
|
+
"keywords": [],
|
|
64
|
+
"author": "",
|
|
65
|
+
"license": "ISC",
|
|
66
|
+
"engines": {
|
|
67
|
+
"node": ">=22.13.0",
|
|
68
|
+
"bun": ">=1.1.0"
|
|
69
|
+
}
|
|
70
|
+
}
|