@agentworkforce/cli 0.11.0 → 0.13.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/CHANGELOG.md +12 -0
- package/dist/cli.d.ts +26 -4
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +168 -15
- package/dist/cli.js.map +1 -1
- package/dist/cli.test.js +92 -15
- package/dist/cli.test.js.map +1 -1
- package/dist/persona-picker.d.ts +66 -0
- package/dist/persona-picker.d.ts.map +1 -0
- package/dist/persona-picker.js +152 -0
- package/dist/persona-picker.js.map +1 -0
- package/dist/persona-picker.test.d.ts +2 -0
- package/dist/persona-picker.test.d.ts.map +1 -0
- package/dist/persona-picker.test.js +184 -0
- package/dist/persona-picker.test.js.map +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compact projection of a persona used for picker prompts. The model only
|
|
3
|
+
* needs enough to reason about intent fit — full systemPrompts would inflate
|
|
4
|
+
* the prompt without improving quality.
|
|
5
|
+
*/
|
|
6
|
+
export interface PickCandidate {
|
|
7
|
+
id: string;
|
|
8
|
+
intent: string;
|
|
9
|
+
tags: readonly string[];
|
|
10
|
+
description: string;
|
|
11
|
+
}
|
|
12
|
+
export type PickConfidence = 'high' | 'medium' | 'low';
|
|
13
|
+
export type PickResult = {
|
|
14
|
+
kind: 'match';
|
|
15
|
+
personaId: string;
|
|
16
|
+
confidence: 'high' | 'medium';
|
|
17
|
+
reason: string;
|
|
18
|
+
} | {
|
|
19
|
+
kind: 'no-match';
|
|
20
|
+
reason: string;
|
|
21
|
+
} | {
|
|
22
|
+
kind: 'picker-unavailable';
|
|
23
|
+
message: string;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Test seam describing one round-trip to the picker subprocess. Returning a
|
|
27
|
+
* structured shape keeps tests free of real `spawnSync` calls while preserving
|
|
28
|
+
* the stdout/stderr/status surface the parser exercises.
|
|
29
|
+
*/
|
|
30
|
+
export interface PickerSubprocessRequest {
|
|
31
|
+
bin: string;
|
|
32
|
+
args: readonly string[];
|
|
33
|
+
systemPrompt: string;
|
|
34
|
+
userPrompt: string;
|
|
35
|
+
timeoutMs: number;
|
|
36
|
+
}
|
|
37
|
+
export interface PickerSubprocessResult {
|
|
38
|
+
status: 'ok' | 'enoent' | 'error';
|
|
39
|
+
stdout: string;
|
|
40
|
+
stderr: string;
|
|
41
|
+
errorMessage?: string;
|
|
42
|
+
}
|
|
43
|
+
export type PickerRunner = (req: PickerSubprocessRequest) => PickerSubprocessResult;
|
|
44
|
+
export interface PickPersonaOptions {
|
|
45
|
+
claudeBin?: string;
|
|
46
|
+
model?: string;
|
|
47
|
+
timeoutMs?: number;
|
|
48
|
+
runner?: PickerRunner;
|
|
49
|
+
}
|
|
50
|
+
export declare function buildUserPrompt(task: string, candidates: readonly PickCandidate[]): string;
|
|
51
|
+
interface PickerJsonResponse {
|
|
52
|
+
persona: string | null;
|
|
53
|
+
confidence: PickConfidence;
|
|
54
|
+
reason: string;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Parse the model's text output. Accepts either a bare JSON object or the
|
|
58
|
+
* Claude CLI `--output-format json` envelope `{type, result, ...}` whose
|
|
59
|
+
* `result` field carries the model text. Returns undefined when the output
|
|
60
|
+
* cannot be coerced to the expected shape — callers translate that into a
|
|
61
|
+
* `no-match` result.
|
|
62
|
+
*/
|
|
63
|
+
export declare function parsePickerOutput(stdout: string): PickerJsonResponse | undefined;
|
|
64
|
+
export declare function pickPersona(task: string, candidates: readonly PickCandidate[], opts?: PickPersonaOptions): PickResult;
|
|
65
|
+
export {};
|
|
66
|
+
//# sourceMappingURL=persona-picker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persona-picker.d.ts","sourceRoot":"","sources":["../src/persona-picker.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAEvD,MAAM,MAAM,UAAU,GAClB;IACE,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;CAChB,GACD;IACE,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB,GACD;IACE,IAAI,EAAE,oBAAoB,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEN;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,IAAI,GAAG,QAAQ,GAAG,OAAO,CAAC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,uBAAuB,KAAK,sBAAsB,CAAC;AAEpF,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAoBD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,aAAa,EAAE,GAAG,MAAM,CAQ1F;AAED,UAAU,kBAAkB;IAC1B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,cAAc,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;CAChB;AAWD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CA0BhF;AA4BD,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,SAAS,aAAa,EAAE,EACpC,IAAI,GAAE,kBAAuB,GAC5B,UAAU,CA+DZ"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
const DEFAULT_BIN = 'claude';
|
|
3
|
+
// Use the dated model id rather than the `claude-haiku-4-5` alias so the
|
|
4
|
+
// subprocess survives any future change in the Claude CLI's alias resolver.
|
|
5
|
+
// The alias works today but the dated id is strictly more robust.
|
|
6
|
+
const DEFAULT_MODEL = 'claude-haiku-4-5-20251001';
|
|
7
|
+
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
8
|
+
const SYSTEM_PROMPT = `You pick the single best persona for a user task from a fixed catalog.
|
|
9
|
+
|
|
10
|
+
Rules:
|
|
11
|
+
- Read the task and the candidate list.
|
|
12
|
+
- Choose the persona whose intent and description most directly match the task.
|
|
13
|
+
- If no persona is a clear fit, set "persona" to null with confidence "low".
|
|
14
|
+
- Output ONE JSON object on a single line. No prose, no code fences, no commentary.
|
|
15
|
+
|
|
16
|
+
Output schema:
|
|
17
|
+
{"persona": "<id from the candidate list, or null>", "confidence": "high" | "medium" | "low", "reason": "<one short sentence>"}`;
|
|
18
|
+
export function buildUserPrompt(task, candidates) {
|
|
19
|
+
const compact = candidates.map((c) => ({
|
|
20
|
+
id: c.id,
|
|
21
|
+
intent: c.intent,
|
|
22
|
+
tags: [...c.tags],
|
|
23
|
+
description: c.description
|
|
24
|
+
}));
|
|
25
|
+
return `Task:\n${task.trim()}\n\nCandidates (JSON):\n${JSON.stringify(compact)}`;
|
|
26
|
+
}
|
|
27
|
+
function isPickerJsonResponse(value) {
|
|
28
|
+
if (typeof value !== 'object' || value === null)
|
|
29
|
+
return false;
|
|
30
|
+
const v = value;
|
|
31
|
+
if (v.persona !== null && typeof v.persona !== 'string')
|
|
32
|
+
return false;
|
|
33
|
+
if (v.confidence !== 'high' && v.confidence !== 'medium' && v.confidence !== 'low')
|
|
34
|
+
return false;
|
|
35
|
+
if (typeof v.reason !== 'string')
|
|
36
|
+
return false;
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Parse the model's text output. Accepts either a bare JSON object or the
|
|
41
|
+
* Claude CLI `--output-format json` envelope `{type, result, ...}` whose
|
|
42
|
+
* `result` field carries the model text. Returns undefined when the output
|
|
43
|
+
* cannot be coerced to the expected shape — callers translate that into a
|
|
44
|
+
* `no-match` result.
|
|
45
|
+
*/
|
|
46
|
+
export function parsePickerOutput(stdout) {
|
|
47
|
+
const trimmed = stdout.trim();
|
|
48
|
+
if (!trimmed)
|
|
49
|
+
return undefined;
|
|
50
|
+
let candidate;
|
|
51
|
+
try {
|
|
52
|
+
candidate = JSON.parse(trimmed);
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
if (typeof candidate === 'object' &&
|
|
58
|
+
candidate !== null &&
|
|
59
|
+
'result' in candidate &&
|
|
60
|
+
typeof candidate.result === 'string') {
|
|
61
|
+
const inner = candidate.result.trim();
|
|
62
|
+
try {
|
|
63
|
+
candidate = JSON.parse(inner);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return isPickerJsonResponse(candidate) ? candidate : undefined;
|
|
70
|
+
}
|
|
71
|
+
function defaultRunner(req) {
|
|
72
|
+
const opts = {
|
|
73
|
+
encoding: 'utf8',
|
|
74
|
+
timeout: req.timeoutMs
|
|
75
|
+
};
|
|
76
|
+
const child = spawnSync(req.bin, [...req.args], opts);
|
|
77
|
+
if (child.error) {
|
|
78
|
+
const err = child.error;
|
|
79
|
+
if (err.code === 'ENOENT') {
|
|
80
|
+
return { status: 'enoent', stdout: '', stderr: '', errorMessage: err.message };
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
status: 'error',
|
|
84
|
+
stdout: typeof child.stdout === 'string' ? child.stdout : '',
|
|
85
|
+
stderr: typeof child.stderr === 'string' ? child.stderr : '',
|
|
86
|
+
errorMessage: err.message
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
const stdout = typeof child.stdout === 'string' ? child.stdout : '';
|
|
90
|
+
const stderr = typeof child.stderr === 'string' ? child.stderr : '';
|
|
91
|
+
if (typeof child.status === 'number' && child.status !== 0) {
|
|
92
|
+
return { status: 'error', stdout, stderr, errorMessage: `exit ${child.status}` };
|
|
93
|
+
}
|
|
94
|
+
return { status: 'ok', stdout, stderr };
|
|
95
|
+
}
|
|
96
|
+
export function pickPersona(task, candidates, opts = {}) {
|
|
97
|
+
if (!task.trim()) {
|
|
98
|
+
return { kind: 'no-match', reason: 'empty task description' };
|
|
99
|
+
}
|
|
100
|
+
if (candidates.length === 0) {
|
|
101
|
+
return { kind: 'no-match', reason: 'no candidates available' };
|
|
102
|
+
}
|
|
103
|
+
const bin = opts.claudeBin ?? DEFAULT_BIN;
|
|
104
|
+
const model = opts.model ?? DEFAULT_MODEL;
|
|
105
|
+
const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
106
|
+
const runner = opts.runner ?? defaultRunner;
|
|
107
|
+
const userPrompt = buildUserPrompt(task, candidates);
|
|
108
|
+
const args = [
|
|
109
|
+
'-p',
|
|
110
|
+
'--model',
|
|
111
|
+
model,
|
|
112
|
+
'--output-format',
|
|
113
|
+
'json',
|
|
114
|
+
'--system-prompt',
|
|
115
|
+
SYSTEM_PROMPT,
|
|
116
|
+
userPrompt
|
|
117
|
+
];
|
|
118
|
+
const result = runner({ bin, args, systemPrompt: SYSTEM_PROMPT, userPrompt, timeoutMs });
|
|
119
|
+
if (result.status === 'enoent') {
|
|
120
|
+
return {
|
|
121
|
+
kind: 'picker-unavailable',
|
|
122
|
+
message: `\`${bin}\` not found on PATH. Install Claude Code (https://docs.claude.com/en/docs/claude-code) or run \`agentworkforce harness check\` to verify.`
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
if (result.status === 'error') {
|
|
126
|
+
return {
|
|
127
|
+
kind: 'picker-unavailable',
|
|
128
|
+
message: `picker subprocess failed: ${result.errorMessage ?? 'unknown error'}${result.stderr ? `\n${result.stderr.trim()}` : ''}`
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
const parsed = parsePickerOutput(result.stdout);
|
|
132
|
+
if (!parsed) {
|
|
133
|
+
return { kind: 'no-match', reason: 'picker returned no parseable response' };
|
|
134
|
+
}
|
|
135
|
+
if (parsed.persona === null || parsed.confidence === 'low') {
|
|
136
|
+
return { kind: 'no-match', reason: parsed.reason || 'low confidence' };
|
|
137
|
+
}
|
|
138
|
+
const known = new Set(candidates.map((c) => c.id));
|
|
139
|
+
if (!known.has(parsed.persona)) {
|
|
140
|
+
return {
|
|
141
|
+
kind: 'no-match',
|
|
142
|
+
reason: `picker returned unknown persona id "${parsed.persona}"`
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
kind: 'match',
|
|
147
|
+
personaId: parsed.persona,
|
|
148
|
+
confidence: parsed.confidence,
|
|
149
|
+
reason: parsed.reason
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=persona-picker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persona-picker.js","sourceRoot":"","sources":["../src/persona-picker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persona-picker.test.d.ts","sourceRoot":"","sources":["../src/persona-picker.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { buildUserPrompt, parsePickerOutput, pickPersona } from './persona-picker.js';
|
|
4
|
+
const SAMPLE_CANDIDATES = [
|
|
5
|
+
{
|
|
6
|
+
id: 'code-reviewer',
|
|
7
|
+
intent: 'review',
|
|
8
|
+
tags: ['review'],
|
|
9
|
+
description: 'Reviews PRs.'
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
id: 'debugger',
|
|
13
|
+
intent: 'debugging',
|
|
14
|
+
tags: ['debugging'],
|
|
15
|
+
description: 'Roots out bugs.'
|
|
16
|
+
}
|
|
17
|
+
];
|
|
18
|
+
function fakeRunner(result) {
|
|
19
|
+
const calls = [];
|
|
20
|
+
return {
|
|
21
|
+
calls,
|
|
22
|
+
runner(req) {
|
|
23
|
+
calls.push(req);
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
test('buildUserPrompt: includes the task and a JSON candidate list', () => {
|
|
29
|
+
const prompt = buildUserPrompt('fix the login bug', SAMPLE_CANDIDATES);
|
|
30
|
+
assert.match(prompt, /Task:\nfix the login bug/);
|
|
31
|
+
assert.match(prompt, /"id":"code-reviewer"/);
|
|
32
|
+
assert.match(prompt, /"id":"debugger"/);
|
|
33
|
+
});
|
|
34
|
+
test('parsePickerOutput: parses a bare JSON response object', () => {
|
|
35
|
+
const out = '{"persona":"code-reviewer","confidence":"high","reason":"PR review"}';
|
|
36
|
+
assert.deepEqual(parsePickerOutput(out), {
|
|
37
|
+
persona: 'code-reviewer',
|
|
38
|
+
confidence: 'high',
|
|
39
|
+
reason: 'PR review'
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
test('parsePickerOutput: unwraps the Claude CLI {result: "<json>"} envelope', () => {
|
|
43
|
+
const inner = JSON.stringify({
|
|
44
|
+
persona: 'debugger',
|
|
45
|
+
confidence: 'medium',
|
|
46
|
+
reason: 'looks like a bug hunt'
|
|
47
|
+
});
|
|
48
|
+
const envelope = JSON.stringify({
|
|
49
|
+
type: 'result',
|
|
50
|
+
subtype: 'success',
|
|
51
|
+
is_error: false,
|
|
52
|
+
result: inner
|
|
53
|
+
});
|
|
54
|
+
assert.deepEqual(parsePickerOutput(envelope), {
|
|
55
|
+
persona: 'debugger',
|
|
56
|
+
confidence: 'medium',
|
|
57
|
+
reason: 'looks like a bug hunt'
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
test('parsePickerOutput: returns undefined on non-JSON', () => {
|
|
61
|
+
assert.equal(parsePickerOutput('not json'), undefined);
|
|
62
|
+
assert.equal(parsePickerOutput(''), undefined);
|
|
63
|
+
assert.equal(parsePickerOutput(' \n '), undefined);
|
|
64
|
+
});
|
|
65
|
+
test('parsePickerOutput: returns undefined on shape mismatch', () => {
|
|
66
|
+
assert.equal(parsePickerOutput('{"persona":42,"confidence":"high","reason":"x"}'), undefined);
|
|
67
|
+
assert.equal(parsePickerOutput('{"persona":"x","confidence":"sky-high","reason":"x"}'), undefined);
|
|
68
|
+
assert.equal(parsePickerOutput('{"persona":"x","confidence":"high"}'), undefined);
|
|
69
|
+
});
|
|
70
|
+
test('pickPersona: well-formed match propagates id, confidence, reason', () => {
|
|
71
|
+
const { runner, calls } = fakeRunner({
|
|
72
|
+
status: 'ok',
|
|
73
|
+
stdout: '{"persona":"code-reviewer","confidence":"high","reason":"PR review fits"}',
|
|
74
|
+
stderr: ''
|
|
75
|
+
});
|
|
76
|
+
const result = pickPersona('review my PR', SAMPLE_CANDIDATES, { runner });
|
|
77
|
+
assert.equal(result.kind, 'match');
|
|
78
|
+
if (result.kind === 'match') {
|
|
79
|
+
assert.equal(result.personaId, 'code-reviewer');
|
|
80
|
+
assert.equal(result.confidence, 'high');
|
|
81
|
+
assert.equal(result.reason, 'PR review fits');
|
|
82
|
+
}
|
|
83
|
+
assert.equal(calls.length, 1);
|
|
84
|
+
assert.equal(calls[0].bin, 'claude');
|
|
85
|
+
assert.ok(calls[0].args.includes('-p'));
|
|
86
|
+
assert.ok(calls[0].args.includes('--output-format'));
|
|
87
|
+
});
|
|
88
|
+
test('pickPersona: persona=null collapses to no-match', () => {
|
|
89
|
+
const { runner } = fakeRunner({
|
|
90
|
+
status: 'ok',
|
|
91
|
+
stdout: '{"persona":null,"confidence":"low","reason":"none fit"}',
|
|
92
|
+
stderr: ''
|
|
93
|
+
});
|
|
94
|
+
const result = pickPersona('xyzzy', SAMPLE_CANDIDATES, { runner });
|
|
95
|
+
assert.equal(result.kind, 'no-match');
|
|
96
|
+
});
|
|
97
|
+
test('pickPersona: low confidence collapses to no-match even with a persona id', () => {
|
|
98
|
+
const { runner } = fakeRunner({
|
|
99
|
+
status: 'ok',
|
|
100
|
+
stdout: '{"persona":"code-reviewer","confidence":"low","reason":"weak match"}',
|
|
101
|
+
stderr: ''
|
|
102
|
+
});
|
|
103
|
+
const result = pickPersona('something', SAMPLE_CANDIDATES, { runner });
|
|
104
|
+
assert.equal(result.kind, 'no-match');
|
|
105
|
+
});
|
|
106
|
+
test('pickPersona: unknown persona id from model is rejected as no-match', () => {
|
|
107
|
+
const { runner } = fakeRunner({
|
|
108
|
+
status: 'ok',
|
|
109
|
+
stdout: '{"persona":"made-up-persona","confidence":"high","reason":"hallucinated"}',
|
|
110
|
+
stderr: ''
|
|
111
|
+
});
|
|
112
|
+
const result = pickPersona('do work', SAMPLE_CANDIDATES, { runner });
|
|
113
|
+
assert.equal(result.kind, 'no-match');
|
|
114
|
+
if (result.kind === 'no-match') {
|
|
115
|
+
assert.match(result.reason, /unknown persona id/);
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
test('pickPersona: ENOENT from subprocess maps to picker-unavailable', () => {
|
|
119
|
+
const { runner } = fakeRunner({
|
|
120
|
+
status: 'enoent',
|
|
121
|
+
stdout: '',
|
|
122
|
+
stderr: '',
|
|
123
|
+
errorMessage: 'spawn claude ENOENT'
|
|
124
|
+
});
|
|
125
|
+
const result = pickPersona('do work', SAMPLE_CANDIDATES, { runner });
|
|
126
|
+
assert.equal(result.kind, 'picker-unavailable');
|
|
127
|
+
if (result.kind === 'picker-unavailable') {
|
|
128
|
+
assert.match(result.message, /not found on PATH/);
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
test('pickPersona: non-zero exit maps to picker-unavailable with stderr', () => {
|
|
132
|
+
const { runner } = fakeRunner({
|
|
133
|
+
status: 'error',
|
|
134
|
+
stdout: '',
|
|
135
|
+
stderr: 'rate limited',
|
|
136
|
+
errorMessage: 'exit 1'
|
|
137
|
+
});
|
|
138
|
+
const result = pickPersona('do work', SAMPLE_CANDIDATES, { runner });
|
|
139
|
+
assert.equal(result.kind, 'picker-unavailable');
|
|
140
|
+
if (result.kind === 'picker-unavailable') {
|
|
141
|
+
assert.match(result.message, /rate limited/);
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
test('pickPersona: unparseable stdout collapses to no-match', () => {
|
|
145
|
+
const { runner } = fakeRunner({
|
|
146
|
+
status: 'ok',
|
|
147
|
+
stdout: 'I refuse to answer in JSON.',
|
|
148
|
+
stderr: ''
|
|
149
|
+
});
|
|
150
|
+
const result = pickPersona('do work', SAMPLE_CANDIDATES, { runner });
|
|
151
|
+
assert.equal(result.kind, 'no-match');
|
|
152
|
+
if (result.kind === 'no-match') {
|
|
153
|
+
assert.match(result.reason, /no parseable response/);
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
test('pickPersona: empty task short-circuits to no-match without invoking runner', () => {
|
|
157
|
+
const { runner, calls } = fakeRunner({ status: 'ok', stdout: '', stderr: '' });
|
|
158
|
+
const result = pickPersona(' ', SAMPLE_CANDIDATES, { runner });
|
|
159
|
+
assert.equal(result.kind, 'no-match');
|
|
160
|
+
assert.equal(calls.length, 0);
|
|
161
|
+
});
|
|
162
|
+
test('pickPersona: empty candidates short-circuits to no-match', () => {
|
|
163
|
+
const { runner, calls } = fakeRunner({ status: 'ok', stdout: '', stderr: '' });
|
|
164
|
+
const result = pickPersona('do work', [], { runner });
|
|
165
|
+
assert.equal(result.kind, 'no-match');
|
|
166
|
+
assert.equal(calls.length, 0);
|
|
167
|
+
});
|
|
168
|
+
test('pickPersona: respects custom claudeBin and model in args', () => {
|
|
169
|
+
const { runner, calls } = fakeRunner({
|
|
170
|
+
status: 'ok',
|
|
171
|
+
stdout: '{"persona":"debugger","confidence":"medium","reason":"x"}',
|
|
172
|
+
stderr: ''
|
|
173
|
+
});
|
|
174
|
+
pickPersona('hunt a bug', SAMPLE_CANDIDATES, {
|
|
175
|
+
runner,
|
|
176
|
+
claudeBin: '/custom/claude',
|
|
177
|
+
model: 'claude-opus-4-7'
|
|
178
|
+
});
|
|
179
|
+
assert.equal(calls[0].bin, '/custom/claude');
|
|
180
|
+
const modelIdx = calls[0].args.indexOf('--model');
|
|
181
|
+
assert.notEqual(modelIdx, -1);
|
|
182
|
+
assert.equal(calls[0].args[modelIdx + 1], 'claude-opus-4-7');
|
|
183
|
+
});
|
|
184
|
+
//# sourceMappingURL=persona-picker.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persona-picker.test.js","sourceRoot":"","sources":["../src/persona-picker.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentworkforce/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
"@relayburn/sdk": "^2.3.0",
|
|
14
14
|
"@relayfile/local-mount": "^0.6.1",
|
|
15
15
|
"ora": "^9.4.0",
|
|
16
|
-
"@agentworkforce/harness-kit": "0.
|
|
17
|
-
"@agentworkforce/workload-router": "0.
|
|
16
|
+
"@agentworkforce/harness-kit": "0.13.0",
|
|
17
|
+
"@agentworkforce/workload-router": "0.13.0"
|
|
18
18
|
},
|
|
19
19
|
"repository": {
|
|
20
20
|
"type": "git",
|