@ryuenn3123/agentic-senior-core 3.0.19 → 3.0.21
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/bootstrap-design.md +96 -103
- package/.agent-context/prompts/init-project.md +32 -100
- package/.agent-context/prompts/refactor.md +22 -44
- package/.agent-context/prompts/review-code.md +28 -52
- package/.agent-context/review-checklists/architecture-review.md +31 -62
- package/.agent-context/review-checklists/pr-checklist.md +74 -108
- package/.agent-context/rules/api-docs.md +18 -206
- package/.agent-context/rules/architecture.md +40 -207
- package/.agent-context/rules/database-design.md +10 -199
- package/.agent-context/rules/docker-runtime.md +5 -5
- package/.agent-context/rules/efficiency-vs-hype.md +11 -149
- package/.agent-context/rules/error-handling.md +9 -231
- package/.agent-context/rules/event-driven.md +17 -221
- package/.agent-context/rules/frontend-architecture.md +74 -119
- package/.agent-context/rules/git-workflow.md +1 -1
- package/.agent-context/rules/microservices.md +28 -161
- package/.agent-context/rules/naming-conv.md +8 -138
- package/.agent-context/rules/performance.md +9 -175
- package/.agent-context/rules/realtime.md +11 -44
- package/.agent-context/rules/security.md +11 -295
- package/.agent-context/rules/testing.md +9 -174
- package/.agent-context/state/benchmark-analysis.json +3 -3
- package/.agent-context/state/memory-continuity-benchmark.json +1 -1
- package/.agent-context/state/onboarding-report.json +71 -11
- package/.agents/workflows/init-project.md +7 -24
- package/.agents/workflows/refactor.md +7 -24
- package/.agents/workflows/review-code.md +7 -24
- package/.cursorrules +22 -21
- package/.gemini/instructions.md +2 -2
- package/.github/copilot-instructions.md +2 -2
- package/.instructions.md +112 -213
- package/.windsurfrules +22 -21
- package/AGENTS.md +4 -4
- package/CONTRIBUTING.md +13 -22
- package/README.md +6 -20
- package/lib/cli/commands/init.mjs +102 -148
- package/lib/cli/commands/launch.mjs +3 -3
- package/lib/cli/commands/optimize.mjs +14 -4
- package/lib/cli/commands/upgrade.mjs +25 -23
- package/lib/cli/compiler.mjs +96 -62
- package/lib/cli/constants.mjs +28 -136
- package/lib/cli/detector/design-evidence.mjs +189 -6
- package/lib/cli/detector.mjs +6 -7
- package/lib/cli/init-detection-flow.mjs +10 -93
- package/lib/cli/init-selection.mjs +2 -68
- package/lib/cli/project-scaffolder/constants.mjs +1 -1
- package/lib/cli/project-scaffolder/design-contract.mjs +183 -108
- package/lib/cli/project-scaffolder/discovery.mjs +36 -82
- package/lib/cli/project-scaffolder/prompt-builders.mjs +45 -55
- package/lib/cli/project-scaffolder/storage.mjs +0 -2
- package/lib/cli/token-optimization.mjs +1 -1
- package/lib/cli/utils.mjs +75 -9
- package/package.json +2 -2
- package/scripts/detection-benchmark.mjs +4 -15
- package/scripts/documentation-boundary-audit.mjs +9 -9
- package/scripts/explain-on-demand-audit.mjs +11 -11
- package/scripts/forbidden-content-check.mjs +9 -9
- package/scripts/frontend-usability-audit.mjs +45 -35
- package/scripts/llm-judge.mjs +1 -1
- package/scripts/mcp-server/constants.mjs +2 -2
- package/scripts/mcp-server/tool-registry.mjs +1 -1
- package/scripts/release-gate/audit-checks.mjs +22 -7
- package/scripts/release-gate/static-checks.mjs +5 -5
- package/scripts/release-gate.mjs +1 -1
- package/scripts/rules-guardian-audit.mjs +14 -13
- package/scripts/single-source-lazy-loading-audit.mjs +3 -3
- package/scripts/sync-thin-adapters.mjs +5 -5
- package/scripts/ui-design-judge/design-execution-summary.mjs +27 -1
- package/scripts/ui-design-judge/prompting.mjs +5 -5
- package/scripts/ui-design-judge/reporting.mjs +3 -1
- package/scripts/ui-design-judge/rubric-calibration.mjs +8 -5
- package/scripts/ui-design-judge/rubric-goldset.json +2 -2
- package/scripts/ui-design-judge.mjs +75 -7
- package/scripts/validate/config.mjs +138 -48
- package/scripts/validate/coverage-checks.mjs +32 -7
- package/scripts/validate.mjs +8 -4
- package/lib/cli/architect.mjs +0 -431
|
@@ -11,7 +11,8 @@ import {
|
|
|
11
11
|
CLI_VERSION,
|
|
12
12
|
AGENT_CONTEXT_DIR,
|
|
13
13
|
PROFILE_PRESETS,
|
|
14
|
-
|
|
14
|
+
AGENT_DECISION_STACK_FILE_NAME,
|
|
15
|
+
AGENT_DECISION_BLUEPRINT_FILE_NAME,
|
|
15
16
|
} from '../constants.mjs';
|
|
16
17
|
|
|
17
18
|
import {
|
|
@@ -103,8 +104,8 @@ export function parseUpgradeArguments(commandArguments) {
|
|
|
103
104
|
function buildExistingProjectMajorConstraints() {
|
|
104
105
|
return [
|
|
105
106
|
'Preserve existing project markers and avoid forced stack migration.',
|
|
106
|
-
'
|
|
107
|
-
'Upgrade keeps prior onboarding
|
|
107
|
+
'Use runtime markers as evidence only unless the user already recorded an explicit runtime constraint.',
|
|
108
|
+
'Upgrade keeps prior explicit onboarding constraints but does not create new stack or blueprint decisions.',
|
|
108
109
|
];
|
|
109
110
|
}
|
|
110
111
|
|
|
@@ -172,9 +173,11 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
|
|
|
172
173
|
|
|
173
174
|
try {
|
|
174
175
|
console.log(`\nAgentic-Senior-Core CLI v${CLI_VERSION}`);
|
|
175
|
-
console.log('Running
|
|
176
|
+
console.log('Running managed guidance upgrade for an existing repository.');
|
|
176
177
|
|
|
177
|
-
const managedSurfacePlan = await analyzeManagedGovernanceSurface(resolvedTargetDirectoryPath
|
|
178
|
+
const managedSurfacePlan = await analyzeManagedGovernanceSurface(resolvedTargetDirectoryPath, {
|
|
179
|
+
includeMcpTemplate: upgradeOptions.includeMcpTemplate === true,
|
|
180
|
+
});
|
|
178
181
|
|
|
179
182
|
const stackFileNames = await collectFileNames(path.join(AGENT_CONTEXT_DIR, 'stacks'));
|
|
180
183
|
const blueprintFileNames = await collectFileNames(path.join(AGENT_CONTEXT_DIR, 'blueprints'));
|
|
@@ -184,29 +187,28 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
|
|
|
184
187
|
? existingOnboardingReport.selectedProfile
|
|
185
188
|
: 'balanced';
|
|
186
189
|
|
|
187
|
-
const
|
|
190
|
+
const hasExplicitRuntimeConstraint = existingOnboardingReport?.runtimeDecision?.mode === 'explicit-constraint';
|
|
191
|
+
const hasExplicitArchitectureConstraint = existingOnboardingReport?.architectureDecision?.mode === 'explicit-constraint';
|
|
192
|
+
|
|
193
|
+
const selectedStackFileName = hasExplicitRuntimeConstraint && stackFileNames.includes(existingOnboardingReport?.selectedStack)
|
|
188
194
|
? existingOnboardingReport.selectedStack
|
|
189
|
-
:
|
|
195
|
+
: AGENT_DECISION_STACK_FILE_NAME;
|
|
190
196
|
|
|
191
|
-
const selectedAdditionalStackFileNames = Array.isArray(existingOnboardingReport?.selectedAdditionalStacks)
|
|
197
|
+
const selectedAdditionalStackFileNames = hasExplicitRuntimeConstraint && Array.isArray(existingOnboardingReport?.selectedAdditionalStacks)
|
|
192
198
|
? Array.from(new Set(existingOnboardingReport.selectedAdditionalStacks.filter(
|
|
193
199
|
(stackFileName) => stackFileNames.includes(stackFileName) && stackFileName !== selectedStackFileName
|
|
194
200
|
)))
|
|
195
|
-
:
|
|
196
|
-
(stackFileName) => stackFileNames.includes(stackFileName) && stackFileName !== selectedStackFileName
|
|
197
|
-
)));
|
|
201
|
+
: [];
|
|
198
202
|
|
|
199
|
-
const selectedBlueprintFileName = blueprintFileNames.includes(existingOnboardingReport?.selectedBlueprint)
|
|
203
|
+
const selectedBlueprintFileName = hasExplicitArchitectureConstraint && blueprintFileNames.includes(existingOnboardingReport?.selectedBlueprint)
|
|
200
204
|
? existingOnboardingReport.selectedBlueprint
|
|
201
|
-
:
|
|
205
|
+
: AGENT_DECISION_BLUEPRINT_FILE_NAME;
|
|
202
206
|
|
|
203
|
-
const selectedAdditionalBlueprintFileNames = Array.isArray(existingOnboardingReport?.selectedAdditionalBlueprints)
|
|
207
|
+
const selectedAdditionalBlueprintFileNames = hasExplicitArchitectureConstraint && Array.isArray(existingOnboardingReport?.selectedAdditionalBlueprints)
|
|
204
208
|
? Array.from(new Set(existingOnboardingReport.selectedAdditionalBlueprints.filter(
|
|
205
209
|
(blueprintFileName) => blueprintFileNames.includes(blueprintFileName) && blueprintFileName !== selectedBlueprintFileName
|
|
206
210
|
)))
|
|
207
|
-
:
|
|
208
|
-
.map((stackFileName) => BLUEPRINT_RECOMMENDATIONS[stackFileName] || null)
|
|
209
|
-
.filter((blueprintFileName) => blueprintFileName && blueprintFileName !== selectedBlueprintFileName)));
|
|
211
|
+
: [];
|
|
210
212
|
|
|
211
213
|
const includeCiGuardrails = typeof existingOnboardingReport?.ciGuardrailsEnabled === 'boolean'
|
|
212
214
|
? existingOnboardingReport.ciGuardrailsEnabled
|
|
@@ -269,10 +271,10 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
|
|
|
269
271
|
};
|
|
270
272
|
|
|
271
273
|
console.log('\nExisting project detection transparency:');
|
|
272
|
-
if (projectDetection.
|
|
274
|
+
if (projectDetection.detectedStackFileName) {
|
|
273
275
|
const confidenceScoreLabel = Number(projectDetection.confidenceScore || 0).toFixed(2);
|
|
274
276
|
console.log(
|
|
275
|
-
`- Detected stack: ${toTitleCase(projectDetection.
|
|
277
|
+
`- Detected stack: ${toTitleCase(projectDetection.detectedStackFileName)} (${projectDetection.confidenceLabel}, score ${confidenceScoreLabel})`
|
|
276
278
|
);
|
|
277
279
|
} else {
|
|
278
280
|
console.log('- Detected stack: unresolved (insufficient markers).');
|
|
@@ -312,11 +314,11 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
|
|
|
312
314
|
|
|
313
315
|
console.log('\nUpgrade preview:');
|
|
314
316
|
console.log(`- Target directory: ${resolvedTargetDirectoryPath}`);
|
|
315
|
-
console.log(`-
|
|
317
|
+
console.log(`- Runtime decision: ${selectedStackFileName === AGENT_DECISION_STACK_FILE_NAME ? 'agent recommendation required from repo evidence' : toTitleCase(selectedStackFileName)}`);
|
|
316
318
|
if (selectedAdditionalStackFileNames.length > 0) {
|
|
317
319
|
console.log(`- Additional stacks: ${selectedAdditionalStackFileNames.map((stackFileName) => toTitleCase(stackFileName)).join(', ')}`);
|
|
318
320
|
}
|
|
319
|
-
console.log(`-
|
|
321
|
+
console.log(`- Architecture decision: ${selectedBlueprintFileName === AGENT_DECISION_BLUEPRINT_FILE_NAME ? 'agent recommendation required from repo evidence' : toTitleCase(selectedBlueprintFileName)}`);
|
|
320
322
|
if (selectedAdditionalBlueprintFileNames.length > 0) {
|
|
321
323
|
console.log(`- Additional blueprints: ${selectedAdditionalBlueprintFileNames.map((blueprintFileName) => toTitleCase(blueprintFileName)).join(', ')}`);
|
|
322
324
|
}
|
|
@@ -355,7 +357,7 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
|
|
|
355
357
|
const detectedVersionLabel = staleDoc.detectedTemplateVersion || 'missing';
|
|
356
358
|
console.log(`- docs/${staleDoc.fileName} (detected: ${detectedVersionLabel}, expected: ${projectDocStalenessReport.expectedTemplateVersion})`);
|
|
357
359
|
}
|
|
358
|
-
console.log('
|
|
360
|
+
console.log('Required action: regenerate docs with init --scaffold-docs or update the files manually to match the latest template version.');
|
|
359
361
|
}
|
|
360
362
|
|
|
361
363
|
if (uiScopeSignals.isUiScopeLikely && missingDesignContractPaths.length > 0) {
|
|
@@ -372,7 +374,7 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
|
|
|
372
374
|
if (shouldSeedDesignIntentOnApply) {
|
|
373
375
|
console.log('- Planned seed on apply: docs/design-intent.json');
|
|
374
376
|
}
|
|
375
|
-
console.log('
|
|
377
|
+
console.log('Required action: create or refresh docs/DESIGN.md and docs/design-intent.json before allowing UI implementation work.');
|
|
376
378
|
console.log('Upgrade synchronizes governance assets and can seed docs/design-intent.json, but it does not author project-specific docs/DESIGN.md automatically.');
|
|
377
379
|
}
|
|
378
380
|
|
package/lib/cli/compiler.mjs
CHANGED
|
@@ -8,7 +8,8 @@ import path from 'node:path';
|
|
|
8
8
|
import {
|
|
9
9
|
CLI_VERSION,
|
|
10
10
|
POLICY_FILE_NAME,
|
|
11
|
-
|
|
11
|
+
AGENT_DECISION_STACK_FILE_NAME,
|
|
12
|
+
AGENT_DECISION_BLUEPRINT_FILE_NAME,
|
|
12
13
|
} from './constants.mjs';
|
|
13
14
|
|
|
14
15
|
import {
|
|
@@ -49,10 +50,11 @@ export async function writeOnboardingReport({
|
|
|
49
50
|
operationMode = 'init',
|
|
50
51
|
tokenOptimization = undefined,
|
|
51
52
|
memoryContinuity = undefined,
|
|
52
|
-
architectRecommendation = null,
|
|
53
53
|
detectionTransparency = null,
|
|
54
54
|
uiScopeSignals = null,
|
|
55
55
|
}) {
|
|
56
|
+
const hasExplicitRuntimeDecision = selectedStackFileName && selectedStackFileName !== AGENT_DECISION_STACK_FILE_NAME;
|
|
57
|
+
const hasExplicitArchitectureDecision = selectedBlueprintFileName && selectedBlueprintFileName !== AGENT_DECISION_BLUEPRINT_FILE_NAME;
|
|
56
58
|
const onboardingReportPath = path.join(targetDirectoryPath, '.agent-context', 'state', 'onboarding-report.json');
|
|
57
59
|
const resolvedTokenOptimization = typeof tokenOptimization === 'undefined'
|
|
58
60
|
? await readTokenOptimizationState(targetDirectoryPath)
|
|
@@ -68,32 +70,39 @@ export async function writeOnboardingReport({
|
|
|
68
70
|
selectedPreset,
|
|
69
71
|
projectScope,
|
|
70
72
|
projectTopology,
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
runtimeDecision: {
|
|
74
|
+
mode: hasExplicitRuntimeDecision ? 'explicit-constraint' : 'agent-decision-required',
|
|
75
|
+
explicitStack: hasExplicitRuntimeDecision ? selectedStackFileName : null,
|
|
76
|
+
detectedStackEvidence: projectDetection.detectedStackFileName || null,
|
|
77
|
+
detectedAdditionalStackEvidence: projectDetection.secondaryStackFileNames || [],
|
|
78
|
+
},
|
|
79
|
+
architectureDecision: {
|
|
80
|
+
mode: hasExplicitArchitectureDecision ? 'explicit-constraint' : 'agent-decision-required',
|
|
81
|
+
explicitBlueprint: hasExplicitArchitectureDecision ? selectedBlueprintFileName : null,
|
|
82
|
+
detectedBlueprintEvidence: projectDetection.detectedBlueprintFileName || null,
|
|
83
|
+
},
|
|
84
|
+
selectedStack: hasExplicitRuntimeDecision ? selectedStackFileName : null,
|
|
85
|
+
selectedAdditionalStacks: hasExplicitRuntimeDecision ? selectedAdditionalStackFileNames : [],
|
|
86
|
+
selectedBlueprint: hasExplicitArchitectureDecision ? selectedBlueprintFileName : null,
|
|
87
|
+
selectedAdditionalBlueprints: hasExplicitArchitectureDecision ? selectedAdditionalBlueprintFileNames : [],
|
|
75
88
|
ruleLoadingPolicy: {
|
|
76
89
|
canonicalSource: '.instructions.md',
|
|
77
90
|
stackLoadingMode: 'lazy',
|
|
78
91
|
loadedOnDemand: true,
|
|
79
|
-
primaryStack: selectedStackFileName,
|
|
80
|
-
additionalStacks: selectedAdditionalStackFileNames,
|
|
92
|
+
primaryStack: hasExplicitRuntimeDecision ? selectedStackFileName : null,
|
|
93
|
+
additionalStacks: hasExplicitRuntimeDecision ? selectedAdditionalStackFileNames : [],
|
|
94
|
+
agentDecisionRequired: !hasExplicitRuntimeDecision,
|
|
81
95
|
},
|
|
82
96
|
ciGuardrailsEnabled: includeCiGuardrails,
|
|
83
97
|
setupDurationMs,
|
|
84
98
|
runtimeEnvironment,
|
|
85
99
|
tokenOptimization: resolvedTokenOptimization,
|
|
86
100
|
memoryContinuity: resolvedMemoryContinuity,
|
|
87
|
-
architectRecommendation,
|
|
88
101
|
autoDetection: {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
? projectDetection.secondaryStackFileNames
|
|
94
|
-
.map((secondaryStackFileName) => BLUEPRINT_RECOMMENDATIONS[secondaryStackFileName] || null)
|
|
95
|
-
.filter(Boolean)
|
|
96
|
-
: [],
|
|
102
|
+
detectedStack: projectDetection.detectedStackFileName,
|
|
103
|
+
detectedAdditionalStacks: projectDetection.secondaryStackFileNames || [],
|
|
104
|
+
detectedBlueprint: projectDetection.detectedBlueprintFileName,
|
|
105
|
+
detectedAdditionalBlueprints: [],
|
|
97
106
|
confidenceLabel: projectDetection.confidenceLabel,
|
|
98
107
|
confidenceScore: projectDetection.confidenceScore,
|
|
99
108
|
confidenceGap: projectDetection.confidenceGap,
|
|
@@ -151,6 +160,8 @@ export async function buildCompiledRulesContent({
|
|
|
151
160
|
const availableStackProfileFileNames = new Set(await collectFileNames(selectedStacksDirectoryPath));
|
|
152
161
|
const availableBlueprintProfileFileNames = new Set(await collectFileNames(selectedBlueprintsDirectoryPath));
|
|
153
162
|
const contextBlocks = [];
|
|
163
|
+
const hasExplicitRuntimeDecision = selectedStackFileName && selectedStackFileName !== AGENT_DECISION_STACK_FILE_NAME;
|
|
164
|
+
const hasExplicitArchitectureDecision = selectedBlueprintFileName && selectedBlueprintFileName !== AGENT_DECISION_BLUEPRINT_FILE_NAME;
|
|
154
165
|
|
|
155
166
|
function firstMarkdownHeading(content, fallbackLabel) {
|
|
156
167
|
const headingLine = content
|
|
@@ -174,11 +185,11 @@ export async function buildCompiledRulesContent({
|
|
|
174
185
|
contextBlocks.push(
|
|
175
186
|
[
|
|
176
187
|
'## BOOTSTRAP CHAIN (MANDATORY)',
|
|
177
|
-
'
|
|
188
|
+
'Resolve the smallest relevant layer set before responding. Do not eagerly load unrelated layers:',
|
|
178
189
|
'1. .agent-context/rules/',
|
|
179
|
-
'2. Resolve
|
|
190
|
+
'2. Resolve runtime and architecture signals from project context, repo evidence, and live research.',
|
|
180
191
|
'3. .agent-context/prompts/',
|
|
181
|
-
'4. Dynamic
|
|
192
|
+
'4. Dynamic runtime and architecture decision signals (from project context + research evidence)',
|
|
182
193
|
'5. .agent-context/state/',
|
|
183
194
|
`6. .agent-context/policies/${POLICY_FILE_NAME}`,
|
|
184
195
|
'7. docs/ project context (or bootstrap prompts when docs are not materialized)',
|
|
@@ -191,31 +202,43 @@ export async function buildCompiledRulesContent({
|
|
|
191
202
|
|
|
192
203
|
contextBlocks.push(
|
|
193
204
|
[
|
|
194
|
-
'## LAYER 1:
|
|
195
|
-
'
|
|
205
|
+
'## LAYER 1: RULES (SCOPE-RESOLVED)',
|
|
206
|
+
'Available rule files under .agent-context/rules/:',
|
|
196
207
|
...universalRuleFileNames.map((universalRuleFileName, index) => `${index + 1}. .agent-context/rules/${universalRuleFileName}`),
|
|
197
208
|
'',
|
|
198
|
-
'
|
|
209
|
+
'Resolution policy: load only the rule files relevant to the current task and prioritize data safety and API contract integrity first, then writing polish.',
|
|
199
210
|
].join('\n')
|
|
200
211
|
);
|
|
201
212
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
213
|
+
if (hasExplicitRuntimeDecision) {
|
|
214
|
+
const stackFilePath = path.join(selectedStacksDirectoryPath, selectedStackFileName);
|
|
215
|
+
const hasStackProfileFile = availableStackProfileFileNames.has(selectedStackFileName);
|
|
216
|
+
const stackSummary = hasStackProfileFile
|
|
217
|
+
? firstMarkdownHeading(await fs.readFile(stackFilePath, 'utf8'), selectedStackFileName)
|
|
218
|
+
: `Explicit runtime constraint for ${humanizeProfileName(selectedStackFileName)}.`;
|
|
219
|
+
contextBlocks.push(
|
|
220
|
+
[
|
|
221
|
+
`## LAYER 2: RUNTIME CONSTRAINT (${selectedStackFileName})`,
|
|
222
|
+
hasStackProfileFile
|
|
223
|
+
? `Source: stack-profile:${selectedStackFileName}`
|
|
224
|
+
: 'Source: explicit user constraint',
|
|
225
|
+
`Summary: ${stackSummary}`,
|
|
226
|
+
'Use this only as a constraint when the task touches that runtime. Do not treat it as design direction.',
|
|
227
|
+
].join('\n')
|
|
228
|
+
);
|
|
229
|
+
} else {
|
|
230
|
+
contextBlocks.push(
|
|
231
|
+
[
|
|
232
|
+
'## LAYER 2: RUNTIME DECISION REQUIRED',
|
|
233
|
+
'No runtime stack was selected by the user.',
|
|
234
|
+
'For a fresh project, the first implementation step is to ask the AI agent to recommend a runtime/framework from the brief, constraints, and live official documentation.',
|
|
235
|
+
'For an existing project, inspect repo markers and current files directly before editing. Detection evidence is not a migration instruction.',
|
|
236
|
+
'Do not silently choose a stack from offline defaults.',
|
|
237
|
+
].join('\n')
|
|
238
|
+
);
|
|
239
|
+
}
|
|
217
240
|
|
|
218
|
-
if (normalizedAdditionalStackFileNames.length > 0) {
|
|
241
|
+
if (hasExplicitRuntimeDecision && normalizedAdditionalStackFileNames.length > 0) {
|
|
219
242
|
contextBlocks.push(
|
|
220
243
|
[
|
|
221
244
|
'## LAYER 2B: ADDITIONAL STACK PROFILES',
|
|
@@ -234,9 +257,9 @@ export async function buildCompiledRulesContent({
|
|
|
234
257
|
contextBlocks.push(
|
|
235
258
|
[
|
|
236
259
|
'## LAYER 2 POLICY: LAZY RULE LOADING',
|
|
237
|
-
|
|
238
|
-
? `Primary
|
|
239
|
-
:
|
|
260
|
+
hasExplicitRuntimeDecision
|
|
261
|
+
? `Primary runtime constraint: ${selectedStackFileName}`
|
|
262
|
+
: 'Primary runtime constraint: unresolved until agent recommendation is approved',
|
|
240
263
|
normalizedAdditionalStackFileNames.length > 0
|
|
241
264
|
? `Additional stack profiles load on demand: ${normalizedAdditionalStackFileNames.map((stackFileName) => {
|
|
242
265
|
if (availableStackProfileFileNames.has(stackFileName)) {
|
|
@@ -245,9 +268,9 @@ export async function buildCompiledRulesContent({
|
|
|
245
268
|
|
|
246
269
|
return `${stackFileName} (dynamic signal)`;
|
|
247
270
|
}).join(', ')}`
|
|
248
|
-
: 'Additional
|
|
249
|
-
'Load
|
|
250
|
-
'Avoid eager loading unrelated
|
|
271
|
+
: 'Additional runtime guidance loads only when explicitly selected by the user or required by touched code.',
|
|
272
|
+
'Load runtime-specific guidance only when task scope touches that runtime.',
|
|
273
|
+
'Avoid eager loading unrelated runtime guidance to prevent instruction conflicts.',
|
|
251
274
|
].join('\n')
|
|
252
275
|
);
|
|
253
276
|
|
|
@@ -261,28 +284,39 @@ export async function buildCompiledRulesContent({
|
|
|
261
284
|
'4. .agent-context/prompts/bootstrap-design.md -> ui, ux, layout, screen, tailwind, frontend, redesign',
|
|
262
285
|
'UI trigger policy:',
|
|
263
286
|
'- Load .agent-context/prompts/bootstrap-design.md and .agent-context/rules/frontend-architecture.md first.',
|
|
264
|
-
'- Keep UI-only requests context-isolated and do not eagerly load backend-only rules such as database-design.md, docker-runtime.md,
|
|
287
|
+
'- Keep UI-only requests context-isolated and do not eagerly load backend-only rules such as database-design.md, docker-runtime.md, microservices.md, git-workflow.md, or general implementation-theory rules unless the task explicitly crosses those boundaries.',
|
|
265
288
|
'- For UI scope, materialize docs/DESIGN.md and docs/design-intent.json before implementing UI surfaces.',
|
|
266
289
|
].join('\n')
|
|
267
290
|
);
|
|
268
291
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
292
|
+
if (hasExplicitArchitectureDecision) {
|
|
293
|
+
const blueprintFilePath = path.join(selectedBlueprintsDirectoryPath, selectedBlueprintFileName);
|
|
294
|
+
const hasBlueprintProfileFile = availableBlueprintProfileFileNames.has(selectedBlueprintFileName);
|
|
295
|
+
const blueprintSummary = hasBlueprintProfileFile
|
|
296
|
+
? firstMarkdownHeading(await fs.readFile(blueprintFilePath, 'utf8'), selectedBlueprintFileName)
|
|
297
|
+
: `Explicit architecture constraint for ${humanizeProfileName(selectedBlueprintFileName)}.`;
|
|
298
|
+
contextBlocks.push(
|
|
299
|
+
[
|
|
300
|
+
`## LAYER 3: ARCHITECTURE CONSTRAINT (${selectedBlueprintFileName})`,
|
|
301
|
+
hasBlueprintProfileFile
|
|
302
|
+
? `Source: architecture-profile:${selectedBlueprintFileName}`
|
|
303
|
+
: 'Source: explicit user constraint',
|
|
304
|
+
`Summary: ${blueprintSummary}`,
|
|
305
|
+
'Use this only as an explicit constraint when scaffolding or changing architecture boundaries.',
|
|
306
|
+
].join('\n')
|
|
307
|
+
);
|
|
308
|
+
} else {
|
|
309
|
+
contextBlocks.push(
|
|
310
|
+
[
|
|
311
|
+
'## LAYER 3: ARCHITECTURE DECISION REQUIRED',
|
|
312
|
+
'No architecture blueprint was selected by the user.',
|
|
313
|
+
'The AI agent must propose the architecture from the product brief, repo evidence, required docs, and live research before implementation.',
|
|
314
|
+
'Do not map detected runtime markers into a blueprint automatically.',
|
|
315
|
+
].join('\n')
|
|
316
|
+
);
|
|
317
|
+
}
|
|
284
318
|
|
|
285
|
-
if (normalizedAdditionalBlueprintFileNames.length > 0) {
|
|
319
|
+
if (hasExplicitArchitectureDecision && normalizedAdditionalBlueprintFileNames.length > 0) {
|
|
286
320
|
contextBlocks.push(
|
|
287
321
|
[
|
|
288
322
|
'## LAYER 3A: ADDITIONAL BLUEPRINT PROFILES',
|
package/lib/cli/constants.mjs
CHANGED
|
@@ -17,128 +17,54 @@ export const POLICY_FILE_NAME = 'llm-judge-threshold.json';
|
|
|
17
17
|
|
|
18
18
|
export const ALLOWED_SEVERITY_LEVELS = new Set(['critical', 'high', 'medium', 'low']);
|
|
19
19
|
|
|
20
|
-
export const
|
|
21
|
-
|
|
22
|
-
'python.md': 'fastapi-service.md',
|
|
23
|
-
'java.md': 'spring-boot-api.md',
|
|
24
|
-
'php.md': 'laravel-api.md',
|
|
25
|
-
'go.md': 'go-service.md',
|
|
26
|
-
'csharp.md': 'aspnet-api.md',
|
|
27
|
-
'react-native.md': 'mobile-app.md',
|
|
28
|
-
'flutter.md': 'mobile-app.md',
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
export const FALLBACK_STACK_FILE_NAMES = [
|
|
32
|
-
'typescript.md',
|
|
33
|
-
'python.md',
|
|
34
|
-
'go.md',
|
|
35
|
-
'java.md',
|
|
36
|
-
'php.md',
|
|
37
|
-
'csharp.md',
|
|
38
|
-
'rust.md',
|
|
39
|
-
'ruby.md',
|
|
40
|
-
'react-native.md',
|
|
41
|
-
'flutter.md',
|
|
42
|
-
];
|
|
43
|
-
|
|
44
|
-
export const FALLBACK_BLUEPRINT_FILE_NAMES = [
|
|
45
|
-
'api-nextjs.md',
|
|
46
|
-
'nestjs-logic.md',
|
|
47
|
-
'fastapi-service.md',
|
|
48
|
-
'spring-boot-api.md',
|
|
49
|
-
'go-service.md',
|
|
50
|
-
'aspnet-api.md',
|
|
51
|
-
'laravel-api.md',
|
|
52
|
-
'graphql-grpc-api.md',
|
|
53
|
-
'ci-github-actions.md',
|
|
54
|
-
'ci-gitlab.md',
|
|
55
|
-
'kubernetes-manifests.md',
|
|
56
|
-
'infrastructure-as-code.md',
|
|
57
|
-
'observability.md',
|
|
58
|
-
'mobile-app.md',
|
|
59
|
-
];
|
|
20
|
+
export const AGENT_DECISION_STACK_FILE_NAME = 'agent-decision-runtime.md';
|
|
21
|
+
export const AGENT_DECISION_BLUEPRINT_FILE_NAME = 'agent-decision-architecture.md';
|
|
60
22
|
|
|
61
23
|
export const INIT_PRESETS = {
|
|
62
|
-
'frontend-
|
|
63
|
-
stack:
|
|
64
|
-
blueprint:
|
|
24
|
+
'frontend-ui': {
|
|
25
|
+
stack: null,
|
|
26
|
+
blueprint: null,
|
|
65
27
|
ci: true,
|
|
66
|
-
description: 'Frontend
|
|
28
|
+
description: 'Frontend/UI scope hint; agent recommends runtime and architecture before coding',
|
|
67
29
|
},
|
|
68
|
-
'backend-
|
|
69
|
-
stack:
|
|
70
|
-
blueprint:
|
|
30
|
+
'backend-service': {
|
|
31
|
+
stack: null,
|
|
32
|
+
blueprint: null,
|
|
71
33
|
ci: true,
|
|
72
|
-
description: 'Backend
|
|
34
|
+
description: 'Backend/API scope hint; agent recommends runtime and architecture before coding',
|
|
73
35
|
},
|
|
74
36
|
'fullstack-product': {
|
|
75
|
-
stack:
|
|
76
|
-
blueprint:
|
|
77
|
-
ci: true,
|
|
78
|
-
description: 'Product delivery starter with fullstack governance',
|
|
79
|
-
},
|
|
80
|
-
'platform-governance': {
|
|
81
|
-
stack: 'go.md',
|
|
82
|
-
blueprint: 'go-service.md',
|
|
83
|
-
ci: true,
|
|
84
|
-
description: 'Platform and delivery starter with Go service defaults',
|
|
85
|
-
},
|
|
86
|
-
'mobile-react-native': {
|
|
87
|
-
stack: 'react-native.md',
|
|
88
|
-
blueprint: 'mobile-app.md',
|
|
89
|
-
ci: true,
|
|
90
|
-
description: 'Mobile app starter for React Native',
|
|
91
|
-
},
|
|
92
|
-
'mobile-flutter': {
|
|
93
|
-
stack: 'flutter.md',
|
|
94
|
-
blueprint: 'mobile-app.md',
|
|
95
|
-
ci: true,
|
|
96
|
-
description: 'Mobile app starter for Flutter',
|
|
97
|
-
},
|
|
98
|
-
'observability-platform': {
|
|
99
|
-
stack: 'go.md',
|
|
100
|
-
blueprint: 'observability.md',
|
|
101
|
-
ci: true,
|
|
102
|
-
description: 'Observability and platform starter',
|
|
103
|
-
},
|
|
104
|
-
'typescript-nestjs-service': {
|
|
105
|
-
stack: 'typescript.md',
|
|
106
|
-
blueprint: 'nestjs-logic.md',
|
|
107
|
-
ci: true,
|
|
108
|
-
description: 'TypeScript service starter with NestJS module blueprint',
|
|
109
|
-
},
|
|
110
|
-
'java-enterprise-api': {
|
|
111
|
-
stack: 'java.md',
|
|
112
|
-
blueprint: 'spring-boot-api.md',
|
|
37
|
+
stack: null,
|
|
38
|
+
blueprint: null,
|
|
113
39
|
ci: true,
|
|
114
|
-
description: '
|
|
40
|
+
description: 'Fullstack product scope hint; agent recommends runtime and architecture before coding',
|
|
115
41
|
},
|
|
116
|
-
'
|
|
117
|
-
stack:
|
|
118
|
-
blueprint:
|
|
42
|
+
'mobile-app': {
|
|
43
|
+
stack: null,
|
|
44
|
+
blueprint: null,
|
|
119
45
|
ci: true,
|
|
120
|
-
description: '
|
|
46
|
+
description: 'Mobile app scope hint; agent recommends native strategy before coding',
|
|
121
47
|
},
|
|
122
|
-
'
|
|
123
|
-
stack:
|
|
124
|
-
blueprint:
|
|
48
|
+
'platform-ops': {
|
|
49
|
+
stack: null,
|
|
50
|
+
blueprint: null,
|
|
125
51
|
ci: true,
|
|
126
|
-
description: '
|
|
52
|
+
description: 'Platform operations scope hint; agent recommends runtime and architecture before coding',
|
|
127
53
|
},
|
|
128
|
-
|
|
129
|
-
stack:
|
|
130
|
-
blueprint:
|
|
54
|
+
observability: {
|
|
55
|
+
stack: null,
|
|
56
|
+
blueprint: null,
|
|
131
57
|
ci: true,
|
|
132
|
-
description: '
|
|
58
|
+
description: 'Observability scope hint; agent recommends runtime and architecture before coding',
|
|
133
59
|
},
|
|
134
60
|
};
|
|
135
61
|
|
|
136
62
|
export const PROFILE_PRESETS = {
|
|
137
63
|
beginner: {
|
|
138
64
|
displayName: 'Beginner',
|
|
139
|
-
description: 'Safest path. Minimal decisions,
|
|
140
|
-
defaultStackFileName:
|
|
141
|
-
defaultBlueprintFileName:
|
|
65
|
+
description: 'Safest path. Minimal decisions, agent-led stack decision, and CI enabled.',
|
|
66
|
+
defaultStackFileName: null,
|
|
67
|
+
defaultBlueprintFileName: null,
|
|
142
68
|
defaultCi: true,
|
|
143
69
|
lockCi: true,
|
|
144
70
|
blockingSeverities: ['critical'],
|
|
@@ -180,40 +106,6 @@ export const PROJECT_SCOPE_CHOICES = [
|
|
|
180
106
|
},
|
|
181
107
|
];
|
|
182
108
|
|
|
183
|
-
export const PROJECT_SCOPE_STACK_FILTERS = {
|
|
184
|
-
'frontend-only': ['typescript.md'],
|
|
185
|
-
'backend-only': ['typescript.md', 'python.md', 'go.md', 'java.md', 'php.md', 'csharp.md', 'ruby.md', 'rust.md'],
|
|
186
|
-
both: ['typescript.md', 'python.md', 'go.md', 'java.md', 'php.md', 'csharp.md', 'ruby.md', 'rust.md'],
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
export const WEB_FRONTEND_STACK_CANDIDATES = ['typescript.md'];
|
|
190
|
-
|
|
191
|
-
export const WEB_BACKEND_STACK_CANDIDATES = [
|
|
192
|
-
'typescript.md',
|
|
193
|
-
'python.md',
|
|
194
|
-
'go.md',
|
|
195
|
-
'java.md',
|
|
196
|
-
'php.md',
|
|
197
|
-
'csharp.md',
|
|
198
|
-
'ruby.md',
|
|
199
|
-
'rust.md',
|
|
200
|
-
];
|
|
201
|
-
|
|
202
|
-
export const WEB_FRONTEND_BLUEPRINT_CANDIDATES = [
|
|
203
|
-
'api-nextjs.md',
|
|
204
|
-
];
|
|
205
|
-
|
|
206
|
-
export const WEB_BACKEND_BLUEPRINT_CANDIDATES = [
|
|
207
|
-
'nestjs-logic.md',
|
|
208
|
-
'fastapi-service.md',
|
|
209
|
-
'go-service.md',
|
|
210
|
-
'spring-boot-api.md',
|
|
211
|
-
'laravel-api.md',
|
|
212
|
-
'aspnet-api.md',
|
|
213
|
-
'graphql-grpc-api.md',
|
|
214
|
-
'api-nextjs.md',
|
|
215
|
-
];
|
|
216
|
-
|
|
217
109
|
export const RUNTIME_ENVIRONMENT_CHOICES = [
|
|
218
110
|
{
|
|
219
111
|
key: 'linux-wsl',
|