@ryuenn3123/agentic-senior-core 3.0.5 → 3.0.6

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.
@@ -1,5 +1,5 @@
1
1
  {
2
- "generatedAt": "2026-04-18T13:45:51.853Z",
2
+ "generatedAt": "2026-04-19T03:52:25.678Z",
3
3
  "reportName": "memory-continuity-benchmark",
4
4
  "schemaVersion": "1.0.0",
5
5
  "passed": true,
package/.cursorrules CHANGED
@@ -1,6 +1,6 @@
1
1
  # AGENTIC-SENIOR-CORE DYNAMIC GOVERNANCE RULESET
2
2
 
3
- Generated by Agentic-Senior-Core CLI v3.0.5
3
+ Generated by Agentic-Senior-Core CLI v3.0.6
4
4
  Timestamp: 2026-04-18T00:00:00.000Z
5
5
  Selected profile: beginner
6
6
  Selected policy file: .agent-context/policies/llm-judge-threshold.json
package/.windsurfrules CHANGED
@@ -1,6 +1,6 @@
1
1
  # AGENTIC-SENIOR-CORE DYNAMIC GOVERNANCE RULESET
2
2
 
3
- Generated by Agentic-Senior-Core CLI v3.0.5
3
+ Generated by Agentic-Senior-Core CLI v3.0.6
4
4
  Timestamp: 2026-04-18T00:00:00.000Z
5
5
  Selected profile: beginner
6
6
  Selected policy file: .agent-context/policies/llm-judge-threshold.json
package/README.md CHANGED
@@ -10,7 +10,7 @@
10
10
  **Production-grade Rules Engine (Governance Engine) for AI coding agents.**
11
11
  Works with Cursor, Windsurf, GitHub Copilot, Claude Code, Gemini, and other LLM-powered IDE workflows.
12
12
 
13
- Latest release: 3.0.5 (2026-04-18).
13
+ Latest release: 3.0.6 (2026-04-19).
14
14
 
15
15
  Highlights in 3.0.0:
16
16
  - Universal IDE adapter surface is completed and synchronized through thin adapters.
@@ -256,6 +256,7 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
256
256
  console.log(`- Rules changed: ${isRulesContentChanged ? 'yes' : 'no'}`);
257
257
  console.log(`- Managed surface stale files: ${managedSurfacePlan.staleFiles.length}`);
258
258
  console.log(`- Managed surface stale directories: ${managedSurfacePlan.staleDirectories.length}`);
259
+ console.log(`- Managed surface sync mode: 1:1 (prune enabled)`);
259
260
  console.log(`- Managed surface prune mode: ${upgradeOptions.pruneManagedSurface === true ? 'enabled (default)' : 'disabled (--no-prune)'}`);
260
261
  console.log(`- MCP config write mode: ${upgradeOptions.includeMcpTemplate === true ? 'enabled (default)' : 'disabled (--no-mcp-template)'}`);
261
262
  if (projectDocStalenessReport.hasProjectDocs) {
@@ -332,11 +333,21 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
332
333
  });
333
334
 
334
335
  console.log('\nUpgrade complete.');
336
+ console.log(`- Governance surface sync: 1:1 (${governanceSyncResult.updatedFiles.length} updated, ${governanceSyncResult.createdFiles.length} new, ${governanceSyncResult.deletedManagedFiles.length} deleted, ${governanceSyncResult.unchangedFiles.length} unchanged)`);
335
337
  console.log(`- Rules rewritten: ${isRulesContentChanged ? 'yes' : 'no (metadata refreshed)'}`);
336
- console.log(`- Managed stale files removed: ${governanceSyncResult.deletedManagedFiles.length}`);
337
- console.log(`- Managed stale directories removed: ${governanceSyncResult.deletedManagedDirectories.length}`);
338
+ if (governanceSyncResult.deletedManagedDirectories.length > 0) {
339
+ console.log(`- Managed stale directories removed: ${governanceSyncResult.deletedManagedDirectories.length}`);
340
+ }
338
341
  console.log(`- Setup time: ${formatDuration(setupDurationMs)}`);
339
- console.log('- Updated files: .cursorrules, .windsurfrules, .agent-context/state/onboarding-report.json');
342
+
343
+ if (governanceSyncResult.updatedFiles.length > 0 || governanceSyncResult.createdFiles.length > 0 || governanceSyncResult.deletedManagedFiles.length > 0) {
344
+ console.log('\nDetailed changes:');
345
+ governanceSyncResult.createdFiles.forEach((fileName) => console.log(` [NEW] ${fileName}`));
346
+ governanceSyncResult.updatedFiles.forEach((fileName) => console.log(` [UPDATED] ${fileName}`));
347
+ governanceSyncResult.deletedManagedFiles.forEach((fileName) => console.log(` [DELETED] ${fileName}`));
348
+ }
349
+
350
+ console.log('\nRefreshed files: .cursorrules, .windsurfrules, .agent-context/state/onboarding-report.json');
340
351
  } catch (error) {
341
352
  console.error('\n[FATAL] An error occurred during upgrade. Attempting automatic rollback...');
342
353
  try {
package/lib/cli/utils.mjs CHANGED
@@ -112,6 +112,66 @@ export async function copyDirectory(sourceDirectoryPath, targetDirectoryPath) {
112
112
  }
113
113
  }
114
114
 
115
+ /**
116
+ * Synchronizes a single file between source and target, returning the operation status.
117
+ */
118
+ export async function syncFile(sourcePath, targetPath) {
119
+ if (!(await pathExists(sourcePath))) return { status: 'skipped' };
120
+
121
+ if (!(await pathExists(targetPath))) {
122
+ await ensureDirectory(path.dirname(targetPath));
123
+ await fs.copyFile(sourcePath, targetPath);
124
+ return { status: 'created' };
125
+ }
126
+
127
+ const sourceContent = await fs.readFile(sourcePath);
128
+ const targetContent = await fs.readFile(targetPath);
129
+
130
+ if (sourceContent.equals(targetContent)) {
131
+ return { status: 'unchanged' };
132
+ }
133
+
134
+ await fs.copyFile(sourcePath, targetPath);
135
+ return { status: 'updated' };
136
+ }
137
+
138
+ /**
139
+ * Intelligent MCP configuration synchronization.
140
+ * Merges the agentic-senior-core server into existing config or creates new.
141
+ */
142
+ async function syncMcpConfig(mcpJsonPath, templateConfig) {
143
+ const topKey = Object.keys(templateConfig)[0]; // e.g. "mcpServers" or "servers"
144
+ const serverName = 'agentic-senior-core';
145
+ const templateServer = templateConfig[topKey][serverName];
146
+
147
+ if (!(await pathExists(mcpJsonPath))) {
148
+ await ensureDirectory(path.dirname(mcpJsonPath));
149
+ await fs.writeFile(mcpJsonPath, JSON.stringify(templateConfig, null, 2) + '\n', 'utf8');
150
+ return { status: 'created' };
151
+ }
152
+
153
+ try {
154
+ const existingContent = await fs.readFile(mcpJsonPath, 'utf8');
155
+ const config = JSON.parse(existingContent);
156
+
157
+ if (!config[topKey]) config[topKey] = {};
158
+
159
+ const existingServer = config[topKey][serverName];
160
+
161
+ if (JSON.stringify(existingServer) === JSON.stringify(templateServer)) {
162
+ return { status: 'unchanged' };
163
+ }
164
+
165
+ config[topKey][serverName] = templateServer;
166
+ await fs.writeFile(mcpJsonPath, JSON.stringify(config, null, 2) + '\n', 'utf8');
167
+ return { status: 'updated' };
168
+ } catch {
169
+ // If JSON is broken, overwrite it as a last resort to recovery
170
+ await fs.writeFile(mcpJsonPath, JSON.stringify(templateConfig, null, 2) + '\n', 'utf8');
171
+ return { status: 'updated' };
172
+ }
173
+ }
174
+
115
175
  function toPosixRelativePath(relativePath) {
116
176
  return relativePath.split(path.sep).join('/');
117
177
  }
@@ -281,9 +341,7 @@ export async function analyzeManagedGovernanceSurface(
281
341
  managedTargetFileCount: targetManifest.files.size,
282
342
  managedTargetDirectoryCount: targetManifest.directories.size,
283
343
  };
284
- }
285
-
286
- export async function copyGovernanceAssetsToTarget(
344
+ }export async function copyGovernanceAssetsToTarget(
287
345
  resolvedTargetDirectoryPath,
288
346
  options = {}
289
347
  ) {
@@ -294,6 +352,9 @@ export async function copyGovernanceAssetsToTarget(
294
352
  : null;
295
353
  const deletedManagedFiles = [];
296
354
  const deletedManagedDirectories = [];
355
+ const createdFiles = [];
356
+ const updatedFiles = [];
357
+ const unchangedFiles = [];
297
358
 
298
359
  for (const sourceDirectoryName of directoryCopies) {
299
360
  const sourceDirectoryPath = path.join(REPO_ROOT, sourceDirectoryName);
@@ -301,7 +362,16 @@ export async function copyGovernanceAssetsToTarget(
301
362
  continue;
302
363
  }
303
364
 
304
- await copyDirectory(sourceDirectoryPath, path.join(resolvedTargetDirectoryPath, sourceDirectoryName));
365
+ const sourceTree = await collectRelativeTreeEntries(sourceDirectoryPath, sourceDirectoryName);
366
+ for (const relativeFilePath of sourceTree.files) {
367
+ const sourcePath = path.join(REPO_ROOT, ...relativeFilePath.split('/'));
368
+ const targetPath = path.join(resolvedTargetDirectoryPath, ...relativeFilePath.split('/'));
369
+ const syncResult = await syncFile(sourcePath, targetPath);
370
+
371
+ if (syncResult.status === 'created') createdFiles.push(relativeFilePath);
372
+ else if (syncResult.status === 'updated') updatedFiles.push(relativeFilePath);
373
+ else if (syncResult.status === 'unchanged') unchangedFiles.push(relativeFilePath);
374
+ }
305
375
  }
306
376
 
307
377
  for (const entryPointFileName of entryPointFiles) {
@@ -316,8 +386,10 @@ export async function copyGovernanceAssetsToTarget(
316
386
  continue;
317
387
  }
318
388
 
319
- await ensureDirectory(path.dirname(targetFilePath));
320
- await fs.copyFile(sourceFilePath, targetFilePath);
389
+ const syncResult = await syncFile(sourceFilePath, targetFilePath);
390
+ if (syncResult.status === 'created') createdFiles.push(entryPointFileName);
391
+ else if (syncResult.status === 'updated') updatedFiles.push(entryPointFileName);
392
+ else if (syncResult.status === 'unchanged') unchangedFiles.push(entryPointFileName);
321
393
  }
322
394
 
323
395
  if (shouldPruneManagedSurface && managedSurfacePlan) {
@@ -346,16 +418,14 @@ export async function copyGovernanceAssetsToTarget(
346
418
  const projectName = path.basename(resolvedTargetDirectoryPath);
347
419
  const mcpArgs = ['./scripts/mcp-server.mjs'];
348
420
 
349
- // Ensure the MCP server entrypoint exists in the target project.
350
- // The workspace MCP configs point at ./scripts/mcp-server.mjs, so we must copy it.
351
421
  const sourceMcpServerPath = path.join(REPO_ROOT, 'scripts', 'mcp-server.mjs');
352
422
  const targetMcpServerPath = path.join(resolvedTargetDirectoryPath, 'scripts', 'mcp-server.mjs');
353
- await ensureDirectory(path.dirname(targetMcpServerPath));
354
- await fs.copyFile(sourceMcpServerPath, targetMcpServerPath);
423
+ const mcpServerSync = await syncFile(sourceMcpServerPath, targetMcpServerPath);
424
+ if (mcpServerSync.status === 'created') createdFiles.push('scripts/mcp-server.mjs');
425
+ else if (mcpServerSync.status === 'updated') updatedFiles.push('scripts/mcp-server.mjs');
355
426
 
356
427
  // 1. VS Code (Workspace Local Settings)
357
- const vscodeDirPath = path.join(resolvedTargetDirectoryPath, '.vscode');
358
- const vscodeMcpJsonPath = path.join(vscodeDirPath, 'mcp.json');
428
+ const vscodeMcpJsonPath = path.join(resolvedTargetDirectoryPath, '.vscode', 'mcp.json');
359
429
  const vscodeWorkspaceMcpConfig = {
360
430
  servers: {
361
431
  'agentic-senior-core': {
@@ -366,15 +436,12 @@ export async function copyGovernanceAssetsToTarget(
366
436
  },
367
437
  },
368
438
  };
369
-
370
- if (!(await pathExists(vscodeMcpJsonPath))) {
371
- await ensureDirectory(vscodeDirPath);
372
- await fs.writeFile(vscodeMcpJsonPath, JSON.stringify(vscodeWorkspaceMcpConfig, null, 2) + '\n', 'utf8');
373
- }
439
+ const vscodeSync = await syncMcpConfig(vscodeMcpJsonPath, vscodeWorkspaceMcpConfig);
440
+ if (vscodeSync.status === 'created') createdFiles.push('.vscode/mcp.json');
441
+ else if (vscodeSync.status === 'updated') updatedFiles.push('.vscode/mcp.json');
374
442
 
375
443
  // 2. Cursor (Workspace Local Settings)
376
- const cursorDirPath = path.join(resolvedTargetDirectoryPath, '.cursor');
377
- const cursorMcpJsonPath = path.join(cursorDirPath, 'mcp.json');
444
+ const cursorMcpJsonPath = path.join(resolvedTargetDirectoryPath, '.cursor', 'mcp.json');
378
445
  const cursorWorkspaceMcpConfig = {
379
446
  mcpServers: {
380
447
  'agentic-senior-core': {
@@ -384,15 +451,12 @@ export async function copyGovernanceAssetsToTarget(
384
451
  },
385
452
  },
386
453
  };
387
-
388
- if (!(await pathExists(cursorMcpJsonPath))) {
389
- await ensureDirectory(cursorDirPath);
390
- await fs.writeFile(cursorMcpJsonPath, JSON.stringify(cursorWorkspaceMcpConfig, null, 2) + '\n', 'utf8');
391
- }
454
+ const cursorSync = await syncMcpConfig(cursorMcpJsonPath, cursorWorkspaceMcpConfig);
455
+ if (cursorSync.status === 'created') createdFiles.push('.cursor/mcp.json');
456
+ else if (cursorSync.status === 'updated') updatedFiles.push('.cursor/mcp.json');
392
457
 
393
458
  // 3. Zed IDE (Workspace Local Settings)
394
- const zedDirPath = path.join(resolvedTargetDirectoryPath, '.zed');
395
- const zedSettingsPath = path.join(zedDirPath, 'settings.json');
459
+ const zedSettingsPath = path.join(resolvedTargetDirectoryPath, '.zed', 'settings.json');
396
460
  const zedMcpConfig = {
397
461
  context_servers: {
398
462
  'agentic-senior-core': {
@@ -404,22 +468,22 @@ export async function copyGovernanceAssetsToTarget(
404
468
  };
405
469
 
406
470
  if (!(await pathExists(zedSettingsPath))) {
407
- await ensureDirectory(zedDirPath);
471
+ await ensureDirectory(path.dirname(zedSettingsPath));
408
472
  await fs.writeFile(zedSettingsPath, JSON.stringify(zedMcpConfig, null, 2) + '\n', 'utf8');
473
+ createdFiles.push('.zed/settings.json');
409
474
  } else {
410
475
  try {
411
476
  const existingZedContent = await fs.readFile(zedSettingsPath, 'utf8');
412
477
  const parsedZedSettings = JSON.parse(existingZedContent);
413
- if (!parsedZedSettings.context_servers) {
414
- parsedZedSettings.context_servers = {};
415
- }
416
- if (!parsedZedSettings.context_servers['agentic-senior-core']) {
417
- parsedZedSettings.context_servers['agentic-senior-core'] = zedMcpConfig.context_servers['agentic-senior-core'];
478
+ if (!parsedZedSettings.context_servers) parsedZedSettings.context_servers = {};
479
+
480
+ const templateServer = zedMcpConfig.context_servers['agentic-senior-core'];
481
+ if (JSON.stringify(parsedZedSettings.context_servers['agentic-senior-core']) !== JSON.stringify(templateServer)) {
482
+ parsedZedSettings.context_servers['agentic-senior-core'] = templateServer;
418
483
  await fs.writeFile(zedSettingsPath, JSON.stringify(parsedZedSettings, null, 2) + '\n', 'utf8');
484
+ updatedFiles.push('.zed/settings.json');
419
485
  }
420
- } catch {
421
- // Fallback or ignore if user has broken JSON
422
- }
486
+ } catch { /* Ignore malformed Zed JSON */ }
423
487
  }
424
488
 
425
489
  // 4. Antigravity / Gemini (Global Settings)
@@ -441,28 +505,29 @@ export async function copyGovernanceAssetsToTarget(
441
505
 
442
506
  const safeProjectName = projectName.replace(/[^a-zA-Z0-9_-]/g, '-');
443
507
  const uniqueServerName = `agentic-senior-core-${safeProjectName}`;
444
-
445
- // For global configs, we use absolute path for cwd
446
- geminiConfig.mcpServers[uniqueServerName] = {
508
+ const templateServer = {
447
509
  command: 'node',
448
510
  args: mcpArgs,
449
511
  cwd: resolvedTargetDirectoryPath,
450
512
  };
451
513
 
452
- await fs.writeFile(globalGeminiMcpPath, JSON.stringify(geminiConfig, null, 2) + '\n', 'utf8');
514
+ if (JSON.stringify(geminiConfig.mcpServers[uniqueServerName]) !== JSON.stringify(templateServer)) {
515
+ geminiConfig.mcpServers[uniqueServerName] = templateServer;
516
+ await fs.writeFile(globalGeminiMcpPath, JSON.stringify(geminiConfig, null, 2) + '\n', 'utf8');
517
+ }
453
518
  }
454
- } catch {
455
- // Ignore global injection errors
456
- }
519
+ } catch { /* Ignore global injection errors */ }
457
520
  }
458
521
  }
459
522
 
460
523
  return {
461
524
  deletedManagedFiles,
462
525
  deletedManagedDirectories,
526
+ createdFiles,
527
+ updatedFiles,
528
+ unchangedFiles,
463
529
  managedSurfacePlan,
464
530
  };
465
-
466
531
  }
467
532
 
468
533
  export async function askChoice(promptMessage, options, userInterface) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ryuenn3123/agentic-senior-core",
3
- "version": "3.0.5",
3
+ "version": "3.0.6",
4
4
  "type": "module",
5
5
  "description": "Force your AI Agent to code like a Staff Engineer, not a Junior.",
6
6
  "bin": {