@sundial-ai/cli 0.1.0

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 (97) hide show
  1. package/PLAN.md +497 -0
  2. package/README.md +30 -0
  3. package/dist/commands/add.d.ts +13 -0
  4. package/dist/commands/add.d.ts.map +1 -0
  5. package/dist/commands/add.js +112 -0
  6. package/dist/commands/add.js.map +1 -0
  7. package/dist/commands/config.d.ts +5 -0
  8. package/dist/commands/config.d.ts.map +1 -0
  9. package/dist/commands/config.js +42 -0
  10. package/dist/commands/config.js.map +1 -0
  11. package/dist/commands/list.d.ts +5 -0
  12. package/dist/commands/list.d.ts.map +1 -0
  13. package/dist/commands/list.js +53 -0
  14. package/dist/commands/list.js.map +1 -0
  15. package/dist/commands/remove.d.ts +13 -0
  16. package/dist/commands/remove.d.ts.map +1 -0
  17. package/dist/commands/remove.js +127 -0
  18. package/dist/commands/remove.js.map +1 -0
  19. package/dist/commands/show.d.ts +5 -0
  20. package/dist/commands/show.d.ts.map +1 -0
  21. package/dist/commands/show.js +81 -0
  22. package/dist/commands/show.js.map +1 -0
  23. package/dist/core/agent-detect.d.ts +9 -0
  24. package/dist/core/agent-detect.d.ts.map +1 -0
  25. package/dist/core/agent-detect.js +44 -0
  26. package/dist/core/agent-detect.js.map +1 -0
  27. package/dist/core/agents.d.ts +8 -0
  28. package/dist/core/agents.d.ts.map +1 -0
  29. package/dist/core/agents.js +34 -0
  30. package/dist/core/agents.js.map +1 -0
  31. package/dist/core/config-manager.d.ts +9 -0
  32. package/dist/core/config-manager.d.ts.map +1 -0
  33. package/dist/core/config-manager.js +47 -0
  34. package/dist/core/config-manager.js.map +1 -0
  35. package/dist/core/skill-hash.d.ts +12 -0
  36. package/dist/core/skill-hash.d.ts.map +1 -0
  37. package/dist/core/skill-hash.js +53 -0
  38. package/dist/core/skill-hash.js.map +1 -0
  39. package/dist/core/skill-info.d.ts +35 -0
  40. package/dist/core/skill-info.d.ts.map +1 -0
  41. package/dist/core/skill-info.js +211 -0
  42. package/dist/core/skill-info.js.map +1 -0
  43. package/dist/core/skill-install.d.ts +24 -0
  44. package/dist/core/skill-install.d.ts.map +1 -0
  45. package/dist/core/skill-install.js +123 -0
  46. package/dist/core/skill-install.js.map +1 -0
  47. package/dist/core/skill-source.d.ts +29 -0
  48. package/dist/core/skill-source.d.ts.map +1 -0
  49. package/dist/core/skill-source.js +105 -0
  50. package/dist/core/skill-source.js.map +1 -0
  51. package/dist/index.d.ts +3 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +104 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/types/index.d.ts +57 -0
  56. package/dist/types/index.d.ts.map +1 -0
  57. package/dist/types/index.js +2 -0
  58. package/dist/types/index.js.map +1 -0
  59. package/dist/utils/fuzzy-match.d.ts +16 -0
  60. package/dist/utils/fuzzy-match.d.ts.map +1 -0
  61. package/dist/utils/fuzzy-match.js +37 -0
  62. package/dist/utils/fuzzy-match.js.map +1 -0
  63. package/dist/utils/prompts.d.ts +16 -0
  64. package/dist/utils/prompts.d.ts.map +1 -0
  65. package/dist/utils/prompts.js +80 -0
  66. package/dist/utils/prompts.js.map +1 -0
  67. package/dist/utils/registry.d.ts +6 -0
  68. package/dist/utils/registry.d.ts.map +1 -0
  69. package/dist/utils/registry.js +14 -0
  70. package/dist/utils/registry.js.map +1 -0
  71. package/package.json +43 -0
  72. package/publish.sh +2 -0
  73. package/src/commands/add.ts +137 -0
  74. package/src/commands/config.ts +49 -0
  75. package/src/commands/list.ts +68 -0
  76. package/src/commands/remove.ts +152 -0
  77. package/src/commands/show.ts +93 -0
  78. package/src/core/agent-detect.ts +53 -0
  79. package/src/core/agents.ts +40 -0
  80. package/src/core/config-manager.ts +55 -0
  81. package/src/core/skill-hash.ts +61 -0
  82. package/src/core/skill-info.ts +246 -0
  83. package/src/core/skill-install.ts +165 -0
  84. package/src/core/skill-source.ts +118 -0
  85. package/src/index.ts +116 -0
  86. package/src/types/index.ts +64 -0
  87. package/src/utils/fuzzy-match.ts +48 -0
  88. package/src/utils/prompts.ts +92 -0
  89. package/src/utils/registry.ts +16 -0
  90. package/test/agents.test.ts +86 -0
  91. package/test/fuzzy-match.test.ts +58 -0
  92. package/test/registry.test.ts +48 -0
  93. package/test/skill-hash.test.ts +77 -0
  94. package/test/skill-info.test.ts +195 -0
  95. package/test/skill-source.test.ts +89 -0
  96. package/tsconfig.json +20 -0
  97. package/vitest.config.ts +15 -0
@@ -0,0 +1,42 @@
1
+ import chalk from 'chalk';
2
+ import { getSupportedAgentsMessage, SUPPORTED_AGENTS } from '../core/agents.js';
3
+ import { loadConfig, setDefaultAgents, getConfigPath } from '../core/config-manager.js';
4
+ import { detectAllAgents } from '../core/agent-detect.js';
5
+ import { promptAgentSelection } from '../utils/prompts.js';
6
+ /**
7
+ * Re-open agent selection dialog and update config.
8
+ */
9
+ export async function configCommand() {
10
+ const config = await loadConfig();
11
+ console.log(chalk.cyan('Sundial CLI Configuration'));
12
+ console.log(chalk.gray(`Config file: ${getConfigPath()}`));
13
+ console.log();
14
+ // Show current defaults
15
+ if (config.defaultAgents.length > 0) {
16
+ console.log('Current default agents:');
17
+ for (const agentFlag of config.defaultAgents) {
18
+ const agent = SUPPORTED_AGENTS.find(a => a.flag === agentFlag);
19
+ if (agent) {
20
+ console.log(` - ${agent.name}`);
21
+ }
22
+ }
23
+ console.log();
24
+ }
25
+ console.log(chalk.gray(getSupportedAgentsMessage()));
26
+ console.log();
27
+ // Detect agents and show selection dialog
28
+ const detectedAgents = await detectAllAgents();
29
+ const selectedAgents = await promptAgentSelection(detectedAgents, config.defaultAgents);
30
+ await setDefaultAgents(selectedAgents);
31
+ console.log();
32
+ console.log(chalk.green('Configuration saved!'));
33
+ // Show new defaults
34
+ console.log('New default agents:');
35
+ for (const agentFlag of selectedAgents) {
36
+ const agent = SUPPORTED_AGENTS.find(a => a.flag === agentFlag);
37
+ if (agent) {
38
+ console.log(` - ${agent.name}`);
39
+ }
40
+ }
41
+ }
42
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAChF,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AACxF,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE3D;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;IAElC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,aAAa,EAAE,EAAE,CAAC,CAAC,CAAC;IAC3D,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,wBAAwB;IACxB,IAAI,MAAM,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;QACvC,KAAK,MAAM,SAAS,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;YAC7C,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;YAC/D,IAAI,KAAK,EAAE,CAAC;gBACV,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;QACD,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,yBAAyB,EAAE,CAAC,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,0CAA0C;IAC1C,MAAM,cAAc,GAAG,MAAM,eAAe,EAAE,CAAC;IAC/C,MAAM,cAAc,GAAG,MAAM,oBAAoB,CAAC,cAAc,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;IAExF,MAAM,gBAAgB,CAAC,cAAc,CAAC,CAAC;IAEvC,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC,CAAC;IAEjD,oBAAoB;IACpB,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;IACnC,KAAK,MAAM,SAAS,IAAI,cAAc,EAAE,CAAC;QACvC,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;QAC/D,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * List all installed skills for each agent.
3
+ */
4
+ export declare function listCommand(): Promise<void>;
5
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAWA;;GAEG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAqDjD"}
@@ -0,0 +1,53 @@
1
+ import chalk from 'chalk';
2
+ import { SUPPORTED_AGENTS, getSupportedAgentsMessage } from '../core/agents.js';
3
+ import { listSkillsForAgent } from '../core/skill-info.js';
4
+ /**
5
+ * List all installed skills for each agent.
6
+ */
7
+ export async function listCommand() {
8
+ const allAgentSkills = [];
9
+ // Check both local and global for each agent
10
+ for (const agent of SUPPORTED_AGENTS) {
11
+ // Local
12
+ const localSkills = await listSkillsForAgent(agent.folderName, false);
13
+ if (localSkills.length > 0) {
14
+ allAgentSkills.push({
15
+ agentName: agent.name,
16
+ folderName: agent.folderName,
17
+ isGlobal: false,
18
+ skills: localSkills
19
+ });
20
+ }
21
+ // Global
22
+ const globalSkills = await listSkillsForAgent(agent.folderName, true);
23
+ if (globalSkills.length > 0) {
24
+ allAgentSkills.push({
25
+ agentName: agent.name,
26
+ folderName: agent.folderName,
27
+ isGlobal: true,
28
+ skills: globalSkills
29
+ });
30
+ }
31
+ }
32
+ if (allAgentSkills.length === 0) {
33
+ console.log(chalk.yellow('No skills installed.'));
34
+ console.log();
35
+ console.log(chalk.gray(getSupportedAgentsMessage()));
36
+ console.log(chalk.gray('You can add skills with "sun add <skill>"'));
37
+ return;
38
+ }
39
+ // Print skills grouped by agent
40
+ for (const agentSkills of allAgentSkills) {
41
+ const location = agentSkills.isGlobal
42
+ ? `global ~/${agentSkills.folderName}/`
43
+ : `${agentSkills.folderName}/`;
44
+ console.log(chalk.cyan(`${agentSkills.agentName} (${location}):`));
45
+ for (const skill of agentSkills.skills) {
46
+ console.log(` - ${skill}`);
47
+ }
48
+ console.log();
49
+ }
50
+ console.log(chalk.gray(getSupportedAgentsMessage()));
51
+ console.log(chalk.gray('You can add skills with "sun add <skill>" or remove with "sun remove <skill>"'));
52
+ }
53
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAS3D;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,cAAc,GAAkB,EAAE,CAAC;IAEzC,6CAA6C;IAC7C,KAAK,MAAM,KAAK,IAAI,gBAAgB,EAAE,CAAC;QACrC,QAAQ;QACR,MAAM,WAAW,GAAG,MAAM,kBAAkB,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QACtE,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,cAAc,CAAC,IAAI,CAAC;gBAClB,SAAS,EAAE,KAAK,CAAC,IAAI;gBACrB,UAAU,EAAE,KAAK,CAAC,UAAU;gBAC5B,QAAQ,EAAE,KAAK;gBACf,MAAM,EAAE,WAAW;aACpB,CAAC,CAAC;QACL,CAAC;QAED,SAAS;QACT,MAAM,YAAY,GAAG,MAAM,kBAAkB,CAAC,KAAK,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QACtE,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,cAAc,CAAC,IAAI,CAAC;gBAClB,SAAS,EAAE,KAAK,CAAC,IAAI;gBACrB,UAAU,EAAE,KAAK,CAAC,UAAU;gBAC5B,QAAQ,EAAE,IAAI;gBACd,MAAM,EAAE,YAAY;aACrB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,CAAC;QAClD,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,yBAAyB,EAAE,CAAC,CAAC,CAAC;QACrD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC,CAAC;QACrE,OAAO;IACT,CAAC;IAED,gCAAgC;IAChC,KAAK,MAAM,WAAW,IAAI,cAAc,EAAE,CAAC;QACzC,MAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ;YACnC,CAAC,CAAC,YAAY,WAAW,CAAC,UAAU,GAAG;YACvC,CAAC,CAAC,GAAG,WAAW,CAAC,UAAU,GAAG,CAAC;QAEjC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,SAAS,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC;QAEnE,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC;YACvC,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,EAAE,CAAC,CAAC;QAC9B,CAAC;QAED,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,yBAAyB,EAAE,CAAC,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,+EAA+E,CAAC,CAAC,CAAC;AAC3G,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { CommandFlags } from '../types/index.js';
2
+ export interface RemoveResult {
3
+ skill: string;
4
+ removedFrom: string[];
5
+ notFoundIn: string[];
6
+ isGlobal: boolean;
7
+ error?: string;
8
+ }
9
+ /**
10
+ * Remove skill(s) from agent configuration(s).
11
+ */
12
+ export declare function removeCommand(skills: string[], flags: CommandFlags): Promise<void>;
13
+ //# sourceMappingURL=remove.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remove.d.ts","sourceRoot":"","sources":["../../src/commands/remove.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAa,YAAY,EAAE,MAAM,mBAAmB,CAAC;AA2DjE,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA2ExF"}
@@ -0,0 +1,127 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import { getAgentByFlag, SUPPORTED_AGENTS } from '../core/agents.js';
4
+ import { getDefaultAgents } from '../core/config-manager.js';
5
+ import { detectLocalAgents } from '../core/agent-detect.js';
6
+ import { removeSkill } from '../core/skill-install.js';
7
+ /**
8
+ * Determine which agents to remove from and whether to target global installs.
9
+ * Uses same logic as add command (except no first-run prompt).
10
+ *
11
+ * Logic:
12
+ * 1. If --global flag is set, always target global
13
+ * 2. If agent flags (--claude, --codex, etc.) are set, use those agents
14
+ * 3. Otherwise use saved default agents (error if none configured)
15
+ *
16
+ * For local vs global:
17
+ * - If --global: always global
18
+ * - Otherwise: check if any configured agents have local folders
19
+ * - If yes: target local
20
+ * - If no local folders exist for configured agents: target global
21
+ */
22
+ async function resolveTargetAgents(flags) {
23
+ const forceGlobal = flags.global ?? false;
24
+ // Check if any agent flags were explicitly set
25
+ const explicitAgents = [];
26
+ for (const agent of SUPPORTED_AGENTS) {
27
+ if (flags[agent.flag]) {
28
+ explicitAgents.push(agent.flag);
29
+ }
30
+ }
31
+ let targetAgents;
32
+ // Determine which agents to target
33
+ if (explicitAgents.length > 0) {
34
+ targetAgents = explicitAgents;
35
+ }
36
+ else {
37
+ // Use saved defaults (no first-run prompt for remove)
38
+ const defaultAgents = await getDefaultAgents();
39
+ if (defaultAgents.length === 0) {
40
+ throw new Error('No default agents configured. Run "sun add" first or use --claude/--codex/--gemini flags.');
41
+ }
42
+ targetAgents = defaultAgents;
43
+ }
44
+ // Determine if we should target global or local
45
+ if (forceGlobal) {
46
+ return { agents: targetAgents, isGlobal: true };
47
+ }
48
+ // Check if any of the target agents have local folders in current directory
49
+ const localAgents = await detectLocalAgents();
50
+ const localAgentFlags = new Set(localAgents.map(a => a.agent.flag));
51
+ const hasLocalFolders = targetAgents.some(agentFlag => localAgentFlags.has(agentFlag));
52
+ // If no local folders exist for any configured agent, target global
53
+ const isGlobal = !hasLocalFolders;
54
+ return { agents: targetAgents, isGlobal };
55
+ }
56
+ /**
57
+ * Remove skill(s) from agent configuration(s).
58
+ */
59
+ export async function removeCommand(skills, flags) {
60
+ if (skills.length === 0) {
61
+ console.error(chalk.red('Error: No skills specified. Usage: sun remove <skill> [skill2] ...'));
62
+ process.exit(1);
63
+ }
64
+ // Resolve target agents
65
+ let agents;
66
+ let isGlobal;
67
+ try {
68
+ const resolved = await resolveTargetAgents(flags);
69
+ agents = resolved.agents;
70
+ isGlobal = resolved.isGlobal;
71
+ }
72
+ catch (error) {
73
+ console.error(chalk.red(error instanceof Error ? error.message : String(error)));
74
+ process.exit(1);
75
+ }
76
+ const results = [];
77
+ for (const skill of skills) {
78
+ const spinner = ora(`Removing ${skill}...`).start();
79
+ const result = {
80
+ skill,
81
+ removedFrom: [],
82
+ notFoundIn: [],
83
+ isGlobal
84
+ };
85
+ try {
86
+ // Remove from each target agent
87
+ for (const agentFlag of agents) {
88
+ const removed = await removeSkill(skill, agentFlag, isGlobal);
89
+ const agentName = getAgentByFlag(agentFlag).name;
90
+ if (removed) {
91
+ result.removedFrom.push(agentName);
92
+ }
93
+ else {
94
+ result.notFoundIn.push(agentName);
95
+ }
96
+ }
97
+ if (result.removedFrom.length > 0) {
98
+ spinner.succeed(`Removed ${skill} from ${result.removedFrom.join(' and ')}`);
99
+ }
100
+ else {
101
+ spinner.warn(`${skill} not found in any agent`);
102
+ }
103
+ if (result.notFoundIn.length > 0 && result.removedFrom.length > 0) {
104
+ console.log(chalk.gray(` (not found in: ${result.notFoundIn.join(', ')})`));
105
+ }
106
+ }
107
+ catch (error) {
108
+ const message = error instanceof Error ? error.message : String(error);
109
+ result.error = message;
110
+ spinner.fail(`Failed to remove ${skill}: ${message}`);
111
+ }
112
+ results.push(result);
113
+ }
114
+ // Print summary if multiple skills
115
+ if (skills.length > 1) {
116
+ const totalRemoved = results.filter(r => r.removedFrom.length > 0).length;
117
+ const totalFailed = results.filter(r => r.error || r.removedFrom.length === 0).length;
118
+ console.log();
119
+ if (totalRemoved > 0) {
120
+ console.log(chalk.green(`Removed ${totalRemoved} skill(s)`));
121
+ }
122
+ if (totalFailed > 0) {
123
+ console.log(chalk.yellow(`${totalFailed} skill(s) not found or failed`));
124
+ }
125
+ }
126
+ }
127
+ //# sourceMappingURL=remove.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remove.js","sourceRoot":"","sources":["../../src/commands/remove.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Show skill details and installation locations.
3
+ */
4
+ export declare function showCommand(skillName: string): Promise<void>;
5
+ //# sourceMappingURL=show.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"show.d.ts","sourceRoot":"","sources":["../../src/commands/show.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,wBAAsB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqFlE"}
@@ -0,0 +1,81 @@
1
+ import chalk from 'chalk';
2
+ import { findSkillInstallations } from '../core/skill-info.js';
3
+ import { getAgentByFlag } from '../core/agents.js';
4
+ /**
5
+ * Show skill details and installation locations.
6
+ */
7
+ export async function showCommand(skillName) {
8
+ if (!skillName) {
9
+ console.error(chalk.red('Error: No skill specified. Usage: sun show <skill>'));
10
+ process.exit(1);
11
+ }
12
+ const installations = await findSkillInstallations(skillName);
13
+ if (installations.length === 0) {
14
+ console.error(chalk.yellow(`Skill "${skillName}" is not installed.`));
15
+ process.exit(1);
16
+ }
17
+ // Check if there are multiple versions (different content hashes)
18
+ const uniqueHashes = new Set(installations.map(i => i.contentHash));
19
+ const hasMultipleVersions = uniqueHashes.size > 1;
20
+ if (hasMultipleVersions) {
21
+ // Multiple versions detected
22
+ console.log(chalk.cyan(`Skill: ${skillName}`));
23
+ console.log(chalk.yellow('Warning: Multiple versions detected'));
24
+ console.log();
25
+ // Group by content hash
26
+ const byHash = new Map();
27
+ for (const inst of installations) {
28
+ const existing = byHash.get(inst.contentHash) || [];
29
+ existing.push(inst);
30
+ byHash.set(inst.contentHash, existing);
31
+ }
32
+ let versionNum = 1;
33
+ for (const [hash, insts] of byHash) {
34
+ const firstInst = insts[0];
35
+ const locations = insts.map(i => {
36
+ const agent = getAgentByFlag(i.agent);
37
+ return i.isGlobal ? `~/${agent.folderName}/` : `${agent.folderName}/`;
38
+ });
39
+ console.log(chalk.white(`Version ${versionNum} (${locations.join(', ')}):`));
40
+ console.log(` Description: ${firstInst.metadata.description}`);
41
+ if (firstInst.metadata.metadata?.author) {
42
+ console.log(` Author: ${firstInst.metadata.metadata.author}`);
43
+ }
44
+ if (firstInst.metadata.metadata?.version) {
45
+ console.log(` Version: ${firstInst.metadata.metadata.version}`);
46
+ }
47
+ if (firstInst.metadata.license) {
48
+ console.log(` License: ${firstInst.metadata.license}`);
49
+ }
50
+ console.log(` Content hash: ${hash}`);
51
+ console.log();
52
+ versionNum++;
53
+ }
54
+ }
55
+ else {
56
+ // Single version across all installations
57
+ const firstInst = installations[0];
58
+ console.log(chalk.cyan(`Skill: ${skillName}`));
59
+ console.log(`Description: ${firstInst.metadata.description}`);
60
+ if (firstInst.metadata.metadata?.author) {
61
+ console.log(`Author: ${firstInst.metadata.metadata.author}`);
62
+ }
63
+ if (firstInst.metadata.metadata?.version) {
64
+ console.log(`Version: ${firstInst.metadata.metadata.version}`);
65
+ }
66
+ if (firstInst.metadata.license) {
67
+ console.log(`License: ${firstInst.metadata.license}`);
68
+ }
69
+ if (firstInst.metadata.compatibility) {
70
+ console.log(`Compatibility: ${firstInst.metadata.compatibility}`);
71
+ }
72
+ console.log();
73
+ console.log('Installed in:');
74
+ for (const inst of installations) {
75
+ const agent = getAgentByFlag(inst.agent);
76
+ const location = inst.isGlobal ? '(global)' : '(local)';
77
+ console.log(` - ${agent.folderName}/ ${chalk.gray(location)}`);
78
+ }
79
+ }
80
+ }
81
+ //# sourceMappingURL=show.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"show.js","sourceRoot":"","sources":["../../src/commands/show.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { DetectedAgent, AgentConfig } from '../types/index.js';
2
+ export declare function detectAgentsInDirectory(directory: string, isGlobal: boolean): Promise<DetectedAgent[]>;
3
+ export declare function detectLocalAgents(): Promise<DetectedAgent[]>;
4
+ export declare function detectGlobalAgents(): Promise<DetectedAgent[]>;
5
+ export declare function detectAllAgents(): Promise<DetectedAgent[]>;
6
+ export declare function getAgentPath(agent: AgentConfig, isGlobal: boolean): string;
7
+ export declare function getSkillsPath(agent: AgentConfig, isGlobal: boolean): string;
8
+ export declare function ensureSkillsDirectory(agent: AgentConfig, isGlobal: boolean): Promise<string>;
9
+ //# sourceMappingURL=agent-detect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-detect.d.ts","sourceRoot":"","sources":["../../src/core/agent-detect.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEpE,wBAAsB,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAe5G;AAED,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAElE;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAEnE;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAMhE;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,GAAG,MAAM,CAG1E;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,GAAG,MAAM,CAE3E;AAED,wBAAsB,qBAAqB,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAIlG"}
@@ -0,0 +1,44 @@
1
+ import fs from 'fs-extra';
2
+ import path from 'path';
3
+ import os from 'os';
4
+ import { SUPPORTED_AGENTS } from './agents.js';
5
+ export async function detectAgentsInDirectory(directory, isGlobal) {
6
+ const detected = [];
7
+ for (const agent of SUPPORTED_AGENTS) {
8
+ const agentPath = path.join(directory, agent.folderName);
9
+ if (await fs.pathExists(agentPath)) {
10
+ detected.push({
11
+ agent,
12
+ path: agentPath,
13
+ isGlobal
14
+ });
15
+ }
16
+ }
17
+ return detected;
18
+ }
19
+ export async function detectLocalAgents() {
20
+ return detectAgentsInDirectory(process.cwd(), false);
21
+ }
22
+ export async function detectGlobalAgents() {
23
+ return detectAgentsInDirectory(os.homedir(), true);
24
+ }
25
+ export async function detectAllAgents() {
26
+ const [local, global] = await Promise.all([
27
+ detectLocalAgents(),
28
+ detectGlobalAgents()
29
+ ]);
30
+ return [...local, ...global];
31
+ }
32
+ export function getAgentPath(agent, isGlobal) {
33
+ const baseDir = isGlobal ? os.homedir() : process.cwd();
34
+ return path.join(baseDir, agent.folderName);
35
+ }
36
+ export function getSkillsPath(agent, isGlobal) {
37
+ return path.join(getAgentPath(agent, isGlobal), 'skills');
38
+ }
39
+ export async function ensureSkillsDirectory(agent, isGlobal) {
40
+ const skillsPath = getSkillsPath(agent, isGlobal);
41
+ await fs.ensureDir(skillsPath);
42
+ return skillsPath;
43
+ }
44
+ //# sourceMappingURL=agent-detect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-detect.js","sourceRoot":"","sources":["../../src/core/agent-detect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAG/C,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,SAAiB,EAAE,QAAiB;IAChF,MAAM,QAAQ,GAAoB,EAAE,CAAC;IAErC,KAAK,MAAM,KAAK,IAAI,gBAAgB,EAAE,CAAC;QACrC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;QACzD,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YACnC,QAAQ,CAAC,IAAI,CAAC;gBACZ,KAAK;gBACL,IAAI,EAAE,SAAS;gBACf,QAAQ;aACT,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,OAAO,uBAAuB,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,OAAO,uBAAuB,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACxC,iBAAiB,EAAE;QACnB,kBAAkB,EAAE;KACrB,CAAC,CAAC;IACH,OAAO,CAAC,GAAG,KAAK,EAAE,GAAG,MAAM,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAkB,EAAE,QAAiB;IAChE,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;IACxD,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAkB,EAAE,QAAiB;IACjE,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,KAAkB,EAAE,QAAiB;IAC/E,MAAM,UAAU,GAAG,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAClD,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IAC/B,OAAO,UAAU,CAAC;AACpB,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { AgentConfig, AgentType } from '../types/index.js';
2
+ export declare const SUPPORTED_AGENTS: AgentConfig[];
3
+ export declare function getAgentByFlag(flag: string): AgentConfig | undefined;
4
+ export declare function getAgentByFolder(folderName: string): AgentConfig | undefined;
5
+ export declare function getSupportedAgentsMessage(): string;
6
+ export declare function isValidAgentType(flag: string): flag is AgentType;
7
+ export declare function getAgentFlags(): string[];
8
+ //# sourceMappingURL=agents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/core/agents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEhE,eAAO,MAAM,gBAAgB,EAAE,WAAW,EAgBzC,CAAC;AAEF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAEpE;AAED,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAE5E;AAED,wBAAgB,yBAAyB,IAAI,MAAM,CAGlD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI,SAAS,CAEhE;AAED,wBAAgB,aAAa,IAAI,MAAM,EAAE,CAExC"}
@@ -0,0 +1,34 @@
1
+ export const SUPPORTED_AGENTS = [
2
+ {
3
+ name: 'Claude Code',
4
+ flag: 'claude',
5
+ folderName: '.claude'
6
+ },
7
+ {
8
+ name: 'Codex',
9
+ flag: 'codex',
10
+ folderName: '.codex'
11
+ },
12
+ {
13
+ name: 'Gemini',
14
+ flag: 'gemini',
15
+ folderName: '.gemini'
16
+ }
17
+ ];
18
+ export function getAgentByFlag(flag) {
19
+ return SUPPORTED_AGENTS.find(agent => agent.flag === flag);
20
+ }
21
+ export function getAgentByFolder(folderName) {
22
+ return SUPPORTED_AGENTS.find(agent => agent.folderName === folderName);
23
+ }
24
+ export function getSupportedAgentsMessage() {
25
+ const agentNames = SUPPORTED_AGENTS.map(a => a.name).join(', ');
26
+ return `Currently supported agents: ${agentNames}`;
27
+ }
28
+ export function isValidAgentType(flag) {
29
+ return SUPPORTED_AGENTS.some(agent => agent.flag === flag);
30
+ }
31
+ export function getAgentFlags() {
32
+ return SUPPORTED_AGENTS.map(a => a.flag);
33
+ }
34
+ //# sourceMappingURL=agents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/core/agents.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,gBAAgB,GAAkB;IAC7C;QACE,IAAI,EAAE,aAAa;QACnB,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE,SAAS;KACtB;IACD;QACE,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,OAAO;QACb,UAAU,EAAE,QAAQ;KACrB;IACD;QACE,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE,SAAS;KACtB;CACF,CAAC;AAEF,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,UAAkB;IACjD,OAAO,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,UAAU,KAAK,UAAU,CAAC,CAAC;AACzE,CAAC;AAED,MAAM,UAAU,yBAAyB;IACvC,MAAM,UAAU,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChE,OAAO,+BAA+B,UAAU,EAAE,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,OAAO,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { SunConfig, AgentType } from '../types/index.js';
2
+ export declare function ensureConfigDir(): Promise<void>;
3
+ export declare function loadConfig(): Promise<SunConfig>;
4
+ export declare function saveConfig(config: SunConfig): Promise<void>;
5
+ export declare function isFirstRun(): Promise<boolean>;
6
+ export declare function getDefaultAgents(): Promise<AgentType[]>;
7
+ export declare function setDefaultAgents(agents: AgentType[]): Promise<void>;
8
+ export declare function getConfigPath(): string;
9
+ //# sourceMappingURL=config-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-manager.d.ts","sourceRoot":"","sources":["../../src/core/config-manager.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAU9D,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAErD;AAED,wBAAsB,UAAU,IAAI,OAAO,CAAC,SAAS,CAAC,CAWrD;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAGjE;AAED,wBAAsB,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC,CAGnD;AAED,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC,CAG7D;AAED,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAKzE;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC"}
@@ -0,0 +1,47 @@
1
+ import fs from 'fs-extra';
2
+ import path from 'path';
3
+ import os from 'os';
4
+ const CONFIG_DIR = path.join(os.homedir(), '.sun');
5
+ const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
6
+ const DEFAULT_CONFIG = {
7
+ defaultAgents: [],
8
+ firstRunComplete: false
9
+ };
10
+ export async function ensureConfigDir() {
11
+ await fs.ensureDir(CONFIG_DIR);
12
+ }
13
+ export async function loadConfig() {
14
+ try {
15
+ await ensureConfigDir();
16
+ if (await fs.pathExists(CONFIG_FILE)) {
17
+ const content = await fs.readFile(CONFIG_FILE, 'utf-8');
18
+ return { ...DEFAULT_CONFIG, ...JSON.parse(content) };
19
+ }
20
+ }
21
+ catch {
22
+ // Config doesn't exist or is invalid, return default
23
+ }
24
+ return { ...DEFAULT_CONFIG };
25
+ }
26
+ export async function saveConfig(config) {
27
+ await ensureConfigDir();
28
+ await fs.writeFile(CONFIG_FILE, JSON.stringify(config, null, 2));
29
+ }
30
+ export async function isFirstRun() {
31
+ const config = await loadConfig();
32
+ return !config.firstRunComplete;
33
+ }
34
+ export async function getDefaultAgents() {
35
+ const config = await loadConfig();
36
+ return config.defaultAgents;
37
+ }
38
+ export async function setDefaultAgents(agents) {
39
+ const config = await loadConfig();
40
+ config.defaultAgents = agents;
41
+ config.firstRunComplete = true;
42
+ await saveConfig(config);
43
+ }
44
+ export function getConfigPath() {
45
+ return CONFIG_FILE;
46
+ }
47
+ //# sourceMappingURL=config-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-manager.js","sourceRoot":"","sources":["../../src/core/config-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AAGpB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,MAAM,CAAC,CAAC;AACnD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAEzD,MAAM,cAAc,GAAc;IAChC,aAAa,EAAE,EAAE;IACjB,gBAAgB,EAAE,KAAK;CACxB,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,IAAI,CAAC;QACH,MAAM,eAAe,EAAE,CAAC;QACxB,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YACrC,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;YACxD,OAAO,EAAE,GAAG,cAAc,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QACvD,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,qDAAqD;IACvD,CAAC;IACD,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;AAC/B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAiB;IAChD,MAAM,eAAe,EAAE,CAAC;IACxB,MAAM,EAAE,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;IAClC,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAAC;AAClC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;IAClC,OAAO,MAAM,CAAC,aAAa,CAAC;AAC9B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,MAAmB;IACxD,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;IAClC,MAAM,CAAC,aAAa,GAAG,MAAM,CAAC;IAC9B,MAAM,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAC/B,MAAM,UAAU,CAAC,MAAM,CAAC,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,WAAW,CAAC;AACrB,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Compute a SHA-256 hash of all files in a skill folder.
3
+ * This allows detecting if two skills with the same name have different content.
4
+ *
5
+ * The hash is computed by:
6
+ * 1. Getting all files recursively
7
+ * 2. Sorting them by path for consistency
8
+ * 3. Hashing each file's relative path + content
9
+ * 4. Combining into a final hash
10
+ */
11
+ export declare function computeContentHash(skillPath: string): Promise<string>;
12
+ //# sourceMappingURL=skill-hash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-hash.d.ts","sourceRoot":"","sources":["../../src/core/skill-hash.ts"],"names":[],"mappings":"AA4BA;;;;;;;;;GASG;AACH,wBAAsB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAsB3E"}
@@ -0,0 +1,53 @@
1
+ import crypto from 'crypto';
2
+ import fs from 'fs-extra';
3
+ import path from 'path';
4
+ /**
5
+ * Get all files in a directory recursively, sorted for consistency.
6
+ */
7
+ async function getAllFiles(dir) {
8
+ const files = [];
9
+ async function walk(currentDir) {
10
+ const entries = await fs.readdir(currentDir, { withFileTypes: true });
11
+ for (const entry of entries) {
12
+ const fullPath = path.join(currentDir, entry.name);
13
+ if (entry.isDirectory()) {
14
+ await walk(fullPath);
15
+ }
16
+ else if (entry.isFile()) {
17
+ files.push(fullPath);
18
+ }
19
+ }
20
+ }
21
+ await walk(dir);
22
+ // Sort for consistent ordering across platforms
23
+ return files.sort();
24
+ }
25
+ /**
26
+ * Compute a SHA-256 hash of all files in a skill folder.
27
+ * This allows detecting if two skills with the same name have different content.
28
+ *
29
+ * The hash is computed by:
30
+ * 1. Getting all files recursively
31
+ * 2. Sorting them by path for consistency
32
+ * 3. Hashing each file's relative path + content
33
+ * 4. Combining into a final hash
34
+ */
35
+ export async function computeContentHash(skillPath) {
36
+ const files = await getAllFiles(skillPath);
37
+ if (files.length === 0) {
38
+ // Empty folder - return hash of empty string
39
+ return crypto.createHash('sha256').update('').digest('hex').slice(0, 12);
40
+ }
41
+ const hash = crypto.createHash('sha256');
42
+ for (const file of files) {
43
+ // Include relative path in hash (so moving files changes the hash)
44
+ const relativePath = path.relative(skillPath, file);
45
+ hash.update(relativePath);
46
+ // Include file content
47
+ const content = await fs.readFile(file);
48
+ hash.update(content);
49
+ }
50
+ // Return first 12 chars for readability
51
+ return hash.digest('hex').slice(0, 12);
52
+ }
53
+ //# sourceMappingURL=skill-hash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-hash.js","sourceRoot":"","sources":["../../src/core/skill-hash.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB;;GAEG;AACH,KAAK,UAAU,WAAW,CAAC,GAAW;IACpC,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,UAAU,IAAI,CAAC,UAAkB;QACpC,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAEtE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YACnD,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC;YACvB,CAAC;iBAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;gBAC1B,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACvB,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;IAChB,gDAAgD;IAChD,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC;AACtB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,SAAiB;IACxD,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,SAAS,CAAC,CAAC;IAE3C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,6CAA6C;QAC7C,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC3E,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IAEzC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,mEAAmE;QACnE,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACpD,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAE1B,uBAAuB;QACvB,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACvB,CAAC;IAED,wCAAwC;IACxC,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACzC,CAAC"}