@open-agent-toolkit/cli 0.1.46 → 0.1.48
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-phase-implementer.md +202 -191
- package/assets/agents/oat-reviewer.md +11 -1
- package/assets/config/dispatch-matrix-recommendation.json +120 -13
- package/assets/docs/cli-utilities/configuration.md +172 -113
- package/assets/docs/cli-utilities/workflow-gates.md +161 -27
- package/assets/docs/contributing/skills.md +14 -8
- package/assets/docs/provider-sync/providers.md +41 -7
- package/assets/docs/provider-sync/scope-and-surface.md +2 -2
- package/assets/docs/reference/cli-reference.md +3 -1
- package/assets/docs/reference/oat-directory-structure.md +27 -26
- package/assets/docs/workflows/projects/artifacts.md +31 -1
- package/assets/docs/workflows/projects/dispatch-ceiling.md +235 -187
- package/assets/docs/workflows/projects/implementation-execution.md +283 -260
- package/assets/docs/workflows/projects/lifecycle.md +26 -5
- package/assets/docs/workflows/projects/reviews.md +27 -2
- package/assets/migration/pjm-restructure.md +1 -1
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/oat-project-implement/SKILL.md +247 -133
- package/assets/skills/oat-project-import-plan/SKILL.md +173 -16
- package/assets/skills/oat-project-next/SKILL.md +2 -2
- package/assets/skills/oat-project-plan/SKILL.md +122 -92
- package/assets/skills/oat-project-plan-writing/SKILL.md +246 -15
- package/assets/skills/oat-project-quick-start/SKILL.md +157 -107
- package/assets/skills/oat-project-review-provide/SKILL.md +94 -22
- package/dist/commands/config/index.d.ts.map +1 -1
- package/dist/commands/config/index.js +64 -39
- package/dist/commands/doctor/index.d.ts.map +1 -1
- package/dist/commands/doctor/index.js +21 -6
- package/dist/commands/gate/index.d.ts +7 -1
- package/dist/commands/gate/index.d.ts.map +1 -1
- package/dist/commands/gate/index.js +544 -67
- package/dist/commands/gate/review-verdict.d.ts +16 -0
- package/dist/commands/gate/review-verdict.d.ts.map +1 -1
- package/dist/commands/gate/review-verdict.js +72 -9
- package/dist/commands/project/dispatch-ceiling/index.d.ts.map +1 -1
- package/dist/commands/project/dispatch-ceiling/index.js +452 -16
- package/dist/commands/providers/codex/materialize.d.ts.map +1 -1
- package/dist/commands/providers/codex/materialize.js +6 -1
- package/dist/commands/shared/frontmatter.d.ts +4 -0
- package/dist/commands/shared/frontmatter.d.ts.map +1 -1
- package/dist/commands/shared/frontmatter.js +23 -0
- package/dist/commands/status/index.d.ts +1 -0
- package/dist/commands/status/index.d.ts.map +1 -1
- package/dist/commands/status/index.js +10 -4
- package/dist/commands/sync/index.d.ts.map +1 -1
- package/dist/commands/sync/index.js +10 -3
- package/dist/commands/sync/sync.types.d.ts +1 -0
- package/dist/commands/sync/sync.types.d.ts.map +1 -1
- package/dist/config/oat-config.d.ts +19 -2
- package/dist/config/oat-config.d.ts.map +1 -1
- package/dist/config/oat-config.js +139 -24
- package/dist/config/resolve.d.ts +8 -0
- package/dist/config/resolve.d.ts.map +1 -1
- package/dist/config/resolve.js +66 -2
- package/dist/engine/index.d.ts +1 -1
- package/dist/engine/index.d.ts.map +1 -1
- package/dist/engine/index.js +1 -1
- package/dist/engine/scanner.d.ts +1 -0
- package/dist/engine/scanner.d.ts.map +1 -1
- package/dist/engine/scanner.js +17 -1
- package/dist/fs/paths.d.ts +4 -0
- package/dist/fs/paths.d.ts.map +1 -1
- package/dist/fs/paths.js +18 -1
- package/dist/providers/ceiling/registry.d.ts +1 -0
- package/dist/providers/ceiling/registry.d.ts.map +1 -1
- package/dist/providers/ceiling/registry.js +12 -5
- package/dist/providers/codex/codec/catalog.d.ts +14 -0
- package/dist/providers/codex/codec/catalog.d.ts.map +1 -0
- package/dist/providers/codex/codec/catalog.js +21 -0
- package/dist/providers/codex/codec/materialize.d.ts.map +1 -1
- package/dist/providers/codex/codec/materialize.js +6 -5
- package/dist/providers/codex/codec/shared.d.ts +19 -0
- package/dist/providers/codex/codec/shared.d.ts.map +1 -1
- package/dist/providers/codex/codec/shared.js +98 -5
- package/dist/providers/codex/codec/sync-extension.d.ts.map +1 -1
- package/dist/providers/codex/codec/sync-extension.js +142 -32
- package/dist/providers/identity/stamp.d.ts.map +1 -1
- package/dist/providers/identity/stamp.js +4 -0
- package/dist/shared/types.d.ts +1 -0
- package/dist/shared/types.d.ts.map +1 -1
- package/dist/shared/types.js +4 -0
- package/package.json +2 -2
|
@@ -3,6 +3,8 @@ export interface ReviewGateVerdict {
|
|
|
3
3
|
reviewType: 'code' | 'artifact' | 'unknown';
|
|
4
4
|
scope: string | null;
|
|
5
5
|
invocation: string | null;
|
|
6
|
+
project: string | null;
|
|
7
|
+
gateInvocation?: ReviewArtifactGateInvocation;
|
|
6
8
|
counts: {
|
|
7
9
|
critical: number;
|
|
8
10
|
important: number;
|
|
@@ -12,11 +14,25 @@ export interface ReviewGateVerdict {
|
|
|
12
14
|
blocking: boolean;
|
|
13
15
|
normalization?: {
|
|
14
16
|
insertedSeverities: Severity[];
|
|
17
|
+
persisted: boolean;
|
|
15
18
|
};
|
|
16
19
|
}
|
|
20
|
+
export interface ReviewArtifactGateInvocation {
|
|
21
|
+
runId: string | null;
|
|
22
|
+
targetId: string | null;
|
|
23
|
+
runtime: string | null;
|
|
24
|
+
model: string | null;
|
|
25
|
+
reasoningEffort: string | null;
|
|
26
|
+
source: string | null;
|
|
27
|
+
}
|
|
17
28
|
export type Severity = keyof ReviewGateVerdict['counts'];
|
|
29
|
+
export interface ReviewGateArtifactSnapshot {
|
|
30
|
+
readonly content: string;
|
|
31
|
+
readonly signature: string;
|
|
32
|
+
}
|
|
18
33
|
export interface ParseReviewGateVerdictOptions {
|
|
19
34
|
normalizeMissingEmptySeveritySections?: boolean;
|
|
35
|
+
artifactSnapshot?: ReviewGateArtifactSnapshot;
|
|
20
36
|
}
|
|
21
37
|
export declare function severityDisplayName(severity: Severity): string;
|
|
22
38
|
export declare function parseReviewGateVerdict(artifactPath: string, options?: ParseReviewGateVerdictOptions): Promise<ReviewGateVerdict>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"review-verdict.d.ts","sourceRoot":"","sources":["../../../src/commands/gate/review-verdict.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"review-verdict.d.ts","sourceRoot":"","sources":["../../../src/commands/gate/review-verdict.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IAC5C,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,cAAc,CAAC,EAAE,4BAA4B,CAAC;IAC9C,MAAM,EAAE;QACN,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE;QACd,kBAAkB,EAAE,QAAQ,EAAE,CAAC;QAC/B,SAAS,EAAE,OAAO,CAAC;KACpB,CAAC;CACH;AAED,MAAM,WAAW,4BAA4B;IAC3C,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,QAAQ,CAAC,CAAC;AAEzD,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,6BAA6B;IAC5C,qCAAqC,CAAC,EAAE,OAAO,CAAC;IAChD,gBAAgB,CAAC,EAAE,0BAA0B,CAAC;CAC/C;AA6LD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAE9D;AAgSD,wBAAsB,sBAAsB,CAC1C,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,6BAAkC,GAC1C,OAAO,CAAC,iBAAiB,CAAC,CAiF5B"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
1
2
|
import { readFile, writeFile } from 'node:fs/promises';
|
|
2
3
|
import { getFrontmatterBlock } from '../shared/frontmatter.js';
|
|
3
4
|
import YAML from 'yaml';
|
|
@@ -13,12 +14,50 @@ const FRONTMATTER_COUNT_KEYS = {
|
|
|
13
14
|
medium: ['oat_review_medium_count', 'medium'],
|
|
14
15
|
minor: ['oat_review_minor_count', 'minor'],
|
|
15
16
|
};
|
|
17
|
+
function artifactContentSignature(content) {
|
|
18
|
+
return createHash('sha256').update(content).digest('hex');
|
|
19
|
+
}
|
|
20
|
+
async function assertArtifactContentCurrent(artifactPath, expectedContent) {
|
|
21
|
+
let currentContent;
|
|
22
|
+
try {
|
|
23
|
+
currentContent = await readFile(artifactPath, 'utf8');
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
27
|
+
throw new Error(`Unable to verify review artifact snapshot at ${artifactPath}: ${detail}`, { cause: error });
|
|
28
|
+
}
|
|
29
|
+
if (artifactContentSignature(currentContent) !==
|
|
30
|
+
artifactContentSignature(expectedContent)) {
|
|
31
|
+
throw new Error(`Review artifact at ${artifactPath} changed after gate correlation; rerun the gate so correlation and verdict evaluation use one immutable snapshot.`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
16
34
|
function normalizeReviewType(value) {
|
|
17
35
|
return value === 'code' || value === 'artifact' ? value : 'unknown';
|
|
18
36
|
}
|
|
19
37
|
function stringOrNull(value) {
|
|
20
38
|
return typeof value === 'string' && value.trim() ? value.trim() : null;
|
|
21
39
|
}
|
|
40
|
+
function readGateInvocation(frontmatter) {
|
|
41
|
+
const keys = [
|
|
42
|
+
'oat_gate_run_id',
|
|
43
|
+
'oat_gate_target',
|
|
44
|
+
'oat_gate_runtime',
|
|
45
|
+
'oat_invocation_model',
|
|
46
|
+
'oat_invocation_reasoning_effort',
|
|
47
|
+
'oat_invocation_source',
|
|
48
|
+
];
|
|
49
|
+
if (!keys.some((key) => key in frontmatter)) {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
runId: stringOrNull(frontmatter['oat_gate_run_id']),
|
|
54
|
+
targetId: stringOrNull(frontmatter['oat_gate_target']),
|
|
55
|
+
runtime: stringOrNull(frontmatter['oat_gate_runtime']),
|
|
56
|
+
model: stringOrNull(frontmatter['oat_invocation_model']),
|
|
57
|
+
reasoningEffort: stringOrNull(frontmatter['oat_invocation_reasoning_effort']),
|
|
58
|
+
source: stringOrNull(frontmatter['oat_invocation_source']),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
22
61
|
function parseCountValue(value) {
|
|
23
62
|
const numberValue = typeof value === 'number'
|
|
24
63
|
? value
|
|
@@ -244,7 +283,7 @@ function insertMissingSeveritySection(content, severity) {
|
|
|
244
283
|
const needsTrailingBlank = suffix.length > 0 ? '\n' : '';
|
|
245
284
|
return `${content.slice(0, insertionPoint)}${insertion}${needsTrailingBlank}${suffix}`;
|
|
246
285
|
}
|
|
247
|
-
async function normalizeMissingEmptySeveritySections(artifactPath, content, counts) {
|
|
286
|
+
async function normalizeMissingEmptySeveritySections(artifactPath, content, counts, persist) {
|
|
248
287
|
if (!findFindingsSection(content)) {
|
|
249
288
|
throw new Error(`Review artifact at ${artifactPath} does not contain a ## Findings section, so missing severity headings cannot be safely normalized.`);
|
|
250
289
|
}
|
|
@@ -257,10 +296,16 @@ async function normalizeMissingEmptySeveritySections(artifactPath, content, coun
|
|
|
257
296
|
normalizedContent = insertMissingSeveritySection(normalizedContent, severity);
|
|
258
297
|
insertedSeverities.push(severity);
|
|
259
298
|
}
|
|
260
|
-
if (insertedSeverities.length > 0) {
|
|
299
|
+
if (insertedSeverities.length > 0 && persist) {
|
|
300
|
+
await assertArtifactContentCurrent(artifactPath, content);
|
|
261
301
|
await writeFile(artifactPath, normalizedContent, 'utf8');
|
|
302
|
+
await assertArtifactContentCurrent(artifactPath, normalizedContent);
|
|
262
303
|
}
|
|
263
|
-
return {
|
|
304
|
+
return {
|
|
305
|
+
content: normalizedContent,
|
|
306
|
+
insertedSeverities,
|
|
307
|
+
persisted: insertedSeverities.length > 0 && persist,
|
|
308
|
+
};
|
|
264
309
|
}
|
|
265
310
|
function resolveCounts(content, frontmatter) {
|
|
266
311
|
const frontmatterCounts = readFrontmatterCounts(frontmatter);
|
|
@@ -275,12 +320,21 @@ function resolveCounts(content, frontmatter) {
|
|
|
275
320
|
}
|
|
276
321
|
export async function parseReviewGateVerdict(artifactPath, options = {}) {
|
|
277
322
|
let content;
|
|
278
|
-
|
|
279
|
-
content =
|
|
323
|
+
if (options.artifactSnapshot) {
|
|
324
|
+
content = options.artifactSnapshot.content;
|
|
325
|
+
if (artifactContentSignature(content) !== options.artifactSnapshot.signature) {
|
|
326
|
+
throw new Error(`Review artifact snapshot signature at ${artifactPath} does not match its content.`);
|
|
327
|
+
}
|
|
328
|
+
await assertArtifactContentCurrent(artifactPath, content);
|
|
280
329
|
}
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
330
|
+
else {
|
|
331
|
+
try {
|
|
332
|
+
content = await readFile(artifactPath, 'utf8');
|
|
333
|
+
}
|
|
334
|
+
catch (error) {
|
|
335
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
336
|
+
throw new Error(`Unable to read review artifact at ${artifactPath}: ${detail}`, { cause: error });
|
|
337
|
+
}
|
|
284
338
|
}
|
|
285
339
|
const frontmatterBlock = getFrontmatterBlock(content);
|
|
286
340
|
const frontmatter = frontmatterBlock
|
|
@@ -288,10 +342,12 @@ export async function parseReviewGateVerdict(artifactPath, options = {}) {
|
|
|
288
342
|
: {};
|
|
289
343
|
let counts = resolveCounts(content, frontmatter);
|
|
290
344
|
let insertedSeverities = [];
|
|
345
|
+
let normalizationPersisted = false;
|
|
291
346
|
if (counts && options.normalizeMissingEmptySeveritySections) {
|
|
292
|
-
const normalized = await normalizeMissingEmptySeveritySections(artifactPath, content, counts);
|
|
347
|
+
const normalized = await normalizeMissingEmptySeveritySections(artifactPath, content, counts, !options.artifactSnapshot);
|
|
293
348
|
content = normalized.content;
|
|
294
349
|
insertedSeverities = normalized.insertedSeverities;
|
|
350
|
+
normalizationPersisted = normalized.persisted;
|
|
295
351
|
}
|
|
296
352
|
if (!counts) {
|
|
297
353
|
counts = parseFindingsSectionCounts(content, artifactPath);
|
|
@@ -299,17 +355,24 @@ export async function parseReviewGateVerdict(artifactPath, options = {}) {
|
|
|
299
355
|
if (!counts) {
|
|
300
356
|
throw new Error(`Review artifact at ${artifactPath} does not contain recognizable review findings or explicit verdict counts.`);
|
|
301
357
|
}
|
|
358
|
+
const gateInvocation = readGateInvocation(frontmatter);
|
|
359
|
+
if (options.artifactSnapshot) {
|
|
360
|
+
await assertArtifactContentCurrent(artifactPath, options.artifactSnapshot.content);
|
|
361
|
+
}
|
|
302
362
|
return {
|
|
303
363
|
artifactPath,
|
|
304
364
|
reviewType: normalizeReviewType(frontmatter['oat_review_type']),
|
|
305
365
|
scope: stringOrNull(frontmatter['oat_review_scope']),
|
|
306
366
|
invocation: stringOrNull(frontmatter['oat_review_invocation']),
|
|
367
|
+
project: stringOrNull(frontmatter['oat_project']),
|
|
368
|
+
...(gateInvocation ? { gateInvocation } : {}),
|
|
307
369
|
counts,
|
|
308
370
|
blocking: hasBlockingFindings(counts),
|
|
309
371
|
...(insertedSeverities.length > 0
|
|
310
372
|
? {
|
|
311
373
|
normalization: {
|
|
312
374
|
insertedSeverities,
|
|
375
|
+
persisted: normalizationPersisted,
|
|
313
376
|
},
|
|
314
377
|
}
|
|
315
378
|
: {}),
|
|
@@ -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;AAY9B,OAAO,
|
|
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;AAY9B,OAAO,EAUL,KAAK,uBAAuB,EAY7B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEL,KAAK,cAAc,EAEpB,MAAM,iBAAiB,CAAC;AAezB,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;AA+0ED,wBAAgB,mCAAmC,CACjD,SAAS,GAAE,OAAO,CAAC,2BAA2B,CAAM,GACnD,OAAO,CAwFT"}
|