fix: align new-project map gate and guard onboarding summary overwrite
init new-project now uses the same seven-file codebase map completeness check as init onboard, so partial .planning/codebase/ directories no longer skip the brownfield mapping offer after onboarding warns about an incomplete map. The onboard workflow now branches on onboarding_summary_exists and asks for confirmation before regenerating SUMMARY.md on repeat runs.
This commit is contained in:
@@ -177,6 +177,33 @@ true, continue.
|
||||
Create `.planning/onboarding/SUMMARY.md` only after PROJECT.md exists. If it already
|
||||
exists, update it only after confirmation; do not overwrite silently.
|
||||
|
||||
If `onboarding_summary_exists` is true:
|
||||
|
||||
- If `TEXT_MODE=true`, print:
|
||||
|
||||
```text
|
||||
Onboarding summary already exists at .planning/onboarding/SUMMARY.md.
|
||||
|
||||
1. Update summary — regenerate from current artifact status (Recommended)
|
||||
2. Keep existing summary — skip writing
|
||||
|
||||
Enter number:
|
||||
```
|
||||
|
||||
Stop and wait for the user's reply.
|
||||
|
||||
- Otherwise use AskUserQuestion:
|
||||
- header: "Onboarding Summary"
|
||||
- question: "Onboarding summary already exists. Update it from current artifact status?"
|
||||
- options:
|
||||
- "Update summary" — Regenerate `.planning/onboarding/SUMMARY.md` (Recommended)
|
||||
- "Keep existing summary" — Skip writing
|
||||
|
||||
If the user chooses to keep the existing summary, skip to Step 7 without writing.
|
||||
|
||||
If `onboarding_summary_exists` is false or the user confirms an update, write the summary
|
||||
using the template below.
|
||||
|
||||
Summary contents:
|
||||
|
||||
```markdown
|
||||
|
||||
10
src/init.cts
10
src/init.cts
@@ -747,6 +747,9 @@ function cmdInitNewProject(cwd: string, raw: boolean): void {
|
||||
|
||||
const hasCode = hasCodeFilesInternal(cwd);
|
||||
const hasPackageFile = hasPackageFileInternal(cwd);
|
||||
const isBrownfield = hasCode || hasPackageFile;
|
||||
const codebaseMapFiles = listCodebaseMapFiles(cwd);
|
||||
const hasCodebaseMap = codebaseMapFiles.length === REQUIRED_CODEBASE_MAP_FILES.length;
|
||||
|
||||
const result: Record<string, unknown> = {
|
||||
researcher_model: resolveModelInternal(cwd, 'gsd-project-researcher'),
|
||||
@@ -756,14 +759,13 @@ function cmdInitNewProject(cwd: string, raw: boolean): void {
|
||||
commit_docs: config.commit_docs,
|
||||
|
||||
project_exists: pathExistsInternal(cwd, '.planning/PROJECT.md'),
|
||||
has_codebase_map: pathExistsInternal(cwd, '.planning/codebase'),
|
||||
has_codebase_map: hasCodebaseMap,
|
||||
planning_exists: pathExistsInternal(cwd, '.planning'),
|
||||
|
||||
has_existing_code: hasCode,
|
||||
has_package_file: hasPackageFile,
|
||||
is_brownfield: hasCode || hasPackageFile,
|
||||
needs_codebase_map:
|
||||
(hasCode || hasPackageFile) && !pathExistsInternal(cwd, '.planning/codebase'),
|
||||
is_brownfield: isBrownfield,
|
||||
needs_codebase_map: isBrownfield && !hasCodebaseMap,
|
||||
|
||||
...getInitGitState(cwd),
|
||||
|
||||
|
||||
@@ -1599,6 +1599,9 @@ describe('cmdInitNewProject', () => {
|
||||
test('brownfield with codebase map does not need map', () => {
|
||||
fs.writeFileSync(path.join(tmpDir, 'package.json'), '{"name":"test"}');
|
||||
fs.mkdirSync(path.join(tmpDir, '.planning', 'codebase'), { recursive: true });
|
||||
for (const name of ['STACK', 'ARCHITECTURE', 'STRUCTURE', 'CONVENTIONS', 'TESTING', 'INTEGRATIONS', 'CONCERNS']) {
|
||||
fs.writeFileSync(path.join(tmpDir, '.planning', 'codebase', `${name}.md`), `# ${name}\n`);
|
||||
}
|
||||
|
||||
const result = runGsdTools('init new-project', tmpDir);
|
||||
assert.ok(result.success, `Command failed: ${result.error}`);
|
||||
|
||||
Reference in New Issue
Block a user