@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
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
PROJECT_SCOPE_CHOICES,
|
|
5
|
+
BLUEPRINT_RECOMMENDATIONS,
|
|
6
|
+
} from './constants.mjs';
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
recommendArchitecture,
|
|
10
|
+
formatArchitectureRecommendation,
|
|
11
|
+
createUpdatedArchitectPreference,
|
|
12
|
+
shouldApplyRepeatedOverridePreference,
|
|
13
|
+
} from './architect.mjs';
|
|
14
|
+
|
|
15
|
+
import {
|
|
16
|
+
askChoice,
|
|
17
|
+
askYesNo,
|
|
18
|
+
toTitleCase,
|
|
19
|
+
} from './utils.mjs';
|
|
20
|
+
|
|
21
|
+
import {
|
|
22
|
+
filterStackFileNamesByCandidates,
|
|
23
|
+
filterBlueprintFileNamesByCandidates,
|
|
24
|
+
resolveProjectScopeKeyFromLabel,
|
|
25
|
+
resolveScopeStackCandidates,
|
|
26
|
+
resolveScopeBlueprintCandidates,
|
|
27
|
+
} from './init-selection.mjs';
|
|
28
|
+
|
|
29
|
+
const DEFAULT_PROJECT_SCOPE_KEY = 'both';
|
|
30
|
+
const DEFAULT_PROJECT_SCOPE_LABEL = PROJECT_SCOPE_CHOICES.find(
|
|
31
|
+
(scopeChoice) => scopeChoice.key === DEFAULT_PROJECT_SCOPE_KEY
|
|
32
|
+
)?.label || 'Both (frontend + backend)';
|
|
33
|
+
|
|
34
|
+
export async function resolveArchitectureSelection({
|
|
35
|
+
shouldRunArchitectureRecommendation,
|
|
36
|
+
initOptions,
|
|
37
|
+
projectDetection,
|
|
38
|
+
stackFileNames,
|
|
39
|
+
blueprintFileNames,
|
|
40
|
+
userInterface,
|
|
41
|
+
isInteractiveSession,
|
|
42
|
+
initialSelectedProjectScopeKey,
|
|
43
|
+
initialSelectedProjectScopeLabel,
|
|
44
|
+
initialSelectedManualStackFileName,
|
|
45
|
+
initialSelectedManualBlueprintFileName,
|
|
46
|
+
architectPreferenceState,
|
|
47
|
+
askStackSelection,
|
|
48
|
+
askBlueprintSelection,
|
|
49
|
+
detectionTransparency,
|
|
50
|
+
}) {
|
|
51
|
+
let selectedProjectScopeKey = initialSelectedProjectScopeKey || DEFAULT_PROJECT_SCOPE_KEY;
|
|
52
|
+
let selectedProjectScopeLabel = initialSelectedProjectScopeLabel || DEFAULT_PROJECT_SCOPE_LABEL;
|
|
53
|
+
let selectedManualStackFileName = initialSelectedManualStackFileName || null;
|
|
54
|
+
let selectedManualBlueprintFileName = initialSelectedManualBlueprintFileName || null;
|
|
55
|
+
let architectureRecommendation = null;
|
|
56
|
+
let nextArchitectPreferenceState = architectPreferenceState;
|
|
57
|
+
let architectPreferenceUpdated = false;
|
|
58
|
+
|
|
59
|
+
if (!shouldRunArchitectureRecommendation) {
|
|
60
|
+
return {
|
|
61
|
+
selectedProjectScopeKey,
|
|
62
|
+
selectedProjectScopeLabel,
|
|
63
|
+
selectedManualStackFileName,
|
|
64
|
+
selectedManualBlueprintFileName,
|
|
65
|
+
architectureRecommendation,
|
|
66
|
+
architectPreferenceState: nextArchitectPreferenceState,
|
|
67
|
+
architectPreferenceUpdated,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
let architectureProjectDescription = String(initOptions.projectDescription || '').trim();
|
|
72
|
+
const isFreshProjectFlow = !projectDetection.hasExistingProjectFiles;
|
|
73
|
+
|
|
74
|
+
if (isFreshProjectFlow && isInteractiveSession) {
|
|
75
|
+
const selectedProjectScopeInput = await askChoice(
|
|
76
|
+
'Project domain (frontend only, backend only, or both):',
|
|
77
|
+
PROJECT_SCOPE_CHOICES.map((scopeChoice) => scopeChoice.label),
|
|
78
|
+
userInterface
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
selectedProjectScopeKey = resolveProjectScopeKeyFromLabel(selectedProjectScopeInput);
|
|
82
|
+
selectedProjectScopeLabel = selectedProjectScopeInput;
|
|
83
|
+
|
|
84
|
+
if (!architectureProjectDescription) {
|
|
85
|
+
architectureProjectDescription = (await userInterface.question(
|
|
86
|
+
'\nProject description (free text): '
|
|
87
|
+
)).trim();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (!architectureProjectDescription && isInteractiveSession && !isFreshProjectFlow) {
|
|
92
|
+
architectureProjectDescription = (await userInterface.question(
|
|
93
|
+
'\nDescribe your project in one short paragraph for architecture recommendation: '
|
|
94
|
+
)).trim();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (!architectureProjectDescription) {
|
|
98
|
+
architectureProjectDescription = `A software project named ${path.basename(initOptions.targetDirectoryPath)}.`;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const scopeStackCandidates = filterStackFileNamesByCandidates(
|
|
102
|
+
stackFileNames,
|
|
103
|
+
resolveScopeStackCandidates(selectedProjectScopeKey)
|
|
104
|
+
);
|
|
105
|
+
const scopeBlueprintCandidates = filterBlueprintFileNamesByCandidates(
|
|
106
|
+
blueprintFileNames,
|
|
107
|
+
resolveScopeBlueprintCandidates(selectedProjectScopeKey)
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
architectureRecommendation = recommendArchitecture({
|
|
111
|
+
projectDescription: architectureProjectDescription,
|
|
112
|
+
projectDetection,
|
|
113
|
+
stackFileNames: scopeStackCandidates,
|
|
114
|
+
blueprintFileNames: scopeBlueprintCandidates,
|
|
115
|
+
tokenBudget: initOptions.architectTokenBudget,
|
|
116
|
+
timeoutMs: initOptions.architectTimeoutMs,
|
|
117
|
+
researchMode: initOptions.architectResearchMode,
|
|
118
|
+
enableRealtimeResearch: initOptions.enableRealtimeResearch,
|
|
119
|
+
realtimeSignalFilePath: initOptions.architectRealtimeSignalFile,
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
architectureRecommendation.projectDomain = {
|
|
123
|
+
key: selectedProjectScopeKey,
|
|
124
|
+
label: selectedProjectScopeLabel,
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
architectureRecommendation.userVeto = {
|
|
128
|
+
applied: false,
|
|
129
|
+
selectedStackFileName: architectureRecommendation.recommendedStackFileName,
|
|
130
|
+
selectedBlueprintFileName: architectureRecommendation.recommendedBlueprintFileName,
|
|
131
|
+
source: 'recommendation',
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
console.log(formatArchitectureRecommendation(architectureRecommendation));
|
|
135
|
+
|
|
136
|
+
const shouldSkipRecommendationDebate = shouldApplyRepeatedOverridePreference(
|
|
137
|
+
nextArchitectPreferenceState,
|
|
138
|
+
architectureRecommendation.recommendedStackFileName
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
if (isFreshProjectFlow) {
|
|
142
|
+
selectedManualStackFileName = architectureRecommendation.recommendedStackFileName;
|
|
143
|
+
selectedManualBlueprintFileName = architectureRecommendation.recommendedBlueprintFileName;
|
|
144
|
+
|
|
145
|
+
if (detectionTransparency) {
|
|
146
|
+
detectionTransparency.quickConfirmation.response = 'fresh-project-two-question';
|
|
147
|
+
detectionTransparency.decision.mode = 'fresh-project-two-question-auto';
|
|
148
|
+
}
|
|
149
|
+
} else if (shouldSkipRecommendationDebate) {
|
|
150
|
+
architectureRecommendation.failureModes.repeatedOverride = true;
|
|
151
|
+
selectedManualStackFileName = stackFileNames.includes(nextArchitectPreferenceState.preferredStackFileName)
|
|
152
|
+
? nextArchitectPreferenceState.preferredStackFileName
|
|
153
|
+
: architectureRecommendation.recommendedStackFileName;
|
|
154
|
+
selectedManualBlueprintFileName = blueprintFileNames.includes(nextArchitectPreferenceState.preferredBlueprintFileName)
|
|
155
|
+
? nextArchitectPreferenceState.preferredBlueprintFileName
|
|
156
|
+
: architectureRecommendation.recommendedBlueprintFileName;
|
|
157
|
+
architectureRecommendation.userVeto = {
|
|
158
|
+
applied: true,
|
|
159
|
+
selectedStackFileName: selectedManualStackFileName,
|
|
160
|
+
selectedBlueprintFileName: selectedManualBlueprintFileName,
|
|
161
|
+
source: 'saved-preference',
|
|
162
|
+
};
|
|
163
|
+
console.log(
|
|
164
|
+
`Repeated override preference detected. Applying ${toTitleCase(selectedManualStackFileName)} + ${toTitleCase(selectedManualBlueprintFileName)} without additional debate.`
|
|
165
|
+
);
|
|
166
|
+
} else if (!isInteractiveSession) {
|
|
167
|
+
selectedManualStackFileName = architectureRecommendation.recommendedStackFileName;
|
|
168
|
+
selectedManualBlueprintFileName = architectureRecommendation.recommendedBlueprintFileName;
|
|
169
|
+
} else {
|
|
170
|
+
const shouldApplyRecommendedArchitecture = await askYesNo(
|
|
171
|
+
'Apply this architecture recommendation?',
|
|
172
|
+
userInterface,
|
|
173
|
+
true
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
if (shouldApplyRecommendedArchitecture) {
|
|
177
|
+
selectedManualStackFileName = architectureRecommendation.recommendedStackFileName;
|
|
178
|
+
selectedManualBlueprintFileName = architectureRecommendation.recommendedBlueprintFileName;
|
|
179
|
+
} else {
|
|
180
|
+
const vetoStackFileName = await askStackSelection(
|
|
181
|
+
'User veto received. Select stack to apply immediately:',
|
|
182
|
+
stackFileNames,
|
|
183
|
+
userInterface
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
const vetoBlueprintCandidates = filterBlueprintFileNamesByCandidates(
|
|
187
|
+
blueprintFileNames,
|
|
188
|
+
[BLUEPRINT_RECOMMENDATIONS[vetoStackFileName]].filter(Boolean)
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
const vetoBlueprintFileName = await askBlueprintSelection(
|
|
192
|
+
'Select blueprint to apply immediately (no further debate):',
|
|
193
|
+
vetoBlueprintCandidates,
|
|
194
|
+
userInterface
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
selectedManualStackFileName = vetoStackFileName;
|
|
198
|
+
selectedManualBlueprintFileName = vetoBlueprintFileName;
|
|
199
|
+
architectureRecommendation.userVeto = {
|
|
200
|
+
applied: true,
|
|
201
|
+
selectedStackFileName: vetoStackFileName,
|
|
202
|
+
selectedBlueprintFileName: vetoBlueprintFileName,
|
|
203
|
+
source: 'interactive-veto',
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
nextArchitectPreferenceState = createUpdatedArchitectPreference(nextArchitectPreferenceState, {
|
|
207
|
+
selectedStackFileName: vetoStackFileName,
|
|
208
|
+
selectedBlueprintFileName: vetoBlueprintFileName,
|
|
209
|
+
});
|
|
210
|
+
architectPreferenceUpdated = true;
|
|
211
|
+
|
|
212
|
+
if (nextArchitectPreferenceState.overrideCount >= 2) {
|
|
213
|
+
architectureRecommendation.failureModes.repeatedOverride = true;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
console.log(
|
|
217
|
+
`Veto applied. Proceeding with ${toTitleCase(vetoStackFileName)} + ${toTitleCase(vetoBlueprintFileName)} without recommendation loops.`
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return {
|
|
223
|
+
selectedProjectScopeKey,
|
|
224
|
+
selectedProjectScopeLabel,
|
|
225
|
+
selectedManualStackFileName,
|
|
226
|
+
selectedManualBlueprintFileName,
|
|
227
|
+
architectureRecommendation,
|
|
228
|
+
architectPreferenceState: nextArchitectPreferenceState,
|
|
229
|
+
architectPreferenceUpdated,
|
|
230
|
+
};
|
|
231
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BLUEPRINT_RECOMMENDATIONS,
|
|
3
|
+
} from './constants.mjs';
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
filterBlueprintFileNamesByCandidates,
|
|
7
|
+
normalizeAdditionalStackSelection,
|
|
8
|
+
} from './init-selection.mjs';
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
toTitleCase,
|
|
12
|
+
} from './utils.mjs';
|
|
13
|
+
|
|
14
|
+
export function buildExistingProjectMajorConstraints() {
|
|
15
|
+
return [
|
|
16
|
+
'Preserve existing project markers and avoid forced stack migration.',
|
|
17
|
+
'Keep stack rule loading lazy and scoped to touched code.',
|
|
18
|
+
'Explicit stack or blueprint overrides always win over auto-detection.',
|
|
19
|
+
];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export async function resolveDetectedSetupDecision({
|
|
23
|
+
shouldAutoApplyDetectedStack,
|
|
24
|
+
projectDetection,
|
|
25
|
+
stackFileNames,
|
|
26
|
+
blueprintFileNames,
|
|
27
|
+
userInterface,
|
|
28
|
+
isInteractiveSession,
|
|
29
|
+
detectionTransparency,
|
|
30
|
+
askYesNo,
|
|
31
|
+
askStackSelection,
|
|
32
|
+
askBlueprintSelection,
|
|
33
|
+
initialSelectedManualStackFileName,
|
|
34
|
+
initialSelectedManualBlueprintFileName,
|
|
35
|
+
initialSelectedAdditionalStackFileNames,
|
|
36
|
+
}) {
|
|
37
|
+
let selectedManualStackFileName = initialSelectedManualStackFileName || null;
|
|
38
|
+
let selectedManualBlueprintFileName = initialSelectedManualBlueprintFileName || null;
|
|
39
|
+
let selectedAdditionalStackFileNames = initialSelectedAdditionalStackFileNames || [];
|
|
40
|
+
let detectedSetupWasApplied = false;
|
|
41
|
+
|
|
42
|
+
const detectedBlueprintFileName = projectDetection.recommendedBlueprintFileName
|
|
43
|
+
|| BLUEPRINT_RECOMMENDATIONS[projectDetection.recommendedStackFileName]
|
|
44
|
+
|| null;
|
|
45
|
+
|
|
46
|
+
if (shouldAutoApplyDetectedStack) {
|
|
47
|
+
if (isInteractiveSession) {
|
|
48
|
+
detectionTransparency.quickConfirmation.offered = true;
|
|
49
|
+
console.log('\nQuick confirmation for existing project detection:');
|
|
50
|
+
console.log(`- Suggested stack: ${toTitleCase(projectDetection.recommendedStackFileName)}`);
|
|
51
|
+
if (detectedBlueprintFileName) {
|
|
52
|
+
console.log(`- Suggested blueprint: ${toTitleCase(detectedBlueprintFileName)}`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const shouldUseDetectedSetup = await askYesNo(
|
|
56
|
+
'Use detected setup for this existing project?',
|
|
57
|
+
userInterface,
|
|
58
|
+
true
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
if (shouldUseDetectedSetup) {
|
|
62
|
+
detectedSetupWasApplied = true;
|
|
63
|
+
detectionTransparency.quickConfirmation.response = 'confirmed-detected';
|
|
64
|
+
detectionTransparency.decision.mode = 'confirmed-detected';
|
|
65
|
+
console.log(`Using detected stack automatically for this existing project: ${toTitleCase(projectDetection.recommendedStackFileName)}.`);
|
|
66
|
+
if (projectDetection.secondaryStackFileNames?.length) {
|
|
67
|
+
console.log(`Detected additional stack signals: ${projectDetection.secondaryStackFileNames.map((stackFileName) => toTitleCase(stackFileName)).join(', ')}.`);
|
|
68
|
+
}
|
|
69
|
+
selectedAdditionalStackFileNames = projectDetection.secondaryStackFileNames || [];
|
|
70
|
+
} else {
|
|
71
|
+
const overrideStackFileName = await askStackSelection(
|
|
72
|
+
'Override detected stack (quick selection):',
|
|
73
|
+
stackFileNames,
|
|
74
|
+
userInterface
|
|
75
|
+
);
|
|
76
|
+
const overrideBlueprintCandidates = filterBlueprintFileNamesByCandidates(
|
|
77
|
+
blueprintFileNames,
|
|
78
|
+
[BLUEPRINT_RECOMMENDATIONS[overrideStackFileName]].filter(Boolean)
|
|
79
|
+
);
|
|
80
|
+
const overrideBlueprintFileName = await askBlueprintSelection(
|
|
81
|
+
'Override detected blueprint (quick selection):',
|
|
82
|
+
overrideBlueprintCandidates,
|
|
83
|
+
userInterface
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
selectedManualStackFileName = overrideStackFileName;
|
|
87
|
+
selectedManualBlueprintFileName = overrideBlueprintFileName;
|
|
88
|
+
selectedAdditionalStackFileNames = normalizeAdditionalStackSelection(
|
|
89
|
+
overrideStackFileName,
|
|
90
|
+
projectDetection.secondaryStackFileNames || []
|
|
91
|
+
);
|
|
92
|
+
detectionTransparency.quickConfirmation.response = 'overridden-detected';
|
|
93
|
+
detectionTransparency.decision.mode = 'overridden-detected';
|
|
94
|
+
console.log(
|
|
95
|
+
`Detection override applied: ${toTitleCase(overrideStackFileName)} + ${toTitleCase(overrideBlueprintFileName)}.`
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
} else {
|
|
99
|
+
detectedSetupWasApplied = true;
|
|
100
|
+
detectionTransparency.quickConfirmation.response = 'non-interactive-auto';
|
|
101
|
+
detectionTransparency.decision.mode = 'non-interactive-auto';
|
|
102
|
+
console.log(`Using detected stack automatically for this existing project: ${toTitleCase(projectDetection.recommendedStackFileName)}.`);
|
|
103
|
+
if (projectDetection.secondaryStackFileNames?.length) {
|
|
104
|
+
console.log(`Detected additional stack signals: ${projectDetection.secondaryStackFileNames.map((stackFileName) => toTitleCase(stackFileName)).join(', ')}.`);
|
|
105
|
+
}
|
|
106
|
+
selectedAdditionalStackFileNames = projectDetection.secondaryStackFileNames || [];
|
|
107
|
+
}
|
|
108
|
+
} else if (projectDetection.hasExistingProjectFiles && projectDetection.recommendedStackFileName) {
|
|
109
|
+
detectionTransparency.quickConfirmation.response = 'explicit-selection-or-low-confidence';
|
|
110
|
+
detectionTransparency.decision.mode = 'explicit-selection-or-low-confidence';
|
|
111
|
+
} else if (!projectDetection.hasExistingProjectFiles) {
|
|
112
|
+
detectionTransparency.quickConfirmation.response = 'not-applicable';
|
|
113
|
+
detectionTransparency.decision.mode = 'fresh-directory';
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return {
|
|
117
|
+
detectedSetupWasApplied,
|
|
118
|
+
selectedManualStackFileName,
|
|
119
|
+
selectedManualBlueprintFileName,
|
|
120
|
+
selectedAdditionalStackFileNames,
|
|
121
|
+
detectedBlueprintFileName,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Init Options Parser — isolates CLI option parsing from init runtime flow.
|
|
3
|
+
*/
|
|
4
|
+
import {
|
|
5
|
+
ARCHITECT_DEFAULT_TOKEN_BUDGET,
|
|
6
|
+
ARCHITECT_DEFAULT_TIMEOUT_MS,
|
|
7
|
+
ARCHITECT_MIN_TOKEN_BUDGET,
|
|
8
|
+
ARCHITECT_MAX_TOKEN_BUDGET,
|
|
9
|
+
ARCHITECT_MIN_TIMEOUT_MS,
|
|
10
|
+
ARCHITECT_MAX_TIMEOUT_MS,
|
|
11
|
+
} from './architect.mjs';
|
|
12
|
+
import { normalizeDocsLanguage } from './project-scaffolder.mjs';
|
|
13
|
+
import { normalizeAgentName } from './token-optimization.mjs';
|
|
14
|
+
import { normalizeChoiceInput, matchProfileNameFromInput } from './utils.mjs';
|
|
15
|
+
|
|
16
|
+
const INIT_DEFAULT_RESEARCH_MODE = 'realtime';
|
|
17
|
+
|
|
18
|
+
export function normalizeRuntimeEnvironmentKey(rawRuntimeEnvironmentKey) {
|
|
19
|
+
const normalizedRuntimeEnvironmentKey = normalizeChoiceInput(String(rawRuntimeEnvironmentKey || 'auto'));
|
|
20
|
+
const supportedRuntimeEnvironmentKeys = new Set(['auto', 'linux-wsl', 'linux', 'windows', 'macos']);
|
|
21
|
+
return supportedRuntimeEnvironmentKeys.has(normalizedRuntimeEnvironmentKey) ? normalizedRuntimeEnvironmentKey : null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function parseInitArguments(commandArguments) {
|
|
25
|
+
const parsedInitOptions = {
|
|
26
|
+
targetDirectory: '.',
|
|
27
|
+
preset: undefined,
|
|
28
|
+
profile: undefined,
|
|
29
|
+
profilePack: undefined,
|
|
30
|
+
stack: undefined,
|
|
31
|
+
blueprint: undefined,
|
|
32
|
+
ci: undefined,
|
|
33
|
+
newbie: false,
|
|
34
|
+
tokenOptimize: true,
|
|
35
|
+
memoryContinuity: true,
|
|
36
|
+
tokenAgent: 'copilot',
|
|
37
|
+
includeMcpTemplate: true,
|
|
38
|
+
scaffoldDocs: undefined,
|
|
39
|
+
docsLang: 'en',
|
|
40
|
+
docsLangProvided: false,
|
|
41
|
+
projectConfig: undefined,
|
|
42
|
+
projectDescription: '',
|
|
43
|
+
architectTokenBudget: ARCHITECT_DEFAULT_TOKEN_BUDGET,
|
|
44
|
+
architectTimeoutMs: ARCHITECT_DEFAULT_TIMEOUT_MS,
|
|
45
|
+
architectResearchMode: INIT_DEFAULT_RESEARCH_MODE,
|
|
46
|
+
enableRealtimeResearch: true,
|
|
47
|
+
architectRealtimeSignalFile: null,
|
|
48
|
+
runtimeEnv: 'auto',
|
|
49
|
+
runtimeEnvProvided: false,
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
for (let argumentIndex = 0; argumentIndex < commandArguments.length; argumentIndex++) {
|
|
53
|
+
const currentArgument = commandArguments[argumentIndex];
|
|
54
|
+
|
|
55
|
+
if (!currentArgument.startsWith('--')) {
|
|
56
|
+
parsedInitOptions.targetDirectory = currentArgument;
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (currentArgument === '--profile') {
|
|
61
|
+
parsedInitOptions.profile = matchProfileNameFromInput(commandArguments[argumentIndex + 1] || '');
|
|
62
|
+
argumentIndex += 1;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (currentArgument === '--preset') {
|
|
67
|
+
parsedInitOptions.preset = normalizeChoiceInput(commandArguments[argumentIndex + 1] || '');
|
|
68
|
+
argumentIndex += 1;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (currentArgument.startsWith('--preset=')) {
|
|
73
|
+
parsedInitOptions.preset = normalizeChoiceInput(currentArgument.split('=')[1]);
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (currentArgument.startsWith('--profile=')) {
|
|
78
|
+
parsedInitOptions.profile = matchProfileNameFromInput(currentArgument.split('=')[1]);
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (currentArgument === '--profile-pack') {
|
|
83
|
+
parsedInitOptions.profilePack = commandArguments[argumentIndex + 1];
|
|
84
|
+
argumentIndex += 1;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (currentArgument.startsWith('--profile-pack=')) {
|
|
89
|
+
parsedInitOptions.profilePack = currentArgument.split('=')[1];
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (currentArgument === '--stack') {
|
|
94
|
+
parsedInitOptions.stack = commandArguments[argumentIndex + 1];
|
|
95
|
+
argumentIndex += 1;
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (currentArgument.startsWith('--stack=')) {
|
|
100
|
+
parsedInitOptions.stack = currentArgument.split('=')[1];
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (currentArgument === '--blueprint') {
|
|
105
|
+
parsedInitOptions.blueprint = commandArguments[argumentIndex + 1];
|
|
106
|
+
argumentIndex += 1;
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (currentArgument.startsWith('--blueprint=')) {
|
|
111
|
+
parsedInitOptions.blueprint = currentArgument.split('=')[1];
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (currentArgument === '--ci') {
|
|
116
|
+
const ciRawValue = commandArguments[argumentIndex + 1];
|
|
117
|
+
parsedInitOptions.ci = ciRawValue?.toLowerCase() === 'true';
|
|
118
|
+
argumentIndex += 1;
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (currentArgument.startsWith('--ci=')) {
|
|
123
|
+
parsedInitOptions.ci = currentArgument.split('=')[1]?.toLowerCase() === 'true';
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (currentArgument === '--newbie') {
|
|
128
|
+
parsedInitOptions.newbie = true;
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (currentArgument === '--token-optimize') {
|
|
133
|
+
parsedInitOptions.tokenOptimize = true;
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (currentArgument === '--memory-continuity') {
|
|
138
|
+
parsedInitOptions.memoryContinuity = true;
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (currentArgument === '--token-agent') {
|
|
143
|
+
parsedInitOptions.tokenAgent = commandArguments[argumentIndex + 1] || 'copilot';
|
|
144
|
+
argumentIndex += 1;
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (currentArgument.startsWith('--token-agent=')) {
|
|
149
|
+
parsedInitOptions.tokenAgent = currentArgument.split('=')[1] || 'copilot';
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (currentArgument === '--no-token-optimize') {
|
|
154
|
+
parsedInitOptions.tokenOptimize = false;
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (currentArgument === '--no-memory-continuity') {
|
|
159
|
+
parsedInitOptions.memoryContinuity = false;
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (currentArgument === '--mcp-template') {
|
|
164
|
+
parsedInitOptions.includeMcpTemplate = true;
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (currentArgument === '--no-mcp-template') {
|
|
169
|
+
parsedInitOptions.includeMcpTemplate = false;
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (currentArgument === '--scaffold-docs') {
|
|
174
|
+
parsedInitOptions.scaffoldDocs = true;
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (currentArgument === '--no-scaffold-docs') {
|
|
179
|
+
parsedInitOptions.scaffoldDocs = false;
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (currentArgument === '--docs-lang') {
|
|
184
|
+
parsedInitOptions.docsLang = commandArguments[argumentIndex + 1] || 'en';
|
|
185
|
+
parsedInitOptions.docsLangProvided = true;
|
|
186
|
+
argumentIndex += 1;
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (currentArgument.startsWith('--docs-lang=')) {
|
|
191
|
+
parsedInitOptions.docsLang = currentArgument.split('=')[1] || 'en';
|
|
192
|
+
parsedInitOptions.docsLangProvided = true;
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (currentArgument === '--project-config') {
|
|
197
|
+
parsedInitOptions.projectConfig = commandArguments[argumentIndex + 1];
|
|
198
|
+
argumentIndex += 1;
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (currentArgument.startsWith('--project-config=')) {
|
|
203
|
+
parsedInitOptions.projectConfig = currentArgument.split('=')[1];
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (currentArgument === '--project-description') {
|
|
208
|
+
parsedInitOptions.projectDescription = commandArguments[argumentIndex + 1] || '';
|
|
209
|
+
argumentIndex += 1;
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (currentArgument.startsWith('--project-description=')) {
|
|
214
|
+
parsedInitOptions.projectDescription = currentArgument.split('=')[1] || '';
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if (currentArgument === '--architect-token-budget') {
|
|
219
|
+
const rawTokenBudget = Number.parseInt(commandArguments[argumentIndex + 1], 10);
|
|
220
|
+
if (Number.isNaN(rawTokenBudget)) {
|
|
221
|
+
throw new Error('--architect-token-budget must be a number');
|
|
222
|
+
}
|
|
223
|
+
parsedInitOptions.architectTokenBudget = rawTokenBudget;
|
|
224
|
+
argumentIndex += 1;
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (currentArgument.startsWith('--architect-token-budget=')) {
|
|
229
|
+
const rawTokenBudget = Number.parseInt(currentArgument.split('=')[1], 10);
|
|
230
|
+
if (Number.isNaN(rawTokenBudget)) {
|
|
231
|
+
throw new Error('--architect-token-budget must be a number');
|
|
232
|
+
}
|
|
233
|
+
parsedInitOptions.architectTokenBudget = rawTokenBudget;
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (currentArgument === '--architect-timeout-ms') {
|
|
238
|
+
const rawTimeoutMs = Number.parseInt(commandArguments[argumentIndex + 1], 10);
|
|
239
|
+
if (Number.isNaN(rawTimeoutMs)) {
|
|
240
|
+
throw new Error('--architect-timeout-ms must be a number');
|
|
241
|
+
}
|
|
242
|
+
parsedInitOptions.architectTimeoutMs = rawTimeoutMs;
|
|
243
|
+
argumentIndex += 1;
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (currentArgument.startsWith('--architect-timeout-ms=')) {
|
|
248
|
+
const rawTimeoutMs = Number.parseInt(currentArgument.split('=')[1], 10);
|
|
249
|
+
if (Number.isNaN(rawTimeoutMs)) {
|
|
250
|
+
throw new Error('--architect-timeout-ms must be a number');
|
|
251
|
+
}
|
|
252
|
+
parsedInitOptions.architectTimeoutMs = rawTimeoutMs;
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if (currentArgument === '--architect-research-mode') {
|
|
257
|
+
parsedInitOptions.architectResearchMode = commandArguments[argumentIndex + 1] || INIT_DEFAULT_RESEARCH_MODE;
|
|
258
|
+
argumentIndex += 1;
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (currentArgument.startsWith('--architect-research-mode=')) {
|
|
263
|
+
parsedInitOptions.architectResearchMode = currentArgument.split('=')[1] || INIT_DEFAULT_RESEARCH_MODE;
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (currentArgument === '--enable-realtime-research') {
|
|
268
|
+
parsedInitOptions.enableRealtimeResearch = true;
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
if (currentArgument === '--disable-realtime-research') {
|
|
273
|
+
parsedInitOptions.enableRealtimeResearch = false;
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if (currentArgument === '--architect-realtime-signal-file') {
|
|
278
|
+
parsedInitOptions.architectRealtimeSignalFile = commandArguments[argumentIndex + 1] || null;
|
|
279
|
+
argumentIndex += 1;
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
if (currentArgument.startsWith('--architect-realtime-signal-file=')) {
|
|
284
|
+
parsedInitOptions.architectRealtimeSignalFile = currentArgument.split('=')[1] || null;
|
|
285
|
+
continue;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
if (currentArgument === '--runtime-env') {
|
|
289
|
+
parsedInitOptions.runtimeEnv = commandArguments[argumentIndex + 1] || 'auto';
|
|
290
|
+
parsedInitOptions.runtimeEnvProvided = true;
|
|
291
|
+
argumentIndex += 1;
|
|
292
|
+
continue;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
if (currentArgument.startsWith('--runtime-env=')) {
|
|
296
|
+
parsedInitOptions.runtimeEnv = currentArgument.split('=')[1] || 'auto';
|
|
297
|
+
parsedInitOptions.runtimeEnvProvided = true;
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
throw new Error(`Unknown option: ${currentArgument}`);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
if (parsedInitOptions.newbie && parsedInitOptions.profile && parsedInitOptions.profile !== 'beginner') {
|
|
305
|
+
throw new Error('--newbie can only be combined with --profile beginner');
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
const normalizedDocsLanguage = normalizeDocsLanguage(parsedInitOptions.docsLang || 'en');
|
|
309
|
+
if (!normalizedDocsLanguage) {
|
|
310
|
+
throw new Error('--docs-lang must be one of: en, id');
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const normalizedRuntimeEnvironment = normalizeRuntimeEnvironmentKey(parsedInitOptions.runtimeEnv || 'auto');
|
|
314
|
+
if (!normalizedRuntimeEnvironment) {
|
|
315
|
+
throw new Error('--runtime-env must be one of: auto, linux-wsl, linux, windows, macos');
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
if (!Number.isInteger(parsedInitOptions.architectTokenBudget)
|
|
319
|
+
|| parsedInitOptions.architectTokenBudget < ARCHITECT_MIN_TOKEN_BUDGET
|
|
320
|
+
|| parsedInitOptions.architectTokenBudget > ARCHITECT_MAX_TOKEN_BUDGET) {
|
|
321
|
+
throw new Error(`--architect-token-budget must be an integer between ${ARCHITECT_MIN_TOKEN_BUDGET} and ${ARCHITECT_MAX_TOKEN_BUDGET}`);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
if (!Number.isInteger(parsedInitOptions.architectTimeoutMs)
|
|
325
|
+
|| parsedInitOptions.architectTimeoutMs < ARCHITECT_MIN_TIMEOUT_MS
|
|
326
|
+
|| parsedInitOptions.architectTimeoutMs > ARCHITECT_MAX_TIMEOUT_MS) {
|
|
327
|
+
throw new Error(`--architect-timeout-ms must be an integer between ${ARCHITECT_MIN_TIMEOUT_MS} and ${ARCHITECT_MAX_TIMEOUT_MS}`);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
const normalizedArchitectResearchMode = normalizeChoiceInput(
|
|
331
|
+
parsedInitOptions.architectResearchMode || INIT_DEFAULT_RESEARCH_MODE
|
|
332
|
+
);
|
|
333
|
+
const supportedArchitectResearchModes = new Set(['snapshot', 'realtime']);
|
|
334
|
+
if (!supportedArchitectResearchModes.has(normalizedArchitectResearchMode)) {
|
|
335
|
+
throw new Error('--architect-research-mode must be one of: snapshot, realtime');
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
parsedInitOptions.docsLang = normalizedDocsLanguage;
|
|
339
|
+
parsedInitOptions.runtimeEnv = normalizedRuntimeEnvironment;
|
|
340
|
+
parsedInitOptions.tokenAgent = normalizeAgentName(parsedInitOptions.tokenAgent);
|
|
341
|
+
parsedInitOptions.architectResearchMode = normalizedArchitectResearchMode;
|
|
342
|
+
|
|
343
|
+
return parsedInitOptions;
|
|
344
|
+
}
|