@open-agent-toolkit/cli 0.2.48 → 0.2.49
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/bundle-metadata.json +1 -1
- package/assets/docs/cli-utilities/workflow-gates.md +19 -0
- package/assets/docs/contributing/skills.md +6 -4
- package/assets/docs/reference/cli-reference.md +1 -1
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/oat-project-design/SKILL.md +13 -6
- package/assets/skills/oat-project-discover/SKILL.md +13 -6
- package/assets/skills/oat-project-import-plan/SKILL.md +8 -2
- package/assets/skills/oat-project-plan/SKILL.md +8 -2
- package/assets/skills/oat-project-quick-start/SKILL.md +8 -2
- package/dist/commands/gate/__fixtures__/fake-runtime.mjs +10 -0
- package/dist/commands/gate/configured-command.d.ts +12 -0
- package/dist/commands/gate/configured-command.d.ts.map +1 -0
- package/dist/commands/gate/configured-command.js +120 -0
- package/dist/commands/gate/index.d.ts.map +1 -1
- package/dist/commands/gate/index.js +51 -0
- package/package.json +2 -2
|
@@ -51,6 +51,17 @@ Fields:
|
|
|
51
51
|
- `description` - optional context for the agent running the gate.
|
|
52
52
|
- `maxAttempts` - retry bound for `block`; defaults to `2`.
|
|
53
53
|
|
|
54
|
+
When `oat gate set` recognizes a direct lifecycle `oat gate review` command,
|
|
55
|
+
it requires the canonical global option placement `oat --json gate review`.
|
|
56
|
+
Missing, late, repeated, or subcommand-scoped `--json` is rejected with exit 1
|
|
57
|
+
before the selected shared, local, or user config layer is changed. Arbitrary
|
|
58
|
+
wrappers, unrelated gate commands, and provider exec-target `baseCommand`
|
|
59
|
+
arrays remain outside this validator.
|
|
60
|
+
|
|
61
|
+
A valid command is stored byte-for-byte. `oat gate resolve` returns that exact
|
|
62
|
+
string, and the lifecycle executes it unchanged; OAT does not inject, reorder,
|
|
63
|
+
or rewrite its shell arguments.
|
|
64
|
+
|
|
54
65
|
`oat-project-plan`, `oat-project-implement`, `oat-project-quick-start`, and
|
|
55
66
|
`oat-project-import-plan` are currently gate-aware. Gate awareness is declared
|
|
56
67
|
in skill frontmatter with `oat_gateable: true`, and
|
|
@@ -284,6 +295,7 @@ and disambiguate re-gate rounds:
|
|
|
284
295
|
| `ok` | 0 | Review completed; gate passed at the threshold. |
|
|
285
296
|
| `blocked` | 1 | Review completed; findings at/above the threshold. |
|
|
286
297
|
| `review_failed` | ≠0 | The provider target exited non-zero; no verdict. |
|
|
298
|
+
| `artifact_missing` | 1 | The child exited cleanly without producing an artifact. |
|
|
287
299
|
| `artifact_validation_failed` | 1 | Artifact format or configured invocation fields are invalid. |
|
|
288
300
|
| `targeting_correlation_failed` | 1 | Identity did not correlate; do not run review-receive. |
|
|
289
301
|
|
|
@@ -296,6 +308,13 @@ For `artifact_validation_failed`, correct the artifact and rerun the gate; do
|
|
|
296
308
|
not invoke review-receive until the gate successfully revalidates it as `ok` or
|
|
297
309
|
`blocked`.
|
|
298
310
|
|
|
311
|
+
`artifact_missing` means the accepted headless child completed without any
|
|
312
|
+
review artifact. It sets `receiveEligible: false`, `remediable: false`, and
|
|
313
|
+
`handoff: null`. Fix the reviewer so review work, artifact creation, and
|
|
314
|
+
bookkeeping finish inline or through a synchronously awaited child, then start
|
|
315
|
+
a new gate run. Do not use review-fix retries or review-receive for the failed
|
|
316
|
+
run.
|
|
317
|
+
|
|
299
318
|
`ok` and `blocked` also include `receiveEligible: true`, `outcome`,
|
|
300
319
|
`artifactPath`, `counts`, `scope`, `handoff`, `gateInvocation`, and
|
|
301
320
|
`corroboration`. Invoke review-receive only when all three conditions hold:
|
|
@@ -262,9 +262,11 @@ The Gate Execution step should:
|
|
|
262
262
|
2. Treat `null` as "no gate configured."
|
|
263
263
|
3. Export the resolved path with `export PROJECT_PATH` before launching the
|
|
264
264
|
command shell.
|
|
265
|
-
4. For `oat gate review`, require the configured command to
|
|
266
|
-
|
|
267
|
-
|
|
265
|
+
4. For `oat gate review`, require the configured command to use
|
|
266
|
+
`oat --json gate review --project "$PROJECT_PATH" ...`, with the global
|
|
267
|
+
`--json` option before `gate review`. Do not inject, append, or reorder
|
|
268
|
+
arguments at runtime, because the resolved command must execute exactly as
|
|
269
|
+
configured.
|
|
268
270
|
5. Run the resolved `command` as the skill's last step and use its exit code as
|
|
269
271
|
the pass/fail signal.
|
|
270
272
|
6. Follow the gate's `onFailure` policy:
|
|
@@ -273,7 +275,7 @@ The Gate Execution step should:
|
|
|
273
275
|
- `warn` - record the failure and continue.
|
|
274
276
|
|
|
275
277
|
For OAT review gates, prefer putting
|
|
276
|
-
`oat gate review --project "$PROJECT_PATH" "<prompt>"` in the configured gate
|
|
278
|
+
`oat --json gate review --project "$PROJECT_PATH" "<prompt>"` in the configured gate
|
|
277
279
|
command rather than hard-coding a provider CLI directly in the skill. Use
|
|
278
280
|
`oat gate cross-provider-exec "<prompt>"` for generic cross-runtime commands
|
|
279
281
|
that should report only the child process status, not review findings.
|
|
@@ -126,7 +126,7 @@ Notable commands introduced in the current CLI surface:
|
|
|
126
126
|
- `oat project validate-plan --project-path <path>` - validates `oat_plan_parallel_groups` metadata in `plan.md`; exits non-zero on invalid. See [Implementation Execution](../workflows/projects/implementation-execution.md#parallel-phase-groups).
|
|
127
127
|
- `oat project log append|check|synthesize|rollup` - manage the optional append-only project observation log: append validated judgment or structural entries, inspect grammar and synthesis status, complete end-of-run synthesis, and roll observations into `summary.md` plus the configured repository ledger. See [Project Log](../cli-utilities/project-log.md).
|
|
128
128
|
- `oat project set-mode` — deprecated no-op. Execution mode is no longer user-selectable; emits a deprecation warning and preserves the `--json` contract.
|
|
129
|
-
- `oat gate review <prompt...>` - run a stateful, headless OAT review through the target registry, parse the produced review artifact, and exit nonzero for configured blocking findings. `--timeout-ms <milliseconds>` overrides target, `workflow.gateTimeouts`, environment, and scope defaults; accepted values are 1,000–14,400,000. Final/phase/range code reviews default to 30 minutes, while task code and artifact reviews default to 15 minutes. With `--json`, the result envelope on exit is the canonical completion signal: `status` is `ok` | `blocked` | `review_failed` | `artifact_validation_failed` | `targeting_correlation_failed`, alongside `runId`, `generatedAt`, and `artifactPath` when available. For `targeting_correlation_failed`, do not run review-receive even if an artifact path is present. For `artifact_validation_failed`, correct the artifact and rerun the gate until it revalidates as `ok` or `blocked`. Invoke `oat-project-review-receive` only when all three conditions hold: `status` is `ok` or `blocked`, `receiveEligible` is `true`, and `handoff` is non-null. `review_failed` may include structured `refusal`, `noOutputProduced`, and metadata-only `activityEvidence`; these diagnostic fields never make a run receive-eligible. After a timeout, a validated run-correlated artifact returns the ordinary `ok` or `blocked` envelope with additive `lateCompletion: true`. Duplicate run-ID matches or a changed artifact with a mismatched run ID retain `targeting_correlation_failed` and `receiveEligible: false`. Orchestrators should read the structured result rather than poll the filesystem. See [Workflow Gates](../cli-utilities/workflow-gates.md).
|
|
129
|
+
- `oat gate review <prompt...>` - run a stateful, headless OAT review through the target registry, parse the produced review artifact, and exit nonzero for configured blocking findings. `--timeout-ms <milliseconds>` overrides target, `workflow.gateTimeouts`, environment, and scope defaults; accepted values are 1,000–14,400,000. Final/phase/range code reviews default to 30 minutes, while task code and artifact reviews default to 15 minutes. With `--json`, the result envelope on exit is the canonical completion signal: `status` is `ok` | `blocked` | `review_failed` | `artifact_missing` | `artifact_validation_failed` | `targeting_correlation_failed`, alongside `runId`, `generatedAt`, and `artifactPath` when available. `artifact_missing` means an accepted child exited cleanly without an artifact; fix synchronous review/artifact completion and start a new run, without review-receive or same-run remediation. For `targeting_correlation_failed`, correct the project declaration or artifact routing and start a new run; do not run review-receive even if an artifact path is present. For `artifact_validation_failed`, correct the artifact and rerun the gate until it revalidates as `ok` or `blocked`. Invoke `oat-project-review-receive` only when all three conditions hold: `status` is `ok` or `blocked`, `receiveEligible` is `true`, and `handoff` is non-null. `review_failed` may include structured `refusal`, `noOutputProduced`, and metadata-only `activityEvidence`; these diagnostic fields never make a run receive-eligible. After a timeout, a validated run-correlated artifact returns the ordinary `ok` or `blocked` envelope with additive `lateCompletion: true`. Duplicate run-ID matches or a changed artifact with a mismatched run ID retain `targeting_correlation_failed` and `receiveEligible: false`. Orchestrators should read the structured result rather than poll the filesystem. See [Workflow Gates](../cli-utilities/workflow-gates.md).
|
|
130
130
|
- `oat gate route --expect-runtime <runtime> --expect-model <model> --can-await <true|false> --json` - return the headless child route (`inline`, `delegate-sync`, or `refuse`) from provider-marker and model evidence. Ambiguous or contradictory evidence never routes inline.
|
|
131
131
|
- `oat gate exec <prompt...>` / `oat gate cross-provider-exec <prompt...>` - run a generic target prompt. `--timeout-ms` uses the same validated CLI override; untyped runs otherwise retain the legacy default path.
|
|
132
132
|
- `oat gate target set <id> --invocation-model <model|provider-default> --invocation-reasoning-effort <effort|provider-default>` - persist optional configured invocation metadata alongside an exec target without inferring it from the target command.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: oat-project-design
|
|
3
|
-
version: 2.3.
|
|
3
|
+
version: 2.3.2
|
|
4
4
|
description: Use when discovery is complete and implementation-ready decisions are needed. Runs a collaborative, selective collaborative, or draft-and-review design flow, confirms requirements and produces both `spec.md` and `design.md`, and commits artifacts before the user-review gate.
|
|
5
5
|
disable-model-invocation: true
|
|
6
6
|
user-invocable: true
|
|
@@ -658,11 +658,18 @@ gate as the last check before the completion boundary:
|
|
|
658
658
|
```
|
|
659
659
|
|
|
660
660
|
If the resolved command invokes `oat gate review`, the configured review
|
|
661
|
-
command must already include `--project "$PROJECT_PATH"`
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
661
|
+
command must already include `--project "$PROJECT_PATH"` as part of the
|
|
662
|
+
structured-output contract. Its canonical form is:
|
|
663
|
+
|
|
664
|
+
```bash
|
|
665
|
+
oat --json gate review --project "$PROJECT_PATH" ...
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
This requires global `--json` before `gate review`. Reusable declarations
|
|
669
|
+
must not include
|
|
670
|
+
`--target <id>`. Reject `oat gate review ...` without the global `--json`
|
|
671
|
+
placement. Stop and migrate an invalid stored declaration before execution;
|
|
672
|
+
never inject or append execution-time argv.
|
|
666
673
|
|
|
667
674
|
3. Execute the resolved command exactly as configured. Capture stdout, stderr,
|
|
668
675
|
the exit code, and the structured JSON result. A zero exit code means the
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: oat-project-discover
|
|
3
|
-
version: 2.2.
|
|
3
|
+
version: 2.2.2
|
|
4
4
|
description: Use when the user explicitly asks to continue discovery for an active spec-driven OAT project — e.g. "continue discovery", "run discovery", or confirms a previously offered discovery step. Do NOT auto-invoke for new ideas or quick-mode projects. Gathers requirements and context before spec/design.
|
|
5
5
|
disable-model-invocation: false
|
|
6
6
|
user-invocable: true
|
|
@@ -445,11 +445,18 @@ gate as the last check before the completion boundary:
|
|
|
445
445
|
```
|
|
446
446
|
|
|
447
447
|
If the resolved command invokes `oat gate review`, the configured review
|
|
448
|
-
command must already include `--project "$PROJECT_PATH"`
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
448
|
+
command must already include `--project "$PROJECT_PATH"` as part of the
|
|
449
|
+
structured-output contract. Its canonical form is:
|
|
450
|
+
|
|
451
|
+
```bash
|
|
452
|
+
oat --json gate review --project "$PROJECT_PATH" ...
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
This requires global `--json` before `gate review`. Reusable declarations
|
|
456
|
+
must not include
|
|
457
|
+
`--target <id>`. Reject `oat gate review ...` without the global `--json`
|
|
458
|
+
placement. Stop and migrate an invalid stored declaration before execution;
|
|
459
|
+
never inject or append execution-time argv.
|
|
453
460
|
|
|
454
461
|
3. Execute the resolved command exactly as configured. Capture stdout, stderr,
|
|
455
462
|
the exit code, and the structured JSON result. A zero exit code means the
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: oat-project-import-plan
|
|
3
|
-
version: 1.4.
|
|
3
|
+
version: 1.4.11
|
|
4
4
|
description: Use when you have an external markdown plan to execute with OAT. Preserves the source plan and normalizes it into canonical plan.md format.
|
|
5
5
|
argument-hint: '<path-to-plan.md> [--provider codex|cursor|claude] [--project <name>]'
|
|
6
6
|
oat_gateable: true
|
|
@@ -460,7 +460,13 @@ Before reporting this skill as complete, run the configured gate as the final st
|
|
|
460
460
|
export PROJECT_PATH
|
|
461
461
|
```
|
|
462
462
|
|
|
463
|
-
If the resolved command invokes `oat gate review`, the configured review command must already include `--project "$PROJECT_PATH"`
|
|
463
|
+
If the resolved command invokes `oat gate review`, the configured review command must already include `--project "$PROJECT_PATH"` as part of the structured-output contract. Its canonical form is:
|
|
464
|
+
|
|
465
|
+
```bash
|
|
466
|
+
oat --json gate review --project "$PROJECT_PATH" ...
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
This requires global `--json` before `gate review`. Reusable declarations must not include `--target <id>`. Reject `oat gate review ...` without the global `--json` placement. Stop and migrate an invalid stored declaration before execution; never inject or append execution-time argv.
|
|
464
470
|
|
|
465
471
|
3. Resolve the current planning parent's model identity from session context.
|
|
466
472
|
When that identity is non-empty and the resolved configured command invokes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: oat-project-plan
|
|
3
|
-
version: 1.4.
|
|
3
|
+
version: 1.4.6
|
|
4
4
|
description: Use when design.md is complete and executable implementation tasks are needed. Breaks design into bite-sized TDD tasks in canonical plan.md format.
|
|
5
5
|
oat_gateable: true
|
|
6
6
|
disable-model-invocation: true
|
|
@@ -544,7 +544,13 @@ the last check before the completion boundary:
|
|
|
544
544
|
export PROJECT_PATH
|
|
545
545
|
```
|
|
546
546
|
|
|
547
|
-
If the resolved command invokes `oat gate review`, the configured review command must already include `--project "$PROJECT_PATH"`
|
|
547
|
+
If the resolved command invokes `oat gate review`, the configured review command must already include `--project "$PROJECT_PATH"` as part of the structured-output contract. Its canonical form is:
|
|
548
|
+
|
|
549
|
+
```bash
|
|
550
|
+
oat --json gate review --project "$PROJECT_PATH" ...
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
This requires global `--json` before `gate review`. Reusable declarations must not include `--target <id>`. Reject `oat gate review ...` without the global `--json` placement. Stop and migrate an invalid stored declaration before execution; never inject or append execution-time argv.
|
|
548
554
|
|
|
549
555
|
3. Resolve the current planning parent's model identity from session context.
|
|
550
556
|
When that identity is non-empty and the resolved configured command invokes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: oat-project-quick-start
|
|
3
|
-
version: 2.3.
|
|
3
|
+
version: 2.3.7
|
|
4
4
|
description: Use when a task is small enough for quick mode or rapid iteration is preferred. Scaffolds a lightweight OAT project from discovery directly to a runnable plan, with optional brainstorming and lightweight design.
|
|
5
5
|
argument-hint: '<project-name> ["project description"]'
|
|
6
6
|
oat_gateable: true
|
|
@@ -735,7 +735,13 @@ as the last check before plan and project completion:
|
|
|
735
735
|
export PROJECT_PATH
|
|
736
736
|
```
|
|
737
737
|
|
|
738
|
-
If the resolved command invokes `oat gate review`, the configured review command must already include `--project "$PROJECT_PATH"`
|
|
738
|
+
If the resolved command invokes `oat gate review`, the configured review command must already include `--project "$PROJECT_PATH"` as part of the structured-output contract. Its canonical form is:
|
|
739
|
+
|
|
740
|
+
```bash
|
|
741
|
+
oat --json gate review --project "$PROJECT_PATH" ...
|
|
742
|
+
```
|
|
743
|
+
|
|
744
|
+
This requires global `--json` before `gate review`. Reusable declarations must not include `--target <id>`. Reject `oat gate review ...` without the global `--json` placement. Stop and migrate an invalid stored declaration before execution; never inject or append execution-time argv.
|
|
739
745
|
|
|
740
746
|
3. Resolve the current planning parent's model identity from session context.
|
|
741
747
|
When that identity is non-empty and the resolved configured command invokes
|
|
@@ -8,6 +8,16 @@ const delayMs = Number(process.env.FAKE_GATE_DELAY_MS ?? '0');
|
|
|
8
8
|
const exitCode = Number(process.env.FAKE_GATE_EXIT_CODE ?? '0');
|
|
9
9
|
const artifactMode = process.env.FAKE_GATE_ARTIFACT ?? 'none';
|
|
10
10
|
const transcriptIntervalMs = Number(process.env.FAKE_GATE_TRANSCRIPT_INTERVAL_MS ?? '0');
|
|
11
|
+
if (process.env.FAKE_GATE_INVOCATION_LOG) {
|
|
12
|
+
await appendFile(process.env.FAKE_GATE_INVOCATION_LOG, `${JSON.stringify({
|
|
13
|
+
pid: process.pid,
|
|
14
|
+
headless: process.env.OAT_GATE_HEADLESS ?? null,
|
|
15
|
+
nonInteractive: process.env.OAT_NON_INTERACTIVE ?? null,
|
|
16
|
+
runId: process.env.OAT_GATE_RUN_ID ?? null,
|
|
17
|
+
cliPath: process.env.OAT_GATE_CLI_PATH ?? null,
|
|
18
|
+
routeReceiptPath: process.env.OAT_GATE_ROUTE_RECEIPT_PATH ?? null,
|
|
19
|
+
})}\n`);
|
|
20
|
+
}
|
|
11
21
|
function promptValue(key) {
|
|
12
22
|
return prompt.match(new RegExp(`^${key}: (.+)$`, 'm'))?.[1] ?? 'unknown';
|
|
13
23
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type GateCommandContractResult = {
|
|
2
|
+
kind: 'not-applicable';
|
|
3
|
+
} | {
|
|
4
|
+
kind: 'valid';
|
|
5
|
+
command: 'gate-review';
|
|
6
|
+
} | {
|
|
7
|
+
kind: 'invalid';
|
|
8
|
+
command: 'gate-review';
|
|
9
|
+
message: string;
|
|
10
|
+
};
|
|
11
|
+
export declare function validateConfiguredGateCommand(command: string): GateCommandContractResult;
|
|
12
|
+
//# sourceMappingURL=configured-command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configured-command.d.ts","sourceRoot":"","sources":["../../../src/commands/gate/configured-command.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,yBAAyB,GACjC;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,GAC1B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,aAAa,CAAA;CAAE,GACzC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAmIjE,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,MAAM,GACd,yBAAyB,CAoB3B"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
const INVALID_GATE_REVIEW_COMMAND_MESSAGE = 'Configured oat gate review commands must use the structured-output contract `oat --json gate review ...`.';
|
|
2
|
+
function tokenizeCommand(command) {
|
|
3
|
+
const tokens = [];
|
|
4
|
+
let token = '';
|
|
5
|
+
let tokenStarted = false;
|
|
6
|
+
let quote = null;
|
|
7
|
+
let escaped = false;
|
|
8
|
+
for (let index = 0; index < command.length; index += 1) {
|
|
9
|
+
const character = command[index];
|
|
10
|
+
if (quote === "'") {
|
|
11
|
+
if (character === "'") {
|
|
12
|
+
quote = null;
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
token += character;
|
|
16
|
+
}
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
if (escaped) {
|
|
20
|
+
if (character === '\n') {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
token += character;
|
|
24
|
+
tokenStarted = true;
|
|
25
|
+
escaped = false;
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
if (character === '\\') {
|
|
29
|
+
escaped = true;
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
if (quote) {
|
|
33
|
+
if (character === quote) {
|
|
34
|
+
quote = null;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
if (character === '`' ||
|
|
38
|
+
(character === '$' && command[index + 1] === '(')) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
token += character;
|
|
42
|
+
}
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (character === '"' || character === "'") {
|
|
46
|
+
quote = character;
|
|
47
|
+
tokenStarted = true;
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (character === '\n' || character === '`') {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
if (/\s/.test(character)) {
|
|
54
|
+
if (tokenStarted) {
|
|
55
|
+
tokens.push(token);
|
|
56
|
+
token = '';
|
|
57
|
+
tokenStarted = false;
|
|
58
|
+
}
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if ('|;&<>'.includes(character) ||
|
|
62
|
+
(character === '$' && command[index + 1] === '(')) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
token += character;
|
|
66
|
+
tokenStarted = true;
|
|
67
|
+
}
|
|
68
|
+
if (escaped || quote) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
if (tokenStarted) {
|
|
72
|
+
tokens.push(token);
|
|
73
|
+
}
|
|
74
|
+
return tokens;
|
|
75
|
+
}
|
|
76
|
+
function isDirectGateReview(tokens) {
|
|
77
|
+
if (tokens[0] !== 'oat') {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
let index = 1;
|
|
81
|
+
while (index < tokens.length) {
|
|
82
|
+
const token = tokens[index];
|
|
83
|
+
if (token === 'gate') {
|
|
84
|
+
return (tokens[index + 1] === 'review' ||
|
|
85
|
+
(tokens[index + 1] === '--json' && tokens[index + 2] === 'review'));
|
|
86
|
+
}
|
|
87
|
+
if (token === '--json' ||
|
|
88
|
+
token === '--verbose' ||
|
|
89
|
+
token.startsWith('--cwd=')) {
|
|
90
|
+
index += 1;
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
if (token === '--cwd') {
|
|
94
|
+
if (tokens[index + 1] === undefined) {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
index += 2;
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
export function validateConfiguredGateCommand(command) {
|
|
105
|
+
const tokens = tokenizeCommand(command);
|
|
106
|
+
if (!tokens || !isDirectGateReview(tokens)) {
|
|
107
|
+
return { kind: 'not-applicable' };
|
|
108
|
+
}
|
|
109
|
+
if (tokens[1] === '--json' &&
|
|
110
|
+
tokens[2] === 'gate' &&
|
|
111
|
+
tokens[3] === 'review' &&
|
|
112
|
+
tokens.filter((token) => token === '--json').length === 1) {
|
|
113
|
+
return { kind: 'valid', command: 'gate-review' };
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
kind: 'invalid',
|
|
117
|
+
command: 'gate-review',
|
|
118
|
+
message: INVALID_GATE_REVIEW_COMMAND_MESSAGE,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/gate/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAShE,OAAO,EAWL,KAAK,UAAU,EAIf,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,UAAU,EAEhB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,iBAAiB,CAAC;AAWzB,OAAO,EAEL,KAAK,WAAW,EACjB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EAExB,MAAM,gCAAgC,CAAC;AAExC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EACL,uBAAuB,EAExB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,EAEzB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACtB,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/gate/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,6 +21,7 @@ import YAML from 'yaml';
|
|
|
21
21
|
import { createGateActivityProbe, } from './activity-probes.js';
|
|
22
22
|
import { createBranchLocalGateCli, currentGateCliLaunch, readGateRouteReceipt, removeBranchLocalGateCli, } from './branch-local-cli.js';
|
|
23
23
|
import { runChildProcess, } from './child-process.js';
|
|
24
|
+
import { validateConfiguredGateCommand } from './configured-command.js';
|
|
24
25
|
import { parseReviewGateVerdict, severityDisplayName, } from './review-verdict.js';
|
|
25
26
|
import { createGateRouteCommand } from './route.js';
|
|
26
27
|
const DEFAULT_DEPENDENCIES = {
|
|
@@ -71,6 +72,7 @@ const VALID_IDENTITY_PROVENANCES = [
|
|
|
71
72
|
];
|
|
72
73
|
const REVIEW_GATE_CONTEXT_NOTE = [
|
|
73
74
|
'This review is gate-originated. If you run `oat-project-review-provide`, set `oat_review_invocation: gate` in the review artifact. Write a canonical review artifact with `### Critical`, `### Important`, `### Medium`, and `### Minor` headings in that order, using `None` for empty sections.',
|
|
75
|
+
'Complete the review, artifact write, and required bookkeeping inline or through a synchronously awaited child before this headless process exits. Do not start background tasks, monitors, or waiters that outlive this turn.',
|
|
74
76
|
"Artifact hygiene contract: Before finishing or committing, format every file you created or edited. Use the concrete write/fix formatting command supplied by the governing plan, task, or brief. If none is usable, discover the repository's documented write/fix command from applicable `AGENTS.md`/`CLAUDE.md` instructions and relevant package manifests; do not infer or hardcode a formatter. Prefer a file-scoped invocation when supported, and avoid rewriting unrelated files. If no command is discoverable, warn once with `no format command discovered in repo instructions; skipping`, then continue.",
|
|
75
77
|
].join('\n\n');
|
|
76
78
|
const GATE_CHECK_TIMEOUT_MS = 5_000;
|
|
@@ -1528,6 +1530,32 @@ function writeReviewGateArtifactValidationFailure(context, payload) {
|
|
|
1528
1530
|
context.logger.error(`Review completed but artifact validation failed: ${payload.message}`);
|
|
1529
1531
|
context.logger.error(payload.recovery);
|
|
1530
1532
|
}
|
|
1533
|
+
function writeReviewGateArtifactMissing(context, payload) {
|
|
1534
|
+
const message = `Review target ${payload.target} completed without producing the required correlated review artifact.`;
|
|
1535
|
+
const recovery = 'Fix the accepted headless target so it can write and finalize the review artifact before the process exits, then start a new gate run.';
|
|
1536
|
+
if (context.json) {
|
|
1537
|
+
context.logger.json({
|
|
1538
|
+
status: 'artifact_missing',
|
|
1539
|
+
outcome: 'review_completed_artifact_missing',
|
|
1540
|
+
runId: payload.runId,
|
|
1541
|
+
target: payload.target,
|
|
1542
|
+
project: payload.project,
|
|
1543
|
+
projectResolutionSource: payload.projectResolutionSource,
|
|
1544
|
+
artifactPath: null,
|
|
1545
|
+
generatedAt: null,
|
|
1546
|
+
gateInvocation: payload.gateInvocation,
|
|
1547
|
+
dispatchReport: payload.dispatchReport,
|
|
1548
|
+
receiveEligible: false,
|
|
1549
|
+
remediable: false,
|
|
1550
|
+
handoff: null,
|
|
1551
|
+
message,
|
|
1552
|
+
recovery,
|
|
1553
|
+
});
|
|
1554
|
+
return;
|
|
1555
|
+
}
|
|
1556
|
+
context.logger.error(message);
|
|
1557
|
+
context.logger.error(recovery);
|
|
1558
|
+
}
|
|
1531
1559
|
function writeReviewGateTargetingFailure(context, payload) {
|
|
1532
1560
|
const corroboration = {
|
|
1533
1561
|
run: payload.corroboration.run,
|
|
@@ -1712,6 +1740,12 @@ async function runGateSet(skillName, options, context, dependencies) {
|
|
|
1712
1740
|
const layer = parseLayer(options.layer);
|
|
1713
1741
|
const normalizedSkill = trimRequired(skillName, '<skill>');
|
|
1714
1742
|
const gate = parseGateConfig(options);
|
|
1743
|
+
if (gate) {
|
|
1744
|
+
const validation = validateConfiguredGateCommand(gate.command);
|
|
1745
|
+
if (validation.kind === 'invalid') {
|
|
1746
|
+
throw new Error(validation.message);
|
|
1747
|
+
}
|
|
1748
|
+
}
|
|
1715
1749
|
const warnings = gate
|
|
1716
1750
|
? detectDevBuildGateCommandWarnings(gate.command)
|
|
1717
1751
|
: [];
|
|
@@ -2068,6 +2102,23 @@ async function runReviewGate(prompt, options, context, dependencies) {
|
|
|
2068
2102
|
const producedArtifact = artifactResolution.artifact;
|
|
2069
2103
|
if (!producedArtifact) {
|
|
2070
2104
|
const diagnosticArtifact = artifactResolution.diagnosticArtifact;
|
|
2105
|
+
if (!diagnosticArtifact &&
|
|
2106
|
+
artifactResolution.matchingArtifactPaths.length === 0) {
|
|
2107
|
+
if (projectLogFinalization) {
|
|
2108
|
+
projectLogFinalization.status = 'artifact_missing';
|
|
2109
|
+
projectLogFinalization.exitCode = 1;
|
|
2110
|
+
}
|
|
2111
|
+
writeReviewGateArtifactMissing(context, {
|
|
2112
|
+
runId,
|
|
2113
|
+
target: selected.id,
|
|
2114
|
+
project: projectPath,
|
|
2115
|
+
projectResolutionSource: reviewProject.source,
|
|
2116
|
+
gateInvocation,
|
|
2117
|
+
dispatchReport,
|
|
2118
|
+
});
|
|
2119
|
+
process.exitCode = 1;
|
|
2120
|
+
return;
|
|
2121
|
+
}
|
|
2071
2122
|
const message = artifactResolution.matchingArtifactPaths.length > 1
|
|
2072
2123
|
? `Multiple direct review artifacts carried gate run ID ${runId}.`
|
|
2073
2124
|
: initialTargetCorroboration.run === 'mismatched'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-agent-toolkit/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.49",
|
|
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.2.
|
|
37
|
+
"@open-agent-toolkit/control-plane": "0.2.49"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/node": "^22.10.0",
|