@caiqueoak/flow 0.6.0 → 0.8.0
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/README.md +65 -43
- package/dist/artifacts/backlog.d.mts +16 -0
- package/dist/artifacts/backlog.d.mts.map +1 -0
- package/dist/artifacts/backlog.mjs +193 -0
- package/dist/artifacts/backlog.mjs.map +1 -0
- package/dist/artifacts/document.d.mts +6 -0
- package/dist/artifacts/document.d.mts.map +1 -0
- package/dist/artifacts/document.mjs +39 -0
- package/dist/artifacts/document.mjs.map +1 -0
- package/dist/artifacts/engineering.d.mts +5 -0
- package/dist/artifacts/engineering.d.mts.map +1 -0
- package/dist/artifacts/engineering.mjs +27 -0
- package/dist/artifacts/engineering.mjs.map +1 -0
- package/dist/artifacts/gates.d.mts +7 -0
- package/dist/artifacts/gates.d.mts.map +1 -0
- package/dist/artifacts/gates.mjs +42 -0
- package/dist/artifacts/gates.mjs.map +1 -0
- package/dist/artifacts/implementation-plan.d.mts +11 -0
- package/dist/artifacts/implementation-plan.d.mts.map +1 -0
- package/dist/artifacts/implementation-plan.mjs +30 -0
- package/dist/artifacts/implementation-plan.mjs.map +1 -0
- package/dist/artifacts/prd.d.mts +4 -0
- package/dist/artifacts/prd.d.mts.map +1 -0
- package/dist/artifacts/prd.mjs +13 -0
- package/dist/artifacts/prd.mjs.map +1 -0
- package/dist/artifacts/review.d.mts +11 -0
- package/dist/artifacts/review.d.mts.map +1 -0
- package/dist/artifacts/review.mjs +27 -0
- package/dist/artifacts/review.mjs.map +1 -0
- package/dist/artifacts/spec.d.mts +14 -0
- package/dist/artifacts/spec.d.mts.map +1 -0
- package/dist/artifacts/spec.mjs +50 -0
- package/dist/artifacts/spec.mjs.map +1 -0
- package/dist/artifacts/state.d.mts +44 -0
- package/dist/artifacts/state.d.mts.map +1 -0
- package/dist/artifacts/state.mjs +60 -0
- package/dist/artifacts/state.mjs.map +1 -0
- package/dist/artifacts/tasks.d.mts +10 -0
- package/dist/artifacts/tasks.d.mts.map +1 -0
- package/dist/artifacts/tasks.mjs +107 -0
- package/dist/artifacts/tasks.mjs.map +1 -0
- package/dist/artifacts/work-items.d.mts +21 -0
- package/dist/artifacts/work-items.d.mts.map +1 -0
- package/dist/artifacts/work-items.mjs +81 -0
- package/dist/artifacts/work-items.mjs.map +1 -0
- package/dist/cli/command-registry.d.mts +498 -0
- package/dist/cli/command-registry.d.mts.map +1 -0
- package/dist/cli/command-registry.mjs +230 -0
- package/dist/cli/command-registry.mjs.map +1 -0
- package/dist/cli.d.mts +3 -0
- package/dist/cli.d.mts.map +1 -0
- package/dist/cli.mjs +48 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/commands/doctor.d.mts +21 -0
- package/dist/commands/doctor.d.mts.map +1 -0
- package/dist/commands/doctor.mjs +79 -0
- package/dist/commands/doctor.mjs.map +1 -0
- package/dist/commands/gates.d.mts +14 -0
- package/dist/commands/gates.d.mts.map +1 -0
- package/dist/commands/gates.mjs +136 -0
- package/dist/commands/gates.mjs.map +1 -0
- package/dist/commands/graph.d.mts +11 -0
- package/dist/commands/graph.d.mts.map +1 -0
- package/dist/commands/graph.mjs +78 -0
- package/dist/commands/graph.mjs.map +1 -0
- package/dist/commands/init.d.mts +6 -0
- package/dist/commands/init.d.mts.map +1 -0
- package/dist/commands/init.mjs +126 -0
- package/dist/commands/init.mjs.map +1 -0
- package/dist/commands/migrate.d.mts +27 -0
- package/dist/commands/migrate.d.mts.map +1 -0
- package/dist/commands/migrate.mjs +379 -0
- package/dist/commands/migrate.mjs.map +1 -0
- package/dist/commands/operations.d.mts +13 -0
- package/dist/commands/operations.d.mts.map +1 -0
- package/dist/commands/operations.mjs +340 -0
- package/dist/commands/operations.mjs.map +1 -0
- package/dist/commands/route.d.mts +12 -0
- package/dist/commands/route.d.mts.map +1 -0
- package/dist/commands/route.mjs +45 -0
- package/dist/commands/route.mjs.map +1 -0
- package/dist/commands/schemas.d.mts +5 -0
- package/dist/commands/schemas.d.mts.map +1 -0
- package/dist/commands/schemas.mjs +14 -0
- package/dist/commands/schemas.mjs.map +1 -0
- package/dist/commands/status.d.mts +4 -0
- package/dist/commands/status.d.mts.map +1 -0
- package/dist/commands/status.mjs +18 -0
- package/dist/commands/status.mjs.map +1 -0
- package/dist/commands/sync.d.mts +18 -0
- package/dist/commands/sync.d.mts.map +1 -0
- package/dist/commands/sync.mjs +29 -0
- package/dist/commands/sync.mjs.map +1 -0
- package/dist/commands/trace.d.mts +30 -0
- package/dist/commands/trace.d.mts.map +1 -0
- package/dist/commands/trace.mjs +111 -0
- package/dist/commands/trace.mjs.map +1 -0
- package/dist/commands/validate.d.mts +8 -0
- package/dist/commands/validate.d.mts.map +1 -0
- package/dist/commands/validate.mjs +82 -0
- package/dist/commands/validate.mjs.map +1 -0
- package/dist/domain/contracts.d.mts +203 -0
- package/dist/domain/contracts.d.mts.map +1 -0
- package/dist/domain/contracts.mjs +126 -0
- package/dist/domain/contracts.mjs.map +1 -0
- package/dist/domain/types.d.ts +45 -0
- package/dist/domain/types.d.ts.map +1 -0
- package/dist/domain/types.js +2 -0
- package/dist/domain/types.js.map +1 -0
- package/dist/entry.d.ts +3 -0
- package/dist/entry.d.ts.map +1 -0
- package/dist/entry.js +4 -0
- package/dist/entry.js.map +1 -0
- package/dist/shared/cli-io.d.mts +15 -0
- package/dist/shared/cli-io.d.mts.map +1 -0
- package/dist/shared/cli-io.mjs +83 -0
- package/dist/shared/cli-io.mjs.map +1 -0
- package/dist/shared/profiles.d.mts +17 -0
- package/dist/shared/profiles.d.mts.map +1 -0
- package/dist/shared/profiles.mjs +25 -0
- package/dist/shared/profiles.mjs.map +1 -0
- package/dist/shared/project-config.d.mts +21 -0
- package/dist/shared/project-config.d.mts.map +1 -0
- package/dist/shared/project-config.mjs +41 -0
- package/dist/shared/project-config.mjs.map +1 -0
- package/dist/shared/project-path.d.mts +3 -0
- package/dist/shared/project-path.d.mts.map +1 -0
- package/dist/shared/project-path.mjs +9 -0
- package/dist/shared/project-path.mjs.map +1 -0
- package/dist/shared/skill-installer.d.mts +2 -0
- package/dist/shared/skill-installer.d.mts.map +1 -0
- package/dist/shared/skill-installer.mjs +33 -0
- package/dist/shared/skill-installer.mjs.map +1 -0
- package/package.json +16 -8
- package/schemas/backlog.schema.json +85 -0
- package/schemas/config.schema.json +29 -0
- package/schemas/gates.schema.json +17 -0
- package/schemas/review.schema.json +28 -0
- package/schemas/tasks.schema.json +66 -0
- package/skills/flow/SKILL.md +10 -11
- package/skills/flow/build/step-01-execute-task.md +3 -3
- package/skills/flow/discovery/bmad-comparison.md +5 -0
- package/skills/flow/discovery/step-01-project.md +8 -3
- package/skills/flow/engineering/profiles/readability-first.md +1 -0
- package/skills/flow/engineering/step-02-synthesize.md +2 -2
- package/skills/flow/invariants.md +4 -4
- package/skills/flow/planning/step-01-create-tasks.md +3 -0
- package/skills/flow/planning/step-01-plan-work-item.md +2 -2
- package/skills/flow/planning/step-02-prepare-plan.md +1 -1
- package/skills/flow/review/step-01-review-work-item.md +2 -2
- package/skills/flow/specification/step-01-deepen-spec.md +7 -0
- package/src/artifacts/backlog.mjs +0 -157
- package/src/artifacts/document.mjs +0 -30
- package/src/artifacts/engineering.mjs +0 -26
- package/src/artifacts/gates.mjs +0 -28
- package/src/artifacts/implementation-plan.mjs +0 -27
- package/src/artifacts/prd.mjs +0 -12
- package/src/artifacts/state.mjs +0 -63
- package/src/artifacts/tasks.mjs +0 -90
- package/src/cli.mjs +0 -62
- package/src/commands/gates.mjs +0 -71
- package/src/commands/graph.mjs +0 -92
- package/src/commands/init.mjs +0 -111
- package/src/commands/migrate.mjs +0 -224
- package/src/commands/route.mjs +0 -135
- package/src/commands/status.mjs +0 -35
- package/src/commands/trace.mjs +0 -58
- package/src/commands/validate.mjs +0 -197
- package/src/shared/cli-io.mjs +0 -86
- package/src/shared/profiles.mjs +0 -27
- package/src/shared/project-config.mjs +0 -39
- package/src/shared/project-path.mjs +0 -10
- package/src/shared/skill-installer.mjs +0 -34
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { validateDocument } from './document.mjs';
|
|
2
|
+
export function validatePrdDocument(text) {
|
|
3
|
+
return validateDocument(text, [
|
|
4
|
+
'# Product Requirements',
|
|
5
|
+
'## Purpose',
|
|
6
|
+
'## Users',
|
|
7
|
+
'## Scope',
|
|
8
|
+
'## Requirements',
|
|
9
|
+
'## Constraints',
|
|
10
|
+
'## Non-goals'
|
|
11
|
+
]);
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=prd.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prd.mjs","sourceRoot":"","sources":["../../src/artifacts/prd.mjs"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,MAAM,UAAU,mBAAmB,CAAC,IAAI;IACtC,OAAO,gBAAgB,CAAC,IAAI,EAAE;QAC5B,wBAAwB;QACxB,YAAY;QACZ,UAAU;QACV,UAAU;QACV,iBAAiB;QACjB,gBAAgB;QAChB,cAAc;KACf,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare function parseReview(text: any, { expectedWorkItem, source }?: {
|
|
2
|
+
expectedWorkItem?: null | undefined;
|
|
3
|
+
source?: string | undefined;
|
|
4
|
+
}): {
|
|
5
|
+
schema_version: number;
|
|
6
|
+
work_item: any;
|
|
7
|
+
status: any;
|
|
8
|
+
reviewed_at?: any;
|
|
9
|
+
};
|
|
10
|
+
export declare const stringifyReview: (value: any) => any;
|
|
11
|
+
//# sourceMappingURL=review.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review.d.mts","sourceRoot":"","sources":["../../src/artifacts/review.mjs"],"names":[],"mappings":"AAGA,wBAAgB,WAAW,CAAC,IAAI,KAAA,EAAE,EAAE,gBAAuB,EAAE,MAAsB,EAAE;;;CAAK;;;;;EAoBzF;AACD,eAAO,MAAM,eAAe,qBAAwE,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { parseDocument, stringify } from 'yaml';
|
|
2
|
+
import { ArtifactValidationError } from './backlog.mjs';
|
|
3
|
+
import { REVIEW_SCHEMA_VERSION, WORK_ITEM_ID } from '../domain/contracts.mjs';
|
|
4
|
+
export function parseReview(text, { expectedWorkItem = null, source = 'review.yaml' } = {}) {
|
|
5
|
+
const doc = parseDocument(text, { prettyErrors: false, uniqueKeys: true });
|
|
6
|
+
if (doc.errors.length)
|
|
7
|
+
throw new ArtifactValidationError(`${source} is invalid: ${doc.errors[0].message}`);
|
|
8
|
+
const v = doc.toJS();
|
|
9
|
+
if (!v || typeof v !== 'object' || Array.isArray(v))
|
|
10
|
+
throw new ArtifactValidationError(`${source} must be a mapping.`);
|
|
11
|
+
if (v.schema_version !== REVIEW_SCHEMA_VERSION)
|
|
12
|
+
throw new ArtifactValidationError(`${source} schema_version must be ${REVIEW_SCHEMA_VERSION}.`);
|
|
13
|
+
if (!WORK_ITEM_ID.test(v.work_item ?? '') || (expectedWorkItem && v.work_item !== expectedWorkItem))
|
|
14
|
+
throw new ArtifactValidationError(`${source} has an invalid work_item.`);
|
|
15
|
+
if (!['pending', 'approved'].includes(v.status))
|
|
16
|
+
throw new ArtifactValidationError(`${source}.status must be pending or approved.`);
|
|
17
|
+
if (v.status === 'approved' && v.reviewed_at !== undefined && Number.isNaN(Date.parse(v.reviewed_at)))
|
|
18
|
+
throw new ArtifactValidationError(`${source}.reviewed_at must be ISO.`);
|
|
19
|
+
return {
|
|
20
|
+
schema_version: REVIEW_SCHEMA_VERSION,
|
|
21
|
+
work_item: v.work_item,
|
|
22
|
+
status: v.status,
|
|
23
|
+
...(v.reviewed_at ? { reviewed_at: v.reviewed_at } : {})
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export const stringifyReview = (value) => stringify(parseReview(stringify(value)), { lineWidth: 0 });
|
|
27
|
+
//# sourceMappingURL=review.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review.mjs","sourceRoot":"","sources":["../../src/artifacts/review.mjs"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAChD,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC9E,MAAM,UAAU,WAAW,CAAC,IAAI,EAAE,EAAE,gBAAgB,GAAG,IAAI,EAAE,MAAM,GAAG,aAAa,EAAE,GAAG,EAAE;IACxF,MAAM,GAAG,GAAG,aAAa,CAAC,IAAI,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3E,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM;QAAE,MAAM,IAAI,uBAAuB,CAAC,GAAG,MAAM,gBAAgB,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;IAC3G,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IACrB,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QACjD,MAAM,IAAI,uBAAuB,CAAC,GAAG,MAAM,qBAAqB,CAAC,CAAC;IACpE,IAAI,CAAC,CAAC,cAAc,KAAK,qBAAqB;QAC5C,MAAM,IAAI,uBAAuB,CAAC,GAAG,MAAM,2BAA2B,qBAAqB,GAAG,CAAC,CAAC;IAClG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,IAAI,EAAE,CAAC,IAAI,CAAC,gBAAgB,IAAI,CAAC,CAAC,SAAS,KAAK,gBAAgB,CAAC;QACjG,MAAM,IAAI,uBAAuB,CAAC,GAAG,MAAM,4BAA4B,CAAC,CAAC;IAC3E,IAAI,CAAC,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;QAC7C,MAAM,IAAI,uBAAuB,CAAC,GAAG,MAAM,sCAAsC,CAAC,CAAC;IACrF,IAAI,CAAC,CAAC,MAAM,KAAK,UAAU,IAAI,CAAC,CAAC,WAAW,KAAK,SAAS,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;QACnG,MAAM,IAAI,uBAAuB,CAAC,GAAG,MAAM,2BAA2B,CAAC,CAAC;IAC1E,OAAO;QACL,cAAc,EAAE,qBAAqB;QACrC,SAAS,EAAE,CAAC,CAAC,SAAS;QACtB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACzD,CAAC;AACJ,CAAC;AACD,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,WAAW,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare const SPEC_HEADINGS: readonly string[];
|
|
2
|
+
export declare function parseWorkItemSpec(text: any, { expectedWorkItem }?: {
|
|
3
|
+
expectedWorkItem?: null | undefined;
|
|
4
|
+
}): {
|
|
5
|
+
metadata: any;
|
|
6
|
+
body: any;
|
|
7
|
+
};
|
|
8
|
+
export declare function validateSpec(text: any, options?: {}): {
|
|
9
|
+
metadata: any;
|
|
10
|
+
body: any;
|
|
11
|
+
valid: boolean;
|
|
12
|
+
errors: string[];
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=spec.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec.d.mts","sourceRoot":"","sources":["../../src/artifacts/spec.mjs"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,mBAaxB,CAAC;AAKH,wBAAgB,iBAAiB,CAAC,IAAI,KAAA,EAAE,EAAE,gBAAuB,EAAE;;CAAK;IAuB7D,QAAQ;IAAK,IAAI;EAC3B;AACD,wBAAgB,YAAY,CAAC,IAAI,KAAA,EAAE,OAAO,KAAK;;;;;EAM9C"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export const SPEC_HEADINGS = Object.freeze([
|
|
2
|
+
'# Work Item Specification',
|
|
3
|
+
'## Problem',
|
|
4
|
+
'## Scope',
|
|
5
|
+
'## Non-goals',
|
|
6
|
+
'## Requirements',
|
|
7
|
+
'## Acceptance criteria',
|
|
8
|
+
'## Contracts',
|
|
9
|
+
'## Data and APIs',
|
|
10
|
+
'## Edge cases',
|
|
11
|
+
'## Risks',
|
|
12
|
+
'## Decisions',
|
|
13
|
+
'## Gates'
|
|
14
|
+
]);
|
|
15
|
+
import { parseDocument } from 'yaml';
|
|
16
|
+
import { ArtifactValidationError } from './backlog.mjs';
|
|
17
|
+
import { WORK_ITEM_ID } from '../domain/contracts.mjs';
|
|
18
|
+
export function parseWorkItemSpec(text, { expectedWorkItem = null } = {}) {
|
|
19
|
+
const match = text.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/);
|
|
20
|
+
if (!match)
|
|
21
|
+
throw new ArtifactValidationError('spec.md requires YAML frontmatter.');
|
|
22
|
+
const doc = parseDocument(match[1], { prettyErrors: false, uniqueKeys: true });
|
|
23
|
+
if (doc.errors.length)
|
|
24
|
+
throw new ArtifactValidationError(`spec.md frontmatter is invalid: ${doc.errors[0].message}`);
|
|
25
|
+
const m = doc.toJS();
|
|
26
|
+
if (!m ||
|
|
27
|
+
m.schema_version !== 1 ||
|
|
28
|
+
!WORK_ITEM_ID.test(m.work_item ?? '') ||
|
|
29
|
+
(expectedWorkItem && m.work_item !== expectedWorkItem))
|
|
30
|
+
throw new ArtifactValidationError('spec.md has invalid schema_version or work_item.');
|
|
31
|
+
if (!m.title?.trim() ||
|
|
32
|
+
!['feature', 'technical', 'maintenance'].includes(m.kind) ||
|
|
33
|
+
!Number.isInteger(m.priority) ||
|
|
34
|
+
m.priority < 1 ||
|
|
35
|
+
!['outlined', 'ready'].includes(m.maturity))
|
|
36
|
+
throw new ArtifactValidationError('spec.md has invalid canonical metadata.');
|
|
37
|
+
for (const key of ['depends_on', 'blockers'])
|
|
38
|
+
if (!Array.isArray(m[key]))
|
|
39
|
+
throw new ArtifactValidationError(`spec.md ${key} must be a list.`);
|
|
40
|
+
return { metadata: m, body: match[2] };
|
|
41
|
+
}
|
|
42
|
+
export function validateSpec(text, options = {}) {
|
|
43
|
+
const parsed = parseWorkItemSpec(text, options);
|
|
44
|
+
if (parsed.metadata.maturity === 'outlined')
|
|
45
|
+
return { valid: true, errors: [], ...parsed };
|
|
46
|
+
const lines = new Set(parsed.body.split(/\r?\n/));
|
|
47
|
+
const errors = SPEC_HEADINGS.filter((heading) => !lines.has(heading)).map((heading) => `Missing ${heading}.`);
|
|
48
|
+
return { valid: errors.length === 0, errors, ...parsed };
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=spec.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec.mjs","sourceRoot":"","sources":["../../src/artifacts/spec.mjs"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export declare const WORKFLOW_STEPS: Readonly<{
|
|
2
|
+
discovery: string[];
|
|
3
|
+
prd: string[];
|
|
4
|
+
engineering: string[];
|
|
5
|
+
backlog: string[];
|
|
6
|
+
specification: string[];
|
|
7
|
+
planning: string[];
|
|
8
|
+
implementation: string[];
|
|
9
|
+
review: string[];
|
|
10
|
+
reconcile: string[];
|
|
11
|
+
complete: string[];
|
|
12
|
+
}>;
|
|
13
|
+
export declare function emptyState(): {
|
|
14
|
+
schema_version: number;
|
|
15
|
+
execution: {
|
|
16
|
+
phase: string;
|
|
17
|
+
step: string;
|
|
18
|
+
};
|
|
19
|
+
active: {
|
|
20
|
+
work_item: null;
|
|
21
|
+
task: null;
|
|
22
|
+
};
|
|
23
|
+
stop_reason: null;
|
|
24
|
+
migration: {
|
|
25
|
+
status: string;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
export declare function parseState(text: any, { source }?: {
|
|
29
|
+
source?: string | undefined;
|
|
30
|
+
}): {
|
|
31
|
+
schema_version: number;
|
|
32
|
+
execution: {
|
|
33
|
+
phase: any;
|
|
34
|
+
step: any;
|
|
35
|
+
};
|
|
36
|
+
active: {
|
|
37
|
+
work_item: any;
|
|
38
|
+
task: any;
|
|
39
|
+
};
|
|
40
|
+
stop_reason: any;
|
|
41
|
+
migration: any;
|
|
42
|
+
};
|
|
43
|
+
export declare function stringifyState(state: any): any;
|
|
44
|
+
//# sourceMappingURL=state.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.mts","sourceRoot":"","sources":["../../src/artifacts/state.mjs"],"names":[],"mappings":"AAKA,eAAO,MAAM,cAAc;;;;;;;;;;;EAAW,CAAC;AAGvC,wBAAgB,UAAU;;;QAGT,KAAK;QAAe,IAAI;;;QAC3B,SAAS;QAAQ,IAAI;;;;QAElB,MAAM;;EAEtB;AAED,wBAAgB,UAAU,CAAC,IAAI,KAAA,EAAE,EAAE,MAAqB,EAAE;;CAAK;;;;;;;QAgCzD,SAAS;QACT,IAAI;;;;EAKT;AAED,wBAAgB,cAAc,CAAC,KAAK,KAAA,OAEnC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { parseDocument, stringify } from 'yaml';
|
|
2
|
+
import { ArtifactValidationError } from './backlog.mjs';
|
|
3
|
+
import { STATE_SCHEMA_VERSION, WORKFLOW, WORK_ITEM_ID, QUALIFIED_TASK_ID } from '../domain/contracts.mjs';
|
|
4
|
+
const PHASES = new Set(Object.keys(WORKFLOW));
|
|
5
|
+
export const WORKFLOW_STEPS = WORKFLOW;
|
|
6
|
+
const STOP_REASONS = new Set([null, 'consequential_decision', 'external_action', 'unrecoverable_blocker', 'finished']);
|
|
7
|
+
export function emptyState() {
|
|
8
|
+
return {
|
|
9
|
+
schema_version: STATE_SCHEMA_VERSION,
|
|
10
|
+
execution: { phase: 'discovery', step: 'define_problem' },
|
|
11
|
+
active: { work_item: null, task: null },
|
|
12
|
+
stop_reason: null,
|
|
13
|
+
migration: { status: 'not_required' }
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export function parseState(text, { source = 'state.yaml' } = {}) {
|
|
17
|
+
const document = parseDocument(text, { prettyErrors: false, uniqueKeys: true });
|
|
18
|
+
if (document.errors.length)
|
|
19
|
+
throw new ArtifactValidationError(`${source} is invalid: ${document.errors[0].message}`);
|
|
20
|
+
const value = document.toJS();
|
|
21
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
22
|
+
throw new ArtifactValidationError(`${source} must be a mapping.`);
|
|
23
|
+
if (value.schema_version !== STATE_SCHEMA_VERSION)
|
|
24
|
+
throw new ArtifactValidationError(`${source} schema_version must be ${STATE_SCHEMA_VERSION}.`);
|
|
25
|
+
const phase = value.execution?.phase;
|
|
26
|
+
if (!PHASES.has(phase))
|
|
27
|
+
throw new ArtifactValidationError(`${source} execution.phase is invalid.`);
|
|
28
|
+
const step = value.execution?.step;
|
|
29
|
+
if (!WORKFLOW_STEPS[phase].includes(step))
|
|
30
|
+
throw new ArtifactValidationError(`${source} execution.step '${step}' is invalid for phase '${phase}'.`);
|
|
31
|
+
if (!STOP_REASONS.has(value.stop_reason ?? null))
|
|
32
|
+
throw new ArtifactValidationError(`${source} stop_reason is invalid.`);
|
|
33
|
+
if (!['not_required', 'pending_reconciliation', 'completed'].includes(value.migration?.status ?? 'not_required'))
|
|
34
|
+
throw new ArtifactValidationError(`${source} migration.status is invalid.`);
|
|
35
|
+
const activeWorkItem = value.active?.work_item ?? null;
|
|
36
|
+
const activeTask = value.active?.task ?? null;
|
|
37
|
+
if (activeWorkItem !== null && !WORK_ITEM_ID.test(activeWorkItem))
|
|
38
|
+
throw new ArtifactValidationError(`${source} active.work_item is invalid.`);
|
|
39
|
+
if (activeTask !== null && !QUALIFIED_TASK_ID.test(activeTask))
|
|
40
|
+
throw new ArtifactValidationError(`${source} active.task is invalid.`);
|
|
41
|
+
if (activeTask && activeWorkItem && !activeTask.startsWith(`${activeWorkItem}-`))
|
|
42
|
+
throw new ArtifactValidationError(`${source} active.task does not belong to active.work_item.`);
|
|
43
|
+
return {
|
|
44
|
+
schema_version: STATE_SCHEMA_VERSION,
|
|
45
|
+
execution: {
|
|
46
|
+
phase,
|
|
47
|
+
step
|
|
48
|
+
},
|
|
49
|
+
active: {
|
|
50
|
+
work_item: activeWorkItem,
|
|
51
|
+
task: activeTask
|
|
52
|
+
},
|
|
53
|
+
stop_reason: value.stop_reason ?? null,
|
|
54
|
+
migration: value.migration ?? { status: 'not_required' }
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
export function stringifyState(state) {
|
|
58
|
+
return stringify(state, { lineWidth: 0 });
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=state.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.mjs","sourceRoot":"","sources":["../../src/artifacts/state.mjs"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare function parseTasks(text: any, { source, expectedWorkItem }?: {
|
|
2
|
+
expectedWorkItem?: null | undefined;
|
|
3
|
+
source?: string | undefined;
|
|
4
|
+
}): {
|
|
5
|
+
schema_version: number;
|
|
6
|
+
work_item: any;
|
|
7
|
+
tasks: any;
|
|
8
|
+
};
|
|
9
|
+
export declare function qualifiedTaskId(workItem: any, task: any): string;
|
|
10
|
+
//# sourceMappingURL=tasks.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tasks.d.mts","sourceRoot":"","sources":["../../src/artifacts/tasks.mjs"],"names":[],"mappings":"AAmBA,wBAAgB,UAAU,CAAC,IAAI,KAAA,EAAE,EAAE,MAAqB,EAAE,gBAAuB,EAAE;;;CAAK;;;;EAsDvF;AAoBD,wBAAgB,eAAe,CAAC,QAAQ,KAAA,EAAE,IAAI,KAAA,UAE7C"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { parseDocument } from 'yaml';
|
|
2
|
+
import { ArtifactValidationError } from './backlog.mjs';
|
|
3
|
+
import { LIFECYCLE_STATES, TASKS_SCHEMA_VERSION, TASK_ID as TASK_ID_PATTERN } from '../domain/contracts.mjs';
|
|
4
|
+
const STATES = new Set(LIFECYCLE_STATES);
|
|
5
|
+
const TASK_ID = TASK_ID_PATTERN;
|
|
6
|
+
function fail(message) {
|
|
7
|
+
throw new ArtifactValidationError(message);
|
|
8
|
+
}
|
|
9
|
+
function requireObject(value, label) {
|
|
10
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
11
|
+
fail(`${label} must be a mapping.`);
|
|
12
|
+
return value;
|
|
13
|
+
}
|
|
14
|
+
function requireString(value, label) {
|
|
15
|
+
if (typeof value !== 'string' || !value.trim())
|
|
16
|
+
fail(`${label} must be a non-empty string.`);
|
|
17
|
+
return value.trim();
|
|
18
|
+
}
|
|
19
|
+
export function parseTasks(text, { source = 'tasks.yaml', expectedWorkItem = null } = {}) {
|
|
20
|
+
const document = parseDocument(text, { prettyErrors: false, uniqueKeys: true });
|
|
21
|
+
if (document.errors.length)
|
|
22
|
+
fail(`${source} is invalid: ${document.errors[0].message}`);
|
|
23
|
+
const value = requireObject(document.toJS(), source);
|
|
24
|
+
if (value.schema_version !== TASKS_SCHEMA_VERSION)
|
|
25
|
+
fail(`${source} schema_version must be ${TASKS_SCHEMA_VERSION}.`);
|
|
26
|
+
const workItem = requireString(value.work_item, `${source} work_item`);
|
|
27
|
+
if (expectedWorkItem && workItem !== expectedWorkItem)
|
|
28
|
+
fail(`${source} belongs to ${workItem}, expected ${expectedWorkItem}.`);
|
|
29
|
+
if (!Array.isArray(value.tasks))
|
|
30
|
+
fail(`${source} tasks must be a list.`);
|
|
31
|
+
const ids = new Set();
|
|
32
|
+
const tasks = value.tasks.map((raw, index) => {
|
|
33
|
+
const label = `tasks[${index}]`;
|
|
34
|
+
const task = requireObject(raw, label);
|
|
35
|
+
const id = requireString(task.id, `${label}.id`);
|
|
36
|
+
if (!TASK_ID.test(id))
|
|
37
|
+
fail(`${label}.id must use T followed by a zero-padded numeric sequence, e.g. T003.`);
|
|
38
|
+
if (ids.has(id))
|
|
39
|
+
fail(`${source} contains duplicate task ID '${id}'.`);
|
|
40
|
+
ids.add(id);
|
|
41
|
+
const title = requireString(task.title, `${label}.title`);
|
|
42
|
+
const state = task.state ?? task.status;
|
|
43
|
+
if (!STATES.has(state))
|
|
44
|
+
fail(`${label}.state must be pending, in_progress, or completed.`);
|
|
45
|
+
if (!Array.isArray(task.depends_on ?? []))
|
|
46
|
+
fail(`${label}.depends_on must be a list.`);
|
|
47
|
+
const dependencies = [...new Set(task.depends_on ?? [])];
|
|
48
|
+
if (dependencies.length !== (task.depends_on ?? []).length)
|
|
49
|
+
fail(`${id} contains duplicate task dependencies.`);
|
|
50
|
+
for (const dependency of dependencies) {
|
|
51
|
+
if (!TASK_ID.test(dependency))
|
|
52
|
+
fail(`${id} depends on invalid task ID '${dependency}'.`);
|
|
53
|
+
if (dependency === id)
|
|
54
|
+
fail(`${id} cannot depend on itself.`);
|
|
55
|
+
}
|
|
56
|
+
if (Object.hasOwn(task, 'traceability') ||
|
|
57
|
+
Object.hasOwn(task, 'implementation') ||
|
|
58
|
+
Object.hasOwn(task, 'commit_sha'))
|
|
59
|
+
fail(`${id}: traceability, implementation and commit_sha are retired.`);
|
|
60
|
+
if (task.provenance !== undefined && task.provenance !== 'legacy_migration')
|
|
61
|
+
fail(`${id}.provenance must be legacy_migration when present.`);
|
|
62
|
+
if (task.provenance === 'legacy_migration' && state !== 'completed')
|
|
63
|
+
fail(`${id}: legacy_migration is reserved for completed migrated tasks.`);
|
|
64
|
+
return {
|
|
65
|
+
id,
|
|
66
|
+
title,
|
|
67
|
+
state,
|
|
68
|
+
depends_on: dependencies,
|
|
69
|
+
...(task.provenance ? { provenance: task.provenance } : {}),
|
|
70
|
+
...(task.legacy_commit ? { legacy_commit: task.legacy_commit } : {})
|
|
71
|
+
};
|
|
72
|
+
});
|
|
73
|
+
const byId = new Map(tasks.map((task) => [task.id, task]));
|
|
74
|
+
for (const task of tasks)
|
|
75
|
+
for (const dependency of task.depends_on)
|
|
76
|
+
if (!byId.has(dependency))
|
|
77
|
+
fail(`${task.id} depends on unknown task '${dependency}'.`);
|
|
78
|
+
validateTaskDag(tasks);
|
|
79
|
+
if (tasks.filter((task) => task.state === 'in_progress').length > 1)
|
|
80
|
+
fail('Only one mutating task may be in_progress.');
|
|
81
|
+
return { schema_version: TASKS_SCHEMA_VERSION, work_item: workItem, tasks };
|
|
82
|
+
}
|
|
83
|
+
function validateTaskDag(tasks) {
|
|
84
|
+
const indegree = new Map(tasks.map((task) => [task.id, task.depends_on.length]));
|
|
85
|
+
const dependents = new Map(tasks.map((task) => [task.id, []]));
|
|
86
|
+
for (const task of tasks)
|
|
87
|
+
for (const dependency of task.depends_on)
|
|
88
|
+
dependents.get(dependency).push(task.id);
|
|
89
|
+
const queue = tasks.filter((task) => task.depends_on.length === 0).map((task) => task.id);
|
|
90
|
+
let visited = 0;
|
|
91
|
+
while (queue.length) {
|
|
92
|
+
const id = queue.shift();
|
|
93
|
+
visited += 1;
|
|
94
|
+
for (const dependent of dependents.get(id)) {
|
|
95
|
+
const next = indegree.get(dependent) - 1;
|
|
96
|
+
indegree.set(dependent, next);
|
|
97
|
+
if (next === 0)
|
|
98
|
+
queue.push(dependent);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (visited !== tasks.length)
|
|
102
|
+
fail('tasks.yaml task dependencies contain a cycle.');
|
|
103
|
+
}
|
|
104
|
+
export function qualifiedTaskId(workItem, task) {
|
|
105
|
+
return `${workItem}-${task}`;
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=tasks.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tasks.mjs","sourceRoot":"","sources":["../../src/artifacts/tasks.mjs"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export declare function workItemsDirectory(root: any): any;
|
|
2
|
+
export declare function loadWorkItems(root: any): any;
|
|
3
|
+
export declare function lifecycle(item: any, byId: any): {
|
|
4
|
+
status: string;
|
|
5
|
+
reasons: any[];
|
|
6
|
+
};
|
|
7
|
+
export declare function derivedBacklog(items: any): {
|
|
8
|
+
schema_version: number;
|
|
9
|
+
work_items: {
|
|
10
|
+
id: any;
|
|
11
|
+
folder: any;
|
|
12
|
+
title: any;
|
|
13
|
+
kind: any;
|
|
14
|
+
priority: any;
|
|
15
|
+
spec_maturity: any;
|
|
16
|
+
depends_on: any;
|
|
17
|
+
blockers: any;
|
|
18
|
+
state: string;
|
|
19
|
+
}[];
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=work-items.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"work-items.d.mts","sourceRoot":"","sources":["../../src/artifacts/work-items.mjs"],"names":[],"mappings":"AASA,wBAAgB,kBAAkB,CAAC,IAAI,KAAA,OAEtC;AACD,wBAAgB,aAAa,CAAC,IAAI,KAAA,OA2BjC;AACD,wBAAgB,SAAS,CAAC,IAAI,KAAA,EAAE,IAAI,KAAA;;;EAgBnC;AACD,wBAAgB,cAAc,CAAC,KAAK,KAAA;IAGhC,cAAc;IACd,UAAU;;;;;;;;;;;EAYb"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { parseWorkItemSpec } from './spec.mjs';
|
|
4
|
+
import { parseTasks } from './tasks.mjs';
|
|
5
|
+
import { parseReview } from './review.mjs';
|
|
6
|
+
import { validateAcyclic, ArtifactValidationError, topologicalOrder } from './backlog.mjs';
|
|
7
|
+
const folderPattern = /^(W\d{3,})-[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
8
|
+
const read = (file) => fs.readFileSync(file, 'utf8');
|
|
9
|
+
export function workItemsDirectory(root) {
|
|
10
|
+
return path.join(root, '_flow', 'work-items');
|
|
11
|
+
}
|
|
12
|
+
export function loadWorkItems(root) {
|
|
13
|
+
const dir = workItemsDirectory(root);
|
|
14
|
+
if (!fs.existsSync(dir))
|
|
15
|
+
return [];
|
|
16
|
+
const items = fs
|
|
17
|
+
.readdirSync(dir, { withFileTypes: true })
|
|
18
|
+
.filter((e) => e.isDirectory())
|
|
19
|
+
.map((entry) => {
|
|
20
|
+
const match = entry.name.match(folderPattern);
|
|
21
|
+
if (!match)
|
|
22
|
+
throw new ArtifactValidationError(`Invalid work-item folder '${entry.name}'.`);
|
|
23
|
+
const base = path.join(dir, entry.name);
|
|
24
|
+
const id = match[1];
|
|
25
|
+
for (const name of ['spec.md', 'tasks.yaml', 'implementation-plan.md', 'review.yaml'])
|
|
26
|
+
if (!fs.existsSync(path.join(base, name)))
|
|
27
|
+
throw new ArtifactValidationError(`${id} is missing ${name}.`);
|
|
28
|
+
const spec = parseWorkItemSpec(read(path.join(base, 'spec.md')), { expectedWorkItem: id });
|
|
29
|
+
const tasks = parseTasks(read(path.join(base, 'tasks.yaml')), { expectedWorkItem: id });
|
|
30
|
+
const review = parseReview(read(path.join(base, 'review.yaml')), { expectedWorkItem: id });
|
|
31
|
+
return { id, folder: entry.name, ...spec.metadata, specBody: spec.body, tasks, review, base };
|
|
32
|
+
})
|
|
33
|
+
.sort((a, b) => a.id.localeCompare(b.id, undefined, { numeric: true }));
|
|
34
|
+
const ids = new Set(items.map((i) => i.id));
|
|
35
|
+
for (const item of items)
|
|
36
|
+
for (const dep of item.depends_on) {
|
|
37
|
+
if (!ids.has(dep))
|
|
38
|
+
throw new ArtifactValidationError(`${item.id} depends on unknown work item '${dep}'.`);
|
|
39
|
+
if (dep === item.id)
|
|
40
|
+
throw new ArtifactValidationError(`${item.id} cannot depend on itself.`);
|
|
41
|
+
}
|
|
42
|
+
validateAcyclic(items);
|
|
43
|
+
return items;
|
|
44
|
+
}
|
|
45
|
+
export function lifecycle(item, byId) {
|
|
46
|
+
if (item.maturity === 'outlined')
|
|
47
|
+
return { status: 'outlined', reasons: [] };
|
|
48
|
+
const incomplete = item.depends_on.filter((id) => lifecycle(byId.get(id), byId).status !== 'completed');
|
|
49
|
+
const blockers = item.blockers.filter((b) => b.status === 'unresolved');
|
|
50
|
+
if (incomplete.length || blockers.length)
|
|
51
|
+
return {
|
|
52
|
+
status: 'blocked',
|
|
53
|
+
reasons: [
|
|
54
|
+
...incomplete.map((ref) => ({ type: 'dependency', ref })),
|
|
55
|
+
...blockers.map((b) => ({ type: 'blocker', ref: b.id }))
|
|
56
|
+
]
|
|
57
|
+
};
|
|
58
|
+
if (item.tasks.tasks.some((t) => t.state === 'in_progress'))
|
|
59
|
+
return { status: 'in_progress', reasons: [] };
|
|
60
|
+
if (item.tasks.tasks.length && item.tasks.tasks.every((t) => t.state === 'completed'))
|
|
61
|
+
return { status: item.review.status === 'approved' ? 'completed' : 'review', reasons: [] };
|
|
62
|
+
return { status: 'eligible', reasons: [] };
|
|
63
|
+
}
|
|
64
|
+
export function derivedBacklog(items) {
|
|
65
|
+
const byId = new Map(items.map((i) => [i.id, i]));
|
|
66
|
+
return {
|
|
67
|
+
schema_version: 4,
|
|
68
|
+
work_items: topologicalOrder(items).map((i) => ({
|
|
69
|
+
id: i.id,
|
|
70
|
+
folder: i.folder,
|
|
71
|
+
title: i.title,
|
|
72
|
+
kind: i.kind,
|
|
73
|
+
priority: i.priority,
|
|
74
|
+
spec_maturity: i.maturity,
|
|
75
|
+
depends_on: i.depends_on,
|
|
76
|
+
blockers: i.blockers,
|
|
77
|
+
state: lifecycle(i, byId).status
|
|
78
|
+
}))
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=work-items.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"work-items.mjs","sourceRoot":"","sources":["../../src/artifacts/work-items.mjs"],"names":[],"mappings":"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"}
|