@open-agent-toolkit/cli 0.1.66 → 0.1.72
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/assets/agents/oat-reviewer.md +0 -1
- package/assets/docs/cli-utilities/configuration.md +27 -0
- package/assets/docs/cli-utilities/index.md +1 -1
- package/assets/docs/cli-utilities/workflow-gates.md +147 -5
- package/assets/docs/reference/cli-reference.md +5 -1
- package/assets/docs/workflows/projects/dispatch-ceiling.md +25 -8
- package/assets/docs/workflows/projects/orchestration-model.md +21 -0
- package/assets/docs/workflows/projects/pr-flow.md +12 -1
- package/assets/docs/workflows/projects/review-flavors.md +9 -0
- package/assets/docs/workflows/projects/reviews.md +21 -1
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/oat-dispatch-subagents/SKILL.md +21 -1
- package/assets/skills/oat-dispatch-subagents/references/provider-claude.md +21 -0
- package/assets/skills/oat-dispatch-subagents/references/provider-codex.md +16 -0
- package/assets/skills/oat-dispatch-subagents/references/provider-cursor.md +21 -0
- package/assets/skills/oat-project-autonomous/SKILL.md +1 -1
- package/assets/skills/oat-project-autonomous/references/gate-inventory.md +5 -2
- package/assets/skills/oat-project-complete/SKILL.md +20 -2
- package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +5 -2
- package/assets/skills/oat-project-implement/SKILL.md +1 -1
- package/assets/skills/oat-project-implement/references/completion-and-closeout.md +12 -1
- package/assets/skills/oat-project-implement/references/dispatch-and-dry-run.md +24 -9
- package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +5 -2
- package/assets/skills/oat-project-implement/references/phase-execution.md +5 -2
- package/assets/skills/oat-project-next/SKILL.md +21 -6
- package/assets/skills/oat-project-plan/SKILL.md +6 -1
- package/assets/skills/oat-project-plan-writing/SKILL.md +41 -34
- package/assets/skills/oat-project-pr-final/SKILL.md +20 -5
- package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +5 -2
- package/assets/skills/oat-project-pr-progress/SKILL.md +18 -3
- package/assets/skills/oat-project-progress/SKILL.md +4 -1
- package/assets/skills/oat-project-quick-start/SKILL.md +6 -1
- package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +5 -2
- package/assets/skills/oat-project-review-provide/SKILL.md +68 -2
- package/assets/skills/oat-project-review-receive/SKILL.md +46 -18
- package/assets/skills/oat-project-review-receive-remote/SKILL.md +41 -8
- package/dist/commands/cleanup/project/project.utils.d.ts.map +1 -1
- package/dist/commands/cleanup/project/project.utils.js +19 -1
- package/dist/commands/config/index.d.ts.map +1 -1
- package/dist/commands/config/index.js +65 -1
- package/dist/commands/gate/__fixtures__/fake-runtime.d.mts +3 -0
- package/dist/commands/gate/__fixtures__/fake-runtime.d.mts.map +1 -0
- package/dist/commands/gate/__fixtures__/fake-runtime.mjs +167 -0
- package/dist/commands/gate/activity-probes.d.ts +35 -0
- package/dist/commands/gate/activity-probes.d.ts.map +1 -0
- package/dist/commands/gate/activity-probes.js +135 -0
- package/dist/commands/gate/branch-local-cli.d.ts +31 -0
- package/dist/commands/gate/branch-local-cli.d.ts.map +1 -0
- package/dist/commands/gate/branch-local-cli.js +116 -0
- package/dist/commands/gate/index.d.ts +31 -0
- package/dist/commands/gate/index.d.ts.map +1 -1
- package/dist/commands/gate/index.js +465 -31
- package/dist/commands/gate/route.d.ts +22 -0
- package/dist/commands/gate/route.d.ts.map +1 -0
- package/dist/commands/gate/route.js +109 -0
- package/dist/commands/project/dispatch-ceiling/index.d.ts.map +1 -1
- package/dist/commands/project/dispatch-ceiling/index.js +100 -16
- package/dist/commands/review/latest.d.ts +1 -0
- package/dist/commands/review/latest.d.ts.map +1 -1
- package/dist/commands/review/latest.js +96 -22
- package/dist/config/oat-config.d.ts +9 -0
- package/dist/config/oat-config.d.ts.map +1 -1
- package/dist/config/oat-config.js +23 -0
- package/dist/config/resolve.js +7 -0
- package/package.json +2 -2
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { CommandContext, GlobalOptions } from '../../app/command-context.js';
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
export type GateRoute = 'inline' | 'delegate-sync' | 'refuse';
|
|
4
|
+
export interface GateRouteDecision {
|
|
5
|
+
route: GateRoute;
|
|
6
|
+
reason: string;
|
|
7
|
+
}
|
|
8
|
+
interface GateRouteInput {
|
|
9
|
+
expectRuntime: string;
|
|
10
|
+
expectModel: string;
|
|
11
|
+
canAwait: boolean;
|
|
12
|
+
env: NodeJS.ProcessEnv;
|
|
13
|
+
}
|
|
14
|
+
interface GateRouteCommandDependencies {
|
|
15
|
+
processEnv: NodeJS.ProcessEnv;
|
|
16
|
+
buildCommandContext: (options: GlobalOptions) => CommandContext;
|
|
17
|
+
cliRoot?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function resolveGateRoute(input: GateRouteInput): GateRouteDecision;
|
|
20
|
+
export declare function createGateRouteCommand(dependencies: GateRouteCommandDependencies): Command;
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=route.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../src/commands/gate/route.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1E,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,eAAe,GAAG,QAAQ,CAAC;AAE9D,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,SAAS,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,cAAc;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;CACxB;AAED,UAAU,4BAA4B;IACpC,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC;IAC9B,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,cAAc,CAAC;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAkCD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,GAAG,iBAAiB,CAyDzE;AAoBD,wBAAgB,sBAAsB,CACpC,YAAY,EAAE,4BAA4B,GACzC,OAAO,CAgDT"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { writeFileSync } from 'node:fs';
|
|
2
|
+
import { readGlobalOptions } from '../shared/shared.utils.js';
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import { currentGateCliRoot } from './branch-local-cli.js';
|
|
5
|
+
const PROVIDER_MARKERS = [
|
|
6
|
+
{ runtime: 'claude', keys: ['CLAUDECODE'] },
|
|
7
|
+
{ runtime: 'cursor', keys: ['CURSOR_AGENT'] },
|
|
8
|
+
{ runtime: 'codex', keys: ['CODEX_THREAD_ID', 'CODEX_SESSION_ID'] },
|
|
9
|
+
];
|
|
10
|
+
const PROVIDER_MODEL_EVIDENCE_KEYS = {
|
|
11
|
+
claude: ['ANTHROPIC_MODEL', 'CLAUDE_MODEL'],
|
|
12
|
+
cursor: ['CURSOR_MODEL'],
|
|
13
|
+
codex: ['CODEX_MODEL'],
|
|
14
|
+
};
|
|
15
|
+
function nonEmptyEnvValue(env, key) {
|
|
16
|
+
const value = env[key]?.trim();
|
|
17
|
+
return value ? value : undefined;
|
|
18
|
+
}
|
|
19
|
+
function fallbackRoute(canAwait, reason) {
|
|
20
|
+
return canAwait
|
|
21
|
+
? { route: 'delegate-sync', reason }
|
|
22
|
+
: { route: 'refuse', reason };
|
|
23
|
+
}
|
|
24
|
+
export function resolveGateRoute(input) {
|
|
25
|
+
const expectedRuntime = input.expectRuntime.trim().toLowerCase();
|
|
26
|
+
const expectedModel = input.expectModel.trim();
|
|
27
|
+
const activeMarkers = PROVIDER_MARKERS.flatMap(({ keys, runtime }) => {
|
|
28
|
+
const activeKeys = keys.filter((key) => nonEmptyEnvValue(input.env, key));
|
|
29
|
+
return activeKeys.length > 0 ? [{ keys: activeKeys, runtime }] : [];
|
|
30
|
+
});
|
|
31
|
+
const expectedRuntimeMarker = activeMarkers.find(({ runtime }) => runtime === expectedRuntime);
|
|
32
|
+
if (!expectedRuntimeMarker && activeMarkers.length !== 1) {
|
|
33
|
+
return fallbackRoute(input.canAwait, activeMarkers.length === 0
|
|
34
|
+
? 'No provider runtime marker is available; inline reviewer identity is ambiguous.'
|
|
35
|
+
: `Multiple provider runtime markers are present (${activeMarkers.flatMap(({ keys }) => keys).join(', ')}), but none identifies expected runtime ${expectedRuntime}.`);
|
|
36
|
+
}
|
|
37
|
+
if (!expectedRuntimeMarker) {
|
|
38
|
+
const activeRuntime = activeMarkers[0].runtime;
|
|
39
|
+
return fallbackRoute(input.canAwait, `Provider runtime marker identifies ${activeRuntime}, not expected runtime ${expectedRuntime}.`);
|
|
40
|
+
}
|
|
41
|
+
const providerModelEvidenceKeys = expectedRuntime in PROVIDER_MODEL_EVIDENCE_KEYS
|
|
42
|
+
? PROVIDER_MODEL_EVIDENCE_KEYS[expectedRuntime]
|
|
43
|
+
: [];
|
|
44
|
+
const modelEvidence = providerModelEvidenceKeys.flatMap((key) => {
|
|
45
|
+
const value = nonEmptyEnvValue(input.env, key);
|
|
46
|
+
return value ? [{ key, value }] : [];
|
|
47
|
+
});
|
|
48
|
+
const enforceExpectedModel = expectedModel !== 'unknown' && expectedModel !== 'provider-default';
|
|
49
|
+
const contradictoryModel = enforceExpectedModel
|
|
50
|
+
? modelEvidence.find(({ value }) => value !== expectedModel)
|
|
51
|
+
: undefined;
|
|
52
|
+
if (contradictoryModel) {
|
|
53
|
+
return fallbackRoute(input.canAwait, `Model evidence ${contradictoryModel.key}=${contradictoryModel.value} contradicts expected model ${expectedModel}.`);
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
route: 'inline',
|
|
57
|
+
reason: modelEvidence.length > 0
|
|
58
|
+
? `Provider runtime marker matches expected runtime ${expectedRuntime}; available model evidence matches ${expectedModel}.`
|
|
59
|
+
: `Provider runtime marker matches expected runtime ${expectedRuntime}; model evidence is unavailable.`,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function parseRequiredOption(value, name) {
|
|
63
|
+
const parsed = value?.trim();
|
|
64
|
+
if (!parsed) {
|
|
65
|
+
throw new Error(`${name} must be a non-empty string.`);
|
|
66
|
+
}
|
|
67
|
+
return parsed;
|
|
68
|
+
}
|
|
69
|
+
function parseCanAwait(value) {
|
|
70
|
+
if (value === 'true') {
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
if (value === 'false') {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
throw new Error('--can-await must be true or false.');
|
|
77
|
+
}
|
|
78
|
+
export function createGateRouteCommand(dependencies) {
|
|
79
|
+
return new Command('route')
|
|
80
|
+
.description('Choose a headless-safe reviewer execution route')
|
|
81
|
+
.requiredOption('--expect-runtime <runtime>', 'Expected reviewer runtime from gate invocation metadata')
|
|
82
|
+
.requiredOption('--expect-model <model>', 'Expected reviewer model from gate invocation metadata')
|
|
83
|
+
.requiredOption('--can-await <boolean>', 'Whether the host can synchronously await a delegated reviewer')
|
|
84
|
+
.option('--json', 'Print the route decision as JSON')
|
|
85
|
+
.action((options, command) => {
|
|
86
|
+
const context = dependencies.buildCommandContext(readGlobalOptions(command));
|
|
87
|
+
const expectedRuntime = parseRequiredOption(options.expectRuntime, '--expect-runtime');
|
|
88
|
+
const decision = resolveGateRoute({
|
|
89
|
+
expectRuntime: expectedRuntime,
|
|
90
|
+
expectModel: parseRequiredOption(options.expectModel, '--expect-model'),
|
|
91
|
+
canAwait: parseCanAwait(options.canAwait),
|
|
92
|
+
env: dependencies.processEnv,
|
|
93
|
+
});
|
|
94
|
+
if (context.json) {
|
|
95
|
+
const envelope = {
|
|
96
|
+
...decision,
|
|
97
|
+
cliRoot: dependencies.cliRoot ?? currentGateCliRoot(),
|
|
98
|
+
};
|
|
99
|
+
const receiptPath = dependencies.processEnv.OAT_GATE_ROUTE_RECEIPT_PATH;
|
|
100
|
+
if (receiptPath) {
|
|
101
|
+
writeFileSync(receiptPath, `${JSON.stringify({ ...envelope, runtime: expectedRuntime })}\n`, { mode: 0o600 });
|
|
102
|
+
}
|
|
103
|
+
context.logger.json(envelope);
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
context.logger.info(`${decision.route}: ${decision.reason}`);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/dispatch-ceiling/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAa9B,OAAO,EAUL,KAAK,uBAAuB,EAY7B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEL,KAAK,cAAc,EAEpB,MAAM,iBAAiB,CAAC;AAsBzB,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAiC5C,UAAU,2BAA2B;IACnC,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,cAAc,CAAC;IAChE,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,sBAAsB,EAAE,CACtB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,GAAG,EAAE,MAAM,CAAC,UAAU,KACnB,OAAO,CAAC,cAAc,CAAC,CAAC;IAC7B,oBAAoB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAC7E,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5C,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC;CAC/B;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/dispatch-ceiling/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAa9B,OAAO,EAUL,KAAK,uBAAuB,EAY7B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEL,KAAK,cAAc,EAEpB,MAAM,iBAAiB,CAAC;AAsBzB,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAiC5C,UAAU,2BAA2B;IACnC,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,cAAc,CAAC;IAChE,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,sBAAsB,EAAE,CACtB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,GAAG,EAAE,MAAM,CAAC,UAAU,KACnB,OAAO,CAAC,cAAc,CAAC,CAAC;IAC7B,oBAAoB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAC7E,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5C,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC;CAC/B;AAqmFD,wBAAgB,mCAAmC,CACjD,SAAS,GAAE,OAAO,CAAC,2BAA2B,CAAM,GACnD,OAAO,CAkGT"}
|
|
@@ -1243,9 +1243,58 @@ async function resolveCodexProviderDefaultEffort(repoRoot, context, dependencies
|
|
|
1243
1243
|
}
|
|
1244
1244
|
return 'unknown';
|
|
1245
1245
|
}
|
|
1246
|
-
function
|
|
1247
|
-
const
|
|
1248
|
-
|
|
1246
|
+
function mergeEffectiveDispatchMatrix(resolvedConfig) {
|
|
1247
|
+
const merged = {};
|
|
1248
|
+
const layers = [
|
|
1249
|
+
resolvedConfig.user.workflow?.dispatchCeiling?.providers,
|
|
1250
|
+
resolvedConfig.shared.workflow?.dispatchCeiling?.providers,
|
|
1251
|
+
resolvedConfig.local.workflow?.dispatchCeiling?.providers,
|
|
1252
|
+
];
|
|
1253
|
+
for (const providers of layers) {
|
|
1254
|
+
for (const [provider, value] of Object.entries(providers ?? {})) {
|
|
1255
|
+
const previous = merged[provider];
|
|
1256
|
+
merged[provider] =
|
|
1257
|
+
typeof value === 'object' &&
|
|
1258
|
+
value !== null &&
|
|
1259
|
+
!Array.isArray(value) &&
|
|
1260
|
+
typeof previous === 'object' &&
|
|
1261
|
+
previous !== null &&
|
|
1262
|
+
!Array.isArray(previous)
|
|
1263
|
+
? { ...previous, ...value }
|
|
1264
|
+
: value;
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
return merged;
|
|
1268
|
+
}
|
|
1269
|
+
function inspectLadderCompleteness(matrix) {
|
|
1270
|
+
const missingCells = [];
|
|
1271
|
+
for (const provider of ['codex', 'claude', 'cursor']) {
|
|
1272
|
+
const providerValue = matrix[provider];
|
|
1273
|
+
for (const tier of VALID_DISPATCH_MATRIX_TIERS) {
|
|
1274
|
+
const cell = typeof providerValue === 'object' &&
|
|
1275
|
+
providerValue !== null &&
|
|
1276
|
+
!Array.isArray(providerValue)
|
|
1277
|
+
? providerValue[tier]
|
|
1278
|
+
: undefined;
|
|
1279
|
+
if (cell === undefined ||
|
|
1280
|
+
!isWorkflowDispatchCandidateLadder(cell) ||
|
|
1281
|
+
cell.candidates.length === 0) {
|
|
1282
|
+
missingCells.push(`${provider}.${tier}`);
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
return { complete: missingCells.length === 0, missingCells };
|
|
1287
|
+
}
|
|
1288
|
+
function unresolvedMessage(reason, missingCells) {
|
|
1289
|
+
const policyFix = 'set `oat_dispatch_policy` in project state (normally at plan time) or select Inherit Host Defaults';
|
|
1290
|
+
const ladderFix = `adopt a dispatch matrix${missingCells.length > 0 ? `; missing cells: ${missingCells.join(', ')}` : ''}`;
|
|
1291
|
+
if (reason === 'policy') {
|
|
1292
|
+
return `BLOCKED: project dispatch policy is unresolved; ${policyFix}.`;
|
|
1293
|
+
}
|
|
1294
|
+
if (reason === 'ladder') {
|
|
1295
|
+
return `BLOCKED: dispatch ladder is unresolved; ${ladderFix}.`;
|
|
1296
|
+
}
|
|
1297
|
+
return `BLOCKED: project dispatch policy and dispatch ladder are unresolved; ${policyFix}; ${ladderFix}.`;
|
|
1249
1298
|
}
|
|
1250
1299
|
function isNonInteractiveEnv(env) {
|
|
1251
1300
|
return env['OAT_NON_INTERACTIVE'] === '1';
|
|
@@ -1260,6 +1309,9 @@ async function resolveDispatchCeiling(context, dependencies, options) {
|
|
|
1260
1309
|
dependencies.resolveEffectiveConfig(repoRoot, userConfigDir, dependencies.processEnv),
|
|
1261
1310
|
resolveProjectPath(repoRoot, dependencies, options),
|
|
1262
1311
|
]);
|
|
1312
|
+
const effectiveMatrix = mergeEffectiveDispatchMatrix(resolvedConfig);
|
|
1313
|
+
const ladderCompleteness = inspectLadderCompleteness(effectiveMatrix);
|
|
1314
|
+
const reportedMatrix = Object.keys(effectiveMatrix).length > 0 ? effectiveMatrix : null;
|
|
1263
1315
|
const providerDefaultEffort = provider === 'codex'
|
|
1264
1316
|
? await resolveCodexProviderDefaultEffort(repoRoot, context, dependencies)
|
|
1265
1317
|
: 'not-applicable';
|
|
@@ -1267,6 +1319,8 @@ async function resolveDispatchCeiling(context, dependencies, options) {
|
|
|
1267
1319
|
const preferredValue = normalizePreferredValue(provider, options.preferred);
|
|
1268
1320
|
const ceilingTier = normalizeCeilingTier(options.ceilingTier, role);
|
|
1269
1321
|
const escalationLevel = normalizeEscalationLevel(options.escalationLevel);
|
|
1322
|
+
const policyResolution = readResolvedConfigCeiling(provider, resolvedConfig) ??
|
|
1323
|
+
(await resolveProjectStateCeiling(provider, projectPath, dependencies));
|
|
1270
1324
|
const resolvedValue = await resolveCeilingValue(provider, resolvedConfig, projectPath, dependencies, escalationLevel, role, preferredValue, requestedCandidate, ceilingTier);
|
|
1271
1325
|
for (const warning of resolvedValue?.warnings ?? []) {
|
|
1272
1326
|
context.logger.warn(warning);
|
|
@@ -1299,21 +1353,35 @@ async function resolveDispatchCeiling(context, dependencies, options) {
|
|
|
1299
1353
|
projectPath,
|
|
1300
1354
|
providerDefaultEffort,
|
|
1301
1355
|
matrix: resolvedValue.matrix,
|
|
1356
|
+
ladderCompleteness,
|
|
1302
1357
|
providers,
|
|
1303
1358
|
message: managedCodexDepthBlockMessage(scope, depth),
|
|
1304
1359
|
};
|
|
1305
1360
|
}
|
|
1306
1361
|
}
|
|
1362
|
+
const activeTier = policyTier(resolvedValue.policy);
|
|
1363
|
+
const activeCell = activeTier
|
|
1364
|
+
? resolveProviderMatrixCellDefinition(provider, activeTier, resolvedConfig, resolvedValue.matrix)
|
|
1365
|
+
: null;
|
|
1366
|
+
const activeLadderMissing = options.preflight === true &&
|
|
1367
|
+
resolvedValue.mode === 'managed' &&
|
|
1368
|
+
activeTier !== null &&
|
|
1369
|
+
(activeCell === null ||
|
|
1370
|
+
!isWorkflowDispatchCandidateLadder(activeCell.cell) ||
|
|
1371
|
+
activeCell.cell.candidates.length === 0);
|
|
1307
1372
|
const incompleteManagedPreflight = options.preflight === true &&
|
|
1308
1373
|
resolvedValue.mode === 'managed' &&
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1374
|
+
(activeLadderMissing ||
|
|
1375
|
+
(providerResolution.mode === 'advisory' &&
|
|
1376
|
+
providerResolution.selection.target?.crossHarness !== true &&
|
|
1377
|
+
providerResolution.selection.selectionMode !== 'no-review-target'));
|
|
1312
1378
|
if (incompleteManagedPreflight) {
|
|
1313
1379
|
const shouldBlock = options.nonInteractive === true ||
|
|
1314
1380
|
isNonInteractiveEnv(dependencies.processEnv) ||
|
|
1315
1381
|
(!context.interactive && !context.json);
|
|
1316
|
-
const message = shouldBlock
|
|
1382
|
+
const message = shouldBlock
|
|
1383
|
+
? unresolvedMessage('ladder', ladderCompleteness.missingCells)
|
|
1384
|
+
: undefined;
|
|
1317
1385
|
return {
|
|
1318
1386
|
status: shouldBlock ? 'blocked' : 'unresolved',
|
|
1319
1387
|
provider,
|
|
@@ -1325,7 +1393,11 @@ async function resolveDispatchCeiling(context, dependencies, options) {
|
|
|
1325
1393
|
unresolved: true,
|
|
1326
1394
|
projectPath,
|
|
1327
1395
|
providerDefaultEffort,
|
|
1328
|
-
matrix: resolvedValue.matrixCompatibility ??
|
|
1396
|
+
matrix: resolvedValue.matrixCompatibility ??
|
|
1397
|
+
resolvedValue.matrix ??
|
|
1398
|
+
reportedMatrix,
|
|
1399
|
+
ladderCompleteness,
|
|
1400
|
+
unresolvedReason: 'ladder',
|
|
1329
1401
|
providers,
|
|
1330
1402
|
message,
|
|
1331
1403
|
};
|
|
@@ -1341,26 +1413,38 @@ async function resolveDispatchCeiling(context, dependencies, options) {
|
|
|
1341
1413
|
unresolved: false,
|
|
1342
1414
|
projectPath,
|
|
1343
1415
|
providerDefaultEffort,
|
|
1344
|
-
matrix: resolvedValue.matrixCompatibility ??
|
|
1416
|
+
matrix: resolvedValue.matrixCompatibility ??
|
|
1417
|
+
resolvedValue.matrix ??
|
|
1418
|
+
reportedMatrix,
|
|
1419
|
+
ladderCompleteness,
|
|
1345
1420
|
providers,
|
|
1346
1421
|
};
|
|
1347
1422
|
}
|
|
1348
1423
|
const shouldBlock = options.nonInteractive === true ||
|
|
1349
1424
|
isNonInteractiveEnv(dependencies.processEnv) ||
|
|
1350
1425
|
(options.preflight === true && !context.interactive && !context.json);
|
|
1351
|
-
const
|
|
1426
|
+
const unresolvedReason = policyResolution
|
|
1427
|
+
? 'ladder'
|
|
1428
|
+
: ladderCompleteness.complete
|
|
1429
|
+
? 'policy'
|
|
1430
|
+
: 'both';
|
|
1431
|
+
const message = shouldBlock
|
|
1432
|
+
? unresolvedMessage(unresolvedReason, ladderCompleteness.missingCells)
|
|
1433
|
+
: undefined;
|
|
1352
1434
|
return {
|
|
1353
1435
|
status: shouldBlock ? 'blocked' : 'unresolved',
|
|
1354
1436
|
provider,
|
|
1355
|
-
value: null,
|
|
1356
|
-
policyMode: null,
|
|
1357
|
-
policy: null,
|
|
1358
|
-
source: null,
|
|
1359
|
-
preset: null,
|
|
1437
|
+
value: policyResolution?.value ?? null,
|
|
1438
|
+
policyMode: policyResolution?.mode ?? null,
|
|
1439
|
+
policy: policyResolution?.policy ?? null,
|
|
1440
|
+
source: policyResolution?.source ?? null,
|
|
1441
|
+
preset: policyResolution?.preset ?? null,
|
|
1360
1442
|
unresolved: true,
|
|
1361
1443
|
projectPath,
|
|
1362
1444
|
providerDefaultEffort,
|
|
1363
|
-
matrix:
|
|
1445
|
+
matrix: reportedMatrix,
|
|
1446
|
+
ladderCompleteness,
|
|
1447
|
+
unresolvedReason,
|
|
1364
1448
|
providers,
|
|
1365
1449
|
message,
|
|
1366
1450
|
};
|
|
@@ -13,6 +13,7 @@ export interface LatestReview {
|
|
|
13
13
|
export interface FindLatestReviewOptions {
|
|
14
14
|
repoRoot: string;
|
|
15
15
|
projectPath?: string | null;
|
|
16
|
+
actionableProjectOnly?: boolean;
|
|
16
17
|
}
|
|
17
18
|
interface ReviewLatestDependencies {
|
|
18
19
|
buildCommandContext: (options: GlobalOptions) => CommandContext;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"latest.d.ts","sourceRoot":"","sources":["../../../src/commands/review/latest.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAO9B,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAE7E,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,OAAO,CAAC;AAEnD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,gBAAgB,CAAC;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;CACrB;
|
|
1
|
+
{"version":3,"file":"latest.d.ts","sourceRoot":"","sources":["../../../src/commands/review/latest.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAO9B,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAE7E,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,OAAO,CAAC;AAEnD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,gBAAgB,CAAC;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;CACrB;AASD,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,UAAU,wBAAwB;IAChC,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,cAAc,CAAC;IAChE,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;CACnE;AAgOD,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAkG9B;AAmDD,wBAAgB,yBAAyB,CACvC,SAAS,GAAE,OAAO,CAAC,wBAAwB,CAAM,GAChD,OAAO,CA2BT"}
|
|
@@ -77,9 +77,11 @@ async function readReviewCandidate(repoRoot, relativePath, kind, priority, archi
|
|
|
77
77
|
return null;
|
|
78
78
|
}
|
|
79
79
|
const scope = getFrontmatterField(frontmatter, 'oat_review_scope') ?? '';
|
|
80
|
+
const reviewType = getFrontmatterField(frontmatter, 'oat_review_type') ?? 'code';
|
|
80
81
|
return {
|
|
81
82
|
path: relativePath,
|
|
82
83
|
scope,
|
|
84
|
+
reviewType,
|
|
83
85
|
generatedAt,
|
|
84
86
|
kind,
|
|
85
87
|
archived,
|
|
@@ -89,6 +91,62 @@ async function readReviewCandidate(repoRoot, relativePath, kind, priority, archi
|
|
|
89
91
|
priority,
|
|
90
92
|
};
|
|
91
93
|
}
|
|
94
|
+
function parseReviewLedgerEvents(planContent) {
|
|
95
|
+
const heading = /^## Reviews[ \t]*\r?$/m.exec(planContent);
|
|
96
|
+
if (!heading) {
|
|
97
|
+
return [];
|
|
98
|
+
}
|
|
99
|
+
const remaining = planContent.slice(heading.index + heading[0].length);
|
|
100
|
+
const nextHeadingIndex = remaining.search(/^##(?!#)[ \t]+\S.*\r?$/m);
|
|
101
|
+
const section = nextHeadingIndex === -1 ? remaining : remaining.slice(0, nextHeadingIndex);
|
|
102
|
+
return section
|
|
103
|
+
.split('\n')
|
|
104
|
+
.filter((line) => line.trim().startsWith('|'))
|
|
105
|
+
.slice(2)
|
|
106
|
+
.map((line) => line
|
|
107
|
+
.split('|')
|
|
108
|
+
.slice(1, -1)
|
|
109
|
+
.map((cell) => cell.trim()))
|
|
110
|
+
.filter((cells) => cells.length === 5)
|
|
111
|
+
.map(([scope = '', type = '', status = '', , artifact = '']) => ({
|
|
112
|
+
scope,
|
|
113
|
+
type,
|
|
114
|
+
status,
|
|
115
|
+
artifact,
|
|
116
|
+
}));
|
|
117
|
+
}
|
|
118
|
+
async function correlateProjectActionability(repoRoot, projectPath, candidates) {
|
|
119
|
+
let planContent;
|
|
120
|
+
try {
|
|
121
|
+
planContent = await readFile(join(repoRoot, projectPath, 'plan.md'), 'utf8');
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
if (typeof error === 'object' &&
|
|
125
|
+
error !== null &&
|
|
126
|
+
'code' in error &&
|
|
127
|
+
error.code === 'ENOENT') {
|
|
128
|
+
return candidates;
|
|
129
|
+
}
|
|
130
|
+
throw error;
|
|
131
|
+
}
|
|
132
|
+
const events = parseReviewLedgerEvents(planContent);
|
|
133
|
+
if (events.length === 0) {
|
|
134
|
+
return candidates;
|
|
135
|
+
}
|
|
136
|
+
return candidates.map((candidate) => {
|
|
137
|
+
if (candidate.kind !== 'project' || candidate.archived) {
|
|
138
|
+
return candidate;
|
|
139
|
+
}
|
|
140
|
+
const artifact = normalizeToPosixPath(relative(projectPath, candidate.path));
|
|
141
|
+
const matchingEvent = events.find((event) => event.scope.toLowerCase() === candidate.scope.toLowerCase() &&
|
|
142
|
+
event.type.toLowerCase() === candidate.reviewType.toLowerCase() &&
|
|
143
|
+
normalizeToPosixPath(event.artifact) === artifact);
|
|
144
|
+
return {
|
|
145
|
+
...candidate,
|
|
146
|
+
actionable: matchingEvent?.status.toLowerCase() === 'received',
|
|
147
|
+
};
|
|
148
|
+
});
|
|
149
|
+
}
|
|
92
150
|
function sortReviewCandidates(a, b) {
|
|
93
151
|
if (a.generatedTime !== b.generatedTime) {
|
|
94
152
|
return b.generatedTime - a.generatedTime;
|
|
@@ -116,34 +174,45 @@ export async function findLatestReview(options) {
|
|
|
116
174
|
priority: 0,
|
|
117
175
|
archived: false,
|
|
118
176
|
actionable: true,
|
|
177
|
+
});
|
|
178
|
+
if (!options.actionableProjectOnly) {
|
|
179
|
+
scanTargets.push({
|
|
180
|
+
dir: `${projectPath}/reviews/archived`,
|
|
181
|
+
kind: 'project',
|
|
182
|
+
priority: 1,
|
|
183
|
+
archived: true,
|
|
184
|
+
actionable: false,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (!options.actionableProjectOnly) {
|
|
189
|
+
scanTargets.push({
|
|
190
|
+
dir: '.oat/repo/reviews',
|
|
191
|
+
kind: 'adhoc',
|
|
192
|
+
priority: 2,
|
|
193
|
+
archived: false,
|
|
194
|
+
actionable: true,
|
|
119
195
|
}, {
|
|
120
|
-
dir:
|
|
121
|
-
kind: '
|
|
122
|
-
priority:
|
|
123
|
-
archived:
|
|
124
|
-
actionable:
|
|
196
|
+
dir: '.oat/projects/local/orphan-reviews',
|
|
197
|
+
kind: 'adhoc',
|
|
198
|
+
priority: 3,
|
|
199
|
+
archived: false,
|
|
200
|
+
actionable: true,
|
|
125
201
|
});
|
|
126
202
|
}
|
|
127
|
-
scanTargets.
|
|
128
|
-
dir: '.oat/repo/reviews',
|
|
129
|
-
kind: 'adhoc',
|
|
130
|
-
priority: 2,
|
|
131
|
-
archived: false,
|
|
132
|
-
actionable: true,
|
|
133
|
-
}, {
|
|
134
|
-
dir: '.oat/projects/local/orphan-reviews',
|
|
135
|
-
kind: 'adhoc',
|
|
136
|
-
priority: 3,
|
|
137
|
-
archived: false,
|
|
138
|
-
actionable: true,
|
|
139
|
-
});
|
|
140
|
-
const candidates = (await Promise.all(scanTargets.map(async (target) => {
|
|
203
|
+
let candidates = (await Promise.all(scanTargets.map(async (target) => {
|
|
141
204
|
const files = await listMarkdownFiles(options.repoRoot, target.dir);
|
|
142
205
|
return Promise.all(files.map((file) => readReviewCandidate(options.repoRoot, file, target.kind, target.priority, target.archived, target.actionable)));
|
|
143
206
|
})))
|
|
144
207
|
.flat()
|
|
145
|
-
.filter((candidate) => candidate !== null)
|
|
146
|
-
|
|
208
|
+
.filter((candidate) => candidate !== null);
|
|
209
|
+
if (projectPath) {
|
|
210
|
+
candidates = await correlateProjectActionability(options.repoRoot, projectPath, candidates);
|
|
211
|
+
}
|
|
212
|
+
if (options.actionableProjectOnly) {
|
|
213
|
+
candidates = candidates.filter((candidate) => candidate.actionable);
|
|
214
|
+
}
|
|
215
|
+
candidates.sort(sortReviewCandidates);
|
|
147
216
|
const latest = candidates[0];
|
|
148
217
|
if (!latest) {
|
|
149
218
|
return null;
|
|
@@ -168,7 +237,11 @@ async function runReviewLatest(context, options, dependencies) {
|
|
|
168
237
|
try {
|
|
169
238
|
const repoRoot = await dependencies.resolveProjectRoot(context.cwd);
|
|
170
239
|
const projectPath = await resolveProjectPath(repoRoot, options.project, dependencies);
|
|
171
|
-
const result = await findLatestReview({
|
|
240
|
+
const result = await findLatestReview({
|
|
241
|
+
repoRoot,
|
|
242
|
+
projectPath,
|
|
243
|
+
actionableProjectOnly: options.actionableProject,
|
|
244
|
+
});
|
|
172
245
|
if (context.json) {
|
|
173
246
|
context.logger.json(result ?? EMPTY_RESULT);
|
|
174
247
|
}
|
|
@@ -196,6 +269,7 @@ export function createReviewLatestCommand(overrides = {}) {
|
|
|
196
269
|
return new Command('latest')
|
|
197
270
|
.description('Find the most recent OAT review artifact')
|
|
198
271
|
.option('--project <path>', 'Project path to scan in addition to ad-hoc review locations')
|
|
272
|
+
.option('--actionable-project', 'Scan only active project reviews, excluding archived and ad-hoc history')
|
|
199
273
|
.action(async (options, command) => {
|
|
200
274
|
const context = dependencies.buildCommandContext(readGlobalOptions(command));
|
|
201
275
|
await runReviewLatest(context, options, dependencies);
|
|
@@ -35,6 +35,9 @@ export type WorkflowDispatchPolicyMode = 'managed' | 'inherit';
|
|
|
35
35
|
export type WorkflowManagedDispatchPolicy = 'economy' | 'balanced' | 'high' | 'frontier' | 'uncapped';
|
|
36
36
|
export type GateOnFailure = 'block' | 'prompt' | 'warn';
|
|
37
37
|
export type GateAvoid = 'same-family' | 'same-runtime' | 'none';
|
|
38
|
+
export declare const MIN_GATE_TIMEOUT_MS = 1000;
|
|
39
|
+
export declare const MAX_GATE_TIMEOUT_MS = 14400000;
|
|
40
|
+
export declare function isValidGateTimeoutMs(value: unknown): value is number;
|
|
38
41
|
export interface WorkflowDispatchCeiling {
|
|
39
42
|
preset?: WorkflowDispatchCeilingPreset;
|
|
40
43
|
recommendationVersion?: string;
|
|
@@ -66,12 +69,17 @@ export interface ExecTarget {
|
|
|
66
69
|
hostDetectionCommand?: string[];
|
|
67
70
|
availabilityCommand?: string[];
|
|
68
71
|
priority: number;
|
|
72
|
+
timeoutMs?: number;
|
|
69
73
|
}
|
|
70
74
|
export type ExecTargetConfig = Partial<ExecTarget>;
|
|
71
75
|
export interface WorkflowGatesConfig {
|
|
72
76
|
execTargets?: Record<string, ExecTargetConfig | null>;
|
|
73
77
|
skills?: Record<string, GateConfig | null>;
|
|
74
78
|
}
|
|
79
|
+
export interface WorkflowGateTimeouts {
|
|
80
|
+
code?: number;
|
|
81
|
+
artifact?: number;
|
|
82
|
+
}
|
|
75
83
|
export interface OatWorkflowConfig {
|
|
76
84
|
hillCheckpointDefault?: WorkflowHillCheckpointDefault;
|
|
77
85
|
archiveOnComplete?: boolean;
|
|
@@ -84,6 +92,7 @@ export interface OatWorkflowConfig {
|
|
|
84
92
|
designMode?: WorkflowDesignMode;
|
|
85
93
|
dispatchPolicy?: WorkflowDispatchPolicy;
|
|
86
94
|
dispatchCeiling?: WorkflowDispatchCeiling;
|
|
95
|
+
gateTimeouts?: WorkflowGateTimeouts;
|
|
87
96
|
gates?: WorkflowGatesConfig;
|
|
88
97
|
}
|
|
89
98
|
export declare const VALID_CODEX_DISPATCH_CEILINGS: readonly WorkflowCodexDispatchCeiling[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oat-config.d.ts","sourceRoot":"","sources":["../../src/config/oat-config.ts"],"names":[],"mappings":"AAOA,OAAO,EAEL,KAAK,6BAA6B,EACnC,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,2BAA2B,EAC3B,8BAA8B,EAC9B,iCAAiC,EACjC,+BAA+B,EAC/B,iCAAiC,EACjC,2BAA2B,EAC3B,KAAK,6BAA6B,EAClC,KAAK,yBAAyB,EAC9B,KAAK,+BAA+B,EACpC,KAAK,6BAA6B,EAClC,KAAK,gCAAgC,EACrC,KAAK,0BAA0B,EAC/B,KAAK,0BAA0B,EAC/B,KAAK,6BAA6B,EAClC,KAAK,qBAAqB,EAC1B,KAAK,0BAA0B,EAC/B,KAAK,2BAA2B,GACjC,MAAM,mBAAmB,CAAC;AAE3B,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACvC;AAED,MAAM,WAAW,YAAY;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,6BAA6B,GAAG,OAAO,GAAG,OAAO,CAAC;AAC9D,MAAM,MAAM,yBAAyB,GAAG,SAAS,GAAG,UAAU,GAAG,IAAI,CAAC;AACtE,MAAM,MAAM,mCAAmC,GAC3C,MAAM,GACN,SAAS,GACT,IAAI,GACJ,SAAS,CAAC;AACd,MAAM,WAAW,uCAAuC;IACtD,WAAW,EAAE,yBAAyB,EAAE,CAAC;IACzC,YAAY,EAAE,yBAAyB,EAAE,CAAC;CAC3C;AACD,MAAM,MAAM,6BAA6B,GACrC,mCAAmC,GACnC,uCAAuC,CAAC;AAC5C,MAAM,MAAM,4BAA4B,GACpC,UAAU,GACV,QAAQ,GACR,eAAe,CAAC;AACpB,MAAM,MAAM,kBAAkB,GAAG,eAAe,GAAG,WAAW,GAAG,OAAO,CAAC;AACzE,MAAM,MAAM,4BAA4B,GACpC,KAAK,GACL,QAAQ,GACR,MAAM,GACN,OAAO,GACP,KAAK,CAAC;AACV,MAAM,MAAM,6BAA6B,GACrC,OAAO,GACP,QAAQ,GACR,MAAM,GACN,OAAO,CAAC;AACZ,MAAM,MAAM,6BAA6B,GACrC,UAAU,GACV,SAAS,GACT,gBAAgB,CAAC;AACrB,MAAM,MAAM,0BAA0B,GAAG,SAAS,GAAG,SAAS,CAAC;AAC/D,MAAM,MAAM,6BAA6B,GACrC,SAAS,GACT,UAAU,GACV,MAAM,GACN,UAAU,GACV,UAAU,CAAC;AACf,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;AACxD,MAAM,MAAM,SAAS,GAAG,aAAa,GAAG,cAAc,GAAG,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"oat-config.d.ts","sourceRoot":"","sources":["../../src/config/oat-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,6 +6,14 @@ import { normalizeToPosixPath, validateRealPathWithinScope } from '../fs/paths.j
|
|
|
6
6
|
import { normalizeDispatchMatrix, } from './dispatch-matrix.js';
|
|
7
7
|
import { parseJsonConfig } from './json.js';
|
|
8
8
|
export { VALID_DISPATCH_MATRIX_TIERS, isCodexMaterializedRouteTarget, isWorkflowDispatchCandidateLadder, isWorkflowDispatchFallbackRoute, toWorkflowDispatchCandidateLadder, validateDispatchRouteTarget, } from './dispatch-matrix.js';
|
|
9
|
+
export const MIN_GATE_TIMEOUT_MS = 1_000;
|
|
10
|
+
export const MAX_GATE_TIMEOUT_MS = 14_400_000;
|
|
11
|
+
export function isValidGateTimeoutMs(value) {
|
|
12
|
+
return (typeof value === 'number' &&
|
|
13
|
+
Number.isInteger(value) &&
|
|
14
|
+
value >= MIN_GATE_TIMEOUT_MS &&
|
|
15
|
+
value <= MAX_GATE_TIMEOUT_MS);
|
|
16
|
+
}
|
|
9
17
|
const VALID_HILL_CHECKPOINT_DEFAULTS = ['every', 'final'];
|
|
10
18
|
const VALID_POST_IMPLEMENT_LEGACY_SEQUENCES = ['wait', 'summary', 'pr', 'docs-pr'];
|
|
11
19
|
const VALID_POST_IMPLEMENT_STEPS = [
|
|
@@ -206,6 +214,9 @@ function normalizeExecTarget(value) {
|
|
|
206
214
|
target.priority = value.priority;
|
|
207
215
|
}
|
|
208
216
|
}
|
|
217
|
+
if (isValidGateTimeoutMs(value.timeoutMs)) {
|
|
218
|
+
target.timeoutMs = value.timeoutMs;
|
|
219
|
+
}
|
|
209
220
|
const hostDetectionCommand = normalizeArgv(value.hostDetectionCommand);
|
|
210
221
|
if (hostDetectionCommand !== undefined) {
|
|
211
222
|
target.hostDetectionCommand = hostDetectionCommand;
|
|
@@ -323,6 +334,18 @@ function normalizeWorkflowConfig(parsed) {
|
|
|
323
334
|
next.dispatchCeiling = dispatchCeiling;
|
|
324
335
|
}
|
|
325
336
|
}
|
|
337
|
+
if (isRecord(parsed.gateTimeouts)) {
|
|
338
|
+
const gateTimeouts = {};
|
|
339
|
+
if (isValidGateTimeoutMs(parsed.gateTimeouts.code)) {
|
|
340
|
+
gateTimeouts.code = parsed.gateTimeouts.code;
|
|
341
|
+
}
|
|
342
|
+
if (isValidGateTimeoutMs(parsed.gateTimeouts.artifact)) {
|
|
343
|
+
gateTimeouts.artifact = parsed.gateTimeouts.artifact;
|
|
344
|
+
}
|
|
345
|
+
if (Object.keys(gateTimeouts).length > 0) {
|
|
346
|
+
next.gateTimeouts = gateTimeouts;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
326
349
|
if (isRecord(parsed.gates)) {
|
|
327
350
|
const gates = {};
|
|
328
351
|
const execTargets = normalizeRecordMap(parsed.gates.execTargets, normalizeExecTarget);
|
package/dist/config/resolve.js
CHANGED
|
@@ -235,6 +235,7 @@ function mergeExecTargetLayer(targets, layer) {
|
|
|
235
235
|
hostDetectionCommand: override.hostDetectionCommand ?? existing.hostDetectionCommand,
|
|
236
236
|
availabilityCommand: override.availabilityCommand ?? existing.availabilityCommand,
|
|
237
237
|
priority: override.priority ?? existing.priority,
|
|
238
|
+
timeoutMs: override.timeoutMs ?? existing.timeoutMs,
|
|
238
239
|
});
|
|
239
240
|
continue;
|
|
240
241
|
}
|
|
@@ -268,6 +269,9 @@ function cloneExecTarget(target) {
|
|
|
268
269
|
if (target.models) {
|
|
269
270
|
next.models = [...target.models];
|
|
270
271
|
}
|
|
272
|
+
if (target.timeoutMs !== undefined) {
|
|
273
|
+
next.timeoutMs = target.timeoutMs;
|
|
274
|
+
}
|
|
271
275
|
return next;
|
|
272
276
|
}
|
|
273
277
|
function toCompleteExecTarget(target) {
|
|
@@ -294,6 +298,9 @@ function toCompleteExecTarget(target) {
|
|
|
294
298
|
if (isValidStringList(target.models)) {
|
|
295
299
|
completeTarget.models = target.models.map((model) => model.trim());
|
|
296
300
|
}
|
|
301
|
+
if (target.timeoutMs !== undefined) {
|
|
302
|
+
completeTarget.timeoutMs = target.timeoutMs;
|
|
303
|
+
}
|
|
297
304
|
return completeTarget;
|
|
298
305
|
}
|
|
299
306
|
function mergeExecTargetInvocation(existing, override) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-agent-toolkit/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.72",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Open Agent Toolkit CLI",
|
|
6
6
|
"homepage": "https://github.com/voxmedia/open-agent-toolkit/tree/main/packages/cli",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"ora": "^9.0.0",
|
|
35
35
|
"yaml": "2.8.2",
|
|
36
36
|
"zod": "^3.25.76",
|
|
37
|
-
"@open-agent-toolkit/control-plane": "0.1.
|
|
37
|
+
"@open-agent-toolkit/control-plane": "0.1.72"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/node": "^22.10.0",
|