aiwcli 0.13.6 → 0.13.7
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/dist/templates/cc-native/.claude/settings.json +3 -1
- package/dist/templates/cc-native/_cc-native/cc-native.config.json +4 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/settings.ts +2 -2
- package/dist/templates/cc-native/_cc-native/lib-ts/types.ts +21 -0
- package/dist/templates/cc-native/_cc-native/plan-review/lib/agent-selection.ts +41 -9
- package/dist/templates/cc-native/_cc-native/plan-review/lib/preflight.ts +162 -0
- package/dist/templates/cc-native/_cc-native/plan-review/lib/review-pipeline.ts +39 -6
- package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/providers/claude-agent.ts +21 -0
- package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/providers/codex-agent.ts +14 -0
- package/oclif.manifest.json +1 -1
- package/package.json +1 -1
|
@@ -70,8 +70,8 @@ export const DEFAULT_COMPLEXITY_CATEGORIES = ["code", "infrastructure", "documen
|
|
|
70
70
|
|
|
71
71
|
export const DEFAULT_MODELS_CONFIG: ModelsConfig = {
|
|
72
72
|
providers: {
|
|
73
|
-
claude: { enabled:
|
|
74
|
-
codex: { enabled: true, models: ["
|
|
73
|
+
claude: { enabled: false, models: ["sonnet"] },
|
|
74
|
+
codex: { enabled: true, models: ["gpt-5.2"] },
|
|
75
75
|
},
|
|
76
76
|
};
|
|
77
77
|
|
|
@@ -327,3 +327,24 @@ export interface IterationAdvancement {
|
|
|
327
327
|
updatedState: IterationState;
|
|
328
328
|
newGraduates: string[];
|
|
329
329
|
}
|
|
330
|
+
|
|
331
|
+
// ---------------------------------------------------------------------------
|
|
332
|
+
// Preflight Types
|
|
333
|
+
// ---------------------------------------------------------------------------
|
|
334
|
+
|
|
335
|
+
/** Result from a single provider+model preflight check */
|
|
336
|
+
export interface PreflightCheckResult {
|
|
337
|
+
provider: string;
|
|
338
|
+
model: string;
|
|
339
|
+
available: boolean;
|
|
340
|
+
latencyMs: number;
|
|
341
|
+
error?: string;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/** Aggregated preflight report across all provider+model combos */
|
|
345
|
+
export interface PreflightReport {
|
|
346
|
+
checks: PreflightCheckResult[];
|
|
347
|
+
available: Map<string, Set<string>>; // provider → set of working models
|
|
348
|
+
allFailed: boolean;
|
|
349
|
+
totalMs: number;
|
|
350
|
+
}
|
|
@@ -47,35 +47,67 @@ export function resolveMandatoryAgents(
|
|
|
47
47
|
// Model Assignment
|
|
48
48
|
// ---------------------------------------------------------------------------
|
|
49
49
|
|
|
50
|
+
/** Provider priority order: codex first (cheaper/faster), claude as fallback */
|
|
51
|
+
const PROVIDER_PRIORITY = ["codex", "claude"];
|
|
52
|
+
|
|
50
53
|
/**
|
|
51
|
-
*
|
|
52
|
-
*
|
|
54
|
+
* Assign providers and models to agents.
|
|
55
|
+
* When preflightAvailable is provided, filters to only models that passed preflight.
|
|
56
|
+
* Providers are ordered by PROVIDER_PRIORITY (codex first, claude fallback).
|
|
57
|
+
* All agents get the first available provider; random model within that provider.
|
|
53
58
|
*/
|
|
54
59
|
export function assignModelsToAgents(
|
|
55
60
|
agents: AgentConfig[],
|
|
56
61
|
modelsConfig: ModelsConfig,
|
|
62
|
+
preflightAvailable?: Map<string, Set<string>>,
|
|
57
63
|
): AgentConfig[] {
|
|
58
|
-
|
|
64
|
+
let enabledProviders = Object.entries(modelsConfig.providers)
|
|
59
65
|
.filter(([name, config]) => {
|
|
60
66
|
if (!config.enabled || config.models.length === 0) return false;
|
|
61
67
|
const cliName = name === "claude" ? "claude" : name;
|
|
62
68
|
const found = findExecutable(cliName);
|
|
63
69
|
if (!found) {
|
|
64
70
|
logWarn(HOOK, `Provider '${name}' enabled but CLI '${cliName}' not found on PATH — skipping`);
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
return true;
|
|
74
|
+
})
|
|
75
|
+
.map(([name, config]) => {
|
|
76
|
+
// Filter models by preflight results when available
|
|
77
|
+
if (preflightAvailable) {
|
|
78
|
+
const passedModels = preflightAvailable.get(name);
|
|
79
|
+
if (!passedModels || passedModels.size === 0) {
|
|
80
|
+
logWarn(HOOK, `Provider '${name}' has no models that passed preflight — skipping`);
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
const filteredModels = config.models.filter(m => passedModels.has(m));
|
|
84
|
+
if (filteredModels.length === 0) {
|
|
85
|
+
logWarn(HOOK, `Provider '${name}': none of its configured models passed preflight — skipping`);
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
return [name, { ...config, models: filteredModels }] as [string, typeof config];
|
|
65
89
|
}
|
|
66
|
-
return
|
|
67
|
-
})
|
|
90
|
+
return [name, config] as [string, typeof config];
|
|
91
|
+
})
|
|
92
|
+
.filter((entry): entry is [string, { enabled: boolean; models: string[] }] => entry !== null);
|
|
93
|
+
|
|
94
|
+
// Sort by provider priority (codex first)
|
|
95
|
+
enabledProviders.sort((a, b) => {
|
|
96
|
+
const aIdx = PROVIDER_PRIORITY.indexOf(a[0]);
|
|
97
|
+
const bIdx = PROVIDER_PRIORITY.indexOf(b[0]);
|
|
98
|
+
return (aIdx === -1 ? 999 : aIdx) - (bIdx === -1 ? 999 : bIdx);
|
|
99
|
+
});
|
|
68
100
|
|
|
69
101
|
if (enabledProviders.length === 0) {
|
|
70
102
|
logWarn(HOOK, "No providers with available CLI found, falling back to Claude with agent defaults");
|
|
71
103
|
return agents.map(a => ({ ...a, provider: "claude" }));
|
|
72
104
|
}
|
|
73
105
|
|
|
106
|
+
// Assign all agents to the first (highest-priority) available provider
|
|
107
|
+
const [providerName, providerConfig] = enabledProviders[0]!;
|
|
108
|
+
logInfo(HOOK, `Using provider: ${providerName} (models: ${providerConfig.models.join(", ")})`);
|
|
109
|
+
|
|
74
110
|
return agents.map(agent => {
|
|
75
|
-
const idx = Math.floor(Math.random() * enabledProviders.length);
|
|
76
|
-
const entry = enabledProviders[idx];
|
|
77
|
-
if (!entry) return { ...agent, provider: "claude" };
|
|
78
|
-
const [providerName, providerConfig] = entry;
|
|
79
111
|
const modelIdx = Math.floor(Math.random() * providerConfig.models.length);
|
|
80
112
|
const model = providerConfig.models[modelIdx] ?? providerConfig.models[0] ?? agent.model;
|
|
81
113
|
return { ...agent, provider: providerName, model };
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preflight health checks for plan review agents.
|
|
3
|
+
* Validates provider+model combos work before committing agents to them.
|
|
4
|
+
* Runs minimal "ping" requests in parallel per unique provider:model combo.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { logInfo, logWarn, logDebug } from "../../../_shared/lib-ts/base/logger.js";
|
|
8
|
+
import { findExecutable, execFileAsync, getInternalSubprocessEnv } from "../../../_shared/lib-ts/base/subprocess-utils.js";
|
|
9
|
+
import type { ModelsConfig, PreflightCheckResult, PreflightReport } from "../../lib-ts/types.js";
|
|
10
|
+
import { claudePreflightArgs, CLAUDE_PREFLIGHT_INPUT } from "./reviewers/providers/claude-agent.js";
|
|
11
|
+
import { codexPreflightArgs, CODEX_PREFLIGHT_INPUT } from "./reviewers/providers/codex-agent.js";
|
|
12
|
+
|
|
13
|
+
const HOOK = "preflight";
|
|
14
|
+
const DEFAULT_TIMEOUT_MS = 15000;
|
|
15
|
+
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// Provider Registry
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
|
|
20
|
+
interface PreflightCommandConfig {
|
|
21
|
+
cliName: string;
|
|
22
|
+
buildArgs: (model: string) => string[];
|
|
23
|
+
input: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const PREFLIGHT_COMMANDS: Record<string, PreflightCommandConfig> = {
|
|
27
|
+
claude: { cliName: "claude", buildArgs: claudePreflightArgs, input: CLAUDE_PREFLIGHT_INPUT },
|
|
28
|
+
codex: { cliName: "codex", buildArgs: codexPreflightArgs, input: CODEX_PREFLIGHT_INPUT },
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
// Error Classification
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
|
|
35
|
+
function classifyError(stderr: string, exitCode: number | null, killed: boolean, signal: string | null): string {
|
|
36
|
+
if (killed || signal === "SIGTERM") return "Preflight timed out";
|
|
37
|
+
if (/model.*not found|not available/i.test(stderr)) return "Model not available for this account";
|
|
38
|
+
if (/rate limit|429/i.test(stderr)) return "Rate limited";
|
|
39
|
+
if (/auth|api key|401/i.test(stderr)) return "Authentication failed";
|
|
40
|
+
if (/quota|billing/i.test(stderr)) return "Quota/billing issue";
|
|
41
|
+
return `Exit code ${exitCode}`;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
// Single Check
|
|
46
|
+
// ---------------------------------------------------------------------------
|
|
47
|
+
|
|
48
|
+
async function checkProviderModel(
|
|
49
|
+
provider: string,
|
|
50
|
+
model: string,
|
|
51
|
+
timeoutMs: number,
|
|
52
|
+
): Promise<PreflightCheckResult> {
|
|
53
|
+
const config = PREFLIGHT_COMMANDS[provider];
|
|
54
|
+
if (!config) {
|
|
55
|
+
return { provider, model, available: false, latencyMs: 0, error: `Unknown provider: ${provider}` };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const cliPath = findExecutable(config.cliName);
|
|
59
|
+
if (!cliPath) {
|
|
60
|
+
return { provider, model, available: false, latencyMs: 0, error: `CLI '${config.cliName}' not found on PATH` };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const start = Date.now();
|
|
64
|
+
try {
|
|
65
|
+
const env = getInternalSubprocessEnv();
|
|
66
|
+
const result = await execFileAsync(cliPath, config.buildArgs(model), {
|
|
67
|
+
input: config.input,
|
|
68
|
+
timeout: timeoutMs,
|
|
69
|
+
env: env as Record<string, string>,
|
|
70
|
+
maxBuffer: 1 * 1024 * 1024,
|
|
71
|
+
shell: process.platform === "win32",
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const latencyMs = Date.now() - start;
|
|
75
|
+
|
|
76
|
+
if (result.killed || result.signal === "SIGTERM") {
|
|
77
|
+
return { provider, model, available: false, latencyMs, error: "Preflight timed out" };
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (result.exitCode !== 0) {
|
|
81
|
+
const error = classifyError(result.stderr, result.exitCode, result.killed, result.signal);
|
|
82
|
+
logWarn(HOOK, `${provider}:${model} failed: ${error} (stderr: ${result.stderr.slice(-200)})`);
|
|
83
|
+
return { provider, model, available: false, latencyMs, error };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
logDebug(HOOK, `${provider}:${model} passed (${latencyMs}ms)`);
|
|
87
|
+
return { provider, model, available: true, latencyMs };
|
|
88
|
+
} catch (err) {
|
|
89
|
+
const latencyMs = Date.now() - start;
|
|
90
|
+
const error = err instanceof Error ? err.message : String(err);
|
|
91
|
+
logWarn(HOOK, `${provider}:${model} exception: ${error}`);
|
|
92
|
+
return { provider, model, available: false, latencyMs, error };
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// ---------------------------------------------------------------------------
|
|
97
|
+
// Run All Checks
|
|
98
|
+
// ---------------------------------------------------------------------------
|
|
99
|
+
|
|
100
|
+
export async function runPreflight(
|
|
101
|
+
modelsConfig: ModelsConfig,
|
|
102
|
+
timeoutMs?: number,
|
|
103
|
+
): Promise<PreflightReport> {
|
|
104
|
+
const effectiveTimeout = timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
105
|
+
const start = Date.now();
|
|
106
|
+
|
|
107
|
+
// Collect unique provider:model combos from enabled providers
|
|
108
|
+
const checks: Array<{ provider: string; model: string }> = [];
|
|
109
|
+
const seen = new Set<string>();
|
|
110
|
+
|
|
111
|
+
for (const [provider, config] of Object.entries(modelsConfig.providers)) {
|
|
112
|
+
if (!config.enabled || config.models.length === 0) continue;
|
|
113
|
+
if (!PREFLIGHT_COMMANDS[provider]) {
|
|
114
|
+
logWarn(HOOK, `No preflight command for provider '${provider}', skipping`);
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
for (const model of config.models) {
|
|
118
|
+
const key = `${provider}:${model}`;
|
|
119
|
+
if (!seen.has(key)) {
|
|
120
|
+
seen.add(key);
|
|
121
|
+
checks.push({ provider, model });
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (checks.length === 0) {
|
|
127
|
+
logWarn(HOOK, "No provider:model combos to check");
|
|
128
|
+
return { checks: [], available: new Map(), allFailed: true, totalMs: Date.now() - start };
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
logInfo(HOOK, `Checking ${checks.length} provider:model combo(s): ${checks.map(c => `${c.provider}:${c.model}`).join(", ")}`);
|
|
132
|
+
|
|
133
|
+
// Run all checks in parallel
|
|
134
|
+
const results = await Promise.all(
|
|
135
|
+
checks.map(({ provider, model }) => checkProviderModel(provider, model, effectiveTimeout)),
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
// Build available map
|
|
139
|
+
const available = new Map<string, Set<string>>();
|
|
140
|
+
for (const r of results) {
|
|
141
|
+
if (r.available) {
|
|
142
|
+
if (!available.has(r.provider)) available.set(r.provider, new Set());
|
|
143
|
+
available.get(r.provider)!.add(r.model);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const allFailed = available.size === 0;
|
|
148
|
+
const totalMs = Date.now() - start;
|
|
149
|
+
|
|
150
|
+
// Log summary
|
|
151
|
+
const passed = results.filter(r => r.available).length;
|
|
152
|
+
const failed = results.filter(r => !r.available).length;
|
|
153
|
+
logInfo(HOOK, `Preflight complete: ${passed} passed, ${failed} failed (${totalMs}ms)`);
|
|
154
|
+
|
|
155
|
+
for (const r of results) {
|
|
156
|
+
if (!r.available) {
|
|
157
|
+
logWarn(HOOK, ` FAIL ${r.provider}:${r.model} — ${r.error}`);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return { checks: results, available, allFailed, totalMs };
|
|
162
|
+
}
|
|
@@ -8,6 +8,7 @@ import * as fs from "node:fs";
|
|
|
8
8
|
import * as path from "node:path";
|
|
9
9
|
|
|
10
10
|
import { resolveMandatoryAgents, assignModelsToAgents, selectAgents } from "./agent-selection.js";
|
|
11
|
+
import { runPreflight } from "./preflight.js";
|
|
11
12
|
import { computeCorroboratedDecision } from "./corroboration.js";
|
|
12
13
|
import { computePassEligible, extractTopIssuesForTracker, advanceIterationState } from "./graduation.js";
|
|
13
14
|
import { runOrchestrator } from "./orchestrator.js";
|
|
@@ -225,6 +226,28 @@ export async function runReviewPipeline(input: PipelineInput): Promise<PipelineR
|
|
|
225
226
|
const agentResults: Record<string, ReviewerResult> = {};
|
|
226
227
|
let detectedComplexity = "medium";
|
|
227
228
|
|
|
229
|
+
// Preflight: validate provider+model combos before committing agents or orchestrator
|
|
230
|
+
const preflightEnabled = (agentSettings.preflight as Record<string, unknown>)?.enabled ?? true;
|
|
231
|
+
let preflightAvailable: Map<string, Set<string>> | undefined;
|
|
232
|
+
|
|
233
|
+
if (preflightEnabled && agentReviewEnabled) {
|
|
234
|
+
logInfo(HOOK, "=== PREFLIGHT: Checking provider availability ===");
|
|
235
|
+
const preflightTimeoutMs = (agentSettings.preflight as Record<string, unknown>)?.timeoutMs as number | undefined;
|
|
236
|
+
const modelsConfig = loadModelsConfig(settings);
|
|
237
|
+
const preflightReport = await runPreflight(modelsConfig, preflightTimeoutMs);
|
|
238
|
+
|
|
239
|
+
if (preflightReport.allFailed) {
|
|
240
|
+
logWarn(HOOK, "All providers failed preflight checks");
|
|
241
|
+
// Preflight failures skip review rather than block because an unavailable
|
|
242
|
+
// reviewer is worse than no reviewer. A permanently broken config will
|
|
243
|
+
// silently pass all plans — mitigated by the log warnings above.
|
|
244
|
+
eprint("[plan-review] All AI providers unavailable. Skipping review.");
|
|
245
|
+
return { action: "skip", reason: "No AI providers passed preflight. Check CLI, API keys, model access, and quota." };
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
preflightAvailable = preflightReport.available;
|
|
249
|
+
}
|
|
250
|
+
|
|
228
251
|
// 7. PHASE 1: Orchestrator
|
|
229
252
|
const graduatedSet = new Set(iterationState.graduated);
|
|
230
253
|
if (graduatedSet.size > 0) {
|
|
@@ -254,10 +277,20 @@ export async function runReviewPipeline(input: PipelineInput): Promise<PipelineR
|
|
|
254
277
|
const phase1Promises: Array<{ name: string; promise: Promise<ReviewerResult | OrchestratorResult> }> = [];
|
|
255
278
|
|
|
256
279
|
if (orchestratorConfig.enabled && enabledAgents.length > 0 && !legacyMode) {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
280
|
+
// Guard orchestrator against preflight failures (always uses claude provider)
|
|
281
|
+
const orchProvider = "claude";
|
|
282
|
+
const orchModel = orchestratorConfig.model;
|
|
283
|
+
const orchPassed = !preflightAvailable ||
|
|
284
|
+
(preflightAvailable.has(orchProvider) && preflightAvailable.get(orchProvider)!.has(orchModel));
|
|
285
|
+
|
|
286
|
+
if (!orchPassed) {
|
|
287
|
+
logWarn(HOOK, `Orchestrator model ${orchProvider}:${orchModel} failed preflight, skipping`);
|
|
288
|
+
} else {
|
|
289
|
+
phase1Promises.push({
|
|
290
|
+
name: "orchestrator",
|
|
291
|
+
promise: runOrchestrator(plan, enabledAgents, orchestratorConfig, agentSettings, alwaysMandatory),
|
|
292
|
+
});
|
|
293
|
+
}
|
|
261
294
|
}
|
|
262
295
|
|
|
263
296
|
logInfo(HOOK, `=== PHASE 1: Running ${phase1Promises.length} tasks in parallel ===`);
|
|
@@ -318,9 +351,9 @@ export async function runReviewPipeline(input: PipelineInput): Promise<PipelineR
|
|
|
318
351
|
iterationState.max = reviewIterations[detectedComplexity] ?? iterationState.max;
|
|
319
352
|
logDebug(HOOK, `Iteration state: ${iterationState.current}/${iterationState.max} (${detectedComplexity})`);
|
|
320
353
|
|
|
321
|
-
// Assign
|
|
354
|
+
// Assign providers + models (filtered by preflight results if available)
|
|
322
355
|
const modelsConfig = loadModelsConfig(settings);
|
|
323
|
-
selectedAgents = assignModelsToAgents(selectedAgents, modelsConfig);
|
|
356
|
+
selectedAgents = assignModelsToAgents(selectedAgents, modelsConfig, preflightAvailable);
|
|
324
357
|
logInfo(HOOK, `Model assignments: ${selectedAgents.map(a => `${a.name}→${a.provider}:${a.model}`).join(", ")}`);
|
|
325
358
|
|
|
326
359
|
// 9. PHASE 3: Run agents
|
package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/providers/claude-agent.ts
CHANGED
|
@@ -15,6 +15,27 @@ import { makeResult } from "../types.js";
|
|
|
15
15
|
* Claude CLI-based agent reviewer.
|
|
16
16
|
* Extends BaseCliAgent with Claude-specific prompt and argument handling.
|
|
17
17
|
*/
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// Preflight (standalone — no instance needed)
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
|
|
22
|
+
export const CLAUDE_PREFLIGHT_INPUT = "Respond with exactly: ok";
|
|
23
|
+
|
|
24
|
+
export function claudePreflightArgs(model: string): string[] {
|
|
25
|
+
return [
|
|
26
|
+
"--model", model,
|
|
27
|
+
"--max-turns", "1",
|
|
28
|
+
"--output-format", "json",
|
|
29
|
+
"--setting-sources", process.platform === "win32" ? '""' : "",
|
|
30
|
+
"-p",
|
|
31
|
+
"--no-session-persistence",
|
|
32
|
+
];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
// Agent Class
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
|
|
18
39
|
export class ClaudeAgent extends BaseCliAgent<ReviewerResult> {
|
|
19
40
|
protected buildCliArgs(): string[] {
|
|
20
41
|
const schemaJson = JSON.stringify(this.schema);
|
package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/providers/codex-agent.ts
CHANGED
|
@@ -16,6 +16,20 @@ import { BaseCliAgent, type ExecResult } from "../base/base-agent.js";
|
|
|
16
16
|
import { AGENT_REVIEW_PROMPT_PREFIX } from "../schemas.js";
|
|
17
17
|
import { makeResult } from "../types.js";
|
|
18
18
|
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
// Preflight (standalone — no instance needed)
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
|
|
23
|
+
export const CODEX_PREFLIGHT_INPUT = "Respond with exactly: ok";
|
|
24
|
+
|
|
25
|
+
export function codexPreflightArgs(model: string): string[] {
|
|
26
|
+
return ["exec", "--sandbox", "read-only", "--model", model, "-"];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// Agent Class
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
|
|
19
33
|
/** Temp directory for Codex schema/output files */
|
|
20
34
|
const _tmpDir: string | null = null;
|
|
21
35
|
|
package/oclif.manifest.json
CHANGED