@mrpatronz/nexusflow 2.11.0 → 2.12.1
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/LICENSE +1 -1
- package/README.md +154 -13
- package/dist/analyzers/detect-deps.js +1 -1
- package/dist/analyzers/detect-deps.js.map +1 -1
- package/dist/commands/commit.d.ts.map +1 -1
- package/dist/commands/commit.js +15 -0
- package/dist/commands/commit.js.map +1 -1
- package/dist/commands/create.d.ts +10 -1
- package/dist/commands/create.d.ts.map +1 -1
- package/dist/commands/create.js +44 -23
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/finish.d.ts.map +1 -1
- package/dist/commands/finish.js +15 -0
- package/dist/commands/finish.js.map +1 -1
- package/dist/commands/flow.d.ts +13 -0
- package/dist/commands/flow.d.ts.map +1 -0
- package/dist/commands/flow.js +91 -0
- package/dist/commands/flow.js.map +1 -0
- package/dist/commands/skill.d.ts +28 -0
- package/dist/commands/skill.d.ts.map +1 -0
- package/dist/commands/skill.js +250 -0
- package/dist/commands/skill.js.map +1 -0
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +14 -0
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/tag.d.ts +13 -0
- package/dist/commands/tag.d.ts.map +1 -0
- package/dist/commands/tag.js +179 -0
- package/dist/commands/tag.js.map +1 -0
- package/dist/commands/verify.d.ts +16 -0
- package/dist/commands/verify.d.ts.map +1 -0
- package/dist/commands/verify.js +91 -0
- package/dist/commands/verify.js.map +1 -0
- package/dist/core/adapters/local-storage.d.ts.map +1 -1
- package/dist/core/adapters/local-storage.js +2 -2
- package/dist/core/adapters/local-storage.js.map +1 -1
- package/dist/core/commit.d.ts +2 -0
- package/dist/core/commit.d.ts.map +1 -1
- package/dist/core/commit.js +15 -0
- package/dist/core/commit.js.map +1 -1
- package/dist/core/domain-catalog.d.ts +9 -0
- package/dist/core/domain-catalog.d.ts.map +1 -0
- package/dist/core/domain-catalog.js +47 -0
- package/dist/core/domain-catalog.js.map +1 -0
- package/dist/core/domain-packs.d.ts +81 -0
- package/dist/core/domain-packs.d.ts.map +1 -0
- package/dist/core/domain-packs.js +443 -0
- package/dist/core/domain-packs.js.map +1 -0
- package/dist/core/generation-lock.d.ts +1 -1
- package/dist/core/generation-lock.d.ts.map +1 -1
- package/dist/core/generation-lock.js +18 -11
- package/dist/core/generation-lock.js.map +1 -1
- package/dist/core/lifecycle.d.ts +28 -0
- package/dist/core/lifecycle.d.ts.map +1 -0
- package/dist/core/lifecycle.js +423 -0
- package/dist/core/lifecycle.js.map +1 -0
- package/dist/core/planning-notes.d.ts +11 -0
- package/dist/core/planning-notes.d.ts.map +1 -0
- package/dist/core/planning-notes.js +108 -0
- package/dist/core/planning-notes.js.map +1 -0
- package/dist/core/verify.d.ts +39 -0
- package/dist/core/verify.d.ts.map +1 -0
- package/dist/core/verify.js +397 -0
- package/dist/core/verify.js.map +1 -0
- package/dist/core/work-guidance.d.ts +202 -0
- package/dist/core/work-guidance.d.ts.map +1 -0
- package/dist/core/work-guidance.js +231 -0
- package/dist/core/work-guidance.js.map +1 -0
- package/dist/core/workspace-git.d.ts.map +1 -1
- package/dist/core/workspace-git.js +1 -0
- package/dist/core/workspace-git.js.map +1 -1
- package/dist/core/workspace-state.d.ts +24 -3
- package/dist/core/workspace-state.d.ts.map +1 -1
- package/dist/core/workspace-state.js +93 -31
- package/dist/core/workspace-state.js.map +1 -1
- package/dist/core/workspace-tools.d.ts +10 -0
- package/dist/core/workspace-tools.d.ts.map +1 -0
- package/dist/core/workspace-tools.js +123 -0
- package/dist/core/workspace-tools.js.map +1 -0
- package/dist/core/workspace.d.ts.map +1 -1
- package/dist/core/workspace.js +7 -17
- package/dist/core/workspace.js.map +1 -1
- package/dist/generators/base.d.ts.map +1 -1
- package/dist/generators/base.js +42 -5
- package/dist/generators/base.js.map +1 -1
- package/dist/generators/index.d.ts.map +1 -1
- package/dist/generators/index.js +11 -0
- package/dist/generators/index.js.map +1 -1
- package/dist/generators/plan-generator.d.ts.map +1 -1
- package/dist/generators/plan-generator.js +61 -58
- package/dist/generators/plan-generator.js.map +1 -1
- package/dist/generators/skills-generator.d.ts.map +1 -1
- package/dist/generators/skills-generator.js +36 -3
- package/dist/generators/skills-generator.js.map +1 -1
- package/dist/gui/assets/AgentsPage-C7Rh_dp7.js +3 -0
- package/dist/gui/assets/DashboardPage-YVONGtqS.js +1 -0
- package/dist/gui/assets/{GettingStartedPage-1MOTng3B.js → GettingStartedPage-C2Kbvz_N.js} +1 -1
- package/dist/gui/assets/ProjectsPage-DOpfV2Oj.js +1 -0
- package/dist/gui/assets/{ScaffoldRepoInline-CP0yn5mw.js → ScaffoldRepoInline-D91aitAi.js} +1 -1
- package/dist/gui/assets/{SettingsPage-DWmrLV8o.js → SettingsPage-BdaHN6fa.js} +1 -1
- package/dist/gui/assets/SkillsPage-DT9lRkCg.js +7 -0
- package/dist/gui/assets/StartWorkPage-D932lq9x.js +1 -0
- package/dist/gui/assets/{StrategiesPage-CdCbbIu-.js → StrategiesPage-DCfS-wdu.js} +2 -2
- package/dist/gui/assets/WorkroomsPage-BQU27nWS.js +4 -0
- package/dist/gui/assets/WorkspacesPage-D3TLVmq-.js +13 -0
- package/dist/gui/assets/{alert-dialog-u7qgb9Hq.js → alert-dialog-YynbGyj1.js} +1 -1
- package/dist/gui/assets/badge-DTBzXOWn.js +1 -0
- package/dist/gui/assets/index-er-mkc2S.css +2 -0
- package/dist/gui/assets/index-hTa55BQ6.js +57 -0
- package/dist/gui/assets/square-check-big-Bj8Rf_dH.js +1 -0
- package/dist/gui/assets/tabs-DfW7Akjs.js +1 -0
- package/dist/gui/assets/{useAriaLabelledBy-C4zV-1Ra.js → useAriaLabelledBy-BmJErI5a.js} +1 -1
- package/dist/gui/assets/vsc-BsVrJLSg.js +1 -0
- package/dist/gui/index.html +3 -5
- package/dist/http/work-guidance-routes.d.ts +4 -0
- package/dist/http/work-guidance-routes.d.ts.map +1 -0
- package/dist/http/work-guidance-routes.js +50 -0
- package/dist/http/work-guidance-routes.js.map +1 -0
- package/dist/index.js +169 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/tools.d.ts +0 -7
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +207 -0
- package/dist/mcp/tools.js.map +1 -1
- package/dist/resources/contracts.d.ts.map +1 -1
- package/dist/resources/contracts.js +2 -1
- package/dist/resources/contracts.js.map +1 -1
- package/dist/resources/fs-safety.d.ts.map +1 -1
- package/dist/resources/fs-safety.js +2 -1
- package/dist/resources/fs-safety.js.map +1 -1
- package/dist/resources/materializer.d.ts +3 -0
- package/dist/resources/materializer.d.ts.map +1 -1
- package/dist/resources/materializer.js +45 -19
- package/dist/resources/materializer.js.map +1 -1
- package/dist/resources/service.d.ts +1 -1
- package/dist/resources/service.d.ts.map +1 -1
- package/dist/resources/service.js +3 -2
- package/dist/resources/service.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +333 -8
- package/dist/server.js.map +1 -1
- package/dist/static-resources/skills/contextspace-verify-release/SKILL.md +51 -0
- package/dist/static-resources/skills/contextspace-verify-release/references/evidence.md +21 -0
- package/dist/static-resources/skills/nexusflow-dev/SKILL.md +49 -0
- package/dist/static-resources/skills/nexusflow-dev/references/cli-conventions.md +15 -0
- package/dist/static-resources/skills/nexusflow-dev/references/verification-checklist.md +28 -0
- package/dist/static-resources/skills/nexusflow-lifecycle/SKILL.md +66 -0
- package/dist/static-resources/skills/nexusflow-lifecycle/references/epic-deliverables.md +36 -0
- package/dist/static-resources/skills/nexusflow-lifecycle/references/flow-selection-matrix.md +21 -0
- package/dist/static-resources/skills/nexusflow-lifecycle/references/stage-outcomes.md +23 -0
- package/dist/static-resources/workflows/epic-multi-slice.md +21 -0
- package/dist/static-resources/workflows/plan-implement-review.md +17 -6
- package/dist/static-resources/workflows/research-verify.md +15 -4
- package/dist/static-resources/workflows/solo-developer.md +11 -2
- package/dist/test-setup.d.ts +2 -0
- package/dist/test-setup.d.ts.map +1 -0
- package/dist/test-setup.js +8 -0
- package/dist/test-setup.js.map +1 -0
- package/dist/types.d.ts +178 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/resolve-workspace.d.ts.map +1 -1
- package/dist/utils/resolve-workspace.js +15 -8
- package/dist/utils/resolve-workspace.js.map +1 -1
- package/dist/utils/skills-catalog.d.ts +18 -9
- package/dist/utils/skills-catalog.d.ts.map +1 -1
- package/dist/utils/skills-catalog.js +248 -344
- package/dist/utils/skills-catalog.js.map +1 -1
- package/dist/utils/workflow-advisor.d.ts +1 -1
- package/dist/utils/workflow-advisor.d.ts.map +1 -1
- package/dist/utils/workflow-advisor.js +16 -4
- package/dist/utils/workflow-advisor.js.map +1 -1
- package/dist/utils/workflows.d.ts.map +1 -1
- package/dist/utils/workflows.js +5 -2
- package/dist/utils/workflows.js.map +1 -1
- package/dist/workrooms/contracts.d.ts +3 -3
- package/dist/workrooms/local-resources.d.ts +4 -1
- package/dist/workrooms/local-resources.d.ts.map +1 -1
- package/dist/workrooms/manager.d.ts +5 -2
- package/dist/workrooms/manager.d.ts.map +1 -1
- package/dist/workrooms/store.d.ts +2 -2
- package/package.json +3 -2
- package/resources/skills/contextspace-verify-release/SKILL.md +51 -0
- package/resources/skills/contextspace-verify-release/references/evidence.md +21 -0
- package/resources/skills/nexusflow-dev/SKILL.md +49 -0
- package/resources/skills/nexusflow-dev/references/cli-conventions.md +15 -0
- package/resources/skills/nexusflow-dev/references/verification-checklist.md +28 -0
- package/resources/skills/nexusflow-lifecycle/SKILL.md +66 -0
- package/resources/skills/nexusflow-lifecycle/references/epic-deliverables.md +36 -0
- package/resources/skills/nexusflow-lifecycle/references/flow-selection-matrix.md +21 -0
- package/resources/skills/nexusflow-lifecycle/references/stage-outcomes.md +23 -0
- package/resources/workflows/epic-multi-slice.md +21 -0
- package/resources/workflows/plan-implement-review.md +17 -6
- package/resources/workflows/research-verify.md +15 -4
- package/resources/workflows/solo-developer.md +11 -2
- package/dist/gui/assets/AgentsPage-DbivhmK0.js +0 -3
- package/dist/gui/assets/DashboardPage-D50Qrm3e.js +0 -1
- package/dist/gui/assets/NullStore-tdPen1kp.js +0 -1
- package/dist/gui/assets/ProjectsPage-srKgf7VN.js +0 -1
- package/dist/gui/assets/SkillsPage-CKjTXdrd.js +0 -6
- package/dist/gui/assets/StartWorkPage-BCUnJ9k8.js +0 -1
- package/dist/gui/assets/WorkroomsPage-BcT-mGtT.js +0 -4
- package/dist/gui/assets/WorkspacesPage-CYFCm-7_.js +0 -2
- package/dist/gui/assets/badge-DwXvB44H.js +0 -1
- package/dist/gui/assets/chunk-BV7QT456-DfUBKG-z.js +0 -3
- package/dist/gui/assets/index-3tD_IeyQ.js +0 -55
- package/dist/gui/assets/index-CK5YRfPV.css +0 -2
- package/dist/gui/assets/square-check-big-BSIiYXPI.js +0 -1
- package/dist/gui/assets/tabs-BrHKp5bD.js +0 -1
- package/dist/gui/assets/vsc-D80c4gBT.js +0 -1
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module core/lifecycle
|
|
3
|
+
* Active lifecycle state machine and multi-branch fleet radar for ContextSpace.
|
|
4
|
+
*
|
|
5
|
+
* Manages discrete development milestones/steps, dependency gating,
|
|
6
|
+
* non-destructive origin branch fleet tracking, and test gate transitions.
|
|
7
|
+
*/
|
|
8
|
+
import { z } from 'zod';
|
|
9
|
+
import { execa } from 'execa';
|
|
10
|
+
import { loadFeatureConfig, resolveRepoInfos } from './workspace.js';
|
|
11
|
+
import { resolveFeatureRepoPath } from '../utils/feature.js';
|
|
12
|
+
import { getRepoBranch, getAheadBehind } from '../utils/multi-git.js';
|
|
13
|
+
import { loadWorkspaceState, mutateWorkspaceState } from './workspace-state.js';
|
|
14
|
+
import { verifyWorkspace } from './verify.js';
|
|
15
|
+
/**
|
|
16
|
+
* Non-destructively inspects local and remote tracking branches for repositories in the workspace.
|
|
17
|
+
*/
|
|
18
|
+
export async function getBranchFleet(workspacePath) {
|
|
19
|
+
const feature = await loadFeatureConfig(workspacePath);
|
|
20
|
+
if (!feature)
|
|
21
|
+
return [];
|
|
22
|
+
const resolvedPaths = feature.repos.map((r) => resolveFeatureRepoPath(feature, workspacePath, r));
|
|
23
|
+
const repoInfos = await resolveRepoInfos(resolvedPaths);
|
|
24
|
+
const fleet = [];
|
|
25
|
+
for (const repo of repoInfos) {
|
|
26
|
+
const currentBranch = await getRepoBranch(repo.path);
|
|
27
|
+
const aheadBehind = await getAheadBehind(repo.path, currentBranch ?? repo.defaultBranch);
|
|
28
|
+
let currentSha = 'unknown';
|
|
29
|
+
let currentMessage = '';
|
|
30
|
+
let currentAuthor = '';
|
|
31
|
+
let currentDate = '';
|
|
32
|
+
try {
|
|
33
|
+
const { stdout } = await execa('git', ['log', '-1', '--format=%h%x1f%s%x1f%an%x1f%cI'], { cwd: repo.path });
|
|
34
|
+
const [sha, msg, author, date] = stdout.trim().split('\x1f');
|
|
35
|
+
currentSha = sha ?? 'unknown';
|
|
36
|
+
currentMessage = msg ?? '';
|
|
37
|
+
currentAuthor = author ?? '';
|
|
38
|
+
currentDate = date ?? '';
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
// Ignore
|
|
42
|
+
}
|
|
43
|
+
// 1. Add current active branch
|
|
44
|
+
fleet.push({
|
|
45
|
+
branch: currentBranch ?? 'detached',
|
|
46
|
+
repoName: repo.name,
|
|
47
|
+
isCurrent: true,
|
|
48
|
+
headSha: currentSha,
|
|
49
|
+
ahead: aheadBehind.ahead ?? 0,
|
|
50
|
+
behind: aheadBehind.behind ?? 0,
|
|
51
|
+
lastCommitMessage: currentMessage,
|
|
52
|
+
lastCommitAuthor: currentAuthor,
|
|
53
|
+
lastCommitDate: currentDate,
|
|
54
|
+
remoteTracked: aheadBehind.ahead !== null,
|
|
55
|
+
});
|
|
56
|
+
// 2. Inspect origin remote tracking branches (non-destructive)
|
|
57
|
+
try {
|
|
58
|
+
const { stdout: refOut } = await execa('git', [
|
|
59
|
+
'for-each-ref',
|
|
60
|
+
'--sort=-committerdate',
|
|
61
|
+
'--count=100',
|
|
62
|
+
'--format=%(refname:short)\x1f%(objectname:short)\x1f%(subject)\x1f%(authorname)\x1f%(committerdate:iso-strict)\x1f%(symref)',
|
|
63
|
+
'refs/remotes/origin/',
|
|
64
|
+
], { cwd: repo.path });
|
|
65
|
+
const lines = refOut.split('\n').map((l) => l.trim()).filter(Boolean);
|
|
66
|
+
for (const line of lines) {
|
|
67
|
+
const [refShort, sha, subject, author, relDate, symref] = line.split('\x1f');
|
|
68
|
+
if (!refShort)
|
|
69
|
+
continue;
|
|
70
|
+
const branchName = refShort.replace(/^origin\//, '');
|
|
71
|
+
if (/^(?:renovate|dependabot)\//i.test(branchName))
|
|
72
|
+
continue;
|
|
73
|
+
if (fleet.filter((member) => member.repoName === repo.name && !member.isCurrent).length >= 6)
|
|
74
|
+
break;
|
|
75
|
+
if (symref || refShort === 'origin' || refShort === 'origin/HEAD' || branchName === 'HEAD' || branchName === currentBranch)
|
|
76
|
+
continue;
|
|
77
|
+
fleet.push({
|
|
78
|
+
branch: refShort,
|
|
79
|
+
repoName: repo.name,
|
|
80
|
+
isCurrent: false,
|
|
81
|
+
headSha: sha,
|
|
82
|
+
ahead: 0,
|
|
83
|
+
behind: 0,
|
|
84
|
+
lastCommitMessage: subject,
|
|
85
|
+
lastCommitAuthor: author,
|
|
86
|
+
lastCommitDate: relDate,
|
|
87
|
+
remoteTracked: true,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
// Ignore remote queries if remote not reachable
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return fleet;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Creates a default structured lifecycle if none exists for the workspace.
|
|
99
|
+
*/
|
|
100
|
+
export function createDefaultSteps(flowType, featureId, branchName) {
|
|
101
|
+
if (flowType === 'quick') {
|
|
102
|
+
return [
|
|
103
|
+
{
|
|
104
|
+
id: 'reproduce_and_fix',
|
|
105
|
+
title: 'Scope & Implement Focused Change',
|
|
106
|
+
description: 'Confirm the expected behavior or baseline, then make a focused change.',
|
|
107
|
+
branch: branchName,
|
|
108
|
+
owner: 'Developer',
|
|
109
|
+
status: 'in_progress',
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
id: 'verify_and_ship',
|
|
113
|
+
requiresVerification: true,
|
|
114
|
+
title: 'Mechanical Verification Gate & Ship',
|
|
115
|
+
description: 'Execute automated tests, anchor commit SHA proof, and publish PR.',
|
|
116
|
+
branch: branchName,
|
|
117
|
+
owner: 'Developer',
|
|
118
|
+
status: 'pending',
|
|
119
|
+
dependsOn: ['reproduce_and_fix'],
|
|
120
|
+
},
|
|
121
|
+
];
|
|
122
|
+
}
|
|
123
|
+
if (flowType === 'epic') {
|
|
124
|
+
return [
|
|
125
|
+
{
|
|
126
|
+
id: 'epic_slice_1',
|
|
127
|
+
title: 'Define Outcomes & Constraints',
|
|
128
|
+
description: 'Agree the intended outcome, scope, constraints, and acceptance criteria.',
|
|
129
|
+
branch: branchName,
|
|
130
|
+
owner: 'Developer',
|
|
131
|
+
status: 'in_progress',
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
id: 'epic_slice_2',
|
|
135
|
+
title: 'Deliver First Increment',
|
|
136
|
+
description: 'Implement and test the first independently reviewable deliverable.',
|
|
137
|
+
branch: branchName,
|
|
138
|
+
owner: 'Developer',
|
|
139
|
+
status: 'pending',
|
|
140
|
+
dependsOn: ['epic_slice_1'],
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
id: 'epic_slice_3',
|
|
144
|
+
title: 'Deliver Follow-up Increments',
|
|
145
|
+
description: 'Add milestones for the remaining deliverables and their dependencies.',
|
|
146
|
+
branch: branchName,
|
|
147
|
+
owner: 'Developer',
|
|
148
|
+
status: 'pending',
|
|
149
|
+
dependsOn: ['epic_slice_2'],
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
id: 'epic_slice_4',
|
|
153
|
+
requiresVerification: true,
|
|
154
|
+
title: 'Cross-Repo Integration & E2E Gate',
|
|
155
|
+
description: 'End-to-end integration tests, mechanical verification, and milestone signoff.',
|
|
156
|
+
branch: branchName,
|
|
157
|
+
owner: 'Developer',
|
|
158
|
+
status: 'blocked',
|
|
159
|
+
dependsOn: ['epic_slice_2', 'epic_slice_3'],
|
|
160
|
+
},
|
|
161
|
+
];
|
|
162
|
+
}
|
|
163
|
+
// Standard Feature flow
|
|
164
|
+
return [
|
|
165
|
+
{
|
|
166
|
+
id: 'step_discovery',
|
|
167
|
+
title: 'Explore Architecture & Design Test Skeleton',
|
|
168
|
+
description: 'Survey relevant modules, inspect interfaces, and create verification skeleton.',
|
|
169
|
+
branch: branchName,
|
|
170
|
+
owner: 'Developer',
|
|
171
|
+
status: 'in_progress',
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
id: 'step_implementation',
|
|
175
|
+
title: 'Core Implementation',
|
|
176
|
+
description: 'Implement feature changes across affected workspace repositories.',
|
|
177
|
+
branch: branchName,
|
|
178
|
+
owner: 'Developer',
|
|
179
|
+
status: 'pending',
|
|
180
|
+
dependsOn: ['step_discovery'],
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
id: 'step_verification',
|
|
184
|
+
requiresVerification: true,
|
|
185
|
+
title: 'Mechanical Verification Gate',
|
|
186
|
+
description: 'Run automated test suites and anchor clean commit SHA proof in state.',
|
|
187
|
+
branch: branchName,
|
|
188
|
+
owner: 'Developer',
|
|
189
|
+
status: 'pending',
|
|
190
|
+
dependsOn: ['step_implementation'],
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
id: 'step_ship',
|
|
194
|
+
title: 'Review, Create PR & Clean Workspace',
|
|
195
|
+
description: 'Surface compare links, create GitHub pull request, and conclude workspace loop.',
|
|
196
|
+
branch: branchName,
|
|
197
|
+
owner: 'Developer',
|
|
198
|
+
status: 'pending',
|
|
199
|
+
dependsOn: ['step_verification'],
|
|
200
|
+
},
|
|
201
|
+
];
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Loads or initializes the active lifecycle for a workspace.
|
|
205
|
+
*/
|
|
206
|
+
export async function loadWorkspaceLifecycle(workspacePath) {
|
|
207
|
+
const state = await loadWorkspaceState(workspacePath);
|
|
208
|
+
const feature = await loadFeatureConfig(workspacePath);
|
|
209
|
+
if (state.lifecycle) {
|
|
210
|
+
// Refresh branch fleet asynchronously
|
|
211
|
+
try {
|
|
212
|
+
state.lifecycle.fleet = await getBranchFleet(workspacePath);
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
// Best-effort
|
|
216
|
+
}
|
|
217
|
+
return state.lifecycle;
|
|
218
|
+
}
|
|
219
|
+
// Determine flow type
|
|
220
|
+
let flowType = feature?.flowType ?? 'feature';
|
|
221
|
+
if (!feature?.flowType && (feature?.branchName.startsWith('fix/') || feature?.branchName.startsWith('quick/'))) {
|
|
222
|
+
flowType = 'quick';
|
|
223
|
+
}
|
|
224
|
+
else if (!feature?.flowType && ((feature?.repos.length ?? 0) > 2 ||
|
|
225
|
+
feature?.branchName.startsWith('epic/') ||
|
|
226
|
+
feature?.branchName.startsWith('flow/'))) {
|
|
227
|
+
flowType = 'epic';
|
|
228
|
+
}
|
|
229
|
+
let fleet = [];
|
|
230
|
+
try {
|
|
231
|
+
fleet = await getBranchFleet(workspacePath);
|
|
232
|
+
}
|
|
233
|
+
catch {
|
|
234
|
+
// Best-effort
|
|
235
|
+
}
|
|
236
|
+
const branches = [...new Set(fleet.filter((member) => member.isCurrent).map((member) => member.branch))];
|
|
237
|
+
const branch = feature?.mode !== 'in-place' && branches.length === 1 && branches[0] !== 'detached'
|
|
238
|
+
? branches[0]
|
|
239
|
+
: !branches.length && feature?.mode !== 'in-place' && !feature?.repoBranches
|
|
240
|
+
? feature?.branchName
|
|
241
|
+
: undefined;
|
|
242
|
+
const steps = createDefaultSteps(flowType, feature?.id ?? 'workspace', branch);
|
|
243
|
+
const lifecycle = {
|
|
244
|
+
workspaceId: feature?.id ?? 'workspace',
|
|
245
|
+
flowType,
|
|
246
|
+
currentStepId: steps.find((s) => s.status === 'in_progress')?.id,
|
|
247
|
+
steps,
|
|
248
|
+
fleet,
|
|
249
|
+
updatedAt: new Date().toISOString(),
|
|
250
|
+
};
|
|
251
|
+
return mutateWorkspaceState(workspacePath, (current) => {
|
|
252
|
+
// Another reader may have initialized or advanced it while fleet data loaded.
|
|
253
|
+
current.lifecycle ??= lifecycle;
|
|
254
|
+
return current.lifecycle;
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
function dependenciesAreComplete(steps, candidate) {
|
|
258
|
+
return (candidate.dependsOn ?? []).every((id) => steps.some((step) => step.id === id && step.status === 'completed'));
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Advances or transitions a step in the workspace lifecycle.
|
|
262
|
+
*/
|
|
263
|
+
export async function advanceLifecycleStep(workspacePath, stepId, action) {
|
|
264
|
+
const lifecycle = await loadWorkspaceLifecycle(workspacePath);
|
|
265
|
+
const stepIndex = lifecycle.steps.findIndex((s) => s.id === stepId);
|
|
266
|
+
if (stepIndex < 0) {
|
|
267
|
+
throw new Error(`Step "${stepId}" not found in workspace lifecycle.`);
|
|
268
|
+
}
|
|
269
|
+
const step = structuredClone(lifecycle.steps[stepIndex]);
|
|
270
|
+
const originalStep = JSON.stringify(step);
|
|
271
|
+
if (!['start', 'verify', 'complete'].includes(action)) {
|
|
272
|
+
throw new Error(`Unknown lifecycle action "${action}".`);
|
|
273
|
+
}
|
|
274
|
+
if (!dependenciesAreComplete(lifecycle.steps, step)) {
|
|
275
|
+
throw new Error(`Complete dependencies before advancing step "${stepId}".`);
|
|
276
|
+
}
|
|
277
|
+
if (step.status === 'completed') {
|
|
278
|
+
throw new Error(`Step "${stepId}" is already completed.`);
|
|
279
|
+
}
|
|
280
|
+
if (action !== 'start' && step.status !== 'in_progress' && step.status !== 'verified') {
|
|
281
|
+
throw new Error(`Start step "${stepId}" before ${action}.`);
|
|
282
|
+
}
|
|
283
|
+
// Recognize gates in lifecycles saved before requiresVerification existed.
|
|
284
|
+
const requiresVerification = step.requiresVerification || Boolean(step.verificationCommand) || Boolean(step.lastVerificationStatus) ||
|
|
285
|
+
['verify_and_ship', 'step_verification', 'epic_slice_4'].includes(step.id);
|
|
286
|
+
let gateFailed = false;
|
|
287
|
+
if (action === 'verify' || (action === 'complete' && requiresVerification)) {
|
|
288
|
+
const report = await verifyWorkspace(workspacePath, { command: step.verificationCommand });
|
|
289
|
+
step.lastVerificationStatus = report.overallStatus;
|
|
290
|
+
step.lastVerificationSha = report.repos[0]?.headSha;
|
|
291
|
+
gateFailed = !report.canProgress;
|
|
292
|
+
step.status = gateFailed ? 'in_progress' : 'verified';
|
|
293
|
+
}
|
|
294
|
+
const updated = await mutateWorkspaceState(workspacePath, (state) => {
|
|
295
|
+
const lifecycle = state.lifecycle;
|
|
296
|
+
const currentStep = lifecycle?.steps.find((candidate) => candidate.id === stepId);
|
|
297
|
+
if (!lifecycle || !currentStep || JSON.stringify(currentStep) !== originalStep) {
|
|
298
|
+
throw new Error(`Step "${stepId}" changed during this operation. Reload the flow and retry.`);
|
|
299
|
+
}
|
|
300
|
+
if (!dependenciesAreComplete(lifecycle.steps, step)) {
|
|
301
|
+
throw new Error(`Dependencies changed for step "${stepId}". Reload the flow and retry.`);
|
|
302
|
+
}
|
|
303
|
+
Object.assign(currentStep, step);
|
|
304
|
+
if (action === 'start') {
|
|
305
|
+
currentStep.status = 'in_progress';
|
|
306
|
+
lifecycle.currentStepId = step.id;
|
|
307
|
+
}
|
|
308
|
+
else if (action === 'complete' && !gateFailed) {
|
|
309
|
+
currentStep.status = 'completed';
|
|
310
|
+
currentStep.completedAt = new Date().toISOString();
|
|
311
|
+
for (const nextStep of lifecycle.steps) {
|
|
312
|
+
if (nextStep.status === 'blocked' && dependenciesAreComplete(lifecycle.steps, nextStep)) {
|
|
313
|
+
nextStep.status = 'pending';
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
const active = lifecycle.steps.find((s) => s.status === 'in_progress' || s.status === 'verified');
|
|
317
|
+
const next = active ?? lifecycle.steps.find((s) => s.status === 'pending' && dependenciesAreComplete(lifecycle.steps, s));
|
|
318
|
+
if (next && !active)
|
|
319
|
+
next.status = 'in_progress';
|
|
320
|
+
lifecycle.currentStepId = next?.id;
|
|
321
|
+
}
|
|
322
|
+
lifecycle.revision = (lifecycle.revision ?? 0) + 1;
|
|
323
|
+
lifecycle.updatedAt = new Date().toISOString();
|
|
324
|
+
return lifecycle;
|
|
325
|
+
});
|
|
326
|
+
if (gateFailed && action === 'complete') {
|
|
327
|
+
throw new Error(`Verification did not permit progress for step "${stepId}" (${step.lastVerificationStatus}).`);
|
|
328
|
+
}
|
|
329
|
+
return updated;
|
|
330
|
+
}
|
|
331
|
+
const planStepSchema = z.object({
|
|
332
|
+
id: z.string().regex(/^[a-zA-Z0-9_-]+$/).max(100),
|
|
333
|
+
title: z.string().trim().min(1).max(200), description: z.string().max(4000).optional(),
|
|
334
|
+
owner: z.string().max(200).optional(), branch: z.string().max(200).optional(),
|
|
335
|
+
repo: z.string().max(200).optional(), workItem: z.string().max(2000).optional(),
|
|
336
|
+
unblockCondition: z.string().max(2000).optional(),
|
|
337
|
+
dependsOn: z.array(z.string()).max(100).optional(),
|
|
338
|
+
requiresVerification: z.boolean().optional(), verificationCommand: z.string().max(2000).optional(),
|
|
339
|
+
});
|
|
340
|
+
/** Update definitions while retaining the authoritative milestone progress and proofs. */
|
|
341
|
+
export async function updateLifecyclePlan(workspacePath, input) {
|
|
342
|
+
const update = z.object({ revision: z.number().int().nonnegative(), steps: z.array(planStepSchema).min(1).max(100) }).parse(input);
|
|
343
|
+
await loadWorkspaceLifecycle(workspacePath);
|
|
344
|
+
return mutateWorkspaceState(workspacePath, (state) => {
|
|
345
|
+
const lifecycle = state.lifecycle;
|
|
346
|
+
if ((lifecycle.revision ?? 0) !== update.revision)
|
|
347
|
+
throw new Error('The plan changed in another session. Reload before saving.');
|
|
348
|
+
const definitions = update.steps.map((definition) => ({
|
|
349
|
+
...lifecycle.steps.find((step) => step.id === definition.id), ...definition,
|
|
350
|
+
...(definition.verificationCommand === '' ? { verificationCommand: undefined } : {}),
|
|
351
|
+
}));
|
|
352
|
+
const byId = new Map(definitions.map((step) => [step.id, step]));
|
|
353
|
+
if (byId.size !== definitions.length)
|
|
354
|
+
throw new Error('Milestone IDs must be unique.');
|
|
355
|
+
if (lifecycle.steps.some((step) => !byId.has(step.id)))
|
|
356
|
+
throw new Error('Existing milestones must be retained; edit their details or add a new milestone.');
|
|
357
|
+
// Validate the merged definitions: omitted optional fields retain their saved values.
|
|
358
|
+
const visiting = new Set();
|
|
359
|
+
const visited = new Set();
|
|
360
|
+
const visit = (id) => {
|
|
361
|
+
if (visiting.has(id))
|
|
362
|
+
throw new Error('Milestone dependencies contain a cycle.');
|
|
363
|
+
if (visited.has(id))
|
|
364
|
+
return;
|
|
365
|
+
const step = byId.get(id);
|
|
366
|
+
if (!step)
|
|
367
|
+
throw new Error(`Dependency "${id}" does not name a milestone.`);
|
|
368
|
+
visiting.add(id);
|
|
369
|
+
for (const dependency of step.dependsOn ?? [])
|
|
370
|
+
visit(dependency);
|
|
371
|
+
visiting.delete(id);
|
|
372
|
+
visited.add(id);
|
|
373
|
+
};
|
|
374
|
+
for (const step of definitions)
|
|
375
|
+
visit(step.id);
|
|
376
|
+
lifecycle.steps = definitions.map((definition) => {
|
|
377
|
+
const existing = lifecycle.steps.find((step) => step.id === definition.id);
|
|
378
|
+
if (!existing)
|
|
379
|
+
return { ...definition, status: 'pending' };
|
|
380
|
+
const gateChanged = Boolean(existing.requiresVerification) !== Boolean(definition.requiresVerification)
|
|
381
|
+
|| existing.verificationCommand !== definition.verificationCommand;
|
|
382
|
+
const dependenciesChanged = JSON.stringify(existing.dependsOn ?? []) !== JSON.stringify(definition.dependsOn ?? []);
|
|
383
|
+
if (existing.status === 'completed' && (gateChanged || dependenciesChanged)) {
|
|
384
|
+
throw new Error(`Completed milestone "${existing.title}" cannot change its gate or dependencies.`);
|
|
385
|
+
}
|
|
386
|
+
if (['in_progress', 'verified'].includes(existing.status) &&
|
|
387
|
+
(definition.dependsOn ?? []).some((id) => lifecycle.steps.find((step) => step.id === id)?.status !== 'completed')) {
|
|
388
|
+
throw new Error(`Active milestone "${existing.title}" cannot depend on unfinished work.`);
|
|
389
|
+
}
|
|
390
|
+
return { ...existing, ...definition,
|
|
391
|
+
...(gateChanged ? { lastVerificationSha: undefined, lastVerificationStatus: undefined,
|
|
392
|
+
status: existing.status === 'verified' ? 'in_progress' : existing.status } : {}),
|
|
393
|
+
};
|
|
394
|
+
});
|
|
395
|
+
lifecycle.revision = (lifecycle.revision ?? 0) + 1;
|
|
396
|
+
lifecycle.updatedAt = new Date().toISOString();
|
|
397
|
+
return lifecycle;
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
export function renderLifecyclePlan(lifecycle, live = true) {
|
|
401
|
+
const lines = ['<!-- CONTEXTSPACE:MILESTONES:START -->', '## Milestone plan', '',
|
|
402
|
+
live ? 'Current progress from the workspace lifecycle.' : 'Milestone definitions from the workspace lifecycle. Run `ctxspace flow` for current progress.', ''];
|
|
403
|
+
for (const [index, step] of lifecycle.steps.entries()) {
|
|
404
|
+
lines.push(`${index + 1}. **${step.title}**${live ? ` — ${step.status.replaceAll('_', ' ')}` : ''}`);
|
|
405
|
+
if (step.description)
|
|
406
|
+
lines.push(` ${step.description}`);
|
|
407
|
+
if (step.dependsOn?.length)
|
|
408
|
+
lines.push(` Depends on: ${step.dependsOn.map((id) => lifecycle.steps.find((item) => item.id === id)?.title ?? id).join(', ')}`);
|
|
409
|
+
if (step.repo)
|
|
410
|
+
lines.push(` Repository: ${step.repo}`);
|
|
411
|
+
if (step.workItem)
|
|
412
|
+
lines.push(` Work item / PR: ${step.workItem}`);
|
|
413
|
+
if (step.unblockCondition)
|
|
414
|
+
lines.push(` Unblock condition: ${step.unblockCondition}`);
|
|
415
|
+
if (step.branch)
|
|
416
|
+
lines.push(` Branch: ${step.branch}`);
|
|
417
|
+
if (step.requiresVerification || step.verificationCommand)
|
|
418
|
+
lines.push(' Requires verification before completion.');
|
|
419
|
+
}
|
|
420
|
+
lines.push('', '<!-- CONTEXTSPACE:MILESTONES:END -->');
|
|
421
|
+
return lines.join('\n');
|
|
422
|
+
}
|
|
423
|
+
//# sourceMappingURL=lifecycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../src/core/lifecycle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const PLANNING_NOTES_FILE = "contextspace-milestones.md";
|
|
2
|
+
export declare function readPlanningNotes(root: string): Promise<{
|
|
3
|
+
content: string;
|
|
4
|
+
revision: string;
|
|
5
|
+
}>;
|
|
6
|
+
export declare function ensurePlanningNotes(root: string, featureId: string): Promise<void>;
|
|
7
|
+
export declare function savePlanningNotes(root: string, expectedRevision: string, content: string): Promise<{
|
|
8
|
+
content: string;
|
|
9
|
+
revision: string;
|
|
10
|
+
}>;
|
|
11
|
+
//# sourceMappingURL=planning-notes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"planning-notes.d.ts","sourceRoot":"","sources":["../../src/core/planning-notes.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,mBAAmB,+BAA+B,CAAC;AAmChE,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM;;;GAQnD;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,iBAYxE;AAWD,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;;;GAS9F"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import * as fs from 'node:fs/promises';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import { createHash } from 'node:crypto';
|
|
4
|
+
import { acquireLock, createMutationQueue } from './locks.js';
|
|
5
|
+
import { readWorkspaceFile, writeWorkspaceFile } from './storage.js';
|
|
6
|
+
import { loadFeatureConfig } from './workspace.js';
|
|
7
|
+
import { PRIMARY_PLAN_FILE } from './constants.js';
|
|
8
|
+
import { assertNoLinkedPathComponents } from '../resources/fs-safety.js';
|
|
9
|
+
export const PLANNING_NOTES_FILE = 'contextspace-milestones.md';
|
|
10
|
+
const template = `# Delivery plan and open questions
|
|
11
|
+
|
|
12
|
+
This is an authored planning document. Refresh preserves it. Use the lifecycle
|
|
13
|
+
editor for executable milestone gates; record the rationale and release sequence here.
|
|
14
|
+
|
|
15
|
+
## Outcomes and release order
|
|
16
|
+
|
|
17
|
+
| Milestone ID | Outcome / acceptance criteria | Repo / work item / PR | Depends on | Release / publish / consumer bump order |
|
|
18
|
+
| --- | --- | --- | --- | --- |
|
|
19
|
+
|
|
20
|
+
## Open questions
|
|
21
|
+
|
|
22
|
+
| ID | Question | Owner | Status (open / resolved) | Blocks | Resolution / evidence |
|
|
23
|
+
| --- | --- | --- | --- | --- | --- |
|
|
24
|
+
|
|
25
|
+
## Existing work — verify before replanning
|
|
26
|
+
|
|
27
|
+
| Outcome | Repo / branch / PR / commit | Status (merged / on branch / no change needed) | Evidence checked | Remaining work |
|
|
28
|
+
| --- | --- | --- | --- | --- |
|
|
29
|
+
|
|
30
|
+
## Flagged defects and deferred decisions
|
|
31
|
+
|
|
32
|
+
| Item | Decision (flag only / defer / implement) | Reason | Owner | Follow-up |
|
|
33
|
+
| --- | --- | --- | --- | --- |
|
|
34
|
+
|
|
35
|
+
## Draft work items
|
|
36
|
+
|
|
37
|
+
Use applicable enabled skill templates for the requested planning output. Store
|
|
38
|
+
each resulting PBI/spec as a draft source document and link it to its milestone.
|
|
39
|
+
Enabling a skill makes instructions available; it does not execute generation automatically.
|
|
40
|
+
`;
|
|
41
|
+
const revision = (content) => createHash('sha256').update(content).digest('hex');
|
|
42
|
+
const queue = createMutationQueue();
|
|
43
|
+
export async function readPlanningNotes(root) {
|
|
44
|
+
const feature = await loadFeatureConfig(root);
|
|
45
|
+
if (!feature)
|
|
46
|
+
throw new Error('Workspace not found.');
|
|
47
|
+
await assertNoLinkedPathComponents(root, path.join(root, PLANNING_NOTES_FILE));
|
|
48
|
+
let content;
|
|
49
|
+
try {
|
|
50
|
+
content = await readWorkspaceFile(root, feature.id, PLANNING_NOTES_FILE);
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
if (error.code !== 'ENOENT')
|
|
54
|
+
throw error;
|
|
55
|
+
content = template;
|
|
56
|
+
}
|
|
57
|
+
return { content, revision: revision(content) };
|
|
58
|
+
}
|
|
59
|
+
export async function ensurePlanningNotes(root, featureId) {
|
|
60
|
+
return mutate(root, async () => {
|
|
61
|
+
try {
|
|
62
|
+
await readWorkspaceFile(root, featureId, PLANNING_NOTES_FILE);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
if (error.code !== 'ENOENT')
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
let imported = '';
|
|
70
|
+
try {
|
|
71
|
+
const previous = await readWorkspaceFile(root, featureId, PRIMARY_PLAN_FILE);
|
|
72
|
+
const start = previous.search(/^## Milestones\s*$/m);
|
|
73
|
+
if (start >= 0)
|
|
74
|
+
imported = '\n## Imported planning notes\n\n' + previous.slice(start);
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
if (error.code !== 'ENOENT')
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
await writeWorkspaceFile(root, featureId, PLANNING_NOTES_FILE, template + imported);
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
async function mutate(root, operation) {
|
|
84
|
+
return queue(async () => {
|
|
85
|
+
root = await fs.realpath(root);
|
|
86
|
+
await assertNoLinkedPathComponents(root, path.join(root, PLANNING_NOTES_FILE));
|
|
87
|
+
const release = await acquireLock(path.join(root, '.contextspace-planning.lock'), { staleMs: 60_000, timeoutMs: 10_000, timeoutMessage: 'Planning notes are busy. Retry.' });
|
|
88
|
+
try {
|
|
89
|
+
return await operation();
|
|
90
|
+
}
|
|
91
|
+
finally {
|
|
92
|
+
await release();
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
export async function savePlanningNotes(root, expectedRevision, content) {
|
|
97
|
+
return mutate(root, async () => {
|
|
98
|
+
const current = await readPlanningNotes(root);
|
|
99
|
+
if (current.revision !== expectedRevision)
|
|
100
|
+
throw new Error('Planning notes changed in another session. Reload before saving.');
|
|
101
|
+
const feature = await loadFeatureConfig(root);
|
|
102
|
+
if (!feature)
|
|
103
|
+
throw new Error('Workspace not found.');
|
|
104
|
+
await writeWorkspaceFile(root, feature.id, PLANNING_NOTES_FILE, content);
|
|
105
|
+
return { content, revision: revision(content) };
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=planning-notes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"planning-notes.js","sourceRoot":"","sources":["../../src/core/planning-notes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module core/verify
|
|
3
|
+
* Mechanical verification gate for repositories in a ContextSpace workspace.
|
|
4
|
+
*
|
|
5
|
+
* Runs detected or configured test commands, captures process exit codes,
|
|
6
|
+
* execution duration, stdout/stderr, and anchors validation proof to the Git
|
|
7
|
+
* HEAD commit SHA and working-tree clean status.
|
|
8
|
+
*/
|
|
9
|
+
import type { RepoVerificationReport, WorkspaceVerificationReport } from '../types.js';
|
|
10
|
+
export interface VerifyCommandSpec {
|
|
11
|
+
command: string;
|
|
12
|
+
args: string[];
|
|
13
|
+
runner: string;
|
|
14
|
+
followingCommands?: VerifyCommandSpec[];
|
|
15
|
+
}
|
|
16
|
+
export interface VerifyRepoOptions {
|
|
17
|
+
filter?: string;
|
|
18
|
+
command?: string;
|
|
19
|
+
timeoutMs?: number;
|
|
20
|
+
env?: Record<string, string>;
|
|
21
|
+
allowDirty?: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface VerifyWorkspaceOptions extends VerifyRepoOptions {
|
|
24
|
+
repoName?: string;
|
|
25
|
+
tag?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Detects the appropriate test command and runner for a repository path.
|
|
29
|
+
*/
|
|
30
|
+
export declare function detectTestCommand(repoPath: string, preferredCommand?: string): Promise<VerifyCommandSpec | null>;
|
|
31
|
+
/**
|
|
32
|
+
* Runs mechanical verification for a single repository.
|
|
33
|
+
*/
|
|
34
|
+
export declare function verifyRepo(repoPath: string, repoName: string, options?: VerifyRepoOptions): Promise<RepoVerificationReport>;
|
|
35
|
+
/**
|
|
36
|
+
* Runs mechanical verification for an entire workspace.
|
|
37
|
+
*/
|
|
38
|
+
export declare function verifyWorkspace(workspacePath: string, options?: VerifyWorkspaceOptions): Promise<WorkspaceVerificationReport>;
|
|
39
|
+
//# sourceMappingURL=verify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../src/core/verify.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,KAAK,EACV,sBAAsB,EAEtB,2BAA2B,EAC5B,MAAM,aAAa,CAAC;AAOrB,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,CAAC,EAAE,iBAAiB,EAAE,CAAC;CACzC;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,sBAAuB,SAAQ,iBAAiB;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AA+DD;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,MAAM,EAChB,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAwFnC;AAkDD;;GAEG;AACH,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,sBAAsB,CAAC,CAoHjC;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,2BAA2B,CAAC,CAyEtC"}
|