@a5c-ai/agent-mux-harness-mock 0.2.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/LICENSE +21 -0
- package/README.md +32 -0
- package/dist/bin/mock-harness.d.ts +33 -0
- package/dist/bin/mock-harness.d.ts.map +1 -0
- package/dist/bin/mock-harness.js +165 -0
- package/dist/bin/mock-harness.js.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/mock-process.d.ts +47 -0
- package/dist/mock-process.d.ts.map +1 -0
- package/dist/mock-process.js +207 -0
- package/dist/mock-process.js.map +1 -0
- package/dist/probe.d.ts +60 -0
- package/dist/probe.d.ts.map +1 -0
- package/dist/probe.js +168 -0
- package/dist/probe.js.map +1 -0
- package/dist/scenarios/errors.d.ts +22 -0
- package/dist/scenarios/errors.d.ts.map +1 -0
- package/dist/scenarios/errors.js +73 -0
- package/dist/scenarios/errors.js.map +1 -0
- package/dist/scenarios/hooks.d.ts +13 -0
- package/dist/scenarios/hooks.d.ts.map +1 -0
- package/dist/scenarios/hooks.js +61 -0
- package/dist/scenarios/hooks.js.map +1 -0
- package/dist/scenarios/index.d.ts +23 -0
- package/dist/scenarios/index.d.ts.map +1 -0
- package/dist/scenarios/index.js +47 -0
- package/dist/scenarios/index.js.map +1 -0
- package/dist/scenarios/interactive.d.ts +18 -0
- package/dist/scenarios/interactive.d.ts.map +1 -0
- package/dist/scenarios/interactive.js +46 -0
- package/dist/scenarios/interactive.js.map +1 -0
- package/dist/scenarios/per-agent.d.ts +46 -0
- package/dist/scenarios/per-agent.d.ts.map +1 -0
- package/dist/scenarios/per-agent.js +150 -0
- package/dist/scenarios/per-agent.js.map +1 -0
- package/dist/scenarios/wire-format.d.ts +36 -0
- package/dist/scenarios/wire-format.d.ts.map +1 -0
- package/dist/scenarios/wire-format.js +96 -0
- package/dist/scenarios/wire-format.js.map +1 -0
- package/dist/scenarios.d.ts +30 -0
- package/dist/scenarios.d.ts.map +1 -0
- package/dist/scenarios.js +141 -0
- package/dist/scenarios.js.map +1 -0
- package/dist/types.d.ts +144 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/dist/workspace.d.ts +53 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +157 -0
- package/dist/workspace.js.map +1 -0
- package/package.json +58 -0
package/dist/probe.d.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HarnessProbe — probes real harness installations to capture behavior profiles.
|
|
3
|
+
*
|
|
4
|
+
* Used by the CI pipeline to periodically compare mock fidelity against
|
|
5
|
+
* real harness behavior. Runs the actual CLI tools with controlled inputs
|
|
6
|
+
* and records output format, timing, exit codes, etc.
|
|
7
|
+
*/
|
|
8
|
+
import type { HarnessType, HarnessBehaviorProfile } from './types.js';
|
|
9
|
+
export interface ProbeConfig {
|
|
10
|
+
/** The harness to probe. */
|
|
11
|
+
harness: HarnessType;
|
|
12
|
+
/** Command to invoke (e.g., 'claude', 'codex'). */
|
|
13
|
+
command: string;
|
|
14
|
+
/** Arguments for a simple probe run. */
|
|
15
|
+
args?: string[];
|
|
16
|
+
/** Environment overrides for the probe. */
|
|
17
|
+
env?: Record<string, string>;
|
|
18
|
+
/** Timeout for each probe run (ms). */
|
|
19
|
+
timeoutMs?: number;
|
|
20
|
+
/** Working directory for the probe. */
|
|
21
|
+
cwd?: string;
|
|
22
|
+
}
|
|
23
|
+
/** Pre-configured probe configurations for known harnesses. */
|
|
24
|
+
export declare const PROBE_CONFIGS: Record<string, ProbeConfig>;
|
|
25
|
+
export interface ProbeResult {
|
|
26
|
+
/** Whether the probe succeeded. */
|
|
27
|
+
success: boolean;
|
|
28
|
+
/** Error message if the probe failed. */
|
|
29
|
+
error?: string;
|
|
30
|
+
/** The captured behavior profile. */
|
|
31
|
+
profile?: HarnessBehaviorProfile;
|
|
32
|
+
/** Raw stdout from the probe. */
|
|
33
|
+
stdout?: string;
|
|
34
|
+
/** Raw stderr from the probe. */
|
|
35
|
+
stderr?: string;
|
|
36
|
+
/** Exit code from the probe. */
|
|
37
|
+
exitCode?: number;
|
|
38
|
+
/** Wall-clock duration of the probe (ms). */
|
|
39
|
+
durationMs?: number;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Probe a real harness installation and capture its behavior profile.
|
|
43
|
+
*/
|
|
44
|
+
export declare function probeHarness(config: ProbeConfig): Promise<ProbeResult>;
|
|
45
|
+
/**
|
|
46
|
+
* Probe all configured harnesses and save profiles to a directory.
|
|
47
|
+
*/
|
|
48
|
+
export declare function probeAllHarnesses(outputDir: string, configs?: Record<string, ProbeConfig>): Promise<Map<string, ProbeResult>>;
|
|
49
|
+
/**
|
|
50
|
+
* Compare a behavior profile against a previous baseline.
|
|
51
|
+
* Returns a list of differences.
|
|
52
|
+
*/
|
|
53
|
+
export declare function compareProfiles(baseline: HarnessBehaviorProfile, current: HarnessBehaviorProfile): ProfileDiff[];
|
|
54
|
+
export interface ProfileDiff {
|
|
55
|
+
field: string;
|
|
56
|
+
baseline: unknown;
|
|
57
|
+
current: unknown;
|
|
58
|
+
severity: 'info' | 'warning' | 'breaking';
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=probe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probe.d.ts","sourceRoot":"","sources":["../src/probe.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH,OAAO,KAAK,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAMtE,MAAM,WAAW,WAAW;IAC1B,4BAA4B;IAC5B,OAAO,EAAE,WAAW,CAAC;IAErB,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC;IAEhB,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAEhB,2CAA2C;IAC3C,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE7B,uCAAuC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,uCAAuC;IACvC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,+DAA+D;AAC/D,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAarD,CAAC;AAMF,MAAM,WAAW,WAAW;IAC1B,mCAAmC;IACnC,OAAO,EAAE,OAAO,CAAC;IAEjB,yCAAyC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,qCAAqC;IACrC,OAAO,CAAC,EAAE,sBAAsB,CAAC;IAEjC,iCAAiC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,iCAAiC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,gCAAgC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAMD;;GAEG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAkD5E;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GACpC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CA2BnC;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,sBAAsB,EAChC,OAAO,EAAE,sBAAsB,GAC9B,WAAW,EAAE,CAiCf;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC;CAC3C"}
|
package/dist/probe.js
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HarnessProbe — probes real harness installations to capture behavior profiles.
|
|
3
|
+
*
|
|
4
|
+
* Used by the CI pipeline to periodically compare mock fidelity against
|
|
5
|
+
* real harness behavior. Runs the actual CLI tools with controlled inputs
|
|
6
|
+
* and records output format, timing, exit codes, etc.
|
|
7
|
+
*/
|
|
8
|
+
import { execFile } from 'node:child_process';
|
|
9
|
+
import * as fs from 'node:fs';
|
|
10
|
+
import * as os from 'node:os';
|
|
11
|
+
import * as path from 'node:path';
|
|
12
|
+
/** Pre-configured probe configurations for known harnesses. */
|
|
13
|
+
export const PROBE_CONFIGS = {
|
|
14
|
+
'claude-code': {
|
|
15
|
+
harness: 'claude-code',
|
|
16
|
+
command: 'claude',
|
|
17
|
+
args: ['-p', 'Say hello in one word', '--output-format', 'json'],
|
|
18
|
+
timeoutMs: 30000,
|
|
19
|
+
},
|
|
20
|
+
'codex': {
|
|
21
|
+
harness: 'codex',
|
|
22
|
+
command: 'codex',
|
|
23
|
+
args: ['-q', 'Say hello in one word'],
|
|
24
|
+
timeoutMs: 30000,
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
// Probing logic
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
/**
|
|
31
|
+
* Probe a real harness installation and capture its behavior profile.
|
|
32
|
+
*/
|
|
33
|
+
export async function probeHarness(config) {
|
|
34
|
+
const startTime = Date.now();
|
|
35
|
+
const cwd = config.cwd ?? os.tmpdir();
|
|
36
|
+
const timeout = config.timeoutMs ?? 30000;
|
|
37
|
+
return new Promise((resolve) => {
|
|
38
|
+
const child = execFile(config.command, config.args ?? [], {
|
|
39
|
+
cwd,
|
|
40
|
+
timeout,
|
|
41
|
+
maxBuffer: 10 * 1024 * 1024, // 10MB
|
|
42
|
+
env: { ...process.env, ...config.env },
|
|
43
|
+
}, (error, stdout, stderr) => {
|
|
44
|
+
const durationMs = Date.now() - startTime;
|
|
45
|
+
const exitCode = error?.code !== undefined
|
|
46
|
+
? (typeof error.code === 'number' ? error.code : 1)
|
|
47
|
+
: 0;
|
|
48
|
+
if (error && !stdout && !stderr) {
|
|
49
|
+
resolve({
|
|
50
|
+
success: false,
|
|
51
|
+
error: error.message,
|
|
52
|
+
durationMs,
|
|
53
|
+
exitCode: typeof exitCode === 'number' ? exitCode : 1,
|
|
54
|
+
});
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const profile = buildProfile(config, stdout, stderr, durationMs);
|
|
58
|
+
resolve({
|
|
59
|
+
success: true,
|
|
60
|
+
profile,
|
|
61
|
+
stdout,
|
|
62
|
+
stderr,
|
|
63
|
+
exitCode: typeof exitCode === 'number' ? exitCode : 0,
|
|
64
|
+
durationMs,
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
// Safety: kill if timeout is exceeded (execFile should handle this, but belt-and-suspenders)
|
|
68
|
+
setTimeout(() => {
|
|
69
|
+
if (!child.killed) {
|
|
70
|
+
child.kill('SIGKILL');
|
|
71
|
+
}
|
|
72
|
+
}, timeout + 5000);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Probe all configured harnesses and save profiles to a directory.
|
|
77
|
+
*/
|
|
78
|
+
export async function probeAllHarnesses(outputDir, configs) {
|
|
79
|
+
const results = new Map();
|
|
80
|
+
const allConfigs = configs ?? PROBE_CONFIGS;
|
|
81
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
82
|
+
for (const [name, config] of Object.entries(allConfigs)) {
|
|
83
|
+
const result = await probeHarness(config);
|
|
84
|
+
results.set(name, result);
|
|
85
|
+
if (result.profile) {
|
|
86
|
+
const profilePath = path.join(outputDir, `${name}.profile.json`);
|
|
87
|
+
fs.writeFileSync(profilePath, JSON.stringify(result.profile, null, 2), 'utf-8');
|
|
88
|
+
}
|
|
89
|
+
const resultPath = path.join(outputDir, `${name}.result.json`);
|
|
90
|
+
fs.writeFileSync(resultPath, JSON.stringify({
|
|
91
|
+
success: result.success,
|
|
92
|
+
error: result.error,
|
|
93
|
+
exitCode: result.exitCode,
|
|
94
|
+
durationMs: result.durationMs,
|
|
95
|
+
stdoutLength: result.stdout?.length ?? 0,
|
|
96
|
+
stderrLength: result.stderr?.length ?? 0,
|
|
97
|
+
}, null, 2), 'utf-8');
|
|
98
|
+
}
|
|
99
|
+
return results;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Compare a behavior profile against a previous baseline.
|
|
103
|
+
* Returns a list of differences.
|
|
104
|
+
*/
|
|
105
|
+
export function compareProfiles(baseline, current) {
|
|
106
|
+
const diffs = [];
|
|
107
|
+
if (baseline.version !== current.version) {
|
|
108
|
+
diffs.push({ field: 'version', baseline: baseline.version, current: current.version, severity: 'info' });
|
|
109
|
+
}
|
|
110
|
+
if (baseline.outputFormat !== current.outputFormat) {
|
|
111
|
+
diffs.push({ field: 'outputFormat', baseline: baseline.outputFormat, current: current.outputFormat, severity: 'breaking' });
|
|
112
|
+
}
|
|
113
|
+
if (baseline.supportsStdin !== current.supportsStdin) {
|
|
114
|
+
diffs.push({ field: 'supportsStdin', baseline: baseline.supportsStdin, current: current.supportsStdin, severity: 'breaking' });
|
|
115
|
+
}
|
|
116
|
+
// Check exit code changes
|
|
117
|
+
for (const [scenario, code] of Object.entries(baseline.exitCodes)) {
|
|
118
|
+
if (current.exitCodes[scenario] !== undefined && current.exitCodes[scenario] !== code) {
|
|
119
|
+
diffs.push({ field: `exitCodes.${scenario}`, baseline: code, current: current.exitCodes[scenario], severity: 'warning' });
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// Check CLI pattern changes
|
|
123
|
+
for (const [key, pattern] of Object.entries(baseline.cliPatterns)) {
|
|
124
|
+
if (current.cliPatterns[key] !== undefined && current.cliPatterns[key] !== pattern) {
|
|
125
|
+
diffs.push({ field: `cliPatterns.${key}`, baseline: pattern, current: current.cliPatterns[key], severity: 'breaking' });
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// Check startup time drift (>2x is a warning)
|
|
129
|
+
if (current.startupTimeMs > baseline.startupTimeMs * 2) {
|
|
130
|
+
diffs.push({ field: 'startupTimeMs', baseline: baseline.startupTimeMs, current: current.startupTimeMs, severity: 'warning' });
|
|
131
|
+
}
|
|
132
|
+
return diffs;
|
|
133
|
+
}
|
|
134
|
+
// ---------------------------------------------------------------------------
|
|
135
|
+
// Internal helpers
|
|
136
|
+
// ---------------------------------------------------------------------------
|
|
137
|
+
function buildProfile(config, stdout, stderr, durationMs) {
|
|
138
|
+
// Detect output format
|
|
139
|
+
let outputFormat = 'text';
|
|
140
|
+
const firstLine = stdout.split('\n')[0]?.trim() ?? '';
|
|
141
|
+
if (firstLine.startsWith('{')) {
|
|
142
|
+
try {
|
|
143
|
+
JSON.parse(firstLine);
|
|
144
|
+
outputFormat = 'jsonl';
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
outputFormat = 'text';
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// Detect stdin support from stderr cues
|
|
151
|
+
const supportsStdin = stderr.includes('(y/n)') || stderr.includes('stdin') || stderr.includes('interactive');
|
|
152
|
+
return {
|
|
153
|
+
harness: config.harness,
|
|
154
|
+
version: 'unknown', // Would need --version probe
|
|
155
|
+
capturedAt: new Date().toISOString(),
|
|
156
|
+
startupTimeMs: Math.min(durationMs, 5000), // First output would be more precise
|
|
157
|
+
outputFormat,
|
|
158
|
+
supportsStdin,
|
|
159
|
+
fileOperationPatterns: [],
|
|
160
|
+
exitCodes: { 'probe-hello': 0 },
|
|
161
|
+
environmentVariables: [],
|
|
162
|
+
cliPatterns: {
|
|
163
|
+
command: config.command,
|
|
164
|
+
args: (config.args ?? []).join(' '),
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=probe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probe.js","sourceRoot":"","sources":["../src/probe.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error scenarios: rate-limit, auth-required, crash, timeout, oom.
|
|
3
|
+
*
|
|
4
|
+
* Each scenario emits wire output whose parsed AgentEvent has a specific
|
|
5
|
+
* error code, or exits abnormally so onProcessExit/onTimeout surface the
|
|
6
|
+
* appropriate code.
|
|
7
|
+
*/
|
|
8
|
+
import type { HarnessScenario } from '../types.js';
|
|
9
|
+
export interface ErrorScenarioMeta {
|
|
10
|
+
/** Scenario to spawn. */
|
|
11
|
+
scenario: HarnessScenario;
|
|
12
|
+
/** The error code a caller should classify this run as, after combining
|
|
13
|
+
* wire events and process exit. */
|
|
14
|
+
expectedCode: 'RATE_LIMITED' | 'AUTH_ERROR' | 'AGENT_CRASH' | 'TIMEOUT' | 'INTERNAL';
|
|
15
|
+
}
|
|
16
|
+
export declare const rateLimitClaude: ErrorScenarioMeta;
|
|
17
|
+
export declare const authRequiredCodex: ErrorScenarioMeta;
|
|
18
|
+
export declare const crashClaude: ErrorScenarioMeta;
|
|
19
|
+
export declare const timeoutGemini: ErrorScenarioMeta;
|
|
20
|
+
export declare const oomClaude: ErrorScenarioMeta;
|
|
21
|
+
export declare const ERROR_SCENARIOS: Record<string, ErrorScenarioMeta>;
|
|
22
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/scenarios/errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAQnD,MAAM,WAAW,iBAAiB;IAChC,yBAAyB;IACzB,QAAQ,EAAE,eAAe,CAAC;IAC1B;wCACoC;IACpC,YAAY,EAAE,cAAc,GAAG,YAAY,GAAG,aAAa,GAAG,SAAS,GAAG,UAAU,CAAC;CACtF;AAED,eAAO,MAAM,eAAe,EAAE,iBAW7B,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,iBAW/B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,iBAUzB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,iBAU3B,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,iBAUvB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAM7D,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error scenarios: rate-limit, auth-required, crash, timeout, oom.
|
|
3
|
+
*
|
|
4
|
+
* Each scenario emits wire output whose parsed AgentEvent has a specific
|
|
5
|
+
* error code, or exits abnormally so onProcessExit/onTimeout surface the
|
|
6
|
+
* appropriate code.
|
|
7
|
+
*/
|
|
8
|
+
import { claudeError, codexError, geminiError, stderrChunk, stdoutChunk } from './wire-format.js';
|
|
9
|
+
export const rateLimitClaude = {
|
|
10
|
+
scenario: {
|
|
11
|
+
harness: 'claude-code',
|
|
12
|
+
name: 'error:rate-limit',
|
|
13
|
+
process: { exitCode: 1 },
|
|
14
|
+
output: [
|
|
15
|
+
stdoutChunk(claudeError('Rate limit exceeded. Please retry after 60 seconds.'), 10),
|
|
16
|
+
stderrChunk('HTTP 429 Too Many Requests\n', 5),
|
|
17
|
+
],
|
|
18
|
+
},
|
|
19
|
+
expectedCode: 'RATE_LIMITED',
|
|
20
|
+
};
|
|
21
|
+
export const authRequiredCodex = {
|
|
22
|
+
scenario: {
|
|
23
|
+
harness: 'codex',
|
|
24
|
+
name: 'error:auth-required',
|
|
25
|
+
process: { exitCode: 1 },
|
|
26
|
+
output: [
|
|
27
|
+
stdoutChunk(codexError('Missing OPENAI_API_KEY. Please authenticate.'), 10),
|
|
28
|
+
stderrChunk('auth: unauthorized\n', 5),
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
expectedCode: 'AUTH_ERROR',
|
|
32
|
+
};
|
|
33
|
+
export const crashClaude = {
|
|
34
|
+
scenario: {
|
|
35
|
+
harness: 'claude-code',
|
|
36
|
+
name: 'error:crash',
|
|
37
|
+
process: { exitCode: 1, crashAfterMs: 80, crashSignal: 'SIGTERM' },
|
|
38
|
+
output: [
|
|
39
|
+
stderrChunk('segfault\n', 20),
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
expectedCode: 'AGENT_CRASH',
|
|
43
|
+
};
|
|
44
|
+
export const timeoutGemini = {
|
|
45
|
+
scenario: {
|
|
46
|
+
harness: 'gemini',
|
|
47
|
+
name: 'error:timeout',
|
|
48
|
+
process: { exitCode: 0, hang: true },
|
|
49
|
+
output: [
|
|
50
|
+
stdoutChunk(geminiError('Working...'), 10),
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
expectedCode: 'TIMEOUT',
|
|
54
|
+
};
|
|
55
|
+
export const oomClaude = {
|
|
56
|
+
scenario: {
|
|
57
|
+
harness: 'claude-code',
|
|
58
|
+
name: 'error:oom',
|
|
59
|
+
process: { exitCode: 137, crashAfterMs: 60, crashSignal: 'SIGKILL' },
|
|
60
|
+
output: [
|
|
61
|
+
stderrChunk('FATAL ERROR: Reached heap limit\n', 20),
|
|
62
|
+
],
|
|
63
|
+
},
|
|
64
|
+
expectedCode: 'AGENT_CRASH',
|
|
65
|
+
};
|
|
66
|
+
export const ERROR_SCENARIOS = {
|
|
67
|
+
'rate-limit': rateLimitClaude,
|
|
68
|
+
'auth-required': authRequiredCodex,
|
|
69
|
+
'crash': crashClaude,
|
|
70
|
+
'timeout': timeoutGemini,
|
|
71
|
+
'oom': oomClaude,
|
|
72
|
+
};
|
|
73
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/scenarios/errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAelG,MAAM,CAAC,MAAM,eAAe,GAAsB;IAChD,QAAQ,EAAE;QACR,OAAO,EAAE,aAAa;QACtB,IAAI,EAAE,kBAAkB;QACxB,OAAO,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE;QACxB,MAAM,EAAE;YACN,WAAW,CAAC,WAAW,CAAC,qDAAqD,CAAC,EAAE,EAAE,CAAC;YACnF,WAAW,CAAC,8BAA8B,EAAE,CAAC,CAAC;SAC/C;KACF;IACD,YAAY,EAAE,cAAc;CAC7B,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAsB;IAClD,QAAQ,EAAE;QACR,OAAO,EAAE,OAAO;QAChB,IAAI,EAAE,qBAAqB;QAC3B,OAAO,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE;QACxB,MAAM,EAAE;YACN,WAAW,CAAC,UAAU,CAAC,8CAA8C,CAAC,EAAE,EAAE,CAAC;YAC3E,WAAW,CAAC,sBAAsB,EAAE,CAAC,CAAC;SACvC;KACF;IACD,YAAY,EAAE,YAAY;CAC3B,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAsB;IAC5C,QAAQ,EAAE;QACR,OAAO,EAAE,aAAa;QACtB,IAAI,EAAE,aAAa;QACnB,OAAO,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE;QAClE,MAAM,EAAE;YACN,WAAW,CAAC,YAAY,EAAE,EAAE,CAAC;SAC9B;KACF;IACD,YAAY,EAAE,aAAa;CAC5B,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAsB;IAC9C,QAAQ,EAAE;QACR,OAAO,EAAE,QAAQ;QACjB,IAAI,EAAE,eAAe;QACrB,OAAO,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE;QACpC,MAAM,EAAE;YACN,WAAW,CAAC,WAAW,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC;SAC3C;KACF;IACD,YAAY,EAAE,SAAS;CACxB,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAsB;IAC1C,QAAQ,EAAE;QACR,OAAO,EAAE,aAAa;QACtB,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,YAAY,EAAE,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE;QACpE,MAAM,EAAE;YACN,WAAW,CAAC,mCAAmC,EAAE,EAAE,CAAC;SACrD;KACF;IACD,YAAY,EAAE,aAAa;CAC5B,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAsC;IAChE,YAAY,EAAE,eAAe;IAC7B,eAAe,EAAE,iBAAiB;IAClC,OAAO,EAAE,WAAW;IACpB,SAAS,EAAE,aAAa;IACxB,KAAK,EAAE,SAAS;CACjB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook payload fixtures — deterministic JSON payloads that each harness
|
|
3
|
+
* would send to a hook script on stdin. Useful in tests for driving
|
|
4
|
+
* parseHookPayload, HookDispatcher, and `amux hooks handle` end-to-end.
|
|
5
|
+
*/
|
|
6
|
+
export interface HookPayloadFixture {
|
|
7
|
+
agent: string;
|
|
8
|
+
hookType: string;
|
|
9
|
+
payload: Record<string, unknown>;
|
|
10
|
+
}
|
|
11
|
+
export declare const HOOK_PAYLOAD_FIXTURES: HookPayloadFixture[];
|
|
12
|
+
export declare function getHookFixture(agent: string, hookType: string): HookPayloadFixture | undefined;
|
|
13
|
+
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/scenarios/hooks.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,eAAO,MAAM,qBAAqB,EAAE,kBAAkB,EAmDrD,CAAC;AAEF,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAE9F"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook payload fixtures — deterministic JSON payloads that each harness
|
|
3
|
+
* would send to a hook script on stdin. Useful in tests for driving
|
|
4
|
+
* parseHookPayload, HookDispatcher, and `amux hooks handle` end-to-end.
|
|
5
|
+
*/
|
|
6
|
+
export const HOOK_PAYLOAD_FIXTURES = [
|
|
7
|
+
{
|
|
8
|
+
agent: 'claude',
|
|
9
|
+
hookType: 'PreToolUse',
|
|
10
|
+
payload: {
|
|
11
|
+
session_id: 'sess-claude-1',
|
|
12
|
+
transcript_path: '/tmp/t.jsonl',
|
|
13
|
+
cwd: '/work/proj',
|
|
14
|
+
tool_name: 'Bash',
|
|
15
|
+
tool_input: { command: 'ls' },
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
agent: 'claude',
|
|
20
|
+
hookType: 'PostToolUse',
|
|
21
|
+
payload: {
|
|
22
|
+
session_id: 'sess-claude-1',
|
|
23
|
+
tool_name: 'Bash',
|
|
24
|
+
tool_input: { command: 'ls' },
|
|
25
|
+
tool_output: 'file.txt\n',
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
agent: 'claude',
|
|
30
|
+
hookType: 'Stop',
|
|
31
|
+
payload: { session_id: 'sess-claude-1' },
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
agent: 'codex',
|
|
35
|
+
hookType: 'OnToolCall',
|
|
36
|
+
payload: {
|
|
37
|
+
session_id: 'sess-codex-1',
|
|
38
|
+
tool_name: 'apply_patch',
|
|
39
|
+
tool_input: { path: 'a.txt' },
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
agent: 'codex',
|
|
44
|
+
hookType: 'OnStop',
|
|
45
|
+
payload: { session_id: 'sess-codex-1' },
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
agent: 'gemini',
|
|
49
|
+
hookType: 'pre_prompt',
|
|
50
|
+
payload: { session_id: 'g-1', prompt: 'hello' },
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
agent: 'copilot',
|
|
54
|
+
hookType: 'preTool',
|
|
55
|
+
payload: { session_id: 'co-1', tool_name: 'edit' },
|
|
56
|
+
},
|
|
57
|
+
];
|
|
58
|
+
export function getHookFixture(agent, hookType) {
|
|
59
|
+
return HOOK_PAYLOAD_FIXTURES.find((f) => f.agent === agent && f.hookType === hookType);
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/scenarios/hooks.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,MAAM,CAAC,MAAM,qBAAqB,GAAyB;IACzD;QACE,KAAK,EAAE,QAAQ;QACf,QAAQ,EAAE,YAAY;QACtB,OAAO,EAAE;YACP,UAAU,EAAE,eAAe;YAC3B,eAAe,EAAE,cAAc;YAC/B,GAAG,EAAE,YAAY;YACjB,SAAS,EAAE,MAAM;YACjB,UAAU,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;SAC9B;KACF;IACD;QACE,KAAK,EAAE,QAAQ;QACf,QAAQ,EAAE,aAAa;QACvB,OAAO,EAAE;YACP,UAAU,EAAE,eAAe;YAC3B,SAAS,EAAE,MAAM;YACjB,UAAU,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;YAC7B,WAAW,EAAE,YAAY;SAC1B;KACF;IACD;QACE,KAAK,EAAE,QAAQ;QACf,QAAQ,EAAE,MAAM;QAChB,OAAO,EAAE,EAAE,UAAU,EAAE,eAAe,EAAE;KACzC;IACD;QACE,KAAK,EAAE,OAAO;QACd,QAAQ,EAAE,YAAY;QACtB,OAAO,EAAE;YACP,UAAU,EAAE,cAAc;YAC1B,SAAS,EAAE,aAAa;YACxB,UAAU,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE;SAC9B;KACF;IACD;QACE,KAAK,EAAE,OAAO;QACd,QAAQ,EAAE,QAAQ;QAClB,OAAO,EAAE,EAAE,UAAU,EAAE,cAAc,EAAE;KACxC;IACD;QACE,KAAK,EAAE,QAAQ;QACf,QAAQ,EAAE,YAAY;QACtB,OAAO,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE;KAChD;IACD;QACE,KAAK,EAAE,SAAS;QAChB,QAAQ,EAAE,SAAS;QACnB,OAAO,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE;KACnD;CACF,CAAC;AAEF,MAAM,UAAU,cAAc,CAAC,KAAa,EAAE,QAAgB;IAC5D,OAAO,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,IAAI,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC;AACzF,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scenarios barrel.
|
|
3
|
+
*
|
|
4
|
+
* Re-exports the legacy top-level scenarios plus the per-agent,
|
|
5
|
+
* interactive, and error presets.
|
|
6
|
+
*/
|
|
7
|
+
export * from '../scenarios.js';
|
|
8
|
+
export * from './wire-format.js';
|
|
9
|
+
export * from './per-agent.js';
|
|
10
|
+
export * from './errors.js';
|
|
11
|
+
export * from './interactive.js';
|
|
12
|
+
export * from './hooks.js';
|
|
13
|
+
import type { HarnessScenario } from '../types.js';
|
|
14
|
+
/**
|
|
15
|
+
* Resolve a scenario by name. Supports:
|
|
16
|
+
* - agent scenario ids like `claude:basic-text`
|
|
17
|
+
* - error ids like `error:rate-limit`
|
|
18
|
+
* - interaction ids like `interactive:yolo`
|
|
19
|
+
*/
|
|
20
|
+
export declare function resolveScenario(name: string): HarnessScenario | undefined;
|
|
21
|
+
/** List all resolvable scenario names. */
|
|
22
|
+
export declare function listScenarioNames(): string[];
|
|
23
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scenarios/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAK3B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAWzE;AAED,0CAA0C;AAC1C,wBAAgB,iBAAiB,IAAI,MAAM,EAAE,CAM5C"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scenarios barrel.
|
|
3
|
+
*
|
|
4
|
+
* Re-exports the legacy top-level scenarios plus the per-agent,
|
|
5
|
+
* interactive, and error presets.
|
|
6
|
+
*/
|
|
7
|
+
export * from '../scenarios.js';
|
|
8
|
+
export * from './wire-format.js';
|
|
9
|
+
export * from './per-agent.js';
|
|
10
|
+
export * from './errors.js';
|
|
11
|
+
export * from './interactive.js';
|
|
12
|
+
export * from './hooks.js';
|
|
13
|
+
import { AGENT_SCENARIOS } from './per-agent.js';
|
|
14
|
+
import { ERROR_SCENARIOS } from './errors.js';
|
|
15
|
+
import { INTERACTION_SCENARIOS } from './interactive.js';
|
|
16
|
+
/**
|
|
17
|
+
* Resolve a scenario by name. Supports:
|
|
18
|
+
* - agent scenario ids like `claude:basic-text`
|
|
19
|
+
* - error ids like `error:rate-limit`
|
|
20
|
+
* - interaction ids like `interactive:yolo`
|
|
21
|
+
*/
|
|
22
|
+
export function resolveScenario(name) {
|
|
23
|
+
if (AGENT_SCENARIOS[name])
|
|
24
|
+
return AGENT_SCENARIOS[name];
|
|
25
|
+
if (name.startsWith('error:')) {
|
|
26
|
+
const meta = ERROR_SCENARIOS[name.slice('error:'.length)];
|
|
27
|
+
if (meta)
|
|
28
|
+
return meta.scenario;
|
|
29
|
+
}
|
|
30
|
+
if (name.startsWith('interactive:')) {
|
|
31
|
+
const m = name.slice('interactive:'.length);
|
|
32
|
+
if (INTERACTION_SCENARIOS[m])
|
|
33
|
+
return INTERACTION_SCENARIOS[m];
|
|
34
|
+
}
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
/** List all resolvable scenario names. */
|
|
38
|
+
export function listScenarioNames() {
|
|
39
|
+
const names = [];
|
|
40
|
+
names.push(...Object.keys(AGENT_SCENARIOS));
|
|
41
|
+
for (const k of Object.keys(ERROR_SCENARIOS))
|
|
42
|
+
names.push(`error:${k}`);
|
|
43
|
+
for (const k of Object.keys(INTERACTION_SCENARIOS))
|
|
44
|
+
names.push(`interactive:${k}`);
|
|
45
|
+
return names.sort();
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/scenarios/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAE3B,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAGzD;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,IAAI,eAAe,CAAC,IAAI,CAAC;QAAE,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;IACxD,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QAC1D,IAAI,IAAI;YAAE,OAAO,IAAI,CAAC,QAAQ,CAAC;IACjC,CAAC;IACD,IAAI,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QACpC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAA+B,CAAC;QAC1E,IAAI,qBAAqB,CAAC,CAAC,CAAC;YAAE,OAAO,qBAAqB,CAAC,CAAC,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,0CAA0C;AAC1C,MAAM,UAAU,iBAAiB;IAC/B,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;IAC5C,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IACvE,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;IACnF,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC;AACtB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interaction scenarios.
|
|
3
|
+
*
|
|
4
|
+
* The mock process emits a prompt-style line then waits for stdin. When
|
|
5
|
+
* running in the CLI binary, three approval modes are exposed:
|
|
6
|
+
*
|
|
7
|
+
* - yolo: auto-respond "y" with no user prompt
|
|
8
|
+
* - prompt: emit a question, wait for user to write y/n on stdin
|
|
9
|
+
* - deny: auto-respond "n"
|
|
10
|
+
*
|
|
11
|
+
* The scenario's `interactions` field configures which auto-response the
|
|
12
|
+
* MockProcess fires when it sees the prompt pattern.
|
|
13
|
+
*/
|
|
14
|
+
import type { HarnessScenario } from '../types.js';
|
|
15
|
+
export type InteractionMode = 'yolo' | 'prompt' | 'deny';
|
|
16
|
+
export declare function buildInteractiveScenario(mode: InteractionMode): HarnessScenario;
|
|
17
|
+
export declare const INTERACTION_SCENARIOS: Record<InteractionMode, HarnessScenario>;
|
|
18
|
+
//# sourceMappingURL=interactive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive.d.ts","sourceRoot":"","sources":["../../src/scenarios/interactive.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGnD,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEzD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,eAAe,GAAG,eAAe,CA2B/E;AAED,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,eAAe,EAAE,eAAe,CAI1E,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interaction scenarios.
|
|
3
|
+
*
|
|
4
|
+
* The mock process emits a prompt-style line then waits for stdin. When
|
|
5
|
+
* running in the CLI binary, three approval modes are exposed:
|
|
6
|
+
*
|
|
7
|
+
* - yolo: auto-respond "y" with no user prompt
|
|
8
|
+
* - prompt: emit a question, wait for user to write y/n on stdin
|
|
9
|
+
* - deny: auto-respond "n"
|
|
10
|
+
*
|
|
11
|
+
* The scenario's `interactions` field configures which auto-response the
|
|
12
|
+
* MockProcess fires when it sees the prompt pattern.
|
|
13
|
+
*/
|
|
14
|
+
import { claudeSystemInit, claudeAssistantText, claudeResult, stderrChunk, stdoutChunk } from './wire-format.js';
|
|
15
|
+
export function buildInteractiveScenario(mode) {
|
|
16
|
+
const prompt = 'Do you want to allow this tool call? (y/n)';
|
|
17
|
+
const response = mode === 'yolo' ? 'y\n' : mode === 'deny' ? 'n\n' : '';
|
|
18
|
+
const output = [
|
|
19
|
+
stdoutChunk(claudeSystemInit('sess_interact', ['Write']), 5),
|
|
20
|
+
stdoutChunk(claudeAssistantText('I need to write a file.'), 10),
|
|
21
|
+
stderrChunk(prompt + '\n', 10),
|
|
22
|
+
];
|
|
23
|
+
// Only auto-respond in yolo/deny modes. In prompt mode the driver
|
|
24
|
+
// (user / test) writes to stdin explicitly.
|
|
25
|
+
const base = {
|
|
26
|
+
harness: 'claude-code',
|
|
27
|
+
name: `interactive:${mode}`,
|
|
28
|
+
process: { exitCode: 0, shutdownDelayMs: 50 },
|
|
29
|
+
output: [
|
|
30
|
+
...output,
|
|
31
|
+
stdoutChunk(claudeResult('sess_interact', mode === 'deny' ? 'denied' : 'done'), 80),
|
|
32
|
+
],
|
|
33
|
+
};
|
|
34
|
+
if (response) {
|
|
35
|
+
base.interactions = [
|
|
36
|
+
{ triggerPattern: 'Do you want to allow', response, delayMs: 20 },
|
|
37
|
+
];
|
|
38
|
+
}
|
|
39
|
+
return base;
|
|
40
|
+
}
|
|
41
|
+
export const INTERACTION_SCENARIOS = {
|
|
42
|
+
yolo: buildInteractiveScenario('yolo'),
|
|
43
|
+
prompt: buildInteractiveScenario('prompt'),
|
|
44
|
+
deny: buildInteractiveScenario('deny'),
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=interactive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive.js","sourceRoot":"","sources":["../../src/scenarios/interactive.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAIjH,MAAM,UAAU,wBAAwB,CAAC,IAAqB;IAC5D,MAAM,MAAM,GAAG,4CAA4C,CAAC;IAC5D,MAAM,QAAQ,GAAG,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IAExE,MAAM,MAAM,GAAG;QACb,WAAW,CAAC,gBAAgB,CAAC,eAAe,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;QAC5D,WAAW,CAAC,mBAAmB,CAAC,yBAAyB,CAAC,EAAE,EAAE,CAAC;QAC/D,WAAW,CAAC,MAAM,GAAG,IAAI,EAAE,EAAE,CAAC;KAC/B,CAAC;IAEF,kEAAkE;IAClE,4CAA4C;IAC5C,MAAM,IAAI,GAAoB;QAC5B,OAAO,EAAE,aAAa;QACtB,IAAI,EAAE,eAAe,IAAI,EAAE;QAC3B,OAAO,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,eAAe,EAAE,EAAE,EAAE;QAC7C,MAAM,EAAE;YACN,GAAG,MAAM;YACT,WAAW,CAAC,YAAY,CAAC,eAAe,EAAE,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;SACpF;KACF,CAAC;IACF,IAAI,QAAQ,EAAE,CAAC;QACb,IAAI,CAAC,YAAY,GAAG;YAClB,EAAE,cAAc,EAAE,sBAAsB,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE;SAClE,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,MAAM,qBAAqB,GAA6C;IAC7E,IAAI,EAAE,wBAAwB,CAAC,MAAM,CAAC;IACtC,MAAM,EAAE,wBAAwB,CAAC,QAAQ,CAAC;IAC1C,IAAI,EAAE,wBAAwB,CAAC,MAAM,CAAC;CACvC,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-agent scenario presets.
|
|
3
|
+
*
|
|
4
|
+
* Each of the 10 built-in agents has at least two presets emitting realistic
|
|
5
|
+
* wire output (text deltas, tool calls, completion). Output strings come from
|
|
6
|
+
* the deterministic wire-format helpers so the real adapter parseEvent logic
|
|
7
|
+
* will parse them faithfully.
|
|
8
|
+
*/
|
|
9
|
+
import type { HarnessScenario } from '../types.js';
|
|
10
|
+
export declare const claudeBasicText: HarnessScenario;
|
|
11
|
+
export declare const claudeToolCall: HarnessScenario;
|
|
12
|
+
export declare const claudeMultiTurn: HarnessScenario;
|
|
13
|
+
export declare const codexBasicText: HarnessScenario;
|
|
14
|
+
export declare const codexCodeGeneration: HarnessScenario;
|
|
15
|
+
export declare const geminiBasicText: HarnessScenario;
|
|
16
|
+
export declare const geminiStreaming: HarnessScenario;
|
|
17
|
+
export declare const copilotScenarios: {
|
|
18
|
+
basic: HarnessScenario;
|
|
19
|
+
tool: HarnessScenario;
|
|
20
|
+
};
|
|
21
|
+
export declare const cursorScenarios: {
|
|
22
|
+
basic: HarnessScenario;
|
|
23
|
+
tool: HarnessScenario;
|
|
24
|
+
};
|
|
25
|
+
export declare const opencodeScenarios: {
|
|
26
|
+
basic: HarnessScenario;
|
|
27
|
+
tool: HarnessScenario;
|
|
28
|
+
};
|
|
29
|
+
export declare const piScenarios: {
|
|
30
|
+
basic: HarnessScenario;
|
|
31
|
+
tool: HarnessScenario;
|
|
32
|
+
};
|
|
33
|
+
export declare const ompScenarios: {
|
|
34
|
+
basic: HarnessScenario;
|
|
35
|
+
tool: HarnessScenario;
|
|
36
|
+
};
|
|
37
|
+
export declare const openclawScenarios: {
|
|
38
|
+
basic: HarnessScenario;
|
|
39
|
+
tool: HarnessScenario;
|
|
40
|
+
};
|
|
41
|
+
export declare const hermesScenarios: {
|
|
42
|
+
basic: HarnessScenario;
|
|
43
|
+
tool: HarnessScenario;
|
|
44
|
+
};
|
|
45
|
+
export declare const AGENT_SCENARIOS: Record<string, HarnessScenario>;
|
|
46
|
+
//# sourceMappingURL=per-agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"per-agent.d.ts","sourceRoot":"","sources":["../../src/scenarios/per-agent.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAqBnD,eAAO,MAAM,eAAe,EAAE,eAU7B,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,eAY5B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,eAW7B,CAAC;AAMF,eAAO,MAAM,cAAc,EAAE,eAQ5B,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,eAUjC,CAAC;AAMF,eAAO,MAAM,eAAe,EAAE,eAO7B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,eAU7B,CAAC;AA2BF,eAAO,MAAM,gBAAgB;WArBsD,eAAe;UAAQ,eAAe;CAqBxD,CAAC;AAClE,eAAO,MAAM,eAAe;WAtBuD,eAAe;UAAQ,eAAe;CAsB3D,CAAC;AAC/D,eAAO,MAAM,iBAAiB;WAvBqD,eAAe;UAAQ,eAAe;CAuBrD,CAAC;AACrE,eAAO,MAAM,WAAW;WAxB2D,eAAe;UAAQ,eAAe;CAwBvE,CAAC;AACnD,eAAO,MAAM,YAAY;WAzB0D,eAAe;UAAQ,eAAe;CAyBpE,CAAC;AACtD,eAAO,MAAM,iBAAiB;WA1BqD,eAAe;UAAQ,eAAe;CA0BrD,CAAC;AACrE,eAAO,MAAM,eAAe;WA3BuD,eAAe;UAAQ,eAAe;CA2B3D,CAAC;AAM/D,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAsB3D,CAAC"}
|