@plaited/acp-harness 0.2.5 → 0.3.1
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/LICENSE +1 -1
- package/README.md +120 -16
- package/bin/cli.ts +105 -636
- package/bin/tests/cli.spec.ts +218 -51
- package/package.json +20 -4
- package/src/acp-client.ts +5 -4
- package/src/acp-transport.ts +14 -7
- package/src/adapter-check.ts +542 -0
- package/src/adapter-scaffold.ts +934 -0
- package/src/balance.ts +232 -0
- package/src/calibrate.ts +300 -0
- package/src/capture.ts +457 -0
- package/src/constants.ts +94 -0
- package/src/grader-loader.ts +174 -0
- package/src/harness.ts +35 -0
- package/src/schemas-cli.ts +239 -0
- package/src/schemas.ts +567 -0
- package/src/summarize.ts +245 -0
- package/src/tests/adapter-check.spec.ts +70 -0
- package/src/tests/adapter-scaffold.spec.ts +112 -0
- package/src/tests/fixtures/grader-bad-module.ts +5 -0
- package/src/tests/fixtures/grader-exec-fail.py +9 -0
- package/src/tests/fixtures/grader-exec-invalid.py +6 -0
- package/src/tests/fixtures/grader-exec.py +29 -0
- package/src/tests/fixtures/grader-module.ts +14 -0
- package/src/tests/grader-loader.spec.ts +153 -0
- package/src/trials.ts +395 -0
- package/src/validate-refs.ts +188 -0
- package/.claude/rules/accuracy.md +0 -43
- package/.claude/rules/bun-apis.md +0 -80
- package/.claude/rules/code-review.md +0 -254
- package/.claude/rules/git-workflow.md +0 -37
- package/.claude/rules/github.md +0 -154
- package/.claude/rules/testing.md +0 -172
- package/.claude/skills/acp-harness/SKILL.md +0 -310
- package/.claude/skills/acp-harness/assets/Dockerfile.acp +0 -25
- package/.claude/skills/acp-harness/assets/docker-compose.acp.yml +0 -19
- package/.claude/skills/acp-harness/references/downstream.md +0 -288
- package/.claude/skills/acp-harness/references/output-formats.md +0 -221
- package/.claude-plugin/marketplace.json +0 -15
- package/.claude-plugin/plugin.json +0 -16
- package/.github/CODEOWNERS +0 -6
- package/.github/workflows/ci.yml +0 -63
- package/.github/workflows/publish.yml +0 -146
- package/.mcp.json +0 -20
- package/CLAUDE.md +0 -92
- package/Dockerfile.test +0 -23
- package/biome.json +0 -96
- package/bun.lock +0 -513
- package/docker-compose.test.yml +0 -21
- package/scripts/bun-test-wrapper.sh +0 -46
- package/src/acp.constants.ts +0 -56
- package/src/acp.schemas.ts +0 -161
- package/src/acp.types.ts +0 -28
- package/src/tests/fixtures/.claude/settings.local.json +0 -8
- package/src/tests/fixtures/.claude/skills/greeting/SKILL.md +0 -17
- package/tsconfig.json +0 -32
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
# Output Formats
|
|
2
|
-
|
|
3
|
-
The harness supports two output formats optimized for different use cases.
|
|
4
|
-
|
|
5
|
-
## Format Selection
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
bunx @plaited/acp-harness prompts.jsonl --format <format> -o <output>
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
| Format | Files Created | Use Case |
|
|
12
|
-
|--------|---------------|----------|
|
|
13
|
-
| `summary` | Single JSONL | Quick metrics, dashboards, jq analysis |
|
|
14
|
-
| `judge` | `.md` + `.full.jsonl` | Downstream LLM-as-judge scoring |
|
|
15
|
-
|
|
16
|
-
## Summary Format (Default)
|
|
17
|
-
|
|
18
|
-
Minimal JSONL for quick metrics and analysis.
|
|
19
|
-
|
|
20
|
-
### Schema
|
|
21
|
-
|
|
22
|
-
```typescript
|
|
23
|
-
type SummaryResult = {
|
|
24
|
-
id: string // Prompt identifier
|
|
25
|
-
input: string // Original prompt text
|
|
26
|
-
output: string // Final agent response
|
|
27
|
-
toolCalls: string[] // List of tool names used
|
|
28
|
-
status: 'passed' | 'failed' | 'error' | 'timeout'
|
|
29
|
-
duration: number // Total execution time (ms)
|
|
30
|
-
}
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
### Example Output
|
|
34
|
-
|
|
35
|
-
```jsonl
|
|
36
|
-
{"id":"test-001","input":"Create a primary button","output":"I created the button in src/button.tsx","toolCalls":["Write"],"status":"passed","duration":1234}
|
|
37
|
-
{"id":"test-002","input":"Fix the TypeScript error","output":"I fixed the type error...","toolCalls":["Read","Edit"],"status":"passed","duration":2567}
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
### Analysis with jq
|
|
41
|
-
|
|
42
|
-
```bash
|
|
43
|
-
# Calculate average duration
|
|
44
|
-
cat results.jsonl | jq -s 'map(.duration) | add / length'
|
|
45
|
-
|
|
46
|
-
# Count tool usage
|
|
47
|
-
cat results.jsonl | jq -s 'map(.toolCalls) | flatten | group_by(.) | map({tool: .[0], count: length})'
|
|
48
|
-
|
|
49
|
-
# Filter by status
|
|
50
|
-
cat results.jsonl | jq 'select(.status == "failed")'
|
|
51
|
-
|
|
52
|
-
# Pass rate
|
|
53
|
-
cat results.jsonl | jq -s 'map(select(.status == "passed")) | length as $p | length as $t | "\($p)/\($t) passed"'
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
## Judge Format (Two-Tier)
|
|
57
|
-
|
|
58
|
-
Creates two files for downstream LLM-as-judge scoring with step-level correlation.
|
|
59
|
-
|
|
60
|
-
```bash
|
|
61
|
-
bunx @plaited/acp-harness prompts.jsonl --format judge -o results
|
|
62
|
-
# Creates: results.md + results.full.jsonl
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
### Markdown File (`<output>.md`)
|
|
66
|
-
|
|
67
|
-
Human-readable summary with step IDs and code previews.
|
|
68
|
-
|
|
69
|
-
**Structure:**
|
|
70
|
-
|
|
71
|
-
```markdown
|
|
72
|
-
## Capture Record: <id>
|
|
73
|
-
|
|
74
|
-
**Input:** <original prompt>
|
|
75
|
-
|
|
76
|
-
**Trajectory:**
|
|
77
|
-
1. [THOUGHT] <truncated content> [->stepId]
|
|
78
|
-
2. [TOOL:<name>] -> <status> (<duration>ms) [->stepId]
|
|
79
|
-
File: <path> (<size> chars)
|
|
80
|
-
```<ext>
|
|
81
|
-
<head lines>
|
|
82
|
-
|
|
83
|
-
// ... N lines omitted ...
|
|
84
|
-
|
|
85
|
-
<tail lines>
|
|
86
|
-
```
|
|
87
|
-
3. [PLAN] <plan summary> [->stepId]
|
|
88
|
-
4. [MESSAGE] <truncated content> [->stepId]
|
|
89
|
-
|
|
90
|
-
**Output:** <truncated final output>
|
|
91
|
-
**Metadata:** category=ui, agent=claude-code-acp, ...
|
|
92
|
-
**Status:** passed|failed|error|timeout
|
|
93
|
-
**Duration:** <ms>ms
|
|
94
|
-
|
|
95
|
-
---
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
**Step ID Format:** `<prompt-id>-step-<N>` (e.g., `test-001-step-2`)
|
|
99
|
-
|
|
100
|
-
**Truncation Rules:**
|
|
101
|
-
- Thought/message content: First 100 characters
|
|
102
|
-
- Output: First 200 characters
|
|
103
|
-
- Code preview: Head (8 lines) + tail (4 lines) for files > 12 lines
|
|
104
|
-
|
|
105
|
-
### Full JSONL File (`<output>.full.jsonl`)
|
|
106
|
-
|
|
107
|
-
Complete trajectory with step IDs for correlation.
|
|
108
|
-
|
|
109
|
-
**Schema:**
|
|
110
|
-
|
|
111
|
-
```typescript
|
|
112
|
-
type FullResult = {
|
|
113
|
-
id: string
|
|
114
|
-
input: string
|
|
115
|
-
output: string
|
|
116
|
-
expected?: string
|
|
117
|
-
trajectory: IndexedStep[] // Steps with stepId
|
|
118
|
-
metadata: Record<string, unknown>
|
|
119
|
-
timing: {
|
|
120
|
-
start: number // Unix timestamp (ms)
|
|
121
|
-
end: number // Unix timestamp (ms)
|
|
122
|
-
firstResponse?: number // Time to first response (ms)
|
|
123
|
-
}
|
|
124
|
-
status: 'passed' | 'failed' | 'error' | 'timeout'
|
|
125
|
-
errors?: string[]
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
type IndexedStep = TrajectoryStep & { stepId: string }
|
|
129
|
-
|
|
130
|
-
type TrajectoryStep =
|
|
131
|
-
| { type: 'thought'; content: string; timestamp: number }
|
|
132
|
-
| { type: 'message'; content: string; timestamp: number }
|
|
133
|
-
| {
|
|
134
|
-
type: 'tool_call'
|
|
135
|
-
name: string // Tool title from ACP SDK
|
|
136
|
-
status: string // pending, in_progress, completed, failed
|
|
137
|
-
input?: unknown // Raw input parameters
|
|
138
|
-
output?: unknown // Raw output
|
|
139
|
-
duration?: number // Execution time (ms)
|
|
140
|
-
timestamp: number
|
|
141
|
-
}
|
|
142
|
-
| { type: 'plan'; entries: PlanEntry[]; timestamp: number }
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
**Example:**
|
|
146
|
-
|
|
147
|
-
```jsonl
|
|
148
|
-
{"id":"test-001","input":"Create a primary button","output":"I created the button...","trajectory":[{"type":"thought","content":"I'll create a styled button template with createStyles","timestamp":100,"stepId":"test-001-step-1"},{"type":"tool_call","name":"Write","status":"completed","input":{"file_path":"src/button.tsx","content":"import { createStyles }..."},"output":"File written successfully","duration":234,"timestamp":150,"stepId":"test-001-step-2"},{"type":"message","content":"I created the button template","timestamp":500,"stepId":"test-001-step-3"}],"metadata":{"category":"ui","agent":"claude"},"timing":{"start":1704067200000,"end":1704067201234,"firstResponse":100},"status":"passed"}
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
## Two-Tier Scoring Workflow
|
|
152
|
-
|
|
153
|
-
### Direct Scoring (Large Context)
|
|
154
|
-
|
|
155
|
-
For judges with large context windows (Gemini 1M+, Claude 200k):
|
|
156
|
-
|
|
157
|
-
```bash
|
|
158
|
-
# Feed full JSONL directly
|
|
159
|
-
cat results.full.jsonl | your-gemini-judge.ts
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
### Step-Level Retrieval (Small Context)
|
|
163
|
-
|
|
164
|
-
For smaller models or step-specific analysis:
|
|
165
|
-
|
|
166
|
-
```typescript
|
|
167
|
-
// Load both files
|
|
168
|
-
const markdown = await Bun.file('results.md').text()
|
|
169
|
-
const fullLines = (await Bun.file('results.full.jsonl').text()).trim().split('\n')
|
|
170
|
-
|
|
171
|
-
// Parse full results indexed by step ID
|
|
172
|
-
const stepIndex = new Map<string, unknown>()
|
|
173
|
-
for (const line of fullLines) {
|
|
174
|
-
const result = JSON.parse(line)
|
|
175
|
-
for (const step of result.trajectory) {
|
|
176
|
-
stepIndex.set(step.stepId, step)
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// Judge requests full content for specific step
|
|
181
|
-
const stepId = 'test-001-step-2' // From markdown [->stepId]
|
|
182
|
-
const fullStep = stepIndex.get(stepId)
|
|
183
|
-
console.log(fullStep.input) // Complete tool input
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
## Status Values
|
|
187
|
-
|
|
188
|
-
| Status | Meaning |
|
|
189
|
-
|--------|---------|
|
|
190
|
-
| `passed` | Completed without tool errors |
|
|
191
|
-
| `failed` | Completed but one or more tool calls failed |
|
|
192
|
-
| `error` | Unhandled exception during execution |
|
|
193
|
-
| `timeout` | Request exceeded timeout limit |
|
|
194
|
-
|
|
195
|
-
## Input Format
|
|
196
|
-
|
|
197
|
-
Both formats accept the same JSONL input:
|
|
198
|
-
|
|
199
|
-
```jsonl
|
|
200
|
-
{"id":"test-001","input":"Create a primary button","expected":"should contain <button>","metadata":{"category":"ui"}}
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
| Field | Required | Description |
|
|
204
|
-
|-------|----------|-------------|
|
|
205
|
-
| `id` | Yes | Unique identifier |
|
|
206
|
-
| `input` | Yes | Prompt text for the agent |
|
|
207
|
-
| `expected` | No | Expected output (for downstream scoring) |
|
|
208
|
-
| `metadata` | No | Tags, category, difficulty for filtering |
|
|
209
|
-
| `timeout` | No | Override default timeout for this prompt |
|
|
210
|
-
|
|
211
|
-
## Streaming Behavior
|
|
212
|
-
|
|
213
|
-
Both formats stream output line-by-line as results complete:
|
|
214
|
-
|
|
215
|
-
```bash
|
|
216
|
-
# Watch results in real-time
|
|
217
|
-
bunx @plaited/acp-harness prompts.jsonl --progress -o results.jsonl &
|
|
218
|
-
tail -f results.jsonl
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
Use `--append` to continue interrupted runs without overwriting previous results.
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "plaited-acp-harness",
|
|
3
|
-
"metadata": {
|
|
4
|
-
"description": "Claude Code plugin for Agent Client Protocol testing and evaluation"
|
|
5
|
-
},
|
|
6
|
-
"owner": {
|
|
7
|
-
"name": "Plaited Labs"
|
|
8
|
-
},
|
|
9
|
-
"plugins": [
|
|
10
|
-
{
|
|
11
|
-
"name": "acp-harness",
|
|
12
|
-
"source": "./"
|
|
13
|
-
}
|
|
14
|
-
]
|
|
15
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "acp-harness",
|
|
3
|
-
"version": "0.2.5",
|
|
4
|
-
"description": "Agent Client Protocol client and evaluation harness for TypeScript/Bun projects. Includes: createACPClient for programmatic agent access, run-harness.ts for trajectory capture, and LLM-as-judge evaluation templates. Requires Bun runtime.",
|
|
5
|
-
"author": {
|
|
6
|
-
"name": "Plaited Labs"
|
|
7
|
-
},
|
|
8
|
-
"license": "ISC",
|
|
9
|
-
"mcpServers": {
|
|
10
|
-
"agent-client-protocol": {
|
|
11
|
-
"type": "http",
|
|
12
|
-
"url": "https://agentclientprotocol.com/mcp"
|
|
13
|
-
}
|
|
14
|
-
},
|
|
15
|
-
"skills": "./.claude/skills"
|
|
16
|
-
}
|
package/.github/CODEOWNERS
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
# Code owners for acp-harness repository
|
|
2
|
-
# These users will be automatically requested for review when someone opens a pull request.
|
|
3
|
-
# See https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
|
|
4
|
-
|
|
5
|
-
# Organization admins own all files
|
|
6
|
-
* @EdwardIrby @alisonailea
|
package/.github/workflows/ci.yml
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
name: CI
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches:
|
|
6
|
-
- main
|
|
7
|
-
pull_request:
|
|
8
|
-
|
|
9
|
-
permissions:
|
|
10
|
-
contents: read
|
|
11
|
-
|
|
12
|
-
jobs:
|
|
13
|
-
# Detect which paths changed to conditionally run expensive jobs
|
|
14
|
-
changes:
|
|
15
|
-
runs-on: ubuntu-latest
|
|
16
|
-
permissions:
|
|
17
|
-
pull-requests: read
|
|
18
|
-
outputs:
|
|
19
|
-
acp: ${{ steps.filter.outputs.acp }}
|
|
20
|
-
steps:
|
|
21
|
-
- uses: actions/checkout@v4
|
|
22
|
-
- uses: dorny/paths-filter@v3
|
|
23
|
-
id: filter
|
|
24
|
-
with:
|
|
25
|
-
filters: |
|
|
26
|
-
acp:
|
|
27
|
-
- 'src/**'
|
|
28
|
-
|
|
29
|
-
test-pr:
|
|
30
|
-
runs-on: ubuntu-latest
|
|
31
|
-
|
|
32
|
-
steps:
|
|
33
|
-
- uses: actions/checkout@v4
|
|
34
|
-
- uses: oven-sh/setup-bun@v2
|
|
35
|
-
with:
|
|
36
|
-
bun-version: latest
|
|
37
|
-
- name: Install dependencies
|
|
38
|
-
run: bun install
|
|
39
|
-
- name: Run check
|
|
40
|
-
run: bun run check
|
|
41
|
-
- name: Run test
|
|
42
|
-
run: bun run test
|
|
43
|
-
|
|
44
|
-
# ACP integration tests run in Docker container for consistent environment
|
|
45
|
-
# Only runs when src/ files change to reduce API costs
|
|
46
|
-
test-acp-integration:
|
|
47
|
-
needs: changes
|
|
48
|
-
if: ${{ needs.changes.outputs.acp == 'true' }}
|
|
49
|
-
runs-on: ubuntu-latest
|
|
50
|
-
container:
|
|
51
|
-
image: oven/bun:1.2.9
|
|
52
|
-
options: --user root
|
|
53
|
-
|
|
54
|
-
steps:
|
|
55
|
-
- uses: actions/checkout@v4
|
|
56
|
-
|
|
57
|
-
- name: Install dependencies
|
|
58
|
-
run: bun install --frozen-lockfile
|
|
59
|
-
|
|
60
|
-
- name: Run ACP integration tests
|
|
61
|
-
env:
|
|
62
|
-
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
63
|
-
run: bun test ./src/tests/acp-integration.docker.ts
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
name: Publish
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
workflow_dispatch:
|
|
5
|
-
inputs:
|
|
6
|
-
version:
|
|
7
|
-
description: "New version tag (e.g., 1.0.0)"
|
|
8
|
-
required: true
|
|
9
|
-
next:
|
|
10
|
-
description: "Next prerelease number (optional, will create a version like x.y.z-next.N)"
|
|
11
|
-
required: false
|
|
12
|
-
jobs:
|
|
13
|
-
publish:
|
|
14
|
-
runs-on: ubuntu-22.04
|
|
15
|
-
permissions:
|
|
16
|
-
contents: write
|
|
17
|
-
id-token: write
|
|
18
|
-
|
|
19
|
-
steps:
|
|
20
|
-
- name: Validate inputs
|
|
21
|
-
env:
|
|
22
|
-
INPUT_VERSION: ${{ github.event.inputs.version }}
|
|
23
|
-
INPUT_NEXT: ${{ github.event.inputs.next }}
|
|
24
|
-
run: |
|
|
25
|
-
# SECURITY: Validate all inputs before use to prevent injection
|
|
26
|
-
# Using env vars instead of direct interpolation to prevent shell injection
|
|
27
|
-
|
|
28
|
-
# Validate version format (semver)
|
|
29
|
-
if ! echo "$INPUT_VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then
|
|
30
|
-
echo "::error::Invalid version format: $INPUT_VERSION"
|
|
31
|
-
echo "::error::Expected: X.Y.Z (e.g., 1.0.0)"
|
|
32
|
-
exit 1
|
|
33
|
-
fi
|
|
34
|
-
|
|
35
|
-
# Validate next is a number if provided
|
|
36
|
-
if [[ -n "$INPUT_NEXT" ]] && ! echo "$INPUT_NEXT" | grep -qE '^[0-9]+$'; then
|
|
37
|
-
echo "::error::Invalid next value: $INPUT_NEXT"
|
|
38
|
-
echo "::error::Expected: number (e.g., 1, 2, 3)"
|
|
39
|
-
exit 1
|
|
40
|
-
fi
|
|
41
|
-
|
|
42
|
-
echo "✓ Input validation passed"
|
|
43
|
-
|
|
44
|
-
- name: Set version
|
|
45
|
-
id: set_version
|
|
46
|
-
env:
|
|
47
|
-
INPUT_VERSION: ${{ github.event.inputs.version }}
|
|
48
|
-
INPUT_NEXT: ${{ github.event.inputs.next }}
|
|
49
|
-
run: |
|
|
50
|
-
base_version="$INPUT_VERSION"
|
|
51
|
-
next="$INPUT_NEXT"
|
|
52
|
-
|
|
53
|
-
if [[ -n "$next" ]]; then
|
|
54
|
-
echo "version=${base_version}-next.${next}" >> $GITHUB_OUTPUT
|
|
55
|
-
echo "is_prerelease=true" >> $GITHUB_OUTPUT
|
|
56
|
-
else
|
|
57
|
-
echo "version=${base_version}" >> $GITHUB_OUTPUT
|
|
58
|
-
echo "is_prerelease=false" >> $GITHUB_OUTPUT
|
|
59
|
-
fi
|
|
60
|
-
|
|
61
|
-
- name: Validate version format
|
|
62
|
-
env:
|
|
63
|
-
VERSION: ${{ steps.set_version.outputs.version }}
|
|
64
|
-
run: |
|
|
65
|
-
version="$VERSION"
|
|
66
|
-
|
|
67
|
-
# Check for 'v' prefix (common mistake)
|
|
68
|
-
if [[ "$version" =~ ^v ]]; then
|
|
69
|
-
echo "::error::Version should not include 'v' prefix"
|
|
70
|
-
echo "::error::Enter '1.3.4' not 'v1.3.4'"
|
|
71
|
-
echo "::error::The workflow will automatically add 'v' for Git tags"
|
|
72
|
-
exit 1
|
|
73
|
-
fi
|
|
74
|
-
|
|
75
|
-
# Validate semver format (allows dots in prerelease suffix for formats like 1.0.0-next.1)
|
|
76
|
-
if [[ ! "$version" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)(-([a-zA-Z0-9._-]+))?$ ]]; then
|
|
77
|
-
echo "::error::Version must have the format 'x.y.z' or 'x.y.z-<string>', where x, y, and z are numbers."
|
|
78
|
-
exit 1
|
|
79
|
-
fi
|
|
80
|
-
|
|
81
|
-
echo "✅ Version format validated: $version"
|
|
82
|
-
|
|
83
|
-
- name: Checkout repository
|
|
84
|
-
uses: actions/checkout@v4
|
|
85
|
-
with:
|
|
86
|
-
token: ${{ secrets.GH_PAT }}
|
|
87
|
-
|
|
88
|
-
- name: Setup Node.js (for NPM OIDC)
|
|
89
|
-
uses: actions/setup-node@v4
|
|
90
|
-
with:
|
|
91
|
-
node-version: "lts/*"
|
|
92
|
-
registry-url: https://registry.npmjs.org
|
|
93
|
-
check-latest: true
|
|
94
|
-
|
|
95
|
-
- uses: oven-sh/setup-bun@v1
|
|
96
|
-
|
|
97
|
-
- name: Setup
|
|
98
|
-
run: |
|
|
99
|
-
bun install
|
|
100
|
-
|
|
101
|
-
- name: Configure Git
|
|
102
|
-
env:
|
|
103
|
-
GIT_AUTHOR_NAME: ${{ github.actor }}
|
|
104
|
-
GIT_AUTHOR_EMAIL: ${{ github.actor }}@users.noreply.github.com
|
|
105
|
-
run: |
|
|
106
|
-
git config user.name "$GIT_AUTHOR_NAME"
|
|
107
|
-
git config user.email "$GIT_AUTHOR_EMAIL"
|
|
108
|
-
|
|
109
|
-
- name: Version
|
|
110
|
-
env:
|
|
111
|
-
GH_TOKEN: ${{ secrets.GH_PAT }}
|
|
112
|
-
VERSION: ${{ steps.set_version.outputs.version }}
|
|
113
|
-
IS_PRERELEASE: ${{ steps.set_version.outputs.is_prerelease }}
|
|
114
|
-
run: |
|
|
115
|
-
npm version --no-git-tag-version "$VERSION"
|
|
116
|
-
|
|
117
|
-
# Update plugin.json version
|
|
118
|
-
jq --arg v "$VERSION" '.version = $v' .claude-plugin/plugin.json > .claude-plugin/plugin.json.tmp
|
|
119
|
-
mv .claude-plugin/plugin.json.tmp .claude-plugin/plugin.json
|
|
120
|
-
|
|
121
|
-
git add -A
|
|
122
|
-
git commit -m "ci: publish [skip ci]"
|
|
123
|
-
git push
|
|
124
|
-
|
|
125
|
-
# Create GitHub release
|
|
126
|
-
if [[ "$IS_PRERELEASE" == "true" ]]; then
|
|
127
|
-
gh release create "v$VERSION" --generate-notes --prerelease
|
|
128
|
-
else
|
|
129
|
-
gh release create "v$VERSION" --generate-notes
|
|
130
|
-
fi
|
|
131
|
-
|
|
132
|
-
- name: Publish to NPM (Trusted Publishing)
|
|
133
|
-
env:
|
|
134
|
-
IS_PRERELEASE: ${{ steps.set_version.outputs.is_prerelease }}
|
|
135
|
-
run: |
|
|
136
|
-
# NPM trusted publishing uses OIDC token automatically
|
|
137
|
-
# Provenance attestations are generated automatically (npm >=11.5.1)
|
|
138
|
-
# No NPM_TOKEN secret needed - authentication via GitHub OIDC
|
|
139
|
-
|
|
140
|
-
if [[ "$IS_PRERELEASE" == "true" ]]; then
|
|
141
|
-
echo "Publishing as next (prerelease)"
|
|
142
|
-
npm publish --access public --tag next
|
|
143
|
-
else
|
|
144
|
-
echo "Publishing as latest (stable)"
|
|
145
|
-
npm publish --access public
|
|
146
|
-
fi
|
package/.mcp.json
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"mcpServers": {
|
|
3
|
-
"agent-skills-spec": {
|
|
4
|
-
"type": "http",
|
|
5
|
-
"url": "https://agentskills.io/mcp"
|
|
6
|
-
},
|
|
7
|
-
"agent-client-protocol": {
|
|
8
|
-
"type": "http",
|
|
9
|
-
"url": "https://agentclientprotocol.com/mcp"
|
|
10
|
-
},
|
|
11
|
-
"model-context-protocol-docs":{
|
|
12
|
-
"type": "http",
|
|
13
|
-
"url": "https://modelcontextprotocol.io/mcp"
|
|
14
|
-
},
|
|
15
|
-
"braintrust-docs": {
|
|
16
|
-
"type": "http",
|
|
17
|
-
"url": "https://www.braintrust.dev/docs/mcp"
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
}
|
package/CLAUDE.md
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
# CLAUDE.md
|
|
2
|
-
|
|
3
|
-
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
-
|
|
5
|
-
## Essential Commands
|
|
6
|
-
|
|
7
|
-
### Development Setup
|
|
8
|
-
```bash
|
|
9
|
-
# Install dependencies (requires bun >= v1.2.9)
|
|
10
|
-
bun install
|
|
11
|
-
|
|
12
|
-
# Type, lint, and format check (check only, no fixes)
|
|
13
|
-
bun run check
|
|
14
|
-
|
|
15
|
-
# Lint and format fix (auto-fix issues)
|
|
16
|
-
bun run check:write
|
|
17
|
-
|
|
18
|
-
# Run unit tests
|
|
19
|
-
bun test
|
|
20
|
-
|
|
21
|
-
# Run Docker integration tests (requires ANTHROPIC_API_KEY)
|
|
22
|
-
ANTHROPIC_API_KEY=sk-... bun run test:docker
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
## Project Organization
|
|
26
|
-
|
|
27
|
-
This project uses `.claude/rules/` for project-specific guidance:
|
|
28
|
-
|
|
29
|
-
- **Testing**: @.claude/rules/testing.md - Test commands and workflow
|
|
30
|
-
- **Code Review**: @.claude/rules/code-review.md - Review standards
|
|
31
|
-
- **Accuracy**: @.claude/rules/accuracy.md - Confidence thresholds
|
|
32
|
-
- **Bun APIs**: @.claude/rules/bun-apis.md - Bun platform API preferences
|
|
33
|
-
- **Git Workflow**: @.claude/rules/git-workflow.md - Commit conventions
|
|
34
|
-
- **GitHub**: @.claude/rules/github.md - GitHub CLI integration
|
|
35
|
-
|
|
36
|
-
## Quick Reference
|
|
37
|
-
|
|
38
|
-
### Package Overview
|
|
39
|
-
|
|
40
|
-
`@plaited/acp-harness` is a CLI tool for capturing agent trajectories from ACP-compatible agents. It executes prompts, captures full trajectories (tools, thoughts, plans), and outputs structured JSONL for downstream scoring.
|
|
41
|
-
|
|
42
|
-
**CLI usage:**
|
|
43
|
-
```bash
|
|
44
|
-
bunx @plaited/acp-harness prompts.jsonl -o results.jsonl
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
### Code Style Essentials
|
|
48
|
-
|
|
49
|
-
- Prefer arrow functions and `type` over `interface`
|
|
50
|
-
- Use `test` instead of `it` in test files
|
|
51
|
-
- Prefer Bun native APIs over Node.js equivalents
|
|
52
|
-
- Object parameters for functions with 2+ parameters
|
|
53
|
-
- JSON imports require `with { type: 'json' }` attribute
|
|
54
|
-
|
|
55
|
-
For complete conventions, see `.claude/rules/code-review.md`
|
|
56
|
-
|
|
57
|
-
### Plugin Development
|
|
58
|
-
|
|
59
|
-
This project is a Claude Code plugin distributed via the plaited/marketplace aggregator. Structure:
|
|
60
|
-
- `.claude/.claude-plugin/plugin.json` - Plugin manifest
|
|
61
|
-
- `.claude/` - Plugin source (skills, rules, settings)
|
|
62
|
-
|
|
63
|
-
When working on plugins:
|
|
64
|
-
- Clear cache after changes: `rm -rf ~/.claude/plugins-cache`
|
|
65
|
-
- Restart Claude Code to see updates
|
|
66
|
-
- Skills are auto-invoked (won't show in `/plugins` UI)
|
|
67
|
-
- Test installation locally: `claude plugins add github:plaited/marketplace`
|
|
68
|
-
|
|
69
|
-
### Documentation
|
|
70
|
-
|
|
71
|
-
- Public APIs require comprehensive TSDoc documentation
|
|
72
|
-
- No `@example` sections - tests are living examples
|
|
73
|
-
- Use `@internal` marker for non-public APIs
|
|
74
|
-
- Always use `type` over `interface`
|
|
75
|
-
- Use Mermaid diagrams only (not ASCII art)
|
|
76
|
-
|
|
77
|
-
## Important Constraints
|
|
78
|
-
|
|
79
|
-
1. **No Open Contribution**: This is open-source but not open-contribution
|
|
80
|
-
2. **Bun Required**: Development requires bun >= v1.2.9
|
|
81
|
-
3. **ES2024 Features**: Uses Promise.withResolvers() and other modern APIs
|
|
82
|
-
|
|
83
|
-
## Plugin
|
|
84
|
-
|
|
85
|
-
The bundled **acp-harness** skill (`.claude/skills/acp-harness/`) provides:
|
|
86
|
-
- CLI usage and examples
|
|
87
|
-
- Output format specifications
|
|
88
|
-
- Downstream integration patterns
|
|
89
|
-
|
|
90
|
-
Install via Claude Code: `/plugin marketplace add plaited/acp-harness`
|
|
91
|
-
|
|
92
|
-
See `.claude/skills/acp-harness/SKILL.md` for complete documentation.
|
package/Dockerfile.test
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# Dockerfile for integration tests requiring Docker environment
|
|
2
|
-
# Uses same bun version as CI for consistency
|
|
3
|
-
#
|
|
4
|
-
# Tests use *.docker.ts naming to:
|
|
5
|
-
# 1. Avoid bun test pattern matching in normal test runs
|
|
6
|
-
# 2. Signal these tests require Docker (external APIs, etc.)
|
|
7
|
-
|
|
8
|
-
FROM oven/bun:1.2.9
|
|
9
|
-
|
|
10
|
-
# Install git (required for some operations)
|
|
11
|
-
RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*
|
|
12
|
-
|
|
13
|
-
WORKDIR /app
|
|
14
|
-
|
|
15
|
-
# Copy source
|
|
16
|
-
COPY . .
|
|
17
|
-
|
|
18
|
-
# Install dependencies
|
|
19
|
-
RUN bun install --frozen-lockfile
|
|
20
|
-
|
|
21
|
-
# Run all Docker integration tests
|
|
22
|
-
# The wrapper script handles finding and running *.docker.ts files
|
|
23
|
-
CMD ["bash", "scripts/bun-test-wrapper.sh"]
|