@akagilnc/pi-workflow-roles 0.1.1751
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 +202 -0
- package/README.md +104 -0
- package/README.zh-CN.md +133 -0
- package/THIRD_PARTY_NOTICES.md +60 -0
- package/dist/activation-ledger-git.js +68 -0
- package/dist/activation-ledger-session.js +120 -0
- package/dist/activation-ledger-topology.js +239 -0
- package/dist/activation-reconciliation.js +61 -0
- package/dist/audit-escalation.js +108 -0
- package/dist/auditor-dossier-tool.js +35 -0
- package/dist/canonical-json.js +78 -0
- package/dist/compliance-transport.js +77 -0
- package/dist/doctor-contracts.js +172 -0
- package/dist/dossier-resolution.js +103 -0
- package/dist/evidence-child-executor.js +661 -0
- package/dist/exact-utf8.js +12 -0
- package/dist/git-object-id.js +7 -0
- package/dist/in-process-session.js +50 -0
- package/dist/merger-contracts.js +76 -0
- package/dist/navigator-attendance.js +995 -0
- package/dist/navigator-invocation-identity.js +220 -0
- package/dist/open-tool-schema.js +39 -0
- package/dist/package-contracts/collector-output.js +50 -0
- package/dist/package-contracts/fixer-output.js +72 -0
- package/dist/package-contracts/fixer-packet.js +77 -0
- package/dist/package-contracts/judge-output.js +17 -0
- package/dist/package-contracts/reviewer-output.js +82 -0
- package/dist/package-contracts/terminating-tools.js +173 -0
- package/dist/package-contracts/worker-output.js +13 -0
- package/dist/package-owned-tool-idle.js +104 -0
- package/dist/packaged-role-registry.js +34 -0
- package/dist/public-cli/main.js +23867 -0
- package/dist/public-command-renderer.js +20 -0
- package/dist/reviewer-agent.js +93 -0
- package/dist/reviewer-child-executor.js +23 -0
- package/dist/reviewer-construction.js +95 -0
- package/dist/reviewer-dispatch.js +77 -0
- package/dist/reviewer-execution-ledger.js +160 -0
- package/dist/reviewer-failure-diagnostic.js +17 -0
- package/dist/reviewer-git-snapshot.js +38 -0
- package/dist/reviewer-pinned-git.js +146 -0
- package/dist/reviewer-preflight-error.js +15 -0
- package/dist/reviewer-prompt-identity.js +10 -0
- package/dist/reviewer-scope-prompt.js +21 -0
- package/dist/reviewer-workspace.js +151 -0
- package/dist/sha256.js +5 -0
- package/dist/sitian-record-entry.js +33 -0
- package/dist/stderr-jsonl.js +26 -0
- package/dist/stream-idle-guard.js +75 -0
- package/dist/tool-execution-observation.js +141 -0
- package/dist/uuidv7.js +21 -0
- package/dist/work-subject-identity.js +53 -0
- package/extensions/role-runtime.ts +303 -0
- package/package.json +69 -0
- package/packets/fixer-prerequisites.json +6 -0
- package/packets/fixer-repair.md +5 -0
- package/packets/judge-apply.md +77 -0
- package/packets/judge-authority.md +64 -0
- package/packets/judge-plan.md +55 -0
- package/packets/judge-review.md +49 -0
- package/packets/judge-submission.md +34 -0
- package/resources/methods/code-review/SKILL.md +92 -0
- package/resources/methods/code-review/agents/openai.yaml +3 -0
- package/resources/methods/code-review/provenance.json +26 -0
- package/resources/methods/diagnosing-bugs/SKILL.md +134 -0
- package/resources/methods/diagnosing-bugs/agents/openai.yaml +3 -0
- package/resources/methods/diagnosing-bugs/provenance.json +31 -0
- package/resources/methods/diagnosing-bugs/scripts/hitl-loop.template.sh +41 -0
- package/resources/methods/resolving-merge-conflicts/SKILL.md +14 -0
- package/resources/methods/resolving-merge-conflicts/agents/openai.yaml +3 -0
- package/resources/methods/resolving-merge-conflicts/provenance.json +26 -0
- package/resources/methods/tdd/SKILL.md +38 -0
- package/resources/methods/tdd/agents/openai.yaml +3 -0
- package/resources/methods/tdd/mocking.md +59 -0
- package/resources/methods/tdd/provenance.json +36 -0
- package/resources/methods/tdd/tests.md +77 -0
- package/resources/navigator-route-playbook.md +32 -0
- package/schemas/tool-execution-observation.schema.json +107 -0
- package/scripts/build-package.mjs +65 -0
- package/scripts/generate-tool-execution-observation-schema.ts +7 -0
- package/souls/coder.md +10 -0
- package/souls/collector.md +11 -0
- package/souls/doctor-auditor.md +23 -0
- package/souls/doctor.md +8 -0
- package/souls/fixer-auditor.md +33 -0
- package/souls/fixer.md +13 -0
- package/souls/judge-auditor.md +33 -0
- package/souls/judge.md +74 -0
- package/souls/merger.md +5 -0
- package/souls/navigator.md +5 -0
- package/souls/reviewer-auditor.md +25 -0
- package/souls/reviewer.md +11 -0
- package/src/activation-ledger-git.ts +96 -0
- package/src/activation-ledger-session.ts +188 -0
- package/src/activation-ledger-topology.ts +301 -0
- package/src/activation-ledger.ts +240 -0
- package/src/activation-reconciliation.ts +163 -0
- package/src/activation-trace.ts +38 -0
- package/src/audit-escalation.ts +177 -0
- package/src/auditor-dossier-tool.ts +48 -0
- package/src/auditor-soul.ts +28 -0
- package/src/canonical-json.ts +74 -0
- package/src/canonical-skill-binding.ts +107 -0
- package/src/collector-config.ts +89 -0
- package/src/collector-evidence.ts +461 -0
- package/src/collector-github.ts +656 -0
- package/src/collector-identity.ts +161 -0
- package/src/collector-ledger.ts +827 -0
- package/src/collector-receipt.ts +87 -0
- package/src/collector-role.ts +592 -0
- package/src/collector-tool-schemas.ts +19 -0
- package/src/compliance-transport.ts +130 -0
- package/src/doctor-auditor.ts +53 -0
- package/src/doctor-contracts.ts +166 -0
- package/src/doctor-evidence.ts +47 -0
- package/src/doctor-role.ts +18 -0
- package/src/dossier-resolution.ts +137 -0
- package/src/evidence-child-executor.ts +775 -0
- package/src/exact-utf8.ts +9 -0
- package/src/factory-board.ts +1822 -0
- package/src/git-object-id.ts +11 -0
- package/src/human-format.ts +65 -0
- package/src/in-process-session.ts +78 -0
- package/src/judge-auditor.ts +55 -0
- package/src/judge-recording-anti-forge.ts +53 -0
- package/src/judge-role.ts +160 -0
- package/src/merger-contracts.ts +71 -0
- package/src/merger-git-state.ts +76 -0
- package/src/merger-role.ts +60 -0
- package/src/navigator-attendance.ts +1254 -0
- package/src/navigator-invocation-identity.ts +446 -0
- package/src/open-tool-schema.ts +46 -0
- package/src/package-contracts/collector-output.ts +109 -0
- package/src/package-contracts/fixer-output.ts +81 -0
- package/src/package-contracts/fixer-packet.ts +93 -0
- package/src/package-contracts/judge-output.ts +39 -0
- package/src/package-contracts/reviewer-output.ts +115 -0
- package/src/package-contracts/terminating-tools.ts +259 -0
- package/src/package-contracts/worker-output.ts +36 -0
- package/src/package-owned-tool-idle.ts +134 -0
- package/src/package-resources/method-skill-binding.ts +87 -0
- package/src/package-resources/method-skill.ts +358 -0
- package/src/packaged-role-registry.ts +36 -0
- package/src/public-cli/cli-errors.ts +11 -0
- package/src/public-cli/cli-io.ts +4 -0
- package/src/public-cli/cli.ts +912 -0
- package/src/public-cli/coder-run.ts +575 -0
- package/src/public-cli/collector-run.ts +375 -0
- package/src/public-cli/command-renderer.ts +8 -0
- package/src/public-cli/config.ts +346 -0
- package/src/public-cli/doctor-run.ts +355 -0
- package/src/public-cli/explicit-internal.ts +274 -0
- package/src/public-cli/fixer-run.ts +587 -0
- package/src/public-cli/host-pi-runtime.ts +112 -0
- package/src/public-cli/invocation.ts +1958 -0
- package/src/public-cli/judge-run.ts +507 -0
- package/src/public-cli/main.ts +15 -0
- package/src/public-cli/merger-run.ts +681 -0
- package/src/public-cli/public-run-credentials.ts +71 -0
- package/src/public-cli/registry.ts +153 -0
- package/src/public-cli/reviewer-run.ts +561 -0
- package/src/public-cli/run-lifecycle.ts +884 -0
- package/src/public-cli/settlement.ts +3765 -0
- package/src/public-cli/terminal.ts +325 -0
- package/src/public-command-renderer.ts +43 -0
- package/src/reviewer-agent.ts +94 -0
- package/src/reviewer-auditor.ts +53 -0
- package/src/reviewer-child-executor.ts +31 -0
- package/src/reviewer-construction.ts +137 -0
- package/src/reviewer-dispatch.ts +94 -0
- package/src/reviewer-execution-ledger.ts +206 -0
- package/src/reviewer-failure-diagnostic.ts +18 -0
- package/src/reviewer-git-snapshot.ts +53 -0
- package/src/reviewer-pinned-git.ts +144 -0
- package/src/reviewer-preflight-error.ts +14 -0
- package/src/reviewer-prompt-identity.ts +17 -0
- package/src/reviewer-role.ts +193 -0
- package/src/reviewer-scope-prompt.ts +24 -0
- package/src/reviewer-settlement.ts +63 -0
- package/src/reviewer-workspace.ts +111 -0
- package/src/role-runtime.ts +884 -0
- package/src/sha256.ts +6 -0
- package/src/sitian-record-entry.ts +57 -0
- package/src/stderr-jsonl.ts +28 -0
- package/src/stream-idle-guard.ts +98 -0
- package/src/ticket-snapshot.ts +662 -0
- package/src/ticket-trajectory.ts +1000 -0
- package/src/tool-execution-observation.ts +168 -0
- package/src/uuidv7.ts +1 -0
- package/src/work-subject-identity.ts +94 -0
- package/src/worker-role.ts +434 -0
- package/src/worker-submission-gates.ts +225 -0
|
@@ -0,0 +1,912 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public ak-role CLI dispatcher (roles / config / layered help / Judge run).
|
|
3
|
+
*/
|
|
4
|
+
import { homedir } from "node:os";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
effectiveSeatConfigurations,
|
|
9
|
+
formatModelSpec,
|
|
10
|
+
loadCredentialProviders,
|
|
11
|
+
loadPublicCliConfig,
|
|
12
|
+
parseModelSpec,
|
|
13
|
+
resolveEffectiveSeat,
|
|
14
|
+
savePublicCliConfig,
|
|
15
|
+
setPersistentSeatConfig,
|
|
16
|
+
type CredentialProviders,
|
|
17
|
+
type EffectiveSeat,
|
|
18
|
+
type InvocationModelOverride,
|
|
19
|
+
type PublicCliConfig,
|
|
20
|
+
} from "./config.ts";
|
|
21
|
+
import { CliUsageError } from "./cli-errors.ts";
|
|
22
|
+
import type { CliIo } from "./cli-io.ts";
|
|
23
|
+
import {
|
|
24
|
+
type ExplicitInternalPiRunner,
|
|
25
|
+
} from "./explicit-internal.ts";
|
|
26
|
+
import {
|
|
27
|
+
parseCoderArgv,
|
|
28
|
+
parseCollectorArgv,
|
|
29
|
+
parseDoctorArgv,
|
|
30
|
+
parseFixerArgv,
|
|
31
|
+
parseJudgeArgv,
|
|
32
|
+
parseMergerArgv,
|
|
33
|
+
parseReviewerArgv,
|
|
34
|
+
} from "./invocation.ts";
|
|
35
|
+
import { runPublicCoder, runPublicCoderResume } from "./coder-run.ts";
|
|
36
|
+
import { runPublicCollector } from "./collector-run.ts";
|
|
37
|
+
import { runPublicDoctor } from "./doctor-run.ts";
|
|
38
|
+
import { runPublicFixer, runPublicFixerResume } from "./fixer-run.ts";
|
|
39
|
+
import { runPublicJudge, runPublicResume } from "./judge-run.ts";
|
|
40
|
+
import { runPublicMerger, runPublicMergerResume } from "./merger-run.ts";
|
|
41
|
+
import { runPublicReviewer, runPublicReviewerResume } from "./reviewer-run.ts";
|
|
42
|
+
import { peekRoleRunRole } from "./run-lifecycle.ts";
|
|
43
|
+
import {
|
|
44
|
+
INTERNAL_ROLE_ENTRYPOINT_RELATIVE,
|
|
45
|
+
isPublicCliSupportCommand,
|
|
46
|
+
isPublicConfigurableSeat,
|
|
47
|
+
listHelpCapabilities,
|
|
48
|
+
type PublicThinkingLevel,
|
|
49
|
+
} from "./registry.ts";
|
|
50
|
+
import {
|
|
51
|
+
formatCliDiagnostic,
|
|
52
|
+
presentStructuralRejection,
|
|
53
|
+
} from "./settlement.ts";
|
|
54
|
+
import type { TerminalResult } from "./terminal.ts";
|
|
55
|
+
|
|
56
|
+
export {
|
|
57
|
+
buildExplicitInternalActivationArgs,
|
|
58
|
+
resolveInternalRoleEntrypoint,
|
|
59
|
+
} from "./explicit-internal.ts";
|
|
60
|
+
export { CliUsageError } from "./cli-errors.ts";
|
|
61
|
+
export type { CliIo } from "./cli-io.ts";
|
|
62
|
+
|
|
63
|
+
export type CliEnv = {
|
|
64
|
+
home?: string;
|
|
65
|
+
agentDir?: string;
|
|
66
|
+
/** Process cwd for any Pi subprocess owned by ak-role. */
|
|
67
|
+
cwd?: string;
|
|
68
|
+
packageRoot: string;
|
|
69
|
+
credentials?: CredentialProviders;
|
|
70
|
+
io?: CliIo;
|
|
71
|
+
/** Injectable Pi runner (tests); production resolves `pi` on PATH. */
|
|
72
|
+
piRunner?: ExplicitInternalPiRunner;
|
|
73
|
+
/** Optional caller correlation id (#78 host channel). */
|
|
74
|
+
correlationId?: string;
|
|
75
|
+
/** Extra Pi args for Judge runs (tests: faux provider). */
|
|
76
|
+
judgeExtraPiArgs?: readonly string[];
|
|
77
|
+
/** Override Judge role-run timeout (tests). */
|
|
78
|
+
judgeTimeoutMs?: number;
|
|
79
|
+
/** Extra Pi args for Coder runs (tests: faux provider). */
|
|
80
|
+
coderExtraPiArgs?: readonly string[];
|
|
81
|
+
/** Override Coder role-run timeout (tests). */
|
|
82
|
+
coderTimeoutMs?: number;
|
|
83
|
+
/** Extra Pi args for Collector runs (tests: faux provider). */
|
|
84
|
+
collectorExtraPiArgs?: readonly string[];
|
|
85
|
+
/** Override Collector role-run timeout (tests). */
|
|
86
|
+
collectorTimeoutMs?: number;
|
|
87
|
+
/** Extra Pi args for Doctor runs (tests: faux provider). */
|
|
88
|
+
doctorExtraPiArgs?: readonly string[];
|
|
89
|
+
/** Override Doctor role-run timeout (tests). */
|
|
90
|
+
doctorTimeoutMs?: number;
|
|
91
|
+
/** Extra Pi args for Fixer runs (tests: faux provider). */
|
|
92
|
+
fixerExtraPiArgs?: readonly string[];
|
|
93
|
+
/** Override Fixer role-run timeout (tests). */
|
|
94
|
+
fixerTimeoutMs?: number;
|
|
95
|
+
/** Extra Pi args for Reviewer runs (tests: faux provider). */
|
|
96
|
+
reviewerExtraPiArgs?: readonly string[];
|
|
97
|
+
/** Override Reviewer role-run timeout (tests). */
|
|
98
|
+
reviewerTimeoutMs?: number;
|
|
99
|
+
/** Extra Pi args for Merger runs (tests: faux provider). */
|
|
100
|
+
mergerExtraPiArgs?: readonly string[];
|
|
101
|
+
/** Override Merger role-run timeout (tests). */
|
|
102
|
+
mergerTimeoutMs?: number;
|
|
103
|
+
createRunId?: () => string;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
export type CliResult = {
|
|
107
|
+
exitCode: number;
|
|
108
|
+
/** Settled Terminal when an admitted Role run produced one (programmatic/tests). */
|
|
109
|
+
terminal?: TerminalResult;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const THINKING_LEVELS = new Set([
|
|
113
|
+
"off",
|
|
114
|
+
"minimal",
|
|
115
|
+
"low",
|
|
116
|
+
"medium",
|
|
117
|
+
"high",
|
|
118
|
+
"xhigh",
|
|
119
|
+
"max",
|
|
120
|
+
]);
|
|
121
|
+
|
|
122
|
+
function defaultIo(): CliIo {
|
|
123
|
+
return {
|
|
124
|
+
stdout: (text) => {
|
|
125
|
+
process.stdout.write(text);
|
|
126
|
+
},
|
|
127
|
+
stderr: (text) => {
|
|
128
|
+
process.stderr.write(text);
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function resolveHome(env: CliEnv): string {
|
|
134
|
+
return env.home ?? process.env.HOME ?? homedir();
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function resolveAgentDir(env: CliEnv, home: string): string {
|
|
138
|
+
return (
|
|
139
|
+
env.agentDir ??
|
|
140
|
+
process.env.PI_CODING_AGENT_DIR ??
|
|
141
|
+
join(home, ".pi", "agent")
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
type ParsedGlobal = {
|
|
146
|
+
command?: string;
|
|
147
|
+
args: string[];
|
|
148
|
+
model?: string;
|
|
149
|
+
thinking?: PublicThinkingLevel;
|
|
150
|
+
help: boolean;
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
function parseThinking(value: string): PublicThinkingLevel {
|
|
154
|
+
if (!THINKING_LEVELS.has(value)) {
|
|
155
|
+
throw new CliUsageError(`unknown thinking level: ${value}`);
|
|
156
|
+
}
|
|
157
|
+
return value as PublicThinkingLevel;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function parseArgv(argv: readonly string[]): ParsedGlobal {
|
|
161
|
+
const args = [...argv];
|
|
162
|
+
let model: string | undefined;
|
|
163
|
+
let thinking: PublicThinkingLevel | undefined;
|
|
164
|
+
let help = false;
|
|
165
|
+
const positional: string[] = [];
|
|
166
|
+
|
|
167
|
+
// Global flags may appear before or after the subcommand
|
|
168
|
+
// (`ak-role --model x roles` and `ak-role roles --model x`).
|
|
169
|
+
while (args.length > 0) {
|
|
170
|
+
const token = args.shift()!;
|
|
171
|
+
if (token === "--") {
|
|
172
|
+
positional.push(...args);
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
if (token === "--help" || token === "-h") {
|
|
176
|
+
help = true;
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
if (token === "--model") {
|
|
180
|
+
const value = args.shift();
|
|
181
|
+
if (value === undefined) throw new CliUsageError("--model requires a value");
|
|
182
|
+
model = value;
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
if (token.startsWith("--model=")) {
|
|
186
|
+
model = token.slice("--model=".length);
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
if (token === "--thinking") {
|
|
190
|
+
const value = args.shift();
|
|
191
|
+
if (value === undefined) throw new CliUsageError("--thinking requires a value");
|
|
192
|
+
thinking = parseThinking(value);
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
if (token.startsWith("--thinking=")) {
|
|
196
|
+
thinking = parseThinking(token.slice("--thinking=".length));
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
if (token.startsWith("-") && token !== "-") {
|
|
200
|
+
// Subcommands may own additional flags later; only reject unknowns at the
|
|
201
|
+
// top level when they appear before any positional command is collected
|
|
202
|
+
// and the command is one that does not accept free flags (enforced below).
|
|
203
|
+
positional.push(token);
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
positional.push(token);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const [command, ...rest] = positional;
|
|
210
|
+
return {
|
|
211
|
+
...(command === undefined ? {} : { command }),
|
|
212
|
+
args: rest,
|
|
213
|
+
...(model === undefined ? {} : { model }),
|
|
214
|
+
...(thinking === undefined ? {} : { thinking }),
|
|
215
|
+
help,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function invocationFromParsed(parsed: ParsedGlobal): InvocationModelOverride | undefined {
|
|
220
|
+
if (parsed.model === undefined && parsed.thinking === undefined) return undefined;
|
|
221
|
+
return {
|
|
222
|
+
...(parsed.model === undefined ? {} : { model: parsed.model }),
|
|
223
|
+
...(parsed.thinking === undefined ? {} : { thinking: parsed.thinking }),
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/** Typed facts used by help presentation — not layout. */
|
|
228
|
+
export function helpDocument() {
|
|
229
|
+
return {
|
|
230
|
+
executable: "ak-role",
|
|
231
|
+
capabilities: listHelpCapabilities(),
|
|
232
|
+
internalEntrypoint: INTERNAL_ROLE_ENTRYPOINT_RELATIVE,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function renderHelp(): string {
|
|
237
|
+
const doc = helpDocument();
|
|
238
|
+
const lines: string[] = [
|
|
239
|
+
"ak-role — public role CLI",
|
|
240
|
+
"",
|
|
241
|
+
"Support commands:",
|
|
242
|
+
];
|
|
243
|
+
for (const cap of doc.capabilities) {
|
|
244
|
+
if (cap.kind === "support") {
|
|
245
|
+
lines.push(` ${cap.name}`);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
lines.push("", "Callable roles:");
|
|
249
|
+
for (const cap of doc.capabilities) {
|
|
250
|
+
if (cap.kind === "role") {
|
|
251
|
+
const phaseText =
|
|
252
|
+
cap.phases.length === 1 && cap.phases[0] === null
|
|
253
|
+
? "no phase"
|
|
254
|
+
: `phases ${cap.phases.filter((p) => p !== null).join("|")}` +
|
|
255
|
+
(cap.defaultPhase ? ` (default ${cap.defaultPhase})` : "");
|
|
256
|
+
lines.push(` ${cap.name} — ${phaseText}`);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
lines.push(
|
|
260
|
+
"",
|
|
261
|
+
"Global options: --model provider/model --thinking level",
|
|
262
|
+
"Persistent config: ak-role config set <seat> <provider/model:thinking>",
|
|
263
|
+
"Effective seats: ak-role roles",
|
|
264
|
+
);
|
|
265
|
+
return `${lines.join("\n")}\n`;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function renderRoles(seats: readonly EffectiveSeat[]): string {
|
|
269
|
+
const lines: string[] = ["seat\tkind\tsource\tmodel"];
|
|
270
|
+
for (const seat of seats) {
|
|
271
|
+
const kind = seat.automatic ? "automatic" : "callable";
|
|
272
|
+
const model =
|
|
273
|
+
seat.selection === undefined ? "-" : formatModelSpec(seat.selection);
|
|
274
|
+
lines.push(`${seat.seat}\t${kind}\t${seat.source}\t${model}`);
|
|
275
|
+
}
|
|
276
|
+
return `${lines.join("\n")}\n`;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function renderConfig(config: PublicCliConfig): string {
|
|
280
|
+
const lines: string[] = ["seat\tmodel"];
|
|
281
|
+
const keys = Object.keys(config.seats) as (keyof typeof config.seats)[];
|
|
282
|
+
if (keys.length === 0) {
|
|
283
|
+
lines.push("(empty)");
|
|
284
|
+
} else {
|
|
285
|
+
for (const seat of keys.sort()) {
|
|
286
|
+
const selection = config.seats[seat];
|
|
287
|
+
if (selection === undefined) continue;
|
|
288
|
+
lines.push(`${seat}\t${formatModelSpec(selection)}`);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
return `${lines.join("\n")}\n`;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
async function runConfigCommand(
|
|
295
|
+
args: readonly string[],
|
|
296
|
+
home: string,
|
|
297
|
+
io: CliIo,
|
|
298
|
+
): Promise<number> {
|
|
299
|
+
if (args.length === 0 || args[0] === "get" || args[0] === "list" || args[0] === "show") {
|
|
300
|
+
const config = await loadPublicCliConfig(home);
|
|
301
|
+
if (args[0] === "get" && args[1] !== undefined) {
|
|
302
|
+
if (!isPublicConfigurableSeat(args[1])) {
|
|
303
|
+
throw new CliUsageError(`unknown configurable seat: ${args[1]}`);
|
|
304
|
+
}
|
|
305
|
+
const selection = config.seats[args[1]];
|
|
306
|
+
if (selection === undefined) {
|
|
307
|
+
io.stdout(`${args[1]}\t(unconfigured)\n`);
|
|
308
|
+
} else {
|
|
309
|
+
io.stdout(`${args[1]}\t${formatModelSpec(selection)}\n`);
|
|
310
|
+
}
|
|
311
|
+
return 0;
|
|
312
|
+
}
|
|
313
|
+
io.stdout(renderConfig(config));
|
|
314
|
+
return 0;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
if (args[0] === "set") {
|
|
318
|
+
if (args.length < 3) {
|
|
319
|
+
throw new CliUsageError(
|
|
320
|
+
"usage: ak-role config set <seat> <provider/model:thinking>",
|
|
321
|
+
);
|
|
322
|
+
}
|
|
323
|
+
// Bulk: repeated seat spec pairs after `set`
|
|
324
|
+
const pairs = args.slice(1);
|
|
325
|
+
if (pairs.length % 2 !== 0) {
|
|
326
|
+
throw new CliUsageError(
|
|
327
|
+
"config set requires seat/spec pairs: ak-role config set <seat> <spec> [<seat> <spec> ...]",
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
let config = await loadPublicCliConfig(home);
|
|
331
|
+
for (let i = 0; i < pairs.length; i += 2) {
|
|
332
|
+
const seat = pairs[i]!;
|
|
333
|
+
const spec = pairs[i + 1]!;
|
|
334
|
+
if (!isPublicConfigurableSeat(seat)) {
|
|
335
|
+
throw new CliUsageError(`unknown configurable seat: ${seat}`);
|
|
336
|
+
}
|
|
337
|
+
config = setPersistentSeatConfig(config, seat, parseModelSpec(spec));
|
|
338
|
+
}
|
|
339
|
+
await savePublicCliConfig(config, home);
|
|
340
|
+
io.stdout(renderConfig(config));
|
|
341
|
+
return 0;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
throw new CliUsageError(`unknown config subcommand: ${args[0]}`);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
export async function runAkRole(
|
|
348
|
+
argv: readonly string[],
|
|
349
|
+
env: CliEnv,
|
|
350
|
+
): Promise<CliResult> {
|
|
351
|
+
const io = env.io ?? defaultIo();
|
|
352
|
+
const home = resolveHome(env);
|
|
353
|
+
|
|
354
|
+
try {
|
|
355
|
+
const parsed = parseArgv(argv);
|
|
356
|
+
|
|
357
|
+
if (
|
|
358
|
+
parsed.help ||
|
|
359
|
+
parsed.command === undefined ||
|
|
360
|
+
parsed.command === "help"
|
|
361
|
+
) {
|
|
362
|
+
// Layered help: `help <topic>` still derives from the same typed registry.
|
|
363
|
+
if (parsed.command === "help" && parsed.args[0] !== undefined) {
|
|
364
|
+
const topic = parsed.args[0];
|
|
365
|
+
const caps = listHelpCapabilities();
|
|
366
|
+
const match = caps.find((cap) => cap.name === topic);
|
|
367
|
+
if (match === undefined) {
|
|
368
|
+
throw new CliUsageError(`unknown help topic: ${topic}`);
|
|
369
|
+
}
|
|
370
|
+
if (match.kind === "support") {
|
|
371
|
+
io.stdout(`command\t${match.name}\tkind\tsupport\n`);
|
|
372
|
+
} else {
|
|
373
|
+
io.stdout(
|
|
374
|
+
`command\t${match.name}\tkind\trole\tphases\t${match.phases
|
|
375
|
+
.map((p) => (p === null ? "none" : p))
|
|
376
|
+
.join(",")}\tdefault\t${match.defaultPhase ?? "none"}\n`,
|
|
377
|
+
);
|
|
378
|
+
}
|
|
379
|
+
return { exitCode: 0 };
|
|
380
|
+
}
|
|
381
|
+
io.stdout(renderHelp());
|
|
382
|
+
return { exitCode: 0 };
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
if (parsed.command === "roles") {
|
|
386
|
+
if (parsed.args.length > 0) {
|
|
387
|
+
throw new CliUsageError("roles takes no arguments");
|
|
388
|
+
}
|
|
389
|
+
const config = await loadPublicCliConfig(home);
|
|
390
|
+
const credentials =
|
|
391
|
+
env.credentials ??
|
|
392
|
+
(await loadCredentialProviders(resolveAgentDir(env, home)));
|
|
393
|
+
const seats = effectiveSeatConfigurations(
|
|
394
|
+
config,
|
|
395
|
+
credentials,
|
|
396
|
+
invocationFromParsed(parsed),
|
|
397
|
+
);
|
|
398
|
+
io.stdout(renderRoles(seats));
|
|
399
|
+
return { exitCode: 0 };
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
if (parsed.command === "config") {
|
|
403
|
+
return { exitCode: await runConfigCommand(parsed.args, home, io) };
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
// Resume reopens an exact Role run after a typed HTTP 429 (#108/#109).
|
|
407
|
+
// Seat and dispatch follow the durable admitted role (role-correct continuation).
|
|
408
|
+
if (parsed.command === "resume") {
|
|
409
|
+
const agentDir = resolveAgentDir(env, home);
|
|
410
|
+
const cwd = env.cwd ?? process.cwd();
|
|
411
|
+
const config = await loadPublicCliConfig(home);
|
|
412
|
+
const credentials =
|
|
413
|
+
env.credentials ?? (await loadCredentialProviders(agentDir));
|
|
414
|
+
const resumeRunId = parsed.args[0];
|
|
415
|
+
const resumeRole =
|
|
416
|
+
resumeRunId === undefined || resumeRunId.trim() === ""
|
|
417
|
+
? undefined
|
|
418
|
+
: await peekRoleRunRole(home, resumeRunId);
|
|
419
|
+
if (resumeRole === "collector") {
|
|
420
|
+
throw new CliUsageError(
|
|
421
|
+
"collector role runs are one-shot and cannot be resumed",
|
|
422
|
+
);
|
|
423
|
+
}
|
|
424
|
+
if (resumeRole === "doctor") {
|
|
425
|
+
throw new CliUsageError(
|
|
426
|
+
"doctor role runs are one-shot and cannot be resumed",
|
|
427
|
+
);
|
|
428
|
+
}
|
|
429
|
+
const resumeSeatRole =
|
|
430
|
+
resumeRole === "coder"
|
|
431
|
+
? "coder"
|
|
432
|
+
: resumeRole === "fixer"
|
|
433
|
+
? "fixer"
|
|
434
|
+
: resumeRole === "reviewer"
|
|
435
|
+
? "reviewer"
|
|
436
|
+
: resumeRole === "merger"
|
|
437
|
+
? "merger"
|
|
438
|
+
: "judge";
|
|
439
|
+
// Temporary model/thinking override for this resume only — never persists.
|
|
440
|
+
const seat = resolveEffectiveSeat(
|
|
441
|
+
config,
|
|
442
|
+
resumeSeatRole,
|
|
443
|
+
credentials,
|
|
444
|
+
invocationFromParsed(parsed),
|
|
445
|
+
);
|
|
446
|
+
if (resumeRole === "coder") {
|
|
447
|
+
const result = await runPublicCoderResume(
|
|
448
|
+
parsed.args,
|
|
449
|
+
{
|
|
450
|
+
home,
|
|
451
|
+
agentDir,
|
|
452
|
+
packageRoot: env.packageRoot,
|
|
453
|
+
cwd,
|
|
454
|
+
credentials,
|
|
455
|
+
...(env.correlationId === undefined
|
|
456
|
+
? {}
|
|
457
|
+
: { correlationId: env.correlationId }),
|
|
458
|
+
...(env.piRunner === undefined ? {} : { piRunner: env.piRunner }),
|
|
459
|
+
...(seat.selection === undefined ? {} : { model: seat.selection }),
|
|
460
|
+
...(env.coderExtraPiArgs === undefined
|
|
461
|
+
? {}
|
|
462
|
+
: { extraPiArgs: env.coderExtraPiArgs }),
|
|
463
|
+
...(env.coderTimeoutMs === undefined
|
|
464
|
+
? {}
|
|
465
|
+
: { timeoutMs: env.coderTimeoutMs }),
|
|
466
|
+
},
|
|
467
|
+
io,
|
|
468
|
+
);
|
|
469
|
+
return {
|
|
470
|
+
exitCode: result.exitCode,
|
|
471
|
+
...(result.terminal === undefined ? {} : { terminal: result.terminal }),
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
if (resumeRole === "fixer") {
|
|
475
|
+
const result = await runPublicFixerResume(
|
|
476
|
+
parsed.args,
|
|
477
|
+
{
|
|
478
|
+
home,
|
|
479
|
+
agentDir,
|
|
480
|
+
packageRoot: env.packageRoot,
|
|
481
|
+
cwd,
|
|
482
|
+
credentials,
|
|
483
|
+
...(env.correlationId === undefined
|
|
484
|
+
? {}
|
|
485
|
+
: { correlationId: env.correlationId }),
|
|
486
|
+
...(env.piRunner === undefined ? {} : { piRunner: env.piRunner }),
|
|
487
|
+
...(seat.selection === undefined ? {} : { model: seat.selection }),
|
|
488
|
+
...(env.fixerExtraPiArgs === undefined
|
|
489
|
+
? {}
|
|
490
|
+
: { extraPiArgs: env.fixerExtraPiArgs }),
|
|
491
|
+
...(env.fixerTimeoutMs === undefined
|
|
492
|
+
? {}
|
|
493
|
+
: { timeoutMs: env.fixerTimeoutMs }),
|
|
494
|
+
},
|
|
495
|
+
io,
|
|
496
|
+
);
|
|
497
|
+
return {
|
|
498
|
+
exitCode: result.exitCode,
|
|
499
|
+
...(result.terminal === undefined ? {} : { terminal: result.terminal }),
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
if (resumeRole === "reviewer") {
|
|
503
|
+
const result = await runPublicReviewerResume(
|
|
504
|
+
parsed.args,
|
|
505
|
+
{
|
|
506
|
+
home,
|
|
507
|
+
agentDir,
|
|
508
|
+
packageRoot: env.packageRoot,
|
|
509
|
+
cwd,
|
|
510
|
+
credentials,
|
|
511
|
+
...(env.correlationId === undefined
|
|
512
|
+
? {}
|
|
513
|
+
: { correlationId: env.correlationId }),
|
|
514
|
+
...(env.piRunner === undefined ? {} : { piRunner: env.piRunner }),
|
|
515
|
+
...(seat.selection === undefined ? {} : { model: seat.selection }),
|
|
516
|
+
...(env.reviewerExtraPiArgs === undefined
|
|
517
|
+
? {}
|
|
518
|
+
: { extraPiArgs: env.reviewerExtraPiArgs }),
|
|
519
|
+
...(env.reviewerTimeoutMs === undefined
|
|
520
|
+
? {}
|
|
521
|
+
: { timeoutMs: env.reviewerTimeoutMs }),
|
|
522
|
+
},
|
|
523
|
+
io,
|
|
524
|
+
);
|
|
525
|
+
return {
|
|
526
|
+
exitCode: result.exitCode,
|
|
527
|
+
...(result.terminal === undefined ? {} : { terminal: result.terminal }),
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
if (resumeRole === "merger") {
|
|
531
|
+
const result = await runPublicMergerResume(
|
|
532
|
+
parsed.args,
|
|
533
|
+
{
|
|
534
|
+
home,
|
|
535
|
+
agentDir,
|
|
536
|
+
packageRoot: env.packageRoot,
|
|
537
|
+
cwd,
|
|
538
|
+
credentials,
|
|
539
|
+
...(env.correlationId === undefined
|
|
540
|
+
? {}
|
|
541
|
+
: { correlationId: env.correlationId }),
|
|
542
|
+
...(env.piRunner === undefined ? {} : { piRunner: env.piRunner }),
|
|
543
|
+
...(seat.selection === undefined ? {} : { model: seat.selection }),
|
|
544
|
+
...(env.mergerExtraPiArgs === undefined
|
|
545
|
+
? {}
|
|
546
|
+
: { extraPiArgs: env.mergerExtraPiArgs }),
|
|
547
|
+
...(env.mergerTimeoutMs === undefined
|
|
548
|
+
? {}
|
|
549
|
+
: { timeoutMs: env.mergerTimeoutMs }),
|
|
550
|
+
},
|
|
551
|
+
io,
|
|
552
|
+
);
|
|
553
|
+
return {
|
|
554
|
+
exitCode: result.exitCode,
|
|
555
|
+
...(result.terminal === undefined ? {} : { terminal: result.terminal }),
|
|
556
|
+
};
|
|
557
|
+
}
|
|
558
|
+
const result = await runPublicResume(
|
|
559
|
+
parsed.args,
|
|
560
|
+
{
|
|
561
|
+
home,
|
|
562
|
+
agentDir,
|
|
563
|
+
packageRoot: env.packageRoot,
|
|
564
|
+
cwd,
|
|
565
|
+
credentials,
|
|
566
|
+
...(env.correlationId === undefined
|
|
567
|
+
? {}
|
|
568
|
+
: { correlationId: env.correlationId }),
|
|
569
|
+
...(env.piRunner === undefined ? {} : { piRunner: env.piRunner }),
|
|
570
|
+
...(seat.selection === undefined ? {} : { model: seat.selection }),
|
|
571
|
+
...(env.judgeExtraPiArgs === undefined
|
|
572
|
+
? {}
|
|
573
|
+
: { extraPiArgs: env.judgeExtraPiArgs }),
|
|
574
|
+
...(env.judgeTimeoutMs === undefined
|
|
575
|
+
? {}
|
|
576
|
+
: { timeoutMs: env.judgeTimeoutMs }),
|
|
577
|
+
},
|
|
578
|
+
io,
|
|
579
|
+
);
|
|
580
|
+
return {
|
|
581
|
+
exitCode: result.exitCode,
|
|
582
|
+
...(result.terminal === undefined ? {} : { terminal: result.terminal }),
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
if (isPublicCliSupportCommand(parsed.command)) {
|
|
587
|
+
throw new CliUsageError(`unhandled support command: ${parsed.command}`);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
// Judge is the first complete public Role run path (#106).
|
|
591
|
+
if (parsed.command === "judge") {
|
|
592
|
+
const agentDir = resolveAgentDir(env, home);
|
|
593
|
+
const cwd = env.cwd ?? process.cwd();
|
|
594
|
+
const config = await loadPublicCliConfig(home);
|
|
595
|
+
const credentials =
|
|
596
|
+
env.credentials ?? (await loadCredentialProviders(agentDir));
|
|
597
|
+
const seat = resolveEffectiveSeat(
|
|
598
|
+
config,
|
|
599
|
+
"judge",
|
|
600
|
+
credentials,
|
|
601
|
+
invocationFromParsed(parsed),
|
|
602
|
+
);
|
|
603
|
+
const result = await runPublicJudge(
|
|
604
|
+
parsed.args,
|
|
605
|
+
{
|
|
606
|
+
home,
|
|
607
|
+
agentDir,
|
|
608
|
+
packageRoot: env.packageRoot,
|
|
609
|
+
cwd,
|
|
610
|
+
credentials,
|
|
611
|
+
...(env.correlationId === undefined
|
|
612
|
+
? {}
|
|
613
|
+
: { correlationId: env.correlationId }),
|
|
614
|
+
...(env.piRunner === undefined ? {} : { piRunner: env.piRunner }),
|
|
615
|
+
...(seat.selection === undefined ? {} : { model: seat.selection }),
|
|
616
|
+
...(env.judgeExtraPiArgs === undefined
|
|
617
|
+
? {}
|
|
618
|
+
: { extraPiArgs: env.judgeExtraPiArgs }),
|
|
619
|
+
...(env.judgeTimeoutMs === undefined
|
|
620
|
+
? {}
|
|
621
|
+
: { timeoutMs: env.judgeTimeoutMs }),
|
|
622
|
+
...(env.createRunId === undefined ? {} : { createRunId: env.createRunId }),
|
|
623
|
+
},
|
|
624
|
+
io,
|
|
625
|
+
parseJudgeArgv,
|
|
626
|
+
);
|
|
627
|
+
return {
|
|
628
|
+
exitCode: result.exitCode,
|
|
629
|
+
...(result.terminal === undefined ? {} : { terminal: result.terminal }),
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
// Coder public run path with package-owned TDD method (#109).
|
|
634
|
+
if (parsed.command === "coder") {
|
|
635
|
+
const agentDir = resolveAgentDir(env, home);
|
|
636
|
+
const cwd = env.cwd ?? process.cwd();
|
|
637
|
+
const config = await loadPublicCliConfig(home);
|
|
638
|
+
const credentials =
|
|
639
|
+
env.credentials ?? (await loadCredentialProviders(agentDir));
|
|
640
|
+
const seat = resolveEffectiveSeat(
|
|
641
|
+
config,
|
|
642
|
+
"coder",
|
|
643
|
+
credentials,
|
|
644
|
+
invocationFromParsed(parsed),
|
|
645
|
+
);
|
|
646
|
+
const result = await runPublicCoder(
|
|
647
|
+
parsed.args,
|
|
648
|
+
{
|
|
649
|
+
home,
|
|
650
|
+
agentDir,
|
|
651
|
+
packageRoot: env.packageRoot,
|
|
652
|
+
cwd,
|
|
653
|
+
credentials,
|
|
654
|
+
...(env.correlationId === undefined
|
|
655
|
+
? {}
|
|
656
|
+
: { correlationId: env.correlationId }),
|
|
657
|
+
...(env.piRunner === undefined ? {} : { piRunner: env.piRunner }),
|
|
658
|
+
...(seat.selection === undefined ? {} : { model: seat.selection }),
|
|
659
|
+
...(env.coderExtraPiArgs === undefined
|
|
660
|
+
? {}
|
|
661
|
+
: { extraPiArgs: env.coderExtraPiArgs }),
|
|
662
|
+
...(env.coderTimeoutMs === undefined
|
|
663
|
+
? {}
|
|
664
|
+
: { timeoutMs: env.coderTimeoutMs }),
|
|
665
|
+
...(env.createRunId === undefined ? {} : { createRunId: env.createRunId }),
|
|
666
|
+
},
|
|
667
|
+
io,
|
|
668
|
+
parseCoderArgv,
|
|
669
|
+
);
|
|
670
|
+
return {
|
|
671
|
+
exitCode: result.exitCode,
|
|
672
|
+
...(result.terminal === undefined ? {} : { terminal: result.terminal }),
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
// Fixer public run path with optional package-owned diagnosing-bugs (#110).
|
|
677
|
+
if (parsed.command === "fixer") {
|
|
678
|
+
const agentDir = resolveAgentDir(env, home);
|
|
679
|
+
const cwd = env.cwd ?? process.cwd();
|
|
680
|
+
const config = await loadPublicCliConfig(home);
|
|
681
|
+
const credentials =
|
|
682
|
+
env.credentials ?? (await loadCredentialProviders(agentDir));
|
|
683
|
+
const seat = resolveEffectiveSeat(
|
|
684
|
+
config,
|
|
685
|
+
"fixer",
|
|
686
|
+
credentials,
|
|
687
|
+
invocationFromParsed(parsed),
|
|
688
|
+
);
|
|
689
|
+
const result = await runPublicFixer(
|
|
690
|
+
parsed.args,
|
|
691
|
+
{
|
|
692
|
+
home,
|
|
693
|
+
agentDir,
|
|
694
|
+
packageRoot: env.packageRoot,
|
|
695
|
+
cwd,
|
|
696
|
+
credentials,
|
|
697
|
+
...(env.correlationId === undefined
|
|
698
|
+
? {}
|
|
699
|
+
: { correlationId: env.correlationId }),
|
|
700
|
+
...(env.piRunner === undefined ? {} : { piRunner: env.piRunner }),
|
|
701
|
+
...(seat.selection === undefined ? {} : { model: seat.selection }),
|
|
702
|
+
...(env.fixerExtraPiArgs === undefined
|
|
703
|
+
? {}
|
|
704
|
+
: { extraPiArgs: env.fixerExtraPiArgs }),
|
|
705
|
+
...(env.fixerTimeoutMs === undefined
|
|
706
|
+
? {}
|
|
707
|
+
: { timeoutMs: env.fixerTimeoutMs }),
|
|
708
|
+
...(env.createRunId === undefined ? {} : { createRunId: env.createRunId }),
|
|
709
|
+
},
|
|
710
|
+
io,
|
|
711
|
+
parseFixerArgv,
|
|
712
|
+
);
|
|
713
|
+
return {
|
|
714
|
+
exitCode: result.exitCode,
|
|
715
|
+
...(result.terminal === undefined ? {} : { terminal: result.terminal }),
|
|
716
|
+
};
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
// Collector public run path from explicit PR + leg declarations (#112).
|
|
720
|
+
if (parsed.command === "collector") {
|
|
721
|
+
const agentDir = resolveAgentDir(env, home);
|
|
722
|
+
const cwd = env.cwd ?? process.cwd();
|
|
723
|
+
const config = await loadPublicCliConfig(home);
|
|
724
|
+
const credentials =
|
|
725
|
+
env.credentials ?? (await loadCredentialProviders(agentDir));
|
|
726
|
+
const seat = resolveEffectiveSeat(
|
|
727
|
+
config,
|
|
728
|
+
"collector",
|
|
729
|
+
credentials,
|
|
730
|
+
invocationFromParsed(parsed),
|
|
731
|
+
);
|
|
732
|
+
const result = await runPublicCollector(
|
|
733
|
+
parsed.args,
|
|
734
|
+
{
|
|
735
|
+
home,
|
|
736
|
+
agentDir,
|
|
737
|
+
packageRoot: env.packageRoot,
|
|
738
|
+
cwd,
|
|
739
|
+
credentials,
|
|
740
|
+
...(env.correlationId === undefined
|
|
741
|
+
? {}
|
|
742
|
+
: { correlationId: env.correlationId }),
|
|
743
|
+
...(env.piRunner === undefined ? {} : { piRunner: env.piRunner }),
|
|
744
|
+
...(seat.selection === undefined ? {} : { model: seat.selection }),
|
|
745
|
+
...(env.collectorExtraPiArgs === undefined
|
|
746
|
+
? {}
|
|
747
|
+
: { extraPiArgs: env.collectorExtraPiArgs }),
|
|
748
|
+
...(env.collectorTimeoutMs === undefined
|
|
749
|
+
? {}
|
|
750
|
+
: { timeoutMs: env.collectorTimeoutMs }),
|
|
751
|
+
...(env.createRunId === undefined ? {} : { createRunId: env.createRunId }),
|
|
752
|
+
},
|
|
753
|
+
io,
|
|
754
|
+
parseCollectorArgv,
|
|
755
|
+
);
|
|
756
|
+
return {
|
|
757
|
+
exitCode: result.exitCode,
|
|
758
|
+
...(result.terminal === undefined ? {} : { terminal: result.terminal }),
|
|
759
|
+
};
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
// Reviewer public run path with package-owned adapted code-review (#111).
|
|
763
|
+
if (parsed.command === "reviewer") {
|
|
764
|
+
const agentDir = resolveAgentDir(env, home);
|
|
765
|
+
const cwd = env.cwd ?? process.cwd();
|
|
766
|
+
const config = await loadPublicCliConfig(home);
|
|
767
|
+
const credentials =
|
|
768
|
+
env.credentials ?? (await loadCredentialProviders(agentDir));
|
|
769
|
+
const seat = resolveEffectiveSeat(
|
|
770
|
+
config,
|
|
771
|
+
"reviewer",
|
|
772
|
+
credentials,
|
|
773
|
+
invocationFromParsed(parsed),
|
|
774
|
+
);
|
|
775
|
+
const result = await runPublicReviewer(
|
|
776
|
+
parsed.args,
|
|
777
|
+
{
|
|
778
|
+
home,
|
|
779
|
+
agentDir,
|
|
780
|
+
packageRoot: env.packageRoot,
|
|
781
|
+
cwd,
|
|
782
|
+
credentials,
|
|
783
|
+
...(env.correlationId === undefined
|
|
784
|
+
? {}
|
|
785
|
+
: { correlationId: env.correlationId }),
|
|
786
|
+
...(env.piRunner === undefined ? {} : { piRunner: env.piRunner }),
|
|
787
|
+
...(seat.selection === undefined ? {} : { model: seat.selection }),
|
|
788
|
+
...(env.reviewerExtraPiArgs === undefined
|
|
789
|
+
? {}
|
|
790
|
+
: { extraPiArgs: env.reviewerExtraPiArgs }),
|
|
791
|
+
...(env.reviewerTimeoutMs === undefined
|
|
792
|
+
? {}
|
|
793
|
+
: { timeoutMs: env.reviewerTimeoutMs }),
|
|
794
|
+
...(env.createRunId === undefined ? {} : { createRunId: env.createRunId }),
|
|
795
|
+
},
|
|
796
|
+
io,
|
|
797
|
+
parseReviewerArgv,
|
|
798
|
+
);
|
|
799
|
+
return {
|
|
800
|
+
exitCode: result.exitCode,
|
|
801
|
+
...(result.terminal === undefined ? {} : { terminal: result.terminal }),
|
|
802
|
+
};
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
// Doctor public run path from Issue identity + optional confined runs root (#113).
|
|
806
|
+
if (parsed.command === "doctor") {
|
|
807
|
+
const agentDir = resolveAgentDir(env, home);
|
|
808
|
+
const cwd = env.cwd ?? process.cwd();
|
|
809
|
+
const config = await loadPublicCliConfig(home);
|
|
810
|
+
const credentials =
|
|
811
|
+
env.credentials ?? (await loadCredentialProviders(agentDir));
|
|
812
|
+
const seat = resolveEffectiveSeat(
|
|
813
|
+
config,
|
|
814
|
+
"doctor",
|
|
815
|
+
credentials,
|
|
816
|
+
invocationFromParsed(parsed),
|
|
817
|
+
);
|
|
818
|
+
const result = await runPublicDoctor(
|
|
819
|
+
parsed.args,
|
|
820
|
+
{
|
|
821
|
+
home,
|
|
822
|
+
agentDir,
|
|
823
|
+
packageRoot: env.packageRoot,
|
|
824
|
+
cwd,
|
|
825
|
+
credentials,
|
|
826
|
+
...(env.correlationId === undefined
|
|
827
|
+
? {}
|
|
828
|
+
: { correlationId: env.correlationId }),
|
|
829
|
+
...(env.piRunner === undefined ? {} : { piRunner: env.piRunner }),
|
|
830
|
+
...(seat.selection === undefined ? {} : { model: seat.selection }),
|
|
831
|
+
...(env.doctorExtraPiArgs === undefined
|
|
832
|
+
? {}
|
|
833
|
+
: { extraPiArgs: env.doctorExtraPiArgs }),
|
|
834
|
+
...(env.doctorTimeoutMs === undefined
|
|
835
|
+
? {}
|
|
836
|
+
: { timeoutMs: env.doctorTimeoutMs }),
|
|
837
|
+
...(env.createRunId === undefined ? {} : { createRunId: env.createRunId }),
|
|
838
|
+
},
|
|
839
|
+
io,
|
|
840
|
+
parseDoctorArgv,
|
|
841
|
+
);
|
|
842
|
+
return {
|
|
843
|
+
exitCode: result.exitCode,
|
|
844
|
+
...(result.terminal === undefined ? {} : { terminal: result.terminal }),
|
|
845
|
+
};
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
// Merger public run path: derive active-merge envelope + forced merge-only method (#114).
|
|
849
|
+
if (parsed.command === "merger") {
|
|
850
|
+
const agentDir = resolveAgentDir(env, home);
|
|
851
|
+
const cwd = env.cwd ?? process.cwd();
|
|
852
|
+
const config = await loadPublicCliConfig(home);
|
|
853
|
+
const credentials =
|
|
854
|
+
env.credentials ?? (await loadCredentialProviders(agentDir));
|
|
855
|
+
const seat = resolveEffectiveSeat(
|
|
856
|
+
config,
|
|
857
|
+
"merger",
|
|
858
|
+
credentials,
|
|
859
|
+
invocationFromParsed(parsed),
|
|
860
|
+
);
|
|
861
|
+
const result = await runPublicMerger(
|
|
862
|
+
parsed.args,
|
|
863
|
+
{
|
|
864
|
+
home,
|
|
865
|
+
agentDir,
|
|
866
|
+
packageRoot: env.packageRoot,
|
|
867
|
+
cwd,
|
|
868
|
+
credentials,
|
|
869
|
+
...(env.correlationId === undefined
|
|
870
|
+
? {}
|
|
871
|
+
: { correlationId: env.correlationId }),
|
|
872
|
+
...(env.piRunner === undefined ? {} : { piRunner: env.piRunner }),
|
|
873
|
+
...(seat.selection === undefined ? {} : { model: seat.selection }),
|
|
874
|
+
...(env.mergerExtraPiArgs === undefined
|
|
875
|
+
? {}
|
|
876
|
+
: { extraPiArgs: env.mergerExtraPiArgs }),
|
|
877
|
+
...(env.mergerTimeoutMs === undefined
|
|
878
|
+
? {}
|
|
879
|
+
: { timeoutMs: env.mergerTimeoutMs }),
|
|
880
|
+
...(env.createRunId === undefined ? {} : { createRunId: env.createRunId }),
|
|
881
|
+
},
|
|
882
|
+
io,
|
|
883
|
+
parseMergerArgv,
|
|
884
|
+
);
|
|
885
|
+
return {
|
|
886
|
+
exitCode: result.exitCode,
|
|
887
|
+
...(result.terminal === undefined ? {} : { terminal: result.terminal }),
|
|
888
|
+
};
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
// #115: every PUBLIC_CALLABLE_ROLE has a completed handler above. Unknown
|
|
892
|
+
// tokens (including misspelled role names) are structural rejects.
|
|
893
|
+
throw new CliUsageError(`unknown command: ${parsed.command}`);
|
|
894
|
+
} catch (error) {
|
|
895
|
+
if (error instanceof CliUsageError) {
|
|
896
|
+
// Non-judge structural paths share the same rejection presenter as Judge.
|
|
897
|
+
presentStructuralRejection(error, io);
|
|
898
|
+
return { exitCode: 2 };
|
|
899
|
+
}
|
|
900
|
+
// Unrecognized outer failure: retain actual name/message identity (no wash).
|
|
901
|
+
if (error instanceof Error) {
|
|
902
|
+
const label =
|
|
903
|
+
error.name !== "" && error.name !== "Error"
|
|
904
|
+
? `${error.name}: ${error.message}`
|
|
905
|
+
: error.message;
|
|
906
|
+
io.stderr(formatCliDiagnostic(label || error.name || "unrecognized exception"));
|
|
907
|
+
return { exitCode: 1 };
|
|
908
|
+
}
|
|
909
|
+
io.stderr(formatCliDiagnostic(String(error)));
|
|
910
|
+
return { exitCode: 1 };
|
|
911
|
+
}
|
|
912
|
+
}
|