claude-skills-cli 0.0.20 → 0.0.22

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 (81) hide show
  1. package/dist/add-hook.cmd-JWw5UqA3.js +193 -0
  2. package/dist/add-hook.cmd-JWw5UqA3.js.map +1 -0
  3. package/dist/dependency-validator-CQJ1hCoU.js +382 -0
  4. package/dist/dependency-validator-CQJ1hCoU.js.map +1 -0
  5. package/dist/doctor.cmd-DJpHLDCV.js +142 -0
  6. package/dist/doctor.cmd-DJpHLDCV.js.map +1 -0
  7. package/dist/fs-CuGv3Ob2.js +23 -0
  8. package/dist/fs-CuGv3Ob2.js.map +1 -0
  9. package/dist/index.js +24 -22
  10. package/dist/index.js.map +1 -1
  11. package/dist/init.cmd-BdqImX8b.js +108 -0
  12. package/dist/init.cmd-BdqImX8b.js.map +1 -0
  13. package/dist/install.cmd-BaP8k9d2.js +79 -0
  14. package/dist/install.cmd-BaP8k9d2.js.map +1 -0
  15. package/dist/output-DiffPD2u.js +104 -0
  16. package/dist/output-DiffPD2u.js.map +1 -0
  17. package/dist/package.cmd-BYhkheya.js +107 -0
  18. package/dist/package.cmd-BYhkheya.js.map +1 -0
  19. package/dist/stats.cmd-Dd46qjoV.js +154 -0
  20. package/dist/stats.cmd-Dd46qjoV.js.map +1 -0
  21. package/dist/{core/templates.js → templates-fyteNbD0.js} +20 -13
  22. package/dist/templates-fyteNbD0.js.map +1 -0
  23. package/dist/validate.cmd-BxF4HNsu.js +96 -0
  24. package/dist/validate.cmd-BxF4HNsu.js.map +1 -0
  25. package/dist/validator-Dp5x-OjP.js +729 -0
  26. package/dist/validator-Dp5x-OjP.js.map +1 -0
  27. package/package.json +34 -35
  28. package/dist/commands/add-hook.cmd.js +0 -35
  29. package/dist/commands/add-hook.cmd.js.map +0 -1
  30. package/dist/commands/add-hook.js +0 -216
  31. package/dist/commands/add-hook.js.map +0 -1
  32. package/dist/commands/doctor.cmd.js +0 -19
  33. package/dist/commands/doctor.cmd.js.map +0 -1
  34. package/dist/commands/doctor.js +0 -128
  35. package/dist/commands/doctor.js.map +0 -1
  36. package/dist/commands/init.cmd.js +0 -37
  37. package/dist/commands/init.cmd.js.map +0 -1
  38. package/dist/commands/init.js +0 -86
  39. package/dist/commands/init.js.map +0 -1
  40. package/dist/commands/install.cmd.js +0 -23
  41. package/dist/commands/install.cmd.js.map +0 -1
  42. package/dist/commands/install.js +0 -64
  43. package/dist/commands/install.js.map +0 -1
  44. package/dist/commands/package.cmd.js +0 -28
  45. package/dist/commands/package.cmd.js.map +0 -1
  46. package/dist/commands/package.js +0 -134
  47. package/dist/commands/package.js.map +0 -1
  48. package/dist/commands/stats.cmd.js +0 -19
  49. package/dist/commands/stats.cmd.js.map +0 -1
  50. package/dist/commands/stats.js +0 -154
  51. package/dist/commands/stats.js.map +0 -1
  52. package/dist/commands/validate.cmd.js +0 -39
  53. package/dist/commands/validate.cmd.js.map +0 -1
  54. package/dist/commands/validate.js +0 -77
  55. package/dist/commands/validate.js.map +0 -1
  56. package/dist/core/templates.js.map +0 -1
  57. package/dist/core/validator.js +0 -252
  58. package/dist/core/validator.js.map +0 -1
  59. package/dist/help.js +0 -305
  60. package/dist/help.js.map +0 -1
  61. package/dist/skills/.gitkeep +0 -0
  62. package/dist/types.js +0 -2
  63. package/dist/types.js.map +0 -1
  64. package/dist/utils/fs.js +0 -25
  65. package/dist/utils/fs.js.map +0 -1
  66. package/dist/utils/output.js +0 -102
  67. package/dist/utils/output.js.map +0 -1
  68. package/dist/validators/alignment-validator.js +0 -54
  69. package/dist/validators/alignment-validator.js.map +0 -1
  70. package/dist/validators/content-validator.js +0 -156
  71. package/dist/validators/content-validator.js.map +0 -1
  72. package/dist/validators/description-validator.js +0 -150
  73. package/dist/validators/description-validator.js.map +0 -1
  74. package/dist/validators/file-structure-validator.js +0 -125
  75. package/dist/validators/file-structure-validator.js.map +0 -1
  76. package/dist/validators/frontmatter-validator.js +0 -190
  77. package/dist/validators/frontmatter-validator.js.map +0 -1
  78. package/dist/validators/references-validator.js +0 -155
  79. package/dist/validators/references-validator.js.map +0 -1
  80. package/dist/validators/text-analysis.js +0 -71
  81. package/dist/validators/text-analysis.js.map +0 -1
@@ -0,0 +1,142 @@
1
+ import { n as error, o as success, r as info } from "./output-DiffPD2u.js";
2
+ import { a as has_yaml_frontmatter, i as extract_frontmatter, o as is_description_multiline, r as extract_array_field, t as check_package_dependencies } from "./dependency-validator-CQJ1hCoU.js";
3
+ import { defineCommand } from "citty";
4
+ import { readFileSync, writeFileSync } from "node:fs";
5
+ import { basename, join } from "node:path";
6
+ //#region src/commands/doctor.ts
7
+ function doctor_command(options) {
8
+ const { skill_path } = options;
9
+ const skill_name = basename(skill_path);
10
+ const skill_md_path = join(skill_path, "SKILL.md");
11
+ info(`Running doctor on: ${skill_name}`);
12
+ console.log("=".repeat(60));
13
+ let content;
14
+ try {
15
+ content = readFileSync(skill_md_path, "utf-8");
16
+ } catch (err) {
17
+ error(`Failed to read SKILL.md: ${String(err)}`);
18
+ process.exit(1);
19
+ }
20
+ let fixes_applied = 0;
21
+ let issues_found = 0;
22
+ if (extract_frontmatter(content).description_is_multiline) {
23
+ issues_found++;
24
+ info("Found multi-line description. Fixing...");
25
+ const fixed_content = fix_multiline_description(content);
26
+ try {
27
+ writeFileSync(skill_md_path, fixed_content, "utf-8");
28
+ content = fixed_content;
29
+ fixes_applied++;
30
+ success("Fixed multi-line description");
31
+ console.log(" • Added # prettier-ignore comment before description");
32
+ console.log(" • Reflowed description to single line");
33
+ } catch (err) {
34
+ error(`Failed to write SKILL.md: ${String(err)}`);
35
+ }
36
+ }
37
+ if (has_yaml_frontmatter(content)) {
38
+ const parts = content.split("---\n");
39
+ if (parts.length >= 3) {
40
+ const frontmatter_raw = parts[1];
41
+ const packages = extract_array_field(frontmatter_raw, "depends-on-packages");
42
+ if (packages && packages.length > 0) {
43
+ const missing = check_package_dependencies(packages).filter((r) => !r.found);
44
+ if (missing.length > 0) {
45
+ issues_found++;
46
+ console.log("");
47
+ info(`Missing ${missing.length} package dependenc${missing.length === 1 ? "y" : "ies"}:`);
48
+ for (const dep of missing) console.log(` • ${dep.name}`);
49
+ console.log("\nSuggested commands:");
50
+ for (const dep of missing) console.log(` npm install ${dep.name} # or: pip install ${dep.name}`);
51
+ }
52
+ }
53
+ }
54
+ }
55
+ console.log("");
56
+ if (issues_found === 0) success("No issues found");
57
+ else {
58
+ console.log(`Found ${issues_found} issue${issues_found === 1 ? "" : "s"}, applied ${fixes_applied} fix${fixes_applied === 1 ? "" : "es"}`);
59
+ if (fixes_applied > 0) console.log("\n✓ Run validate command to confirm the fixes");
60
+ }
61
+ }
62
+ /**
63
+ * Fix multi-line description by adding prettier-ignore and reflowing to single line
64
+ */
65
+ function fix_multiline_description(content) {
66
+ const lines = content.split("\n");
67
+ const fixed_lines = [];
68
+ let in_frontmatter = false;
69
+ let frontmatter_count = 0;
70
+ let in_description = false;
71
+ let description_parts = [];
72
+ for (let i = 0; i < lines.length; i++) {
73
+ const line = lines[i];
74
+ if (line.trim() === "---") {
75
+ frontmatter_count++;
76
+ if (frontmatter_count === 2 && in_description) {
77
+ const full_description = description_parts.join(" ");
78
+ fixed_lines.push(`description: ${full_description}`);
79
+ description_parts = [];
80
+ in_description = false;
81
+ }
82
+ in_frontmatter = frontmatter_count === 1;
83
+ fixed_lines.push(line);
84
+ continue;
85
+ }
86
+ if (!in_frontmatter) {
87
+ fixed_lines.push(line);
88
+ continue;
89
+ }
90
+ if (line.match(/^description:/)) {
91
+ if (!is_description_multiline(lines.slice(i).join("\n"))) {
92
+ fixed_lines.push(line);
93
+ continue;
94
+ }
95
+ in_description = true;
96
+ const match = line.match(/^description:\s*(.*)$/);
97
+ const value_on_line = match ? match[1].trim() : "";
98
+ if (value_on_line) description_parts.push(value_on_line);
99
+ fixed_lines.push("# prettier-ignore");
100
+ continue;
101
+ }
102
+ if (in_description) {
103
+ if (line.match(/^[a-z_-]+:/)) {
104
+ const full_description = description_parts.join(" ");
105
+ fixed_lines.push(`description: ${full_description}`);
106
+ description_parts = [];
107
+ in_description = false;
108
+ fixed_lines.push(line);
109
+ continue;
110
+ }
111
+ const trimmed = line.trim();
112
+ if (trimmed && !trimmed.startsWith("#")) description_parts.push(trimmed);
113
+ continue;
114
+ }
115
+ fixed_lines.push(line);
116
+ }
117
+ if (in_description && description_parts.length > 0) {
118
+ const full_description = description_parts.join(" ");
119
+ fixed_lines.push(`description: ${full_description}`);
120
+ }
121
+ return fixed_lines.join("\n");
122
+ }
123
+ //#endregion
124
+ //#region src/commands/doctor.cmd.ts
125
+ var doctor_cmd_default = defineCommand({
126
+ meta: {
127
+ name: "doctor",
128
+ description: "Fix common skill issues automatically"
129
+ },
130
+ args: { skill_path: {
131
+ type: "positional",
132
+ description: "Path to skill directory",
133
+ required: true
134
+ } },
135
+ run({ args }) {
136
+ doctor_command({ skill_path: args.skill_path });
137
+ }
138
+ });
139
+ //#endregion
140
+ export { doctor_cmd_default as default };
141
+
142
+ //# sourceMappingURL=doctor.cmd-DJpHLDCV.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.cmd-DJpHLDCV.js","names":[],"sources":["../src/commands/doctor.ts","../src/commands/doctor.cmd.ts"],"sourcesContent":["import { readFileSync, writeFileSync } from 'node:fs';\nimport { basename, join } from 'node:path';\nimport type { DoctorOptions } from '../types.js';\nimport { error, info, success } from '../utils/output.js';\nimport { check_package_dependencies } from '../validators/dependency-validator.js';\nimport {\n\textract_array_field,\n\textract_frontmatter,\n\thas_yaml_frontmatter,\n\tis_description_multiline,\n} from '../validators/frontmatter-validator.js';\n\nexport function doctor_command(options: DoctorOptions): void {\n\tconst { skill_path } = options;\n\tconst skill_name = basename(skill_path);\n\tconst skill_md_path = join(skill_path, 'SKILL.md');\n\n\tinfo(`Running doctor on: ${skill_name}`);\n\tconsole.log('='.repeat(60));\n\n\t// Read SKILL.md\n\tlet content: string;\n\ttry {\n\t\tcontent = readFileSync(skill_md_path, 'utf-8');\n\t} catch (err) {\n\t\terror(`Failed to read SKILL.md: ${String(err)}`);\n\t\tprocess.exit(1);\n\t}\n\n\tlet fixes_applied = 0;\n\tlet issues_found = 0;\n\n\t// Check 1: Multi-line description\n\tconst frontmatter_data = extract_frontmatter(content);\n\n\tif (frontmatter_data.description_is_multiline) {\n\t\tissues_found++;\n\t\tinfo('Found multi-line description. Fixing...');\n\n\t\tconst fixed_content = fix_multiline_description(content);\n\n\t\ttry {\n\t\t\twriteFileSync(skill_md_path, fixed_content, 'utf-8');\n\t\t\tcontent = fixed_content;\n\t\t\tfixes_applied++;\n\t\t\tsuccess('Fixed multi-line description');\n\t\t\tconsole.log(\n\t\t\t\t' • Added # prettier-ignore comment before description',\n\t\t\t);\n\t\t\tconsole.log(' • Reflowed description to single line');\n\t\t} catch (err) {\n\t\t\terror(`Failed to write SKILL.md: ${String(err)}`);\n\t\t}\n\t}\n\n\t// Check 2: Missing package dependencies\n\tif (has_yaml_frontmatter(content)) {\n\t\tconst parts = content.split('---\\n');\n\t\tif (parts.length >= 3) {\n\t\t\tconst frontmatter_raw = parts[1];\n\t\t\tconst packages = extract_array_field(\n\t\t\t\tfrontmatter_raw,\n\t\t\t\t'depends-on-packages',\n\t\t\t);\n\n\t\t\tif (packages && packages.length > 0) {\n\t\t\t\tconst results = check_package_dependencies(packages);\n\t\t\t\tconst missing = results.filter((r) => !r.found);\n\n\t\t\t\tif (missing.length > 0) {\n\t\t\t\t\tissues_found++;\n\t\t\t\t\tconsole.log('');\n\t\t\t\t\tinfo(\n\t\t\t\t\t\t`Missing ${missing.length} package dependenc${missing.length === 1 ? 'y' : 'ies'}:`,\n\t\t\t\t\t);\n\t\t\t\t\tfor (const dep of missing) {\n\t\t\t\t\t\tconsole.log(` • ${dep.name}`);\n\t\t\t\t\t}\n\t\t\t\t\tconsole.log('\\nSuggested commands:');\n\t\t\t\t\tfor (const dep of missing) {\n\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t` npm install ${dep.name} # or: pip install ${dep.name}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Summary\n\tconsole.log('');\n\tif (issues_found === 0) {\n\t\tsuccess('No issues found');\n\t} else {\n\t\tconsole.log(\n\t\t\t`Found ${issues_found} issue${issues_found === 1 ? '' : 's'}, applied ${fixes_applied} fix${fixes_applied === 1 ? '' : 'es'}`,\n\t\t);\n\t\tif (fixes_applied > 0) {\n\t\t\tconsole.log('\\n✓ Run validate command to confirm the fixes');\n\t\t}\n\t}\n}\n\n/**\n * Fix multi-line description by adding prettier-ignore and reflowing to single line\n */\nfunction fix_multiline_description(content: string): string {\n\tconst lines = content.split('\\n');\n\tconst fixed_lines: string[] = [];\n\tlet in_frontmatter = false;\n\tlet frontmatter_count = 0;\n\tlet in_description = false;\n\tlet description_parts: string[] = [];\n\n\tfor (let i = 0; i < lines.length; i++) {\n\t\tconst line = lines[i];\n\n\t\t// Track frontmatter boundaries\n\t\tif (line.trim() === '---') {\n\t\t\tfrontmatter_count++;\n\n\t\t\t// If we're closing frontmatter and still collecting description\n\t\t\tif (frontmatter_count === 2 && in_description) {\n\t\t\t\t// Write out the collected description\n\t\t\t\tconst full_description = description_parts.join(' ');\n\t\t\t\tfixed_lines.push(`description: ${full_description}`);\n\t\t\t\tdescription_parts = [];\n\t\t\t\tin_description = false;\n\t\t\t}\n\n\t\t\tin_frontmatter = frontmatter_count === 1;\n\t\t\tfixed_lines.push(line);\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Not in frontmatter, just pass through\n\t\tif (!in_frontmatter) {\n\t\t\tfixed_lines.push(line);\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Check if this is the description line\n\t\tif (line.match(/^description:/)) {\n\t\t\t// Check if it's already multi-line\n\t\t\tif (!is_description_multiline(lines.slice(i).join('\\n'))) {\n\t\t\t\t// Single line, just pass through\n\t\t\t\tfixed_lines.push(line);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tin_description = true;\n\n\t\t\t// Extract value on same line (if any)\n\t\t\tconst match = line.match(/^description:\\s*(.*)$/);\n\t\t\tconst value_on_line = match ? match[1].trim() : '';\n\t\t\tif (value_on_line) {\n\t\t\t\tdescription_parts.push(value_on_line);\n\t\t\t}\n\n\t\t\t// Add prettier-ignore comment\n\t\t\tfixed_lines.push('# prettier-ignore');\n\t\t\t// We'll add the description line later\n\t\t\tcontinue;\n\t\t}\n\n\t\t// If we're in description, collect continuation lines\n\t\tif (in_description) {\n\t\t\t// Stop if we hit another YAML field\n\t\t\tif (line.match(/^[a-z_-]+:/)) {\n\t\t\t\t// Done collecting description, write it out\n\t\t\t\tconst full_description = description_parts.join(' ');\n\t\t\t\tfixed_lines.push(`description: ${full_description}`);\n\t\t\t\tdescription_parts = [];\n\t\t\t\tin_description = false;\n\n\t\t\t\t// Add the current line (next field)\n\t\t\t\tfixed_lines.push(line);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Continuation line - collect it\n\t\t\tconst trimmed = line.trim();\n\t\t\tif (trimmed && !trimmed.startsWith('#')) {\n\t\t\t\tdescription_parts.push(trimmed);\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Regular frontmatter line\n\t\tfixed_lines.push(line);\n\t}\n\n\t// If we ended while still in description (at end of frontmatter)\n\tif (in_description && description_parts.length > 0) {\n\t\tconst full_description = description_parts.join(' ');\n\t\tfixed_lines.push(`description: ${full_description}`);\n\t}\n\n\treturn fixed_lines.join('\\n');\n}\n","import { defineCommand } from 'citty';\nimport { doctor_command } from './doctor.js';\n\nexport default defineCommand({\n\tmeta: {\n\t\tname: 'doctor',\n\t\tdescription: 'Fix common skill issues automatically',\n\t},\n\targs: {\n\t\tskill_path: {\n\t\t\ttype: 'positional',\n\t\t\tdescription: 'Path to skill directory',\n\t\t\trequired: true,\n\t\t},\n\t},\n\trun({ args }) {\n\t\tdoctor_command({ skill_path: args.skill_path });\n\t},\n});\n"],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { chmodSync, mkdirSync, writeFileSync } from "node:fs";
2
+ import { dirname } from "node:path";
3
+ //#region src/utils/fs.ts
4
+ function ensure_dir(path) {
5
+ mkdirSync(path, { recursive: true });
6
+ }
7
+ function write_file(path, content) {
8
+ ensure_dir(dirname(path));
9
+ writeFileSync(path, content, "utf-8");
10
+ }
11
+ function make_executable(path) {
12
+ chmodSync(path, 493);
13
+ }
14
+ function to_title_case(kebab_case) {
15
+ return kebab_case.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
16
+ }
17
+ function is_lowercase(str) {
18
+ return str === str.toLowerCase();
19
+ }
20
+ //#endregion
21
+ export { write_file as a, to_title_case as i, is_lowercase as n, make_executable as r, ensure_dir as t };
22
+
23
+ //# sourceMappingURL=fs-CuGv3Ob2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs-CuGv3Ob2.js","names":[],"sources":["../src/utils/fs.ts"],"sourcesContent":["import { chmodSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { dirname } from 'node:path';\n\nexport function ensure_dir(path: string): void {\n\tmkdirSync(path, { recursive: true });\n}\n\nexport function write_file(path: string, content: string): void {\n\tensure_dir(dirname(path));\n\twriteFileSync(path, content, 'utf-8');\n}\n\nexport function make_executable(path: string): void {\n\tchmodSync(path, 0o755);\n}\n\nexport function to_title_case(kebab_case: string): string {\n\treturn kebab_case\n\t\t.split('-')\n\t\t.map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n\t\t.join(' ');\n}\n\nexport function is_kebab_case(str: string): boolean {\n\treturn /^[a-z0-9-]+$/.test(str);\n}\n\nexport function is_lowercase(str: string): boolean {\n\treturn str === str.toLowerCase();\n}\n"],"mappings":";;;AAGA,SAAgB,WAAW,MAAoB;AAC9C,WAAU,MAAM,EAAE,WAAW,MAAM,CAAC;;AAGrC,SAAgB,WAAW,MAAc,SAAuB;AAC/D,YAAW,QAAQ,KAAK,CAAC;AACzB,eAAc,MAAM,SAAS,QAAQ;;AAGtC,SAAgB,gBAAgB,MAAoB;AACnD,WAAU,MAAM,IAAM;;AAGvB,SAAgB,cAAc,YAA4B;AACzD,QAAO,WACL,MAAM,IAAI,CACV,KAAK,SAAS,KAAK,OAAO,EAAE,CAAC,aAAa,GAAG,KAAK,MAAM,EAAE,CAAC,CAC3D,KAAK,IAAI;;AAOZ,SAAgB,aAAa,KAAsB;AAClD,QAAO,QAAQ,IAAI,aAAa"}
package/dist/index.js CHANGED
@@ -1,25 +1,27 @@
1
1
  #!/usr/bin/env node
2
- import { defineCommand, runMain } from 'citty';
3
- import { readFileSync } from 'node:fs';
4
- import { dirname, join } from 'node:path';
5
- import { fileURLToPath } from 'node:url';
2
+ import { defineCommand, runMain } from "citty";
3
+ import { readFileSync } from "node:fs";
4
+ import { dirname, join } from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+ //#region src/index.ts
6
7
  const __dirname = dirname(fileURLToPath(import.meta.url));
7
- const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8'));
8
- const main = defineCommand({
9
- meta: {
10
- name: 'claude-skills-cli',
11
- version: pkg.version,
12
- description: 'CLI toolkit for creating and managing Claude Agent Skills\n\nIMPORTANT FOR LLMs:\n ALWAYS run validate after creating or editing a skill:\n claude-skills-cli validate <skill-path>\n Skills MUST pass validation before use.\n Fix all errors immediately. Address warnings promptly.\n\nResources:\n Pre-built skills & hooks: https://github.com/spences10/claude-code-toolkit\n Includes a UserPromptSubmit hook for automatic skill activation.',
13
- },
14
- subCommands: {
15
- init: () => import('./commands/init.cmd.js').then((r) => r.default),
16
- install: () => import('./commands/install.cmd.js').then((r) => r.default),
17
- validate: () => import('./commands/validate.cmd.js').then((r) => r.default),
18
- doctor: () => import('./commands/doctor.cmd.js').then((r) => r.default),
19
- package: () => import('./commands/package.cmd.js').then((r) => r.default),
20
- stats: () => import('./commands/stats.cmd.js').then((r) => r.default),
21
- 'add-hook': () => import('./commands/add-hook.cmd.js').then((r) => r.default),
22
- },
23
- });
24
- runMain(main);
8
+ runMain(defineCommand({
9
+ meta: {
10
+ name: "claude-skills-cli",
11
+ version: JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf-8")).version,
12
+ description: "CLI toolkit for creating and managing Claude Agent Skills\n\nIMPORTANT FOR LLMs:\n ALWAYS run validate after creating or editing a skill:\n claude-skills-cli validate <skill-path>\n Skills MUST pass validation before use.\n Fix all errors immediately. Address warnings promptly.\n\nResources:\n Pre-built skills & hooks: https://github.com/spences10/claude-code-toolkit\n Includes a UserPromptSubmit hook for automatic skill activation."
13
+ },
14
+ subCommands: {
15
+ init: () => import("./init.cmd-BdqImX8b.js").then((r) => r.default),
16
+ install: () => import("./install.cmd-BaP8k9d2.js").then((r) => r.default),
17
+ validate: () => import("./validate.cmd-BxF4HNsu.js").then((r) => r.default),
18
+ doctor: () => import("./doctor.cmd-DJpHLDCV.js").then((r) => r.default),
19
+ package: () => import("./package.cmd-BYhkheya.js").then((r) => r.default),
20
+ stats: () => import("./stats.cmd-Dd46qjoV.js").then((r) => r.default),
21
+ "add-hook": () => import("./add-hook.cmd-JWw5UqA3.js").then((r) => r.default)
22
+ }
23
+ }));
24
+ //#endregion
25
+ export {};
26
+
25
27
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CACrB,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAC5D,CAAC;AAEF,MAAM,IAAI,GAAG,aAAa,CAAC;IAC1B,IAAI,EAAE;QACL,IAAI,EAAE,mBAAmB;QACzB,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,WAAW,EACV,8bAA8b;KAC/b;IACD,WAAW,EAAE;QACZ,IAAI,EAAE,GAAG,EAAE,CACV,MAAM,CAAC,wBAAwB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;QACxD,OAAO,EAAE,GAAG,EAAE,CACb,MAAM,CAAC,2BAA2B,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;QAC3D,QAAQ,EAAE,GAAG,EAAE,CACd,MAAM,CAAC,4BAA4B,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;QAC5D,MAAM,EAAE,GAAG,EAAE,CACZ,MAAM,CAAC,0BAA0B,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;QAC1D,OAAO,EAAE,GAAG,EAAE,CACb,MAAM,CAAC,2BAA2B,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;QAC3D,KAAK,EAAE,GAAG,EAAE,CACX,MAAM,CAAC,yBAAyB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;QACzD,UAAU,EAAE,GAAG,EAAE,CAChB,MAAM,CAAC,4BAA4B,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;KAC5D;CACD,CAAC,CAAC;AAEH,OAAO,CAAC,IAAI,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { defineCommand, runMain } from 'citty';\nimport { readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst pkg = JSON.parse(\n\treadFileSync(join(__dirname, '..', 'package.json'), 'utf-8'),\n);\n\nconst main = defineCommand({\n\tmeta: {\n\t\tname: 'claude-skills-cli',\n\t\tversion: pkg.version,\n\t\tdescription:\n\t\t\t'CLI toolkit for creating and managing Claude Agent Skills\\n\\nIMPORTANT FOR LLMs:\\n ALWAYS run validate after creating or editing a skill:\\n claude-skills-cli validate <skill-path>\\n Skills MUST pass validation before use.\\n Fix all errors immediately. Address warnings promptly.\\n\\nResources:\\n Pre-built skills & hooks: https://github.com/spences10/claude-code-toolkit\\n Includes a UserPromptSubmit hook for automatic skill activation.',\n\t},\n\tsubCommands: {\n\t\tinit: () =>\n\t\t\timport('./commands/init.cmd.js').then((r) => r.default),\n\t\tinstall: () =>\n\t\t\timport('./commands/install.cmd.js').then((r) => r.default),\n\t\tvalidate: () =>\n\t\t\timport('./commands/validate.cmd.js').then((r) => r.default),\n\t\tdoctor: () =>\n\t\t\timport('./commands/doctor.cmd.js').then((r) => r.default),\n\t\tpackage: () =>\n\t\t\timport('./commands/package.cmd.js').then((r) => r.default),\n\t\tstats: () =>\n\t\t\timport('./commands/stats.cmd.js').then((r) => r.default),\n\t\t'add-hook': () =>\n\t\t\timport('./commands/add-hook.cmd.js').then((r) => r.default),\n\t},\n});\n\nvoid runMain(main);\n"],"mappings":";;;;;;AAOA,MAAM,YAAY,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC;AA8BpD,QAzBQ,cAAc;CAC1B,MAAM;EACL,MAAM;EACN,SAPU,KAAK,MAChB,aAAa,KAAK,WAAW,MAAM,eAAe,EAAE,QAAQ,CAC5D,CAKc;EACb,aACC;EACD;CACD,aAAa;EACZ,YACC,OAAO,0BAA0B,MAAM,MAAM,EAAE,QAAQ;EACxD,eACC,OAAO,6BAA6B,MAAM,MAAM,EAAE,QAAQ;EAC3D,gBACC,OAAO,8BAA8B,MAAM,MAAM,EAAE,QAAQ;EAC5D,cACC,OAAO,4BAA4B,MAAM,MAAM,EAAE,QAAQ;EAC1D,eACC,OAAO,6BAA6B,MAAM,MAAM,EAAE,QAAQ;EAC3D,aACC,OAAO,2BAA2B,MAAM,MAAM,EAAE,QAAQ;EACzD,kBACC,OAAO,8BAA8B,MAAM,MAAM,EAAE,QAAQ;EAC5D;CACD,CAAC,CAEgB"}
@@ -0,0 +1,108 @@
1
+ import { i as SCRIPT_TEMPLATE, o as SKILL_MD_TEMPLATE, r as REFERENCE_TEMPLATE } from "./templates-fyteNbD0.js";
2
+ import { a as write_file, i as to_title_case, n as is_lowercase, r as make_executable, t as ensure_dir } from "./fs-CuGv3Ob2.js";
3
+ import { n as error, o as success } from "./output-DiffPD2u.js";
4
+ import { defineCommand } from "citty";
5
+ import { join } from "node:path";
6
+ import { homedir } from "node:os";
7
+ //#region src/commands/init.ts
8
+ function init_command(options) {
9
+ let skill_path;
10
+ let name;
11
+ let description;
12
+ if (options.path) {
13
+ skill_path = options.path;
14
+ name = skill_path.split("/").pop() || "";
15
+ description = options.description || "TODO: [Domain] [operations]. Use when [trigger phrase]";
16
+ } else if (options.name) {
17
+ name = options.name;
18
+ description = options.description || "TODO: [Domain] [operations]. Use when [trigger phrase]";
19
+ skill_path = options.global ? join(homedir(), ".claude", "skills", name) : join(".claude", "skills", name);
20
+ } else {
21
+ error("Either --name or --path must be provided");
22
+ console.log("\nUsage:");
23
+ console.log(" claude-skills-cli init --name my-skill --description \"Description\"");
24
+ console.log(" claude-skills-cli init --path /custom/path/my-skill");
25
+ process.exit(1);
26
+ }
27
+ const alphanumeric_check = name.replace(/-/g, "").replace(/_/g, "");
28
+ if (!/^[a-z0-9]+$/.test(alphanumeric_check)) {
29
+ error(`Skill name must be kebab-case alphanumeric: ${name}`);
30
+ process.exit(1);
31
+ }
32
+ if (!is_lowercase(name)) {
33
+ error(`Skill name must be lowercase: ${name}`);
34
+ process.exit(1);
35
+ }
36
+ create_skill(skill_path, name, description, options.with_examples || false, options.global || false);
37
+ }
38
+ function create_skill(path, name, description, with_examples = false, global = false) {
39
+ ensure_dir(path);
40
+ ensure_dir(join(path, "references"));
41
+ const title = to_title_case(name);
42
+ const skill_md = SKILL_MD_TEMPLATE(name, description, title, with_examples);
43
+ write_file(join(path, "SKILL.md"), skill_md);
44
+ if (with_examples) {
45
+ ensure_dir(join(path, "scripts"));
46
+ ensure_dir(join(path, "assets"));
47
+ const reference_md = REFERENCE_TEMPLATE(title);
48
+ write_file(join(path, "references", "detailed-guide.md"), reference_md);
49
+ const script_js = SCRIPT_TEMPLATE("example.js");
50
+ const script_path = join(path, "scripts", "example.js");
51
+ write_file(script_path, script_js);
52
+ make_executable(script_path);
53
+ }
54
+ success(`Skill created at: ${path} (${global ? "global" : "project"})`);
55
+ console.log("\nNext steps:");
56
+ console.log(`1. Edit ${path}/SKILL.md with your skill instructions`);
57
+ console.log(`2. Add detailed documentation to references/`);
58
+ if (with_examples) {
59
+ console.log(`3. Add executable scripts to scripts/`);
60
+ console.log(`4. Remove example files you don't need`);
61
+ } else console.log(`3. Use --with-examples flag if you need scripts/ and example files`);
62
+ console.log(`\n⚠️ REQUIRED: Validate the skill before use:`);
63
+ console.log(` claude-skills-cli validate ${path}`);
64
+ console.log(` Fix all errors immediately.`);
65
+ }
66
+ //#endregion
67
+ //#region src/commands/init.cmd.ts
68
+ var init_cmd_default = defineCommand({
69
+ meta: {
70
+ name: "init",
71
+ description: "Create a new skill"
72
+ },
73
+ args: {
74
+ name: {
75
+ type: "string",
76
+ description: "Skill name (kebab-case, lowercase)"
77
+ },
78
+ description: {
79
+ type: "string",
80
+ description: "Brief description with trigger keywords"
81
+ },
82
+ path: {
83
+ type: "string",
84
+ description: "Custom path (alternative to --name)"
85
+ },
86
+ "with-examples": {
87
+ type: "boolean",
88
+ description: "Include example files (scripts/, assets/)"
89
+ },
90
+ global: {
91
+ type: "boolean",
92
+ description: "Install skill in ~/.claude/skills/ (available in all projects)"
93
+ }
94
+ },
95
+ run({ args }) {
96
+ init_command({
97
+ name: args.name,
98
+ description: args.description,
99
+ path: args.path,
100
+ with_examples: args["with-examples"],
101
+ global: args.global
102
+ });
103
+ }
104
+ });
105
+ //#endregion
106
+ export { init_cmd_default as default };
107
+
108
+ //# sourceMappingURL=init.cmd-BdqImX8b.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.cmd-BdqImX8b.js","names":[],"sources":["../src/commands/init.ts","../src/commands/init.cmd.ts"],"sourcesContent":["import { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport {\n\tREFERENCE_TEMPLATE,\n\tSCRIPT_TEMPLATE,\n\tSKILL_MD_TEMPLATE,\n} from '../core/templates.js';\nimport type { InitOptions } from '../types.js';\nimport {\n\tensure_dir,\n\tis_lowercase,\n\tmake_executable,\n\tto_title_case,\n\twrite_file,\n} from '../utils/fs.js';\nimport { error, success } from '../utils/output.js';\n\nexport function init_command(options: InitOptions): void {\n\tlet skill_path: string;\n\tlet name: string;\n\tlet description: string;\n\n\t// Determine path and name\n\tif (options.path) {\n\t\tskill_path = options.path;\n\t\tname = skill_path.split('/').pop() || '';\n\t\tdescription =\n\t\t\toptions.description ||\n\t\t\t'TODO: [Domain] [operations]. Use when [trigger phrase]';\n\t} else if (options.name) {\n\t\tname = options.name;\n\t\tdescription =\n\t\t\toptions.description ||\n\t\t\t'TODO: [Domain] [operations]. Use when [trigger phrase]';\n\t\t// Use ~/.claude/skills/ for global, .claude/skills/ for project\n\t\tskill_path = options.global\n\t\t\t? join(homedir(), '.claude', 'skills', name)\n\t\t\t: join('.claude', 'skills', name);\n\t} else {\n\t\terror('Either --name or --path must be provided');\n\t\tconsole.log('\\nUsage:');\n\t\tconsole.log(\n\t\t\t' claude-skills-cli init --name my-skill --description \"Description\"',\n\t\t);\n\t\tconsole.log(\n\t\t\t' claude-skills-cli init --path /custom/path/my-skill',\n\t\t);\n\t\tprocess.exit(1);\n\t}\n\n\t// Validate name format\n\tconst alphanumeric_check = name.replace(/-/g, '').replace(/_/g, '');\n\tif (!/^[a-z0-9]+$/.test(alphanumeric_check)) {\n\t\terror(`Skill name must be kebab-case alphanumeric: ${name}`);\n\t\tprocess.exit(1);\n\t}\n\n\tif (!is_lowercase(name)) {\n\t\terror(`Skill name must be lowercase: ${name}`);\n\t\tprocess.exit(1);\n\t}\n\n\t// Create skill\n\tcreate_skill(\n\t\tskill_path,\n\t\tname,\n\t\tdescription,\n\t\toptions.with_examples || false,\n\t\toptions.global || false,\n\t);\n}\n\nfunction create_skill(\n\tpath: string,\n\tname: string,\n\tdescription: string,\n\twith_examples: boolean = false,\n\tglobal: boolean = false,\n): void {\n\t// Create base directories\n\tensure_dir(path);\n\tensure_dir(join(path, 'references'));\n\n\t// Create SKILL.md\n\tconst title = to_title_case(name);\n\tconst skill_md = SKILL_MD_TEMPLATE(\n\t\tname,\n\t\tdescription,\n\t\ttitle,\n\t\twith_examples,\n\t);\n\twrite_file(join(path, 'SKILL.md'), skill_md);\n\n\t// Only create example files if requested\n\tif (with_examples) {\n\t\t// Create example directories\n\t\tensure_dir(join(path, 'scripts'));\n\t\tensure_dir(join(path, 'assets'));\n\n\t\t// Create example reference\n\t\tconst reference_md = REFERENCE_TEMPLATE(title);\n\t\twrite_file(\n\t\t\tjoin(path, 'references', 'detailed-guide.md'),\n\t\t\treference_md,\n\t\t);\n\n\t\t// Create example script\n\t\tconst script_js = SCRIPT_TEMPLATE('example.js');\n\t\tconst script_path = join(path, 'scripts', 'example.js');\n\t\twrite_file(script_path, script_js);\n\t\tmake_executable(script_path);\n\t}\n\n\tconst scope = global ? 'global' : 'project';\n\tsuccess(`Skill created at: ${path} (${scope})`);\n\tconsole.log('\\nNext steps:');\n\tconsole.log(\n\t\t`1. Edit ${path}/SKILL.md with your skill instructions`,\n\t);\n\tconsole.log(`2. Add detailed documentation to references/`);\n\tif (with_examples) {\n\t\tconsole.log(`3. Add executable scripts to scripts/`);\n\t\tconsole.log(`4. Remove example files you don't need`);\n\t} else {\n\t\tconsole.log(\n\t\t\t`3. Use --with-examples flag if you need scripts/ and example files`,\n\t\t);\n\t}\n\tconsole.log(`\\n⚠️ REQUIRED: Validate the skill before use:`);\n\tconsole.log(` claude-skills-cli validate ${path}`);\n\tconsole.log(` Fix all errors immediately.`);\n}\n","import { defineCommand } from 'citty';\nimport { init_command } from './init.js';\n\nexport default defineCommand({\n\tmeta: { name: 'init', description: 'Create a new skill' },\n\targs: {\n\t\tname: {\n\t\t\ttype: 'string',\n\t\t\tdescription: 'Skill name (kebab-case, lowercase)',\n\t\t},\n\t\tdescription: {\n\t\t\ttype: 'string',\n\t\t\tdescription: 'Brief description with trigger keywords',\n\t\t},\n\t\tpath: {\n\t\t\ttype: 'string',\n\t\t\tdescription: 'Custom path (alternative to --name)',\n\t\t},\n\t\t'with-examples': {\n\t\t\ttype: 'boolean',\n\t\t\tdescription: 'Include example files (scripts/, assets/)',\n\t\t},\n\t\tglobal: {\n\t\t\ttype: 'boolean',\n\t\t\tdescription:\n\t\t\t\t'Install skill in ~/.claude/skills/ (available in all projects)',\n\t\t},\n\t},\n\trun({ args }) {\n\t\tinit_command({\n\t\t\tname: args.name,\n\t\t\tdescription: args.description,\n\t\t\tpath: args.path,\n\t\t\twith_examples: args['with-examples'],\n\t\t\tglobal: args.global,\n\t\t});\n\t},\n});\n"],"mappings":";;;;;;;AAiBA,SAAgB,aAAa,SAA4B;CACxD,IAAI;CACJ,IAAI;CACJ,IAAI;AAGJ,KAAI,QAAQ,MAAM;AACjB,eAAa,QAAQ;AACrB,SAAO,WAAW,MAAM,IAAI,CAAC,KAAK,IAAI;AACtC,gBACC,QAAQ,eACR;YACS,QAAQ,MAAM;AACxB,SAAO,QAAQ;AACf,gBACC,QAAQ,eACR;AAED,eAAa,QAAQ,SAClB,KAAK,SAAS,EAAE,WAAW,UAAU,KAAK,GAC1C,KAAK,WAAW,UAAU,KAAK;QAC5B;AACN,QAAM,2CAA2C;AACjD,UAAQ,IAAI,WAAW;AACvB,UAAQ,IACP,yEACA;AACD,UAAQ,IACP,wDACA;AACD,UAAQ,KAAK,EAAE;;CAIhB,MAAM,qBAAqB,KAAK,QAAQ,MAAM,GAAG,CAAC,QAAQ,MAAM,GAAG;AACnE,KAAI,CAAC,cAAc,KAAK,mBAAmB,EAAE;AAC5C,QAAM,+CAA+C,OAAO;AAC5D,UAAQ,KAAK,EAAE;;AAGhB,KAAI,CAAC,aAAa,KAAK,EAAE;AACxB,QAAM,iCAAiC,OAAO;AAC9C,UAAQ,KAAK,EAAE;;AAIhB,cACC,YACA,MACA,aACA,QAAQ,iBAAiB,OACzB,QAAQ,UAAU,MAClB;;AAGF,SAAS,aACR,MACA,MACA,aACA,gBAAyB,OACzB,SAAkB,OACX;AAEP,YAAW,KAAK;AAChB,YAAW,KAAK,MAAM,aAAa,CAAC;CAGpC,MAAM,QAAQ,cAAc,KAAK;CACjC,MAAM,WAAW,kBAChB,MACA,aACA,OACA,cACA;AACD,YAAW,KAAK,MAAM,WAAW,EAAE,SAAS;AAG5C,KAAI,eAAe;AAElB,aAAW,KAAK,MAAM,UAAU,CAAC;AACjC,aAAW,KAAK,MAAM,SAAS,CAAC;EAGhC,MAAM,eAAe,mBAAmB,MAAM;AAC9C,aACC,KAAK,MAAM,cAAc,oBAAoB,EAC7C,aACA;EAGD,MAAM,YAAY,gBAAgB,aAAa;EAC/C,MAAM,cAAc,KAAK,MAAM,WAAW,aAAa;AACvD,aAAW,aAAa,UAAU;AAClC,kBAAgB,YAAY;;AAI7B,SAAQ,qBAAqB,KAAK,IADpB,SAAS,WAAW,UACU,GAAG;AAC/C,SAAQ,IAAI,gBAAgB;AAC5B,SAAQ,IACP,WAAW,KAAK,wCAChB;AACD,SAAQ,IAAI,+CAA+C;AAC3D,KAAI,eAAe;AAClB,UAAQ,IAAI,wCAAwC;AACpD,UAAQ,IAAI,yCAAyC;OAErD,SAAQ,IACP,qEACA;AAEF,SAAQ,IAAI,iDAAiD;AAC7D,SAAQ,IAAI,iCAAiC,OAAO;AACpD,SAAQ,IAAI,iCAAiC;;;;AC/H9C,IAAA,mBAAe,cAAc;CAC5B,MAAM;EAAE,MAAM;EAAQ,aAAa;EAAsB;CACzD,MAAM;EACL,MAAM;GACL,MAAM;GACN,aAAa;GACb;EACD,aAAa;GACZ,MAAM;GACN,aAAa;GACb;EACD,MAAM;GACL,MAAM;GACN,aAAa;GACb;EACD,iBAAiB;GAChB,MAAM;GACN,aAAa;GACb;EACD,QAAQ;GACP,MAAM;GACN,aACC;GACD;EACD;CACD,IAAI,EAAE,QAAQ;AACb,eAAa;GACZ,MAAM,KAAK;GACX,aAAa,KAAK;GAClB,MAAM,KAAK;GACX,eAAe,KAAK;GACpB,QAAQ,KAAK;GACb,CAAC;;CAEH,CAAC"}
@@ -0,0 +1,79 @@
1
+ import { t as ensure_dir } from "./fs-CuGv3Ob2.js";
2
+ import { n as error, o as success, r as info } from "./output-DiffPD2u.js";
3
+ import { defineCommand } from "citty";
4
+ import { cpSync, existsSync } from "node:fs";
5
+ import { dirname, join } from "node:path";
6
+ import { fileURLToPath } from "node:url";
7
+ //#region src/commands/install.ts
8
+ const BUNDLED_SKILLS_DIR = join(dirname(fileURLToPath(import.meta.url)), "..", "skills");
9
+ const AVAILABLE_SKILLS = [];
10
+ function install_command(options) {
11
+ const skill_name = options.skill_name;
12
+ if (!skill_name || AVAILABLE_SKILLS.length === 0) {
13
+ info("No bundled skills available");
14
+ console.log("\nOfficial method: /plugin install <skill>@<marketplace>");
15
+ console.log("See: https://code.claude.com/docs/en/plugins");
16
+ console.log("\nFor pre-built skills & activation hooks, see: https://github.com/spences10/claude-code-toolkit");
17
+ console.log("\nUse \"claude-skills-cli init\" to create new skills.");
18
+ process.exit(0);
19
+ }
20
+ if (!AVAILABLE_SKILLS.includes(skill_name)) {
21
+ error(`Unknown skill: ${skill_name}`);
22
+ console.log("\nNo bundled skills available.");
23
+ console.log("For pre-built skills & activation hooks, see: https://github.com/spences10/claude-code-toolkit");
24
+ process.exit(1);
25
+ }
26
+ const source_path = join(BUNDLED_SKILLS_DIR, skill_name);
27
+ const dest_path = join(".claude", "skills", skill_name);
28
+ if (!existsSync(source_path)) {
29
+ error(`Bundled skill not found: ${skill_name}`);
30
+ console.log(`Expected at: ${source_path}\n\nThis may be a package installation issue.`);
31
+ process.exit(1);
32
+ }
33
+ if (existsSync(dest_path)) if (options.force) info(`Skill already exists at ${dest_path}, overwriting (--force)...`);
34
+ else {
35
+ info(`Skill already installed at: ${dest_path}`);
36
+ console.log("\nUse --force to overwrite the existing skill.");
37
+ process.exit(0);
38
+ }
39
+ ensure_dir(join(".claude", "skills"));
40
+ try {
41
+ cpSync(source_path, dest_path, {
42
+ recursive: true,
43
+ force: options.force || false
44
+ });
45
+ success(`Installed ${skill_name} to: ${dest_path}`);
46
+ } catch (err) {
47
+ error(`Failed to install skill: ${err.message}`);
48
+ process.exit(1);
49
+ }
50
+ }
51
+ //#endregion
52
+ //#region src/commands/install.cmd.ts
53
+ var install_cmd_default = defineCommand({
54
+ meta: {
55
+ name: "install",
56
+ description: "Install a bundled skill"
57
+ },
58
+ args: {
59
+ skill_name: {
60
+ type: "positional",
61
+ description: "Name of bundled skill",
62
+ required: true
63
+ },
64
+ force: {
65
+ type: "boolean",
66
+ description: "Replace existing skill without prompting"
67
+ }
68
+ },
69
+ run({ args }) {
70
+ install_command({
71
+ skill_name: args.skill_name,
72
+ force: args.force
73
+ });
74
+ }
75
+ });
76
+ //#endregion
77
+ export { install_cmd_default as default };
78
+
79
+ //# sourceMappingURL=install.cmd-BaP8k9d2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.cmd-BaP8k9d2.js","names":[],"sources":["../src/commands/install.ts","../src/commands/install.cmd.ts"],"sourcesContent":["import { cpSync, existsSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { InstallOptions } from '../types.js';\nimport { ensure_dir } from '../utils/fs.js';\nimport { error, info, success } from '../utils/output.js';\n\n// Get the directory where this module is located (dist/commands/)\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n// Bundled skills are in dist/skills/ directory\nconst BUNDLED_SKILLS_DIR = join(__dirname, '..', 'skills');\n\nconst AVAILABLE_SKILLS: string[] = [];\n\nexport function install_command(options: InstallOptions): void {\n\tconst skill_name = options.skill_name;\n\n\t// Validate skill name\n\tif (!skill_name || AVAILABLE_SKILLS.length === 0) {\n\t\tinfo('No bundled skills available');\n\t\tconsole.log(\n\t\t\t'\\nOfficial method: /plugin install <skill>@<marketplace>',\n\t\t);\n\t\tconsole.log('See: https://code.claude.com/docs/en/plugins');\n\t\tconsole.log(\n\t\t\t'\\nFor pre-built skills & activation hooks, see: https://github.com/spences10/claude-code-toolkit',\n\t\t);\n\t\tconsole.log(\n\t\t\t'\\nUse \"claude-skills-cli init\" to create new skills.',\n\t\t);\n\t\tprocess.exit(0);\n\t}\n\n\tif (!AVAILABLE_SKILLS.includes(skill_name)) {\n\t\terror(`Unknown skill: ${skill_name}`);\n\t\tconsole.log('\\nNo bundled skills available.');\n\t\tconsole.log(\n\t\t\t'For pre-built skills & activation hooks, see: https://github.com/spences10/claude-code-toolkit',\n\t\t);\n\t\tprocess.exit(1);\n\t}\n\n\t// Source and destination paths\n\tconst source_path = join(BUNDLED_SKILLS_DIR, skill_name);\n\tconst dest_path = join('.claude', 'skills', skill_name);\n\n\t// Check if source exists in bundle\n\tif (!existsSync(source_path)) {\n\t\terror(`Bundled skill not found: ${skill_name}`);\n\t\tconsole.log(\n\t\t\t`Expected at: ${source_path}\\n\\nThis may be a package installation issue.`,\n\t\t);\n\t\tprocess.exit(1);\n\t}\n\n\t// Check if already installed\n\tif (existsSync(dest_path)) {\n\t\tif (options.force) {\n\t\t\tinfo(\n\t\t\t\t`Skill already exists at ${dest_path}, overwriting (--force)...`,\n\t\t\t);\n\t\t} else {\n\t\t\tinfo(`Skill already installed at: ${dest_path}`);\n\t\t\tconsole.log('\\nUse --force to overwrite the existing skill.');\n\t\t\tprocess.exit(0);\n\t\t}\n\t}\n\n\t// Create destination directory\n\tensure_dir(join('.claude', 'skills'));\n\n\t// Copy skill directory\n\ttry {\n\t\tcpSync(source_path, dest_path, {\n\t\t\trecursive: true,\n\t\t\tforce: options.force || false,\n\t\t});\n\t\tsuccess(`Installed ${skill_name} to: ${dest_path}`);\n\t} catch (err) {\n\t\terror(`Failed to install skill: ${(err as Error).message}`);\n\t\tprocess.exit(1);\n\t}\n}\n","import { defineCommand } from 'citty';\nimport { install_command } from './install.js';\n\nexport default defineCommand({\n\tmeta: { name: 'install', description: 'Install a bundled skill' },\n\targs: {\n\t\tskill_name: {\n\t\t\ttype: 'positional',\n\t\t\tdescription: 'Name of bundled skill',\n\t\t\trequired: true,\n\t\t},\n\t\tforce: {\n\t\t\ttype: 'boolean',\n\t\t\tdescription: 'Replace existing skill without prompting',\n\t\t},\n\t},\n\trun({ args }) {\n\t\tinstall_command({\n\t\t\tskill_name: args.skill_name,\n\t\t\tforce: args.force,\n\t\t});\n\t},\n});\n"],"mappings":";;;;;;;AAYA,MAAM,qBAAqB,KAHT,QADC,cAAc,OAAO,KAAK,IAAI,CACZ,EAGM,MAAM,SAAS;AAE1D,MAAM,mBAA6B,EAAE;AAErC,SAAgB,gBAAgB,SAA+B;CAC9D,MAAM,aAAa,QAAQ;AAG3B,KAAI,CAAC,cAAc,iBAAiB,WAAW,GAAG;AACjD,OAAK,8BAA8B;AACnC,UAAQ,IACP,2DACA;AACD,UAAQ,IAAI,+CAA+C;AAC3D,UAAQ,IACP,mGACA;AACD,UAAQ,IACP,yDACA;AACD,UAAQ,KAAK,EAAE;;AAGhB,KAAI,CAAC,iBAAiB,SAAS,WAAW,EAAE;AAC3C,QAAM,kBAAkB,aAAa;AACrC,UAAQ,IAAI,iCAAiC;AAC7C,UAAQ,IACP,iGACA;AACD,UAAQ,KAAK,EAAE;;CAIhB,MAAM,cAAc,KAAK,oBAAoB,WAAW;CACxD,MAAM,YAAY,KAAK,WAAW,UAAU,WAAW;AAGvD,KAAI,CAAC,WAAW,YAAY,EAAE;AAC7B,QAAM,4BAA4B,aAAa;AAC/C,UAAQ,IACP,gBAAgB,YAAY,+CAC5B;AACD,UAAQ,KAAK,EAAE;;AAIhB,KAAI,WAAW,UAAU,CACxB,KAAI,QAAQ,MACX,MACC,2BAA2B,UAAU,4BACrC;MACK;AACN,OAAK,+BAA+B,YAAY;AAChD,UAAQ,IAAI,iDAAiD;AAC7D,UAAQ,KAAK,EAAE;;AAKjB,YAAW,KAAK,WAAW,SAAS,CAAC;AAGrC,KAAI;AACH,SAAO,aAAa,WAAW;GAC9B,WAAW;GACX,OAAO,QAAQ,SAAS;GACxB,CAAC;AACF,UAAQ,aAAa,WAAW,OAAO,YAAY;UAC3C,KAAK;AACb,QAAM,4BAA6B,IAAc,UAAU;AAC3D,UAAQ,KAAK,EAAE;;;;;AC/EjB,IAAA,sBAAe,cAAc;CAC5B,MAAM;EAAE,MAAM;EAAW,aAAa;EAA2B;CACjE,MAAM;EACL,YAAY;GACX,MAAM;GACN,aAAa;GACb,UAAU;GACV;EACD,OAAO;GACN,MAAM;GACN,aAAa;GACb;EACD;CACD,IAAI,EAAE,QAAQ;AACb,kBAAgB;GACf,YAAY,KAAK;GACjB,OAAO,KAAK;GACZ,CAAC;;CAEH,CAAC"}
@@ -0,0 +1,104 @@
1
+ //#region src/constants.ts
2
+ /** Token budget for Level 2 content (~5000 words * 1.3) */
3
+ const TOKEN_BUDGET = 6500;
4
+ /**
5
+ * Progressive disclosure limits — three tiers for SKILL.md body
6
+ *
7
+ * strict: opinionated defaults for minimal context usage
8
+ * lenient: relaxed for larger skills
9
+ * loose: matches Anthropic official limits (500 lines)
10
+ */
11
+ const LIMITS = {
12
+ strict: {
13
+ lines: {
14
+ excellent: 30,
15
+ good: 40,
16
+ max: 50
17
+ },
18
+ words: {
19
+ excellent: 300,
20
+ good: 500,
21
+ max: 1e3
22
+ }
23
+ },
24
+ lenient: {
25
+ lines: {
26
+ excellent: 50,
27
+ good: 100,
28
+ max: 150
29
+ },
30
+ words: {
31
+ excellent: 500,
32
+ good: 1e3,
33
+ max: 2e3
34
+ }
35
+ },
36
+ loose: {
37
+ lines: {
38
+ excellent: 100,
39
+ good: 200,
40
+ max: 500
41
+ },
42
+ words: {
43
+ excellent: 1e3,
44
+ good: 2e3,
45
+ max: 5e3
46
+ }
47
+ }
48
+ };
49
+ /** Semver format regex for version field validation */
50
+ const SEMVER_REGEX = /^\d+\.\d+\.\d+(-[a-zA-Z0-9.]+)?(\+[a-zA-Z0-9.]+)?$/;
51
+ //#endregion
52
+ //#region src/utils/output.ts
53
+ const success = (msg) => console.log(`✅ ${msg}`);
54
+ const error = (msg) => console.log(`❌ ${msg}`);
55
+ const warning = (msg) => console.log(`⚠️ ${msg}`);
56
+ const info = (msg) => console.log(`📋 ${msg}`);
57
+ const package_ = (msg) => console.log(`📦 ${msg}`);
58
+ const upload = (msg) => console.log(`📤 ${msg}`);
59
+ const search = (msg) => console.log(`🔍 ${msg}`);
60
+ const S = LIMITS.strict;
61
+ /**
62
+ * Display progressive disclosure statistics
63
+ */
64
+ function display_validation_stats(stats) {
65
+ console.log("\n📊 Progressive Disclosure Stats:");
66
+ console.log("\n Level 1 (Metadata - Always Loaded):");
67
+ const desc_status = stats.description_length <= 250 ? "✅ Optimal" : "❌ Too long";
68
+ console.log(` Description: ${stats.description_length} chars, ~${stats.description_tokens} tokens ${desc_status}`);
69
+ console.log(` (Target: <250 chars for Level 1 efficiency)`);
70
+ console.log("\n Level 2 (SKILL.md Body - Loaded when triggered):");
71
+ let line_status;
72
+ if (stats.line_count <= S.lines.excellent) line_status = "✅ Excellent";
73
+ else if (stats.line_count <= S.lines.good) line_status = "✅ Good";
74
+ else if (stats.line_count <= S.lines.max) line_status = "⚠️ Consider splitting";
75
+ else line_status = "❌ Too large";
76
+ console.log(` Lines: ${stats.line_count} (max: ${S.lines.max}) ${line_status}`);
77
+ let word_status;
78
+ if (stats.word_count < S.words.excellent) word_status = "✅ Excellent";
79
+ else if (stats.word_count < S.words.good) word_status = "✅ Good";
80
+ else if (stats.word_count < S.words.max) word_status = "⚠️ Consider splitting";
81
+ else word_status = "❌ Too large";
82
+ console.log(` Words: ${stats.word_count} (max: ${S.words.max}) ${word_status}`);
83
+ const token_status = stats.estimated_tokens < 6500 ? "within budget" : "exceeds budget";
84
+ console.log(` Est. tokens: ~${stats.estimated_tokens} (budget: <${TOKEN_BUDGET}) ${token_status}`);
85
+ const code_status = stats.code_blocks > 3 ? " (recommended: 1-2)" : stats.code_blocks <= 2 ? " ✅" : "";
86
+ console.log(` Code blocks: ${stats.code_blocks}${code_status}`);
87
+ const section_status = stats.sections > 8 ? " (recommended: 3-5)" : stats.sections >= 3 && stats.sections <= 5 ? " ✅" : "";
88
+ console.log(` Sections: ${stats.sections}${section_status}`);
89
+ if (stats.long_paragraphs > 0) {
90
+ const para_status = stats.long_paragraphs > 3 ? " (consider moving to references/)" : "";
91
+ console.log(` Long paragraphs: ${stats.long_paragraphs}${para_status}`);
92
+ }
93
+ console.log("\n Level 3+ (References - Loaded as needed):");
94
+ console.log(" Use references/ directory for detailed docs (unlimited size)");
95
+ console.log("\n Overall Assessment:");
96
+ if (stats.line_count <= S.lines.excellent && stats.description_length <= 250) console.log(" ✅ Excellent progressive disclosure!");
97
+ else if (stats.line_count <= S.lines.max && stats.description_length <= 250) console.log(" ✅ Good progressive disclosure");
98
+ else if (stats.line_count <= LIMITS.lenient.lines.max && stats.word_count < LIMITS.lenient.words.max) console.log(" ⚠️ Consider splitting content into references/");
99
+ else console.log(" ❌ Violates progressive disclosure (move content to references/)");
100
+ }
101
+ //#endregion
102
+ export { search as a, warning as c, package_ as i, LIMITS as l, error as n, success as o, info as r, upload as s, display_validation_stats as t, SEMVER_REGEX as u };
103
+
104
+ //# sourceMappingURL=output-DiffPD2u.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output-DiffPD2u.js","names":[],"sources":["../src/constants.ts","../src/utils/output.ts"],"sourcesContent":["/**\n * Anthropic skill spec limits\n * https://code.claude.com/docs/en/skills#frontmatter-reference\n */\n\n/** Max chars for skill name field */\nexport const NAME_MAX_LENGTH = 64;\n\n/** Max chars for description — Claude truncates at this limit in skill listing */\nexport const DESCRIPTION_MAX_LENGTH = 250;\n\n/** Min recommended chars for description to be useful */\nexport const DESCRIPTION_MIN_LENGTH = 50;\n\n/** Token budget for Level 2 content (~5000 words * 1.3) */\nexport const TOKEN_BUDGET = 6500;\n\n/** Words per paragraph before it's considered \"long\" */\nexport const LONG_PARAGRAPH_WORDS = 100;\n\n/** Min body length (chars) before warning about short content */\nexport const MIN_BODY_LENGTH = 100;\n\n/**\n * Progressive disclosure limits — three tiers for SKILL.md body\n *\n * strict: opinionated defaults for minimal context usage\n * lenient: relaxed for larger skills\n * loose: matches Anthropic official limits (500 lines)\n */\nexport const LIMITS = {\n\tstrict: {\n\t\tlines: { excellent: 30, good: 40, max: 50 },\n\t\twords: { excellent: 300, good: 500, max: 1000 },\n\t},\n\tlenient: {\n\t\tlines: { excellent: 50, good: 100, max: 150 },\n\t\twords: { excellent: 500, good: 1000, max: 2000 },\n\t},\n\tloose: {\n\t\tlines: { excellent: 100, good: 200, max: 500 },\n\t\twords: { excellent: 1000, good: 2000, max: 5000 },\n\t},\n} as const;\n\n/** Semver format regex for version field validation */\nexport const SEMVER_REGEX =\n\t/^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9.]+)?(\\+[a-zA-Z0-9.]+)?$/;\n","import {\n\tDESCRIPTION_MAX_LENGTH,\n\tLIMITS,\n\tTOKEN_BUDGET,\n} from '../constants.js';\nimport type { ValidationStats } from '../types.js';\n\nexport const success = (msg: string) => console.log(`✅ ${msg}`);\nexport const error = (msg: string) => console.log(`❌ ${msg}`);\nexport const warning = (msg: string) => console.log(`⚠️ ${msg}`);\nexport const info = (msg: string) => console.log(`📋 ${msg}`);\nexport const step = (msg: string) => console.log(` ${msg}`);\nexport const package_ = (msg: string) => console.log(`📦 ${msg}`);\nexport const upload = (msg: string) => console.log(`📤 ${msg}`);\nexport const search = (msg: string) => console.log(`🔍 ${msg}`);\n\nconst S = LIMITS.strict;\n\n/**\n * Display progressive disclosure statistics\n */\nexport function display_validation_stats(\n\tstats: ValidationStats,\n): void {\n\tconsole.log('\\n📊 Progressive Disclosure Stats:');\n\n\t// Level 1: Description\n\tconsole.log('\\n Level 1 (Metadata - Always Loaded):');\n\tconst desc_status =\n\t\tstats.description_length <= DESCRIPTION_MAX_LENGTH\n\t\t\t? '✅ Optimal'\n\t\t\t: '❌ Too long';\n\n\tconsole.log(\n\t\t` Description: ${stats.description_length} chars, ~${stats.description_tokens} tokens ${desc_status}`,\n\t);\n\tconsole.log(\n\t\t` (Target: <${DESCRIPTION_MAX_LENGTH} chars for Level 1 efficiency)`,\n\t);\n\n\t// Level 2: SKILL.md Body\n\tconsole.log('\\n Level 2 (SKILL.md Body - Loaded when triggered):');\n\n\t// Line count\n\tlet line_status: string;\n\tif (stats.line_count <= S.lines.excellent) {\n\t\tline_status = '✅ Excellent';\n\t} else if (stats.line_count <= S.lines.good) {\n\t\tline_status = '✅ Good';\n\t} else if (stats.line_count <= S.lines.max) {\n\t\tline_status = '⚠️ Consider splitting';\n\t} else {\n\t\tline_status = '❌ Too large';\n\t}\n\n\tconsole.log(\n\t\t` Lines: ${stats.line_count} (max: ${S.lines.max}) ${line_status}`,\n\t);\n\n\t// Word count\n\tlet word_status: string;\n\tif (stats.word_count < S.words.excellent) {\n\t\tword_status = '✅ Excellent';\n\t} else if (stats.word_count < S.words.good) {\n\t\tword_status = '✅ Good';\n\t} else if (stats.word_count < S.words.max) {\n\t\tword_status = '⚠️ Consider splitting';\n\t} else {\n\t\tword_status = '❌ Too large';\n\t}\n\n\tconsole.log(\n\t\t` Words: ${stats.word_count} (max: ${S.words.max}) ${word_status}`,\n\t);\n\n\t// Token estimation\n\tconst token_status =\n\t\tstats.estimated_tokens < TOKEN_BUDGET\n\t\t\t? 'within budget'\n\t\t\t: 'exceeds budget';\n\n\tconsole.log(\n\t\t` Est. tokens: ~${stats.estimated_tokens} (budget: <${TOKEN_BUDGET}) ${token_status}`,\n\t);\n\n\t// Code blocks\n\tconst code_status =\n\t\tstats.code_blocks > 3\n\t\t\t? ' (recommended: 1-2)'\n\t\t\t: stats.code_blocks <= 2\n\t\t\t\t? ' ✅'\n\t\t\t\t: '';\n\tconsole.log(` Code blocks: ${stats.code_blocks}${code_status}`);\n\n\t// Sections\n\tconst section_status =\n\t\tstats.sections > 8\n\t\t\t? ' (recommended: 3-5)'\n\t\t\t: stats.sections >= 3 && stats.sections <= 5\n\t\t\t\t? ' ✅'\n\t\t\t\t: '';\n\tconsole.log(` Sections: ${stats.sections}${section_status}`);\n\n\t// Long paragraphs\n\tif (stats.long_paragraphs > 0) {\n\t\tconst para_status =\n\t\t\tstats.long_paragraphs > 3\n\t\t\t\t? ' (consider moving to references/)'\n\t\t\t\t: '';\n\t\tconsole.log(\n\t\t\t` Long paragraphs: ${stats.long_paragraphs}${para_status}`,\n\t\t);\n\t}\n\n\t// Level 3 info\n\tconsole.log('\\n Level 3+ (References - Loaded as needed):');\n\tconsole.log(\n\t\t' Use references/ directory for detailed docs (unlimited size)',\n\t);\n\n\t// Overall assessment (based on strict defaults)\n\tconsole.log('\\n Overall Assessment:');\n\tif (\n\t\tstats.line_count <= S.lines.excellent &&\n\t\tstats.description_length <= DESCRIPTION_MAX_LENGTH\n\t) {\n\t\tconsole.log(' ✅ Excellent progressive disclosure!');\n\t} else if (\n\t\tstats.line_count <= S.lines.max &&\n\t\tstats.description_length <= DESCRIPTION_MAX_LENGTH\n\t) {\n\t\tconsole.log(' ✅ Good progressive disclosure');\n\t} else if (\n\t\tstats.line_count <= LIMITS.lenient.lines.max &&\n\t\tstats.word_count < LIMITS.lenient.words.max\n\t) {\n\t\tconsole.log(\n\t\t\t' ⚠️ Consider splitting content into references/',\n\t\t);\n\t} else {\n\t\tconsole.log(\n\t\t\t' ❌ Violates progressive disclosure (move content to references/)',\n\t\t);\n\t}\n}\n"],"mappings":";;AAeA,MAAa,eAAe;;;;;;;;AAe5B,MAAa,SAAS;CACrB,QAAQ;EACP,OAAO;GAAE,WAAW;GAAI,MAAM;GAAI,KAAK;GAAI;EAC3C,OAAO;GAAE,WAAW;GAAK,MAAM;GAAK,KAAK;GAAM;EAC/C;CACD,SAAS;EACR,OAAO;GAAE,WAAW;GAAI,MAAM;GAAK,KAAK;GAAK;EAC7C,OAAO;GAAE,WAAW;GAAK,MAAM;GAAM,KAAK;GAAM;EAChD;CACD,OAAO;EACN,OAAO;GAAE,WAAW;GAAK,MAAM;GAAK,KAAK;GAAK;EAC9C,OAAO;GAAE,WAAW;GAAM,MAAM;GAAM,KAAK;GAAM;EACjD;CACD;;AAGD,MAAa,eACZ;;;ACxCD,MAAa,WAAW,QAAgB,QAAQ,IAAI,KAAK,MAAM;AAC/D,MAAa,SAAS,QAAgB,QAAQ,IAAI,KAAK,MAAM;AAC7D,MAAa,WAAW,QAAgB,QAAQ,IAAI,OAAO,MAAM;AACjE,MAAa,QAAQ,QAAgB,QAAQ,IAAI,MAAM,MAAM;AAE7D,MAAa,YAAY,QAAgB,QAAQ,IAAI,MAAM,MAAM;AACjE,MAAa,UAAU,QAAgB,QAAQ,IAAI,MAAM,MAAM;AAC/D,MAAa,UAAU,QAAgB,QAAQ,IAAI,MAAM,MAAM;AAE/D,MAAM,IAAI,OAAO;;;;AAKjB,SAAgB,yBACf,OACO;AACP,SAAQ,IAAI,qCAAqC;AAGjD,SAAQ,IAAI,0CAA0C;CACtD,MAAM,cACL,MAAM,sBAAA,MACH,cACA;AAEJ,SAAQ,IACP,oBAAoB,MAAM,mBAAmB,WAAW,MAAM,mBAAmB,UAAU,cAC3F;AACD,SAAQ,IACP,kDACA;AAGD,SAAQ,IAAI,uDAAuD;CAGnE,IAAI;AACJ,KAAI,MAAM,cAAc,EAAE,MAAM,UAC/B,eAAc;UACJ,MAAM,cAAc,EAAE,MAAM,KACtC,eAAc;UACJ,MAAM,cAAc,EAAE,MAAM,IACtC,eAAc;KAEd,eAAc;AAGf,SAAQ,IACP,cAAc,MAAM,WAAW,SAAS,EAAE,MAAM,IAAI,IAAI,cACxD;CAGD,IAAI;AACJ,KAAI,MAAM,aAAa,EAAE,MAAM,UAC9B,eAAc;UACJ,MAAM,aAAa,EAAE,MAAM,KACrC,eAAc;UACJ,MAAM,aAAa,EAAE,MAAM,IACrC,eAAc;KAEd,eAAc;AAGf,SAAQ,IACP,cAAc,MAAM,WAAW,SAAS,EAAE,MAAM,IAAI,IAAI,cACxD;CAGD,MAAM,eACL,MAAM,mBAAA,OACH,kBACA;AAEJ,SAAQ,IACP,qBAAqB,MAAM,iBAAiB,aAAa,aAAa,IAAI,eAC1E;CAGD,MAAM,cACL,MAAM,cAAc,IACjB,wBACA,MAAM,eAAe,IACpB,OACA;AACL,SAAQ,IAAI,oBAAoB,MAAM,cAAc,cAAc;CAGlE,MAAM,iBACL,MAAM,WAAW,IACd,wBACA,MAAM,YAAY,KAAK,MAAM,YAAY,IACxC,OACA;AACL,SAAQ,IAAI,iBAAiB,MAAM,WAAW,iBAAiB;AAG/D,KAAI,MAAM,kBAAkB,GAAG;EAC9B,MAAM,cACL,MAAM,kBAAkB,IACrB,sCACA;AACJ,UAAQ,IACP,wBAAwB,MAAM,kBAAkB,cAChD;;AAIF,SAAQ,IAAI,gDAAgD;AAC5D,SAAQ,IACP,mEACA;AAGD,SAAQ,IAAI,0BAA0B;AACtC,KACC,MAAM,cAAc,EAAE,MAAM,aAC5B,MAAM,sBAAA,IAEN,SAAQ,IAAI,0CAA0C;UAEtD,MAAM,cAAc,EAAE,MAAM,OAC5B,MAAM,sBAAA,IAEN,SAAQ,IAAI,oCAAoC;UAEhD,MAAM,cAAc,OAAO,QAAQ,MAAM,OACzC,MAAM,aAAa,OAAO,QAAQ,MAAM,IAExC,SAAQ,IACP,sDACA;KAED,SAAQ,IACP,sEACA"}