Skip to content

Commit 5b7b149

Browse files
committed
refactor(agents): simplify CLI agent modes to work/review, add customization options
- Remove test mode (redundant with work mode for e2e scenarios) - Add defaultMode config option for agents to set their own default - Add workModeInstructions/testModeInstructions config overrides - Add CliAgentMode type and CLI_AGENT_MODES constant for type safety - Extract getTestModeInstructions into separate function (then removed) - Use CLI_AGENT_MODES constant instead of hardcoded arrays (DRY) - Update prompts and schemas to reflect two-mode system
1 parent 198b0a4 commit 5b7b149

File tree

4 files changed

+123
-49
lines changed

4 files changed

+123
-49
lines changed

.agents/lib/cli-agent-prompts.ts

Lines changed: 84 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { CliAgentConfig } from './cli-agent-types'
2+
import { CLI_AGENT_MODES } from './cli-agent-types'
23

34
const TMUX_SESSION_DOCS = `## Session Logs (Paper Trail)
45
@@ -71,33 +72,42 @@ The review should focus on these key areas:
7172
- Missing or incomplete type definitions`
7273

7374
export function getSpawnerPrompt(config: CliAgentConfig): string {
74-
const base = `Expert at testing ${config.cliName} CLI functionality using tmux, or performing code reviews via ${config.cliName}.
75+
const defaultMode = config.defaultMode ?? 'work'
76+
const modeDescriptions = {
77+
work: `Use ${config.cliName} to implement features, fix bugs, refactor code, or complete other coding tasks.`,
78+
review: `Uses ${config.cliName} CLI to perform code reviews on specified files or directories.`,
79+
}
80+
const modeLines = CLI_AGENT_MODES.map(mode => {
81+
const isDefault = mode === defaultMode
82+
return `- \`${mode}\`${isDefault ? ' (default)' : ''}: ${modeDescriptions[mode]}`
83+
}).join('\n')
84+
85+
const base = `Expert at using ${config.cliName} CLI via tmux for implementation work or code reviews.
7586
7687
**Modes:**
77-
- \`test\` (default): Spawns tmux sessions, sends input to ${config.cliName} CLI, captures terminal output, and validates behavior.
78-
- \`review\`: Uses ${config.cliName} CLI to perform code reviews on specified files or directories.
88+
${modeLines}
7989
8090
**Paper trail:** Session logs are saved to \`debug/tmux-sessions/{session}/\`. Use \`read_files\` to view captures.
8191
8292
**Your responsibilities as the parent agent:**
8393
1. If \`scriptIssues\` is not empty, fix the scripts in \`scripts/tmux/\` based on the suggested fixes
8494
2. Use \`read_files\` on the capture paths to see what the CLI displayed
85-
3. Re-run the test after fixing any script issues`
95+
3. Re-run the agent after fixing any script issues`
8696

8797
return config.spawnerPromptExtras ? `${base}\n\n${config.spawnerPromptExtras}` : base
8898
}
8999

90100
export function getSystemPrompt(config: CliAgentConfig): string {
91101
const cliSpecificSection = config.cliSpecificDocs ? `\n${config.cliSpecificDocs}\n` : '\n'
92102

93-
return `You are an expert at testing ${config.cliName} CLI using tmux. You have access to helper scripts that handle the complexities of tmux communication with TUI apps.
103+
return `You are an expert at using ${config.cliName} CLI via tmux for implementation work and code reviews. You have access to helper scripts that handle the complexities of tmux communication with TUI apps.
94104
95105
## ${config.cliName} Startup
96106
97-
For testing ${config.cliName}, use the \`--command\` flag with permission bypass:
107+
To start ${config.cliName}, use the \`--command\` flag with permission bypass:
98108
99109
\`\`\`bash
100-
# Start ${config.cliName} CLI (with permission bypass for testing)
110+
# Start ${config.cliName} CLI (with permission bypass)
101111
SESSION=$(./scripts/tmux/tmux-cli.sh start --command "${config.startCommand}")
102112
103113
# Or with specific options
@@ -108,12 +118,12 @@ SESSION=$(./scripts/tmux/tmux-cli.sh start --command "${config.startCommand} --h
108118
${cliSpecificSection}
109119
## Helper Scripts
110120
111-
Use these scripts in \`scripts/tmux/\` for reliable CLI testing:
121+
Use these scripts in \`scripts/tmux/\` for reliable CLI interaction:
112122
113123
### Unified Script (Recommended)
114124
115125
\`\`\`bash
116-
# Start a ${config.cliName} test session (with permission bypass)
126+
# Start a ${config.cliName} session (with permission bypass)
117127
SESSION=$(./scripts/tmux/tmux-cli.sh start --command "${config.startCommand}")
118128
119129
# Send input to the CLI
@@ -162,7 +172,8 @@ ${TMUX_DEBUG_TIPS}`
162172
}
163173

164174
export function getDefaultReviewModeInstructions(config: CliAgentConfig): string {
165-
return `## Review Mode Instructions
175+
const isDefault = config.defaultMode === 'review'
176+
return `## Review Mode Instructions${isDefault ? ' (Default)' : ''}
166177
167178
In review mode, you send a detailed review prompt to ${config.cliName}. The prompt MUST start with the word "review" and include specific areas of concern.
168179
@@ -216,60 +227,98 @@ ${REVIEW_CRITERIA}
216227
\`\`\``
217228
}
218229

219-
export function getInstructionsPrompt(config: CliAgentConfig): string {
220-
const reviewModeInstructions = config.reviewModeInstructions ?? getDefaultReviewModeInstructions(config)
230+
export function getWorkModeInstructions(config: CliAgentConfig): string {
231+
const isDefault = (config.defaultMode ?? 'work') === 'work'
232+
return `## Work Mode Instructions${isDefault ? ' (Default)' : ''}
221233
222-
return `Instructions:
234+
Use ${config.cliName} to complete implementation tasks like building features, fixing bugs, or refactoring code.
223235
224-
Check the \`mode\` parameter to determine your operation:
225-
- If \`mode\` is "review": follow **Review Mode** instructions
226-
- Otherwise: follow **Test Mode** instructions (default)
236+
### Workflow
227237
228-
---
238+
1. **Start ${config.cliName}** with permission bypass:
239+
\`\`\`bash
240+
SESSION=$(./scripts/tmux/tmux-cli.sh start --command "${config.startCommand}")
241+
\`\`\`
229242
230-
## Test Mode Instructions
243+
2. **Wait for CLI to initialize**, then capture:
244+
\`\`\`bash
245+
sleep 3
246+
./scripts/tmux/tmux-cli.sh capture "$SESSION" --label "initial-state"
247+
\`\`\`
248+
249+
3. **Send your task** (from the prompt you received) to the CLI:
250+
\`\`\`bash
251+
./scripts/tmux/tmux-cli.sh send "$SESSION" "<the task from your prompt parameter>"
252+
\`\`\`
231253
232-
1. **Use the helper scripts** in \`scripts/tmux/\` - they handle bracketed paste mode automatically
254+
Use the exact task description from the prompt the parent agent gave you.
233255
234-
2. **Start a ${config.cliName} test session** with permission bypass:
256+
4. **Wait for completion and capture output** (implementation tasks may take a while):
235257
\`\`\`bash
236-
SESSION=$(./scripts/tmux/tmux-cli.sh start --command "${config.startCommand}")
258+
./scripts/tmux/tmux-cli.sh capture "$SESSION" --label "work-in-progress" --wait 30
237259
\`\`\`
238260
239-
3. **Verify the CLI started** by capturing initial output:
261+
If the work is still in progress, wait and capture again:
240262
\`\`\`bash
241-
./scripts/tmux/tmux-cli.sh capture "$SESSION"
263+
./scripts/tmux/tmux-cli.sh capture "$SESSION" --label "work-continued" --wait 30
242264
\`\`\`
243265
244-
4. **Send commands** and capture responses:
266+
5. **Send follow-up prompts** if needed to refine or continue the work:
245267
\`\`\`bash
246-
./scripts/tmux/tmux-cli.sh send "$SESSION" "your command here"
247-
./scripts/tmux/tmux-cli.sh capture "$SESSION" --wait 3
268+
./scripts/tmux/tmux-cli.sh send "$SESSION" "<follow-up instructions>"
269+
./scripts/tmux/tmux-cli.sh capture "$SESSION" --label "follow-up" --wait 30
248270
\`\`\`
249271
250-
5. **Always clean up** when done:
272+
6. **Verify the changes** by checking files or running commands:
251273
\`\`\`bash
252-
./scripts/tmux/tmux-cli.sh stop "$SESSION"
274+
./scripts/tmux/tmux-cli.sh send "$SESSION" "run the tests to verify the changes"
275+
./scripts/tmux/tmux-cli.sh capture "$SESSION" --label "verification" --wait 60
253276
\`\`\`
254277
255-
6. **Use labels when capturing** to create a clear paper trail:
278+
7. **Clean up** when done:
256279
\`\`\`bash
257-
./scripts/tmux/tmux-cli.sh capture "$SESSION" --label "initial-state"
258-
./scripts/tmux/tmux-cli.sh capture "$SESSION" --label "after-help-command" --wait 2
280+
./scripts/tmux/tmux-cli.sh stop "$SESSION"
259281
\`\`\`
260282
283+
### Tips
284+
285+
- Break complex tasks into smaller prompts
286+
- Capture frequently to track progress
287+
- Use descriptive labels for captures
288+
- Check intermediate results before moving on`
289+
}
290+
291+
export function getInstructionsPrompt(config: CliAgentConfig): string {
292+
const defaultMode = config.defaultMode ?? 'work'
293+
const workModeInstructions = config.workModeInstructions ?? getWorkModeInstructions(config)
294+
const reviewModeInstructions = config.reviewModeInstructions ?? getDefaultReviewModeInstructions(config)
295+
296+
const modeNames = { work: 'Work Mode', review: 'Review Mode' }
297+
const nonDefaultModes = CLI_AGENT_MODES.filter(m => m !== defaultMode)
298+
const modeChecks = nonDefaultModes.map(m => `- If \`mode\` is "${m}": follow **${modeNames[m]}** instructions`).join('\n')
299+
300+
return `Instructions:
301+
302+
Check the \`mode\` parameter to determine your operation:
303+
${modeChecks}
304+
- Otherwise: follow **${modeNames[defaultMode]}** instructions (default)
305+
306+
---
307+
308+
${workModeInstructions}
309+
261310
---
262311
263312
${reviewModeInstructions}
264313
265314
---
266315
267-
## Output (Both Modes)
316+
## Output (All Modes)
268317
269318
**Report results using set_output** - You MUST call set_output with structured results:
270319
- \`overallStatus\`: "success", "failure", or "partial"
271-
- \`summary\`: Brief description of what was tested/reviewed
272-
- \`testResults\`: Array of test outcomes (for test mode)
320+
- \`summary\`: Brief description of what was done
321+
- \`results\`: Array of task outcomes (for work mode)
273322
- \`scriptIssues\`: Array of any problems with the helper scripts
274323
- \`captures\`: Array of capture paths with labels
275324
- \`reviewFindings\`: Array of code review findings (for review mode)
@@ -278,7 +327,7 @@ ${reviewModeInstructions}
278327
- \`script\`: Which script failed
279328
- \`issue\`: What went wrong
280329
- \`errorOutput\`: The actual error message
281-
- \`suggestedFix\`: How the parent agent should fix the script
330+
- \`suggestedFix\`: How to fix the script
282331
283332
**Always include captures** in your output so the parent agent can see what you saw.
284333

.agents/lib/cli-agent-schemas.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,29 @@
1-
// Shared output schema for CLI tester agents. testResults for test mode, reviewFindings for review mode.
1+
// Shared output schema for CLI agents. results for work mode, reviewFindings for review mode.
22
export const outputSchema = {
33
type: 'object' as const,
44
properties: {
55
overallStatus: {
66
type: 'string' as const,
77
enum: ['success', 'failure', 'partial'],
8-
description: 'Overall test outcome',
8+
description: 'Overall outcome',
99
},
1010
summary: {
1111
type: 'string' as const,
12-
description: 'Brief summary of what was tested and the outcome',
12+
description: 'Brief summary of what was done and the outcome',
1313
},
14-
testResults: {
14+
results: {
1515
type: 'array' as const,
1616
items: {
1717
type: 'object' as const,
1818
properties: {
19-
testName: { type: 'string' as const, description: 'Name/description of the test' },
20-
passed: { type: 'boolean' as const, description: 'Whether the test passed' },
19+
name: { type: 'string' as const, description: 'Name/description of the task' },
20+
passed: { type: 'boolean' as const, description: 'Whether the task succeeded' },
2121
details: { type: 'string' as const, description: 'Details about what happened' },
2222
capturedOutput: { type: 'string' as const, description: 'Relevant output captured from the CLI' },
2323
},
24-
required: ['testName', 'passed'],
24+
required: ['name', 'passed'],
2525
},
26-
description: 'Array of individual test results',
26+
description: 'Array of individual task results',
2727
},
2828
scriptIssues: {
2929
type: 'array' as const,
@@ -37,7 +37,7 @@ export const outputSchema = {
3737
},
3838
required: ['script', 'issue', 'suggestedFix'],
3939
},
40-
description: 'Issues encountered with the helper scripts that the parent agent should fix',
40+
description: 'Issues encountered with the helper scripts that should be fixed',
4141
},
4242
captures: {
4343
type: 'array' as const,

.agents/lib/cli-agent-types.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
1+
export type CliAgentMode = 'work' | 'review'
2+
3+
export const CLI_AGENT_MODES: readonly CliAgentMode[] = ['work', 'review'] as const
4+
15
export interface InputParamDefinition {
26
type: 'string' | 'number' | 'boolean' | 'array' | 'object'
37
description?: string
48
enum?: string[]
59
}
610

7-
// Prevent extraInputParams from overriding 'mode' at compile time
8-
export type ExtraInputParams = Omit<Record<string, InputParamDefinition>, 'mode'>
11+
/**
12+
* Extra input params that can be added to CLI agent configs.
13+
* Uses key remapping to exclude 'mode' at compile time (Omit on Record is a no-op).
14+
*/
15+
export type ExtraInputParams = {
16+
[K in string as K extends 'mode' ? never : K]?: InputParamDefinition
17+
}
918

1019
export interface CliAgentConfig {
1120
id: string
@@ -16,8 +25,13 @@ export interface CliAgentConfig {
1625
startCommand: string
1726
permissionNote: string
1827
model: string
28+
/** Default mode when mode param is not specified. Defaults to 'work' */
29+
defaultMode?: CliAgentMode
1930
spawnerPromptExtras?: string
2031
extraInputParams?: ExtraInputParams
32+
/** Custom instructions for work mode. If not provided, uses getWorkModeInstructions() */
33+
workModeInstructions?: string
34+
/** Custom instructions for review mode. If not provided, uses getDefaultReviewModeInstructions() */
2135
reviewModeInstructions?: string
2236
cliSpecificDocs?: string
2337
}

.agents/lib/create-cli-agent.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { AgentDefinition } from '../types/agent-definition'
22
import type { CliAgentConfig } from './cli-agent-types'
3+
import { CLI_AGENT_MODES } from './cli-agent-types'
34
import { outputSchema } from './cli-agent-schemas'
45
import {
56
getSpawnerPrompt,
@@ -15,11 +16,21 @@ export function createCliAgent(config: CliAgentConfig): AgentDefinition {
1516
)
1617
}
1718

19+
const defaultMode = config.defaultMode ?? 'work'
20+
const modeDescriptions = {
21+
work: 'implementation tasks',
22+
review: `code review via ${config.cliName}`,
23+
}
24+
const modeDescParts = CLI_AGENT_MODES.map(mode => {
25+
const isDefault = mode === defaultMode
26+
return `"${mode}" for ${modeDescriptions[mode]}${isDefault ? ' (default)' : ''}`
27+
})
28+
1829
const baseInputParams = {
1930
mode: {
2031
type: 'string' as const,
21-
enum: ['test', 'review'],
22-
description: `Operation mode - "test" for CLI testing (default), "review" for code review via ${config.cliName}`,
32+
enum: [...CLI_AGENT_MODES],
33+
description: `Operation mode - ${modeDescParts.join(', ')}`,
2334
},
2435
}
2536

@@ -38,7 +49,7 @@ export function createCliAgent(config: CliAgentConfig): AgentDefinition {
3849
prompt: {
3950
type: 'string' as const,
4051
description:
41-
'Description of what to do. For test mode: what CLI functionality to test. For review mode: what code to review and any specific concerns.',
52+
'Description of what to do. For work mode: implementation task to complete. For review mode: code to review.',
4253
},
4354
params: {
4455
type: 'object' as const,

0 commit comments

Comments
 (0)