@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.
- package/.agent-context/prompts/init-project.md +5 -5
- package/.agent-context/prompts/refactor.md +2 -1
- package/.agent-context/prompts/review-code.md +3 -2
- package/.agent-context/review-checklists/pr-checklist.md +8 -1
- package/.agent-context/rules/architecture.md +11 -0
- package/.agent-context/rules/frontend-architecture.md +2 -2
- package/.agent-context/state/architecture-map.md +1 -1
- package/.agent-context/state/memory-continuity-benchmark.json +1 -1
- package/.agents/workflows/init-project.md +3 -3
- package/.agents/workflows/refactor.md +1 -1
- package/.agents/workflows/review-code.md +4 -5
- package/.cursorrules +27 -71
- package/.gemini/instructions.md +6 -7
- package/.github/copilot-instructions.md +5 -6
- package/.windsurfrules +27 -71
- package/AGENTS.md +7 -9
- package/CONTRIBUTING.md +18 -31
- package/README.md +21 -4
- package/bin/agentic-senior-core.js +0 -6
- package/lib/cli/commands/init.mjs +113 -650
- package/lib/cli/commands/launch.mjs +1 -23
- package/lib/cli/commands/rollback.mjs +1 -1
- package/lib/cli/commands/upgrade.mjs +1 -23
- package/lib/cli/compiler.mjs +77 -72
- package/lib/cli/constants.mjs +84 -26
- package/lib/cli/init-architecture-flow.mjs +231 -0
- package/lib/cli/init-detection-flow.mjs +123 -0
- package/lib/cli/init-options.mjs +344 -0
- package/lib/cli/init-selection.mjs +100 -0
- package/lib/cli/preflight.mjs +1 -1
- package/lib/cli/profile-packs.mjs +15 -1
- package/lib/cli/project-scaffolder.mjs +18 -154
- package/lib/cli/utils.mjs +16 -12
- package/mcp.json +19 -19
- package/package.json +5 -2
- package/scripts/context-triggered-audit.mjs +18 -18
- package/scripts/documentation-boundary-audit.mjs +92 -5
- package/scripts/forbidden-content-check.mjs +1 -1
- package/scripts/frontend-usability-audit.mjs +21 -28
- package/scripts/governance-weekly-report.mjs +29 -15
- package/scripts/llm-judge.mjs +2 -5
- package/scripts/mcp-server.mjs +389 -5
- package/scripts/release-gate.mjs +121 -145
- package/scripts/sync-thin-adapters.mjs +161 -0
- package/scripts/v3-purge-audit.mjs +231 -0
- package/scripts/validate-evidence-bundle.mjs +1 -1
- package/scripts/validate.mjs +224 -272
- package/.agent-context/blueprints/api-nextjs.md +0 -184
- package/.agent-context/blueprints/aspnet-api.md +0 -247
- package/.agent-context/blueprints/ci-github-actions.md +0 -226
- package/.agent-context/blueprints/ci-gitlab.md +0 -200
- package/.agent-context/blueprints/fastapi-service.md +0 -210
- package/.agent-context/blueprints/go-service.md +0 -217
- package/.agent-context/blueprints/graphql-grpc-api.md +0 -51
- package/.agent-context/blueprints/infrastructure-as-code.md +0 -62
- package/.agent-context/blueprints/kubernetes-manifests.md +0 -76
- package/.agent-context/blueprints/laravel-api.md +0 -233
- package/.agent-context/blueprints/mobile-app.md +0 -91
- package/.agent-context/blueprints/nestjs-logic.md +0 -247
- package/.agent-context/blueprints/observability.md +0 -227
- package/.agent-context/blueprints/spring-boot-api.md +0 -218
- package/.agent-context/profiles/platform.md +0 -13
- package/.agent-context/profiles/regulated.md +0 -13
- package/.agent-context/profiles/startup.md +0 -13
- package/.agent-context/review-checklists/frontend-excellence-rubric.md +0 -73
- package/.agent-context/review-checklists/frontend-skill-parity.md +0 -29
- package/.agent-context/review-checklists/frontend-usability.md +0 -35
- package/.agent-context/review-checklists/marketplace-acceptance.md +0 -60
- package/.agent-context/review-checklists/performance-audit.md +0 -71
- package/.agent-context/review-checklists/release-operations.md +0 -33
- package/.agent-context/review-checklists/security-audit.md +0 -119
- package/.agent-context/skills/README.md +0 -63
- package/.agent-context/skills/backend/README.md +0 -68
- package/.agent-context/skills/backend/architecture.md +0 -361
- package/.agent-context/skills/backend/compatibility-manifest.json +0 -8
- package/.agent-context/skills/backend/data-access.md +0 -231
- package/.agent-context/skills/backend/errors.md +0 -138
- package/.agent-context/skills/backend/validation.md +0 -117
- package/.agent-context/skills/backend.md +0 -29
- package/.agent-context/skills/cli/.evidence/compatibility-manifest.json +0 -5
- package/.agent-context/skills/cli/.evidence/sbom-excerpt.json +0 -10
- package/.agent-context/skills/cli/.evidence/test-report.json +0 -8
- package/.agent-context/skills/cli/CHANGELOG.md +0 -6
- package/.agent-context/skills/cli/README.md +0 -56
- package/.agent-context/skills/cli/compatibility-manifest.json +0 -8
- package/.agent-context/skills/cli/init.md +0 -38
- package/.agent-context/skills/cli/output.md +0 -36
- package/.agent-context/skills/cli/package.json +0 -5
- package/.agent-context/skills/cli/safety-telemetry.md +0 -39
- package/.agent-context/skills/cli/tests/.gitkeep +0 -1
- package/.agent-context/skills/cli/upgrade.md +0 -38
- package/.agent-context/skills/cli.md +0 -32
- package/.agent-context/skills/distribution/.evidence/compatibility-manifest.json +0 -9
- package/.agent-context/skills/distribution/.evidence/sbom-excerpt.json +0 -6
- package/.agent-context/skills/distribution/.evidence/test-report.json +0 -8
- package/.agent-context/skills/distribution/CHANGELOG.md +0 -7
- package/.agent-context/skills/distribution/README.md +0 -27
- package/.agent-context/skills/distribution/compatibility-manifest.json +0 -8
- package/.agent-context/skills/distribution/compatibility.md +0 -32
- package/.agent-context/skills/distribution/package.json +0 -5
- package/.agent-context/skills/distribution/provenance-attestation.md +0 -47
- package/.agent-context/skills/distribution/publish.md +0 -37
- package/.agent-context/skills/distribution/rollback.md +0 -32
- package/.agent-context/skills/distribution/tests/.gitkeep +0 -1
- package/.agent-context/skills/distribution.md +0 -32
- package/.agent-context/skills/frontend/.evidence/compatibility-manifest.json +0 -9
- package/.agent-context/skills/frontend/.evidence/sbom-excerpt.json +0 -6
- package/.agent-context/skills/frontend/.evidence/test-report.json +0 -8
- package/.agent-context/skills/frontend/CHANGELOG.md +0 -7
- package/.agent-context/skills/frontend/README.md +0 -50
- package/.agent-context/skills/frontend/accessibility.md +0 -107
- package/.agent-context/skills/frontend/compatibility-manifest.json +0 -8
- package/.agent-context/skills/frontend/conversion-clarity.md +0 -51
- package/.agent-context/skills/frontend/motion.md +0 -67
- package/.agent-context/skills/frontend/package.json +0 -5
- package/.agent-context/skills/frontend/performance.md +0 -63
- package/.agent-context/skills/frontend/responsive-delivery.md +0 -41
- package/.agent-context/skills/frontend/tests/.gitkeep +0 -1
- package/.agent-context/skills/frontend/ui-architecture.md +0 -128
- package/.agent-context/skills/frontend.md +0 -40
- package/.agent-context/skills/fullstack/.evidence/compatibility-manifest.json +0 -9
- package/.agent-context/skills/fullstack/.evidence/sbom-excerpt.json +0 -6
- package/.agent-context/skills/fullstack/.evidence/test-report.json +0 -8
- package/.agent-context/skills/fullstack/CHANGELOG.md +0 -7
- package/.agent-context/skills/fullstack/README.md +0 -27
- package/.agent-context/skills/fullstack/compatibility-manifest.json +0 -8
- package/.agent-context/skills/fullstack/contracts.md +0 -53
- package/.agent-context/skills/fullstack/end-to-end.md +0 -42
- package/.agent-context/skills/fullstack/feature-slicing.md +0 -65
- package/.agent-context/skills/fullstack/package.json +0 -5
- package/.agent-context/skills/fullstack/release-coordination.md +0 -51
- package/.agent-context/skills/fullstack/tests/.gitkeep +0 -1
- package/.agent-context/skills/fullstack.md +0 -30
- package/.agent-context/skills/index.json +0 -107
- package/.agent-context/skills/review-quality/.evidence/compatibility-manifest.json +0 -9
- package/.agent-context/skills/review-quality/.evidence/sbom-excerpt.json +0 -6
- package/.agent-context/skills/review-quality/.evidence/test-report.json +0 -8
- package/.agent-context/skills/review-quality/CHANGELOG.md +0 -7
- package/.agent-context/skills/review-quality/README.md +0 -27
- package/.agent-context/skills/review-quality/benchmark.md +0 -30
- package/.agent-context/skills/review-quality/compatibility-manifest.json +0 -8
- package/.agent-context/skills/review-quality/package.json +0 -5
- package/.agent-context/skills/review-quality/planning.md +0 -38
- package/.agent-context/skills/review-quality/release-decision.md +0 -49
- package/.agent-context/skills/review-quality/security.md +0 -34
- package/.agent-context/skills/review-quality/tests/.gitkeep +0 -1
- package/.agent-context/skills/review-quality.md +0 -34
- package/.agent-context/stacks/csharp.md +0 -149
- package/.agent-context/stacks/flutter.md +0 -16
- package/.agent-context/stacks/go.md +0 -181
- package/.agent-context/stacks/java.md +0 -135
- package/.agent-context/stacks/php.md +0 -192
- package/.agent-context/stacks/python.md +0 -153
- package/.agent-context/stacks/react-native.md +0 -16
- package/.agent-context/stacks/ruby.md +0 -80
- package/.agent-context/stacks/rust.md +0 -86
- package/.agent-context/stacks/typescript.md +0 -317
- package/.agent-context/state/skill-platform.json +0 -38
- package/lib/cli/skill-selector.mjs +0 -232
- package/lib/cli/templates/api-contract.md.id.tmpl +0 -143
- package/lib/cli/templates/api-contract.md.tmpl +0 -143
- package/lib/cli/templates/architecture-decision-record.md.id.tmpl +0 -106
- package/lib/cli/templates/architecture-decision-record.md.tmpl +0 -145
- package/lib/cli/templates/database-schema.md.id.tmpl +0 -74
- package/lib/cli/templates/database-schema.md.tmpl +0 -74
- package/lib/cli/templates/flow-overview.md.id.tmpl +0 -118
- package/lib/cli/templates/flow-overview.md.tmpl +0 -131
- package/lib/cli/templates/project-brief.md.id.tmpl +0 -55
- package/lib/cli/templates/project-brief.md.tmpl +0 -79
- package/scripts/init-project.ps1 +0 -105
- package/scripts/init-project.sh +0 -131
- package/scripts/skill-tier-policy.mjs +0 -76
- 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,
|
|
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
|
-
|
|
18
|
-
|
|
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
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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
|
-
|
|
197
|
+
await createBackup(resolvedTargetDirectoryPath);
|
|
592
198
|
|
|
593
199
|
const userInterface = createInterface({ input: stdin, output: stdout });
|
|
594
200
|
|
|
595
201
|
try {
|
|
596
|
-
const
|
|
597
|
-
const
|
|
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: [
|
|
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
|
-
|
|
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
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
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
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
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
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
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
|
-
|
|
979
|
-
|
|
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}`);
|