@plaited/acp-harness 0.2.5
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/rules/accuracy.md +43 -0
- package/.claude/rules/bun-apis.md +80 -0
- package/.claude/rules/code-review.md +254 -0
- package/.claude/rules/git-workflow.md +37 -0
- package/.claude/rules/github.md +154 -0
- package/.claude/rules/testing.md +172 -0
- package/.claude/skills/acp-harness/SKILL.md +310 -0
- package/.claude/skills/acp-harness/assets/Dockerfile.acp +25 -0
- package/.claude/skills/acp-harness/assets/docker-compose.acp.yml +19 -0
- package/.claude/skills/acp-harness/references/downstream.md +288 -0
- package/.claude/skills/acp-harness/references/output-formats.md +221 -0
- package/.claude-plugin/marketplace.json +15 -0
- package/.claude-plugin/plugin.json +16 -0
- package/.github/CODEOWNERS +6 -0
- package/.github/workflows/ci.yml +63 -0
- package/.github/workflows/publish.yml +146 -0
- package/.mcp.json +20 -0
- package/CLAUDE.md +92 -0
- package/Dockerfile.test +23 -0
- package/LICENSE +15 -0
- package/README.md +94 -0
- package/bin/cli.ts +670 -0
- package/bin/tests/cli.spec.ts +362 -0
- package/biome.json +96 -0
- package/bun.lock +513 -0
- package/docker-compose.test.yml +21 -0
- package/package.json +57 -0
- package/scripts/bun-test-wrapper.sh +46 -0
- package/src/acp-client.ts +503 -0
- package/src/acp-helpers.ts +121 -0
- package/src/acp-transport.ts +455 -0
- package/src/acp-utils.ts +341 -0
- package/src/acp.constants.ts +56 -0
- package/src/acp.schemas.ts +161 -0
- package/src/acp.ts +27 -0
- package/src/acp.types.ts +28 -0
- package/src/tests/acp-client.spec.ts +205 -0
- package/src/tests/acp-helpers.spec.ts +105 -0
- package/src/tests/acp-integration.docker.ts +214 -0
- package/src/tests/acp-transport.spec.ts +153 -0
- package/src/tests/acp-utils.spec.ts +394 -0
- package/src/tests/fixtures/.claude/settings.local.json +8 -0
- package/src/tests/fixtures/.claude/skills/greeting/SKILL.md +17 -0
- package/src/tests/fixtures/calculator-mcp.ts +215 -0
- package/tsconfig.json +32 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Accuracy and Confidence Standards
|
|
2
|
+
|
|
3
|
+
**Confidence Threshold**: 95% - Report uncertainty rather than guess
|
|
4
|
+
|
|
5
|
+
## Verification Protocol
|
|
6
|
+
|
|
7
|
+
1. **Verification First**: Before stating any specific implementation detail (function signature, file path, API schema), use the `typescript-lsp` skill to verify types and signatures, then read the relevant file in real-time to verify accuracy.
|
|
8
|
+
|
|
9
|
+
2. **Handling Uncertainty**: If you cannot verify information or find contradictions between instructions and live code, you must NOT provide speculative answers.
|
|
10
|
+
- **Action**: Clearly state you cannot answer with high confidence and explain the discrepancy.
|
|
11
|
+
- Example: "I cannot confirm [detail] because my instructions indicate [X], but the current file shows [Y]. My knowledge may be outdated."
|
|
12
|
+
|
|
13
|
+
3. **Dynamic Exploration**:
|
|
14
|
+
- **PREFER typescript-lsp over Grep/Glob** for `.ts`, `.tsx`, `.js`, `.jsx` files
|
|
15
|
+
- Use `lsp-find` to search for symbols, types, and patterns across the workspace
|
|
16
|
+
- Use `lsp-references` to find all usages of a symbol
|
|
17
|
+
- Use `lsp-hover` to verify type signatures
|
|
18
|
+
- Only fall back to Grep/Glob for non-TypeScript files or when LSP is unavailable
|
|
19
|
+
- Use Read for other file types. Always prioritize live code over instructions.
|
|
20
|
+
|
|
21
|
+
4. **Tool-Assisted Verification**: Use these skills to enhance verification accuracy:
|
|
22
|
+
- **`typescript-lsp` skill**: Use `lsp-hover` to verify type signatures, `lsp-references` to find all usages before modifying, `lsp-symbols` for file structure, and `lsp-find` to search for patterns across the workspace.
|
|
23
|
+
- **WebFetch**: Retrieve current documentation from authoritative sources (MDN Web Docs, WHATWG specs) when using web platform APIs.
|
|
24
|
+
- These skills complement (but do not replace) reading live code - always verify outputs against actual implementation.
|
|
25
|
+
|
|
26
|
+
## Certainty Requirements
|
|
27
|
+
|
|
28
|
+
You may only propose a specific change if you are **at least 95% certain** it is correct, based on direct comparison with current code.
|
|
29
|
+
|
|
30
|
+
**When uncertain:**
|
|
31
|
+
- Report the discrepancy clearly
|
|
32
|
+
- State why you cannot confidently recommend a fix
|
|
33
|
+
- Present the issue to the user for manual resolution
|
|
34
|
+
- DO NOT invent solutions or infer changes
|
|
35
|
+
|
|
36
|
+
## For Agent-Specific Applications
|
|
37
|
+
|
|
38
|
+
Agents should apply these standards to their specific domain:
|
|
39
|
+
|
|
40
|
+
- **Documentation agents**: Only update TSDoc if parameter names/types match current code
|
|
41
|
+
- **Architecture agents**: Verify referenced patterns exist in current codebase
|
|
42
|
+
- **Code review agents**: Read files before commenting on implementation details
|
|
43
|
+
- **Pattern agents**: Confirm examples reflect actual usage in codebase
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Bun Platform APIs
|
|
2
|
+
|
|
3
|
+
**IMPORTANT**: Prefer Bun's native APIs over Node.js equivalents when running in the Bun environment.
|
|
4
|
+
|
|
5
|
+
## File System Operations
|
|
6
|
+
|
|
7
|
+
- ✅ Use `Bun.file(path).exists()` instead of `fs.existsSync()`
|
|
8
|
+
- ✅ Use `Bun.file(path)` API for reading/writing files
|
|
9
|
+
- ✅ Use `Bun.write()` for efficient file writes
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
// ✅ Good: Bun APIs
|
|
13
|
+
const exists = await Bun.file('config.json').exists()
|
|
14
|
+
const content = await Bun.file('data.txt').text()
|
|
15
|
+
await Bun.write('output.json', JSON.stringify(data))
|
|
16
|
+
|
|
17
|
+
// ❌ Avoid: Node.js equivalents
|
|
18
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs'
|
|
19
|
+
const exists = existsSync('config.json')
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Shell Commands
|
|
23
|
+
|
|
24
|
+
- ✅ Use `Bun.$` template literal for shell commands
|
|
25
|
+
- ❌ Avoid `child_process.spawn()` or `child_process.exec()`
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
// ✅ Good: Bun shell
|
|
29
|
+
await Bun.$`npm install`
|
|
30
|
+
const result = await Bun.$`git status`.text()
|
|
31
|
+
|
|
32
|
+
// ❌ Avoid: Node.js child_process
|
|
33
|
+
import { spawn } from 'node:child_process'
|
|
34
|
+
spawn('npm', ['install'])
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Path Resolution
|
|
38
|
+
|
|
39
|
+
- ✅ Use `Bun.resolveSync()` for module resolution
|
|
40
|
+
- ✅ Use `import.meta.dir` for current directory
|
|
41
|
+
- ⚠️ Keep `node:path` utilities for path manipulation (join, resolve, dirname)
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
// ✅ Good: Bun + node:path combo
|
|
45
|
+
import { join } from 'node:path'
|
|
46
|
+
const configPath = join(import.meta.dir, 'config.json')
|
|
47
|
+
const resolved = Bun.resolveSync('./module', import.meta.dir)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Package Management
|
|
51
|
+
|
|
52
|
+
- ✅ Use `Bun.which(cmd)` to check for executables
|
|
53
|
+
- ⚠️ No programmatic package manager API yet - use CLI commands via `Bun.$`
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
// ✅ Good: Check for executable
|
|
57
|
+
const bunPath = Bun.which('bun')
|
|
58
|
+
if (!bunPath) throw new Error('bun not found')
|
|
59
|
+
|
|
60
|
+
// Install packages via shell
|
|
61
|
+
await Bun.$`bun add zod`
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Environment Detection
|
|
65
|
+
|
|
66
|
+
- ✅ Check `typeof Bun !== 'undefined'` for Bun runtime
|
|
67
|
+
- ✅ Use `Bun.which('bun')` to verify bun executable exists
|
|
68
|
+
|
|
69
|
+
## When to Use Node.js APIs
|
|
70
|
+
|
|
71
|
+
- Interactive input (readline)
|
|
72
|
+
- Complex path manipulation (prefer `node:path` utilities)
|
|
73
|
+
- APIs without Bun equivalents
|
|
74
|
+
|
|
75
|
+
## Documentation
|
|
76
|
+
|
|
77
|
+
- Main docs: https://bun.sh/docs
|
|
78
|
+
- Shell API: https://bun.sh/docs/runtime/shell
|
|
79
|
+
- File I/O: https://bun.sh/docs/api/file-io
|
|
80
|
+
- Runtime APIs: https://bun.sh/docs/runtime/bun-apis
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# Code Review Standards
|
|
2
|
+
|
|
3
|
+
The following standards are not automatically enforced by Biome but should be checked during code review.
|
|
4
|
+
|
|
5
|
+
## Automated Validation
|
|
6
|
+
|
|
7
|
+
Before completing a code review, run these validation scripts:
|
|
8
|
+
|
|
9
|
+
### Plugin Skills Validation
|
|
10
|
+
|
|
11
|
+
When changes touch `.claude/skills/`, validate against the AgentSkills spec by running:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
/validate-skill
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
This checks:
|
|
18
|
+
- SKILL.md exists and has required frontmatter
|
|
19
|
+
- Scripts have proper structure
|
|
20
|
+
- References are valid markdown files
|
|
21
|
+
|
|
22
|
+
## TypeScript Style Conventions
|
|
23
|
+
|
|
24
|
+
### Prefer `type` Over `interface`
|
|
25
|
+
|
|
26
|
+
Use type aliases instead of interfaces for better consistency and flexibility:
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
// ✅ Good
|
|
30
|
+
type User = {
|
|
31
|
+
name: string
|
|
32
|
+
email: string
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// ❌ Avoid
|
|
36
|
+
interface User {
|
|
37
|
+
name: string
|
|
38
|
+
email: string
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**Rationale:** Type aliases are more flexible (unions, intersections, mapped types) and provide consistent syntax across the codebase.
|
|
43
|
+
|
|
44
|
+
### No `any` Types
|
|
45
|
+
|
|
46
|
+
Always use proper types; use `unknown` if type is truly unknown and add type guards:
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
// ✅ Good
|
|
50
|
+
const process = (data: unknown) => {
|
|
51
|
+
if (typeof data === 'string') {
|
|
52
|
+
return data.toUpperCase()
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// ❌ Avoid
|
|
57
|
+
const process = (data: any) => {
|
|
58
|
+
return data.toUpperCase()
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### PascalCase for Types and Schemas
|
|
63
|
+
|
|
64
|
+
All type names use PascalCase. Zod schema names use `PascalCaseSchema` suffix:
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
// ✅ Good
|
|
68
|
+
type UserConfig = { /* ... */ }
|
|
69
|
+
const UserConfigSchema = z.object({ /* ... */ })
|
|
70
|
+
|
|
71
|
+
// ❌ Avoid
|
|
72
|
+
type userConfig = { /* ... */ }
|
|
73
|
+
const zUserConfig = z.object({ /* ... */ }) // Don't use z-prefix
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Arrow Functions Preferred
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
// ✅ Good
|
|
80
|
+
const greet = (name: string) => `Hello, ${name}!`
|
|
81
|
+
|
|
82
|
+
// ❌ Avoid
|
|
83
|
+
function greet(name: string) {
|
|
84
|
+
return `Hello, ${name}!`
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Object Parameter Pattern
|
|
89
|
+
|
|
90
|
+
For functions with more than two parameters, use a single object parameter:
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
// ✅ Good: Object parameter pattern
|
|
94
|
+
const createClient = ({
|
|
95
|
+
command,
|
|
96
|
+
timeout,
|
|
97
|
+
cwd,
|
|
98
|
+
}: {
|
|
99
|
+
command: string[]
|
|
100
|
+
timeout: number
|
|
101
|
+
cwd?: string
|
|
102
|
+
}): ACPClient => { /* ... */ }
|
|
103
|
+
|
|
104
|
+
// ❌ Avoid: Multiple positional parameters
|
|
105
|
+
const createClient = (
|
|
106
|
+
command: string[],
|
|
107
|
+
timeout: number,
|
|
108
|
+
cwd?: string
|
|
109
|
+
): ACPClient => { /* ... */ }
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## TypeScript Comment Directives
|
|
113
|
+
|
|
114
|
+
### `@ts-ignore` Requires Description
|
|
115
|
+
|
|
116
|
+
- When using `@ts-ignore`, always include a description explaining why the type error is being suppressed
|
|
117
|
+
- This helps future maintainers understand the reasoning
|
|
118
|
+
- Example:
|
|
119
|
+
```typescript
|
|
120
|
+
// @ts-ignore - TypeScript incorrectly infers this as string when it's actually a number from the API
|
|
121
|
+
const value = response.data
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**Rationale:** Lost TypeScript-ESLint rule `ban-ts-comment` with `allow-with-description` option during Biome migration
|
|
125
|
+
|
|
126
|
+
## Expression Statements
|
|
127
|
+
|
|
128
|
+
### Allow Short-Circuit and Ternary Expressions
|
|
129
|
+
|
|
130
|
+
- Short-circuit evaluation is acceptable: `condition && doSomething()`
|
|
131
|
+
- Ternary expressions are acceptable: `condition ? doThis() : doThat()`
|
|
132
|
+
- These patterns are idiomatic and improve code readability
|
|
133
|
+
|
|
134
|
+
**Rationale:** Lost TypeScript-ESLint rule `no-unused-expressions` with `allowShortCircuit` and `allowTernary` options during Biome migration
|
|
135
|
+
|
|
136
|
+
## Empty Object Types
|
|
137
|
+
|
|
138
|
+
### Allow Empty Object Types When Extending a Single Interface
|
|
139
|
+
|
|
140
|
+
- Empty object types are acceptable when they extend exactly one other interface
|
|
141
|
+
- This pattern is useful for creating branded types or extending third-party interfaces
|
|
142
|
+
- Example:
|
|
143
|
+
```typescript
|
|
144
|
+
// ✅ Acceptable: Extends single interface
|
|
145
|
+
interface CustomElement extends HTMLElement {}
|
|
146
|
+
|
|
147
|
+
// ❌ Avoid: Empty with no extends or multiple extends
|
|
148
|
+
interface Empty {}
|
|
149
|
+
interface Multi extends Foo, Bar {}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
**Rationale:** Lost TypeScript-ESLint rule `no-empty-object-type` with `allowInterfaces: 'with-single-extends'` option during Biome migration
|
|
153
|
+
|
|
154
|
+
## Modern JavaScript Standards
|
|
155
|
+
|
|
156
|
+
### Prefer Private Fields Over `private` Keyword
|
|
157
|
+
|
|
158
|
+
Use JavaScript private fields (`#field`) instead of TypeScript's `private` keyword:
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
// ✅ Good: JavaScript private fields (ES2022+)
|
|
162
|
+
class EventBus {
|
|
163
|
+
#listeners = new Map<string, Set<Function>>()
|
|
164
|
+
#count = 0
|
|
165
|
+
|
|
166
|
+
#emit(event: string) {
|
|
167
|
+
this.#count++
|
|
168
|
+
this.#listeners.get(event)?.forEach(fn => fn())
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// ❌ Avoid: TypeScript private keyword
|
|
173
|
+
class EventBus {
|
|
174
|
+
private listeners = new Map<string, Set<Function>>()
|
|
175
|
+
private count = 0
|
|
176
|
+
|
|
177
|
+
private emit(event: string) {
|
|
178
|
+
this.count++
|
|
179
|
+
this.listeners.get(event)?.forEach(fn => fn())
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**Rationale:** JavaScript private fields are a runtime feature (ES2022) providing true encapsulation. TypeScript's `private` is erased at compile time and can be bypassed. Prefer platform standards over TypeScript-only features
|
|
185
|
+
|
|
186
|
+
### JSON Import Attributes
|
|
187
|
+
|
|
188
|
+
Use import attributes when importing JSON files. This is required because the tsconfig uses `verbatimModuleSyntax: true` without `resolveJsonModule`:
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
// ✅ Good: Import attribute for JSON
|
|
192
|
+
import { version } from '../package.json' with { type: 'json' }
|
|
193
|
+
import config from './config.json' with { type: 'json' }
|
|
194
|
+
|
|
195
|
+
// ❌ Avoid: Missing import attribute
|
|
196
|
+
import { version } from '../package.json'
|
|
197
|
+
import config from './config.json'
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**Rationale:** Import attributes (ES2025) explicitly declare module types to the runtime. The `with { type: 'json' }` syntax is the standard (replacing the deprecated `assert` keyword). This provides runtime enforcement—if the file isn't valid JSON, the import fails.
|
|
201
|
+
|
|
202
|
+
## Module Organization
|
|
203
|
+
|
|
204
|
+
Organize module exports into separate files by category:
|
|
205
|
+
|
|
206
|
+
```
|
|
207
|
+
module/
|
|
208
|
+
├── module.types.ts # Type definitions only
|
|
209
|
+
├── module.schemas.ts # Zod schemas and schema-inferred types
|
|
210
|
+
├── module.constants.ts # Constants and enum-like objects
|
|
211
|
+
├── module-client.ts # Implementation
|
|
212
|
+
└── index.ts # Public API exports (barrel file)
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Key Principles
|
|
216
|
+
|
|
217
|
+
- **Types file**: Contains only type definitions, does NOT re-export from sibling files
|
|
218
|
+
- **Schemas file**: Contains Zod schemas and their inferred types, does NOT export constants
|
|
219
|
+
- **Constants file**: Contains all constant values (error codes, method names, defaults)
|
|
220
|
+
- **Barrel file**: Uses wildcard exports; non-public files are simply not included
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
// ✅ Good: Direct imports from specific files
|
|
224
|
+
import type { Config } from './module.types.ts'
|
|
225
|
+
import { ConfigSchema } from './module.schemas.ts'
|
|
226
|
+
import { METHODS, ERROR_CODES } from './module.constants.ts'
|
|
227
|
+
|
|
228
|
+
// ❌ Avoid: Expecting types file to re-export everything
|
|
229
|
+
import { Config, ConfigSchema, METHODS } from './module.types.ts'
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
**Rationale:** Prevents circular dependencies, makes dependencies explicit, improves tree-shaking.
|
|
233
|
+
|
|
234
|
+
## Documentation Standards
|
|
235
|
+
|
|
236
|
+
### Mermaid Diagrams Only
|
|
237
|
+
|
|
238
|
+
Use [mermaid](https://mermaid.js.org/) syntax for all diagrams in markdown files:
|
|
239
|
+
|
|
240
|
+
```markdown
|
|
241
|
+
\```mermaid
|
|
242
|
+
flowchart TD
|
|
243
|
+
A[Start] --> B[Process]
|
|
244
|
+
B --> C[End]
|
|
245
|
+
\```
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
**Avoid**: ASCII box-drawing characters (`┌`, `│`, `└`, `─`, etc.)
|
|
249
|
+
|
|
250
|
+
**Rationale:** Token efficiency, clearer semantic meaning, easier maintenance.
|
|
251
|
+
|
|
252
|
+
### No `@example` Sections in TSDoc
|
|
253
|
+
|
|
254
|
+
Tests serve as living examples. Do not add `@example` sections to TSDoc comments.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Git Workflow
|
|
2
|
+
|
|
3
|
+
## Commit Message Format
|
|
4
|
+
|
|
5
|
+
When creating commits with multi-line messages, use single-quoted strings instead of heredocs. The sandbox environment restricts temp file creation needed for heredocs.
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# ✅ CORRECT: Single-quoted multi-line string
|
|
9
|
+
git commit -m 'refactor: description here
|
|
10
|
+
|
|
11
|
+
Additional context on second line.
|
|
12
|
+
|
|
13
|
+
🤖 Generated with [Claude Code](https://claude.com/claude-code)
|
|
14
|
+
|
|
15
|
+
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>'
|
|
16
|
+
|
|
17
|
+
# ❌ WRONG: Heredoc syntax (fails in sandbox)
|
|
18
|
+
git commit -m "$(cat <<'EOF'
|
|
19
|
+
refactor: description here
|
|
20
|
+
EOF
|
|
21
|
+
)"
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The heredoc approach fails with:
|
|
25
|
+
```
|
|
26
|
+
(eval):1: can't create temp file for here document: operation not permitted
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Commit Conventions
|
|
30
|
+
|
|
31
|
+
This project follows conventional commits:
|
|
32
|
+
- `feat:` - New features
|
|
33
|
+
- `fix:` - Bug fixes
|
|
34
|
+
- `refactor:` - Code changes that neither fix bugs nor add features
|
|
35
|
+
- `docs:` - Documentation only changes
|
|
36
|
+
- `chore:` - Maintenance tasks
|
|
37
|
+
- `test:` - Adding or updating tests
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# GitHub Integration
|
|
2
|
+
|
|
3
|
+
## Prefer GitHub CLI Over Web Fetch
|
|
4
|
+
|
|
5
|
+
When given GitHub URLs (PRs, issues, repos), use the `gh` CLI instead of WebFetch for more reliable and complete data access.
|
|
6
|
+
|
|
7
|
+
### PR Information
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# Get PR details with comments and reviews (comprehensive)
|
|
11
|
+
gh pr view <number> --repo <owner>/<repo> --json title,body,comments,reviews,reviewRequests,state,author,additions,deletions,changedFiles
|
|
12
|
+
|
|
13
|
+
# Get PR diff
|
|
14
|
+
gh pr diff <number> --repo <owner>/<repo>
|
|
15
|
+
|
|
16
|
+
# Get PR files changed
|
|
17
|
+
gh pr view <number> --repo <owner>/<repo> --json files
|
|
18
|
+
|
|
19
|
+
# Get PR checks status
|
|
20
|
+
gh pr checks <number> --repo <owner>/<repo>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Complete PR Evaluation Workflow
|
|
24
|
+
|
|
25
|
+
When asked to evaluate PR feedback, you MUST fetch **all** feedback sources. Do not just fetch comments/reviews - also check security alerts and inline code comments.
|
|
26
|
+
|
|
27
|
+
**Step 1: Fetch PR comments and reviews**
|
|
28
|
+
```bash
|
|
29
|
+
gh pr view <number> --repo <owner>/<repo> --json title,body,comments,reviews,state
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Step 2: Fetch code scanning alerts (security vulnerabilities)**
|
|
33
|
+
```bash
|
|
34
|
+
gh api repos/<owner>/<repo>/code-scanning/alerts --jq '
|
|
35
|
+
.[] | select(.state == "open") | {
|
|
36
|
+
number: .number,
|
|
37
|
+
rule: .rule.description,
|
|
38
|
+
severity: .rule.severity,
|
|
39
|
+
file: .most_recent_instance.location.path,
|
|
40
|
+
line: .most_recent_instance.location.start_line
|
|
41
|
+
}
|
|
42
|
+
'
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**Step 3: Fetch inline review comments (code quality, suggestions)**
|
|
46
|
+
```bash
|
|
47
|
+
gh api repos/<owner>/<repo>/pulls/<number>/comments --jq '
|
|
48
|
+
.[] | {
|
|
49
|
+
id: .id,
|
|
50
|
+
user: .user.login,
|
|
51
|
+
file: .path,
|
|
52
|
+
line: .line,
|
|
53
|
+
body: .body
|
|
54
|
+
}
|
|
55
|
+
'
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**Step 4: Address ALL feedback**
|
|
59
|
+
Create a checklist and address each item:
|
|
60
|
+
- [ ] Human reviewer comments
|
|
61
|
+
- [ ] Claude Code review comments
|
|
62
|
+
- [ ] GitHub Advanced Security alerts (ReDoS, injection, etc.)
|
|
63
|
+
- [ ] GitHub Code Quality comments (dead code, useless assignments)
|
|
64
|
+
- [ ] Inline review suggestions
|
|
65
|
+
|
|
66
|
+
### Comment Sources
|
|
67
|
+
|
|
68
|
+
| Source | API/Location | Description |
|
|
69
|
+
|--------|--------------|-------------|
|
|
70
|
+
| Human reviewers | `gh pr view --json reviews` | Code owners, team members |
|
|
71
|
+
| Claude Code | `gh pr view --json comments` | AI-generated review (login: `claude`) |
|
|
72
|
+
| GitHub Advanced Security | `gh api .../code-scanning/alerts` | Security vulnerabilities (ReDoS, injection) |
|
|
73
|
+
| GitHub Code Quality | `gh api .../pulls/.../comments` | Code quality issues (login: `github-code-quality[bot]`) |
|
|
74
|
+
| Inline suggestions | `gh api .../pulls/.../comments` | Line-specific review comments |
|
|
75
|
+
|
|
76
|
+
### Filtering by Author
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# Get all automated reviews from PR
|
|
80
|
+
gh pr view <number> --repo <owner>/<repo> --json reviews --jq '
|
|
81
|
+
.reviews[] | select(.author.login | test("github-|claude")) | {author: .author.login, state: .state}
|
|
82
|
+
'
|
|
83
|
+
|
|
84
|
+
# Get specific inline comment by ID
|
|
85
|
+
gh api repos/<owner>/<repo>/pulls/<number>/comments --jq '
|
|
86
|
+
.[] | select(.id == <comment_id>)
|
|
87
|
+
'
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### URL Patterns for Specific Feedback
|
|
91
|
+
|
|
92
|
+
| URL Pattern | How to Fetch |
|
|
93
|
+
|-------------|--------------|
|
|
94
|
+
| `.../pull/<n>#issuecomment-<id>` | `gh pr view <n> --json comments` |
|
|
95
|
+
| `.../pull/<n>#discussion_r<id>` | `gh api repos/.../pulls/<n>/comments` |
|
|
96
|
+
| `.../security/code-scanning/<id>` | `gh api repos/.../code-scanning/alerts/<id>` |
|
|
97
|
+
|
|
98
|
+
### Review States
|
|
99
|
+
- `APPROVED` - Reviewer approved changes
|
|
100
|
+
- `CHANGES_REQUESTED` - Reviewer requested changes
|
|
101
|
+
- `COMMENTED` - Review with comments only
|
|
102
|
+
- `PENDING` - Review not yet submitted
|
|
103
|
+
|
|
104
|
+
### Issue Information
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# Get issue details
|
|
108
|
+
gh issue view <number> --repo <owner>/<repo> --json title,body,comments,state,author
|
|
109
|
+
|
|
110
|
+
# List issues
|
|
111
|
+
gh issue list --repo <owner>/<repo> --json number,title,state
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Repository Information
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
# Get repo info
|
|
118
|
+
gh repo view <owner>/<repo> --json name,description,url
|
|
119
|
+
|
|
120
|
+
# List workflows
|
|
121
|
+
gh workflow list --repo <owner>/<repo>
|
|
122
|
+
|
|
123
|
+
# View run logs
|
|
124
|
+
gh run view <run-id> --repo <owner>/<repo> --log
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### URL Parsing
|
|
128
|
+
|
|
129
|
+
When given a GitHub URL, extract the components:
|
|
130
|
+
|
|
131
|
+
| URL Pattern | Command |
|
|
132
|
+
|-------------|---------|
|
|
133
|
+
| `github.com/<owner>/<repo>/pull/<number>` | `gh pr view <number> --repo <owner>/<repo>` |
|
|
134
|
+
| `github.com/<owner>/<repo>/issues/<number>` | `gh issue view <number> --repo <owner>/<repo>` |
|
|
135
|
+
| `github.com/<owner>/<repo>` | `gh repo view <owner>/<repo>` |
|
|
136
|
+
| `github.com/<owner>/<repo>/actions/runs/<id>` | `gh run view <id> --repo <owner>/<repo>` |
|
|
137
|
+
|
|
138
|
+
### JSON Output Fields
|
|
139
|
+
|
|
140
|
+
Common useful JSON fields for PRs:
|
|
141
|
+
- `title`, `body`, `state`, `author`
|
|
142
|
+
- `comments` - PR comments
|
|
143
|
+
- `reviews` - Review comments and approvals
|
|
144
|
+
- `additions`, `deletions`, `changedFiles`
|
|
145
|
+
- `files` - List of changed files
|
|
146
|
+
- `commits` - Commit history
|
|
147
|
+
|
|
148
|
+
### Benefits Over WebFetch
|
|
149
|
+
|
|
150
|
+
1. **Complete data** - Access to all comments, reviews, and metadata
|
|
151
|
+
2. **Authentication** - Uses configured GitHub credentials
|
|
152
|
+
3. **Structured output** - JSON format for reliable parsing
|
|
153
|
+
4. **No rate limiting issues** - Authenticated requests have higher limits
|
|
154
|
+
5. **Access to private repos** - Works with repos you have access to
|