@open-agent-toolkit/control-plane 0.1.65 → 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/dist/project.d.ts.map +1 -1
- package/dist/project.js +21 -10
- package/dist/recommender/router.js +7 -2
- package/dist/state/reviews.d.ts +4 -0
- package/dist/state/reviews.d.ts.map +1 -1
- package/dist/state/reviews.js +15 -4
- package/package.json +1 -1
package/dist/project.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,YAAY,EACZ,cAAc,EAGf,MAAM,SAAS,CAAC;AAEjB,wBAAsB,eAAe,CACnC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,YAAY,CAAC,CA6DvB;AAED,wBAAsB,YAAY,CAChC,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,cAAc,EAAE,CAAC,CAkF3B"}
|
package/dist/project.js
CHANGED
|
@@ -3,7 +3,7 @@ import { basename, dirname, isAbsolute, join, relative } from 'node:path';
|
|
|
3
3
|
import { recommendSkill } from './recommender/router.js';
|
|
4
4
|
import { scanArtifacts } from './state/artifacts.js';
|
|
5
5
|
import { parseStateFrontmatter } from './state/parser.js';
|
|
6
|
-
import { parseReviewTable, scanUnprocessedReviews } from './state/reviews.js';
|
|
6
|
+
import { parseReviewArtifactIdentity, parseReviewTable, scanUnprocessedReviews, } from './state/reviews.js';
|
|
7
7
|
import { parseTaskProgress } from './state/tasks.js';
|
|
8
8
|
export async function getProjectState(projectPath) {
|
|
9
9
|
const displayPath = await resolveProjectDisplayPath(projectPath);
|
|
@@ -15,8 +15,9 @@ export async function getProjectState(projectPath) {
|
|
|
15
15
|
scanUnprocessedReviews(projectPath),
|
|
16
16
|
]);
|
|
17
17
|
const parsedState = parseStateFrontmatter(stateContent);
|
|
18
|
-
const
|
|
19
|
-
const
|
|
18
|
+
const tableReviews = parseReviewTable(planContent);
|
|
19
|
+
const activeReviewArtifacts = await toActiveReviewArtifacts(reviewFiles, projectPath, tableReviews);
|
|
20
|
+
const reviews = mergeReviews(tableReviews, activeReviewArtifacts);
|
|
20
21
|
const progress = parseTaskProgress(planContent, implementationContent);
|
|
21
22
|
const projectStateWithoutRecommendation = {
|
|
22
23
|
name: basename(projectPath),
|
|
@@ -71,8 +72,9 @@ export async function listProjects(projectsRoot) {
|
|
|
71
72
|
scanUnprocessedReviews(projectDir),
|
|
72
73
|
]);
|
|
73
74
|
const parsedState = parseStateFrontmatter(stateContent);
|
|
74
|
-
const
|
|
75
|
-
const
|
|
75
|
+
const tableReviews = parseReviewTable(planContent);
|
|
76
|
+
const activeReviewArtifacts = await toActiveReviewArtifacts(reviewFiles, projectDir, tableReviews);
|
|
77
|
+
const reviews = mergeReviews(tableReviews, activeReviewArtifacts);
|
|
76
78
|
const progress = parseTaskProgress(planContent, implementationContent);
|
|
77
79
|
const stateWithoutRecommendation = {
|
|
78
80
|
name: basename(projectDir),
|
|
@@ -192,10 +194,19 @@ function mergeReviews(tableReviews, activeReviewArtifacts) {
|
|
|
192
194
|
}
|
|
193
195
|
return merged;
|
|
194
196
|
}
|
|
195
|
-
function toActiveReviewArtifacts(reviewFiles, projectPath) {
|
|
196
|
-
return reviewFiles.map((reviewFile) =>
|
|
197
|
-
path
|
|
198
|
-
|
|
199
|
-
actionable
|
|
197
|
+
async function toActiveReviewArtifacts(reviewFiles, projectPath, tableReviews) {
|
|
198
|
+
return Promise.all(reviewFiles.map(async (reviewFile) => {
|
|
199
|
+
const path = relative(projectPath, reviewFile).replace(/\\/g, '/');
|
|
200
|
+
const identity = parseReviewArtifactIdentity(await readOptionalFile(reviewFile));
|
|
201
|
+
const actionable = identity !== null &&
|
|
202
|
+
tableReviews.some((review) => review.scope.toLowerCase() === identity.scope.toLowerCase() &&
|
|
203
|
+
review.type.toLowerCase() === identity.type.toLowerCase() &&
|
|
204
|
+
review.artifact === path &&
|
|
205
|
+
review.status.toLowerCase() === 'received');
|
|
206
|
+
return {
|
|
207
|
+
path,
|
|
208
|
+
archived: false,
|
|
209
|
+
actionable,
|
|
210
|
+
};
|
|
200
211
|
}));
|
|
201
212
|
}
|
|
@@ -104,7 +104,9 @@ function getPostImplementationRecommendation(state) {
|
|
|
104
104
|
reason: 'Unprocessed review feedback exists',
|
|
105
105
|
};
|
|
106
106
|
}
|
|
107
|
-
const finalReview = state.reviews
|
|
107
|
+
const finalReview = [...state.reviews]
|
|
108
|
+
.reverse()
|
|
109
|
+
.find((review) => review.scope === 'final' && review.type === 'code');
|
|
108
110
|
if (!finalReview || finalReview.status === 'pending') {
|
|
109
111
|
return {
|
|
110
112
|
skill: 'oat-project-review-provide',
|
|
@@ -148,7 +150,10 @@ function hasIncompleteRevisionPhase(state) {
|
|
|
148
150
|
return state.progress.phases.some((phase) => phase.isRevision && phase.completed < phase.total);
|
|
149
151
|
}
|
|
150
152
|
function hasActionableReviewArtifacts(state) {
|
|
151
|
-
return state.activeReviewArtifacts.some((reviewArtifact) => reviewArtifact.actionable &&
|
|
153
|
+
return state.activeReviewArtifacts.some((reviewArtifact) => reviewArtifact.actionable &&
|
|
154
|
+
!reviewArtifact.archived &&
|
|
155
|
+
state.reviews.some((review) => review.artifact === reviewArtifact.path &&
|
|
156
|
+
review.status.toLowerCase() === 'received'));
|
|
152
157
|
}
|
|
153
158
|
function getCurrentArtifact(state) {
|
|
154
159
|
if (state.phase === 'decomposition') {
|
package/dist/state/reviews.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import type { ReviewStatus } from '../types.js';
|
|
2
2
|
export declare function parseReviewTable(planContent: string): ReviewStatus[];
|
|
3
3
|
export declare function scanUnprocessedReviews(projectPath: string): Promise<string[]>;
|
|
4
|
+
export declare function parseReviewArtifactIdentity(content: string): {
|
|
5
|
+
scope: string;
|
|
6
|
+
type: string;
|
|
7
|
+
} | null;
|
|
4
8
|
//# sourceMappingURL=reviews.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reviews.d.ts","sourceRoot":"","sources":["../../src/state/reviews.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"reviews.d.ts","sourceRoot":"","sources":["../../src/state/reviews.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAI7C,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,EAAE,CAepE;AAED,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,EAAE,CAAC,CAgBnB;AAED,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,MAAM,GACd;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAYxC"}
|
package/dist/state/reviews.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { readdir } from 'node:fs/promises';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { isMissingFileError } from '../shared/utils/errors.js';
|
|
4
|
+
import { parseFrontmatterRecord } from '../shared/utils/frontmatter.js';
|
|
4
5
|
const REVIEWS_HEADING = '## Reviews';
|
|
5
6
|
export function parseReviewTable(planContent) {
|
|
6
7
|
const reviewsSection = extractReviewsSection(planContent);
|
|
@@ -32,13 +33,23 @@ export async function scanUnprocessedReviews(projectPath) {
|
|
|
32
33
|
throw error;
|
|
33
34
|
}
|
|
34
35
|
}
|
|
36
|
+
export function parseReviewArtifactIdentity(content) {
|
|
37
|
+
const frontmatter = parseFrontmatterRecord(content);
|
|
38
|
+
const scope = typeof frontmatter.oat_review_scope === 'string'
|
|
39
|
+
? frontmatter.oat_review_scope.trim()
|
|
40
|
+
: '';
|
|
41
|
+
const type = typeof frontmatter.oat_review_type === 'string'
|
|
42
|
+
? frontmatter.oat_review_type.trim()
|
|
43
|
+
: '';
|
|
44
|
+
return scope && type ? { scope, type } : null;
|
|
45
|
+
}
|
|
35
46
|
function extractReviewsSection(planContent) {
|
|
36
|
-
const
|
|
37
|
-
if (
|
|
47
|
+
const reviewsHeading = new RegExp(`^${REVIEWS_HEADING}[ \\t]*\\r?$`, 'm').exec(planContent);
|
|
48
|
+
if (!reviewsHeading) {
|
|
38
49
|
return null;
|
|
39
50
|
}
|
|
40
|
-
const remaining = planContent.slice(
|
|
41
|
-
const nextHeadingIndex = remaining.search(
|
|
51
|
+
const remaining = planContent.slice(reviewsHeading.index + reviewsHeading[0].length);
|
|
52
|
+
const nextHeadingIndex = remaining.search(/^##(?!#)[ \t]+\S.*\r?$/m);
|
|
42
53
|
if (nextHeadingIndex === -1) {
|
|
43
54
|
return remaining.trim();
|
|
44
55
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-agent-toolkit/control-plane",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.69",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Read-only OAT control-plane library for structured project state",
|
|
6
6
|
"homepage": "https://github.com/voxmedia/open-agent-toolkit/tree/main/packages/control-plane",
|