@ktpartners/dgs-platform 2.7.5 → 2.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/CHANGELOG.md +16 -0
- package/agents/dgs-executor.md +0 -52
- package/deliver-great-systems/bin/dgs-tools.cjs +66 -10
- package/deliver-great-systems/bin/lib/commands.cjs +1 -8
- package/deliver-great-systems/bin/lib/config.cjs +9 -90
- package/deliver-great-systems/bin/lib/context.cjs +2 -2
- package/deliver-great-systems/bin/lib/context.test.cjs +100 -100
- package/deliver-great-systems/bin/lib/core.cjs +17 -57
- package/deliver-great-systems/bin/lib/core.test.cjs +166 -170
- package/deliver-great-systems/bin/lib/docs.cjs +3 -3
- package/deliver-great-systems/bin/lib/docs.test.cjs +14 -7
- package/deliver-great-systems/bin/lib/execution.cjs +2 -2
- package/deliver-great-systems/bin/lib/execution.test.cjs +65 -67
- package/deliver-great-systems/bin/lib/ideas.cjs +4 -4
- package/deliver-great-systems/bin/lib/ideas.test.cjs +45 -44
- package/deliver-great-systems/bin/lib/init.cjs +9 -4
- package/deliver-great-systems/bin/lib/init.test.cjs +242 -175
- package/deliver-great-systems/bin/lib/jobs.cjs +1 -1
- package/deliver-great-systems/bin/lib/jobs.test.cjs +203 -202
- package/deliver-great-systems/bin/lib/migration.cjs +256 -281
- package/deliver-great-systems/bin/lib/migration.test.cjs +385 -440
- package/deliver-great-systems/bin/lib/milestone.cjs +1 -1
- package/deliver-great-systems/bin/lib/overlap.cjs +4 -4
- package/deliver-great-systems/bin/lib/overlap.test.cjs +45 -44
- package/deliver-great-systems/bin/lib/path-audit.test.cjs +16 -22
- package/deliver-great-systems/bin/lib/paths.cjs +60 -59
- package/deliver-great-systems/bin/lib/paths.test.cjs +192 -225
- package/deliver-great-systems/bin/lib/phase.cjs +5 -4
- package/deliver-great-systems/bin/lib/projects.cjs +8 -8
- package/deliver-great-systems/bin/lib/projects.test.cjs +75 -74
- package/deliver-great-systems/bin/lib/repos.cjs +94 -230
- package/deliver-great-systems/bin/lib/repos.test.cjs +84 -75
- package/deliver-great-systems/bin/lib/search.cjs +4 -4
- package/deliver-great-systems/bin/lib/specs.cjs +2 -2
- package/deliver-great-systems/bin/lib/sync.cjs +1 -1
- package/deliver-great-systems/bin/lib/template.cjs +3 -3
- package/deliver-great-systems/bin/lib/test-helpers.cjs +59 -162
- package/deliver-great-systems/bin/lib/verify.cjs +3 -3
- package/deliver-great-systems/references/planning-config.md +7 -8
- package/deliver-great-systems/workflows/add-tests.md +1 -1
- package/deliver-great-systems/workflows/approve-spec.md +1 -11
- package/deliver-great-systems/workflows/complete-milestone.md +2 -2
- package/deliver-great-systems/workflows/consolidate-ideas.md +1 -1
- package/deliver-great-systems/workflows/create-milestone-job.md +2 -2
- package/deliver-great-systems/workflows/discuss-phase.md +2 -2
- package/deliver-great-systems/workflows/execute-phase.md +63 -4
- package/deliver-great-systems/workflows/execute-plan.md +0 -51
- package/deliver-great-systems/workflows/find-related-ideas.md +1 -1
- package/deliver-great-systems/workflows/help.md +25 -58
- package/deliver-great-systems/workflows/init-product.md +14 -451
- package/deliver-great-systems/workflows/map-codebase.md +109 -0
- package/deliver-great-systems/workflows/new-project.md +0 -1
- package/deliver-great-systems/workflows/quick.md +2 -2
- package/deliver-great-systems/workflows/run-job.md +56 -0
- package/package.json +1 -1
|
@@ -11,17 +11,11 @@ const path = require('path');
|
|
|
11
11
|
const { safeReadFile, execGit, isV2Install, output, error } = require('./core.cjs');
|
|
12
12
|
const { writeConfigField } = require('./config.cjs');
|
|
13
13
|
const { getPlanningRoot, resetPaths } = require('./paths.cjs');
|
|
14
|
-
// Lazy-loaded to avoid circular dependency (migration.cjs requires writeReposMd from this file)
|
|
15
|
-
let _migration;
|
|
16
|
-
function migration() {
|
|
17
|
-
if (!_migration) _migration = require('./migration.cjs');
|
|
18
|
-
return _migration;
|
|
19
|
-
}
|
|
20
14
|
|
|
21
15
|
// ─── REPOS.md Parse / Write ──────────────────────────────────────────────────
|
|
22
16
|
|
|
23
17
|
/**
|
|
24
|
-
* Parse
|
|
18
|
+
* Parse REPOS.md into structured data.
|
|
25
19
|
*
|
|
26
20
|
* Returns null if the file doesn't exist or doesn't start with '# Repos'.
|
|
27
21
|
* Returns { repos: [] } if the header exists but the table has no data rows.
|
|
@@ -76,7 +70,7 @@ function parseReposMd(cwd) {
|
|
|
76
70
|
}
|
|
77
71
|
|
|
78
72
|
/**
|
|
79
|
-
* Write repos array to
|
|
73
|
+
* Write repos array to REPOS.md with standard format.
|
|
80
74
|
*
|
|
81
75
|
* Creates the '# Repos' header (v2 marker), explanatory text, and
|
|
82
76
|
* a properly formatted markdown table.
|
|
@@ -268,7 +262,6 @@ function extractRepoDescription(repoPath) {
|
|
|
268
262
|
*
|
|
269
263
|
* Scans for subdirectories containing .git/, excluding:
|
|
270
264
|
* - node_modules
|
|
271
|
-
* - .planning
|
|
272
265
|
* - Dot-directories (starting with '.')
|
|
273
266
|
* - Non-directories (files)
|
|
274
267
|
*
|
|
@@ -513,7 +506,7 @@ function hasPathConflict(newPath, existingRepos) {
|
|
|
513
506
|
// ─── PROJECTS.md Scaffold ────────────────────────────────────────────────────
|
|
514
507
|
|
|
515
508
|
/**
|
|
516
|
-
* Write
|
|
509
|
+
* Write PROJECTS.MD with standard scaffold format.
|
|
517
510
|
*
|
|
518
511
|
* Creates the '# Projects' header (v2 marker), Active and Completed
|
|
519
512
|
* sections with table headers.
|
|
@@ -689,124 +682,81 @@ function validateReposConsistency(planContent, repos) {
|
|
|
689
682
|
// ─── Layout Detection ─────────────────────────────────────────────────────────
|
|
690
683
|
|
|
691
684
|
/**
|
|
692
|
-
* Detect
|
|
685
|
+
* Detect whether a repo has existing root-layout planning or is fresh.
|
|
693
686
|
*
|
|
694
687
|
* Heuristic (checked in order):
|
|
695
|
-
* 1. .
|
|
696
|
-
* 2.
|
|
697
|
-
* 3.
|
|
698
|
-
* 4.
|
|
699
|
-
* 5. Default -> dotplanning (safer default)
|
|
688
|
+
* 1. config.local.json at root -> root (already configured)
|
|
689
|
+
* 2. Repo is empty-ish (no source code indicators at depth 1) -> root
|
|
690
|
+
* 3. Planning artifacts at root (PROJECT.md, ROADMAP.md) -> root
|
|
691
|
+
* 4. Default -> fresh (no planning setup detected)
|
|
700
692
|
*
|
|
701
693
|
* @param {string} cwd - Working directory (repo root)
|
|
702
694
|
* @param {boolean} raw - Raw output mode
|
|
703
695
|
*/
|
|
704
696
|
function cmdDetectLayout(cwd, raw) {
|
|
705
697
|
const signals = [];
|
|
706
|
-
// Pre-init detection: must check .planning/ directly (not via getPlanningRoot)
|
|
707
|
-
const DOT_PLANNING_DIR = '.planning';
|
|
708
|
-
const dotPlanning = path.join(cwd, DOT_PLANNING_DIR);
|
|
709
|
-
|
|
710
|
-
// Signal 1: .planning/ directory with config files
|
|
711
|
-
if (
|
|
712
|
-
fs.existsSync(path.join(dotPlanning, 'config.json')) ||
|
|
713
|
-
fs.existsSync(path.join(dotPlanning, 'config.local.json')) ||
|
|
714
|
-
fs.existsSync(path.join(dotPlanning, 'dgs.config.json'))
|
|
715
|
-
) {
|
|
716
|
-
signals.push('existing .planning/ directory with config files');
|
|
717
|
-
output({ suggested: 'dotplanning', signals }, raw);
|
|
718
|
-
return;
|
|
719
|
-
}
|
|
720
698
|
|
|
721
|
-
// Signal
|
|
699
|
+
// Signal 1: config.local.json at root
|
|
722
700
|
const rootLocalConfigPath = path.join(cwd, 'config.local.json');
|
|
723
701
|
if (fs.existsSync(rootLocalConfigPath)) {
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
signals.push('config.local.json at root with planningRoot: "."');
|
|
728
|
-
output({ suggested: 'root', signals }, raw);
|
|
729
|
-
return;
|
|
730
|
-
}
|
|
731
|
-
} catch { /* malformed config -- continue detection */ }
|
|
702
|
+
signals.push('config.local.json at root');
|
|
703
|
+
output({ suggested: 'root', signals }, raw);
|
|
704
|
+
return;
|
|
732
705
|
}
|
|
733
706
|
|
|
734
|
-
// Signal
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
707
|
+
// Signal 2: Empty-ish repo (no source code indicators at depth 1)
|
|
708
|
+
let hasSourceIndicators = false;
|
|
709
|
+
try {
|
|
710
|
+
const entries = fs.readdirSync(cwd, { withFileTypes: true });
|
|
711
|
+
const SOURCE_EXTENSIONS = ['.ts', '.js', '.py', '.go', '.rs', '.java'];
|
|
712
|
+
|
|
713
|
+
for (const entry of entries) {
|
|
714
|
+
const name = entry.name;
|
|
715
|
+
// Skip hidden files/dirs
|
|
716
|
+
if (name.startsWith('.')) continue;
|
|
717
|
+
|
|
718
|
+
// Check for source code directories
|
|
719
|
+
if (entry.isDirectory() && (name === 'src' || name === 'lib')) {
|
|
720
|
+
hasSourceIndicators = true;
|
|
721
|
+
break;
|
|
743
722
|
}
|
|
744
|
-
} catch { /* malformed config -- continue detection */ }
|
|
745
|
-
}
|
|
746
|
-
|
|
747
|
-
// Signal 3: Empty-ish repo (no source code indicators at depth 1)
|
|
748
|
-
const hasDotPlanning = fs.existsSync(dotPlanning);
|
|
749
|
-
if (!hasDotPlanning) {
|
|
750
|
-
let hasSourceIndicators = false;
|
|
751
|
-
try {
|
|
752
|
-
const entries = fs.readdirSync(cwd, { withFileTypes: true });
|
|
753
|
-
const SOURCE_EXTENSIONS = ['.ts', '.js', '.py', '.go', '.rs', '.java'];
|
|
754
723
|
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
// Check for source code directories
|
|
761
|
-
if (entry.isDirectory() && (name === 'src' || name === 'lib')) {
|
|
762
|
-
hasSourceIndicators = true;
|
|
763
|
-
break;
|
|
764
|
-
}
|
|
724
|
+
// Check for package.json
|
|
725
|
+
if (name === 'package.json') {
|
|
726
|
+
hasSourceIndicators = true;
|
|
727
|
+
break;
|
|
728
|
+
}
|
|
765
729
|
|
|
766
|
-
|
|
767
|
-
|
|
730
|
+
// Check for source code files at depth 1
|
|
731
|
+
if (entry.isFile()) {
|
|
732
|
+
const ext = path.extname(name);
|
|
733
|
+
if (SOURCE_EXTENSIONS.includes(ext)) {
|
|
768
734
|
hasSourceIndicators = true;
|
|
769
735
|
break;
|
|
770
736
|
}
|
|
771
|
-
|
|
772
|
-
// Check for source code files at depth 1
|
|
773
|
-
if (entry.isFile()) {
|
|
774
|
-
const ext = path.extname(name);
|
|
775
|
-
if (SOURCE_EXTENSIONS.includes(ext)) {
|
|
776
|
-
hasSourceIndicators = true;
|
|
777
|
-
break;
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
737
|
}
|
|
781
|
-
} catch { /* can't read dir — treat as not empty-ish */ hasSourceIndicators = true; }
|
|
782
|
-
|
|
783
|
-
if (!hasSourceIndicators) {
|
|
784
|
-
signals.push('repo is empty-ish (no source code indicators at depth 1)');
|
|
785
|
-
output({ suggested: 'root', signals }, raw);
|
|
786
|
-
return;
|
|
787
738
|
}
|
|
788
|
-
}
|
|
739
|
+
} catch { /* can't read dir -- treat as not empty-ish */ hasSourceIndicators = true; }
|
|
789
740
|
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
fs.existsSync(path.join(cwd, 'ROADMAP.md'));
|
|
795
|
-
if (hasPlanningArtifacts) {
|
|
796
|
-
signals.push('planning artifacts (PROJECT.md or ROADMAP.md) at root without .planning/');
|
|
797
|
-
output({ suggested: 'root', signals }, raw);
|
|
798
|
-
return;
|
|
799
|
-
}
|
|
741
|
+
if (!hasSourceIndicators) {
|
|
742
|
+
signals.push('repo is empty-ish (no source code indicators at depth 1)');
|
|
743
|
+
output({ suggested: 'root', signals }, raw);
|
|
744
|
+
return;
|
|
800
745
|
}
|
|
801
746
|
|
|
802
|
-
// Signal
|
|
803
|
-
|
|
804
|
-
|
|
747
|
+
// Signal 3: Planning artifacts at root
|
|
748
|
+
const hasPlanningArtifacts =
|
|
749
|
+
fs.existsSync(path.join(cwd, 'PROJECT.md')) ||
|
|
750
|
+
fs.existsSync(path.join(cwd, 'ROADMAP.md'));
|
|
751
|
+
if (hasPlanningArtifacts) {
|
|
752
|
+
signals.push('planning artifacts (PROJECT.md or ROADMAP.md) at root');
|
|
753
|
+
output({ suggested: 'root', signals }, raw);
|
|
754
|
+
return;
|
|
805
755
|
}
|
|
806
756
|
|
|
807
|
-
// Default:
|
|
808
|
-
signals.push('default (no
|
|
809
|
-
output({ suggested: '
|
|
757
|
+
// Default: fresh (no planning setup detected)
|
|
758
|
+
signals.push('default (no planning setup detected)');
|
|
759
|
+
output({ suggested: 'fresh', signals }, raw);
|
|
810
760
|
}
|
|
811
761
|
|
|
812
762
|
// ─── Root-Layout .gitignore ───────────────────────────────────────────────────
|
|
@@ -1126,101 +1076,40 @@ function cmdReposResolve(cwd, filePath, raw) {
|
|
|
1126
1076
|
}
|
|
1127
1077
|
|
|
1128
1078
|
/**
|
|
1129
|
-
* Initialize a product folder structure (v2 mode).
|
|
1130
|
-
* Creates REPOS.md, PROJECTS.md,
|
|
1079
|
+
* Initialize a product folder structure (v2 mode, root layout).
|
|
1080
|
+
* Creates REPOS.md, PROJECTS.md, generates .gitignore, updates config.
|
|
1131
1081
|
*
|
|
1132
|
-
*
|
|
1133
|
-
*
|
|
1134
|
-
* with planningRoot:'.', then creates all artifacts at repo root (no .planning/).
|
|
1135
|
-
* - layout=null (default): Standard .planning/ layout (unchanged).
|
|
1082
|
+
* All initialization uses root layout -- config.local.json at repo root,
|
|
1083
|
+
* planning artifacts at repo root (no subdirectory).
|
|
1136
1084
|
*
|
|
1137
1085
|
* @param {string} cwd - Working directory
|
|
1138
1086
|
* @param {Object} options - { productName?: string, layout?: string }
|
|
1139
1087
|
* @param {boolean} raw - Raw output mode
|
|
1140
1088
|
*/
|
|
1141
1089
|
function cmdReposInitProduct(cwd, options, raw) {
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
fs.writeFileSync(
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
// Silently ensure v3.0 directories exist (backfill for upgrades)
|
|
1159
|
-
const ideasStates = ['pending', 'rejected', 'done'];
|
|
1160
|
-
for (const st of ideasStates) {
|
|
1161
|
-
fs.mkdirSync(path.join(getPlanningRoot(cwd), 'ideas', st), { recursive: true });
|
|
1162
|
-
}
|
|
1163
|
-
fs.mkdirSync(path.join(getPlanningRoot(cwd), 'specs'), { recursive: true });
|
|
1164
|
-
fs.mkdirSync(path.join(getPlanningRoot(cwd), 'docs', 'product'), { recursive: true });
|
|
1165
|
-
error('Product already initialized. Use /dgs:progress to see status.');
|
|
1166
|
-
}
|
|
1167
|
-
} else {
|
|
1168
|
-
// ── Standard layout: existing v1/v2 checks ────────────────────────────
|
|
1169
|
-
// Check if user previously declined v1-to-v2 migration
|
|
1170
|
-
const configPath = path.join(getPlanningRoot(cwd), 'config.json');
|
|
1171
|
-
let existingConfig = {};
|
|
1172
|
-
try {
|
|
1173
|
-
existingConfig = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
1174
|
-
} catch { /* no config yet */ }
|
|
1175
|
-
if (existingConfig.v1_decline_migration) {
|
|
1176
|
-
output({
|
|
1177
|
-
v1_declined: true,
|
|
1178
|
-
message: 'v1 mode preserved (migration was previously declined). Your v1 setup continues to work unchanged.',
|
|
1179
|
-
}, raw);
|
|
1180
|
-
return;
|
|
1181
|
-
}
|
|
1182
|
-
|
|
1183
|
-
// Check for v1 install (existing .planning/PROJECT.md without v2 markers)
|
|
1184
|
-
const v1Check = migration().detectV1Install(cwd);
|
|
1185
|
-
if (v1Check.isV1) {
|
|
1186
|
-
// Return v1 detection info — workflow handles the user prompt
|
|
1187
|
-
output({
|
|
1188
|
-
v1_detected: true,
|
|
1189
|
-
project_name: v1Check.projectName,
|
|
1190
|
-
slug: v1Check.slug,
|
|
1191
|
-
}, raw);
|
|
1192
|
-
return;
|
|
1193
|
-
}
|
|
1194
|
-
|
|
1195
|
-
// Check if already v2
|
|
1196
|
-
if (isV2Install(cwd)) {
|
|
1197
|
-
// Silently ensure v3.0 directories exist (backfill for upgrades)
|
|
1198
|
-
const ideasStates = ['pending', 'rejected', 'done'];
|
|
1199
|
-
for (const st of ideasStates) {
|
|
1200
|
-
fs.mkdirSync(path.join(getPlanningRoot(cwd), 'ideas', st), { recursive: true });
|
|
1201
|
-
}
|
|
1202
|
-
fs.mkdirSync(path.join(getPlanningRoot(cwd), 'specs'), { recursive: true });
|
|
1203
|
-
fs.mkdirSync(path.join(getPlanningRoot(cwd), 'docs', 'product'), { recursive: true });
|
|
1204
|
-
// Add .gitkeep files if directories are empty
|
|
1205
|
-
const dirsToKeep = [
|
|
1206
|
-
path.join(getPlanningRoot(cwd), 'ideas', 'pending', '.gitkeep'),
|
|
1207
|
-
path.join(getPlanningRoot(cwd), 'ideas', 'rejected', '.gitkeep'),
|
|
1208
|
-
path.join(getPlanningRoot(cwd), 'ideas', 'done', '.gitkeep'),
|
|
1209
|
-
path.join(getPlanningRoot(cwd), 'specs', '.gitkeep'),
|
|
1210
|
-
path.join(getPlanningRoot(cwd), 'docs', 'product', '.gitkeep'),
|
|
1211
|
-
];
|
|
1212
|
-
for (const gk of dirsToKeep) {
|
|
1213
|
-
if (!fs.existsSync(gk)) {
|
|
1214
|
-
fs.writeFileSync(gk, '', 'utf-8');
|
|
1215
|
-
}
|
|
1216
|
-
}
|
|
1217
|
-
error('Product already initialized. Use /dgs:progress to see status.');
|
|
1090
|
+
// Write config.local.json FIRST so getPlanningRoot returns repo root
|
|
1091
|
+
const rootLocalConfigPath = path.join(cwd, 'config.local.json');
|
|
1092
|
+
fs.writeFileSync(rootLocalConfigPath, JSON.stringify({}, null, 2));
|
|
1093
|
+
// Write empty shared config.json at root
|
|
1094
|
+
const rootSharedConfigPath = path.join(cwd, 'config.json');
|
|
1095
|
+
if (!fs.existsSync(rootSharedConfigPath)) {
|
|
1096
|
+
fs.writeFileSync(rootSharedConfigPath, JSON.stringify({}, null, 2));
|
|
1097
|
+
}
|
|
1098
|
+
resetPaths(); // Clear stale cache so getPlanningRoot resolves to cwd
|
|
1099
|
+
|
|
1100
|
+
// Check if already initialized (idempotency)
|
|
1101
|
+
if (isV2Install(cwd)) {
|
|
1102
|
+
// Silently ensure v3.0 directories exist (backfill for upgrades)
|
|
1103
|
+
const ideasStates = ['pending', 'rejected', 'done'];
|
|
1104
|
+
for (const st of ideasStates) {
|
|
1105
|
+
fs.mkdirSync(path.join(getPlanningRoot(cwd), 'ideas', st), { recursive: true });
|
|
1218
1106
|
}
|
|
1107
|
+
fs.mkdirSync(path.join(getPlanningRoot(cwd), 'specs'), { recursive: true });
|
|
1108
|
+
fs.mkdirSync(path.join(getPlanningRoot(cwd), 'docs', 'product'), { recursive: true });
|
|
1109
|
+
error('Product already initialized. Use /dgs:progress to see status.');
|
|
1219
1110
|
}
|
|
1220
1111
|
|
|
1221
|
-
//
|
|
1222
|
-
|
|
1223
|
-
// Ensure planning root exists (for standard layout creates .planning/; for root it's cwd)
|
|
1112
|
+
// Planning root is cwd (root layout)
|
|
1224
1113
|
fs.mkdirSync(getPlanningRoot(cwd), { recursive: true });
|
|
1225
1114
|
|
|
1226
1115
|
// Create ideas, specs, and docs directories for v3.0 features
|
|
@@ -1270,52 +1159,27 @@ function cmdReposInitProduct(cwd, options, raw) {
|
|
|
1270
1159
|
// Write REPOS.md
|
|
1271
1160
|
writeReposMd(cwd, allRepos);
|
|
1272
1161
|
|
|
1273
|
-
// Write PROJECTS.md (empty
|
|
1162
|
+
// Write PROJECTS.md (empty -- no projects yet)
|
|
1274
1163
|
writeProjectsMd(cwd, []);
|
|
1275
1164
|
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
generateRootGitignore(cwd);
|
|
1279
|
-
|
|
1280
|
-
// Update config with product_name (config already exists from config-first step)
|
|
1281
|
-
writeConfigField(cwd, 'product_name', productName);
|
|
1282
|
-
|
|
1283
|
-
output({
|
|
1284
|
-
initialized: true,
|
|
1285
|
-
layout: 'root',
|
|
1286
|
-
product_name: productName,
|
|
1287
|
-
repos_found: allRepos.length,
|
|
1288
|
-
repos: allRepos,
|
|
1289
|
-
needs_git_init: needsGitInit,
|
|
1290
|
-
ideas_dirs_created: true,
|
|
1291
|
-
specs_dir_created: true,
|
|
1292
|
-
docs_dir_created: true,
|
|
1293
|
-
files_created: ['config.json', 'config.local.json', 'REPOS.md', 'PROJECTS.md', 'ideas/', 'specs/', 'docs/', '.gitignore', 'review-keys.json'],
|
|
1294
|
-
}, raw);
|
|
1295
|
-
} else {
|
|
1296
|
-
// Standard layout: sync .gitignore for local repo paths
|
|
1297
|
-
const localPaths = allRepos.map(r => r.path).filter(p => p.startsWith('./'));
|
|
1298
|
-
if (localPaths.length > 0) {
|
|
1299
|
-
syncGitignore(cwd, localPaths);
|
|
1300
|
-
}
|
|
1165
|
+
// Generate .gitignore for root-layout repo
|
|
1166
|
+
generateRootGitignore(cwd);
|
|
1301
1167
|
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
}, raw);
|
|
1318
|
-
}
|
|
1168
|
+
// Update config with product_name (config already exists from config-first step)
|
|
1169
|
+
writeConfigField(cwd, 'product_name', productName);
|
|
1170
|
+
|
|
1171
|
+
output({
|
|
1172
|
+
initialized: true,
|
|
1173
|
+
layout: 'root',
|
|
1174
|
+
product_name: productName,
|
|
1175
|
+
repos_found: allRepos.length,
|
|
1176
|
+
repos: allRepos,
|
|
1177
|
+
needs_git_init: needsGitInit,
|
|
1178
|
+
ideas_dirs_created: true,
|
|
1179
|
+
specs_dir_created: true,
|
|
1180
|
+
docs_dir_created: true,
|
|
1181
|
+
files_created: ['config.json', 'config.local.json', 'REPOS.md', 'PROJECTS.md', 'ideas/', 'specs/', 'docs/', '.gitignore', 'review-keys.json'],
|
|
1182
|
+
}, raw);
|
|
1319
1183
|
}
|
|
1320
1184
|
|
|
1321
1185
|
/**
|