@ryuenn3123/agentic-senior-core 2.5.21 → 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 +28 -4
- package/bin/agentic-senior-core.js +0 -6
- package/lib/cli/commands/init.mjs +142 -655
- 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 +116 -70
- 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 +209 -161
- package/lib/cli/utils.mjs +17 -13
- 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;
|
|
@@ -1171,15 +633,24 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
|
|
|
1171
633
|
additionalBlueprintFileNames: selectedAdditionalBlueprintFileNames,
|
|
1172
634
|
runtimeEnvironmentKey: selectedRuntimeEnvironmentKey,
|
|
1173
635
|
runtimeEnvironmentLabel: resolveRuntimeEnvironmentLabelFromKey(selectedRuntimeEnvironmentKey),
|
|
636
|
+
architectureRecommendation,
|
|
1174
637
|
},
|
|
1175
638
|
{
|
|
1176
639
|
docsLanguage: selectedDocsLanguage,
|
|
1177
640
|
}
|
|
1178
641
|
);
|
|
1179
642
|
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
643
|
+
if (scaffoldingResult.bootstrapMode === 'ai-synthesis') {
|
|
644
|
+
console.log(`\nAI synthesis bootstrap prompts generated in .agent-context/prompts/:`);
|
|
645
|
+
for (const generatedPromptFileName of scaffoldingResult.generatedPromptFileNames || []) {
|
|
646
|
+
console.log(` - .agent-context/prompts/${generatedPromptFileName}`);
|
|
647
|
+
}
|
|
648
|
+
console.log('Project docs will be authored dynamically by your IDE assistant from these prompts.');
|
|
649
|
+
} else {
|
|
650
|
+
console.log(`\nProject documentation generated in docs/:`);
|
|
651
|
+
for (const generatedFileName of scaffoldingResult.generatedFileNames) {
|
|
652
|
+
console.log(` - docs/${generatedFileName}`);
|
|
653
|
+
}
|
|
1183
654
|
}
|
|
1184
655
|
}
|
|
1185
656
|
}
|
|
@@ -1210,8 +681,6 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
|
|
|
1210
681
|
includeCiGuardrails,
|
|
1211
682
|
setupDurationMs,
|
|
1212
683
|
projectDetection,
|
|
1213
|
-
selectedSkillDomains: selectedSkillDomainNames,
|
|
1214
|
-
compatibilityWarnings,
|
|
1215
684
|
runtimeEnvironment: {
|
|
1216
685
|
selected: selectedRuntimeEnvironmentKey,
|
|
1217
686
|
selectedLabel: resolveRuntimeEnvironmentLabelFromKey(selectedRuntimeEnvironmentKey),
|
|
@@ -1253,6 +722,9 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
|
|
|
1253
722
|
console.log(
|
|
1254
723
|
`- Architect recommendation: ${toTitleCase(architectureRecommendation.recommendedStackFileName)} + ${toTitleCase(architectureRecommendation.recommendedBlueprintFileName)} (${architectureRecommendation.confidenceLabel})`
|
|
1255
724
|
);
|
|
725
|
+
if (!projectDetection.hasExistingProjectFiles) {
|
|
726
|
+
console.log(`- Project domain: ${selectedProjectScopeLabel}`);
|
|
727
|
+
}
|
|
1256
728
|
if (architectureRecommendation.userVeto?.applied) {
|
|
1257
729
|
console.log(
|
|
1258
730
|
`- User veto path: applied (${toTitleCase(architectureRecommendation.userVeto.selectedStackFileName)} + ${toTitleCase(architectureRecommendation.userVeto.selectedBlueprintFileName)})`
|
|
@@ -1271,8 +743,12 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
|
|
|
1271
743
|
console.log(`- CI/CD quality checks (guardrails): ${includeCiGuardrails ? 'enabled' : 'disabled'}`);
|
|
1272
744
|
console.log(`- Blocking severities: ${formatBlockingSeverities(selectedProfile.blockingSeverities)}`);
|
|
1273
745
|
console.log(`- Setup time: ${formatDuration(setupDurationMs)}`);
|
|
1274
|
-
console.log('- Generated files: .cursorrules, .windsurfrules, and .agent-context/state/onboarding-report.json');
|
|
1275
|
-
if (scaffoldingResult) {
|
|
746
|
+
console.log('- Generated files: .agent-instructions.md, .cursorrules, .windsurfrules, .clauderc, and .agent-context/state/onboarding-report.json');
|
|
747
|
+
if (scaffoldingResult?.bootstrapMode === 'ai-synthesis') {
|
|
748
|
+
console.log(`- Bootstrap prompts: ${(scaffoldingResult.generatedPromptFileNames || []).length} files generated in .agent-context/prompts/`);
|
|
749
|
+
console.log(`- Bootstrap docs language: ${scaffoldingResult.docsLanguage}`);
|
|
750
|
+
console.log(`- Expected project docs after synthesis: ${scaffoldingResult.generatedFileNames.length} files in docs/`);
|
|
751
|
+
} else if (scaffoldingResult) {
|
|
1276
752
|
console.log(`- Project docs: ${scaffoldingResult.generatedFileNames.length} files generated in docs/`);
|
|
1277
753
|
console.log(`- Project docs language: ${scaffoldingResult.docsLanguage}`);
|
|
1278
754
|
}
|
|
@@ -1296,7 +772,18 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
|
|
|
1296
772
|
if (selectedAdditionalBlueprintFileNames.length > 0) {
|
|
1297
773
|
console.log(`I also included additional blueprint context for ${selectedAdditionalBlueprintFileNames.map((blueprintFileName) => toTitleCase(blueprintFileName)).join(', ')}.`);
|
|
1298
774
|
}
|
|
1299
|
-
if (scaffoldingResult) {
|
|
775
|
+
if (scaffoldingResult?.bootstrapMode === 'ai-synthesis') {
|
|
776
|
+
console.log(`I prepared dynamic synthesis bootstrap prompts (${scaffoldingResult.docsLanguage}) so your IDE assistant can author project docs from scratch on first chat.`);
|
|
777
|
+
|
|
778
|
+
const promptProjectName = scaffoldingResult.discoveryAnswers?.projectName || 'this project';
|
|
779
|
+
console.log('\nPrompt starter examples (copy and adapt in your IDE):');
|
|
780
|
+
console.log('- If docs/project-brief.md is missing, execute .agent-context/prompts/bootstrap-project-context.md now and create all required docs files.');
|
|
781
|
+
if ((scaffoldingResult.generatedPromptFileNames || []).includes('bootstrap-design.md')) {
|
|
782
|
+
console.log('- If docs/DESIGN.md is missing, execute .agent-context/prompts/bootstrap-design.md now before building UI components.');
|
|
783
|
+
}
|
|
784
|
+
console.log(`- Build an MVP for ${promptProjectName} using the newly synthesized docs as strict project context.`);
|
|
785
|
+
console.log('- When scope changes, update docs/* in the same change so future prompts stay aligned.');
|
|
786
|
+
} else if (scaffoldingResult) {
|
|
1300
787
|
console.log(`I also generated project documentation (${scaffoldingResult.docsLanguage}) based on your project description. AI agents will use docs/ as project context.`);
|
|
1301
788
|
|
|
1302
789
|
const promptProjectName = scaffoldingResult.discoveryAnswers?.projectName || 'this project';
|