@open-agent-toolkit/cli 0.1.66 → 0.1.69
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/workflow-gates.md +24 -5
- package/assets/docs/reference/cli-reference.md +1 -1
- package/assets/docs/workflows/projects/dispatch-ceiling.md +11 -3
- package/assets/docs/workflows/projects/pr-flow.md +12 -1
- package/assets/docs/workflows/projects/reviews.md +21 -1
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/oat-project-autonomous/SKILL.md +1 -1
- package/assets/skills/oat-project-autonomous/references/gate-inventory.md +2 -2
- package/assets/skills/oat-project-complete/SKILL.md +20 -2
- package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +2 -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 +2 -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 +19 -2
- package/assets/skills/oat-project-pr-final/SKILL.md +20 -5
- package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +2 -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 +2 -2
- package/assets/skills/oat-project-review-provide/SKILL.md +7 -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/gate/index.d.ts +2 -0
- package/dist/commands/gate/index.d.ts.map +1 -1
- package/dist/commands/gate/index.js +29 -1
- 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/package.json +2 -2
|
@@ -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);
|
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.69",
|
|
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.69"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/node": "^22.10.0",
|