@ryuenn3123/agentic-senior-core 3.0.37 → 3.0.38

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.
Files changed (58) hide show
  1. package/.agent-context/prompts/bootstrap-design.md +108 -146
  2. package/.agent-context/rules/frontend-architecture.md +92 -108
  3. package/.agent-context/state/README.md +26 -0
  4. package/.cursor/mcp.json +10 -0
  5. package/.cursor/rules/agentic-senior-core.mdc +48 -0
  6. package/.cursorrules +22 -88
  7. package/.gemini/instructions.md +25 -16
  8. package/.github/copilot-instructions.md +25 -16
  9. package/.github/instructions/agentic-senior-core.instructions.md +47 -0
  10. package/.instructions.md +98 -207
  11. package/.windsurf/rules/agentic-senior-core.md +43 -0
  12. package/.windsurfrules +22 -88
  13. package/AGENTS.md +23 -26
  14. package/CLAUDE.md +43 -0
  15. package/CONTRIBUTING.md +5 -2
  16. package/GEMINI.md +43 -0
  17. package/README.md +24 -7
  18. package/lib/cli/backup.mjs +4 -4
  19. package/lib/cli/commands/init/project-context.mjs +101 -0
  20. package/lib/cli/commands/init/runtime-environment.mjs +59 -0
  21. package/lib/cli/commands/init/setup-decisions.mjs +83 -0
  22. package/lib/cli/commands/init.mjs +33 -250
  23. package/lib/cli/commands/optimize.mjs +1 -1
  24. package/lib/cli/commands/upgrade.mjs +32 -7
  25. package/lib/cli/compiler.mjs +59 -17
  26. package/lib/cli/constants.mjs +5 -0
  27. package/lib/cli/detector.mjs +4 -0
  28. package/lib/cli/preflight.mjs +3 -3
  29. package/lib/cli/project-scaffolder/design-contract/validation.mjs +789 -0
  30. package/lib/cli/project-scaffolder/design-contract.mjs +119 -924
  31. package/lib/cli/project-scaffolder/prompt-builders.mjs +69 -84
  32. package/lib/cli/utils/filesystem.mjs +79 -0
  33. package/lib/cli/utils/managed-surface.mjs +237 -0
  34. package/lib/cli/utils/prompting.mjs +44 -0
  35. package/lib/cli/utils.mjs +33 -335
  36. package/package.json +21 -2
  37. package/scripts/clean-local-artifacts.mjs +76 -0
  38. package/scripts/docs-quality-drift-report.mjs +5 -0
  39. package/scripts/frontend-usability-audit.mjs +23 -19
  40. package/scripts/governance-weekly-report.mjs +37 -15
  41. package/scripts/single-source-lazy-loading-audit.mjs +24 -0
  42. package/scripts/sync-thin-adapters.mjs +99 -129
  43. package/scripts/v3-purge-audit.mjs +5 -0
  44. package/scripts/validate/config.mjs +10 -0
  45. package/scripts/validate/coverage-checks.mjs +55 -0
  46. package/.agent-context/marketplace/trust-tiers.json +0 -114
  47. package/.agent-context/state/benchmark-analysis.json +0 -431
  48. package/.agent-context/state/benchmark-evidence-bundle.json +0 -1040
  49. package/.agent-context/state/benchmark-history.json +0 -75
  50. package/.agent-context/state/benchmark-trend-report.csv +0 -5
  51. package/.agent-context/state/benchmark-trend-report.json +0 -140
  52. package/.agent-context/state/benchmark-writer-judge-matrix.json +0 -462
  53. package/.agent-context/state/memory-continuity-benchmark.json +0 -132
  54. package/.agent-context/state/onboarding-report.json +0 -102
  55. package/.agent-context/state/quality-trend-report.json +0 -89
  56. package/.agent-context/state/token-optimization-benchmark.json +0 -130
  57. package/.agent-context/state/weekly-governance-report.json +0 -329
  58. package/lib/cli/compatibility.mjs +0 -124
@@ -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
- function normalizeContextLine(rawText) {
86
- return String(rawText || '')
87
- .replace(/\s+/g, ' ')
88
- .trim();
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
- compiledEntrypoints: [
424
- '.agent-instructions.md',
425
- '.cursorrules',
426
- '.windsurfrules',
427
- '.clauderc',
428
- '.gemini/instructions.md',
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 .cursorrules/.windsurfrules');
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, compiled adapters, and .agent-context/state/onboarding-report.json');
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 plus the original source rules, and your review threshold is stored in .agent-context/policies/llm-judge-threshold.json.');
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: .cursorrules, .windsurfrules, .agent-context/state/token-optimization.json');
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) {
@@ -251,7 +251,18 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
251
251
  detectionSummary: buildDetectionSummary(projectDetection),
252
252
  activeRulesSummary: {
253
253
  canonicalSource: '.instructions.md',
254
- compiledEntrypoints: ['.cursorrules', '.windsurfrules'],
254
+ compiledRulebook: '.agent-instructions.md',
255
+ legacyThinAdapters: ['.cursorrules', '.windsurfrules', '.clauderc'],
256
+ generatedBridgeAdapters: [
257
+ 'AGENTS.md',
258
+ 'CLAUDE.md',
259
+ 'GEMINI.md',
260
+ '.cursor/rules/agentic-senior-core.mdc',
261
+ '.windsurf/rules/agentic-senior-core.md',
262
+ '.github/copilot-instructions.md',
263
+ '.github/instructions/agentic-senior-core.instructions.md',
264
+ '.gemini/instructions.md',
265
+ ],
255
266
  stackLoadingMode: 'lazy',
256
267
  domainRuleLoadingMode: 'lazy',
257
268
  selectedProfile: selectedProfileName,
@@ -281,7 +292,7 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
281
292
  } else {
282
293
  console.log('- Detected stack: unresolved (insufficient markers).');
283
294
  }
284
- console.log('- Active rules baseline: canonical .instructions.md -> compiled .cursorrules/.windsurfrules');
295
+ console.log('- Active rules baseline: canonical .instructions.md -> compiled .agent-instructions.md + legacy thin root adapters');
285
296
  console.log(
286
297
  `- Active review thresholds: ${(
287
298
  PROFILE_PRESETS[selectedProfileName]?.blockingSeverities || []
@@ -296,7 +307,7 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
296
307
 
297
308
  const projectDocStalenessReport = await detectProjectDocTemplateStaleness(resolvedTargetDirectoryPath);
298
309
 
299
- const currentRulesPath = path.join(resolvedTargetDirectoryPath, '.cursorrules');
310
+ const currentRulesPath = path.join(resolvedTargetDirectoryPath, '.agent-instructions.md');
300
311
  const currentRulesContent = await pathExists(currentRulesPath)
301
312
  ? await fs.readFile(currentRulesPath, 'utf8')
302
313
  : '';
@@ -423,13 +434,14 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
423
434
  }
424
435
  }
425
436
 
426
- await compileDynamicContext({
437
+ const compileResult = await compileDynamicContext({
427
438
  targetDirectoryPath: resolvedTargetDirectoryPath,
428
439
  selectedStackFileName,
429
440
  selectedAdditionalStackFileNames,
430
441
  selectedBlueprintFileName,
431
442
  selectedAdditionalBlueprintFileNames,
432
443
  includeCiGuardrails,
444
+ preserveUserOwnedEntrypoints: true,
433
445
  });
434
446
  await writeSelectedPolicy(resolvedTargetDirectoryPath, selectedProfileName);
435
447
 
@@ -454,25 +466,38 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
454
466
  console.log('\nUpgrade complete.');
455
467
  console.log(`- Governance surface sync: 1:1 (${governanceSyncResult.updatedFiles.length} updated, ${governanceSyncResult.createdFiles.length} new, ${governanceSyncResult.deletedManagedFiles.length} deleted, ${governanceSyncResult.unchangedFiles.length} unchanged)`);
456
468
  console.log(`- Rules rewritten: ${isRulesContentChanged ? 'yes' : 'no (metadata refreshed)'}`);
469
+ const preservedInstructionEntrypoints = Array.from(new Set([
470
+ ...(governanceSyncResult.preservedFiles || []),
471
+ ...(compileResult.preservedEntrypoints || []),
472
+ ])).sort();
473
+ if (preservedInstructionEntrypoints.length > 0) {
474
+ console.log(`- User-owned instruction entrypoints preserved: ${preservedInstructionEntrypoints.length}`);
475
+ }
457
476
  if (governanceSyncResult.deletedManagedDirectories.length > 0) {
458
477
  console.log(`- Managed stale directories removed: ${governanceSyncResult.deletedManagedDirectories.length}`);
459
478
  }
460
479
  console.log(`- Setup time: ${formatDuration(setupDurationMs)}`);
461
480
 
462
- if (governanceSyncResult.updatedFiles.length > 0 || governanceSyncResult.createdFiles.length > 0 || governanceSyncResult.deletedManagedFiles.length > 0) {
481
+ const hasDetailedGovernanceChanges = governanceSyncResult.updatedFiles.length > 0
482
+ || governanceSyncResult.createdFiles.length > 0
483
+ || governanceSyncResult.deletedManagedFiles.length > 0
484
+ || preservedInstructionEntrypoints.length > 0;
485
+
486
+ if (hasDetailedGovernanceChanges) {
463
487
  console.log('\nDetailed changes:');
464
488
  governanceSyncResult.createdFiles.forEach((fileName) => console.log(` [NEW] ${fileName}`));
465
489
  governanceSyncResult.updatedFiles.forEach((fileName) => console.log(` [UPDATED] ${fileName}`));
466
490
  governanceSyncResult.deletedManagedFiles.forEach((fileName) => console.log(` [DELETED] ${fileName}`));
491
+ preservedInstructionEntrypoints.forEach((fileName) => console.log(` [PRESERVE] ${fileName}`));
467
492
  }
468
493
  if (supplementalCreatedFileNames.length > 0) {
469
- if (!(governanceSyncResult.updatedFiles.length > 0 || governanceSyncResult.createdFiles.length > 0 || governanceSyncResult.deletedManagedFiles.length > 0)) {
494
+ if (!hasDetailedGovernanceChanges) {
470
495
  console.log('\nDetailed changes:');
471
496
  }
472
497
  supplementalCreatedFileNames.forEach((fileName) => console.log(` [NEW] ${fileName} (seed)`));
473
498
  }
474
499
 
475
- console.log('\nRefreshed files: .instructions.md, .agent-instructions.md, compiled adapters, and .agent-context/state/onboarding-report.json');
500
+ console.log('\nRefreshed files: .instructions.md, .agent-instructions.md, legacy thin adapters, generated bridge adapters, and .agent-context/state/onboarding-report.json');
476
501
  } catch (error) {
477
502
  console.error('\n[FATAL] An error occurred during upgrade. Attempting automatic rollback...');
478
503
  try {
@@ -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 adapter entrypoints: .cursorrules, .windsurfrules, .clauderc, .gemini/instructions.md, .github/copilot-instructions.md',
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
- await fs.writeFile(path.join(resolvedTargetDirectoryPath, '.agent-instructions.md'), compiledRules, 'utf8');
606
- await fs.writeFile(path.join(resolvedTargetDirectoryPath, '.cursorrules'), compiledRules, 'utf8');
607
- await fs.writeFile(path.join(resolvedTargetDirectoryPath, '.windsurfrules'), compiledRules, 'utf8');
608
- await fs.writeFile(path.join(resolvedTargetDirectoryPath, '.clauderc'), compiledRules, 'utf8');
609
-
610
- // Gemini (Antigravity Editor) instructions
611
- const geminiDir = path.join(resolvedTargetDirectoryPath, '.gemini');
612
- if (!(await pathExists(geminiDir))) {
613
- await fs.mkdir(geminiDir, { recursive: true });
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
- // Copilot instructions (also used by some generic IDE extensions)
618
- const githubDir = path.join(resolvedTargetDirectoryPath, '.github');
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
- await fs.writeFile(path.join(githubDir, 'copilot-instructions.md'), compiledRules, 'utf8');
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
  }
@@ -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
 
@@ -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
 
@@ -2,6 +2,7 @@ import fs from 'node:fs/promises';
2
2
  import path from 'node:path';
3
3
  import { constants } from 'node:fs';
4
4
  import { pathExists } from './utils.mjs';
5
+ import { entryPointFiles } from './constants.mjs';
5
6
 
6
7
  const MINIMUM_NODE_VERSION = 18;
7
8
  const MINIMUM_FREE_DISK_SPACE_MB = 5;
@@ -73,15 +74,14 @@ export async function runPreflightChecks(targetDirectoryPath, operationMode) {
73
74
  // Check 4: Conflicting Files
74
75
  if (operationMode === 'init') {
75
76
  const potentiallyConflictingPaths = [
76
- path.join(targetDirectoryPath, '.cursorrules'),
77
- path.join(targetDirectoryPath, '.windsurfrules'),
77
+ ...entryPointFiles.map((entryPointFileName) => path.join(targetDirectoryPath, entryPointFileName)),
78
78
  path.join(targetDirectoryPath, '.agent-context'),
79
79
  ];
80
80
 
81
81
  const conflictingFound = [];
82
82
  for (const conflictPath of potentiallyConflictingPaths) {
83
83
  if (await pathExists(conflictPath)) {
84
- conflictingFound.push(path.basename(conflictPath));
84
+ conflictingFound.push(path.relative(targetDirectoryPath, conflictPath).replace(/\\/g, '/'));
85
85
  }
86
86
  }
87
87