@ryuenn3123/agentic-senior-core 1.9.0 → 1.9.2

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 (86) hide show
  1. package/.agent-context/blueprints/mobile-app.md +21 -21
  2. package/.agent-context/policies/llm-judge-threshold.json +29 -20
  3. package/.agent-context/profiles/platform.md +13 -13
  4. package/.agent-context/profiles/regulated.md +13 -13
  5. package/.agent-context/profiles/startup.md +13 -13
  6. package/.agent-context/review-checklists/frontend-skill-parity.md +28 -28
  7. package/.agent-context/review-checklists/frontend-usability.md +33 -33
  8. package/.agent-context/review-checklists/release-operations.md +29 -29
  9. package/.agent-context/rules/security.md +92 -0
  10. package/.agent-context/skills/README.md +62 -62
  11. package/.agent-context/skills/backend/README.md +67 -67
  12. package/.agent-context/skills/backend/architecture.md +360 -360
  13. package/.agent-context/skills/backend/data-access.md +230 -230
  14. package/.agent-context/skills/backend/errors.md +137 -137
  15. package/.agent-context/skills/backend/validation.md +116 -116
  16. package/.agent-context/skills/backend.md +28 -28
  17. package/.agent-context/skills/cli/README.md +49 -49
  18. package/.agent-context/skills/cli/init.md +37 -37
  19. package/.agent-context/skills/cli/output.md +35 -35
  20. package/.agent-context/skills/cli/upgrade.md +37 -37
  21. package/.agent-context/skills/cli.md +28 -28
  22. package/.agent-context/skills/distribution/README.md +18 -18
  23. package/.agent-context/skills/distribution/compatibility.md +31 -31
  24. package/.agent-context/skills/distribution/publish.md +36 -36
  25. package/.agent-context/skills/distribution/rollback.md +31 -31
  26. package/.agent-context/skills/distribution.md +28 -28
  27. package/.agent-context/skills/frontend/README.md +35 -35
  28. package/.agent-context/skills/frontend/accessibility.md +107 -107
  29. package/.agent-context/skills/frontend/motion.md +66 -66
  30. package/.agent-context/skills/frontend/performance.md +62 -62
  31. package/.agent-context/skills/frontend/ui-architecture.md +128 -128
  32. package/.agent-context/skills/frontend.md +29 -29
  33. package/.agent-context/skills/fullstack/README.md +18 -18
  34. package/.agent-context/skills/fullstack/contracts.md +52 -52
  35. package/.agent-context/skills/fullstack/end-to-end.md +41 -41
  36. package/.agent-context/skills/fullstack/feature-slicing.md +64 -64
  37. package/.agent-context/skills/fullstack.md +26 -26
  38. package/.agent-context/skills/index.json +107 -107
  39. package/.agent-context/skills/review-quality/README.md +18 -18
  40. package/.agent-context/skills/review-quality/benchmark.md +29 -29
  41. package/.agent-context/skills/review-quality/planning.md +37 -37
  42. package/.agent-context/skills/review-quality/security.md +33 -33
  43. package/.agent-context/skills/review-quality.md +27 -27
  44. package/.agent-context/stacks/flutter.md +16 -16
  45. package/.agent-context/stacks/react-native.md +16 -16
  46. package/.agent-context/state/architecture-map.md +25 -25
  47. package/.agent-context/state/benchmark-analysis.json +431 -431
  48. package/.agent-context/state/benchmark-thresholds.json +10 -10
  49. package/.agent-context/state/benchmark-watchlist.json +19 -19
  50. package/.agent-context/state/dependency-map.md +32 -32
  51. package/.agent-context/state/onboarding-report.json +39 -0
  52. package/.agent-context/state/skill-platform.json +38 -38
  53. package/.agent-override.md +36 -36
  54. package/.cursorrules +3718 -140
  55. package/.github/ISSUE_TEMPLATE/v1.7-frontend-work-item.yml +54 -54
  56. package/.github/workflows/benchmark-detection.yml +38 -38
  57. package/.github/workflows/benchmark-intelligence.yml +50 -50
  58. package/.github/workflows/frontend-usability-gate.yml +36 -36
  59. package/.github/workflows/publish.yml +32 -0
  60. package/.github/workflows/release-gate.yml +32 -32
  61. package/.github/workflows/sbom-compliance.yml +32 -32
  62. package/.windsurfrules +3718 -106
  63. package/AGENTS.md +181 -181
  64. package/README.md +318 -318
  65. package/bin/agentic-senior-core.js +61 -1556
  66. package/lib/cli/commands/init.mjs +339 -0
  67. package/lib/cli/commands/launch.mjs +81 -0
  68. package/lib/cli/commands/upgrade.mjs +165 -0
  69. package/lib/cli/compiler.mjs +204 -0
  70. package/lib/cli/constants.mjs +136 -0
  71. package/lib/cli/detector.mjs +211 -0
  72. package/lib/cli/profile-packs.mjs +94 -0
  73. package/lib/cli/skill-selector.mjs +210 -0
  74. package/lib/cli/utils.mjs +227 -0
  75. package/mcp.json +92 -92
  76. package/package.json +3 -1
  77. package/scripts/benchmark-gate.mjs +121 -121
  78. package/scripts/benchmark-intelligence.mjs +140 -140
  79. package/scripts/detection-benchmark.mjs +138 -138
  80. package/scripts/frontend-usability-audit.mjs +87 -87
  81. package/scripts/generate-sbom.mjs +61 -61
  82. package/scripts/init-project.ps1 +104 -104
  83. package/scripts/llm-judge.mjs +664 -664
  84. package/scripts/release-gate.mjs +116 -116
  85. package/scripts/skill-tier-policy.mjs +75 -75
  86. package/scripts/validate.mjs +636 -636
@@ -0,0 +1,210 @@
1
+ /**
2
+ * Skill Selector — Skill platform interaction and domain inference.
3
+ * Depends on: constants.mjs, utils.mjs
4
+ */
5
+ import fs from 'node:fs/promises';
6
+ import path from 'node:path';
7
+
8
+ import {
9
+ SKILL_PLATFORM_DIRECTORY,
10
+ SKILL_PLATFORM_INDEX_PATH,
11
+ } from './constants.mjs';
12
+
13
+ import { normalizeChoiceInput } from './utils.mjs';
14
+
15
+ export async function loadSkillPlatformIndex() {
16
+ const skillPlatformIndexContent = await fs.readFile(SKILL_PLATFORM_INDEX_PATH, 'utf8');
17
+ return JSON.parse(skillPlatformIndexContent);
18
+ }
19
+
20
+ export function normalizeSkillTierInput(rawTierInput) {
21
+ const normalizedTierInput = normalizeChoiceInput(rawTierInput);
22
+ const allowedTierNames = new Set(['standard', 'advance', 'expert', 'above']);
23
+
24
+ if (!allowedTierNames.has(normalizedTierInput)) {
25
+ return null;
26
+ }
27
+
28
+ return normalizedTierInput;
29
+ }
30
+
31
+ export function findSkillDomainByInput(skillDomainInput, skillDomainEntries) {
32
+ const normalizedSkillDomainInput = normalizeChoiceInput(skillDomainInput);
33
+
34
+ return skillDomainEntries.find((skillDomainEntry) => {
35
+ const normalizedDomainName = normalizeChoiceInput(skillDomainEntry.name);
36
+ const normalizedDisplayName = normalizeChoiceInput(skillDomainEntry.displayName);
37
+
38
+ return normalizedSkillDomainInput === normalizedDomainName || normalizedSkillDomainInput === normalizedDisplayName;
39
+ }) || null;
40
+ }
41
+
42
+ export function formatSkillTierList(skillPlatformIndex) {
43
+ return skillPlatformIndex.tiers.map((tierDefinition) => `${tierDefinition.name} (${tierDefinition.description})`).join('\n');
44
+ }
45
+
46
+ export function inferSkillDomainNamesFromSelection(selectedStackFileName, selectedBlueprintFileName) {
47
+ const inferredDomainNames = new Set();
48
+
49
+ if (selectedBlueprintFileName === 'api-nextjs.md' || selectedBlueprintFileName === 'fastapi-service.md') {
50
+ inferredDomainNames.add('frontend');
51
+ inferredDomainNames.add('fullstack');
52
+ inferredDomainNames.add('cli');
53
+ }
54
+
55
+ if (selectedBlueprintFileName === 'go-service.md'
56
+ || selectedBlueprintFileName === 'spring-boot-api.md'
57
+ || selectedBlueprintFileName === 'laravel-api.md'
58
+ || selectedBlueprintFileName === 'aspnet-api.md') {
59
+ inferredDomainNames.add('backend');
60
+ inferredDomainNames.add('fullstack');
61
+ inferredDomainNames.add('cli');
62
+ }
63
+
64
+ if (selectedStackFileName === 'typescript.md') {
65
+ inferredDomainNames.add('frontend');
66
+ inferredDomainNames.add('cli');
67
+ }
68
+
69
+ if (selectedStackFileName === 'go.md'
70
+ || selectedStackFileName === 'java.md'
71
+ || selectedStackFileName === 'php.md'
72
+ || selectedStackFileName === 'csharp.md'
73
+ || selectedStackFileName === 'python.md'
74
+ || selectedStackFileName === 'ruby.md'
75
+ || selectedStackFileName === 'rust.md') {
76
+ inferredDomainNames.add('backend');
77
+ }
78
+
79
+ if (selectedStackFileName === 'react-native.md' || selectedStackFileName === 'flutter.md') {
80
+ inferredDomainNames.add('frontend');
81
+ inferredDomainNames.add('fullstack');
82
+ inferredDomainNames.add('cli');
83
+ }
84
+
85
+ if (selectedBlueprintFileName === 'mobile-app.md') {
86
+ inferredDomainNames.add('frontend');
87
+ inferredDomainNames.add('fullstack');
88
+ inferredDomainNames.add('cli');
89
+ }
90
+
91
+ if (selectedBlueprintFileName === 'observability.md') {
92
+ inferredDomainNames.add('backend');
93
+ inferredDomainNames.add('fullstack');
94
+ inferredDomainNames.add('cli');
95
+ }
96
+
97
+ if (inferredDomainNames.size === 0) {
98
+ inferredDomainNames.add('fullstack');
99
+ inferredDomainNames.add('cli');
100
+ }
101
+
102
+ return Array.from(inferredDomainNames);
103
+ }
104
+
105
+ export async function buildSkillPackSection(skillDomainEntry, selectedTierName) {
106
+ const resolvedPackFileName = skillDomainEntry.tierToPackFileNames?.[selectedTierName]
107
+ || skillDomainEntry.tierToPackFileNames?.[skillDomainEntry.defaultTier]
108
+ || skillDomainEntry.defaultPackFileName;
109
+ const skillPackFilePath = path.join(SKILL_PLATFORM_DIRECTORY, resolvedPackFileName);
110
+ const skillPackContent = await fs.readFile(skillPackFilePath, 'utf8');
111
+
112
+ return [
113
+ `## SKILL PACK: ${skillDomainEntry.displayName}`,
114
+ `Source: .agent-context/skills/${resolvedPackFileName}`,
115
+ `Default tier: ${skillDomainEntry.defaultTier}`,
116
+ `Selected tier: ${selectedTierName}`,
117
+ `Evidence: ${skillDomainEntry.evidence}`,
118
+ '',
119
+ skillPackContent.trim(),
120
+ '',
121
+ ].join('\n');
122
+ }
123
+
124
+ export async function runSkillCommand(commandArguments) {
125
+ const parsedSkillOptions = {
126
+ domain: null,
127
+ tier: null,
128
+ tierProvided: false,
129
+ json: false,
130
+ };
131
+
132
+ for (let argumentIndex = 0; argumentIndex < commandArguments.length; argumentIndex++) {
133
+ const currentArgument = commandArguments[argumentIndex];
134
+
135
+ if (!currentArgument.startsWith('--')) {
136
+ parsedSkillOptions.domain = currentArgument;
137
+ continue;
138
+ }
139
+
140
+ if (currentArgument === '--tier') {
141
+ parsedSkillOptions.tier = normalizeSkillTierInput(commandArguments[argumentIndex + 1] || '');
142
+ parsedSkillOptions.tierProvided = true;
143
+ argumentIndex += 1;
144
+ continue;
145
+ }
146
+
147
+ if (currentArgument.startsWith('--tier=')) {
148
+ parsedSkillOptions.tier = normalizeSkillTierInput(currentArgument.split('=')[1]);
149
+ parsedSkillOptions.tierProvided = true;
150
+ continue;
151
+ }
152
+
153
+ if (currentArgument === '--json') {
154
+ parsedSkillOptions.json = true;
155
+ continue;
156
+ }
157
+
158
+ throw new Error(`Unknown option: ${currentArgument}`);
159
+ }
160
+
161
+ const skillPlatformIndex = await loadSkillPlatformIndex();
162
+ const skillDomainEntries = Object.values(skillPlatformIndex.domains || {});
163
+ const selectedSkillDomain = parsedSkillOptions.domain
164
+ ? findSkillDomainByInput(parsedSkillOptions.domain, skillDomainEntries)
165
+ : null;
166
+
167
+ if (parsedSkillOptions.domain && !selectedSkillDomain) {
168
+ throw new Error(`Unknown skill domain: ${parsedSkillOptions.domain}`);
169
+ }
170
+
171
+ if (parsedSkillOptions.tierProvided && !parsedSkillOptions.tier) {
172
+ throw new Error(`Unknown skill tier: ${commandArguments.join(' ')}`);
173
+ }
174
+
175
+ const selectedTierName = parsedSkillOptions.tier || skillPlatformIndex.defaultTier || 'advance';
176
+ const recommendedPackFileName = selectedSkillDomain
177
+ ? selectedSkillDomain.tierToPackFileNames?.[selectedTierName]
178
+ || selectedSkillDomain.tierToPackFileNames?.[selectedSkillDomain.defaultTier]
179
+ || selectedSkillDomain.defaultPackFileName
180
+ || null
181
+ : null;
182
+
183
+ if (parsedSkillOptions.json) {
184
+ console.log(JSON.stringify({
185
+ defaultTier: skillPlatformIndex.defaultTier,
186
+ selectedTier: selectedTierName,
187
+ selectedDomain: selectedSkillDomain,
188
+ recommendedPackFileName,
189
+ }, null, 2));
190
+ return;
191
+ }
192
+
193
+ console.log('Skill platform selector');
194
+ console.log(`Default tier: ${skillPlatformIndex.defaultTier}`);
195
+ console.log(`Available tiers:\n${formatSkillTierList(skillPlatformIndex)}`);
196
+
197
+ if (!selectedSkillDomain) {
198
+ console.log('\nAvailable domains:');
199
+ for (const skillDomainEntry of skillDomainEntries) {
200
+ console.log(`- ${skillDomainEntry.name}: ${skillDomainEntry.description}`);
201
+ }
202
+ return;
203
+ }
204
+
205
+ console.log(`\nSelected domain: ${selectedSkillDomain.displayName}`);
206
+ console.log(`Selected tier: ${selectedTierName}`);
207
+ console.log(`Recommended pack: ${recommendedPackFileName}`);
208
+ console.log(`Purpose: ${selectedSkillDomain.description}`);
209
+ console.log(`Evidence: ${selectedSkillDomain.evidence}`);
210
+ }
@@ -0,0 +1,227 @@
1
+ /**
2
+ * CLI Utilities — Shared helper functions.
3
+ * Depends on: constants.mjs
4
+ */
5
+ import fs from 'node:fs/promises';
6
+ import path from 'node:path';
7
+
8
+ import {
9
+ REPO_ROOT,
10
+ ALLOWED_SEVERITY_LEVELS,
11
+ PROFILE_PRESETS,
12
+ entryPointFiles,
13
+ directoryCopies,
14
+ } from './constants.mjs';
15
+
16
+ export function printUsage() {
17
+ console.log('Agentic-Senior-Core CLI');
18
+ console.log('');
19
+ console.log('Local runtime:');
20
+ console.log(' npm exec --yes @ryuenn3123/agentic-senior-core init');
21
+ console.log(' npx @ryuenn3123/agentic-senior-core init');
22
+ console.log(' npm install -g @ryuenn3123/agentic-senior-core && agentic-senior-core init');
23
+ console.log(' bunx @ryuenn3123/agentic-senior-core init # optional Bun path');
24
+ console.log(' open GitHub template: https://github.com/fatidaprilian/Agentic-Senior-Core/generate');
25
+ console.log('');
26
+ console.log('Usage:');
27
+ console.log(' agentic-senior-core launch');
28
+ console.log(' agentic-senior-core init [target-directory] [--preset <name>] [--profile <beginner|balanced|strict>] [--profile-pack <name>] [--stack <name>] [--blueprint <name>] [--ci <true|false>] [--newbie]');
29
+ console.log(' agentic-senior-core upgrade [target-directory] [--dry-run] [--yes]');
30
+ console.log(' agentic-senior-core skill [domain] [--tier <standard|advance|expert|above>] [--json]');
31
+ console.log(' agentic-senior-core --version');
32
+ console.log('');
33
+ console.log('Options:');
34
+ console.log(' --help Show help');
35
+ console.log(' --version Show CLI version');
36
+ console.log(' --profile Choose beginner, balanced, or strict');
37
+ console.log(' --preset Use a plug-and-play starter preset (frontend-web, backend-api, fullstack-product, platform-governance, mobile-react-native, mobile-flutter, observability-platform)');
38
+ console.log(' --profile-pack Apply a team profile pack (startup, regulated, platform)');
39
+ console.log(' --newbie Alias for --profile beginner');
40
+ console.log(' --stack Override stack selection');
41
+ console.log(' --blueprint Override blueprint selection');
42
+ console.log(' --ci Override CI/CD guardrails (true|false)');
43
+ console.log(' --dry-run Preview upgrade without writing files');
44
+ console.log(' --yes Skip confirmation prompts for upgrade');
45
+ console.log(' --tier Choose a skill tier for the skill selector');
46
+ console.log(' --json Emit machine-readable skill selection output');
47
+ }
48
+
49
+ export async function pathExists(targetPath) {
50
+ try {
51
+ await fs.stat(targetPath);
52
+ return true;
53
+ } catch {
54
+ return false;
55
+ }
56
+ }
57
+
58
+ export async function ensureDirectory(directoryPath) {
59
+ await fs.mkdir(directoryPath, { recursive: true });
60
+ }
61
+
62
+ export async function copyDirectory(sourceDirectoryPath, targetDirectoryPath) {
63
+ if (path.resolve(sourceDirectoryPath) === path.resolve(targetDirectoryPath)) {
64
+ return;
65
+ }
66
+
67
+ await ensureDirectory(targetDirectoryPath);
68
+ const directoryEntries = await fs.readdir(sourceDirectoryPath, { withFileTypes: true });
69
+
70
+ for (const directoryEntry of directoryEntries) {
71
+ const sourceEntryPath = path.join(sourceDirectoryPath, directoryEntry.name);
72
+ const targetEntryPath = path.join(targetDirectoryPath, directoryEntry.name);
73
+
74
+ if (directoryEntry.isDirectory()) {
75
+ await copyDirectory(sourceEntryPath, targetEntryPath);
76
+ continue;
77
+ }
78
+
79
+ if (path.resolve(sourceEntryPath) === path.resolve(targetEntryPath)) {
80
+ continue;
81
+ }
82
+
83
+ await fs.copyFile(sourceEntryPath, targetEntryPath);
84
+ }
85
+ }
86
+
87
+ export async function copyGovernanceAssetsToTarget(resolvedTargetDirectoryPath) {
88
+ for (const sourceDirectoryName of directoryCopies) {
89
+ const sourceDirectoryPath = path.join(REPO_ROOT, sourceDirectoryName);
90
+ if (!(await pathExists(sourceDirectoryPath))) {
91
+ continue;
92
+ }
93
+
94
+ await copyDirectory(sourceDirectoryPath, path.join(resolvedTargetDirectoryPath, sourceDirectoryName));
95
+ }
96
+
97
+ for (const entryPointFileName of entryPointFiles) {
98
+ const sourceFilePath = path.join(REPO_ROOT, entryPointFileName);
99
+ const targetFilePath = path.join(resolvedTargetDirectoryPath, entryPointFileName);
100
+
101
+ if (!(await pathExists(sourceFilePath))) {
102
+ continue;
103
+ }
104
+
105
+ if (path.resolve(sourceFilePath) === path.resolve(targetFilePath)) {
106
+ continue;
107
+ }
108
+
109
+ await ensureDirectory(path.dirname(targetFilePath));
110
+ await fs.copyFile(sourceFilePath, targetFilePath);
111
+ }
112
+ }
113
+
114
+ export async function askChoice(promptMessage, options, userInterface) {
115
+ console.log(`\n${promptMessage}`);
116
+ options.forEach((choiceLabel, choiceIndex) => {
117
+ console.log(` ${choiceIndex + 1}. ${choiceLabel}`);
118
+ });
119
+
120
+ while (true) {
121
+ const selectedRawInput = await userInterface.question('Choose a number: ');
122
+ const selectedIndex = Number.parseInt(selectedRawInput.trim(), 10) - 1;
123
+
124
+ if (Number.isNaN(selectedIndex) || selectedIndex < 0 || selectedIndex >= options.length) {
125
+ console.log('Invalid choice. Please select a valid number.');
126
+ continue;
127
+ }
128
+
129
+ return options[selectedIndex];
130
+ }
131
+ }
132
+
133
+ export async function askYesNo(promptMessage, userInterface, defaultValue) {
134
+ const suffix = typeof defaultValue === 'boolean'
135
+ ? defaultValue ? ' (Y/n): ' : ' (y/N): '
136
+ : ' (y/n): ';
137
+
138
+ while (true) {
139
+ const answer = await userInterface.question(`\n${promptMessage}${suffix}`);
140
+ const normalizedAnswer = answer.trim().toLowerCase();
141
+
142
+ if (!normalizedAnswer && typeof defaultValue === 'boolean') {
143
+ return defaultValue;
144
+ }
145
+
146
+ if (normalizedAnswer === 'y' || normalizedAnswer === 'yes') return true;
147
+ if (normalizedAnswer === 'n' || normalizedAnswer === 'no') return false;
148
+
149
+ console.log("Please answer with 'y' or 'n'.");
150
+ }
151
+ }
152
+
153
+ export function toTitleCase(fileName) {
154
+ return fileName
155
+ .replace(/\.md$/i, '')
156
+ .split(/[-_]/g)
157
+ .map((wordPart) => wordPart.charAt(0).toUpperCase() + wordPart.slice(1))
158
+ .join(' ');
159
+ }
160
+
161
+ export function normalizeChoiceInput(rawInput) {
162
+ return rawInput.trim().toLowerCase().replace(/\s+/g, '-');
163
+ }
164
+
165
+ export function matchFileNameFromInput(rawInput, fileNames) {
166
+ const normalizedInput = normalizeChoiceInput(rawInput);
167
+
168
+ return fileNames.find((fileName) => {
169
+ const normalizedFileName = normalizeChoiceInput(fileName.replace(/\.md$/i, ''));
170
+ const normalizedTitle = normalizeChoiceInput(toTitleCase(fileName));
171
+ return normalizedInput === normalizedFileName || normalizedInput === normalizedTitle;
172
+ });
173
+ }
174
+
175
+ export function matchProfileNameFromInput(rawInput) {
176
+ const normalizedInput = normalizeChoiceInput(rawInput);
177
+ return Object.keys(PROFILE_PRESETS).find((profileName) => profileName === normalizedInput) || null;
178
+ }
179
+
180
+ export function parseBooleanSetting(rawBooleanValue, contextLabel) {
181
+ const normalizedValue = normalizeChoiceInput(rawBooleanValue);
182
+
183
+ if (normalizedValue === 'true') {
184
+ return true;
185
+ }
186
+
187
+ if (normalizedValue === 'false') {
188
+ return false;
189
+ }
190
+
191
+ throw new Error(`Invalid boolean value for ${contextLabel}: ${rawBooleanValue}`);
192
+ }
193
+
194
+ export function parseBlockingSeverities(rawSeverityValues, fileName) {
195
+ const parsedSeverities = rawSeverityValues
196
+ .split(',')
197
+ .map((severityValue) => normalizeChoiceInput(severityValue))
198
+ .filter(Boolean);
199
+
200
+ if (parsedSeverities.length === 0) {
201
+ throw new Error(`Profile pack ${fileName} must define at least one blocking severity.`);
202
+ }
203
+
204
+ const invalidSeverity = parsedSeverities.find((severityValue) => !ALLOWED_SEVERITY_LEVELS.has(severityValue));
205
+ if (invalidSeverity) {
206
+ throw new Error(`Profile pack ${fileName} uses unsupported severity: ${invalidSeverity}`);
207
+ }
208
+
209
+ return parsedSeverities;
210
+ }
211
+
212
+ export async function collectFileNames(folderPath) {
213
+ const fileNames = await fs.readdir(folderPath, { withFileTypes: true });
214
+ return fileNames
215
+ .filter((entry) => entry.isFile() && entry.name.endsWith('.md'))
216
+ .map((entry) => entry.name)
217
+ .sort((leftName, rightName) => leftName.localeCompare(rightName));
218
+ }
219
+
220
+ export function formatBlockingSeverities(blockingSeverities) {
221
+ return blockingSeverities.join(', ');
222
+ }
223
+
224
+ export function formatDuration(durationMs) {
225
+ const durationInSeconds = (durationMs / 1000).toFixed(1);
226
+ return `${durationInSeconds}s`;
227
+ }
package/mcp.json CHANGED
@@ -1,92 +1,92 @@
1
- {
2
- "$schema": "https://modelcontextprotocol.io/schemas/mcp.json",
3
- "version": "1.0",
4
- "name": "agentic-senior-core",
5
- "description": "MCP configuration for governance-aware diagnostics and self-healing workflows with full knowledge injection.",
6
- "knowledgeLayers": {
7
- "enabled": true,
8
- "description": "8-layer unified knowledge injection for AI agents",
9
- "layers": {
10
- "rules": {
11
- "path": ".agent-context/rules",
12
- "count": 14,
13
- "autoLoad": true
14
- },
15
- "stacks": {
16
- "path": ".agent-context/stacks",
17
- "count": 10,
18
- "autoLoad": true
19
- },
20
- "blueprints": {
21
- "path": ".agent-context/blueprints",
22
- "count": 14,
23
- "autoLoad": true
24
- },
25
- "skills": {
26
- "path": ".agent-context/skills",
27
- "count": 6,
28
- "autoLoad": true,
29
- "packs": ["backend", "frontend", "cli", "distribution", "fullstack", "review-quality"]
30
- },
31
- "prompts": {
32
- "path": ".agent-context/prompts",
33
- "count": 3,
34
- "autoLoad": true,
35
- "templates": ["init-project", "refactor", "review-code"]
36
- },
37
- "profiles": {
38
- "path": ".agent-context/profiles",
39
- "count": 3,
40
- "autoLoad": true,
41
- "governance": ["platform", "regulated", "startup"]
42
- },
43
- "state": {
44
- "path": ".agent-context/state",
45
- "count": 6,
46
- "autoLoad": true
47
- },
48
- "policies": {
49
- "path": ".agent-context/policies",
50
- "count": 1,
51
- "autoLoad": true
52
- }
53
- }
54
- },
55
- "servers": {
56
- "lint": {
57
- "command": "node",
58
- "args": ["./scripts/validate.mjs"],
59
- "transport": "stdio"
60
- },
61
- "test": {
62
- "command": "node",
63
- "args": ["--test", "./tests/cli-smoke.test.mjs", "./tests/llm-judge.test.mjs"],
64
- "transport": "stdio"
65
- }
66
- },
67
- "workflows": {
68
- "self-heal-on-failure": {
69
- "trigger": ["ci.failure", "lint.failure"],
70
- "steps": [
71
- "collect_logs",
72
- "map_violation_to_rule",
73
- "propose_patch",
74
- "run_checklist_review"
75
- ]
76
- },
77
- "full-knowledge-injection": {
78
- "trigger": ["workspace.initialize", "agent.start"],
79
- "steps": [
80
- "load_all_knowledge_layers",
81
- "inject_rules",
82
- "inject_stacks",
83
- "inject_blueprints",
84
- "inject_skills",
85
- "inject_prompts",
86
- "inject_profiles",
87
- "inject_state",
88
- "inject_policies"
89
- ]
90
- }
91
- }
92
- }
1
+ {
2
+ "$schema": "https://modelcontextprotocol.io/schemas/mcp.json",
3
+ "version": "1.0",
4
+ "name": "agentic-senior-core",
5
+ "description": "MCP configuration for governance-aware diagnostics and self-healing workflows with full knowledge injection.",
6
+ "knowledgeLayers": {
7
+ "enabled": true,
8
+ "description": "8-layer unified knowledge injection for AI agents",
9
+ "layers": {
10
+ "rules": {
11
+ "path": ".agent-context/rules",
12
+ "count": 14,
13
+ "autoLoad": true
14
+ },
15
+ "stacks": {
16
+ "path": ".agent-context/stacks",
17
+ "count": 10,
18
+ "autoLoad": true
19
+ },
20
+ "blueprints": {
21
+ "path": ".agent-context/blueprints",
22
+ "count": 14,
23
+ "autoLoad": true
24
+ },
25
+ "skills": {
26
+ "path": ".agent-context/skills",
27
+ "count": 6,
28
+ "autoLoad": true,
29
+ "packs": ["backend", "frontend", "cli", "distribution", "fullstack", "review-quality"]
30
+ },
31
+ "prompts": {
32
+ "path": ".agent-context/prompts",
33
+ "count": 3,
34
+ "autoLoad": true,
35
+ "templates": ["init-project", "refactor", "review-code"]
36
+ },
37
+ "profiles": {
38
+ "path": ".agent-context/profiles",
39
+ "count": 3,
40
+ "autoLoad": true,
41
+ "governance": ["platform", "regulated", "startup"]
42
+ },
43
+ "state": {
44
+ "path": ".agent-context/state",
45
+ "count": 6,
46
+ "autoLoad": true
47
+ },
48
+ "policies": {
49
+ "path": ".agent-context/policies",
50
+ "count": 1,
51
+ "autoLoad": true
52
+ }
53
+ }
54
+ },
55
+ "servers": {
56
+ "lint": {
57
+ "command": "node",
58
+ "args": ["./scripts/validate.mjs"],
59
+ "transport": "stdio"
60
+ },
61
+ "test": {
62
+ "command": "node",
63
+ "args": ["--test", "./tests/cli-smoke.test.mjs", "./tests/llm-judge.test.mjs"],
64
+ "transport": "stdio"
65
+ }
66
+ },
67
+ "workflows": {
68
+ "self-heal-on-failure": {
69
+ "trigger": ["ci.failure", "lint.failure"],
70
+ "steps": [
71
+ "collect_logs",
72
+ "map_violation_to_rule",
73
+ "propose_patch",
74
+ "run_checklist_review"
75
+ ]
76
+ },
77
+ "full-knowledge-injection": {
78
+ "trigger": ["workspace.initialize", "agent.start"],
79
+ "steps": [
80
+ "load_all_knowledge_layers",
81
+ "inject_rules",
82
+ "inject_stacks",
83
+ "inject_blueprints",
84
+ "inject_skills",
85
+ "inject_prompts",
86
+ "inject_profiles",
87
+ "inject_state",
88
+ "inject_policies"
89
+ ]
90
+ }
91
+ }
92
+ }
package/package.json CHANGED
@@ -1,12 +1,14 @@
1
1
  {
2
2
  "name": "@ryuenn3123/agentic-senior-core",
3
- "version": "1.9.0",
3
+ "version": "1.9.2",
4
+ "type": "module",
4
5
  "description": "Force your AI Agent to code like a Staff Engineer, not a Junior.",
5
6
  "bin": {
6
7
  "agentic-senior-core": "bin/agentic-senior-core.js"
7
8
  },
8
9
  "files": [
9
10
  "bin/",
11
+ "lib/",
10
12
  "scripts/",
11
13
  ".agent-context/",
12
14
  ".agents/",