@catladder/cli 0.0.0-next-80fd0ab4 → 0.0.0-next-ebc933f2

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 (35) hide show
  1. package/dist/bundles/catenv/index.js +223 -1
  2. package/dist/bundles/cli/index.js +223 -1
  3. package/dist/bundles/skills/catladder-cli/SKILL.md +53 -0
  4. package/dist/bundles/skills/catladder-cli/references/commands.md +273 -0
  5. package/dist/bundles/skills/catladder-config/SKILL.md +82 -0
  6. package/dist/bundles/skills/catladder-pipelines/SKILL.md +72 -0
  7. package/dist/bundles/skills/catladder-secrets/SKILL.md +74 -0
  8. package/dist/cli/src/scripts/generateCliSkillReference.d.ts +1 -0
  9. package/dist/cli/src/scripts/generateCliSkillReference.js +87 -0
  10. package/dist/cli/src/scripts/generateCliSkillReference.js.map +1 -0
  11. package/dist/pipeline/src/agentSkills/generateAgentSkills.d.ts +22 -0
  12. package/dist/pipeline/src/agentSkills/generateAgentSkills.js +82 -0
  13. package/dist/pipeline/src/agentSkills/generateAgentSkills.js.map +1 -0
  14. package/dist/pipeline/src/agentSkills/index.d.ts +3 -0
  15. package/dist/pipeline/src/agentSkills/index.js +27 -0
  16. package/dist/pipeline/src/agentSkills/index.js.map +1 -0
  17. package/dist/pipeline/src/agentSkills/shippedSkills.d.ts +22 -0
  18. package/dist/pipeline/src/agentSkills/shippedSkills.js +56 -0
  19. package/dist/pipeline/src/agentSkills/shippedSkills.js.map +1 -0
  20. package/dist/pipeline/src/agentSkills/types.d.ts +22 -0
  21. package/dist/pipeline/src/agentSkills/types.js +25 -0
  22. package/dist/pipeline/src/agentSkills/types.js.map +1 -0
  23. package/dist/pipeline/src/constants.js +1 -1
  24. package/dist/pipeline/src/pipeline/generatePipelineFiles.js +4 -0
  25. package/dist/pipeline/src/pipeline/generatePipelineFiles.js.map +1 -1
  26. package/dist/pipeline/src/types/config.d.ts +15 -0
  27. package/dist/pipeline/src/types/config.js.map +1 -1
  28. package/dist/skills/catladder-cli/SKILL.md +53 -0
  29. package/dist/skills/catladder-cli/references/commands.md +273 -0
  30. package/dist/skills/catladder-config/SKILL.md +82 -0
  31. package/dist/skills/catladder-pipelines/SKILL.md +72 -0
  32. package/dist/skills/catladder-secrets/SKILL.md +74 -0
  33. package/dist/tsconfig.tsbuildinfo +1 -1
  34. package/package.json +4 -2
  35. package/src/scripts/generateCliSkillReference.ts +102 -0
@@ -1533,6 +1533,224 @@ exports.updateSecretsCache = updateSecretsCache;
1533
1533
 
1534
1534
  /***/ }),
1535
1535
 
1536
+ /***/ 22383:
1537
+ /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
1538
+
1539
+ "use strict";
1540
+
1541
+
1542
+ Object.defineProperty(exports, "__esModule", ({
1543
+ value: true
1544
+ }));
1545
+ exports.generateAgentSkills = exports.injectGeneratedMarker = exports.AGENT_SKILL_GENERATED_MARKER = void 0;
1546
+ const fs_1 = __nccwpck_require__(79896);
1547
+ const promises_1 = __nccwpck_require__(91943);
1548
+ const path_1 = __nccwpck_require__(16928);
1549
+ const shippedSkills_1 = __nccwpck_require__(49708);
1550
+ const types_1 = __nccwpck_require__(59260);
1551
+ /**
1552
+ * marks a materialized skill file as generated. Cleanup only ever
1553
+ * removes skill directories whose SKILL.md carries this marker, so a
1554
+ * user's own skills are never touched — even if they picked a
1555
+ * `catladder-*` name.
1556
+ */
1557
+ exports.AGENT_SKILL_GENERATED_MARKER = "<!-- 🐱 🔨 generated by catladder — do not edit manually, this file is overwritten on every catenv run -->";
1558
+ /**
1559
+ * inserts the generated-marker into a markdown file: after the YAML
1560
+ * frontmatter when there is one (a leading comment would break
1561
+ * frontmatter parsing), at the top otherwise
1562
+ */
1563
+ const injectGeneratedMarker = content => {
1564
+ if (content.startsWith("---\n")) {
1565
+ const frontmatterEnd = content.indexOf("\n---\n", 3);
1566
+ if (frontmatterEnd !== -1) {
1567
+ const bodyStart = frontmatterEnd + "\n---\n".length;
1568
+ return content.slice(0, bodyStart) + "\n" + exports.AGENT_SKILL_GENERATED_MARKER + "\n" + content.slice(bodyStart);
1569
+ }
1570
+ }
1571
+ return exports.AGENT_SKILL_GENERATED_MARKER + "\n\n" + content;
1572
+ };
1573
+ exports.injectGeneratedMarker = injectGeneratedMarker;
1574
+ /**
1575
+ * removes previously materialized catladder skills from ALL known
1576
+ * target directories (not just the enabled ones), so that opting out
1577
+ * or narrowing the targets doesn't leave stale copies behind
1578
+ */
1579
+ const cleanupGeneratedAgentSkills = async rootDir => {
1580
+ for (const targetDir of Object.values(types_1.AGENT_SKILL_TARGET_DIRS)) {
1581
+ const skillsRoot = (0, path_1.join)(rootDir, targetDir);
1582
+ if (!(0, fs_1.existsSync)(skillsRoot)) continue;
1583
+ for (const entry of await (0, promises_1.readdir)(skillsRoot)) {
1584
+ if (!entry.startsWith(shippedSkills_1.AGENT_SKILL_PREFIX)) continue;
1585
+ const skillMd = (0, path_1.join)(skillsRoot, entry, "SKILL.md");
1586
+ if (!(0, fs_1.existsSync)(skillMd)) continue;
1587
+ const content = await (0, promises_1.readFile)(skillMd, "utf-8");
1588
+ if (!content.includes(exports.AGENT_SKILL_GENERATED_MARKER)) continue;
1589
+ await (0, promises_1.rm)((0, path_1.join)(skillsRoot, entry), {
1590
+ recursive: true,
1591
+ force: true
1592
+ });
1593
+ }
1594
+ }
1595
+ };
1596
+ /**
1597
+ * materializes the agent skills shipped with catladder (usage guides
1598
+ * for AI coding agents) into the repository's agent skill directories,
1599
+ * so agents working in the project use knowledge matching the installed
1600
+ * catladder version. Opt out or narrow the targets via
1601
+ * `agentSkills` in the config.
1602
+ */
1603
+ const generateAgentSkills = async (context, rootDir = ".") => {
1604
+ await cleanupGeneratedAgentSkills(rootDir);
1605
+ const targets = (0, types_1.getAgentSkillTargets)(context.config.agentSkills);
1606
+ if (targets.length === 0) return;
1607
+ const skills = (0, shippedSkills_1.getShippedSkills)();
1608
+ for (const target of targets) {
1609
+ for (const skill of skills) {
1610
+ for (const file of skill.files) {
1611
+ const path = (0, path_1.join)(rootDir, types_1.AGENT_SKILL_TARGET_DIRS[target], skill.name, file.relativePath);
1612
+ await (0, promises_1.mkdir)((0, path_1.dirname)(path), {
1613
+ recursive: true
1614
+ });
1615
+ const content = file.relativePath.endsWith(".md") ? (0, exports.injectGeneratedMarker)(file.content) : file.content;
1616
+ await context.fileWriter.writeGeneratedFileRaw(path, content);
1617
+ }
1618
+ }
1619
+ }
1620
+ };
1621
+ exports.generateAgentSkills = generateAgentSkills;
1622
+
1623
+ /***/ }),
1624
+
1625
+ /***/ 8853:
1626
+ /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
1627
+
1628
+ "use strict";
1629
+
1630
+
1631
+ var __createBinding = this && this.__createBinding || (Object.create ? function (o, m, k, k2) {
1632
+ if (k2 === undefined) k2 = k;
1633
+ var desc = Object.getOwnPropertyDescriptor(m, k);
1634
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
1635
+ desc = {
1636
+ enumerable: true,
1637
+ get: function () {
1638
+ return m[k];
1639
+ }
1640
+ };
1641
+ }
1642
+ Object.defineProperty(o, k2, desc);
1643
+ } : function (o, m, k, k2) {
1644
+ if (k2 === undefined) k2 = k;
1645
+ o[k2] = m[k];
1646
+ });
1647
+ var __exportStar = this && this.__exportStar || function (m, exports) {
1648
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
1649
+ };
1650
+ Object.defineProperty(exports, "__esModule", ({
1651
+ value: true
1652
+ }));
1653
+ __exportStar(__nccwpck_require__(59260), exports);
1654
+ __exportStar(__nccwpck_require__(49708), exports);
1655
+ __exportStar(__nccwpck_require__(22383), exports);
1656
+
1657
+ /***/ }),
1658
+
1659
+ /***/ 49708:
1660
+ /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
1661
+
1662
+ "use strict";
1663
+
1664
+
1665
+ Object.defineProperty(exports, "__esModule", ({
1666
+ value: true
1667
+ }));
1668
+ exports.getShippedSkills = exports.getShippedSkillsDir = exports.AGENT_SKILL_PREFIX = void 0;
1669
+ const fs_1 = __nccwpck_require__(79896);
1670
+ const path_1 = __nccwpck_require__(16928);
1671
+ /**
1672
+ * all catladder skills use this prefix; it marks the namespace
1673
+ * catladder owns inside the agent skill directories (regeneration may
1674
+ * remove stale `catladder-*` skills it generated earlier)
1675
+ */
1676
+ exports.AGENT_SKILL_PREFIX = "catladder-";
1677
+ /**
1678
+ * the directory containing the agent skill definitions shipped with
1679
+ * the package (copied into dist at build time; the repository layout
1680
+ * is the fallback for development and tests)
1681
+ */
1682
+ const getShippedSkillsDir = () => {
1683
+ const candidates = [
1684
+ // built pipeline package: dist/agentSkills -> dist/skills
1685
+ // bundled cli package (what consumers install): the ncc bundles live
1686
+ // in dist/bundles/<name>, so both resolve to dist/bundles/skills
1687
+ (0, path_1.join)(__dirname, "..", "skills"),
1688
+ // cli tsc dist (catenv-dev): dist/pipeline/src/agentSkills -> dist/skills
1689
+ // repository: pipeline/src/agentSkills -> <root>/skills
1690
+ (0, path_1.join)(__dirname, "..", "..", "..", "skills")];
1691
+ const found = candidates.find(candidate => (0, fs_1.existsSync)(candidate));
1692
+ if (!found) {
1693
+ throw new Error("shipped agent skill definitions not found");
1694
+ }
1695
+ return found;
1696
+ };
1697
+ exports.getShippedSkillsDir = getShippedSkillsDir;
1698
+ const readFilesRecursively = (dir, relativeTo) => (0, fs_1.readdirSync)(dir).sort().flatMap(entry => {
1699
+ const fullPath = (0, path_1.join)(dir, entry);
1700
+ if ((0, fs_1.statSync)(fullPath).isDirectory()) {
1701
+ return readFilesRecursively(fullPath, relativeTo);
1702
+ }
1703
+ return [{
1704
+ relativePath: fullPath.slice(relativeTo.length + 1),
1705
+ content: (0, fs_1.readFileSync)(fullPath, "utf-8")
1706
+ }];
1707
+ });
1708
+ const getShippedSkills = () => {
1709
+ const skillsDir = (0, exports.getShippedSkillsDir)();
1710
+ return (0, fs_1.readdirSync)(skillsDir).sort().filter(entry => (0, fs_1.statSync)((0, path_1.join)(skillsDir, entry)).isDirectory()).map(name => {
1711
+ const skillDir = (0, path_1.join)(skillsDir, name);
1712
+ return {
1713
+ name,
1714
+ files: readFilesRecursively(skillDir, skillDir)
1715
+ };
1716
+ });
1717
+ };
1718
+ exports.getShippedSkills = getShippedSkills;
1719
+
1720
+ /***/ }),
1721
+
1722
+ /***/ 59260:
1723
+ /***/ ((__unused_webpack_module, exports) => {
1724
+
1725
+ "use strict";
1726
+
1727
+
1728
+ Object.defineProperty(exports, "__esModule", ({
1729
+ value: true
1730
+ }));
1731
+ exports.getAgentSkillTargets = exports.AGENT_SKILL_TARGET_DIRS = void 0;
1732
+ /**
1733
+ * where agent skills get materialized, per agent ecosystem:
1734
+ * - claude-code: the Claude Code project skills directory
1735
+ * - agents: the cross-agent universal skills directory
1736
+ * (https://agents.md convention, picked up by Cursor, Codex, ...)
1737
+ */
1738
+ exports.AGENT_SKILL_TARGET_DIRS = {
1739
+ "claude-code": ".claude/skills",
1740
+ agents: ".agents/skills"
1741
+ };
1742
+ const getAgentSkillTargets = agentSkills => {
1743
+ var _a;
1744
+ if (agentSkills === false) return [];
1745
+ if (agentSkills === true || agentSkills === undefined) {
1746
+ return Object.keys(exports.AGENT_SKILL_TARGET_DIRS);
1747
+ }
1748
+ return (_a = agentSkills.targets) !== null && _a !== void 0 ? _a : Object.keys(exports.AGENT_SKILL_TARGET_DIRS);
1749
+ };
1750
+ exports.getAgentSkillTargets = getAgentSkillTargets;
1751
+
1752
+ /***/ }),
1753
+
1536
1754
  /***/ 54038:
1537
1755
  /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
1538
1756
 
@@ -5370,7 +5588,7 @@ Object.defineProperty(exports, "__esModule", ({
5370
5588
  value: true
5371
5589
  }));
5372
5590
  exports.DOCKER_REGISTRY = exports.PIPELINE_IMAGE_TAG = void 0;
5373
- exports.PIPELINE_IMAGE_TAG = "next-80fd0ab4" || 0;
5591
+ exports.PIPELINE_IMAGE_TAG = "next-ebc933f2" || 0;
5374
5592
  exports.DOCKER_REGISTRY = "git.panter.ch:5001/catladder/catladder" || 0;
5375
5593
 
5376
5594
  /***/ }),
@@ -9515,6 +9733,7 @@ const backends_1 = __nccwpck_require__(93243);
9515
9733
  const gitlab_1 = __nccwpck_require__(8475);
9516
9734
  const jobImagesPlan_1 = __nccwpck_require__(11585);
9517
9735
  const shippedCatci_1 = __nccwpck_require__(93401);
9736
+ const agentSkills_1 = __nccwpck_require__(8853);
9518
9737
  /**
9519
9738
  * generates the pipeline files of all pipeline types enabled in the
9520
9739
  * config (see `pipelines`). Pass an explicit `pipelineType` to generate
@@ -9536,6 +9755,9 @@ async function generatePipelineFiles(context, pipelineType) {
9536
9755
  recursive: true,
9537
9756
  force: true
9538
9757
  });
9758
+ // agent skills are backend-independent, materialized once per full
9759
+ // generation
9760
+ await (0, agentSkills_1.generateAgentSkills)(context);
9539
9761
  }
9540
9762
  for (const type of pipelineTypes) {
9541
9763
  await generatePipelineFilesForBackend(context, (0, backends_1.getPipelineBackend)(type));
@@ -7581,6 +7581,224 @@ exports.updateSecretsCache = updateSecretsCache;
7581
7581
 
7582
7582
  /***/ }),
7583
7583
 
7584
+ /***/ 22383:
7585
+ /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
7586
+
7587
+ "use strict";
7588
+
7589
+
7590
+ Object.defineProperty(exports, "__esModule", ({
7591
+ value: true
7592
+ }));
7593
+ exports.generateAgentSkills = exports.injectGeneratedMarker = exports.AGENT_SKILL_GENERATED_MARKER = void 0;
7594
+ const fs_1 = __nccwpck_require__(79896);
7595
+ const promises_1 = __nccwpck_require__(91943);
7596
+ const path_1 = __nccwpck_require__(16928);
7597
+ const shippedSkills_1 = __nccwpck_require__(49708);
7598
+ const types_1 = __nccwpck_require__(59260);
7599
+ /**
7600
+ * marks a materialized skill file as generated. Cleanup only ever
7601
+ * removes skill directories whose SKILL.md carries this marker, so a
7602
+ * user's own skills are never touched — even if they picked a
7603
+ * `catladder-*` name.
7604
+ */
7605
+ exports.AGENT_SKILL_GENERATED_MARKER = "<!-- 🐱 🔨 generated by catladder — do not edit manually, this file is overwritten on every catenv run -->";
7606
+ /**
7607
+ * inserts the generated-marker into a markdown file: after the YAML
7608
+ * frontmatter when there is one (a leading comment would break
7609
+ * frontmatter parsing), at the top otherwise
7610
+ */
7611
+ const injectGeneratedMarker = content => {
7612
+ if (content.startsWith("---\n")) {
7613
+ const frontmatterEnd = content.indexOf("\n---\n", 3);
7614
+ if (frontmatterEnd !== -1) {
7615
+ const bodyStart = frontmatterEnd + "\n---\n".length;
7616
+ return content.slice(0, bodyStart) + "\n" + exports.AGENT_SKILL_GENERATED_MARKER + "\n" + content.slice(bodyStart);
7617
+ }
7618
+ }
7619
+ return exports.AGENT_SKILL_GENERATED_MARKER + "\n\n" + content;
7620
+ };
7621
+ exports.injectGeneratedMarker = injectGeneratedMarker;
7622
+ /**
7623
+ * removes previously materialized catladder skills from ALL known
7624
+ * target directories (not just the enabled ones), so that opting out
7625
+ * or narrowing the targets doesn't leave stale copies behind
7626
+ */
7627
+ const cleanupGeneratedAgentSkills = async rootDir => {
7628
+ for (const targetDir of Object.values(types_1.AGENT_SKILL_TARGET_DIRS)) {
7629
+ const skillsRoot = (0, path_1.join)(rootDir, targetDir);
7630
+ if (!(0, fs_1.existsSync)(skillsRoot)) continue;
7631
+ for (const entry of await (0, promises_1.readdir)(skillsRoot)) {
7632
+ if (!entry.startsWith(shippedSkills_1.AGENT_SKILL_PREFIX)) continue;
7633
+ const skillMd = (0, path_1.join)(skillsRoot, entry, "SKILL.md");
7634
+ if (!(0, fs_1.existsSync)(skillMd)) continue;
7635
+ const content = await (0, promises_1.readFile)(skillMd, "utf-8");
7636
+ if (!content.includes(exports.AGENT_SKILL_GENERATED_MARKER)) continue;
7637
+ await (0, promises_1.rm)((0, path_1.join)(skillsRoot, entry), {
7638
+ recursive: true,
7639
+ force: true
7640
+ });
7641
+ }
7642
+ }
7643
+ };
7644
+ /**
7645
+ * materializes the agent skills shipped with catladder (usage guides
7646
+ * for AI coding agents) into the repository's agent skill directories,
7647
+ * so agents working in the project use knowledge matching the installed
7648
+ * catladder version. Opt out or narrow the targets via
7649
+ * `agentSkills` in the config.
7650
+ */
7651
+ const generateAgentSkills = async (context, rootDir = ".") => {
7652
+ await cleanupGeneratedAgentSkills(rootDir);
7653
+ const targets = (0, types_1.getAgentSkillTargets)(context.config.agentSkills);
7654
+ if (targets.length === 0) return;
7655
+ const skills = (0, shippedSkills_1.getShippedSkills)();
7656
+ for (const target of targets) {
7657
+ for (const skill of skills) {
7658
+ for (const file of skill.files) {
7659
+ const path = (0, path_1.join)(rootDir, types_1.AGENT_SKILL_TARGET_DIRS[target], skill.name, file.relativePath);
7660
+ await (0, promises_1.mkdir)((0, path_1.dirname)(path), {
7661
+ recursive: true
7662
+ });
7663
+ const content = file.relativePath.endsWith(".md") ? (0, exports.injectGeneratedMarker)(file.content) : file.content;
7664
+ await context.fileWriter.writeGeneratedFileRaw(path, content);
7665
+ }
7666
+ }
7667
+ }
7668
+ };
7669
+ exports.generateAgentSkills = generateAgentSkills;
7670
+
7671
+ /***/ }),
7672
+
7673
+ /***/ 8853:
7674
+ /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
7675
+
7676
+ "use strict";
7677
+
7678
+
7679
+ var __createBinding = this && this.__createBinding || (Object.create ? function (o, m, k, k2) {
7680
+ if (k2 === undefined) k2 = k;
7681
+ var desc = Object.getOwnPropertyDescriptor(m, k);
7682
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7683
+ desc = {
7684
+ enumerable: true,
7685
+ get: function () {
7686
+ return m[k];
7687
+ }
7688
+ };
7689
+ }
7690
+ Object.defineProperty(o, k2, desc);
7691
+ } : function (o, m, k, k2) {
7692
+ if (k2 === undefined) k2 = k;
7693
+ o[k2] = m[k];
7694
+ });
7695
+ var __exportStar = this && this.__exportStar || function (m, exports) {
7696
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
7697
+ };
7698
+ Object.defineProperty(exports, "__esModule", ({
7699
+ value: true
7700
+ }));
7701
+ __exportStar(__nccwpck_require__(59260), exports);
7702
+ __exportStar(__nccwpck_require__(49708), exports);
7703
+ __exportStar(__nccwpck_require__(22383), exports);
7704
+
7705
+ /***/ }),
7706
+
7707
+ /***/ 49708:
7708
+ /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
7709
+
7710
+ "use strict";
7711
+
7712
+
7713
+ Object.defineProperty(exports, "__esModule", ({
7714
+ value: true
7715
+ }));
7716
+ exports.getShippedSkills = exports.getShippedSkillsDir = exports.AGENT_SKILL_PREFIX = void 0;
7717
+ const fs_1 = __nccwpck_require__(79896);
7718
+ const path_1 = __nccwpck_require__(16928);
7719
+ /**
7720
+ * all catladder skills use this prefix; it marks the namespace
7721
+ * catladder owns inside the agent skill directories (regeneration may
7722
+ * remove stale `catladder-*` skills it generated earlier)
7723
+ */
7724
+ exports.AGENT_SKILL_PREFIX = "catladder-";
7725
+ /**
7726
+ * the directory containing the agent skill definitions shipped with
7727
+ * the package (copied into dist at build time; the repository layout
7728
+ * is the fallback for development and tests)
7729
+ */
7730
+ const getShippedSkillsDir = () => {
7731
+ const candidates = [
7732
+ // built pipeline package: dist/agentSkills -> dist/skills
7733
+ // bundled cli package (what consumers install): the ncc bundles live
7734
+ // in dist/bundles/<name>, so both resolve to dist/bundles/skills
7735
+ (0, path_1.join)(__dirname, "..", "skills"),
7736
+ // cli tsc dist (catenv-dev): dist/pipeline/src/agentSkills -> dist/skills
7737
+ // repository: pipeline/src/agentSkills -> <root>/skills
7738
+ (0, path_1.join)(__dirname, "..", "..", "..", "skills")];
7739
+ const found = candidates.find(candidate => (0, fs_1.existsSync)(candidate));
7740
+ if (!found) {
7741
+ throw new Error("shipped agent skill definitions not found");
7742
+ }
7743
+ return found;
7744
+ };
7745
+ exports.getShippedSkillsDir = getShippedSkillsDir;
7746
+ const readFilesRecursively = (dir, relativeTo) => (0, fs_1.readdirSync)(dir).sort().flatMap(entry => {
7747
+ const fullPath = (0, path_1.join)(dir, entry);
7748
+ if ((0, fs_1.statSync)(fullPath).isDirectory()) {
7749
+ return readFilesRecursively(fullPath, relativeTo);
7750
+ }
7751
+ return [{
7752
+ relativePath: fullPath.slice(relativeTo.length + 1),
7753
+ content: (0, fs_1.readFileSync)(fullPath, "utf-8")
7754
+ }];
7755
+ });
7756
+ const getShippedSkills = () => {
7757
+ const skillsDir = (0, exports.getShippedSkillsDir)();
7758
+ return (0, fs_1.readdirSync)(skillsDir).sort().filter(entry => (0, fs_1.statSync)((0, path_1.join)(skillsDir, entry)).isDirectory()).map(name => {
7759
+ const skillDir = (0, path_1.join)(skillsDir, name);
7760
+ return {
7761
+ name,
7762
+ files: readFilesRecursively(skillDir, skillDir)
7763
+ };
7764
+ });
7765
+ };
7766
+ exports.getShippedSkills = getShippedSkills;
7767
+
7768
+ /***/ }),
7769
+
7770
+ /***/ 59260:
7771
+ /***/ ((__unused_webpack_module, exports) => {
7772
+
7773
+ "use strict";
7774
+
7775
+
7776
+ Object.defineProperty(exports, "__esModule", ({
7777
+ value: true
7778
+ }));
7779
+ exports.getAgentSkillTargets = exports.AGENT_SKILL_TARGET_DIRS = void 0;
7780
+ /**
7781
+ * where agent skills get materialized, per agent ecosystem:
7782
+ * - claude-code: the Claude Code project skills directory
7783
+ * - agents: the cross-agent universal skills directory
7784
+ * (https://agents.md convention, picked up by Cursor, Codex, ...)
7785
+ */
7786
+ exports.AGENT_SKILL_TARGET_DIRS = {
7787
+ "claude-code": ".claude/skills",
7788
+ agents: ".agents/skills"
7789
+ };
7790
+ const getAgentSkillTargets = agentSkills => {
7791
+ var _a;
7792
+ if (agentSkills === false) return [];
7793
+ if (agentSkills === true || agentSkills === undefined) {
7794
+ return Object.keys(exports.AGENT_SKILL_TARGET_DIRS);
7795
+ }
7796
+ return (_a = agentSkills.targets) !== null && _a !== void 0 ? _a : Object.keys(exports.AGENT_SKILL_TARGET_DIRS);
7797
+ };
7798
+ exports.getAgentSkillTargets = getAgentSkillTargets;
7799
+
7800
+ /***/ }),
7801
+
7584
7802
  /***/ 54038:
7585
7803
  /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
7586
7804
 
@@ -11418,7 +11636,7 @@ Object.defineProperty(exports, "__esModule", ({
11418
11636
  value: true
11419
11637
  }));
11420
11638
  exports.DOCKER_REGISTRY = exports.PIPELINE_IMAGE_TAG = void 0;
11421
- exports.PIPELINE_IMAGE_TAG = "next-80fd0ab4" || 0;
11639
+ exports.PIPELINE_IMAGE_TAG = "next-ebc933f2" || 0;
11422
11640
  exports.DOCKER_REGISTRY = "git.panter.ch:5001/catladder/catladder" || 0;
11423
11641
 
11424
11642
  /***/ }),
@@ -15563,6 +15781,7 @@ const backends_1 = __nccwpck_require__(93243);
15563
15781
  const gitlab_1 = __nccwpck_require__(8475);
15564
15782
  const jobImagesPlan_1 = __nccwpck_require__(11585);
15565
15783
  const shippedCatci_1 = __nccwpck_require__(93401);
15784
+ const agentSkills_1 = __nccwpck_require__(8853);
15566
15785
  /**
15567
15786
  * generates the pipeline files of all pipeline types enabled in the
15568
15787
  * config (see `pipelines`). Pass an explicit `pipelineType` to generate
@@ -15584,6 +15803,9 @@ async function generatePipelineFiles(context, pipelineType) {
15584
15803
  recursive: true,
15585
15804
  force: true
15586
15805
  });
15806
+ // agent skills are backend-independent, materialized once per full
15807
+ // generation
15808
+ await (0, agentSkills_1.generateAgentSkills)(context);
15587
15809
  }
15588
15810
  for (const type of pipelineTypes) {
15589
15811
  await generatePipelineFilesForBackend(context, (0, backends_1.getPipelineBackend)(type));
@@ -0,0 +1,53 @@
1
+ ---
2
+ name: catladder-cli
3
+ description: How to invoke the catladder CLI non-interactively — command structure, passing inputs via flags or --inputs JSON, skipping prompts, and the full generated command reference. Use when running any `catladder` command (project setup, doctor, secrets, k8s, ci, cloudsql, mongo) or when unsure which catladder command exists for a task. Triggers on "catladder command", "yarn catladder", "project doctor", "project setup", "run catladder".
4
+ ---
5
+
6
+ # Using the catladder CLI
7
+
8
+ catladder is installed per project — invoke it as `yarn catladder`
9
+ (never a globally installed copy). Every command can run
10
+ non-interactively, which is the mode agents should use.
11
+
12
+ ## Invocation
13
+
14
+ ```sh
15
+ yarn catladder <command...> [args] [flags]
16
+
17
+ # examples
18
+ yarn catladder project doctor
19
+ yarn catladder project ci job-log
20
+ yarn catladder --help # command tree
21
+ yarn catladder project --help # subcommands of a group
22
+ ```
23
+
24
+ ## Passing inputs
25
+
26
+ Commands declare typed inputs. Any input not provided on the command
27
+ line is prompted for interactively — in a non-interactive context
28
+ (agents!) provide them up front:
29
+
30
+ - positional inputs: `yarn catladder project k8s list-pods dev:api`
31
+ - flag per input: `--some-input value` (kebab-case of the input name),
32
+ booleans as `--flag` / `--no-flag`
33
+ - all at once as JSON: `--inputs '{"envComponent": "dev:api"}'`
34
+ - `-y` / `--yes` skips confirmation prompts
35
+
36
+ A missing required input fails with a message naming the exact flag to
37
+ pass. Environment/component selectors use the `env:component` form
38
+ (e.g. `dev:api`, `review-123:www`).
39
+
40
+ Some commands are inherently interactive (e.g.
41
+ `project config-secrets` opens `$EDITOR`) — ask the user to run those.
42
+
43
+ ## Command reference
44
+
45
+ See [references/commands.md](references/commands.md) for all commands
46
+ with their descriptions and inputs (generated from the CLI itself, so
47
+ it matches the installed version).
48
+
49
+ ## Related skills
50
+
51
+ - `catladder-config` — catladder.ts structure and regeneration
52
+ - `catladder-secrets` — env vars and secret management
53
+ - `catladder-pipelines` — pipeline behavior and CI debugging