@ryuenn3123/agentic-senior-core 3.0.37 → 3.0.39
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 +109 -146
- package/.agent-context/rules/frontend-architecture.md +92 -108
- package/.agent-context/state/README.md +26 -0
- package/.agent-context/state/architecture-map.md +32 -17
- package/.agent-context/state/dependency-map.md +31 -22
- package/.cursor/mcp.json +10 -0
- package/.cursor/rules/agentic-senior-core.mdc +48 -0
- package/.cursorrules +22 -88
- package/.gemini/instructions.md +25 -16
- package/.github/copilot-instructions.md +25 -16
- package/.github/instructions/agentic-senior-core.instructions.md +47 -0
- package/.instructions.md +98 -207
- package/.windsurf/rules/agentic-senior-core.md +43 -0
- package/.windsurfrules +22 -88
- package/AGENTS.md +23 -26
- package/CLAUDE.md +43 -0
- package/CONTRIBUTING.md +7 -2
- package/GEMINI.md +43 -0
- package/README.md +25 -7
- package/lib/cli/backup.mjs +4 -4
- package/lib/cli/commands/init/project-context.mjs +101 -0
- package/lib/cli/commands/init/runtime-environment.mjs +59 -0
- package/lib/cli/commands/init/setup-decisions.mjs +83 -0
- package/lib/cli/commands/init.mjs +33 -250
- package/lib/cli/commands/optimize.mjs +1 -1
- package/lib/cli/commands/upgrade.mjs +34 -16
- package/lib/cli/compiler.mjs +59 -17
- package/lib/cli/constants.mjs +5 -0
- package/lib/cli/detector.mjs +4 -0
- package/lib/cli/init-detection-flow.mjs +9 -1
- package/lib/cli/init-selection.mjs +0 -5
- package/lib/cli/preflight.mjs +3 -3
- package/lib/cli/project-scaffolder/design-contract/validation.mjs +789 -0
- package/lib/cli/project-scaffolder/design-contract.mjs +119 -924
- package/lib/cli/project-scaffolder/prompt-builders.mjs +69 -84
- package/lib/cli/project-scaffolder.mjs +0 -2
- package/lib/cli/utils/filesystem.mjs +79 -0
- package/lib/cli/utils/managed-surface.mjs +237 -0
- package/lib/cli/utils/prompting.mjs +44 -0
- package/lib/cli/utils.mjs +33 -335
- package/package.json +21 -2
- package/scripts/bump-version.mjs +15 -13
- package/scripts/clean-local-artifacts.mjs +76 -0
- package/scripts/docs-quality-drift-report.mjs +5 -0
- package/scripts/frontend-usability-audit.mjs +23 -19
- package/scripts/governance-weekly-report.mjs +37 -15
- package/scripts/single-source-lazy-loading-audit.mjs +24 -0
- package/scripts/sync-thin-adapters.mjs +99 -129
- package/scripts/v3-purge-audit.mjs +5 -0
- package/scripts/validate/config.mjs +10 -0
- package/scripts/validate/coverage-checks.mjs +55 -0
- package/scripts/validate.mjs +20 -0
- package/.agent-context/marketplace/trust-tiers.json +0 -114
- package/.agent-context/state/benchmark-analysis.json +0 -431
- package/.agent-context/state/benchmark-evidence-bundle.json +0 -1040
- package/.agent-context/state/benchmark-history.json +0 -75
- package/.agent-context/state/benchmark-trend-report.csv +0 -5
- package/.agent-context/state/benchmark-trend-report.json +0 -140
- package/.agent-context/state/benchmark-writer-judge-matrix.json +0 -462
- package/.agent-context/state/memory-continuity-benchmark.json +0 -132
- package/.agent-context/state/onboarding-report.json +0 -102
- package/.agent-context/state/quality-trend-report.json +0 -89
- package/.agent-context/state/token-optimization-benchmark.json +0 -130
- package/.agent-context/state/weekly-governance-report.json +0 -329
- package/lib/cli/compatibility.mjs +0 -124
- package/scripts/validate-evidence-bundle.mjs +0 -76
|
@@ -8,7 +8,6 @@ import fs from 'node:fs/promises';
|
|
|
8
8
|
import path from 'node:path';
|
|
9
9
|
|
|
10
10
|
import {
|
|
11
|
-
PROJECT_SCOPE_CHOICES,
|
|
12
11
|
CLI_VERSION,
|
|
13
12
|
AGENT_CONTEXT_DIR,
|
|
14
13
|
INIT_PRESETS,
|
|
@@ -16,15 +15,12 @@ import {
|
|
|
16
15
|
GOLDEN_STANDARD_PROFILE_NAME,
|
|
17
16
|
AGENT_DECISION_STACK_FILE_NAME,
|
|
18
17
|
AGENT_DECISION_BLUEPRINT_FILE_NAME,
|
|
19
|
-
RUNTIME_ENVIRONMENT_CHOICES,
|
|
20
18
|
} from '../constants.mjs';
|
|
21
19
|
|
|
22
20
|
import {
|
|
23
21
|
ensureDirectory,
|
|
24
22
|
askYesNo,
|
|
25
23
|
toTitleCase,
|
|
26
|
-
matchFileNameFromInput,
|
|
27
|
-
normalizeChoiceInput,
|
|
28
24
|
collectFileNames,
|
|
29
25
|
formatBlockingSeverities,
|
|
30
26
|
formatDuration,
|
|
@@ -56,7 +52,6 @@ import {
|
|
|
56
52
|
hasExistingProjectDocs,
|
|
57
53
|
loadProjectConfig,
|
|
58
54
|
normalizeDocsLanguage,
|
|
59
|
-
buildDesignIntentSeedFromSignals,
|
|
60
55
|
} from '../project-scaffolder.mjs';
|
|
61
56
|
import { performRollback } from '../rollback.mjs';
|
|
62
57
|
import {
|
|
@@ -70,6 +65,21 @@ import {
|
|
|
70
65
|
ensureActiveMemorySnapshot,
|
|
71
66
|
writeMemoryContinuityState,
|
|
72
67
|
} from '../memory-continuity.mjs';
|
|
68
|
+
import {
|
|
69
|
+
buildInitExistingProjectDesignIntentSeed,
|
|
70
|
+
inferExistingProjectDescriptionHint,
|
|
71
|
+
} from './init/project-context.mjs';
|
|
72
|
+
import {
|
|
73
|
+
detectRuntimeEnvironment,
|
|
74
|
+
resolveRuntimeEnvironmentKeyFromLabel,
|
|
75
|
+
resolveRuntimeEnvironmentLabelFromKey,
|
|
76
|
+
} from './init/runtime-environment.mjs';
|
|
77
|
+
import {
|
|
78
|
+
inferProjectScopeFromDiscoveryAnswers,
|
|
79
|
+
normalizeExplicitProfileFileName,
|
|
80
|
+
resolveProjectScopeLabelFromKey,
|
|
81
|
+
resolveSilentCiGuardrailsDefault,
|
|
82
|
+
} from './init/setup-decisions.mjs';
|
|
73
83
|
|
|
74
84
|
export { REPO_ROOT } from '../constants.mjs';
|
|
75
85
|
export {
|
|
@@ -81,242 +91,11 @@ export {
|
|
|
81
91
|
normalizeAdditionalStackSelection,
|
|
82
92
|
normalizeAdditionalBlueprintSelection,
|
|
83
93
|
} from '../init-selection.mjs';
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
async function readTextIfExists(filePath) {
|
|
92
|
-
try {
|
|
93
|
-
return await fs.readFile(filePath, 'utf8');
|
|
94
|
-
} catch {
|
|
95
|
-
return '';
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
function extractMarkdownContext(rawMarkdown) {
|
|
100
|
-
return String(rawMarkdown || '')
|
|
101
|
-
.split(/\r?\n/)
|
|
102
|
-
.map((line) => normalizeContextLine(line.replace(/^#+\s*/, '')))
|
|
103
|
-
.filter((line) => line && !line.startsWith('---') && !line.startsWith('```'))
|
|
104
|
-
.slice(0, 3)
|
|
105
|
-
.join(' ');
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
async function inferExistingProjectDescriptionHint(targetDirectoryPath) {
|
|
109
|
-
const evidence = [];
|
|
110
|
-
const packageJsonContent = await readTextIfExists(path.join(targetDirectoryPath, 'package.json'));
|
|
111
|
-
|
|
112
|
-
if (packageJsonContent) {
|
|
113
|
-
try {
|
|
114
|
-
const packageManifest = JSON.parse(packageJsonContent);
|
|
115
|
-
const packageSummary = [
|
|
116
|
-
normalizeContextLine(packageManifest.name),
|
|
117
|
-
normalizeContextLine(packageManifest.description),
|
|
118
|
-
].filter(Boolean).join(': ');
|
|
119
|
-
|
|
120
|
-
if (packageSummary) {
|
|
121
|
-
evidence.push(`package.json: ${packageSummary}`);
|
|
122
|
-
}
|
|
123
|
-
} catch {
|
|
124
|
-
// Invalid package metadata should not block init; other files can still provide context.
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
for (const relativeDocPath of ['docs/project-brief.md', 'docs/README.md', 'README.md']) {
|
|
129
|
-
const docContext = extractMarkdownContext(
|
|
130
|
-
await readTextIfExists(path.join(targetDirectoryPath, relativeDocPath))
|
|
131
|
-
);
|
|
132
|
-
|
|
133
|
-
if (docContext) {
|
|
134
|
-
evidence.push(`${relativeDocPath}: ${docContext}`);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
return evidence.slice(0, 3).join(' | ');
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
export function resolveRuntimeEnvironmentKeyFromLabel(selectedRuntimeEnvironmentLabel) {
|
|
142
|
-
const runtimeEnvironmentEntry = RUNTIME_ENVIRONMENT_CHOICES.find(
|
|
143
|
-
(runtimeEnvironmentChoice) => runtimeEnvironmentChoice.label === selectedRuntimeEnvironmentLabel
|
|
144
|
-
);
|
|
145
|
-
|
|
146
|
-
return runtimeEnvironmentEntry?.key || null;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
export function resolveRuntimeEnvironmentLabelFromKey(runtimeEnvironmentKey) {
|
|
150
|
-
const runtimeEnvironmentEntry = RUNTIME_ENVIRONMENT_CHOICES.find(
|
|
151
|
-
(runtimeEnvironmentChoice) => runtimeEnvironmentChoice.key === runtimeEnvironmentKey
|
|
152
|
-
);
|
|
153
|
-
|
|
154
|
-
return runtimeEnvironmentEntry?.label || runtimeEnvironmentKey;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
export function detectRuntimeEnvironment() {
|
|
158
|
-
const isWslEnvironment = Boolean(process.env.WSL_DISTRO_NAME || process.env.WSL_INTEROP || process.env.__IS_WSL_TEST__);
|
|
159
|
-
|
|
160
|
-
if (isWslEnvironment) {
|
|
161
|
-
return {
|
|
162
|
-
key: 'linux-wsl',
|
|
163
|
-
label: resolveRuntimeEnvironmentLabelFromKey('linux-wsl'),
|
|
164
|
-
shellFamily: 'bash',
|
|
165
|
-
isAutoDetected: true,
|
|
166
|
-
source: 'WSL environment markers',
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
if (process.platform === 'win32') {
|
|
171
|
-
return {
|
|
172
|
-
key: 'windows',
|
|
173
|
-
label: resolveRuntimeEnvironmentLabelFromKey('windows'),
|
|
174
|
-
shellFamily: 'powershell',
|
|
175
|
-
isAutoDetected: true,
|
|
176
|
-
source: 'process.platform',
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
if (process.platform === 'darwin') {
|
|
181
|
-
return {
|
|
182
|
-
key: 'macos',
|
|
183
|
-
label: resolveRuntimeEnvironmentLabelFromKey('macos'),
|
|
184
|
-
shellFamily: 'bash',
|
|
185
|
-
isAutoDetected: true,
|
|
186
|
-
source: 'process.platform',
|
|
187
|
-
};
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
return {
|
|
191
|
-
key: 'linux',
|
|
192
|
-
label: resolveRuntimeEnvironmentLabelFromKey('linux'),
|
|
193
|
-
shellFamily: 'bash',
|
|
194
|
-
isAutoDetected: true,
|
|
195
|
-
source: 'process.platform',
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
function resolveProjectScopeLabelFromKey(projectScopeKey) {
|
|
200
|
-
return PROJECT_SCOPE_CHOICES.find((scopeChoice) => scopeChoice.key === projectScopeKey)?.label
|
|
201
|
-
|| PROJECT_SCOPE_CHOICES.find((scopeChoice) => scopeChoice.key === 'both')?.label
|
|
202
|
-
|| 'Both (frontend + backend)';
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
function inferProjectScopeFromDiscoveryAnswers(discoveryAnswers) {
|
|
206
|
-
const normalizedDomain = String(discoveryAnswers?.primaryDomain || '').trim().toLowerCase();
|
|
207
|
-
const normalizedDescription = [
|
|
208
|
-
discoveryAnswers?.projectDescription,
|
|
209
|
-
...(Array.isArray(discoveryAnswers?.features) ? discoveryAnswers.features : []),
|
|
210
|
-
].join(' ').toLowerCase();
|
|
211
|
-
|
|
212
|
-
if (
|
|
213
|
-
normalizedDomain.includes('api service')
|
|
214
|
-
|| normalizedDomain.includes('cli tool')
|
|
215
|
-
|| normalizedDomain.includes('library')
|
|
216
|
-
) {
|
|
217
|
-
return 'backend-only';
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
if (normalizedDomain.includes('mobile app')) {
|
|
221
|
-
return 'frontend-only';
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
if (normalizedDomain.includes('web application')) {
|
|
225
|
-
if (/(landing page|marketing site|showcase|portfolio|brochure|company profile)/.test(normalizedDescription)) {
|
|
226
|
-
return 'frontend-only';
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
return 'both';
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
return 'both';
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
function resolveSilentCiGuardrailsDefault({
|
|
236
|
-
initOptions,
|
|
237
|
-
selectedPreset,
|
|
238
|
-
selectedPolicyProfile,
|
|
239
|
-
}) {
|
|
240
|
-
if (typeof initOptions.ci === 'boolean') {
|
|
241
|
-
return {
|
|
242
|
-
value: initOptions.ci,
|
|
243
|
-
shouldAsk: false,
|
|
244
|
-
};
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
if (typeof selectedPreset?.ci === 'boolean') {
|
|
248
|
-
return {
|
|
249
|
-
value: selectedPreset.ci,
|
|
250
|
-
shouldAsk: false,
|
|
251
|
-
};
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
if (selectedPolicyProfile.lockCi) {
|
|
255
|
-
return {
|
|
256
|
-
value: selectedPolicyProfile.defaultCi,
|
|
257
|
-
shouldAsk: false,
|
|
258
|
-
};
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
return {
|
|
262
|
-
value: selectedPolicyProfile.defaultCi,
|
|
263
|
-
shouldAsk: true,
|
|
264
|
-
};
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
function normalizeExplicitProfileFileName(rawInput, discoveredFileNames) {
|
|
268
|
-
const matchedFileName = Array.isArray(discoveredFileNames) && discoveredFileNames.length > 0
|
|
269
|
-
? matchFileNameFromInput(rawInput, discoveredFileNames)
|
|
270
|
-
: null;
|
|
271
|
-
|
|
272
|
-
if (matchedFileName) {
|
|
273
|
-
return matchedFileName;
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
const normalizedBaseName = normalizeChoiceInput(String(rawInput || '').replace(/\.md$/i, ''));
|
|
277
|
-
return normalizedBaseName ? `${normalizedBaseName}.md` : null;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
function buildInitExistingProjectDesignIntentSeed({
|
|
281
|
-
targetDirectoryPath,
|
|
282
|
-
packageManifest,
|
|
283
|
-
selectedStackFileName,
|
|
284
|
-
selectedBlueprintFileName,
|
|
285
|
-
uiScopeSignals,
|
|
286
|
-
projectDescriptionHint,
|
|
287
|
-
}) {
|
|
288
|
-
const projectName = String(packageManifest?.name || path.basename(targetDirectoryPath)).trim() || 'existing-ui-project';
|
|
289
|
-
const isMobileUiProject = String(selectedStackFileName || '').toLowerCase().includes('react-native')
|
|
290
|
-
|| String(selectedStackFileName || '').toLowerCase().includes('flutter')
|
|
291
|
-
|| uiScopeSignals.signalReasons.some((signalReason) => signalReason.includes('android') || signalReason.includes('ios'));
|
|
292
|
-
const resolvedDomain = isMobileUiProject ? 'Mobile app' : 'Web application';
|
|
293
|
-
const projectDescription = String(packageManifest?.description || projectDescriptionHint || '').trim()
|
|
294
|
-
|| `Existing ${resolvedDomain.toLowerCase()} detected during init. Create a project-specific dynamic design contract before shipping new UI work.`;
|
|
295
|
-
|
|
296
|
-
return buildDesignIntentSeedFromSignals({
|
|
297
|
-
projectName,
|
|
298
|
-
projectDescription,
|
|
299
|
-
primaryDomain: resolvedDomain,
|
|
300
|
-
features: [],
|
|
301
|
-
initContext: {
|
|
302
|
-
stackFileName: selectedStackFileName,
|
|
303
|
-
blueprintFileName: selectedBlueprintFileName,
|
|
304
|
-
},
|
|
305
|
-
status: 'seed-generated-during-init',
|
|
306
|
-
supplementalFields: {
|
|
307
|
-
initSignals: {
|
|
308
|
-
detectedFrom: uiScopeSignals.signalReasons,
|
|
309
|
-
generatedBy: 'init-existing-project-seed',
|
|
310
|
-
},
|
|
311
|
-
repoEvidence: {
|
|
312
|
-
uiSignalReasons: uiScopeSignals.signalReasons,
|
|
313
|
-
frontendMetrics: uiScopeSignals.frontendEvidenceMetrics || null,
|
|
314
|
-
designEvidenceSummary: uiScopeSignals.designEvidenceSummary || null,
|
|
315
|
-
workspaceUiEntries: uiScopeSignals.workspaceUiEntries || [],
|
|
316
|
-
},
|
|
317
|
-
},
|
|
318
|
-
});
|
|
319
|
-
}
|
|
94
|
+
export {
|
|
95
|
+
detectRuntimeEnvironment,
|
|
96
|
+
resolveRuntimeEnvironmentKeyFromLabel,
|
|
97
|
+
resolveRuntimeEnvironmentLabelFromKey,
|
|
98
|
+
} from './init/runtime-environment.mjs';
|
|
320
99
|
|
|
321
100
|
export async function runInitCommand(targetDirectoryArgument, initOptions = {}) {
|
|
322
101
|
const resolvedTargetDirectoryPath = path.resolve(targetDirectoryArgument || '.');
|
|
@@ -420,13 +199,17 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
|
|
|
420
199
|
: 'No existing project markers were detected.',
|
|
421
200
|
activeRulesSummary: {
|
|
422
201
|
canonicalSource: '.instructions.md',
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
'.
|
|
427
|
-
'.
|
|
428
|
-
'.
|
|
202
|
+
compiledRulebook: '.agent-instructions.md',
|
|
203
|
+
legacyThinAdapters: ['.cursorrules', '.windsurfrules', '.clauderc'],
|
|
204
|
+
generatedBridgeAdapters: [
|
|
205
|
+
'AGENTS.md',
|
|
206
|
+
'CLAUDE.md',
|
|
207
|
+
'GEMINI.md',
|
|
208
|
+
'.cursor/rules/agentic-senior-core.mdc',
|
|
209
|
+
'.windsurf/rules/agentic-senior-core.md',
|
|
429
210
|
'.github/copilot-instructions.md',
|
|
211
|
+
'.github/instructions/agentic-senior-core.instructions.md',
|
|
212
|
+
'.gemini/instructions.md',
|
|
430
213
|
],
|
|
431
214
|
stackLoadingMode: 'lazy',
|
|
432
215
|
domainRuleLoadingMode: 'lazy',
|
|
@@ -466,7 +249,7 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
|
|
|
466
249
|
console.log('- Detected stack: unresolved (insufficient markers).');
|
|
467
250
|
}
|
|
468
251
|
|
|
469
|
-
console.log('- Active rules baseline: canonical .instructions.md -> compiled .
|
|
252
|
+
console.log('- Active rules baseline: canonical .instructions.md -> compiled .agent-instructions.md + legacy thin root adapters');
|
|
470
253
|
console.log(
|
|
471
254
|
`- Active review thresholds: ${formatBlockingSeverities(selectedPolicyProfile.blockingSeverities)}`
|
|
472
255
|
);
|
|
@@ -782,7 +565,7 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
|
|
|
782
565
|
console.log(`- CI/CD quality checks (guardrails): ${includeCiGuardrails ? 'enabled' : 'disabled'}`);
|
|
783
566
|
console.log(`- Review thresholds: ${formatBlockingSeverities(selectedPolicyProfile.blockingSeverities)}`);
|
|
784
567
|
console.log(`- Setup time: ${formatDuration(setupDurationMs)}`);
|
|
785
|
-
console.log('- Generated files: .instructions.md, .agent-instructions.md,
|
|
568
|
+
console.log('- Generated files: .instructions.md, .agent-instructions.md, legacy thin adapters, generated bridge adapters, and .agent-context/state/onboarding-report.json');
|
|
786
569
|
if (scaffoldingResult?.bootstrapMode === 'ai-synthesis') {
|
|
787
570
|
console.log(`- Bootstrap prompts: ${(scaffoldingResult.generatedPromptFileNames || []).length} files generated in .agent-context/prompts/`);
|
|
788
571
|
if ((scaffoldingResult.materializedFileNames || []).length > 0) {
|
|
@@ -846,7 +629,7 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
|
|
|
846
629
|
console.log('- If docs/DESIGN.md is missing, execute .agent-context/prompts/bootstrap-design.md now and refine docs/design-intent.json into a complete design contract before building UI components.');
|
|
847
630
|
console.log('- Keep docs/design-intent.json and docs/DESIGN.md synchronized whenever the UI direction changes.');
|
|
848
631
|
}
|
|
849
|
-
console.log('Your AI tools will now receive one compiled rulebook
|
|
632
|
+
console.log('Your AI tools will now receive one compiled rulebook, thin discovery adapters, and the original source rules. Your review threshold is stored in .agent-context/policies/llm-judge-threshold.json.');
|
|
850
633
|
console.log('MCP server registration is manual inside your IDE settings, even when mcp.json exists.');
|
|
851
634
|
} catch (error) {
|
|
852
635
|
console.error('\n[FATAL] An error occurred during initialization. Attempting automatic rollback...');
|
|
@@ -174,7 +174,7 @@ export async function runOptimizeCommand(targetDirectoryArgument, optimizeOption
|
|
|
174
174
|
console.log(`- Agent profile: ${tokenOptimizationState.selectedAgent}`);
|
|
175
175
|
console.log(`- Preferred shell proxy: ${tokenOptimizationState.preferredShellProxy}`);
|
|
176
176
|
console.log(`- Setup time: ${formatDuration(optimizationDurationMs)}`);
|
|
177
|
-
console.log('- Updated files: .
|
|
177
|
+
console.log('- Updated files: .agent-instructions.md, legacy thin adapters, and .agent-context/state/token-optimization.json');
|
|
178
178
|
|
|
179
179
|
if (tokenOptimizationState.enabled) {
|
|
180
180
|
if (rtkDetection.isAvailable) {
|
|
@@ -48,6 +48,7 @@ import {
|
|
|
48
48
|
buildDesignIntentSeedFromSignals,
|
|
49
49
|
} from '../project-scaffolder.mjs';
|
|
50
50
|
import { ensureActiveMemorySnapshot } from '../memory-continuity.mjs';
|
|
51
|
+
import { buildExistingProjectMajorConstraints } from '../init-detection-flow.mjs';
|
|
51
52
|
|
|
52
53
|
export function parseUpgradeArguments(commandArguments) {
|
|
53
54
|
const parsedUpgradeOptions = {
|
|
@@ -102,14 +103,6 @@ export function parseUpgradeArguments(commandArguments) {
|
|
|
102
103
|
return parsedUpgradeOptions;
|
|
103
104
|
}
|
|
104
105
|
|
|
105
|
-
function buildExistingProjectMajorConstraints() {
|
|
106
|
-
return [
|
|
107
|
-
'Preserve existing project markers and avoid forced stack migration.',
|
|
108
|
-
'Use runtime markers as evidence only unless the user already recorded an explicit runtime constraint.',
|
|
109
|
-
'Upgrade keeps prior explicit onboarding constraints but does not create new stack or blueprint decisions.',
|
|
110
|
-
];
|
|
111
|
-
}
|
|
112
|
-
|
|
113
106
|
function buildUpgradeDesignIntentSeed({
|
|
114
107
|
targetDirectoryPath,
|
|
115
108
|
packageManifest,
|
|
@@ -243,7 +236,7 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
|
|
|
243
236
|
})
|
|
244
237
|
: null;
|
|
245
238
|
|
|
246
|
-
const detectionMajorConstraints = buildExistingProjectMajorConstraints();
|
|
239
|
+
const detectionMajorConstraints = buildExistingProjectMajorConstraints({ mode: 'upgrade' });
|
|
247
240
|
const detectionTransparency = {
|
|
248
241
|
declaredAt: new Date().toISOString(),
|
|
249
242
|
declarationType: 'existing-project',
|
|
@@ -251,7 +244,18 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
|
|
|
251
244
|
detectionSummary: buildDetectionSummary(projectDetection),
|
|
252
245
|
activeRulesSummary: {
|
|
253
246
|
canonicalSource: '.instructions.md',
|
|
254
|
-
|
|
247
|
+
compiledRulebook: '.agent-instructions.md',
|
|
248
|
+
legacyThinAdapters: ['.cursorrules', '.windsurfrules', '.clauderc'],
|
|
249
|
+
generatedBridgeAdapters: [
|
|
250
|
+
'AGENTS.md',
|
|
251
|
+
'CLAUDE.md',
|
|
252
|
+
'GEMINI.md',
|
|
253
|
+
'.cursor/rules/agentic-senior-core.mdc',
|
|
254
|
+
'.windsurf/rules/agentic-senior-core.md',
|
|
255
|
+
'.github/copilot-instructions.md',
|
|
256
|
+
'.github/instructions/agentic-senior-core.instructions.md',
|
|
257
|
+
'.gemini/instructions.md',
|
|
258
|
+
],
|
|
255
259
|
stackLoadingMode: 'lazy',
|
|
256
260
|
domainRuleLoadingMode: 'lazy',
|
|
257
261
|
selectedProfile: selectedProfileName,
|
|
@@ -281,7 +285,7 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
|
|
|
281
285
|
} else {
|
|
282
286
|
console.log('- Detected stack: unresolved (insufficient markers).');
|
|
283
287
|
}
|
|
284
|
-
console.log('- Active rules baseline: canonical .instructions.md -> compiled .
|
|
288
|
+
console.log('- Active rules baseline: canonical .instructions.md -> compiled .agent-instructions.md + legacy thin root adapters');
|
|
285
289
|
console.log(
|
|
286
290
|
`- Active review thresholds: ${(
|
|
287
291
|
PROFILE_PRESETS[selectedProfileName]?.blockingSeverities || []
|
|
@@ -296,7 +300,7 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
|
|
|
296
300
|
|
|
297
301
|
const projectDocStalenessReport = await detectProjectDocTemplateStaleness(resolvedTargetDirectoryPath);
|
|
298
302
|
|
|
299
|
-
const currentRulesPath = path.join(resolvedTargetDirectoryPath, '.
|
|
303
|
+
const currentRulesPath = path.join(resolvedTargetDirectoryPath, '.agent-instructions.md');
|
|
300
304
|
const currentRulesContent = await pathExists(currentRulesPath)
|
|
301
305
|
? await fs.readFile(currentRulesPath, 'utf8')
|
|
302
306
|
: '';
|
|
@@ -423,13 +427,14 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
|
|
|
423
427
|
}
|
|
424
428
|
}
|
|
425
429
|
|
|
426
|
-
await compileDynamicContext({
|
|
430
|
+
const compileResult = await compileDynamicContext({
|
|
427
431
|
targetDirectoryPath: resolvedTargetDirectoryPath,
|
|
428
432
|
selectedStackFileName,
|
|
429
433
|
selectedAdditionalStackFileNames,
|
|
430
434
|
selectedBlueprintFileName,
|
|
431
435
|
selectedAdditionalBlueprintFileNames,
|
|
432
436
|
includeCiGuardrails,
|
|
437
|
+
preserveUserOwnedEntrypoints: true,
|
|
433
438
|
});
|
|
434
439
|
await writeSelectedPolicy(resolvedTargetDirectoryPath, selectedProfileName);
|
|
435
440
|
|
|
@@ -454,25 +459,38 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
|
|
|
454
459
|
console.log('\nUpgrade complete.');
|
|
455
460
|
console.log(`- Governance surface sync: 1:1 (${governanceSyncResult.updatedFiles.length} updated, ${governanceSyncResult.createdFiles.length} new, ${governanceSyncResult.deletedManagedFiles.length} deleted, ${governanceSyncResult.unchangedFiles.length} unchanged)`);
|
|
456
461
|
console.log(`- Rules rewritten: ${isRulesContentChanged ? 'yes' : 'no (metadata refreshed)'}`);
|
|
462
|
+
const preservedInstructionEntrypoints = Array.from(new Set([
|
|
463
|
+
...(governanceSyncResult.preservedFiles || []),
|
|
464
|
+
...(compileResult.preservedEntrypoints || []),
|
|
465
|
+
])).sort();
|
|
466
|
+
if (preservedInstructionEntrypoints.length > 0) {
|
|
467
|
+
console.log(`- User-owned instruction entrypoints preserved: ${preservedInstructionEntrypoints.length}`);
|
|
468
|
+
}
|
|
457
469
|
if (governanceSyncResult.deletedManagedDirectories.length > 0) {
|
|
458
470
|
console.log(`- Managed stale directories removed: ${governanceSyncResult.deletedManagedDirectories.length}`);
|
|
459
471
|
}
|
|
460
472
|
console.log(`- Setup time: ${formatDuration(setupDurationMs)}`);
|
|
461
473
|
|
|
462
|
-
|
|
474
|
+
const hasDetailedGovernanceChanges = governanceSyncResult.updatedFiles.length > 0
|
|
475
|
+
|| governanceSyncResult.createdFiles.length > 0
|
|
476
|
+
|| governanceSyncResult.deletedManagedFiles.length > 0
|
|
477
|
+
|| preservedInstructionEntrypoints.length > 0;
|
|
478
|
+
|
|
479
|
+
if (hasDetailedGovernanceChanges) {
|
|
463
480
|
console.log('\nDetailed changes:');
|
|
464
481
|
governanceSyncResult.createdFiles.forEach((fileName) => console.log(` [NEW] ${fileName}`));
|
|
465
482
|
governanceSyncResult.updatedFiles.forEach((fileName) => console.log(` [UPDATED] ${fileName}`));
|
|
466
483
|
governanceSyncResult.deletedManagedFiles.forEach((fileName) => console.log(` [DELETED] ${fileName}`));
|
|
484
|
+
preservedInstructionEntrypoints.forEach((fileName) => console.log(` [PRESERVE] ${fileName}`));
|
|
467
485
|
}
|
|
468
486
|
if (supplementalCreatedFileNames.length > 0) {
|
|
469
|
-
if (!
|
|
487
|
+
if (!hasDetailedGovernanceChanges) {
|
|
470
488
|
console.log('\nDetailed changes:');
|
|
471
489
|
}
|
|
472
490
|
supplementalCreatedFileNames.forEach((fileName) => console.log(` [NEW] ${fileName} (seed)`));
|
|
473
491
|
}
|
|
474
492
|
|
|
475
|
-
console.log('\nRefreshed files: .instructions.md, .agent-instructions.md,
|
|
493
|
+
console.log('\nRefreshed files: .instructions.md, .agent-instructions.md, legacy thin adapters, generated bridge adapters, and .agent-context/state/onboarding-report.json');
|
|
476
494
|
} catch (error) {
|
|
477
495
|
console.error('\n[FATAL] An error occurred during upgrade. Attempting automatic rollback...');
|
|
478
496
|
try {
|
package/lib/cli/compiler.mjs
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
import {
|
|
16
16
|
pathExists,
|
|
17
17
|
collectFileNames,
|
|
18
|
+
isAgenticManagedContent,
|
|
18
19
|
} from './utils.mjs';
|
|
19
20
|
|
|
20
21
|
import {
|
|
@@ -95,6 +96,38 @@ function buildAnchorCommitmentHeader(designIntent) {
|
|
|
95
96
|
].join('\n');
|
|
96
97
|
}
|
|
97
98
|
|
|
99
|
+
function buildLegacyRootAdapterContent(adapterFileName, toolLabel) {
|
|
100
|
+
return [
|
|
101
|
+
`# ${adapterFileName} - Legacy Thin Adapter`,
|
|
102
|
+
'',
|
|
103
|
+
`Generated by Agentic-Senior-Core CLI v${CLI_VERSION}`,
|
|
104
|
+
'Adapter Mode: legacy-thin',
|
|
105
|
+
'Adapter Source: .agent-instructions.md when present; fallback .instructions.md',
|
|
106
|
+
'Canonical baseline: .instructions.md',
|
|
107
|
+
'',
|
|
108
|
+
`This file is kept only for older ${toolLabel} discovery.`,
|
|
109
|
+
'Read .agent-instructions.md for the compiled rulebook when present.',
|
|
110
|
+
'Use .instructions.md as the canonical policy source.',
|
|
111
|
+
'',
|
|
112
|
+
'Mandatory load floor:',
|
|
113
|
+
'1. Read .agent-instructions.md when present; otherwise read .instructions.md.',
|
|
114
|
+
'2. Load only relevant .agent-context/rules/ by task scope.',
|
|
115
|
+
'3. Apply matching .agent-context/prompts/ contracts.',
|
|
116
|
+
'4. Enforce .agent-context/review-checklists/ before completion.',
|
|
117
|
+
'5. Use .agent-context/state/ and .agent-context/policies/ only when relevant.',
|
|
118
|
+
'6. Resolve Runtime Decision Signals from repo evidence and live official docs.',
|
|
119
|
+
'7. Resolve Structural Planning Signals from constraints and architecture boundaries.',
|
|
120
|
+
'',
|
|
121
|
+
'Current bridges:',
|
|
122
|
+
'- Cursor: .cursor/rules/agentic-senior-core.mdc',
|
|
123
|
+
'- Windsurf: .windsurf/rules/agentic-senior-core.md',
|
|
124
|
+
'- Claude: CLAUDE.md',
|
|
125
|
+
'- Gemini: GEMINI.md and .gemini/instructions.md',
|
|
126
|
+
'- Copilot: .github/copilot-instructions.md and .github/instructions/agentic-senior-core.instructions.md',
|
|
127
|
+
'',
|
|
128
|
+
].join('\n');
|
|
129
|
+
}
|
|
130
|
+
|
|
98
131
|
export async function writeSelectedPolicy(targetDirectoryPath, selectedProfileName) {
|
|
99
132
|
const policyFilePath = path.join(targetDirectoryPath, '.agent-context', 'policies', POLICY_FILE_NAME);
|
|
100
133
|
const parsedPolicy = JSON.parse(await fs.readFile(policyFilePath, 'utf8'));
|
|
@@ -265,7 +298,9 @@ export async function buildCompiledRulesContent({
|
|
|
265
298
|
'7. docs/ project context (or bootstrap prompts when docs are not materialized)',
|
|
266
299
|
'',
|
|
267
300
|
'Project-specific compiled snapshot: .agent-instructions.md',
|
|
268
|
-
'Compiled
|
|
301
|
+
'Compiled rulebook: .agent-instructions.md',
|
|
302
|
+
'Legacy thin root adapters: .cursorrules, .windsurfrules, .clauderc',
|
|
303
|
+
'Generated bridge adapters: AGENTS.md, CLAUDE.md, GEMINI.md, .cursor/rules/agentic-senior-core.mdc, .windsurf/rules/agentic-senior-core.md, .github/copilot-instructions.md, .github/instructions/agentic-senior-core.instructions.md, .gemini/instructions.md',
|
|
269
304
|
'Canonical baseline: .instructions.md',
|
|
270
305
|
].join('\n')
|
|
271
306
|
);
|
|
@@ -591,6 +626,7 @@ export async function compileDynamicContext({
|
|
|
591
626
|
selectedBlueprintFileName,
|
|
592
627
|
selectedAdditionalBlueprintFileNames = [],
|
|
593
628
|
includeCiGuardrails,
|
|
629
|
+
preserveUserOwnedEntrypoints = true,
|
|
594
630
|
}) {
|
|
595
631
|
const resolvedTargetDirectoryPath = path.resolve(targetDirectoryPath);
|
|
596
632
|
const compiledRules = await buildCompiledRulesContent({
|
|
@@ -601,23 +637,29 @@ export async function compileDynamicContext({
|
|
|
601
637
|
selectedAdditionalBlueprintFileNames,
|
|
602
638
|
includeCiGuardrails,
|
|
603
639
|
});
|
|
640
|
+
const preservedEntrypoints = [];
|
|
604
641
|
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
await fs.writeFile(path.join(geminiDir, 'instructions.md'), compiledRules, 'utf8');
|
|
642
|
+
async function writeGeneratedEntrypointFile(relativeFilePath, content) {
|
|
643
|
+
const targetFilePath = path.join(resolvedTargetDirectoryPath, relativeFilePath);
|
|
644
|
+
|
|
645
|
+
if (preserveUserOwnedEntrypoints && await pathExists(targetFilePath)) {
|
|
646
|
+
const existingContent = await fs.readFile(targetFilePath, 'utf8');
|
|
647
|
+
if (!isAgenticManagedContent(existingContent)) {
|
|
648
|
+
preservedEntrypoints.push(relativeFilePath);
|
|
649
|
+
return;
|
|
650
|
+
}
|
|
651
|
+
}
|
|
616
652
|
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
if (!(await pathExists(githubDir))) {
|
|
620
|
-
await fs.mkdir(githubDir, { recursive: true });
|
|
653
|
+
await fs.mkdir(path.dirname(targetFilePath), { recursive: true });
|
|
654
|
+
await fs.writeFile(targetFilePath, content, 'utf8');
|
|
621
655
|
}
|
|
622
|
-
|
|
656
|
+
|
|
657
|
+
await fs.writeFile(path.join(resolvedTargetDirectoryPath, '.agent-instructions.md'), compiledRules, 'utf8');
|
|
658
|
+
await writeGeneratedEntrypointFile('.cursorrules', buildLegacyRootAdapterContent('.cursorrules', 'Cursor'));
|
|
659
|
+
await writeGeneratedEntrypointFile('.windsurfrules', buildLegacyRootAdapterContent('.windsurfrules', 'Windsurf'));
|
|
660
|
+
await writeGeneratedEntrypointFile('.clauderc', buildLegacyRootAdapterContent('.clauderc', 'Claude'));
|
|
661
|
+
|
|
662
|
+
return {
|
|
663
|
+
preservedEntrypoints,
|
|
664
|
+
};
|
|
623
665
|
}
|
package/lib/cli/constants.mjs
CHANGED
|
@@ -130,7 +130,12 @@ export const entryPointFiles = [
|
|
|
130
130
|
'.cursorrules',
|
|
131
131
|
'.windsurfrules',
|
|
132
132
|
'AGENTS.md',
|
|
133
|
+
'CLAUDE.md',
|
|
134
|
+
'GEMINI.md',
|
|
135
|
+
'.cursor/rules/agentic-senior-core.mdc',
|
|
133
136
|
'.github/copilot-instructions.md',
|
|
137
|
+
'.github/instructions/agentic-senior-core.instructions.md',
|
|
138
|
+
'.windsurf/rules/agentic-senior-core.md',
|
|
134
139
|
'.agent-override.md',
|
|
135
140
|
];
|
|
136
141
|
|
package/lib/cli/detector.mjs
CHANGED
|
@@ -22,6 +22,7 @@ const WORKSPACE_SCAN_IGNORE_DIRECTORY_NAMES = new Set([
|
|
|
22
22
|
'.github',
|
|
23
23
|
'.idea',
|
|
24
24
|
'.vscode',
|
|
25
|
+
'.windsurf',
|
|
25
26
|
'.zed',
|
|
26
27
|
]);
|
|
27
28
|
const WORKSPACE_CONTAINER_DIRECTORY_NAMES = new Set([
|
|
@@ -111,9 +112,12 @@ const INTERNAL_GOVERNANCE_SURFACE_NAMES = new Set([
|
|
|
111
112
|
'.github',
|
|
112
113
|
'.instructions.md',
|
|
113
114
|
'.vscode',
|
|
115
|
+
'.windsurf',
|
|
114
116
|
'.windsurfrules',
|
|
115
117
|
'.zed',
|
|
116
118
|
'AGENTS.md',
|
|
119
|
+
'CLAUDE.md',
|
|
120
|
+
'GEMINI.md',
|
|
117
121
|
'mcp.json',
|
|
118
122
|
]);
|
|
119
123
|
|
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
export function buildExistingProjectMajorConstraints() {
|
|
1
|
+
export function buildExistingProjectMajorConstraints({ mode = 'init' } = {}) {
|
|
2
|
+
if (mode === 'upgrade') {
|
|
3
|
+
return [
|
|
4
|
+
'Preserve existing project markers and avoid forced stack migration.',
|
|
5
|
+
'Use runtime markers as evidence only unless the user already recorded an explicit runtime constraint.',
|
|
6
|
+
'Upgrade keeps prior explicit onboarding constraints but does not create new stack or blueprint decisions.',
|
|
7
|
+
];
|
|
8
|
+
}
|
|
9
|
+
|
|
2
10
|
return [
|
|
3
11
|
'Preserve existing project markers and avoid forced stack migration.',
|
|
4
12
|
'Use detected runtime markers as evidence only; do not convert them into stack migration or design direction.',
|
|
@@ -27,8 +27,3 @@ export function normalizeAdditionalBlueprintSelection(selectedBlueprintFileName,
|
|
|
27
27
|
(blueprintFileName) => blueprintFileName && blueprintFileName !== selectedBlueprintFileName
|
|
28
28
|
)));
|
|
29
29
|
}
|
|
30
|
-
|
|
31
|
-
export function resolveScopeBlueprintCandidates(projectScopeKey) {
|
|
32
|
-
void projectScopeKey;
|
|
33
|
-
return null;
|
|
34
|
-
}
|