@aisdlc/core 2.2.2 → 2.2.4

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/dist/index.cjs CHANGED
@@ -9824,10 +9824,39 @@ function computeReworkRatios(totalTime, totalTokens, totalCost, reworkTime, rewo
9824
9824
  costPercent: totalCost > 0 ? Math.round(reworkCost / totalCost * 1e4) / 100 : 0
9825
9825
  };
9826
9826
  }
9827
- function aggregateReleaseKpis(releaseBranch, baseBranch = "main", options = {}) {
9827
+ function resolveReleaseBaseBranch(release, explicitBase, options = {}) {
9828
9828
  const cwd = options.cwd || process.cwd();
9829
+ if (explicitBase && explicitBase !== release) {
9830
+ return explicitBase;
9831
+ }
9832
+ if (release !== "main" && release !== "master") {
9833
+ return "main";
9834
+ }
9835
+ try {
9836
+ const lastTag = child_process.execFileSync("git", ["describe", "--tags", "--abbrev=0", `${release}^`], {
9837
+ cwd,
9838
+ encoding: "utf-8",
9839
+ stdio: ["pipe", "pipe", "pipe"]
9840
+ }).trim();
9841
+ if (lastTag) return lastTag;
9842
+ } catch {
9843
+ }
9844
+ try {
9845
+ const rootSha = child_process.execFileSync("git", ["rev-list", "--max-parents=0", release], {
9846
+ cwd,
9847
+ encoding: "utf-8",
9848
+ stdio: ["pipe", "pipe", "pipe"]
9849
+ }).trim().split("\n")[0];
9850
+ if (rootSha) return rootSha;
9851
+ } catch {
9852
+ }
9853
+ return release;
9854
+ }
9855
+ function aggregateReleaseKpis(releaseBranch, baseBranch, options = {}) {
9856
+ const cwd = options.cwd || process.cwd();
9857
+ const effectiveBase = resolveReleaseBaseBranch(releaseBranch, baseBranch, { cwd });
9829
9858
  const resolvedRelease = resolveGitRef(cwd, releaseBranch);
9830
- const resolvedBase = resolveGitRef(cwd, baseBranch);
9859
+ const resolvedBase = resolveGitRef(cwd, effectiveBase);
9831
9860
  const records = extractCommitKpisFromRange(resolvedBase, resolvedRelease, options);
9832
9861
  const statsMap = {};
9833
9862
  const bugList = [];
@@ -12400,33 +12429,42 @@ function resolveActiveBranch(rootDir) {
12400
12429
  return "HEAD";
12401
12430
  }
12402
12431
  }
12403
- function resolveDefaultBranchBase(rootDir) {
12432
+ function resolveRootCommit(rootDir, targetRef) {
12404
12433
  try {
12405
- const count = parseInt(
12406
- child_process.execFileSync("git", ["rev-list", "--count", "HEAD"], {
12407
- cwd: rootDir,
12408
- encoding: "utf-8",
12409
- stdio: ["pipe", "pipe", "pipe"]
12410
- }).trim(),
12411
- 10
12412
- );
12413
- if (count <= 20) {
12414
- return child_process.execFileSync("git", ["rev-list", "--max-parents=0", "HEAD"], {
12434
+ return child_process.execFileSync("git", ["rev-list", "--max-parents=0", targetRef], {
12435
+ cwd: rootDir,
12436
+ encoding: "utf-8",
12437
+ stdio: ["pipe", "pipe", "pipe"]
12438
+ }).trim().split("\n")[0] || targetRef;
12439
+ } catch {
12440
+ return targetRef;
12441
+ }
12442
+ }
12443
+ function resolveDefaultBranchBase(rootDir, targetRef = "HEAD") {
12444
+ try {
12445
+ const rawCount = child_process.execFileSync("git", ["rev-list", "--count", "--first-parent", targetRef], {
12446
+ cwd: rootDir,
12447
+ encoding: "utf-8",
12448
+ stdio: ["pipe", "pipe", "pipe"]
12449
+ }).trim();
12450
+ const firstParentCount = parseInt(rawCount, 10);
12451
+ if (firstParentCount > 20) {
12452
+ const candidateRef = `${targetRef}~20`;
12453
+ child_process.execFileSync("git", ["rev-parse", "--verify", "--quiet", candidateRef], {
12415
12454
  cwd: rootDir,
12416
- encoding: "utf-8",
12417
12455
  stdio: ["pipe", "pipe", "pipe"]
12418
- }).trim().split("\n")[0];
12456
+ });
12457
+ return candidateRef;
12419
12458
  }
12420
- return "HEAD~20";
12421
12459
  } catch {
12422
- return "HEAD~1";
12423
12460
  }
12461
+ return resolveRootCommit(rootDir, targetRef);
12424
12462
  }
12425
12463
  function resolveActivePrKpi(rootDir, activeBranch) {
12426
12464
  try {
12427
12465
  const isDefaultBranch = activeBranch === "main" || activeBranch === "master";
12428
12466
  if (isDefaultBranch) {
12429
- const base = resolveDefaultBranchBase(rootDir);
12467
+ const base = resolveDefaultBranchBase(rootDir, "HEAD");
12430
12468
  return aggregatePrKpis(base, "HEAD", { cwd: rootDir });
12431
12469
  }
12432
12470
  const prKpi = aggregatePrKpis("main", "HEAD", { cwd: rootDir });
@@ -12481,7 +12519,7 @@ function resolveCandidateBranches(rootDir, activeBranch, history) {
12481
12519
  function fetchBranchKpi(rootDir, branch) {
12482
12520
  try {
12483
12521
  const isDefault = branch === "main" || branch === "master";
12484
- const base = isDefault ? resolveDefaultBranchBase(rootDir) : "main";
12522
+ const base = isDefault ? resolveDefaultBranchBase(rootDir, branch) : "main";
12485
12523
  const kpi = aggregatePrKpis(base, branch, { cwd: rootDir });
12486
12524
  return kpi && kpi.totalCommits > 0 ? kpi : null;
12487
12525
  } catch {
@@ -13052,6 +13090,7 @@ var LIFECYCLE_SKILL_TEMPLATES = [
13052
13090
  title: "Greenfield Project Inception & Delivery Playbook",
13053
13091
  description: "Orchestrate end-to-end AI-SDLC onboarding and Phase 0 Inception for brand-new (Greenfield) projects, from repository initialization (aisdlc init) and NAF v4 Vision (ARCH-INTRO-*) through ProductShape, STRIDE Threat Modeling, arc42 Architecture, and initial SDD increment delivery.",
13054
13092
  references: "[`process/02_product_definition.md`](../../process/02_product_definition.md), [`process/04b_data_protection_and_privacy.md`](../../process/04b_data_protection_and_privacy.md), [`process/05_architecture_arc42_nafv4.md`](../../process/05_architecture_arc42_nafv4.md), [`process/06_spec_driven_development.md`](../../process/06_spec_driven_development.md), and [`process/09_agent_protocols.md`](../../process/09_agent_protocols.md).",
13093
+ globs: "product/**, specs/product/**, architecture/**, templates/**",
13055
13094
  body: `## Purpose & Trigger
13056
13095
  Use this skill when starting a **brand-new software project from scratch (Greenfield)** or when \`specs/product/\` has no canonical baseline yet. It coordinates the sequential execution of AI-SDLC MCP/CLI tools and specialized role agents so no code is written before product vision, security enclaves, privacy-by-design controls, and architecture contracts exist.
13057
13096
 
@@ -13109,6 +13148,7 @@ Use this skill when starting a **brand-new software project from scratch (Greenf
13109
13148
  title: "Legacy / Brownfield Retro-Inception Playbook",
13110
13149
  description: "Orchestrate progressive AI-SDLC adoption and Brownfield retro-inception on existing or legacy repositories without breaking production code, reverse-engineering architecture (ARCH-INTRO-*, CMP-*) and establishing baseline quality, security, and license audits before new SDD increments.",
13111
13150
  references: "[`process/02_product_definition.md`](../../process/02_product_definition.md), [`process/04_open_source_license_compliance.md`](../../process/04_open_source_license_compliance.md), [`process/04b_data_protection_and_privacy.md`](../../process/04b_data_protection_and_privacy.md), [`process/05_architecture_arc42_nafv4.md`](../../process/05_architecture_arc42_nafv4.md), [`process/10_quality_management_and_release_gates.md`](../../process/10_quality_management_and_release_gates.md), and [`process/09_agent_protocols.md`](../../process/09_agent_protocols.md).",
13151
+ globs: "architecture/**, specs/**, src/**, packages/**",
13112
13152
  body: `## Purpose & Trigger
13113
13153
  Use this skill when **adopting AI-SDLC in an existing or legacy codebase (Brownfield)** that already has production source code (\`src/\`, \`packages/\`, etc.) but lacks canonical PDaC specifications, arc42 architecture views, or deterministic quality/license/privacy gates.
13114
13154
 
@@ -13150,6 +13190,7 @@ Once the target domain's baseline artifacts (\`ARCH-INTRO-*\`, \`UC-*\`, \`FR-*\
13150
13190
  title: "Bounded SDD Feature & Bugfix Delivery Playbook",
13151
13191
  description: "Orchestrate the complete Spec-Driven Development (SDD) lifecycle for bounded feature increments, enhancements, and bugfixes (CHG-* / TSK-*), from upstream requirement derivation and 4-tier Git branching through Red-Green-Refactor TDD, Pre-Merge Audit Triad, all 11 Quality Gates, and canonical baseline integration.",
13152
13192
  references: "[`process/06_spec_driven_development.md`](../../process/06_spec_driven_development.md), [`process/08_citation_contract_and_drift.md`](../../process/08_citation_contract_and_drift.md), [`process/10_quality_management_and_release_gates.md`](../../process/10_quality_management_and_release_gates.md), [`process/11_git_branching_and_lifecycle.md`](../../process/11_git_branching_and_lifecycle.md), and [`process/09_agent_protocols.md`](../../process/09_agent_protocols.md).",
13193
+ globs: "specs/changes/**, src/**, packages/**, tests/**",
13153
13194
  body: `## Purpose & Trigger
13154
13195
  Use this skill for **every evolutionary increment (new feature, enhancement, refactoring, or bugfix)** on a project that already has an AI-SDLC baseline. It enforces strict 360\xB0 traceability from upstream ProductShape (\`UC-*\`, \`FR-*\`) through SDD (\`CHG-*\`, \`HOF-*\`, \`TSK-*\`), TDD implementation, the 12 Quality Gates, and baseline promotion.
13155
13196
 
@@ -13223,6 +13264,47 @@ description: >-
13223
13264
 
13224
13265
  Canonical Reference: ${skill.references}
13225
13266
 
13267
+ ${skill.body}
13268
+ `;
13269
+ }
13270
+ function renderCursorSkillFile(skill) {
13271
+ const globs = skill.globs || "";
13272
+ return `---
13273
+ description: ${skill.id} (${skill.title}) - ${skill.description}
13274
+ globs: ${globs}
13275
+ alwaysApply: false
13276
+ ---
13277
+
13278
+ # ${skill.id} (${skill.title})
13279
+
13280
+ Canonical Reference: ${skill.references}
13281
+
13282
+ ${skill.body}
13283
+ `;
13284
+ }
13285
+ function renderClaudeSkillFile(skill) {
13286
+ return `---
13287
+ name: ${skill.id}
13288
+ description: ${skill.description}
13289
+ ---
13290
+
13291
+ # ${skill.id} (${skill.title})
13292
+
13293
+ Canonical Reference: ${skill.references}
13294
+
13295
+ ${skill.body}
13296
+ `;
13297
+ }
13298
+ function renderCopilotSkillFile(skill) {
13299
+ return `---
13300
+ name: ${skill.id}
13301
+ description: ${skill.description}
13302
+ ---
13303
+
13304
+ # ${skill.id} (${skill.title})
13305
+
13306
+ Canonical Reference: ${skill.references}
13307
+
13226
13308
  ${skill.body}
13227
13309
  `;
13228
13310
  }
@@ -15574,12 +15656,24 @@ function appendCursorFiles(dirs, files) {
15574
15656
  for (const agent of SPECIALIZED_AGENT_TEMPLATES) {
15575
15657
  files.push({ relPath: `.cursor/rules/${agent.id}.mdc`, content: renderCursorAgentFile(agent) });
15576
15658
  }
15659
+ for (const skill of LIFECYCLE_SKILL_TEMPLATES) {
15660
+ files.push({ relPath: `.cursor/rules/${skill.id}.mdc`, content: renderCursorSkillFile(skill) });
15661
+ }
15577
15662
  }
15578
15663
  function appendClaudeFiles(dirs, files) {
15579
- dirs.push(".claude/agents");
15664
+ dirs.push(".claude/agents", ".claude/skills");
15580
15665
  files.push({ relPath: "CLAUDE.md", content: STARTER_CLAUDE_RULES });
15581
15666
  for (const agent of SPECIALIZED_AGENT_TEMPLATES) {
15582
- files.push({ relPath: `.claude/agents/${agent.id}.md`, content: renderClaudeAgentFile(agent) });
15667
+ const content = renderClaudeAgentFile(agent);
15668
+ dirs.push(`.claude/skills/${agent.id}`);
15669
+ files.push(
15670
+ { relPath: `.claude/agents/${agent.id}.md`, content },
15671
+ { relPath: `.claude/skills/${agent.id}/SKILL.md`, content }
15672
+ );
15673
+ }
15674
+ for (const skill of LIFECYCLE_SKILL_TEMPLATES) {
15675
+ dirs.push(`.claude/skills/${skill.id}`);
15676
+ files.push({ relPath: `.claude/skills/${skill.id}/SKILL.md`, content: renderClaudeSkillFile(skill) });
15583
15677
  }
15584
15678
  }
15585
15679
  function appendCopilotFiles(dirs, files) {
@@ -15588,6 +15682,9 @@ function appendCopilotFiles(dirs, files) {
15588
15682
  for (const agent of SPECIALIZED_AGENT_TEMPLATES) {
15589
15683
  files.push({ relPath: `.github/agents/${agent.id}.agent.md`, content: renderCopilotAgentFile(agent) });
15590
15684
  }
15685
+ for (const skill of LIFECYCLE_SKILL_TEMPLATES) {
15686
+ files.push({ relPath: `.github/agents/${skill.id}.agent.md`, content: renderCopilotSkillFile(skill) });
15687
+ }
15591
15688
  }
15592
15689
  function isTargetIncluded(targets, name) {
15593
15690
  return targets.has("all") || targets.has(name);
@@ -16094,17 +16191,22 @@ exports.renderAntigravityAgentFile = renderAntigravityAgentFile;
16094
16191
  exports.renderAntigravitySkillFile = renderAntigravitySkillFile;
16095
16192
  exports.renderAutonomyModeSection = renderAutonomyModeSection;
16096
16193
  exports.renderClaudeAgentFile = renderClaudeAgentFile;
16194
+ exports.renderClaudeSkillFile = renderClaudeSkillFile;
16097
16195
  exports.renderCopilotAgentFile = renderCopilotAgentFile;
16196
+ exports.renderCopilotSkillFile = renderCopilotSkillFile;
16098
16197
  exports.renderCursorAgentFile = renderCursorAgentFile;
16198
+ exports.renderCursorSkillFile = renderCursorSkillFile;
16099
16199
  exports.renderDashboardHtml = renderDashboardHtml;
16100
16200
  exports.renderManualsTab = renderManualsTab;
16101
16201
  exports.resolveAgentTargets = resolveAgentTargets;
16102
16202
  exports.resolveBranchHierarchy = resolveBranchHierarchy;
16103
16203
  exports.resolveCiEnvironment = resolveCiEnvironment;
16104
16204
  exports.resolveCytoscapePath = resolveCytoscapePath;
16205
+ exports.resolveDefaultBranchBase = resolveDefaultBranchBase;
16105
16206
  exports.resolveFeatureFilePath = resolveFeatureFilePath;
16106
16207
  exports.resolveGitRef = resolveGitRef;
16107
16208
  exports.resolveLicenseFromFile = resolveLicenseFromFile;
16209
+ exports.resolveReleaseBaseBranch = resolveReleaseBaseBranch;
16108
16210
  exports.resolveSastCwe = resolveSastCwe;
16109
16211
  exports.resolveSastOwasp = resolveSastOwasp;
16110
16212
  exports.resolveSchemaForArtifact = resolveSchemaForArtifact;