@ryuenn3123/agentic-senior-core 1.8.0 → 1.8.1
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/blueprints/mobile-app.md +21 -0
- package/.agent-context/review-checklists/frontend-skill-parity.md +28 -0
- package/.agent-context/skills/README.md +63 -0
- package/.agent-context/skills/backend/README.md +68 -0
- package/.agent-context/skills/backend/architecture.md +361 -0
- package/.agent-context/skills/backend/data-access.md +231 -0
- package/.agent-context/skills/backend/errors.md +138 -0
- package/.agent-context/skills/backend/validation.md +117 -0
- package/.agent-context/skills/backend.md +29 -0
- package/.agent-context/skills/cli/README.md +50 -0
- package/.agent-context/skills/cli/init.md +38 -0
- package/.agent-context/skills/cli/output.md +36 -0
- package/.agent-context/skills/cli/upgrade.md +38 -0
- package/.agent-context/skills/cli.md +29 -0
- package/.agent-context/skills/distribution/README.md +19 -0
- package/.agent-context/skills/distribution/compatibility.md +32 -0
- package/.agent-context/skills/distribution/publish.md +37 -0
- package/.agent-context/skills/distribution/rollback.md +32 -0
- package/.agent-context/skills/distribution.md +29 -0
- package/.agent-context/skills/frontend/README.md +36 -0
- package/.agent-context/skills/frontend/accessibility.md +107 -0
- package/.agent-context/skills/frontend/motion.md +67 -0
- package/.agent-context/skills/frontend/performance.md +63 -0
- package/.agent-context/skills/frontend/ui-architecture.md +128 -0
- package/.agent-context/skills/frontend.md +30 -0
- package/.agent-context/skills/fullstack/README.md +19 -0
- package/.agent-context/skills/fullstack/contracts.md +53 -0
- package/.agent-context/skills/fullstack/end-to-end.md +42 -0
- package/.agent-context/skills/fullstack/feature-slicing.md +65 -0
- package/.agent-context/skills/fullstack.md +27 -0
- package/.agent-context/skills/index.json +107 -0
- package/.agent-context/skills/review-quality/README.md +19 -0
- package/.agent-context/skills/review-quality/benchmark.md +30 -0
- package/.agent-context/skills/review-quality/planning.md +38 -0
- package/.agent-context/skills/review-quality/security.md +34 -0
- package/.agent-context/skills/review-quality.md +28 -0
- package/.agent-context/stacks/flutter.md +16 -0
- package/.agent-context/stacks/react-native.md +16 -0
- package/.agent-context/state/benchmark-analysis.json +431 -0
- package/.agent-context/state/benchmark-thresholds.json +10 -0
- package/.agent-context/state/benchmark-watchlist.json +19 -0
- package/.agent-context/state/skill-platform.json +38 -0
- package/.cursorrules +1 -1
- package/.github/workflows/benchmark-intelligence.yml +50 -0
- package/.windsurfrules +1 -1
- package/README.md +81 -2
- package/bin/agentic-senior-core.js +412 -3
- package/package.json +4 -2
- package/scripts/benchmark-gate.mjs +121 -0
- package/scripts/benchmark-intelligence.mjs +140 -0
- package/scripts/skill-tier-policy.mjs +76 -0
- package/scripts/validate.mjs +82 -0
|
@@ -16,6 +16,8 @@ const REPO_ROOT = path.resolve(__dirname, "..");
|
|
|
16
16
|
const PACKAGE_JSON_PATH = path.join(REPO_ROOT, "package.json");
|
|
17
17
|
const CLI_VERSION = JSON.parse(fsSync.readFileSync(PACKAGE_JSON_PATH, "utf8")).version;
|
|
18
18
|
const AGENT_CONTEXT_DIR = path.join(REPO_ROOT, ".agent-context");
|
|
19
|
+
const SKILL_PLATFORM_DIRECTORY = path.join(AGENT_CONTEXT_DIR, "skills");
|
|
20
|
+
const SKILL_PLATFORM_INDEX_PATH = path.join(SKILL_PLATFORM_DIRECTORY, "index.json");
|
|
19
21
|
const POLICY_FILE_NAME = "llm-judge-threshold.json";
|
|
20
22
|
const PROFILE_PACKS_DIRECTORY_NAME = "profiles";
|
|
21
23
|
const PROFILE_PACK_REQUIRED_FIELDS = [
|
|
@@ -37,6 +39,59 @@ const BLUEPRINT_RECOMMENDATIONS = {
|
|
|
37
39
|
"php.md": "laravel-api.md",
|
|
38
40
|
"go.md": "go-service.md",
|
|
39
41
|
"csharp.md": "aspnet-api.md",
|
|
42
|
+
"react-native.md": "mobile-app.md",
|
|
43
|
+
"flutter.md": "mobile-app.md",
|
|
44
|
+
};
|
|
45
|
+
const INIT_PRESETS = {
|
|
46
|
+
"frontend-web": {
|
|
47
|
+
profile: "balanced",
|
|
48
|
+
stack: "typescript.md",
|
|
49
|
+
blueprint: "api-nextjs.md",
|
|
50
|
+
ci: true,
|
|
51
|
+
description: "Frontend-first web app starter",
|
|
52
|
+
},
|
|
53
|
+
"backend-api": {
|
|
54
|
+
profile: "balanced",
|
|
55
|
+
stack: "python.md",
|
|
56
|
+
blueprint: "fastapi-service.md",
|
|
57
|
+
ci: true,
|
|
58
|
+
description: "Backend API starter with safe defaults",
|
|
59
|
+
},
|
|
60
|
+
"fullstack-product": {
|
|
61
|
+
profile: "balanced",
|
|
62
|
+
stack: "typescript.md",
|
|
63
|
+
blueprint: "api-nextjs.md",
|
|
64
|
+
ci: true,
|
|
65
|
+
description: "Product delivery starter with fullstack governance",
|
|
66
|
+
},
|
|
67
|
+
"platform-governance": {
|
|
68
|
+
profile: "strict",
|
|
69
|
+
stack: "go.md",
|
|
70
|
+
blueprint: "go-service.md",
|
|
71
|
+
ci: true,
|
|
72
|
+
description: "Strict release and platform governance starter",
|
|
73
|
+
},
|
|
74
|
+
"mobile-react-native": {
|
|
75
|
+
profile: "balanced",
|
|
76
|
+
stack: "react-native.md",
|
|
77
|
+
blueprint: "mobile-app.md",
|
|
78
|
+
ci: true,
|
|
79
|
+
description: "Mobile app starter for React Native",
|
|
80
|
+
},
|
|
81
|
+
"mobile-flutter": {
|
|
82
|
+
profile: "balanced",
|
|
83
|
+
stack: "flutter.md",
|
|
84
|
+
blueprint: "mobile-app.md",
|
|
85
|
+
ci: true,
|
|
86
|
+
description: "Mobile app starter for Flutter",
|
|
87
|
+
},
|
|
88
|
+
"observability-platform": {
|
|
89
|
+
profile: "strict",
|
|
90
|
+
stack: "go.md",
|
|
91
|
+
blueprint: "observability.md",
|
|
92
|
+
ci: true,
|
|
93
|
+
description: "Observability and platform starter",
|
|
94
|
+
},
|
|
40
95
|
};
|
|
41
96
|
const PROFILE_PRESETS = {
|
|
42
97
|
beginner: {
|
|
@@ -82,18 +137,24 @@ function printUsage() {
|
|
|
82
137
|
console.log("Agentic-Senior-Core CLI");
|
|
83
138
|
console.log("");
|
|
84
139
|
console.log("Local runtime:");
|
|
140
|
+
console.log(" npm exec --yes @fatidaprilian/agentic-senior-core init");
|
|
85
141
|
console.log(" npx @fatidaprilian/agentic-senior-core init");
|
|
142
|
+
console.log(" npm install -g @fatidaprilian/agentic-senior-core && agentic-senior-core init");
|
|
86
143
|
console.log(" bunx @fatidaprilian/agentic-senior-core init # optional Bun path");
|
|
144
|
+
console.log(" open GitHub template: https://github.com/fatidaprilian/Agentic-Senior-Core/generate");
|
|
87
145
|
console.log("");
|
|
88
146
|
console.log("Usage:");
|
|
89
|
-
console.log(" agentic-senior-core
|
|
147
|
+
console.log(" agentic-senior-core launch");
|
|
148
|
+
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]");
|
|
90
149
|
console.log(" agentic-senior-core upgrade [target-directory] [--dry-run] [--yes]");
|
|
150
|
+
console.log(" agentic-senior-core skill [domain] [--tier <standard|advance|expert|above>] [--json]");
|
|
91
151
|
console.log(" agentic-senior-core --version");
|
|
92
152
|
console.log("");
|
|
93
153
|
console.log("Options:");
|
|
94
154
|
console.log(" --help Show help");
|
|
95
155
|
console.log(" --version Show CLI version");
|
|
96
156
|
console.log(" --profile Choose beginner, balanced, or strict");
|
|
157
|
+
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)");
|
|
97
158
|
console.log(" --profile-pack Apply a team profile pack (startup, regulated, platform)");
|
|
98
159
|
console.log(" --newbie Alias for --profile beginner");
|
|
99
160
|
console.log(" --stack Override stack selection");
|
|
@@ -101,6 +162,8 @@ function printUsage() {
|
|
|
101
162
|
console.log(" --ci Override CI/CD guardrails (true|false)");
|
|
102
163
|
console.log(" --dry-run Preview upgrade without writing files");
|
|
103
164
|
console.log(" --yes Skip confirmation prompts for upgrade");
|
|
165
|
+
console.log(" --tier Choose a skill tier for the skill selector");
|
|
166
|
+
console.log(" --json Emit machine-readable skill selection output");
|
|
104
167
|
}
|
|
105
168
|
|
|
106
169
|
async function pathExists(targetPath) {
|
|
@@ -207,6 +270,76 @@ async function askYesNo(promptMessage, userInterface, defaultValue) {
|
|
|
207
270
|
}
|
|
208
271
|
}
|
|
209
272
|
|
|
273
|
+
async function runLaunchCommand() {
|
|
274
|
+
const userInterface = readline.createInterface({ input, output });
|
|
275
|
+
|
|
276
|
+
try {
|
|
277
|
+
console.log(`\nAgentic-Senior-Core CLI v${CLI_VERSION}`);
|
|
278
|
+
console.log("Start with a numbered choice. You can still use commands later if you want direct control.");
|
|
279
|
+
|
|
280
|
+
const launchChoice = await askChoice(
|
|
281
|
+
"How do you want to start?",
|
|
282
|
+
[
|
|
283
|
+
"GitHub template (zero install)",
|
|
284
|
+
"npm / npx path",
|
|
285
|
+
"Bootstrap scripts",
|
|
286
|
+
"Preset starter",
|
|
287
|
+
"Interactive init wizard",
|
|
288
|
+
"Skill selector",
|
|
289
|
+
"Exit",
|
|
290
|
+
],
|
|
291
|
+
userInterface
|
|
292
|
+
);
|
|
293
|
+
|
|
294
|
+
if (launchChoice === "GitHub template (zero install)") {
|
|
295
|
+
console.log("\nOpen the GitHub template here:");
|
|
296
|
+
console.log("https://github.com/fatidaprilian/Agentic-Senior-Core/generate");
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if (launchChoice === "npm / npx path") {
|
|
301
|
+
console.log("\nChoose one of these package paths:");
|
|
302
|
+
console.log("npm exec --yes @fatidaprilian/agentic-senior-core init");
|
|
303
|
+
console.log("npx @fatidaprilian/agentic-senior-core init");
|
|
304
|
+
console.log("npm install -g @fatidaprilian/agentic-senior-core && agentic-senior-core init");
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
if (launchChoice === "Bootstrap scripts") {
|
|
309
|
+
console.log("\nUse the repository bootstrap scripts:");
|
|
310
|
+
console.log("Windows: powershell -ExecutionPolicy Bypass -File .\\scripts\\init-project.ps1 -TargetDirectory .");
|
|
311
|
+
console.log("Linux/macOS: bash ./scripts/init-project.sh .");
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
if (launchChoice === "Preset starter") {
|
|
316
|
+
const presetNames = Object.keys(INIT_PRESETS);
|
|
317
|
+
const selectedPresetName = await askChoice(
|
|
318
|
+
"Choose a starter preset:",
|
|
319
|
+
presetNames.map((presetName) => `${presetName} - ${INIT_PRESETS[presetName].description}`),
|
|
320
|
+
userInterface
|
|
321
|
+
);
|
|
322
|
+
|
|
323
|
+
await runInitCommand(".", { preset: normalizeChoiceInput(selectedPresetName.split(" - ")[0]) });
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
if (launchChoice === "Interactive init wizard") {
|
|
328
|
+
await runInitCommand(".", {});
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
if (launchChoice === "Skill selector") {
|
|
333
|
+
await runSkillCommand([]);
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
console.log("Exit selected.");
|
|
338
|
+
} finally {
|
|
339
|
+
userInterface.close();
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
210
343
|
function toTitleCase(fileName) {
|
|
211
344
|
return fileName
|
|
212
345
|
.replace(/\.md$/i, "")
|
|
@@ -340,6 +473,203 @@ function findProfilePackByInput(profilePackInput, profilePackDefinitions) {
|
|
|
340
473
|
}) || null;
|
|
341
474
|
}
|
|
342
475
|
|
|
476
|
+
async function loadSkillPlatformIndex() {
|
|
477
|
+
const skillPlatformIndexContent = await fs.readFile(SKILL_PLATFORM_INDEX_PATH, "utf8");
|
|
478
|
+
return JSON.parse(skillPlatformIndexContent);
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
function normalizeSkillTierInput(rawTierInput) {
|
|
482
|
+
const normalizedTierInput = normalizeChoiceInput(rawTierInput);
|
|
483
|
+
const allowedTierNames = new Set(["standard", "advance", "expert", "above"]);
|
|
484
|
+
|
|
485
|
+
if (!allowedTierNames.has(normalizedTierInput)) {
|
|
486
|
+
return null;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
return normalizedTierInput;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
function findSkillDomainByInput(skillDomainInput, skillDomainEntries) {
|
|
493
|
+
const normalizedSkillDomainInput = normalizeChoiceInput(skillDomainInput);
|
|
494
|
+
|
|
495
|
+
return skillDomainEntries.find((skillDomainEntry) => {
|
|
496
|
+
const normalizedDomainName = normalizeChoiceInput(skillDomainEntry.name);
|
|
497
|
+
const normalizedDisplayName = normalizeChoiceInput(skillDomainEntry.displayName);
|
|
498
|
+
|
|
499
|
+
return normalizedSkillDomainInput === normalizedDomainName || normalizedSkillDomainInput === normalizedDisplayName;
|
|
500
|
+
}) || null;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
function formatSkillTierList(skillPlatformIndex) {
|
|
504
|
+
return skillPlatformIndex.tiers.map((tierDefinition) => `${tierDefinition.name} (${tierDefinition.description})`).join("\n");
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
function inferSkillDomainNamesFromSelection(selectedStackFileName, selectedBlueprintFileName) {
|
|
508
|
+
const inferredDomainNames = new Set();
|
|
509
|
+
|
|
510
|
+
if (selectedBlueprintFileName === "api-nextjs.md" || selectedBlueprintFileName === "fastapi-service.md") {
|
|
511
|
+
inferredDomainNames.add("frontend");
|
|
512
|
+
inferredDomainNames.add("fullstack");
|
|
513
|
+
inferredDomainNames.add("cli");
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
if (selectedBlueprintFileName === "go-service.md"
|
|
517
|
+
|| selectedBlueprintFileName === "spring-boot-api.md"
|
|
518
|
+
|| selectedBlueprintFileName === "laravel-api.md"
|
|
519
|
+
|| selectedBlueprintFileName === "aspnet-api.md") {
|
|
520
|
+
inferredDomainNames.add("backend");
|
|
521
|
+
inferredDomainNames.add("fullstack");
|
|
522
|
+
inferredDomainNames.add("cli");
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
if (selectedStackFileName === "typescript.md") {
|
|
526
|
+
inferredDomainNames.add("frontend");
|
|
527
|
+
inferredDomainNames.add("cli");
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
if (selectedStackFileName === "go.md"
|
|
531
|
+
|| selectedStackFileName === "java.md"
|
|
532
|
+
|| selectedStackFileName === "php.md"
|
|
533
|
+
|| selectedStackFileName === "csharp.md"
|
|
534
|
+
|| selectedStackFileName === "python.md"
|
|
535
|
+
|| selectedStackFileName === "ruby.md"
|
|
536
|
+
|| selectedStackFileName === "rust.md") {
|
|
537
|
+
inferredDomainNames.add("backend");
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
if (selectedStackFileName === "react-native.md" || selectedStackFileName === "flutter.md") {
|
|
541
|
+
inferredDomainNames.add("frontend");
|
|
542
|
+
inferredDomainNames.add("fullstack");
|
|
543
|
+
inferredDomainNames.add("cli");
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
if (selectedBlueprintFileName === "mobile-app.md") {
|
|
547
|
+
inferredDomainNames.add("frontend");
|
|
548
|
+
inferredDomainNames.add("fullstack");
|
|
549
|
+
inferredDomainNames.add("cli");
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
if (selectedBlueprintFileName === "observability.md") {
|
|
553
|
+
inferredDomainNames.add("backend");
|
|
554
|
+
inferredDomainNames.add("fullstack");
|
|
555
|
+
inferredDomainNames.add("cli");
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
if (inferredDomainNames.size === 0) {
|
|
559
|
+
inferredDomainNames.add("fullstack");
|
|
560
|
+
inferredDomainNames.add("cli");
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
return Array.from(inferredDomainNames);
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
async function buildSkillPackSection(skillDomainEntry, selectedTierName) {
|
|
567
|
+
const resolvedPackFileName = skillDomainEntry.tierToPackFileNames?.[selectedTierName]
|
|
568
|
+
|| skillDomainEntry.tierToPackFileNames?.[skillDomainEntry.defaultTier]
|
|
569
|
+
|| skillDomainEntry.defaultPackFileName;
|
|
570
|
+
const skillPackFilePath = path.join(SKILL_PLATFORM_DIRECTORY, resolvedPackFileName);
|
|
571
|
+
const skillPackContent = await fs.readFile(skillPackFilePath, "utf8");
|
|
572
|
+
|
|
573
|
+
return [
|
|
574
|
+
`## SKILL PACK: ${skillDomainEntry.displayName}`,
|
|
575
|
+
`Source: .agent-context/skills/${resolvedPackFileName}`,
|
|
576
|
+
`Default tier: ${skillDomainEntry.defaultTier}`,
|
|
577
|
+
`Selected tier: ${selectedTierName}`,
|
|
578
|
+
`Evidence: ${skillDomainEntry.evidence}`,
|
|
579
|
+
"",
|
|
580
|
+
skillPackContent.trim(),
|
|
581
|
+
"",
|
|
582
|
+
].join("\n");
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
async function runSkillCommand(commandArguments) {
|
|
586
|
+
const parsedSkillOptions = {
|
|
587
|
+
domain: null,
|
|
588
|
+
tier: null,
|
|
589
|
+
tierProvided: false,
|
|
590
|
+
json: false,
|
|
591
|
+
};
|
|
592
|
+
|
|
593
|
+
for (let argumentIndex = 0; argumentIndex < commandArguments.length; argumentIndex++) {
|
|
594
|
+
const currentArgument = commandArguments[argumentIndex];
|
|
595
|
+
|
|
596
|
+
if (!currentArgument.startsWith("--")) {
|
|
597
|
+
parsedSkillOptions.domain = currentArgument;
|
|
598
|
+
continue;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
if (currentArgument === "--tier") {
|
|
602
|
+
parsedSkillOptions.tier = normalizeSkillTierInput(commandArguments[argumentIndex + 1] || "");
|
|
603
|
+
parsedSkillOptions.tierProvided = true;
|
|
604
|
+
argumentIndex += 1;
|
|
605
|
+
continue;
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
if (currentArgument.startsWith("--tier=")) {
|
|
609
|
+
parsedSkillOptions.tier = normalizeSkillTierInput(currentArgument.split("=")[1]);
|
|
610
|
+
parsedSkillOptions.tierProvided = true;
|
|
611
|
+
continue;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
if (currentArgument === "--json") {
|
|
615
|
+
parsedSkillOptions.json = true;
|
|
616
|
+
continue;
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
throw new Error(`Unknown option: ${currentArgument}`);
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
const skillPlatformIndex = await loadSkillPlatformIndex();
|
|
623
|
+
const skillDomainEntries = Object.values(skillPlatformIndex.domains || {});
|
|
624
|
+
const selectedSkillDomain = parsedSkillOptions.domain
|
|
625
|
+
? findSkillDomainByInput(parsedSkillOptions.domain, skillDomainEntries)
|
|
626
|
+
: null;
|
|
627
|
+
|
|
628
|
+
if (parsedSkillOptions.domain && !selectedSkillDomain) {
|
|
629
|
+
throw new Error(`Unknown skill domain: ${parsedSkillOptions.domain}`);
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
if (parsedSkillOptions.tierProvided && !parsedSkillOptions.tier) {
|
|
633
|
+
throw new Error(`Unknown skill tier: ${commandArguments.join(" ")}`);
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
const selectedTierName = parsedSkillOptions.tier || skillPlatformIndex.defaultTier || "advance";
|
|
637
|
+
const recommendedPackFileName = selectedSkillDomain
|
|
638
|
+
? selectedSkillDomain.tierToPackFileNames?.[selectedTierName]
|
|
639
|
+
|| selectedSkillDomain.tierToPackFileNames?.[selectedSkillDomain.defaultTier]
|
|
640
|
+
|| selectedSkillDomain.defaultPackFileName
|
|
641
|
+
|| null
|
|
642
|
+
: null;
|
|
643
|
+
|
|
644
|
+
if (parsedSkillOptions.json) {
|
|
645
|
+
console.log(JSON.stringify({
|
|
646
|
+
defaultTier: skillPlatformIndex.defaultTier,
|
|
647
|
+
selectedTier: selectedTierName,
|
|
648
|
+
selectedDomain: selectedSkillDomain,
|
|
649
|
+
recommendedPackFileName,
|
|
650
|
+
}, null, 2));
|
|
651
|
+
return;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
console.log("Skill platform selector");
|
|
655
|
+
console.log(`Default tier: ${skillPlatformIndex.defaultTier}`);
|
|
656
|
+
console.log(`Available tiers:\n${formatSkillTierList(skillPlatformIndex)}`);
|
|
657
|
+
|
|
658
|
+
if (!selectedSkillDomain) {
|
|
659
|
+
console.log("\nAvailable domains:");
|
|
660
|
+
for (const skillDomainEntry of skillDomainEntries) {
|
|
661
|
+
console.log(`- ${skillDomainEntry.name}: ${skillDomainEntry.description}`);
|
|
662
|
+
}
|
|
663
|
+
return;
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
console.log(`\nSelected domain: ${selectedSkillDomain.displayName}`);
|
|
667
|
+
console.log(`Selected tier: ${selectedTierName}`);
|
|
668
|
+
console.log(`Recommended pack: ${recommendedPackFileName}`);
|
|
669
|
+
console.log(`Purpose: ${selectedSkillDomain.description}`);
|
|
670
|
+
console.log(`Evidence: ${selectedSkillDomain.evidence}`);
|
|
671
|
+
}
|
|
672
|
+
|
|
343
673
|
async function collectFileNames(folderPath) {
|
|
344
674
|
const fileNames = await fs.readdir(folderPath, { withFileTypes: true });
|
|
345
675
|
return fileNames
|
|
@@ -454,6 +784,22 @@ async function detectProjectContext(targetDirectoryPath) {
|
|
|
454
784
|
});
|
|
455
785
|
}
|
|
456
786
|
|
|
787
|
+
if (markerNames.has("package.json") && (markerNames.has("android") || markerNames.has("ios") || markerNames.has("react-native.config.js"))) {
|
|
788
|
+
detectionCandidates.push({
|
|
789
|
+
stackFileName: "react-native.md",
|
|
790
|
+
confidenceScore: 0.9,
|
|
791
|
+
evidence: ["package.json", "mobile runtime markers"],
|
|
792
|
+
});
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
if (markerNames.has("pubspec.yaml")) {
|
|
796
|
+
detectionCandidates.push({
|
|
797
|
+
stackFileName: "flutter.md",
|
|
798
|
+
confidenceScore: 0.94,
|
|
799
|
+
evidence: ["pubspec.yaml"],
|
|
800
|
+
});
|
|
801
|
+
}
|
|
802
|
+
|
|
457
803
|
if (detectionCandidates.length === 0) {
|
|
458
804
|
return {
|
|
459
805
|
hasExistingProjectFiles,
|
|
@@ -555,11 +901,13 @@ async function writeOnboardingReport({
|
|
|
555
901
|
targetDirectoryPath,
|
|
556
902
|
selectedProfileName,
|
|
557
903
|
selectedProfilePack,
|
|
904
|
+
selectedPreset,
|
|
558
905
|
selectedStackFileName,
|
|
559
906
|
selectedBlueprintFileName,
|
|
560
907
|
includeCiGuardrails,
|
|
561
908
|
setupDurationMs,
|
|
562
909
|
projectDetection,
|
|
910
|
+
selectedSkillDomains = [],
|
|
563
911
|
operationMode = "init",
|
|
564
912
|
}) {
|
|
565
913
|
const onboardingReportPath = path.join(targetDirectoryPath, ".agent-context", "state", "onboarding-report.json");
|
|
@@ -574,10 +922,12 @@ async function writeOnboardingReport({
|
|
|
574
922
|
sourceFile: selectedProfilePack.fileName,
|
|
575
923
|
}
|
|
576
924
|
: null,
|
|
925
|
+
selectedPreset,
|
|
577
926
|
selectedStack: selectedStackFileName,
|
|
578
927
|
selectedBlueprint: selectedBlueprintFileName,
|
|
579
928
|
ciGuardrailsEnabled: includeCiGuardrails,
|
|
580
929
|
setupDurationMs,
|
|
930
|
+
selectedSkillDomains,
|
|
581
931
|
autoDetection: {
|
|
582
932
|
recommendedStack: projectDetection.recommendedStackFileName,
|
|
583
933
|
recommendedBlueprint: projectDetection.recommendedBlueprintFileName,
|
|
@@ -616,6 +966,8 @@ async function buildCompiledRulesContent({
|
|
|
616
966
|
const selectedBlueprintsDirectoryPath = path.join(resolvedTargetDirectoryPath, ".agent-context", "blueprints");
|
|
617
967
|
const selectedStateDirectoryPath = path.join(resolvedTargetDirectoryPath, ".agent-context", "state");
|
|
618
968
|
const selectedReviewDirectoryPath = path.join(resolvedTargetDirectoryPath, ".agent-context", "review-checklists");
|
|
969
|
+
const skillPlatformIndex = JSON.parse(await fs.readFile(SKILL_PLATFORM_INDEX_PATH, "utf8"));
|
|
970
|
+
const selectedSkillDomainNames = inferSkillDomainNamesFromSelection(selectedStackFileName, selectedBlueprintFileName);
|
|
619
971
|
|
|
620
972
|
const universalRuleFileNames = await collectFileNames(selectedRulesDirectoryPath);
|
|
621
973
|
const contextBlocks = [];
|
|
@@ -653,6 +1005,15 @@ async function buildCompiledRulesContent({
|
|
|
653
1005
|
);
|
|
654
1006
|
}
|
|
655
1007
|
|
|
1008
|
+
for (const selectedSkillDomainName of selectedSkillDomainNames) {
|
|
1009
|
+
const skillDomainEntry = skillPlatformIndex.domains?.[selectedSkillDomainName];
|
|
1010
|
+
if (!skillDomainEntry) {
|
|
1011
|
+
continue;
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
contextBlocks.push(await buildSkillPackSection(skillDomainEntry, skillPlatformIndex.defaultTier || "advance"));
|
|
1015
|
+
}
|
|
1016
|
+
|
|
656
1017
|
const architectureMapContent = await fs.readFile(path.join(selectedStateDirectoryPath, "architecture-map.md"), "utf8");
|
|
657
1018
|
const dependencyMapContent = await fs.readFile(path.join(selectedStateDirectoryPath, "dependency-map.md"), "utf8");
|
|
658
1019
|
const prChecklistContent = await fs.readFile(path.join(selectedReviewDirectoryPath, "pr-checklist.md"), "utf8");
|
|
@@ -722,6 +1083,7 @@ async function runInitCommand(targetDirectoryArgument, initOptions = {}) {
|
|
|
722
1083
|
const stackFileNames = await collectFileNames(path.join(AGENT_CONTEXT_DIR, "stacks"));
|
|
723
1084
|
const blueprintFileNames = await collectFileNames(path.join(AGENT_CONTEXT_DIR, "blueprints"));
|
|
724
1085
|
const profilePackDefinitions = await collectProfilePacks(REPO_ROOT);
|
|
1086
|
+
const selectedPreset = initOptions.preset ? INIT_PRESETS[initOptions.preset] || null : null;
|
|
725
1087
|
|
|
726
1088
|
const selectedStackFileNameFromOption = initOptions.stack
|
|
727
1089
|
? matchFileNameFromInput(initOptions.stack, stackFileNames)
|
|
@@ -745,6 +1107,10 @@ async function runInitCommand(targetDirectoryArgument, initOptions = {}) {
|
|
|
745
1107
|
throw new Error(`Unknown profile pack: ${initOptions.profilePack}`);
|
|
746
1108
|
}
|
|
747
1109
|
|
|
1110
|
+
if (initOptions.preset && !selectedPreset) {
|
|
1111
|
+
throw new Error(`Unknown preset: ${initOptions.preset}`);
|
|
1112
|
+
}
|
|
1113
|
+
|
|
748
1114
|
if (selectedProfilePack && !stackFileNames.includes(selectedProfilePack.defaultStackFileName)) {
|
|
749
1115
|
throw new Error(
|
|
750
1116
|
`Profile pack ${selectedProfilePack.fileName} references unknown stack file: ${selectedProfilePack.defaultStackFileName}`
|
|
@@ -760,6 +1126,10 @@ async function runInitCommand(targetDirectoryArgument, initOptions = {}) {
|
|
|
760
1126
|
console.log(`\nAgentic-Senior-Core CLI v${CLI_VERSION}`);
|
|
761
1127
|
console.log("I will copy governance files into your target folder and compile a single rulebook for your AI tools.");
|
|
762
1128
|
|
|
1129
|
+
if (selectedPreset) {
|
|
1130
|
+
console.log(`Using preset: ${initOptions.preset} (${selectedPreset.description}).`);
|
|
1131
|
+
}
|
|
1132
|
+
|
|
763
1133
|
const projectDetection = await detectProjectContext(resolvedTargetDirectoryPath);
|
|
764
1134
|
if (projectDetection.hasExistingProjectFiles) {
|
|
765
1135
|
console.log("I found files in the target directory, so I checked whether this already looks like an existing project.");
|
|
@@ -774,6 +1144,8 @@ async function runInitCommand(targetDirectoryArgument, initOptions = {}) {
|
|
|
774
1144
|
|
|
775
1145
|
const selectedProfileName = initOptions.profile
|
|
776
1146
|
? initOptions.profile
|
|
1147
|
+
: selectedPreset?.profile
|
|
1148
|
+
? selectedPreset.profile
|
|
777
1149
|
: initOptions.newbie
|
|
778
1150
|
? "beginner"
|
|
779
1151
|
: selectedProfilePack?.defaultProfileName
|
|
@@ -809,6 +1181,7 @@ async function runInitCommand(targetDirectoryArgument, initOptions = {}) {
|
|
|
809
1181
|
const blueprintDisplayChoices = blueprintFileNames.map((blueprintFileName) => toTitleCase(blueprintFileName));
|
|
810
1182
|
|
|
811
1183
|
const selectedResolvedStackFileName = selectedStackFileNameFromOption
|
|
1184
|
+
|| selectedPreset?.stack
|
|
812
1185
|
|| (shouldApplyDetectedStack ? projectDetection.recommendedStackFileName : null)
|
|
813
1186
|
|| selectedProfilePack?.defaultStackFileName
|
|
814
1187
|
|| selectedProfile.defaultStackFileName
|
|
@@ -827,6 +1200,7 @@ async function runInitCommand(targetDirectoryArgument, initOptions = {}) {
|
|
|
827
1200
|
}
|
|
828
1201
|
|
|
829
1202
|
const selectedResolvedBlueprintFileName = selectedBlueprintFileNameFromOption
|
|
1203
|
+
|| selectedPreset?.blueprint
|
|
830
1204
|
|| recommendedBlueprintFileName
|
|
831
1205
|
|| selectedProfilePack?.defaultBlueprintFileName
|
|
832
1206
|
|| selectedProfile.defaultBlueprintFileName
|
|
@@ -838,6 +1212,8 @@ async function runInitCommand(targetDirectoryArgument, initOptions = {}) {
|
|
|
838
1212
|
|
|
839
1213
|
const includeCiGuardrails = typeof initOptions.ci === "boolean"
|
|
840
1214
|
? initOptions.ci
|
|
1215
|
+
: typeof selectedPreset?.ci === "boolean"
|
|
1216
|
+
? selectedPreset.ci
|
|
841
1217
|
: selectedProfilePack?.lockCi
|
|
842
1218
|
? selectedProfilePack.defaultCi
|
|
843
1219
|
: typeof selectedProfilePack?.defaultCi === "boolean"
|
|
@@ -864,17 +1240,22 @@ async function runInitCommand(targetDirectoryArgument, initOptions = {}) {
|
|
|
864
1240
|
targetDirectoryPath: resolvedTargetDirectoryPath,
|
|
865
1241
|
selectedProfileName,
|
|
866
1242
|
selectedProfilePack,
|
|
1243
|
+
selectedPreset: initOptions.preset || null,
|
|
867
1244
|
selectedStackFileName: selectedResolvedStackFileName,
|
|
868
1245
|
selectedBlueprintFileName: selectedResolvedBlueprintFileName,
|
|
869
1246
|
includeCiGuardrails,
|
|
870
1247
|
setupDurationMs,
|
|
871
1248
|
projectDetection,
|
|
1249
|
+
selectedSkillDomains: inferSkillDomainNamesFromSelection(selectedResolvedStackFileName, selectedResolvedBlueprintFileName),
|
|
872
1250
|
operationMode: "init",
|
|
873
1251
|
});
|
|
874
1252
|
|
|
875
1253
|
console.log("\nInitialization complete.");
|
|
876
1254
|
console.log(`- Target directory: ${resolvedTargetDirectoryPath}`);
|
|
877
1255
|
console.log(`- Profile: ${selectedProfile.displayName}`);
|
|
1256
|
+
if (initOptions.preset) {
|
|
1257
|
+
console.log(`- Preset: ${initOptions.preset}`);
|
|
1258
|
+
}
|
|
878
1259
|
if (selectedProfilePack) {
|
|
879
1260
|
console.log(`- Team profile pack: ${selectedProfilePack.displayName}`);
|
|
880
1261
|
}
|
|
@@ -997,7 +1378,12 @@ async function main() {
|
|
|
997
1378
|
const commandArgument = process.argv[2];
|
|
998
1379
|
const commandArguments = process.argv.slice(3);
|
|
999
1380
|
|
|
1000
|
-
if (!commandArgument
|
|
1381
|
+
if (!commandArgument) {
|
|
1382
|
+
await runLaunchCommand();
|
|
1383
|
+
return;
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1386
|
+
if (commandArgument === "--help" || commandArgument === "-h") {
|
|
1001
1387
|
printUsage();
|
|
1002
1388
|
return;
|
|
1003
1389
|
}
|
|
@@ -1007,12 +1393,22 @@ async function main() {
|
|
|
1007
1393
|
return;
|
|
1008
1394
|
}
|
|
1009
1395
|
|
|
1010
|
-
if (commandArgument !== "init" && commandArgument !== "upgrade") {
|
|
1396
|
+
if (commandArgument !== "init" && commandArgument !== "upgrade" && commandArgument !== "skill" && commandArgument !== "launch") {
|
|
1011
1397
|
console.error(`Unknown command: ${commandArgument}`);
|
|
1012
1398
|
printUsage();
|
|
1013
1399
|
exit(1);
|
|
1014
1400
|
}
|
|
1015
1401
|
|
|
1402
|
+
if (commandArgument === "launch") {
|
|
1403
|
+
await runLaunchCommand();
|
|
1404
|
+
return;
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
if (commandArgument === "skill") {
|
|
1408
|
+
await runSkillCommand(commandArguments);
|
|
1409
|
+
return;
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1016
1412
|
if (commandArgument === "upgrade") {
|
|
1017
1413
|
const parsedUpgradeOptions = {
|
|
1018
1414
|
targetDirectory: ".",
|
|
@@ -1047,6 +1443,7 @@ async function main() {
|
|
|
1047
1443
|
|
|
1048
1444
|
const parsedInitOptions = {
|
|
1049
1445
|
targetDirectory: ".",
|
|
1446
|
+
preset: undefined,
|
|
1050
1447
|
profile: undefined,
|
|
1051
1448
|
profilePack: undefined,
|
|
1052
1449
|
stack: undefined,
|
|
@@ -1069,6 +1466,17 @@ async function main() {
|
|
|
1069
1466
|
continue;
|
|
1070
1467
|
}
|
|
1071
1468
|
|
|
1469
|
+
if (currentArgument === "--preset") {
|
|
1470
|
+
parsedInitOptions.preset = normalizeChoiceInput(commandArguments[argumentIndex + 1] || "");
|
|
1471
|
+
argumentIndex += 1;
|
|
1472
|
+
continue;
|
|
1473
|
+
}
|
|
1474
|
+
|
|
1475
|
+
if (currentArgument.startsWith("--preset=")) {
|
|
1476
|
+
parsedInitOptions.preset = normalizeChoiceInput(currentArgument.split("=")[1]);
|
|
1477
|
+
continue;
|
|
1478
|
+
}
|
|
1479
|
+
|
|
1072
1480
|
if (currentArgument.startsWith("--profile=")) {
|
|
1073
1481
|
parsedInitOptions.profile = matchProfileNameFromInput(currentArgument.split("=")[1]);
|
|
1074
1482
|
continue;
|
|
@@ -1132,6 +1540,7 @@ async function main() {
|
|
|
1132
1540
|
}
|
|
1133
1541
|
|
|
1134
1542
|
await runInitCommand(parsedInitOptions.targetDirectory, {
|
|
1543
|
+
preset: parsedInitOptions.preset,
|
|
1135
1544
|
profile: parsedInitOptions.profile,
|
|
1136
1545
|
profilePack: parsedInitOptions.profilePack,
|
|
1137
1546
|
stack: parsedInitOptions.stack,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ryuenn3123/agentic-senior-core",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.1",
|
|
4
4
|
"description": "Force your AI Agent to code like a Staff Engineer, not a Junior.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"agentic-senior-core": "bin/agentic-senior-core.js"
|
|
@@ -44,7 +44,9 @@
|
|
|
44
44
|
"gate:release": "node ./scripts/release-gate.mjs",
|
|
45
45
|
"sbom:generate": "node ./scripts/generate-sbom.mjs",
|
|
46
46
|
"benchmark:detection": "node ./scripts/detection-benchmark.mjs",
|
|
47
|
+
"benchmark:gate": "node ./scripts/benchmark-gate.mjs",
|
|
48
|
+
"benchmark:intelligence": "node ./scripts/benchmark-intelligence.mjs",
|
|
47
49
|
"validate": "node ./scripts/validate.mjs",
|
|
48
|
-
"test": "node --test ./tests/cli-smoke.test.mjs ./tests/llm-judge.test.mjs ./tests/enterprise-ops.test.mjs"
|
|
50
|
+
"test": "node --test ./tests/cli-smoke.test.mjs ./tests/llm-judge.test.mjs ./tests/enterprise-ops.test.mjs ./tests/skill-tier-gate.test.mjs"
|
|
49
51
|
}
|
|
50
52
|
}
|