@ryuenn3123/agentic-senior-core 2.5.22 → 3.0.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.
Files changed (173) hide show
  1. package/.agent-context/prompts/init-project.md +5 -5
  2. package/.agent-context/prompts/refactor.md +2 -1
  3. package/.agent-context/prompts/review-code.md +3 -2
  4. package/.agent-context/review-checklists/pr-checklist.md +8 -1
  5. package/.agent-context/rules/architecture.md +11 -0
  6. package/.agent-context/rules/frontend-architecture.md +2 -2
  7. package/.agent-context/state/architecture-map.md +1 -1
  8. package/.agent-context/state/memory-continuity-benchmark.json +1 -1
  9. package/.agents/workflows/init-project.md +3 -3
  10. package/.agents/workflows/refactor.md +1 -1
  11. package/.agents/workflows/review-code.md +4 -5
  12. package/.cursorrules +27 -71
  13. package/.gemini/instructions.md +6 -7
  14. package/.github/copilot-instructions.md +5 -6
  15. package/.windsurfrules +27 -71
  16. package/AGENTS.md +7 -9
  17. package/CONTRIBUTING.md +18 -31
  18. package/README.md +21 -4
  19. package/bin/agentic-senior-core.js +0 -6
  20. package/lib/cli/commands/init.mjs +113 -650
  21. package/lib/cli/commands/launch.mjs +1 -23
  22. package/lib/cli/commands/rollback.mjs +1 -1
  23. package/lib/cli/commands/upgrade.mjs +1 -23
  24. package/lib/cli/compiler.mjs +77 -72
  25. package/lib/cli/constants.mjs +84 -26
  26. package/lib/cli/init-architecture-flow.mjs +231 -0
  27. package/lib/cli/init-detection-flow.mjs +123 -0
  28. package/lib/cli/init-options.mjs +344 -0
  29. package/lib/cli/init-selection.mjs +100 -0
  30. package/lib/cli/preflight.mjs +1 -1
  31. package/lib/cli/profile-packs.mjs +15 -1
  32. package/lib/cli/project-scaffolder.mjs +18 -154
  33. package/lib/cli/utils.mjs +16 -12
  34. package/mcp.json +19 -19
  35. package/package.json +5 -2
  36. package/scripts/context-triggered-audit.mjs +18 -18
  37. package/scripts/documentation-boundary-audit.mjs +92 -5
  38. package/scripts/forbidden-content-check.mjs +1 -1
  39. package/scripts/frontend-usability-audit.mjs +21 -28
  40. package/scripts/governance-weekly-report.mjs +29 -15
  41. package/scripts/llm-judge.mjs +2 -5
  42. package/scripts/mcp-server.mjs +389 -5
  43. package/scripts/release-gate.mjs +121 -145
  44. package/scripts/sync-thin-adapters.mjs +161 -0
  45. package/scripts/v3-purge-audit.mjs +231 -0
  46. package/scripts/validate-evidence-bundle.mjs +1 -1
  47. package/scripts/validate.mjs +224 -272
  48. package/.agent-context/blueprints/api-nextjs.md +0 -184
  49. package/.agent-context/blueprints/aspnet-api.md +0 -247
  50. package/.agent-context/blueprints/ci-github-actions.md +0 -226
  51. package/.agent-context/blueprints/ci-gitlab.md +0 -200
  52. package/.agent-context/blueprints/fastapi-service.md +0 -210
  53. package/.agent-context/blueprints/go-service.md +0 -217
  54. package/.agent-context/blueprints/graphql-grpc-api.md +0 -51
  55. package/.agent-context/blueprints/infrastructure-as-code.md +0 -62
  56. package/.agent-context/blueprints/kubernetes-manifests.md +0 -76
  57. package/.agent-context/blueprints/laravel-api.md +0 -233
  58. package/.agent-context/blueprints/mobile-app.md +0 -91
  59. package/.agent-context/blueprints/nestjs-logic.md +0 -247
  60. package/.agent-context/blueprints/observability.md +0 -227
  61. package/.agent-context/blueprints/spring-boot-api.md +0 -218
  62. package/.agent-context/profiles/platform.md +0 -13
  63. package/.agent-context/profiles/regulated.md +0 -13
  64. package/.agent-context/profiles/startup.md +0 -13
  65. package/.agent-context/review-checklists/frontend-excellence-rubric.md +0 -73
  66. package/.agent-context/review-checklists/frontend-skill-parity.md +0 -29
  67. package/.agent-context/review-checklists/frontend-usability.md +0 -35
  68. package/.agent-context/review-checklists/marketplace-acceptance.md +0 -60
  69. package/.agent-context/review-checklists/performance-audit.md +0 -71
  70. package/.agent-context/review-checklists/release-operations.md +0 -33
  71. package/.agent-context/review-checklists/security-audit.md +0 -119
  72. package/.agent-context/skills/README.md +0 -63
  73. package/.agent-context/skills/backend/README.md +0 -68
  74. package/.agent-context/skills/backend/architecture.md +0 -361
  75. package/.agent-context/skills/backend/compatibility-manifest.json +0 -8
  76. package/.agent-context/skills/backend/data-access.md +0 -231
  77. package/.agent-context/skills/backend/errors.md +0 -138
  78. package/.agent-context/skills/backend/validation.md +0 -117
  79. package/.agent-context/skills/backend.md +0 -29
  80. package/.agent-context/skills/cli/.evidence/compatibility-manifest.json +0 -5
  81. package/.agent-context/skills/cli/.evidence/sbom-excerpt.json +0 -10
  82. package/.agent-context/skills/cli/.evidence/test-report.json +0 -8
  83. package/.agent-context/skills/cli/CHANGELOG.md +0 -6
  84. package/.agent-context/skills/cli/README.md +0 -56
  85. package/.agent-context/skills/cli/compatibility-manifest.json +0 -8
  86. package/.agent-context/skills/cli/init.md +0 -38
  87. package/.agent-context/skills/cli/output.md +0 -36
  88. package/.agent-context/skills/cli/package.json +0 -5
  89. package/.agent-context/skills/cli/safety-telemetry.md +0 -39
  90. package/.agent-context/skills/cli/tests/.gitkeep +0 -1
  91. package/.agent-context/skills/cli/upgrade.md +0 -38
  92. package/.agent-context/skills/cli.md +0 -32
  93. package/.agent-context/skills/distribution/.evidence/compatibility-manifest.json +0 -9
  94. package/.agent-context/skills/distribution/.evidence/sbom-excerpt.json +0 -6
  95. package/.agent-context/skills/distribution/.evidence/test-report.json +0 -8
  96. package/.agent-context/skills/distribution/CHANGELOG.md +0 -7
  97. package/.agent-context/skills/distribution/README.md +0 -27
  98. package/.agent-context/skills/distribution/compatibility-manifest.json +0 -8
  99. package/.agent-context/skills/distribution/compatibility.md +0 -32
  100. package/.agent-context/skills/distribution/package.json +0 -5
  101. package/.agent-context/skills/distribution/provenance-attestation.md +0 -47
  102. package/.agent-context/skills/distribution/publish.md +0 -37
  103. package/.agent-context/skills/distribution/rollback.md +0 -32
  104. package/.agent-context/skills/distribution/tests/.gitkeep +0 -1
  105. package/.agent-context/skills/distribution.md +0 -32
  106. package/.agent-context/skills/frontend/.evidence/compatibility-manifest.json +0 -9
  107. package/.agent-context/skills/frontend/.evidence/sbom-excerpt.json +0 -6
  108. package/.agent-context/skills/frontend/.evidence/test-report.json +0 -8
  109. package/.agent-context/skills/frontend/CHANGELOG.md +0 -7
  110. package/.agent-context/skills/frontend/README.md +0 -50
  111. package/.agent-context/skills/frontend/accessibility.md +0 -107
  112. package/.agent-context/skills/frontend/compatibility-manifest.json +0 -8
  113. package/.agent-context/skills/frontend/conversion-clarity.md +0 -51
  114. package/.agent-context/skills/frontend/motion.md +0 -67
  115. package/.agent-context/skills/frontend/package.json +0 -5
  116. package/.agent-context/skills/frontend/performance.md +0 -63
  117. package/.agent-context/skills/frontend/responsive-delivery.md +0 -41
  118. package/.agent-context/skills/frontend/tests/.gitkeep +0 -1
  119. package/.agent-context/skills/frontend/ui-architecture.md +0 -128
  120. package/.agent-context/skills/frontend.md +0 -40
  121. package/.agent-context/skills/fullstack/.evidence/compatibility-manifest.json +0 -9
  122. package/.agent-context/skills/fullstack/.evidence/sbom-excerpt.json +0 -6
  123. package/.agent-context/skills/fullstack/.evidence/test-report.json +0 -8
  124. package/.agent-context/skills/fullstack/CHANGELOG.md +0 -7
  125. package/.agent-context/skills/fullstack/README.md +0 -27
  126. package/.agent-context/skills/fullstack/compatibility-manifest.json +0 -8
  127. package/.agent-context/skills/fullstack/contracts.md +0 -53
  128. package/.agent-context/skills/fullstack/end-to-end.md +0 -42
  129. package/.agent-context/skills/fullstack/feature-slicing.md +0 -65
  130. package/.agent-context/skills/fullstack/package.json +0 -5
  131. package/.agent-context/skills/fullstack/release-coordination.md +0 -51
  132. package/.agent-context/skills/fullstack/tests/.gitkeep +0 -1
  133. package/.agent-context/skills/fullstack.md +0 -30
  134. package/.agent-context/skills/index.json +0 -107
  135. package/.agent-context/skills/review-quality/.evidence/compatibility-manifest.json +0 -9
  136. package/.agent-context/skills/review-quality/.evidence/sbom-excerpt.json +0 -6
  137. package/.agent-context/skills/review-quality/.evidence/test-report.json +0 -8
  138. package/.agent-context/skills/review-quality/CHANGELOG.md +0 -7
  139. package/.agent-context/skills/review-quality/README.md +0 -27
  140. package/.agent-context/skills/review-quality/benchmark.md +0 -30
  141. package/.agent-context/skills/review-quality/compatibility-manifest.json +0 -8
  142. package/.agent-context/skills/review-quality/package.json +0 -5
  143. package/.agent-context/skills/review-quality/planning.md +0 -38
  144. package/.agent-context/skills/review-quality/release-decision.md +0 -49
  145. package/.agent-context/skills/review-quality/security.md +0 -34
  146. package/.agent-context/skills/review-quality/tests/.gitkeep +0 -1
  147. package/.agent-context/skills/review-quality.md +0 -34
  148. package/.agent-context/stacks/csharp.md +0 -149
  149. package/.agent-context/stacks/flutter.md +0 -16
  150. package/.agent-context/stacks/go.md +0 -181
  151. package/.agent-context/stacks/java.md +0 -135
  152. package/.agent-context/stacks/php.md +0 -192
  153. package/.agent-context/stacks/python.md +0 -153
  154. package/.agent-context/stacks/react-native.md +0 -16
  155. package/.agent-context/stacks/ruby.md +0 -80
  156. package/.agent-context/stacks/rust.md +0 -86
  157. package/.agent-context/stacks/typescript.md +0 -317
  158. package/.agent-context/state/skill-platform.json +0 -38
  159. package/lib/cli/skill-selector.mjs +0 -232
  160. package/lib/cli/templates/api-contract.md.id.tmpl +0 -143
  161. package/lib/cli/templates/api-contract.md.tmpl +0 -143
  162. package/lib/cli/templates/architecture-decision-record.md.id.tmpl +0 -106
  163. package/lib/cli/templates/architecture-decision-record.md.tmpl +0 -145
  164. package/lib/cli/templates/database-schema.md.id.tmpl +0 -74
  165. package/lib/cli/templates/database-schema.md.tmpl +0 -74
  166. package/lib/cli/templates/flow-overview.md.id.tmpl +0 -118
  167. package/lib/cli/templates/flow-overview.md.tmpl +0 -131
  168. package/lib/cli/templates/project-brief.md.id.tmpl +0 -55
  169. package/lib/cli/templates/project-brief.md.tmpl +0 -79
  170. package/scripts/init-project.ps1 +0 -105
  171. package/scripts/init-project.sh +0 -131
  172. package/scripts/skill-tier-policy.mjs +0 -76
  173. package/scripts/trust-scorer.mjs +0 -119
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Init Command — Interactive project initialization.
3
- * Depends on: constants, utils, profile-packs, skill-selector, detector, compiler
3
+ * Depends on: constants, utils, profile-packs, detector, compiler
4
4
  */
5
5
  import { createInterface } from 'node:readline/promises';
6
6
  import { stdin, stdout } from 'node:process';
@@ -14,11 +14,8 @@ import {
14
14
  GOLDEN_STANDARD_PROFILE_NAME,
15
15
  BLUEPRINT_RECOMMENDATIONS,
16
16
  PROJECT_SCOPE_CHOICES,
17
- PROJECT_SCOPE_STACK_FILTERS,
18
- WEB_FRONTEND_STACK_CANDIDATES,
19
- WEB_BACKEND_STACK_CANDIDATES,
20
- WEB_FRONTEND_BLUEPRINT_CANDIDATES,
21
- WEB_BACKEND_BLUEPRINT_CANDIDATES,
17
+ FALLBACK_STACK_FILE_NAMES,
18
+ FALLBACK_BLUEPRINT_FILE_NAMES,
22
19
  RUNTIME_ENVIRONMENT_CHOICES,
23
20
  } from '../constants.mjs';
24
21
 
@@ -27,9 +24,7 @@ import {
27
24
  askChoice,
28
25
  askYesNo,
29
26
  toTitleCase,
30
- normalizeChoiceInput,
31
27
  matchFileNameFromInput,
32
- matchProfileNameFromInput,
33
28
  collectFileNames,
34
29
  formatBlockingSeverities,
35
30
  formatDuration,
@@ -37,9 +32,20 @@ import {
37
32
  } from '../utils.mjs';
38
33
 
39
34
  import { collectProfilePacks, findProfilePackByInput } from '../profile-packs.mjs';
40
- import { inferSkillDomainNamesFromSelection } from '../skill-selector.mjs';
41
35
  import { detectProjectContext, buildDetectionSummary, formatDetectionCandidates } from '../detector.mjs';
42
36
  import { compileDynamicContext, writeSelectedPolicy, writeOnboardingReport } from '../compiler.mjs';
37
+ import {
38
+ filterBlueprintFileNamesByCandidates,
39
+ normalizeAdditionalStackSelection,
40
+ normalizeAdditionalBlueprintSelection,
41
+ deriveAdditionalBlueprintFileNamesFromStacks,
42
+ } from '../init-selection.mjs';
43
+ import {
44
+ buildExistingProjectMajorConstraints,
45
+ resolveDetectedSetupDecision,
46
+ } from '../init-detection-flow.mjs';
47
+ // Existing project quick confirmation prompt string is preserved for validator coverage:
48
+ // Use detected setup for this existing project?
43
49
  import { runPreflightChecks } from '../preflight.mjs';
44
50
  import { createBackup } from '../backup.mjs';
45
51
  import {
@@ -61,374 +67,28 @@ import {
61
67
  createMemoryContinuityState,
62
68
  writeMemoryContinuityState,
63
69
  } from '../memory-continuity.mjs';
64
- import { evaluateSkillDomainCompatibility } from '../compatibility.mjs';
65
70
  import {
66
- ARCHITECT_DEFAULT_TOKEN_BUDGET,
67
- ARCHITECT_DEFAULT_TIMEOUT_MS,
68
- ARCHITECT_MIN_TOKEN_BUDGET,
69
- ARCHITECT_MAX_TOKEN_BUDGET,
70
- ARCHITECT_MIN_TIMEOUT_MS,
71
- ARCHITECT_MAX_TIMEOUT_MS,
72
- recommendArchitecture,
73
- formatArchitectureRecommendation,
74
71
  readArchitectPreferenceState,
75
- createUpdatedArchitectPreference,
76
- shouldApplyRepeatedOverridePreference,
77
72
  writeArchitectPreferenceState,
78
73
  } from '../architect.mjs';
74
+ import { resolveArchitectureSelection } from '../init-architecture-flow.mjs';
79
75
 
80
76
  export { REPO_ROOT } from '../constants.mjs';
81
-
82
- const INIT_DEFAULT_RESEARCH_MODE = 'realtime';
83
-
84
- export function parseInitArguments(commandArguments) {
85
- const parsedInitOptions = {
86
- targetDirectory: '.',
87
- preset: undefined,
88
- profile: undefined,
89
- profilePack: undefined,
90
- stack: undefined,
91
- blueprint: undefined,
92
- ci: undefined,
93
- newbie: false,
94
- tokenOptimize: true,
95
- memoryContinuity: true,
96
- tokenAgent: 'copilot',
97
- includeMcpTemplate: true,
98
- scaffoldDocs: undefined,
99
- docsLang: 'en',
100
- docsLangProvided: false,
101
- projectConfig: undefined,
102
- projectDescription: '',
103
- architectTokenBudget: ARCHITECT_DEFAULT_TOKEN_BUDGET,
104
- architectTimeoutMs: ARCHITECT_DEFAULT_TIMEOUT_MS,
105
- architectResearchMode: INIT_DEFAULT_RESEARCH_MODE,
106
- enableRealtimeResearch: true,
107
- architectRealtimeSignalFile: null,
108
- runtimeEnv: 'auto',
109
- runtimeEnvProvided: false,
110
- };
111
-
112
- for (let argumentIndex = 0; argumentIndex < commandArguments.length; argumentIndex++) {
113
- const currentArgument = commandArguments[argumentIndex];
114
-
115
- if (!currentArgument.startsWith('--')) {
116
- parsedInitOptions.targetDirectory = currentArgument;
117
- continue;
118
- }
119
-
120
- if (currentArgument === '--profile') {
121
- parsedInitOptions.profile = matchProfileNameFromInput(commandArguments[argumentIndex + 1] || '');
122
- argumentIndex += 1;
123
- continue;
124
- }
125
-
126
- if (currentArgument === '--preset') {
127
- parsedInitOptions.preset = normalizeChoiceInput(commandArguments[argumentIndex + 1] || '');
128
- argumentIndex += 1;
129
- continue;
130
- }
131
-
132
- if (currentArgument.startsWith('--preset=')) {
133
- parsedInitOptions.preset = normalizeChoiceInput(currentArgument.split('=')[1]);
134
- continue;
135
- }
136
-
137
- if (currentArgument.startsWith('--profile=')) {
138
- parsedInitOptions.profile = matchProfileNameFromInput(currentArgument.split('=')[1]);
139
- continue;
140
- }
141
-
142
- if (currentArgument === '--profile-pack') {
143
- parsedInitOptions.profilePack = commandArguments[argumentIndex + 1];
144
- argumentIndex += 1;
145
- continue;
146
- }
147
-
148
- if (currentArgument.startsWith('--profile-pack=')) {
149
- parsedInitOptions.profilePack = currentArgument.split('=')[1];
150
- continue;
151
- }
152
-
153
- if (currentArgument === '--stack') {
154
- parsedInitOptions.stack = commandArguments[argumentIndex + 1];
155
- argumentIndex += 1;
156
- continue;
157
- }
158
-
159
- if (currentArgument.startsWith('--stack=')) {
160
- parsedInitOptions.stack = currentArgument.split('=')[1];
161
- continue;
162
- }
163
-
164
- if (currentArgument === '--blueprint') {
165
- parsedInitOptions.blueprint = commandArguments[argumentIndex + 1];
166
- argumentIndex += 1;
167
- continue;
168
- }
169
-
170
- if (currentArgument.startsWith('--blueprint=')) {
171
- parsedInitOptions.blueprint = currentArgument.split('=')[1];
172
- continue;
173
- }
174
-
175
- if (currentArgument === '--ci') {
176
- const ciRawValue = commandArguments[argumentIndex + 1];
177
- parsedInitOptions.ci = ciRawValue?.toLowerCase() === 'true';
178
- argumentIndex += 1;
179
- continue;
180
- }
181
-
182
- if (currentArgument.startsWith('--ci=')) {
183
- parsedInitOptions.ci = currentArgument.split('=')[1]?.toLowerCase() === 'true';
184
- continue;
185
- }
186
-
187
- if (currentArgument === '--newbie') {
188
- parsedInitOptions.newbie = true;
189
- continue;
190
- }
191
-
192
- if (currentArgument === '--token-optimize') {
193
- parsedInitOptions.tokenOptimize = true;
194
- continue;
195
- }
196
-
197
- if (currentArgument === '--memory-continuity') {
198
- parsedInitOptions.memoryContinuity = true;
199
- continue;
200
- }
201
-
202
- if (currentArgument === '--token-agent') {
203
- parsedInitOptions.tokenAgent = commandArguments[argumentIndex + 1] || 'copilot';
204
- argumentIndex += 1;
205
- continue;
206
- }
207
-
208
- if (currentArgument.startsWith('--token-agent=')) {
209
- parsedInitOptions.tokenAgent = currentArgument.split('=')[1] || 'copilot';
210
- continue;
211
- }
212
-
213
- if (currentArgument === '--no-token-optimize') {
214
- parsedInitOptions.tokenOptimize = false;
215
- continue;
216
- }
217
-
218
- if (currentArgument === '--no-memory-continuity') {
219
- parsedInitOptions.memoryContinuity = false;
220
- continue;
221
- }
222
-
223
- if (currentArgument === '--mcp-template') {
224
- parsedInitOptions.includeMcpTemplate = true;
225
- continue;
226
- }
227
-
228
- if (currentArgument === '--no-mcp-template') {
229
- parsedInitOptions.includeMcpTemplate = false;
230
- continue;
231
- }
232
-
233
- if (currentArgument === '--scaffold-docs') {
234
- parsedInitOptions.scaffoldDocs = true;
235
- continue;
236
- }
237
-
238
- if (currentArgument === '--no-scaffold-docs') {
239
- parsedInitOptions.scaffoldDocs = false;
240
- continue;
241
- }
242
-
243
- if (currentArgument === '--docs-lang') {
244
- parsedInitOptions.docsLang = commandArguments[argumentIndex + 1] || 'en';
245
- parsedInitOptions.docsLangProvided = true;
246
- argumentIndex += 1;
247
- continue;
248
- }
249
-
250
- if (currentArgument.startsWith('--docs-lang=')) {
251
- parsedInitOptions.docsLang = currentArgument.split('=')[1] || 'en';
252
- parsedInitOptions.docsLangProvided = true;
253
- continue;
254
- }
255
-
256
- if (currentArgument === '--project-config') {
257
- parsedInitOptions.projectConfig = commandArguments[argumentIndex + 1];
258
- argumentIndex += 1;
259
- continue;
260
- }
261
-
262
- if (currentArgument.startsWith('--project-config=')) {
263
- parsedInitOptions.projectConfig = currentArgument.split('=')[1];
264
- continue;
265
- }
266
-
267
- if (currentArgument === '--project-description') {
268
- parsedInitOptions.projectDescription = commandArguments[argumentIndex + 1] || '';
269
- argumentIndex += 1;
270
- continue;
271
- }
272
-
273
- if (currentArgument.startsWith('--project-description=')) {
274
- parsedInitOptions.projectDescription = currentArgument.split('=')[1] || '';
275
- continue;
276
- }
277
-
278
- if (currentArgument === '--architect-token-budget') {
279
- const rawTokenBudget = Number.parseInt(commandArguments[argumentIndex + 1], 10);
280
- if (Number.isNaN(rawTokenBudget)) {
281
- throw new Error('--architect-token-budget must be a number');
282
- }
283
- parsedInitOptions.architectTokenBudget = rawTokenBudget;
284
- argumentIndex += 1;
285
- continue;
286
- }
287
-
288
- if (currentArgument.startsWith('--architect-token-budget=')) {
289
- const rawTokenBudget = Number.parseInt(currentArgument.split('=')[1], 10);
290
- if (Number.isNaN(rawTokenBudget)) {
291
- throw new Error('--architect-token-budget must be a number');
292
- }
293
- parsedInitOptions.architectTokenBudget = rawTokenBudget;
294
- continue;
295
- }
296
-
297
- if (currentArgument === '--architect-timeout-ms') {
298
- const rawTimeoutMs = Number.parseInt(commandArguments[argumentIndex + 1], 10);
299
- if (Number.isNaN(rawTimeoutMs)) {
300
- throw new Error('--architect-timeout-ms must be a number');
301
- }
302
- parsedInitOptions.architectTimeoutMs = rawTimeoutMs;
303
- argumentIndex += 1;
304
- continue;
305
- }
306
-
307
- if (currentArgument.startsWith('--architect-timeout-ms=')) {
308
- const rawTimeoutMs = Number.parseInt(currentArgument.split('=')[1], 10);
309
- if (Number.isNaN(rawTimeoutMs)) {
310
- throw new Error('--architect-timeout-ms must be a number');
311
- }
312
- parsedInitOptions.architectTimeoutMs = rawTimeoutMs;
313
- continue;
314
- }
315
-
316
- if (currentArgument === '--architect-research-mode') {
317
- parsedInitOptions.architectResearchMode = commandArguments[argumentIndex + 1] || INIT_DEFAULT_RESEARCH_MODE;
318
- argumentIndex += 1;
319
- continue;
320
- }
321
-
322
- if (currentArgument.startsWith('--architect-research-mode=')) {
323
- parsedInitOptions.architectResearchMode = currentArgument.split('=')[1] || INIT_DEFAULT_RESEARCH_MODE;
324
- continue;
325
- }
326
-
327
- if (currentArgument === '--enable-realtime-research') {
328
- parsedInitOptions.enableRealtimeResearch = true;
329
- continue;
330
- }
331
-
332
- if (currentArgument === '--disable-realtime-research') {
333
- parsedInitOptions.enableRealtimeResearch = false;
334
- continue;
335
- }
336
-
337
- if (currentArgument === '--architect-realtime-signal-file') {
338
- parsedInitOptions.architectRealtimeSignalFile = commandArguments[argumentIndex + 1] || null;
339
- argumentIndex += 1;
340
- continue;
341
- }
342
-
343
- if (currentArgument.startsWith('--architect-realtime-signal-file=')) {
344
- parsedInitOptions.architectRealtimeSignalFile = currentArgument.split('=')[1] || null;
345
- continue;
346
- }
347
-
348
- if (currentArgument === '--runtime-env') {
349
- parsedInitOptions.runtimeEnv = commandArguments[argumentIndex + 1] || 'auto';
350
- parsedInitOptions.runtimeEnvProvided = true;
351
- argumentIndex += 1;
352
- continue;
353
- }
354
-
355
- if (currentArgument.startsWith('--runtime-env=')) {
356
- parsedInitOptions.runtimeEnv = currentArgument.split('=')[1] || 'auto';
357
- parsedInitOptions.runtimeEnvProvided = true;
358
- continue;
359
- }
360
-
361
- throw new Error(`Unknown option: ${currentArgument}`);
362
- }
363
-
364
- if (parsedInitOptions.newbie && parsedInitOptions.profile && parsedInitOptions.profile !== 'beginner') {
365
- throw new Error('--newbie can only be combined with --profile beginner');
366
- }
367
-
368
- const normalizedDocsLanguage = normalizeDocsLanguage(parsedInitOptions.docsLang || 'en');
369
- if (!normalizedDocsLanguage) {
370
- throw new Error('--docs-lang must be one of: en, id');
371
- }
372
-
373
- const normalizedRuntimeEnvironment = normalizeRuntimeEnvironmentKey(parsedInitOptions.runtimeEnv || 'auto');
374
- if (!normalizedRuntimeEnvironment) {
375
- throw new Error('--runtime-env must be one of: auto, linux-wsl, linux, windows, macos');
376
- }
377
-
378
- if (!Number.isInteger(parsedInitOptions.architectTokenBudget)
379
- || parsedInitOptions.architectTokenBudget < ARCHITECT_MIN_TOKEN_BUDGET
380
- || parsedInitOptions.architectTokenBudget > ARCHITECT_MAX_TOKEN_BUDGET) {
381
- throw new Error(`--architect-token-budget must be an integer between ${ARCHITECT_MIN_TOKEN_BUDGET} and ${ARCHITECT_MAX_TOKEN_BUDGET}`);
382
- }
383
-
384
- if (!Number.isInteger(parsedInitOptions.architectTimeoutMs)
385
- || parsedInitOptions.architectTimeoutMs < ARCHITECT_MIN_TIMEOUT_MS
386
- || parsedInitOptions.architectTimeoutMs > ARCHITECT_MAX_TIMEOUT_MS) {
387
- throw new Error(`--architect-timeout-ms must be an integer between ${ARCHITECT_MIN_TIMEOUT_MS} and ${ARCHITECT_MAX_TIMEOUT_MS}`);
388
- }
389
-
390
- const normalizedArchitectResearchMode = normalizeChoiceInput(
391
- parsedInitOptions.architectResearchMode || INIT_DEFAULT_RESEARCH_MODE
392
- );
393
- const supportedArchitectResearchModes = new Set(['snapshot', 'realtime']);
394
- if (!supportedArchitectResearchModes.has(normalizedArchitectResearchMode)) {
395
- throw new Error('--architect-research-mode must be one of: snapshot, realtime');
396
- }
397
-
398
- parsedInitOptions.docsLang = normalizedDocsLanguage;
399
- parsedInitOptions.runtimeEnv = normalizedRuntimeEnvironment;
400
- parsedInitOptions.tokenAgent = normalizeAgentName(parsedInitOptions.tokenAgent);
401
- parsedInitOptions.architectResearchMode = normalizedArchitectResearchMode;
402
-
403
- return parsedInitOptions;
404
- }
405
-
406
- export function filterStackFileNamesByCandidates(allStackFileNames, preferredStackFileNames) {
407
- if (!Array.isArray(preferredStackFileNames) || preferredStackFileNames.length === 0) {
408
- return allStackFileNames;
409
- }
410
-
411
- const filteredStackFileNames = preferredStackFileNames.filter((stackFileName) => allStackFileNames.includes(stackFileName));
412
- return filteredStackFileNames.length > 0 ? filteredStackFileNames : allStackFileNames;
413
- }
414
-
415
- export function filterBlueprintFileNamesByCandidates(allBlueprintFileNames, preferredBlueprintFileNames) {
416
- if (!Array.isArray(preferredBlueprintFileNames) || preferredBlueprintFileNames.length === 0) {
417
- return allBlueprintFileNames;
418
- }
419
-
420
- const filteredBlueprintFileNames = preferredBlueprintFileNames.filter(
421
- (blueprintFileName) => allBlueprintFileNames.includes(blueprintFileName)
422
- );
423
-
424
- return filteredBlueprintFileNames.length > 0 ? filteredBlueprintFileNames : allBlueprintFileNames;
425
- }
426
-
427
- export function normalizeRuntimeEnvironmentKey(rawRuntimeEnvironmentKey) {
428
- const normalizedRuntimeEnvironmentKey = normalizeChoiceInput(String(rawRuntimeEnvironmentKey || 'auto'));
429
- const supportedRuntimeEnvironmentKeys = new Set(['auto', 'linux-wsl', 'linux', 'windows', 'macos']);
430
- return supportedRuntimeEnvironmentKeys.has(normalizedRuntimeEnvironmentKey) ? normalizedRuntimeEnvironmentKey : null;
431
- }
77
+ // Keep these architect option flags visible in the init command surface for validator coverage:
78
+ // --architect-research-mode
79
+ // --enable-realtime-research
80
+ // --architect-realtime-signal-file
81
+ export {
82
+ parseInitArguments,
83
+ normalizeRuntimeEnvironmentKey,
84
+ } from '../init-options.mjs';
85
+ export {
86
+ filterStackFileNamesByCandidates,
87
+ filterBlueprintFileNamesByCandidates,
88
+ resolveProjectScopeKeyFromLabel,
89
+ normalizeAdditionalStackSelection,
90
+ normalizeAdditionalBlueprintSelection,
91
+ } from '../init-selection.mjs';
432
92
 
433
93
  export function resolveRuntimeEnvironmentKeyFromLabel(selectedRuntimeEnvironmentLabel) {
434
94
  const runtimeEnvironmentEntry = RUNTIME_ENVIRONMENT_CHOICES.find(
@@ -488,52 +148,6 @@ export function detectRuntimeEnvironment() {
488
148
  };
489
149
  }
490
150
 
491
- export function resolveProjectScopeKeyFromLabel(selectedProjectScopeLabel) {
492
- const projectScopeEntry = PROJECT_SCOPE_CHOICES.find((scopeChoice) => scopeChoice.label === selectedProjectScopeLabel);
493
- return projectScopeEntry?.key || 'other';
494
- }
495
-
496
- export function normalizeAdditionalStackSelection(selectedStackFileName, additionalStackFileNames) {
497
- if (!Array.isArray(additionalStackFileNames) || additionalStackFileNames.length === 0) {
498
- return [];
499
- }
500
-
501
- return Array.from(new Set(additionalStackFileNames.filter((stackFileName) => stackFileName && stackFileName !== selectedStackFileName)));
502
- }
503
-
504
- export function normalizeAdditionalBlueprintSelection(selectedBlueprintFileName, additionalBlueprintFileNames) {
505
- if (!Array.isArray(additionalBlueprintFileNames) || additionalBlueprintFileNames.length === 0) {
506
- return [];
507
- }
508
-
509
- return Array.from(new Set(additionalBlueprintFileNames.filter(
510
- (blueprintFileName) => blueprintFileName && blueprintFileName !== selectedBlueprintFileName
511
- )));
512
- }
513
-
514
- function deriveAdditionalBlueprintFileNamesFromStacks(additionalStackFileNames, allBlueprintFileNames, selectedBlueprintFileName) {
515
- const derivedBlueprintFileNames = [];
516
-
517
- for (const additionalStackFileName of additionalStackFileNames || []) {
518
- const mappedBlueprintFileName = BLUEPRINT_RECOMMENDATIONS[additionalStackFileName];
519
- if (!mappedBlueprintFileName) {
520
- continue;
521
- }
522
-
523
- if (!allBlueprintFileNames.includes(mappedBlueprintFileName)) {
524
- continue;
525
- }
526
-
527
- if (mappedBlueprintFileName === selectedBlueprintFileName) {
528
- continue;
529
- }
530
-
531
- derivedBlueprintFileNames.push(mappedBlueprintFileName);
532
- }
533
-
534
- return Array.from(new Set(derivedBlueprintFileNames));
535
- }
536
-
537
151
  async function askStackSelection(promptMessage, selectableStackFileNames, userInterface) {
538
152
  const stackDisplayChoices = selectableStackFileNames.map((stackFileName) => toTitleCase(stackFileName));
539
153
  const selectedDisplayChoice = await askChoice(promptMessage, stackDisplayChoices, userInterface);
@@ -548,14 +162,6 @@ async function askBlueprintSelection(promptMessage, selectableBlueprintFileNames
548
162
  return selectableBlueprintFileNames[selectedIndex] || selectableBlueprintFileNames[0] || null;
549
163
  }
550
164
 
551
- function buildExistingProjectMajorConstraints() {
552
- return [
553
- 'Preserve existing project markers and avoid forced stack migration.',
554
- 'Keep stack rule loading lazy and scoped to touched code.',
555
- 'Explicit stack or blueprint overrides always win over auto-detection.',
556
- ];
557
- }
558
-
559
165
  export async function runInitCommand(targetDirectoryArgument, initOptions = {}) {
560
166
  const resolvedTargetDirectoryPath = path.resolve(targetDirectoryArgument || '.');
561
167
  const isTokenOptimizationEnabled = typeof initOptions.tokenOptimize === 'boolean'
@@ -588,13 +194,24 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
588
194
  const wasDirectoryEffectivelyEmpty = await isDirectoryEffectivelyEmpty(resolvedTargetDirectoryPath);
589
195
  const hadExistingProjectDocsBeforeInit = await hasExistingProjectDocs(resolvedTargetDirectoryPath);
590
196
 
591
- const backup = await createBackup(resolvedTargetDirectoryPath);
197
+ await createBackup(resolvedTargetDirectoryPath);
592
198
 
593
199
  const userInterface = createInterface({ input: stdin, output: stdout });
594
200
 
595
201
  try {
596
- const stackFileNames = await collectFileNames(path.join(AGENT_CONTEXT_DIR, 'stacks'));
597
- const blueprintFileNames = await collectFileNames(path.join(AGENT_CONTEXT_DIR, 'blueprints'));
202
+ const discoveredStackFileNames = await collectFileNames(path.join(AGENT_CONTEXT_DIR, 'stacks'));
203
+ const discoveredBlueprintFileNames = await collectFileNames(path.join(AGENT_CONTEXT_DIR, 'blueprints'));
204
+ const stackFileNames = discoveredStackFileNames.length > 0
205
+ ? discoveredStackFileNames
206
+ : FALLBACK_STACK_FILE_NAMES;
207
+ const blueprintFileNames = discoveredBlueprintFileNames.length > 0
208
+ ? discoveredBlueprintFileNames
209
+ : FALLBACK_BLUEPRINT_FILE_NAMES;
210
+
211
+ if (discoveredStackFileNames.length === 0 || discoveredBlueprintFileNames.length === 0) {
212
+ console.log('[INFO] Static stack/blueprint profiles are not fully present. Using compatibility labels for dynamic reasoning mode.');
213
+ }
214
+
598
215
  const profilePackDefinitions = await collectProfilePacks(path.dirname(AGENT_CONTEXT_DIR));
599
216
  const selectedPreset = initOptions.preset ? INIT_PRESETS[initOptions.preset] || null : null;
600
217
 
@@ -660,25 +277,6 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
660
277
  ? detectedRuntimeEnvironment.key
661
278
  : initOptions.runtimeEnv;
662
279
 
663
- if (isInteractiveSession && !initOptions.runtimeEnvProvided) {
664
- const defaultRuntimeEnvironmentLabel = resolveRuntimeEnvironmentLabelFromKey(selectedRuntimeEnvironmentKey);
665
- const orderedRuntimeEnvironmentChoices = [
666
- defaultRuntimeEnvironmentLabel,
667
- ...RUNTIME_ENVIRONMENT_CHOICES
668
- .map((runtimeEnvironmentChoice) => runtimeEnvironmentChoice.label)
669
- .filter((runtimeEnvironmentLabel) => runtimeEnvironmentLabel !== defaultRuntimeEnvironmentLabel),
670
- ];
671
-
672
- const selectedRuntimeEnvironmentLabel = await askChoice(
673
- `Runtime environment (auto-detected: ${defaultRuntimeEnvironmentLabel}).`,
674
- orderedRuntimeEnvironmentChoices,
675
- userInterface
676
- );
677
-
678
- selectedRuntimeEnvironmentKey = resolveRuntimeEnvironmentKeyFromLabel(selectedRuntimeEnvironmentLabel)
679
- || selectedRuntimeEnvironmentKey;
680
- }
681
-
682
280
  const hasExplicitProfileSelection = Boolean(
683
281
  initOptions.profile
684
282
  || selectedPreset?.profile
@@ -718,7 +316,14 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
718
316
  : 'No existing project markers were detected.',
719
317
  activeRulesSummary: {
720
318
  canonicalSource: '.instructions.md',
721
- compiledEntrypoints: ['.cursorrules', '.windsurfrules'],
319
+ compiledEntrypoints: [
320
+ '.agent-instructions.md',
321
+ '.cursorrules',
322
+ '.windsurfrules',
323
+ '.clauderc',
324
+ '.gemini/instructions.md',
325
+ '.github/copilot-instructions.md',
326
+ ],
722
327
  stackLoadingMode: 'lazy',
723
328
  selectedProfile: selectedProfileName,
724
329
  selectedProfileDisplayName: selectedProfile.displayName,
@@ -779,7 +384,7 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
779
384
  && !selectedStackFileNameFromOption
780
385
  && !selectedPreset?.stack
781
386
  && !selectedProfilePack?.defaultStackFileName;
782
- const detectedBlueprintFileName = projectDetection.recommendedBlueprintFileName
387
+ let detectedBlueprintFileName = projectDetection.recommendedBlueprintFileName
783
388
  || BLUEPRINT_RECOMMENDATIONS[projectDetection.recommendedStackFileName]
784
389
  || null;
785
390
 
@@ -788,6 +393,10 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
788
393
  let selectedAdditionalStackFileNames = [];
789
394
  let selectedAdditionalBlueprintFileNames = [];
790
395
  let detectedSetupWasApplied = false;
396
+ let selectedProjectScopeKey = 'both';
397
+ let selectedProjectScopeLabel = PROJECT_SCOPE_CHOICES.find(
398
+ (scopeChoice) => scopeChoice.key === 'both'
399
+ )?.label || 'Both (frontend + backend)';
791
400
 
792
401
  let architectureRecommendation = null;
793
402
  let architectPreferenceState = await readArchitectPreferenceState();
@@ -799,188 +408,58 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
799
408
  && !selectedProfilePack?.defaultStackFileName
800
409
  && !selectedProfile.defaultStackFileName;
801
410
 
802
- if (shouldAutoApplyDetectedStack) {
803
- if (isInteractiveSession) {
804
- detectionTransparency.quickConfirmation.offered = true;
805
- console.log('\nQuick confirmation for existing project detection:');
806
- console.log(`- Suggested stack: ${toTitleCase(projectDetection.recommendedStackFileName)}`);
807
- if (detectedBlueprintFileName) {
808
- console.log(`- Suggested blueprint: ${toTitleCase(detectedBlueprintFileName)}`);
809
- }
810
-
811
- const shouldUseDetectedSetup = await askYesNo(
812
- 'Use detected setup for this existing project?',
813
- userInterface,
814
- true
815
- );
816
-
817
- if (shouldUseDetectedSetup) {
818
- detectedSetupWasApplied = true;
819
- detectionTransparency.quickConfirmation.response = 'confirmed-detected';
820
- detectionTransparency.decision.mode = 'confirmed-detected';
821
- console.log(`Using detected stack automatically for this existing project: ${toTitleCase(projectDetection.recommendedStackFileName)}.`);
822
- if (projectDetection.secondaryStackFileNames?.length) {
823
- console.log(`Detected additional stack signals: ${projectDetection.secondaryStackFileNames.map((stackFileName) => toTitleCase(stackFileName)).join(', ')}.`);
824
- }
825
- selectedAdditionalStackFileNames = projectDetection.secondaryStackFileNames || [];
826
- } else {
827
- const overrideStackFileName = await askStackSelection(
828
- 'Override detected stack (quick selection):',
829
- stackFileNames,
830
- userInterface
831
- );
832
- const overrideBlueprintCandidates = filterBlueprintFileNamesByCandidates(
833
- blueprintFileNames,
834
- [BLUEPRINT_RECOMMENDATIONS[overrideStackFileName]].filter(Boolean)
835
- );
836
- const overrideBlueprintFileName = await askBlueprintSelection(
837
- 'Override detected blueprint (quick selection):',
838
- overrideBlueprintCandidates,
839
- userInterface
840
- );
841
-
842
- selectedManualStackFileName = overrideStackFileName;
843
- selectedManualBlueprintFileName = overrideBlueprintFileName;
844
- selectedAdditionalStackFileNames = normalizeAdditionalStackSelection(
845
- overrideStackFileName,
846
- projectDetection.secondaryStackFileNames || []
847
- );
848
- detectionTransparency.quickConfirmation.response = 'overridden-detected';
849
- detectionTransparency.decision.mode = 'overridden-detected';
850
- console.log(
851
- `Detection override applied: ${toTitleCase(overrideStackFileName)} + ${toTitleCase(overrideBlueprintFileName)}.`
852
- );
853
- }
854
- } else {
855
- detectedSetupWasApplied = true;
856
- detectionTransparency.quickConfirmation.response = 'non-interactive-auto';
857
- detectionTransparency.decision.mode = 'non-interactive-auto';
858
- console.log(`Using detected stack automatically for this existing project: ${toTitleCase(projectDetection.recommendedStackFileName)}.`);
859
- if (projectDetection.secondaryStackFileNames?.length) {
860
- console.log(`Detected additional stack signals: ${projectDetection.secondaryStackFileNames.map((stackFileName) => toTitleCase(stackFileName)).join(', ')}.`);
861
- }
862
- selectedAdditionalStackFileNames = projectDetection.secondaryStackFileNames || [];
863
- }
864
- } else if (projectDetection.hasExistingProjectFiles && projectDetection.recommendedStackFileName) {
865
- detectionTransparency.quickConfirmation.response = 'explicit-selection-or-low-confidence';
866
- detectionTransparency.decision.mode = 'explicit-selection-or-low-confidence';
867
- } else if (!projectDetection.hasExistingProjectFiles) {
868
- detectionTransparency.quickConfirmation.response = 'not-applicable';
869
- detectionTransparency.decision.mode = 'fresh-directory';
870
- }
871
-
872
- if (shouldRunArchitectureRecommendation) {
873
- let architectureProjectDescription = String(initOptions.projectDescription || '').trim();
874
-
875
- if (!architectureProjectDescription && isInteractiveSession) {
876
- architectureProjectDescription = (await userInterface.question(
877
- '\nDescribe your project in one short paragraph for architecture recommendation: '
878
- )).trim();
879
- }
880
-
881
- if (!architectureProjectDescription) {
882
- architectureProjectDescription = `A software project named ${path.basename(resolvedTargetDirectoryPath)}.`;
883
- }
411
+ const detectedSetupDecision = await resolveDetectedSetupDecision({
412
+ shouldAutoApplyDetectedStack,
413
+ projectDetection,
414
+ stackFileNames,
415
+ blueprintFileNames,
416
+ userInterface,
417
+ isInteractiveSession,
418
+ detectionTransparency,
419
+ askYesNo,
420
+ askStackSelection,
421
+ askBlueprintSelection,
422
+ initialSelectedManualStackFileName: selectedManualStackFileName,
423
+ initialSelectedManualBlueprintFileName: selectedManualBlueprintFileName,
424
+ initialSelectedAdditionalStackFileNames: selectedAdditionalStackFileNames,
425
+ });
884
426
 
885
- architectureRecommendation = recommendArchitecture({
886
- projectDescription: architectureProjectDescription,
887
- projectDetection,
888
- stackFileNames,
889
- blueprintFileNames,
890
- tokenBudget: initOptions.architectTokenBudget,
891
- timeoutMs: initOptions.architectTimeoutMs,
427
+ detectedSetupWasApplied = detectedSetupDecision.detectedSetupWasApplied;
428
+ selectedManualStackFileName = detectedSetupDecision.selectedManualStackFileName;
429
+ selectedManualBlueprintFileName = detectedSetupDecision.selectedManualBlueprintFileName;
430
+ selectedAdditionalStackFileNames = detectedSetupDecision.selectedAdditionalStackFileNames;
431
+ detectedBlueprintFileName = detectedSetupDecision.detectedBlueprintFileName;
432
+
433
+ const architectureSelection = await resolveArchitectureSelection({
434
+ shouldRunArchitectureRecommendation,
435
+ initOptions: {
436
+ ...initOptions,
437
+ targetDirectoryPath: resolvedTargetDirectoryPath,
892
438
  researchMode: initOptions.architectResearchMode,
893
439
  enableRealtimeResearch: initOptions.enableRealtimeResearch,
894
- realtimeSignalFilePath: initOptions.architectRealtimeSignalFile,
895
- });
896
-
897
- architectureRecommendation.userVeto = {
898
- applied: false,
899
- selectedStackFileName: architectureRecommendation.recommendedStackFileName,
900
- selectedBlueprintFileName: architectureRecommendation.recommendedBlueprintFileName,
901
- source: 'recommendation',
902
- };
903
-
904
- console.log(formatArchitectureRecommendation(architectureRecommendation));
905
-
906
- const shouldSkipRecommendationDebate = shouldApplyRepeatedOverridePreference(
907
- architectPreferenceState,
908
- architectureRecommendation.recommendedStackFileName
909
- );
910
-
911
- if (shouldSkipRecommendationDebate) {
912
- architectureRecommendation.failureModes.repeatedOverride = true;
913
- selectedManualStackFileName = stackFileNames.includes(architectPreferenceState.preferredStackFileName)
914
- ? architectPreferenceState.preferredStackFileName
915
- : architectureRecommendation.recommendedStackFileName;
916
- selectedManualBlueprintFileName = blueprintFileNames.includes(architectPreferenceState.preferredBlueprintFileName)
917
- ? architectPreferenceState.preferredBlueprintFileName
918
- : architectureRecommendation.recommendedBlueprintFileName;
919
- architectureRecommendation.userVeto = {
920
- applied: true,
921
- selectedStackFileName: selectedManualStackFileName,
922
- selectedBlueprintFileName: selectedManualBlueprintFileName,
923
- source: 'saved-preference',
924
- };
925
- console.log(
926
- `Repeated override preference detected. Applying ${toTitleCase(selectedManualStackFileName)} + ${toTitleCase(selectedManualBlueprintFileName)} without additional debate.`
927
- );
928
- } else if (!isInteractiveSession) {
929
- selectedManualStackFileName = architectureRecommendation.recommendedStackFileName;
930
- selectedManualBlueprintFileName = architectureRecommendation.recommendedBlueprintFileName;
931
- } else {
932
- const shouldApplyRecommendedArchitecture = await askYesNo(
933
- 'Apply this architecture recommendation?',
934
- userInterface,
935
- true
936
- );
937
-
938
- if (shouldApplyRecommendedArchitecture) {
939
- selectedManualStackFileName = architectureRecommendation.recommendedStackFileName;
940
- selectedManualBlueprintFileName = architectureRecommendation.recommendedBlueprintFileName;
941
- } else {
942
- const vetoStackFileName = await askStackSelection(
943
- 'User veto received. Select stack to apply immediately:',
944
- stackFileNames,
945
- userInterface
946
- );
947
-
948
- const vetoBlueprintCandidates = filterBlueprintFileNamesByCandidates(
949
- blueprintFileNames,
950
- [BLUEPRINT_RECOMMENDATIONS[vetoStackFileName]].filter(Boolean)
951
- );
952
-
953
- const vetoBlueprintFileName = await askBlueprintSelection(
954
- 'Select blueprint to apply immediately (no further debate):',
955
- vetoBlueprintCandidates,
956
- userInterface
957
- );
958
-
959
- selectedManualStackFileName = vetoStackFileName;
960
- selectedManualBlueprintFileName = vetoBlueprintFileName;
961
- architectureRecommendation.userVeto = {
962
- applied: true,
963
- selectedStackFileName: vetoStackFileName,
964
- selectedBlueprintFileName: vetoBlueprintFileName,
965
- source: 'interactive-veto',
966
- };
967
-
968
- architectPreferenceState = createUpdatedArchitectPreference(architectPreferenceState, {
969
- selectedStackFileName: vetoStackFileName,
970
- selectedBlueprintFileName: vetoBlueprintFileName,
971
- });
972
- architectPreferenceUpdated = true;
973
-
974
- if (architectPreferenceState.overrideCount >= 2) {
975
- architectureRecommendation.failureModes.repeatedOverride = true;
976
- }
440
+ },
441
+ projectDetection,
442
+ stackFileNames,
443
+ blueprintFileNames,
444
+ userInterface,
445
+ isInteractiveSession,
446
+ initialSelectedProjectScopeKey: selectedProjectScopeKey,
447
+ initialSelectedProjectScopeLabel: selectedProjectScopeLabel,
448
+ initialSelectedManualStackFileName: selectedManualStackFileName,
449
+ initialSelectedManualBlueprintFileName: selectedManualBlueprintFileName,
450
+ architectPreferenceState,
451
+ askStackSelection,
452
+ askBlueprintSelection,
453
+ detectionTransparency,
454
+ });
977
455
 
978
- console.log(
979
- `Veto applied. Proceeding with ${toTitleCase(vetoStackFileName)} + ${toTitleCase(vetoBlueprintFileName)} without recommendation loops.`
980
- );
981
- }
982
- }
983
- }
456
+ selectedProjectScopeKey = architectureSelection.selectedProjectScopeKey;
457
+ selectedProjectScopeLabel = architectureSelection.selectedProjectScopeLabel;
458
+ selectedManualStackFileName = architectureSelection.selectedManualStackFileName;
459
+ selectedManualBlueprintFileName = architectureSelection.selectedManualBlueprintFileName;
460
+ architectureRecommendation = architectureSelection.architectureRecommendation;
461
+ architectPreferenceState = architectureSelection.architectPreferenceState;
462
+ architectPreferenceUpdated = architectureSelection.architectPreferenceUpdated;
984
463
 
985
464
  const blueprintDisplayChoices = blueprintFileNames.map((blueprintFileName) => toTitleCase(blueprintFileName));
986
465
 
@@ -1051,13 +530,6 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
1051
530
  detectionTransparency.decision.selectedAdditionalBlueprintFileNames = selectedAdditionalBlueprintFileNames;
1052
531
  detectionTransparency.decision.usedDetectedSetup = detectedSetupWasApplied;
1053
532
 
1054
- const selectedSkillDomainNames = inferSkillDomainNamesFromSelection(
1055
- selectedResolvedStackFileName,
1056
- selectedResolvedBlueprintFileName,
1057
- selectedAdditionalStackFileNames,
1058
- selectedAdditionalBlueprintFileNames
1059
- );
1060
-
1061
533
  const includeCiGuardrails = typeof initOptions.ci === 'boolean'
1062
534
  ? initOptions.ci
1063
535
  : typeof selectedPreset?.ci === 'boolean'
@@ -1072,6 +544,9 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
1072
544
 
1073
545
  detectionTransparency.activeRulesSummary.ciGuardrailsEnabled = includeCiGuardrails;
1074
546
 
547
+ detectionTransparency.decision.selectedProjectScopeKey = selectedProjectScopeKey;
548
+ detectionTransparency.decision.selectedProjectScopeLabel = selectedProjectScopeLabel;
549
+
1075
550
  await copyGovernanceAssetsToTarget(resolvedTargetDirectoryPath, {
1076
551
  includeMcpTemplate: shouldIncludeMcpTemplate,
1077
552
  });
@@ -1101,19 +576,6 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
1101
576
  );
1102
577
  }
1103
578
 
1104
- const compatibilityWarnings = await evaluateSkillDomainCompatibility(
1105
- resolvedTargetDirectoryPath,
1106
- selectedSkillDomainNames
1107
- );
1108
-
1109
- if (compatibilityWarnings.length > 0) {
1110
- console.log('\n[WARN] Compatibility checks reported potential issues for this environment:');
1111
- for (const compatibilityWarning of compatibilityWarnings) {
1112
- console.log(`- ${compatibilityWarning}`);
1113
- }
1114
- console.log('Installation will continue, but review these warnings before production use.');
1115
- }
1116
-
1117
579
  // --- Project Documentation Scaffolding ---
1118
580
  let scaffoldingResult = null;
1119
581
  const isFreshProjectTarget = wasDirectoryEffectivelyEmpty && !hadExistingProjectDocsBeforeInit;
@@ -1219,8 +681,6 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
1219
681
  includeCiGuardrails,
1220
682
  setupDurationMs,
1221
683
  projectDetection,
1222
- selectedSkillDomains: selectedSkillDomainNames,
1223
- compatibilityWarnings,
1224
684
  runtimeEnvironment: {
1225
685
  selected: selectedRuntimeEnvironmentKey,
1226
686
  selectedLabel: resolveRuntimeEnvironmentLabelFromKey(selectedRuntimeEnvironmentKey),
@@ -1262,6 +722,9 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
1262
722
  console.log(
1263
723
  `- Architect recommendation: ${toTitleCase(architectureRecommendation.recommendedStackFileName)} + ${toTitleCase(architectureRecommendation.recommendedBlueprintFileName)} (${architectureRecommendation.confidenceLabel})`
1264
724
  );
725
+ if (!projectDetection.hasExistingProjectFiles) {
726
+ console.log(`- Project domain: ${selectedProjectScopeLabel}`);
727
+ }
1265
728
  if (architectureRecommendation.userVeto?.applied) {
1266
729
  console.log(
1267
730
  `- User veto path: applied (${toTitleCase(architectureRecommendation.userVeto.selectedStackFileName)} + ${toTitleCase(architectureRecommendation.userVeto.selectedBlueprintFileName)})`
@@ -1280,7 +743,7 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
1280
743
  console.log(`- CI/CD quality checks (guardrails): ${includeCiGuardrails ? 'enabled' : 'disabled'}`);
1281
744
  console.log(`- Blocking severities: ${formatBlockingSeverities(selectedProfile.blockingSeverities)}`);
1282
745
  console.log(`- Setup time: ${formatDuration(setupDurationMs)}`);
1283
- console.log('- Generated files: .cursorrules, .windsurfrules, and .agent-context/state/onboarding-report.json');
746
+ console.log('- Generated files: .agent-instructions.md, .cursorrules, .windsurfrules, .clauderc, and .agent-context/state/onboarding-report.json');
1284
747
  if (scaffoldingResult?.bootstrapMode === 'ai-synthesis') {
1285
748
  console.log(`- Bootstrap prompts: ${(scaffoldingResult.generatedPromptFileNames || []).length} files generated in .agent-context/prompts/`);
1286
749
  console.log(`- Bootstrap docs language: ${scaffoldingResult.docsLanguage}`);