@open-agent-toolkit/cli 0.1.4 → 0.1.6
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/docs/workflows/projects/artifacts.md +17 -0
- package/assets/docs/workflows/projects/implementation-execution.md +2 -2
- package/assets/docs/workflows/projects/index.md +3 -0
- package/assets/docs/workflows/projects/splitting.md +79 -0
- package/assets/docs/workflows/skills/index.md +2 -0
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/oat-brainstorm/SKILL.md +43 -3
- package/assets/skills/oat-project-discover/SKILL.md +72 -8
- package/assets/skills/oat-project-implement/SKILL.md +8 -4
- package/assets/skills/oat-project-quick-start/SKILL.md +14 -5
- package/assets/skills/oat-project-split/SKILL.md +82 -0
- package/assets/templates/state.md +6 -1
- package/dist/__tests__/skills/split-flow-fixtures.d.ts +50 -0
- package/dist/__tests__/skills/split-flow-fixtures.d.ts.map +1 -0
- package/dist/__tests__/skills/split-flow-fixtures.js +161 -0
- package/dist/commands/init/tools/shared/skill-manifest.d.ts +1 -1
- package/dist/commands/init/tools/shared/skill-manifest.d.ts.map +1 -1
- package/dist/commands/init/tools/shared/skill-manifest.js +1 -0
- package/dist/commands/project/complete-discovery/index.d.ts +16 -0
- package/dist/commands/project/complete-discovery/index.d.ts.map +1 -0
- package/dist/commands/project/complete-discovery/index.js +123 -0
- package/dist/commands/project/complete-state/index.d.ts.map +1 -1
- package/dist/commands/project/complete-state/index.js +5 -0
- package/dist/commands/project/index.d.ts.map +1 -1
- package/dist/commands/project/index.js +4 -0
- package/dist/commands/project/list.d.ts +6 -0
- package/dist/commands/project/list.d.ts.map +1 -1
- package/dist/commands/project/list.js +37 -4
- package/dist/commands/project/new/scaffold.d.ts.map +1 -1
- package/dist/commands/project/new/scaffold.js +4 -0
- package/dist/commands/project/open/index.d.ts.map +1 -1
- package/dist/commands/project/open/index.js +9 -3
- package/dist/commands/project/pause/index.d.ts.map +1 -1
- package/dist/commands/project/pause/index.js +7 -1
- package/dist/commands/project/split/evaluate-signals.d.ts +8 -0
- package/dist/commands/project/split/evaluate-signals.d.ts.map +1 -0
- package/dist/commands/project/split/evaluate-signals.js +47 -0
- package/dist/commands/project/split/index.d.ts +3 -0
- package/dist/commands/project/split/index.d.ts.map +1 -0
- package/dist/commands/project/split/index.js +11 -0
- package/dist/commands/project/split/run.d.ts +21 -0
- package/dist/commands/project/split/run.d.ts.map +1 -0
- package/dist/commands/project/split/run.js +231 -0
- package/dist/commands/project/split/validate-plan.d.ts +14 -0
- package/dist/commands/project/split/validate-plan.d.ts.map +1 -0
- package/dist/commands/project/split/validate-plan.js +62 -0
- package/dist/commands/shared/frontmatter.d.ts +9 -0
- package/dist/commands/shared/frontmatter.d.ts.map +1 -1
- package/dist/commands/shared/frontmatter.js +46 -0
- package/dist/commands/state/generate.d.ts.map +1 -1
- package/dist/commands/state/generate.js +38 -6
- package/dist/projects/split/child-plan.d.ts +46 -0
- package/dist/projects/split/child-plan.d.ts.map +1 -0
- package/dist/projects/split/child-plan.js +107 -0
- package/dist/projects/split/document-validation.d.ts +14 -0
- package/dist/projects/split/document-validation.d.ts.map +1 -0
- package/dist/projects/split/document-validation.js +106 -0
- package/dist/projects/split/finalize.d.ts +7 -0
- package/dist/projects/split/finalize.d.ts.map +1 -0
- package/dist/projects/split/finalize.js +32 -0
- package/dist/projects/split/resume.d.ts +19 -0
- package/dist/projects/split/resume.d.ts.map +1 -0
- package/dist/projects/split/resume.js +107 -0
- package/dist/projects/split/seed-children.d.ts +9 -0
- package/dist/projects/split/seed-children.d.ts.map +1 -0
- package/dist/projects/split/seed-children.js +122 -0
- package/dist/projects/split/signals.d.ts +10 -0
- package/dist/projects/split/signals.d.ts.map +1 -0
- package/dist/projects/split/signals.js +18 -0
- package/dist/projects/split/validation.d.ts +14 -0
- package/dist/projects/split/validation.d.ts.map +1 -0
- package/dist/projects/split/validation.js +104 -0
- package/dist/projects/split/write-parent.d.ts +16 -0
- package/dist/projects/split/write-parent.d.ts.map +1 -0
- package/dist/projects/split/write-parent.js +176 -0
- package/dist/validation/project-state.d.ts +50 -0
- package/dist/validation/project-state.d.ts.map +1 -0
- package/dist/validation/project-state.js +279 -0
- package/package.json +2 -2
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { buildCommandContext, } from '../../../app/command-context.js';
|
|
2
|
+
import { readGlobalOptions } from '../../shared/shared.utils.js';
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import { evaluateSignals } from '../../../projects/split/signals.js';
|
|
5
|
+
const SIGNALS = [
|
|
6
|
+
'independently-shippable',
|
|
7
|
+
'no-shared-design-surface',
|
|
8
|
+
'expect-separate-prs',
|
|
9
|
+
'distinct-subsystems',
|
|
10
|
+
];
|
|
11
|
+
const DEFAULT_DEPENDENCIES = {
|
|
12
|
+
buildCommandContext,
|
|
13
|
+
};
|
|
14
|
+
function parseFiredSignals(value) {
|
|
15
|
+
if (value.trim().length === 0) {
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
18
|
+
const validSignals = new Set(SIGNALS);
|
|
19
|
+
return value.split(',').map((raw) => {
|
|
20
|
+
const signal = raw.trim();
|
|
21
|
+
if (!validSignals.has(signal)) {
|
|
22
|
+
throw new Error(`Invalid signal: ${signal}`);
|
|
23
|
+
}
|
|
24
|
+
return signal;
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
export function createEvaluateSignalsCommand(overrides = {}) {
|
|
28
|
+
const dependencies = {
|
|
29
|
+
...DEFAULT_DEPENDENCIES,
|
|
30
|
+
...overrides,
|
|
31
|
+
};
|
|
32
|
+
return new Command('evaluate-signals')
|
|
33
|
+
.description('Evaluate oat-project-split trigger signals')
|
|
34
|
+
.requiredOption('--fired <comma-list>', 'Comma-separated fired signals')
|
|
35
|
+
.action((options, command) => {
|
|
36
|
+
const context = dependencies.buildCommandContext(readGlobalOptions(command));
|
|
37
|
+
try {
|
|
38
|
+
context.logger.json(evaluateSignals({ fired: parseFiredSignals(options.fired) }));
|
|
39
|
+
process.exitCode = 0;
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
43
|
+
context.logger.error(message);
|
|
44
|
+
process.exitCode = 1;
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/split/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,yBAAyB,IAAI,OAAO,CAMnD"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { createEvaluateSignalsCommand } from './evaluate-signals.js';
|
|
3
|
+
import { createProjectSplitRunCommand } from './run.js';
|
|
4
|
+
import { createValidateSplitPlanCommand } from './validate-plan.js';
|
|
5
|
+
export function createProjectSplitCommand() {
|
|
6
|
+
return new Command('split')
|
|
7
|
+
.description('Evaluate, validate, and run oat-project-split payloads')
|
|
8
|
+
.addCommand(createEvaluateSignalsCommand())
|
|
9
|
+
.addCommand(createValidateSplitPlanCommand())
|
|
10
|
+
.addCommand(createProjectSplitRunCommand());
|
|
11
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { appendFile, readFile, readdir, stat } from 'node:fs/promises';
|
|
2
|
+
import { type CommandContext, type GlobalOptions } from '../../../app/command-context.js';
|
|
3
|
+
import { confirmAction } from '../../shared/shared.prompts.js';
|
|
4
|
+
import { Command } from 'commander';
|
|
5
|
+
interface RunSplitDependencies {
|
|
6
|
+
buildCommandContext: (options: GlobalOptions) => CommandContext;
|
|
7
|
+
resolveProjectRoot: (cwd: string) => Promise<string>;
|
|
8
|
+
resolveProjectsRoot: (repoRoot: string, env: NodeJS.ProcessEnv) => Promise<string>;
|
|
9
|
+
readFile: typeof readFile;
|
|
10
|
+
readdir: typeof readdir;
|
|
11
|
+
stat: typeof stat;
|
|
12
|
+
appendFile: typeof appendFile;
|
|
13
|
+
refreshDashboard: (options: {
|
|
14
|
+
repoRoot: string;
|
|
15
|
+
}) => Promise<void>;
|
|
16
|
+
confirmAction: typeof confirmAction;
|
|
17
|
+
processEnv: NodeJS.ProcessEnv;
|
|
18
|
+
}
|
|
19
|
+
export declare function createProjectSplitRunCommand(overrides?: Partial<RunSplitDependencies>): Command;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=run.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/split/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAGvE,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAKhE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqBpC,UAAU,oBAAoB;IAC5B,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,cAAc,CAAC;IAChE,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,mBAAmB,EAAE,CACnB,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,CAAC,UAAU,KACnB,OAAO,CAAC,MAAM,CAAC,CAAC;IACrB,QAAQ,EAAE,OAAO,QAAQ,CAAC;IAC1B,OAAO,EAAE,OAAO,OAAO,CAAC;IACxB,IAAI,EAAE,OAAO,IAAI,CAAC;IAClB,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,gBAAgB,EAAE,CAAC,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnE,aAAa,EAAE,OAAO,aAAa,CAAC;IACpC,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC;CAC/B;AAsLD,wBAAgB,4BAA4B,CAC1C,SAAS,GAAE,OAAO,CAAC,oBAAoB,CAAM,GAC5C,OAAO,CAkJT"}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { appendFile, readFile, readdir, stat } from 'node:fs/promises';
|
|
2
|
+
import { isAbsolute, join, relative } from 'node:path';
|
|
3
|
+
import { buildCommandContext, } from '../../../app/command-context.js';
|
|
4
|
+
import { resolveProjectsRoot } from '../../shared/oat-paths.js';
|
|
5
|
+
import { confirmAction } from '../../shared/shared.prompts.js';
|
|
6
|
+
import { readGlobalOptions } from '../../shared/shared.utils.js';
|
|
7
|
+
import { generateStateDashboard } from '../../state/generate.js';
|
|
8
|
+
import { readOatLocalConfig } from '../../../config/oat-config.js';
|
|
9
|
+
import { resolveProjectRoot } from '../../../fs/paths.js';
|
|
10
|
+
import { Command } from 'commander';
|
|
11
|
+
import { validateSplitPlanDocumentShape } from '../../../projects/split/document-validation.js';
|
|
12
|
+
import { finalizeSplit } from '../../../projects/split/finalize.js';
|
|
13
|
+
import { continueSplitResume, detectPartialSplit, SplitResumeError, } from '../../../projects/split/resume.js';
|
|
14
|
+
import { seedChildren } from '../../../projects/split/seed-children.js';
|
|
15
|
+
import { validateChildPlan } from '../../../projects/split/validation.js';
|
|
16
|
+
import { writeCoordinationParent } from '../../../projects/split/write-parent.js';
|
|
17
|
+
const DEFAULT_DEPENDENCIES = {
|
|
18
|
+
buildCommandContext,
|
|
19
|
+
resolveProjectRoot,
|
|
20
|
+
resolveProjectsRoot,
|
|
21
|
+
readFile,
|
|
22
|
+
readdir,
|
|
23
|
+
stat,
|
|
24
|
+
appendFile,
|
|
25
|
+
refreshDashboard: async (options) => {
|
|
26
|
+
await generateStateDashboard(options);
|
|
27
|
+
},
|
|
28
|
+
confirmAction,
|
|
29
|
+
processEnv: process.env,
|
|
30
|
+
};
|
|
31
|
+
async function exists(path, dependencies) {
|
|
32
|
+
try {
|
|
33
|
+
await dependencies.stat(path);
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
async function existingProjectSlugs(repoRoot, projectsRoot, dependencies) {
|
|
41
|
+
const absoluteProjectsRoot = isAbsolute(projectsRoot)
|
|
42
|
+
? projectsRoot
|
|
43
|
+
: join(repoRoot, projectsRoot);
|
|
44
|
+
try {
|
|
45
|
+
const entries = await dependencies.readdir(absoluteProjectsRoot, {
|
|
46
|
+
withFileTypes: true,
|
|
47
|
+
});
|
|
48
|
+
return new Set(entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name));
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return new Set();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
async function recordDetectedRecommendation(repoRoot, document, dependencies) {
|
|
55
|
+
const localConfig = await readOatLocalConfig(repoRoot);
|
|
56
|
+
if (!localConfig.activeProject) {
|
|
57
|
+
throw new Error('Cannot record detected split recommendation without an active project');
|
|
58
|
+
}
|
|
59
|
+
const discoveryPath = join(repoRoot, localConfig.activeProject, 'discovery.md');
|
|
60
|
+
await dependencies.appendFile(discoveryPath, [
|
|
61
|
+
'',
|
|
62
|
+
'## Detected Split Recommendation',
|
|
63
|
+
'',
|
|
64
|
+
`Origin: ${document.origin}`,
|
|
65
|
+
`Proposed parent: ${document.plan.parentSlug}`,
|
|
66
|
+
`Proposed children: ${document.plan.children
|
|
67
|
+
.map((child) => child.slug)
|
|
68
|
+
.join(', ')}`,
|
|
69
|
+
'',
|
|
70
|
+
].join('\n'), 'utf8');
|
|
71
|
+
}
|
|
72
|
+
function isEffectivelyNonInteractive(options, context, processEnv) {
|
|
73
|
+
return (options.nonInteractive === true ||
|
|
74
|
+
context.interactive === false ||
|
|
75
|
+
processEnv.OAT_NON_INTERACTIVE === '1');
|
|
76
|
+
}
|
|
77
|
+
function formatResumePreview(partial) {
|
|
78
|
+
return [
|
|
79
|
+
'Recovered partial split plan:',
|
|
80
|
+
`Parent: ${partial.parentProjectPath}`,
|
|
81
|
+
`Children: ${partial.plan.children.map((child) => child.slug).join(', ')}`,
|
|
82
|
+
`Missing children: ${partial.missingChildren.length > 0 ? partial.missingChildren.join(', ') : 'none'}`,
|
|
83
|
+
`Dependencies: ${partial.plan.children
|
|
84
|
+
.map((child) => {
|
|
85
|
+
const dependencies = child.knownDependencies.length > 0
|
|
86
|
+
? child.knownDependencies.join(', ')
|
|
87
|
+
: 'none';
|
|
88
|
+
return `${child.slug} -> ${dependencies}`;
|
|
89
|
+
})
|
|
90
|
+
.join('; ')}`,
|
|
91
|
+
`Active child: ${partial.plan.initialActiveChild}`,
|
|
92
|
+
];
|
|
93
|
+
}
|
|
94
|
+
function isDetectedOrigin(document) {
|
|
95
|
+
return (document.origin === 'detected-mid-stream' ||
|
|
96
|
+
document.origin === 'detected-convergence');
|
|
97
|
+
}
|
|
98
|
+
function normalizeProjectPath(path) {
|
|
99
|
+
return path.split('\\').join('/');
|
|
100
|
+
}
|
|
101
|
+
function toRepoRelativeProjectPath(repoRoot, projectPath) {
|
|
102
|
+
const absoluteProjectPath = isAbsolute(projectPath)
|
|
103
|
+
? projectPath
|
|
104
|
+
: join(repoRoot, projectPath);
|
|
105
|
+
return normalizeProjectPath(relative(repoRoot, absoluteProjectPath));
|
|
106
|
+
}
|
|
107
|
+
async function isActiveDetectedParentProject(repoRoot, parentPath, document) {
|
|
108
|
+
if (!isDetectedOrigin(document)) {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
const localConfig = await readOatLocalConfig(repoRoot);
|
|
112
|
+
if (!localConfig.activeProject) {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
return (toRepoRelativeProjectPath(repoRoot, localConfig.activeProject) ===
|
|
116
|
+
toRepoRelativeProjectPath(repoRoot, parentPath));
|
|
117
|
+
}
|
|
118
|
+
async function runFreshSplit(document, repoRoot, projectsRoot, dependencies, options = {}) {
|
|
119
|
+
const slugs = await existingProjectSlugs(repoRoot, projectsRoot, dependencies);
|
|
120
|
+
if (options.allowExistingParent) {
|
|
121
|
+
slugs.delete(document.plan.parentSlug);
|
|
122
|
+
}
|
|
123
|
+
const validation = validateChildPlan(document.plan, slugs);
|
|
124
|
+
if (!validation.ok) {
|
|
125
|
+
throw new Error(`Split plan validation failed: ${validation.errors
|
|
126
|
+
.map((error) => error.message)
|
|
127
|
+
.join('; ')}`);
|
|
128
|
+
}
|
|
129
|
+
await writeCoordinationParent(document, { repoRoot, projectsRoot });
|
|
130
|
+
await seedChildren(document.plan, { repoRoot, projectsRoot });
|
|
131
|
+
await finalizeSplit(document.plan, { repoRoot, projectsRoot });
|
|
132
|
+
}
|
|
133
|
+
export function createProjectSplitRunCommand(overrides = {}) {
|
|
134
|
+
const dependencies = { ...DEFAULT_DEPENDENCIES, ...overrides };
|
|
135
|
+
return new Command('run')
|
|
136
|
+
.description('Run an oat-project-split SplitPlanDocument end to end')
|
|
137
|
+
.requiredOption('--plan-file <path>', 'Path to split-plan.json')
|
|
138
|
+
.option('--non-interactive', 'Fail fast for detected split origins instead of writing projects')
|
|
139
|
+
.option('--resume', 'Confirm resuming an existing partial split without prompting')
|
|
140
|
+
.action(async (options, command) => {
|
|
141
|
+
const context = dependencies.buildCommandContext(readGlobalOptions(command));
|
|
142
|
+
try {
|
|
143
|
+
const repoRoot = await dependencies.resolveProjectRoot(context.cwd);
|
|
144
|
+
const projectsRoot = await dependencies.resolveProjectsRoot(repoRoot, dependencies.processEnv);
|
|
145
|
+
const raw = await dependencies.readFile(options.planFile, 'utf8');
|
|
146
|
+
const parsed = JSON.parse(raw);
|
|
147
|
+
const documentShape = validateSplitPlanDocumentShape(parsed);
|
|
148
|
+
if (!documentShape.ok) {
|
|
149
|
+
throw new Error(`Invalid SplitPlanDocument: ${documentShape.errors
|
|
150
|
+
.map((error) => error.message)
|
|
151
|
+
.join('; ')}`);
|
|
152
|
+
}
|
|
153
|
+
const document = documentShape.document;
|
|
154
|
+
if (isEffectivelyNonInteractive(options, context, dependencies.processEnv) &&
|
|
155
|
+
(document.origin === 'detected-mid-stream' ||
|
|
156
|
+
document.origin === 'detected-convergence')) {
|
|
157
|
+
await recordDetectedRecommendation(repoRoot, document, dependencies);
|
|
158
|
+
context.logger.error('Detected split requires interactive confirmation; recommendation recorded.');
|
|
159
|
+
process.exitCode = 1;
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const parentPath = join(projectsRoot, document.plan.parentSlug)
|
|
163
|
+
.split('\\')
|
|
164
|
+
.join('/');
|
|
165
|
+
const absoluteParentPath = isAbsolute(parentPath)
|
|
166
|
+
? parentPath
|
|
167
|
+
: join(repoRoot, parentPath);
|
|
168
|
+
if (await exists(absoluteParentPath, dependencies)) {
|
|
169
|
+
let partial = null;
|
|
170
|
+
let convertActiveDetectedParent = false;
|
|
171
|
+
try {
|
|
172
|
+
partial = await detectPartialSplit(parentPath, {
|
|
173
|
+
repoRoot,
|
|
174
|
+
projectsRoot,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
if (error instanceof SplitResumeError &&
|
|
179
|
+
error.message === 'Split resume requires a coordination parent' &&
|
|
180
|
+
(await isActiveDetectedParentProject(repoRoot, parentPath, document))) {
|
|
181
|
+
convertActiveDetectedParent = true;
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
throw error;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
if (convertActiveDetectedParent) {
|
|
188
|
+
await runFreshSplit(document, repoRoot, projectsRoot, dependencies, {
|
|
189
|
+
allowExistingParent: true,
|
|
190
|
+
});
|
|
191
|
+
await dependencies.refreshDashboard({ repoRoot });
|
|
192
|
+
context.logger.info('Split completed.');
|
|
193
|
+
process.exitCode = 0;
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
if (!partial) {
|
|
197
|
+
throw new SplitResumeError('Cannot resume split without recovered partial state.');
|
|
198
|
+
}
|
|
199
|
+
for (const line of formatResumePreview(partial)) {
|
|
200
|
+
context.logger.info(line);
|
|
201
|
+
}
|
|
202
|
+
const effectiveNonInteractive = isEffectivelyNonInteractive(options, context, dependencies.processEnv);
|
|
203
|
+
if (!options.resume) {
|
|
204
|
+
if (effectiveNonInteractive) {
|
|
205
|
+
throw new SplitResumeError('Partial split detected. Re-run with --resume to confirm resuming without an interactive prompt.');
|
|
206
|
+
}
|
|
207
|
+
const confirmed = await dependencies.confirmAction('Resume this split from the recovered plan?', { interactive: context.interactive });
|
|
208
|
+
if (!confirmed) {
|
|
209
|
+
throw new SplitResumeError('Split resume cancelled.');
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
await continueSplitResume(partial, { repoRoot, projectsRoot });
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
await runFreshSplit(document, repoRoot, projectsRoot, dependencies);
|
|
216
|
+
}
|
|
217
|
+
await dependencies.refreshDashboard({ repoRoot });
|
|
218
|
+
context.logger.info('Split completed.');
|
|
219
|
+
process.exitCode = 0;
|
|
220
|
+
}
|
|
221
|
+
catch (error) {
|
|
222
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
223
|
+
context.logger.error(message);
|
|
224
|
+
if (error instanceof SplitResumeError) {
|
|
225
|
+
process.exitCode = 1;
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
process.exitCode = 1;
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { readdir as defaultReaddir, readFile as defaultReadFile } from 'node:fs/promises';
|
|
2
|
+
import { type CommandContext, type GlobalOptions } from '../../../app/command-context.js';
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
interface ValidatePlanDependencies {
|
|
5
|
+
buildCommandContext: (options: GlobalOptions) => CommandContext;
|
|
6
|
+
resolveProjectRoot: (cwd: string) => Promise<string>;
|
|
7
|
+
resolveProjectsRoot: (repoRoot: string, env: NodeJS.ProcessEnv) => Promise<string>;
|
|
8
|
+
readFile: typeof defaultReadFile;
|
|
9
|
+
readdir: typeof defaultReaddir;
|
|
10
|
+
processEnv: NodeJS.ProcessEnv;
|
|
11
|
+
}
|
|
12
|
+
export declare function createValidateSplitPlanCommand(overrides?: Partial<ValidatePlanDependencies>): Command;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=validate-plan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-plan.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/split/validate-plan.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,IAAI,cAAc,EACzB,QAAQ,IAAI,eAAe,EAC5B,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAI9B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,UAAU,wBAAwB;IAChC,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,cAAc,CAAC;IAChE,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,mBAAmB,EAAE,CACnB,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,CAAC,UAAU,KACnB,OAAO,CAAC,MAAM,CAAC,CAAC;IACrB,QAAQ,EAAE,OAAO,eAAe,CAAC;IACjC,OAAO,EAAE,OAAO,cAAc,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC;CAC/B;AAgCD,wBAAgB,8BAA8B,CAC5C,SAAS,GAAE,OAAO,CAAC,wBAAwB,CAAM,GAChD,OAAO,CAwCT"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { readdir as defaultReaddir, readFile as defaultReadFile, } from 'node:fs/promises';
|
|
2
|
+
import { isAbsolute, join } from 'node:path';
|
|
3
|
+
import { buildCommandContext, } from '../../../app/command-context.js';
|
|
4
|
+
import { resolveProjectsRoot } from '../../shared/oat-paths.js';
|
|
5
|
+
import { readGlobalOptions } from '../../shared/shared.utils.js';
|
|
6
|
+
import { resolveProjectRoot } from '../../../fs/paths.js';
|
|
7
|
+
import { Command } from 'commander';
|
|
8
|
+
import { validateSplitPlanDocumentShape } from '../../../projects/split/document-validation.js';
|
|
9
|
+
import { validateChildPlan } from '../../../projects/split/validation.js';
|
|
10
|
+
const DEFAULT_DEPENDENCIES = {
|
|
11
|
+
buildCommandContext,
|
|
12
|
+
resolveProjectRoot,
|
|
13
|
+
resolveProjectsRoot,
|
|
14
|
+
readFile: defaultReadFile,
|
|
15
|
+
readdir: defaultReaddir,
|
|
16
|
+
processEnv: process.env,
|
|
17
|
+
};
|
|
18
|
+
async function readExistingProjectSlugs(context, dependencies) {
|
|
19
|
+
const repoRoot = await dependencies.resolveProjectRoot(context.cwd);
|
|
20
|
+
const projectsRoot = await dependencies.resolveProjectsRoot(repoRoot, dependencies.processEnv);
|
|
21
|
+
const absoluteProjectsRoot = isAbsolute(projectsRoot)
|
|
22
|
+
? projectsRoot
|
|
23
|
+
: join(repoRoot, projectsRoot);
|
|
24
|
+
const entries = await dependencies.readdir(absoluteProjectsRoot, {
|
|
25
|
+
withFileTypes: true,
|
|
26
|
+
});
|
|
27
|
+
return new Set(entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name));
|
|
28
|
+
}
|
|
29
|
+
export function createValidateSplitPlanCommand(overrides = {}) {
|
|
30
|
+
const dependencies = {
|
|
31
|
+
...DEFAULT_DEPENDENCIES,
|
|
32
|
+
...overrides,
|
|
33
|
+
};
|
|
34
|
+
return new Command('validate-plan')
|
|
35
|
+
.description('Validate a persisted oat-project-split SplitPlanDocument')
|
|
36
|
+
.requiredOption('--plan-file <path>', 'Path to split-plan.json')
|
|
37
|
+
.action(async (options, command) => {
|
|
38
|
+
const context = dependencies.buildCommandContext(readGlobalOptions(command));
|
|
39
|
+
try {
|
|
40
|
+
const raw = await dependencies.readFile(options.planFile, 'utf8');
|
|
41
|
+
const parsed = JSON.parse(raw);
|
|
42
|
+
const shape = validateSplitPlanDocumentShape(parsed);
|
|
43
|
+
if (!shape.ok) {
|
|
44
|
+
context.logger.json({ ok: false, errors: shape.errors });
|
|
45
|
+
process.exitCode = 1;
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const existingSlugs = await readExistingProjectSlugs(context, dependencies);
|
|
49
|
+
const result = validateChildPlan(shape.document.plan, existingSlugs);
|
|
50
|
+
context.logger.json(result);
|
|
51
|
+
process.exitCode = result.ok ? 0 : 1;
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
55
|
+
context.logger.json({
|
|
56
|
+
ok: false,
|
|
57
|
+
errors: [{ code: 'read-or-parse-failed', message }],
|
|
58
|
+
});
|
|
59
|
+
process.exitCode = 1;
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
export declare const PROJECT_STATE_KINDS: readonly ["implementation", "coordination"];
|
|
2
|
+
export declare const PROJECT_STATE_PHASES: readonly ["discovery", "spec", "design", "plan", "implement", "decomposition"];
|
|
3
|
+
export declare const PROJECT_STATE_FRONTMATTER_FIELDS: readonly ["oat_kind", "oat_parent", "oat_siblings", "oat_depends_on", "oat_children", "oat_inherited_context_revalidated", "oat_phase", "oat_phase_status", "oat_status", "oat_workflow_mode", "oat_lifecycle", "oat_current_task", "oat_last_commit", "oat_blockers", "oat_hill_checkpoints", "oat_hill_completed", "oat_parallel_execution", "oat_pr_status", "oat_pr_url", "oat_project_created", "oat_project_completed", "oat_project_state_updated", "oat_docs_updated", "oat_generated", "oat_template", "oat_template_name"];
|
|
4
|
+
export type ProjectStateKind = (typeof PROJECT_STATE_KINDS)[number];
|
|
5
|
+
export type ProjectStatePhase = (typeof PROJECT_STATE_PHASES)[number];
|
|
6
|
+
export type ProjectStateFrontmatterField = (typeof PROJECT_STATE_FRONTMATTER_FIELDS)[number];
|
|
7
|
+
export declare function isProjectStateKind(value: string): value is ProjectStateKind;
|
|
8
|
+
export declare function isProjectStatePhase(value: string): value is ProjectStatePhase;
|
|
9
|
+
export declare function isProjectStateFrontmatterField(value: string): value is ProjectStateFrontmatterField;
|
|
1
10
|
export declare function getFrontmatterBlock(content: string): string | null;
|
|
2
11
|
export declare function getFrontmatterField(frontmatter: string, field: string): string | null;
|
|
3
12
|
export declare function parseFrontmatterField(filePath: string, field: string): Promise<string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frontmatter.d.ts","sourceRoot":"","sources":["../../../src/commands/shared/frontmatter.ts"],"names":[],"mappings":"AAGA,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGlE;AAED,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,GACZ,MAAM,GAAG,IAAI,CAKf;AAED,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,CAAC,CASjB;AAED,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQxB;AAED,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGxB"}
|
|
1
|
+
{"version":3,"file":"frontmatter.d.ts","sourceRoot":"","sources":["../../../src/commands/shared/frontmatter.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,mBAAmB,6CAA8C,CAAC;AAE/E,eAAO,MAAM,oBAAoB,gFAOvB,CAAC;AAEX,eAAO,MAAM,gCAAgC,sgBA2BnC,CAAC;AAEX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AACpE,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AACtE,MAAM,MAAM,4BAA4B,GACtC,CAAC,OAAO,gCAAgC,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,gBAAgB,CAE3E;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,iBAAiB,CAE7E;AAED,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,MAAM,GACZ,KAAK,IAAI,4BAA4B,CAIvC;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGlE;AAED,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,GACZ,MAAM,GAAG,IAAI,CAKf;AAED,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,CAAC,CASjB;AAED,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQxB;AAED,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGxB"}
|
|
@@ -1,5 +1,51 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
|
+
export const PROJECT_STATE_KINDS = ['implementation', 'coordination'];
|
|
4
|
+
export const PROJECT_STATE_PHASES = [
|
|
5
|
+
'discovery',
|
|
6
|
+
'spec',
|
|
7
|
+
'design',
|
|
8
|
+
'plan',
|
|
9
|
+
'implement',
|
|
10
|
+
'decomposition',
|
|
11
|
+
];
|
|
12
|
+
export const PROJECT_STATE_FRONTMATTER_FIELDS = [
|
|
13
|
+
'oat_kind',
|
|
14
|
+
'oat_parent',
|
|
15
|
+
'oat_siblings',
|
|
16
|
+
'oat_depends_on',
|
|
17
|
+
'oat_children',
|
|
18
|
+
'oat_inherited_context_revalidated',
|
|
19
|
+
'oat_phase',
|
|
20
|
+
'oat_phase_status',
|
|
21
|
+
'oat_status',
|
|
22
|
+
'oat_workflow_mode',
|
|
23
|
+
'oat_lifecycle',
|
|
24
|
+
'oat_current_task',
|
|
25
|
+
'oat_last_commit',
|
|
26
|
+
'oat_blockers',
|
|
27
|
+
'oat_hill_checkpoints',
|
|
28
|
+
'oat_hill_completed',
|
|
29
|
+
'oat_parallel_execution',
|
|
30
|
+
'oat_pr_status',
|
|
31
|
+
'oat_pr_url',
|
|
32
|
+
'oat_project_created',
|
|
33
|
+
'oat_project_completed',
|
|
34
|
+
'oat_project_state_updated',
|
|
35
|
+
'oat_docs_updated',
|
|
36
|
+
'oat_generated',
|
|
37
|
+
'oat_template',
|
|
38
|
+
'oat_template_name',
|
|
39
|
+
];
|
|
40
|
+
export function isProjectStateKind(value) {
|
|
41
|
+
return PROJECT_STATE_KINDS.includes(value);
|
|
42
|
+
}
|
|
43
|
+
export function isProjectStatePhase(value) {
|
|
44
|
+
return PROJECT_STATE_PHASES.includes(value);
|
|
45
|
+
}
|
|
46
|
+
export function isProjectStateFrontmatterField(value) {
|
|
47
|
+
return PROJECT_STATE_FRONTMATTER_FIELDS.includes(value);
|
|
48
|
+
}
|
|
3
49
|
export function getFrontmatterBlock(content) {
|
|
4
50
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
5
51
|
return match?.[1] ?? null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../src/commands/state/generate.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACjC,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CAClD;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,aAAa,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../src/commands/state/generate.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACjC,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CAClD;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,aAAa,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAiHD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAEvE;AAydD,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,mBAAmB,CAAC,CA2C9B"}
|
|
@@ -305,25 +305,53 @@ function computeNextStep(project, hasProjects, state) {
|
|
|
305
305
|
}
|
|
306
306
|
return { step: 'oat-project-progress', reason: 'Check current progress' };
|
|
307
307
|
}
|
|
308
|
+
function isTerminalCoordinationProject(kind, phase, phaseStatus) {
|
|
309
|
+
return (kind === 'coordination' &&
|
|
310
|
+
phase === 'decomposition' &&
|
|
311
|
+
phaseStatus === 'complete');
|
|
312
|
+
}
|
|
308
313
|
async function listAvailableProjects(repoRoot, projectsRoot) {
|
|
309
314
|
const fullRoot = join(repoRoot, projectsRoot);
|
|
310
315
|
try {
|
|
311
316
|
const entries = await readdir(fullRoot, { withFileTypes: true });
|
|
312
317
|
const dirs = entries.filter((e) => e.isDirectory());
|
|
313
|
-
if (dirs.length === 0)
|
|
314
|
-
return
|
|
318
|
+
if (dirs.length === 0) {
|
|
319
|
+
return {
|
|
320
|
+
active: '*(No projects found)*',
|
|
321
|
+
decompositions: '*(No decompositions found)*',
|
|
322
|
+
};
|
|
323
|
+
}
|
|
315
324
|
const lines = [];
|
|
325
|
+
const decompositions = [];
|
|
316
326
|
for (const dir of dirs) {
|
|
317
327
|
const stateFile = join(fullRoot, dir.name, 'state.md');
|
|
318
328
|
if (await fileExists(stateFile)) {
|
|
319
329
|
const phase = (await parseFrontmatterField(stateFile, 'oat_phase')) || 'unknown';
|
|
320
|
-
|
|
330
|
+
const phaseStatus = (await parseFrontmatterField(stateFile, 'oat_phase_status')) ||
|
|
331
|
+
'in_progress';
|
|
332
|
+
const kind = (await parseFrontmatterField(stateFile, 'oat_kind')) ||
|
|
333
|
+
'implementation';
|
|
334
|
+
const line = `- **${dir.name}** - ${phase}`;
|
|
335
|
+
if (isTerminalCoordinationProject(kind, phase, phaseStatus)) {
|
|
336
|
+
decompositions.push(line);
|
|
337
|
+
}
|
|
338
|
+
else {
|
|
339
|
+
lines.push(line);
|
|
340
|
+
}
|
|
321
341
|
}
|
|
322
342
|
}
|
|
323
|
-
return
|
|
343
|
+
return {
|
|
344
|
+
active: lines.length > 0 ? lines.join('\n') : '*(No projects found)*',
|
|
345
|
+
decompositions: decompositions.length > 0
|
|
346
|
+
? decompositions.join('\n')
|
|
347
|
+
: '*(No decompositions found)*',
|
|
348
|
+
};
|
|
324
349
|
}
|
|
325
350
|
catch {
|
|
326
|
-
return
|
|
351
|
+
return {
|
|
352
|
+
active: '*(No projects directory found)*',
|
|
353
|
+
decompositions: '*(No decompositions found)*',
|
|
354
|
+
};
|
|
327
355
|
}
|
|
328
356
|
}
|
|
329
357
|
function buildDashboardMarkdown(project, state, knowledge, staleness, nextStep, projectsList, generatedDate) {
|
|
@@ -412,7 +440,11 @@ function buildDashboardMarkdown(project, state, knowledge, staleness, nextStep,
|
|
|
412
440
|
lines.push('');
|
|
413
441
|
lines.push('## Available Projects');
|
|
414
442
|
lines.push('');
|
|
415
|
-
lines.push(projectsList);
|
|
443
|
+
lines.push(projectsList.active);
|
|
444
|
+
lines.push('');
|
|
445
|
+
lines.push('## Decompositions');
|
|
446
|
+
lines.push('');
|
|
447
|
+
lines.push(projectsList.decompositions);
|
|
416
448
|
lines.push('');
|
|
417
449
|
return lines.join('\n');
|
|
418
450
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export type SplitOrigin = 'declared' | 'detected-mid-stream' | 'detected-convergence' | 'brainstorm-picker';
|
|
2
|
+
export interface SplitChildInput {
|
|
3
|
+
slug: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
inheritedContext?: string;
|
|
6
|
+
knownDependencies?: string[];
|
|
7
|
+
foundation?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface SplitPayload {
|
|
10
|
+
origin: SplitOrigin;
|
|
11
|
+
parentSlug?: string;
|
|
12
|
+
declaredChildren?: SplitChildInput[];
|
|
13
|
+
inferredChildren?: SplitChildInput[];
|
|
14
|
+
priorDiscovery?: {
|
|
15
|
+
path: string;
|
|
16
|
+
brainstormSessionId?: string;
|
|
17
|
+
parentSlug?: string;
|
|
18
|
+
children?: SplitChildInput[];
|
|
19
|
+
inheritedContext?: string;
|
|
20
|
+
integrationSketch?: string;
|
|
21
|
+
};
|
|
22
|
+
interactive: boolean;
|
|
23
|
+
foundationChild?: string;
|
|
24
|
+
integrationSketch?: string;
|
|
25
|
+
initialActiveChild?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface ChildPlan {
|
|
28
|
+
parentSlug: string;
|
|
29
|
+
children: Array<{
|
|
30
|
+
slug: string;
|
|
31
|
+
description?: string;
|
|
32
|
+
inheritedContext: string;
|
|
33
|
+
knownDependencies: string[];
|
|
34
|
+
order: number;
|
|
35
|
+
}>;
|
|
36
|
+
foundationChild?: string;
|
|
37
|
+
integrationSketch?: string;
|
|
38
|
+
initialActiveChild: string;
|
|
39
|
+
}
|
|
40
|
+
export interface SplitPlanDocument {
|
|
41
|
+
origin: SplitOrigin;
|
|
42
|
+
interactive: boolean;
|
|
43
|
+
plan: ChildPlan;
|
|
44
|
+
}
|
|
45
|
+
export declare function buildSplitPlanDocument(payload: SplitPayload): SplitPlanDocument;
|
|
46
|
+
//# sourceMappingURL=child-plan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"child-plan.d.ts","sourceRoot":"","sources":["../../../src/projects/split/child-plan.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GACnB,UAAU,GACV,qBAAqB,GACrB,sBAAsB,GACtB,mBAAmB,CAAC;AAExB,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,WAAW,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAC;IACrC,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAC;IACrC,cAAc,CAAC,EAAE;QACf,IAAI,EAAE,MAAM,CAAC;QACb,mBAAmB,CAAC,EAAE,MAAM,CAAC;QAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,eAAe,EAAE,CAAC;QAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC5B,CAAC;IACF,WAAW,EAAE,OAAO,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,KAAK,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,MAAM,CAAC;QACzB,iBAAiB,EAAE,MAAM,EAAE,CAAC;QAC5B,KAAK,EAAE,MAAM,CAAC;KACf,CAAC,CAAC;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,WAAW,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,IAAI,EAAE,SAAS,CAAC;CACjB;AA0GD,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,YAAY,GACpB,iBAAiB,CAiCnB"}
|