@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.
Files changed (52) hide show
  1. package/.agent-context/blueprints/mobile-app.md +21 -0
  2. package/.agent-context/review-checklists/frontend-skill-parity.md +28 -0
  3. package/.agent-context/skills/README.md +63 -0
  4. package/.agent-context/skills/backend/README.md +68 -0
  5. package/.agent-context/skills/backend/architecture.md +361 -0
  6. package/.agent-context/skills/backend/data-access.md +231 -0
  7. package/.agent-context/skills/backend/errors.md +138 -0
  8. package/.agent-context/skills/backend/validation.md +117 -0
  9. package/.agent-context/skills/backend.md +29 -0
  10. package/.agent-context/skills/cli/README.md +50 -0
  11. package/.agent-context/skills/cli/init.md +38 -0
  12. package/.agent-context/skills/cli/output.md +36 -0
  13. package/.agent-context/skills/cli/upgrade.md +38 -0
  14. package/.agent-context/skills/cli.md +29 -0
  15. package/.agent-context/skills/distribution/README.md +19 -0
  16. package/.agent-context/skills/distribution/compatibility.md +32 -0
  17. package/.agent-context/skills/distribution/publish.md +37 -0
  18. package/.agent-context/skills/distribution/rollback.md +32 -0
  19. package/.agent-context/skills/distribution.md +29 -0
  20. package/.agent-context/skills/frontend/README.md +36 -0
  21. package/.agent-context/skills/frontend/accessibility.md +107 -0
  22. package/.agent-context/skills/frontend/motion.md +67 -0
  23. package/.agent-context/skills/frontend/performance.md +63 -0
  24. package/.agent-context/skills/frontend/ui-architecture.md +128 -0
  25. package/.agent-context/skills/frontend.md +30 -0
  26. package/.agent-context/skills/fullstack/README.md +19 -0
  27. package/.agent-context/skills/fullstack/contracts.md +53 -0
  28. package/.agent-context/skills/fullstack/end-to-end.md +42 -0
  29. package/.agent-context/skills/fullstack/feature-slicing.md +65 -0
  30. package/.agent-context/skills/fullstack.md +27 -0
  31. package/.agent-context/skills/index.json +107 -0
  32. package/.agent-context/skills/review-quality/README.md +19 -0
  33. package/.agent-context/skills/review-quality/benchmark.md +30 -0
  34. package/.agent-context/skills/review-quality/planning.md +38 -0
  35. package/.agent-context/skills/review-quality/security.md +34 -0
  36. package/.agent-context/skills/review-quality.md +28 -0
  37. package/.agent-context/stacks/flutter.md +16 -0
  38. package/.agent-context/stacks/react-native.md +16 -0
  39. package/.agent-context/state/benchmark-analysis.json +431 -0
  40. package/.agent-context/state/benchmark-thresholds.json +10 -0
  41. package/.agent-context/state/benchmark-watchlist.json +19 -0
  42. package/.agent-context/state/skill-platform.json +38 -0
  43. package/.cursorrules +1 -1
  44. package/.github/workflows/benchmark-intelligence.yml +50 -0
  45. package/.windsurfrules +1 -1
  46. package/README.md +81 -2
  47. package/bin/agentic-senior-core.js +412 -3
  48. package/package.json +4 -2
  49. package/scripts/benchmark-gate.mjs +121 -0
  50. package/scripts/benchmark-intelligence.mjs +140 -0
  51. package/scripts/skill-tier-policy.mjs +76 -0
  52. 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 init [target-directory] [--profile <beginner|balanced|strict>] [--profile-pack <name>] [--stack <name>] [--blueprint <name>] [--ci <true|false>] [--newbie]");
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 || commandArgument === "--help" || commandArgument === "-h") {
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.0",
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
  }