@codemieai/code 0.0.33 → 0.0.34

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 (180) hide show
  1. package/README.md +73 -7
  2. package/bin/codemie-opencode.js +11 -0
  3. package/dist/agents/codemie-code/agent.d.ts +17 -1
  4. package/dist/agents/codemie-code/agent.d.ts.map +1 -1
  5. package/dist/agents/codemie-code/agent.js +62 -3
  6. package/dist/agents/codemie-code/agent.js.map +1 -1
  7. package/dist/agents/codemie-code/index.d.ts +1 -0
  8. package/dist/agents/codemie-code/index.d.ts.map +1 -1
  9. package/dist/agents/codemie-code/index.js +28 -2
  10. package/dist/agents/codemie-code/index.js.map +1 -1
  11. package/dist/agents/codemie-code/prompts.d.ts +12 -3
  12. package/dist/agents/codemie-code/prompts.d.ts.map +1 -1
  13. package/dist/agents/codemie-code/prompts.js +25 -5
  14. package/dist/agents/codemie-code/prompts.js.map +1 -1
  15. package/dist/agents/codemie-code/types.d.ts +3 -0
  16. package/dist/agents/codemie-code/types.d.ts.map +1 -1
  17. package/dist/agents/codemie-code/types.js.map +1 -1
  18. package/dist/agents/core/AgentCLI.d.ts.map +1 -1
  19. package/dist/agents/core/AgentCLI.js +3 -1
  20. package/dist/agents/core/AgentCLI.js.map +1 -1
  21. package/dist/agents/core/BaseAgentAdapter.d.ts.map +1 -1
  22. package/dist/agents/core/BaseAgentAdapter.js +33 -0
  23. package/dist/agents/core/BaseAgentAdapter.js.map +1 -1
  24. package/dist/agents/core/session/BaseSessionAdapter.d.ts +25 -0
  25. package/dist/agents/core/session/BaseSessionAdapter.d.ts.map +1 -1
  26. package/dist/agents/core/session/discovery-types.d.ts +53 -0
  27. package/dist/agents/core/session/discovery-types.d.ts.map +1 -0
  28. package/dist/agents/core/session/discovery-types.js +8 -0
  29. package/dist/agents/core/session/discovery-types.js.map +1 -0
  30. package/dist/agents/core/types.d.ts +45 -0
  31. package/dist/agents/core/types.d.ts.map +1 -1
  32. package/dist/agents/plugins/claude/claude.plugin.d.ts +44 -1
  33. package/dist/agents/plugins/claude/claude.plugin.d.ts.map +1 -1
  34. package/dist/agents/plugins/claude/claude.plugin.js +214 -0
  35. package/dist/agents/plugins/claude/claude.plugin.js.map +1 -1
  36. package/dist/agents/plugins/claude/plugin/README.md +40 -2
  37. package/dist/agents/plugins/claude/plugin/claude-templates/README.md +5 -5
  38. package/dist/agents/plugins/claude/plugin/claude-templates/templates/CLAUDE.md.template +177 -436
  39. package/dist/agents/plugins/claude/plugin/claude-templates/templates/agents/code-review-agent-template.md.template +49 -82
  40. package/dist/agents/plugins/claude/plugin/claude-templates/templates/agents/refactor-cleaner-agent.md.template +337 -0
  41. package/dist/agents/plugins/claude/plugin/claude-templates/templates/agents/solution-architect-agent.md.template +129 -419
  42. package/dist/agents/plugins/claude/plugin/claude-templates/templates/agents/unit-tester-agent.md.template +146 -693
  43. package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/api/api-patterns.md.template +110 -138
  44. package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/architecture/architecture.md.template +197 -0
  45. package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/data/database-patterns.md.template +171 -91
  46. package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/development/development-practices.md.template +219 -131
  47. package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/security/security-practices.md.template +223 -98
  48. package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/standards/code-quality.md.template +131 -95
  49. package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/testing/testing-patterns.md.template +247 -75
  50. package/dist/agents/plugins/claude/plugin/commands/README.md +133 -0
  51. package/dist/agents/plugins/claude/plugin/commands/codemie-init.md +336 -544
  52. package/dist/agents/plugins/claude/plugin/commands/codemie-subagents.md +232 -503
  53. package/dist/agents/plugins/claude/plugin/commands/memory-add.md +311 -30
  54. package/dist/agents/plugins/claude/plugin/commands/memory-refresh.md +218 -39
  55. package/dist/agents/plugins/gemini/gemini.plugin.d.ts.map +1 -1
  56. package/dist/agents/plugins/gemini/gemini.plugin.js +0 -3
  57. package/dist/agents/plugins/gemini/gemini.plugin.js.map +1 -1
  58. package/dist/agents/plugins/opencode/index.d.ts +8 -0
  59. package/dist/agents/plugins/opencode/index.d.ts.map +1 -0
  60. package/dist/agents/plugins/opencode/index.js +12 -0
  61. package/dist/agents/plugins/opencode/index.js.map +1 -0
  62. package/dist/agents/plugins/opencode/opencode-message-types.d.ts +207 -0
  63. package/dist/agents/plugins/opencode/opencode-message-types.d.ts.map +1 -0
  64. package/dist/agents/plugins/opencode/opencode-message-types.js +59 -0
  65. package/dist/agents/plugins/opencode/opencode-message-types.js.map +1 -0
  66. package/dist/agents/plugins/opencode/opencode-model-configs.d.ts +65 -0
  67. package/dist/agents/plugins/opencode/opencode-model-configs.d.ts.map +1 -0
  68. package/dist/agents/plugins/opencode/opencode-model-configs.js +184 -0
  69. package/dist/agents/plugins/opencode/opencode-model-configs.js.map +1 -0
  70. package/dist/agents/plugins/opencode/opencode.paths.d.ts +62 -0
  71. package/dist/agents/plugins/opencode/opencode.paths.d.ts.map +1 -0
  72. package/dist/agents/plugins/opencode/opencode.paths.js +148 -0
  73. package/dist/agents/plugins/opencode/opencode.paths.js.map +1 -0
  74. package/dist/agents/plugins/opencode/opencode.plugin.d.ts +35 -0
  75. package/dist/agents/plugins/opencode/opencode.plugin.d.ts.map +1 -0
  76. package/dist/agents/plugins/opencode/opencode.plugin.js +338 -0
  77. package/dist/agents/plugins/opencode/opencode.plugin.js.map +1 -0
  78. package/dist/agents/plugins/opencode/opencode.session.d.ts +77 -0
  79. package/dist/agents/plugins/opencode/opencode.session.d.ts.map +1 -0
  80. package/dist/agents/plugins/opencode/opencode.session.js +424 -0
  81. package/dist/agents/plugins/opencode/opencode.session.js.map +1 -0
  82. package/dist/agents/plugins/opencode/opencode.storage-utils.d.ts +25 -0
  83. package/dist/agents/plugins/opencode/opencode.storage-utils.d.ts.map +1 -0
  84. package/dist/agents/plugins/opencode/opencode.storage-utils.js +96 -0
  85. package/dist/agents/plugins/opencode/opencode.storage-utils.js.map +1 -0
  86. package/dist/agents/plugins/opencode/session/processors/opencode.conversations-processor.d.ts +30 -0
  87. package/dist/agents/plugins/opencode/session/processors/opencode.conversations-processor.d.ts.map +1 -0
  88. package/dist/agents/plugins/opencode/session/processors/opencode.conversations-processor.js +116 -0
  89. package/dist/agents/plugins/opencode/session/processors/opencode.conversations-processor.js.map +1 -0
  90. package/dist/agents/plugins/opencode/session/processors/opencode.metrics-processor.d.ts +102 -0
  91. package/dist/agents/plugins/opencode/session/processors/opencode.metrics-processor.d.ts.map +1 -0
  92. package/dist/agents/plugins/opencode/session/processors/opencode.metrics-processor.js +584 -0
  93. package/dist/agents/plugins/opencode/session/processors/opencode.metrics-processor.js.map +1 -0
  94. package/dist/agents/registry.d.ts.map +1 -1
  95. package/dist/agents/registry.js +2 -0
  96. package/dist/agents/registry.js.map +1 -1
  97. package/dist/cli/commands/doctor/checks/AgentsCheck.d.ts +5 -0
  98. package/dist/cli/commands/doctor/checks/AgentsCheck.d.ts.map +1 -1
  99. package/dist/cli/commands/doctor/checks/AgentsCheck.js +29 -0
  100. package/dist/cli/commands/doctor/checks/AgentsCheck.js.map +1 -1
  101. package/dist/cli/commands/install.d.ts.map +1 -1
  102. package/dist/cli/commands/install.js +86 -7
  103. package/dist/cli/commands/install.js.map +1 -1
  104. package/dist/cli/commands/opencode-metrics.d.ts +13 -0
  105. package/dist/cli/commands/opencode-metrics.d.ts.map +1 -0
  106. package/dist/cli/commands/opencode-metrics.js +200 -0
  107. package/dist/cli/commands/opencode-metrics.js.map +1 -0
  108. package/dist/cli/commands/setup.d.ts.map +1 -1
  109. package/dist/cli/commands/setup.js +113 -0
  110. package/dist/cli/commands/setup.js.map +1 -1
  111. package/dist/cli/commands/skill.d.ts +6 -0
  112. package/dist/cli/commands/skill.d.ts.map +1 -0
  113. package/dist/cli/commands/skill.js +196 -0
  114. package/dist/cli/commands/skill.js.map +1 -0
  115. package/dist/cli/commands/update.d.ts.map +1 -1
  116. package/dist/cli/commands/update.js +34 -6
  117. package/dist/cli/commands/update.js.map +1 -1
  118. package/dist/cli/index.js +4 -0
  119. package/dist/cli/index.js.map +1 -1
  120. package/dist/migrations/003-remove-hooks-node.migration.d.ts +22 -0
  121. package/dist/migrations/003-remove-hooks-node.migration.d.ts.map +1 -0
  122. package/dist/migrations/003-remove-hooks-node.migration.js +103 -0
  123. package/dist/migrations/003-remove-hooks-node.migration.js.map +1 -0
  124. package/dist/migrations/index.d.ts +1 -0
  125. package/dist/migrations/index.d.ts.map +1 -1
  126. package/dist/migrations/index.js +1 -1
  127. package/dist/migrations/index.js.map +1 -1
  128. package/dist/providers/plugins/sso/sso.http-client.js +2 -2
  129. package/dist/providers/plugins/sso/sso.http-client.js.map +1 -1
  130. package/dist/providers/plugins/sso/sso.setup-steps.d.ts.map +1 -1
  131. package/dist/providers/plugins/sso/sso.setup-steps.js +14 -10
  132. package/dist/providers/plugins/sso/sso.setup-steps.js.map +1 -1
  133. package/dist/skills/core/SkillDiscovery.d.ts +83 -0
  134. package/dist/skills/core/SkillDiscovery.d.ts.map +1 -0
  135. package/dist/skills/core/SkillDiscovery.js +237 -0
  136. package/dist/skills/core/SkillDiscovery.js.map +1 -0
  137. package/dist/skills/core/SkillManager.d.ts +86 -0
  138. package/dist/skills/core/SkillManager.d.ts.map +1 -0
  139. package/dist/skills/core/SkillManager.js +155 -0
  140. package/dist/skills/core/SkillManager.js.map +1 -0
  141. package/dist/skills/core/types.d.ts +120 -0
  142. package/dist/skills/core/types.d.ts.map +1 -0
  143. package/dist/skills/core/types.js +20 -0
  144. package/dist/skills/core/types.js.map +1 -0
  145. package/dist/skills/index.d.ts +12 -0
  146. package/dist/skills/index.d.ts.map +1 -0
  147. package/dist/skills/index.js +12 -0
  148. package/dist/skills/index.js.map +1 -0
  149. package/dist/skills/utils/content-loader.d.ts +25 -0
  150. package/dist/skills/utils/content-loader.d.ts.map +1 -0
  151. package/dist/skills/utils/content-loader.js +161 -0
  152. package/dist/skills/utils/content-loader.js.map +1 -0
  153. package/dist/skills/utils/frontmatter.d.ts +60 -0
  154. package/dist/skills/utils/frontmatter.d.ts.map +1 -0
  155. package/dist/skills/utils/frontmatter.js +114 -0
  156. package/dist/skills/utils/frontmatter.js.map +1 -0
  157. package/dist/skills/utils/pattern-matcher.d.ts +60 -0
  158. package/dist/skills/utils/pattern-matcher.d.ts.map +1 -0
  159. package/dist/skills/utils/pattern-matcher.js +97 -0
  160. package/dist/skills/utils/pattern-matcher.js.map +1 -0
  161. package/dist/utils/installation-detector.d.ts +22 -0
  162. package/dist/utils/installation-detector.d.ts.map +1 -0
  163. package/dist/utils/installation-detector.js +49 -0
  164. package/dist/utils/installation-detector.js.map +1 -0
  165. package/dist/utils/native-installer.d.ts +49 -0
  166. package/dist/utils/native-installer.d.ts.map +1 -0
  167. package/dist/utils/native-installer.js +194 -0
  168. package/dist/utils/native-installer.js.map +1 -0
  169. package/dist/utils/version-utils.d.ts +50 -0
  170. package/dist/utils/version-utils.d.ts.map +1 -0
  171. package/dist/utils/version-utils.js +92 -0
  172. package/dist/utils/version-utils.js.map +1 -0
  173. package/package.json +5 -2
  174. package/scripts/copy-mr-skill-to-global.ts +252 -0
  175. package/scripts/demo-hooks.sh +125 -0
  176. package/scripts/test-hooks.sh +196 -0
  177. package/dist/agents/plugins/claude/plugin/claude-templates/templates/INDEX.md +0 -205
  178. package/dist/agents/plugins/claude/plugin/claude-templates/templates/TEMPLATE_SIZES.md +0 -74
  179. package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/architecture/layered-architecture.md.template +0 -143
  180. package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/architecture/project-structure.md.template +0 -127
@@ -0,0 +1,114 @@
1
+ import { parse as parseYaml } from 'yaml';
2
+ /**
3
+ * Error thrown when frontmatter parsing fails
4
+ */
5
+ export class FrontmatterParseError extends Error {
6
+ filePath;
7
+ cause;
8
+ constructor(message, filePath, cause) {
9
+ super(message);
10
+ this.filePath = filePath;
11
+ this.cause = cause;
12
+ this.name = 'FrontmatterParseError';
13
+ }
14
+ }
15
+ /**
16
+ * Parse YAML frontmatter from a markdown file
17
+ *
18
+ * Expected format:
19
+ * ```
20
+ * ---
21
+ * key: value
22
+ * ---
23
+ * Content here
24
+ * ```
25
+ *
26
+ * @param fileContent - Raw file content
27
+ * @param filePath - Optional file path (for error messages)
28
+ * @returns Parsed frontmatter metadata and markdown content
29
+ * @throws FrontmatterParseError if parsing fails
30
+ */
31
+ export function parseFrontmatter(fileContent, filePath) {
32
+ // Trim leading/trailing whitespace
33
+ const trimmed = fileContent.trim();
34
+ // Check if file starts with frontmatter delimiter
35
+ if (!trimmed.startsWith('---')) {
36
+ throw new FrontmatterParseError('File must start with frontmatter delimiter (---)', filePath);
37
+ }
38
+ // Find the closing delimiter
39
+ const lines = trimmed.split('\n');
40
+ let closingDelimiterIndex = -1;
41
+ // Start from line 1 (skip opening ---)
42
+ for (let i = 1; i < lines.length; i++) {
43
+ if (lines[i].trim() === '---') {
44
+ closingDelimiterIndex = i;
45
+ break;
46
+ }
47
+ }
48
+ if (closingDelimiterIndex === -1) {
49
+ throw new FrontmatterParseError('Missing closing frontmatter delimiter (---)', filePath);
50
+ }
51
+ // Extract YAML content (between delimiters)
52
+ const yamlLines = lines.slice(1, closingDelimiterIndex);
53
+ const yamlContent = yamlLines.join('\n');
54
+ // Extract markdown content (after closing delimiter)
55
+ const contentLines = lines.slice(closingDelimiterIndex + 1);
56
+ const content = contentLines.join('\n').trim();
57
+ // Parse YAML
58
+ let metadata;
59
+ try {
60
+ const parsed = parseYaml(yamlContent);
61
+ // Ensure we got an object
62
+ if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
63
+ throw new Error('Frontmatter must be a YAML object (key-value pairs)');
64
+ }
65
+ metadata = parsed;
66
+ }
67
+ catch (error) {
68
+ throw new FrontmatterParseError(`Failed to parse YAML frontmatter: ${error instanceof Error ? error.message : String(error)}`, filePath, error);
69
+ }
70
+ return {
71
+ metadata,
72
+ content,
73
+ };
74
+ }
75
+ /**
76
+ * Check if a file has valid frontmatter format (non-throwing)
77
+ *
78
+ * @param fileContent - Raw file content
79
+ * @returns true if file has valid frontmatter structure
80
+ */
81
+ export function hasFrontmatter(fileContent) {
82
+ try {
83
+ parseFrontmatter(fileContent);
84
+ return true;
85
+ }
86
+ catch {
87
+ return false;
88
+ }
89
+ }
90
+ /**
91
+ * Extract just the metadata without validating content
92
+ *
93
+ * @param fileContent - Raw file content
94
+ * @param filePath - Optional file path (for error messages)
95
+ * @returns Parsed metadata
96
+ * @throws FrontmatterParseError if parsing fails
97
+ */
98
+ export function extractMetadata(fileContent, filePath) {
99
+ const result = parseFrontmatter(fileContent, filePath);
100
+ return result.metadata;
101
+ }
102
+ /**
103
+ * Extract just the content without validating metadata
104
+ *
105
+ * @param fileContent - Raw file content
106
+ * @param filePath - Optional file path (for error messages)
107
+ * @returns Markdown content
108
+ * @throws FrontmatterParseError if parsing fails
109
+ */
110
+ export function extractContent(fileContent, filePath) {
111
+ const result = parseFrontmatter(fileContent, filePath);
112
+ return result.content;
113
+ }
114
+ //# sourceMappingURL=frontmatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../../../src/skills/utils/frontmatter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Pattern matcher for skill invocation detection
3
+ *
4
+ * Detects /skill-name patterns in user messages and extracts skill names.
5
+ * Excludes URLs and built-in CLI commands.
6
+ */
7
+ /**
8
+ * Skill pattern detected in a message
9
+ */
10
+ export interface SkillPattern {
11
+ /** Skill name (e.g., 'mr', 'commit') */
12
+ name: string;
13
+ /** Position in message where pattern starts */
14
+ position: number;
15
+ /** Optional arguments after skill name */
16
+ args?: string;
17
+ /** Full matched pattern (e.g., '/mr', '/commit -m "fix"') */
18
+ raw: string;
19
+ }
20
+ /**
21
+ * Result of pattern matching
22
+ */
23
+ export interface PatternMatchResult {
24
+ /** Detected skill patterns */
25
+ patterns: SkillPattern[];
26
+ /** Original message */
27
+ originalMessage: string;
28
+ /** Whether any patterns were found */
29
+ hasPatterns: boolean;
30
+ }
31
+ /**
32
+ * Extract skill patterns from a user message
33
+ *
34
+ * @param message - User message to scan
35
+ * @returns Pattern match result with detected skills
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * const result = extractSkillPatterns('/mr');
40
+ * // result.patterns = [{ name: 'mr', position: 0, raw: '/mr' }]
41
+ *
42
+ * const result2 = extractSkillPatterns('ensure you can /commit this');
43
+ * // result2.patterns = [{ name: 'commit', position: 15, args: 'this', raw: '/commit this' }]
44
+ * ```
45
+ */
46
+ export declare function extractSkillPatterns(message: string): PatternMatchResult;
47
+ /**
48
+ * Validate a skill name
49
+ *
50
+ * @param name - Skill name to validate
51
+ * @returns True if valid, false otherwise
52
+ *
53
+ * Rules:
54
+ * - Lowercase letters only
55
+ * - Can include digits and hyphens
56
+ * - Must start with a letter
57
+ * - 1-50 characters
58
+ */
59
+ export declare function isValidSkillName(name: string): boolean;
60
+ //# sourceMappingURL=pattern-matcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pattern-matcher.d.ts","sourceRoot":"","sources":["../../../src/skills/utils/pattern-matcher.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,8BAA8B;IAC9B,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,uBAAuB;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,sCAAsC;IACtC,WAAW,EAAE,OAAO,CAAC;CACtB;AAyBD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,kBAAkB,CA8CxE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtD"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Pattern matcher for skill invocation detection
3
+ *
4
+ * Detects /skill-name patterns in user messages and extracts skill names.
5
+ * Excludes URLs and built-in CLI commands.
6
+ */
7
+ /**
8
+ * Built-in CLI commands that should NOT be treated as skills
9
+ */
10
+ const BUILT_IN_COMMANDS = new Set([
11
+ 'help',
12
+ 'clear',
13
+ 'exit',
14
+ 'quit',
15
+ 'stats',
16
+ 'todos',
17
+ 'config',
18
+ 'health',
19
+ ]);
20
+ /**
21
+ * Regex pattern for skill invocation
22
+ *
23
+ * Matches: /skill-name with optional arguments
24
+ * Excludes: URLs (negative lookbehind for : or alphanumeric before /)
25
+ * Format: /[a-z][a-z0-9-]{0,49} (lowercase, alphanumeric + hyphens, 1-50 chars)
26
+ */
27
+ const SKILL_PATTERN = /(?<![:\w])\/([a-z][a-z0-9-]{0,49})(?:\s+([^\n/]+))?/g;
28
+ /**
29
+ * Extract skill patterns from a user message
30
+ *
31
+ * @param message - User message to scan
32
+ * @returns Pattern match result with detected skills
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * const result = extractSkillPatterns('/mr');
37
+ * // result.patterns = [{ name: 'mr', position: 0, raw: '/mr' }]
38
+ *
39
+ * const result2 = extractSkillPatterns('ensure you can /commit this');
40
+ * // result2.patterns = [{ name: 'commit', position: 15, args: 'this', raw: '/commit this' }]
41
+ * ```
42
+ */
43
+ export function extractSkillPatterns(message) {
44
+ const patterns = [];
45
+ const seenNames = new Set();
46
+ // Reset regex state
47
+ SKILL_PATTERN.lastIndex = 0;
48
+ let match;
49
+ while ((match = SKILL_PATTERN.exec(message)) !== null) {
50
+ const [fullMatch, skillName, args] = match;
51
+ const position = match.index;
52
+ // Skip if this is part of a URL
53
+ // Check if there's http:// or https:// within the last 100 chars before this position
54
+ const lookback = Math.min(100, position);
55
+ const beforeMatch = message.slice(position - lookback, position);
56
+ // If we find a protocol and no whitespace between it and this slash, it's part of a URL
57
+ if (/https?:\/\/[^\s]*$/.test(beforeMatch)) {
58
+ continue;
59
+ }
60
+ // Skip built-in commands
61
+ if (BUILT_IN_COMMANDS.has(skillName)) {
62
+ continue;
63
+ }
64
+ // Deduplicate by skill name (keep first occurrence)
65
+ if (seenNames.has(skillName)) {
66
+ continue;
67
+ }
68
+ seenNames.add(skillName);
69
+ patterns.push({
70
+ name: skillName,
71
+ position,
72
+ args: args?.trim(),
73
+ raw: fullMatch,
74
+ });
75
+ }
76
+ return {
77
+ patterns,
78
+ originalMessage: message,
79
+ hasPatterns: patterns.length > 0,
80
+ };
81
+ }
82
+ /**
83
+ * Validate a skill name
84
+ *
85
+ * @param name - Skill name to validate
86
+ * @returns True if valid, false otherwise
87
+ *
88
+ * Rules:
89
+ * - Lowercase letters only
90
+ * - Can include digits and hyphens
91
+ * - Must start with a letter
92
+ * - 1-50 characters
93
+ */
94
+ export function isValidSkillName(name) {
95
+ return /^[a-z][a-z0-9-]{0,49}$/.test(name);
96
+ }
97
+ //# sourceMappingURL=pattern-matcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pattern-matcher.js","sourceRoot":"","sources":["../../../src/skills/utils/pattern-matcher.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA4BH;;GAEG;AACH,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;IAChC,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,OAAO;IACP,OAAO;IACP,QAAQ;IACR,QAAQ;CACT,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,aAAa,GAAG,sDAAsD,CAAC;AAE7E;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAe;IAClD,MAAM,QAAQ,GAAmB,EAAE,CAAC;IACpC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IAEpC,oBAAoB;IACpB,aAAa,CAAC,SAAS,GAAG,CAAC,CAAC;IAE5B,IAAI,KAA6B,CAAC;IAClC,OAAO,CAAC,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACtD,MAAM,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,KAAK,CAAC;QAC3C,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC;QAE7B,gCAAgC;QAChC,sFAAsF;QACtF,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QACzC,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,GAAG,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAEjE,wFAAwF;QACxF,IAAI,oBAAoB,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;YAC3C,SAAS;QACX,CAAC;QAED,yBAAyB;QACzB,IAAI,iBAAiB,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YACrC,SAAS;QACX,CAAC;QAED,oDAAoD;QACpD,IAAI,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7B,SAAS;QACX,CAAC;QACD,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAEzB,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,SAAS;YACf,QAAQ;YACR,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE;YAClB,GAAG,EAAE,SAAS;SACf,CAAC,CAAC;IACL,CAAC;IAED,OAAO;QACL,QAAQ;QACR,eAAe,EAAE,OAAO;QACxB,WAAW,EAAE,QAAQ,CAAC,MAAM,GAAG,CAAC;KACjC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,OAAO,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7C,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Simple installation method detector for external agents
3
+ * Detects whether agents were installed via npm or native installers
4
+ */
5
+ /**
6
+ * Installation method type
7
+ */
8
+ export type InstallationMethod = 'npm' | 'native' | 'unknown';
9
+ /**
10
+ * Detect if a command was installed via npm by checking its path
11
+ *
12
+ * @param commandName - Command to check (e.g., 'claude')
13
+ * @returns Installation method: 'npm', 'native', or 'unknown'
14
+ *
15
+ * @example
16
+ * const method = await detectInstallationMethod('claude');
17
+ * if (method === 'npm') {
18
+ * console.log('Installed via npm (deprecated)');
19
+ * }
20
+ */
21
+ export declare function detectInstallationMethod(commandName: string): Promise<InstallationMethod>;
22
+ //# sourceMappingURL=installation-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"installation-detector.d.ts","sourceRoot":"","sources":["../../src/utils/installation-detector.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,KAAK,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE9D;;;;;;;;;;;GAWG;AACH,wBAAsB,wBAAwB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAiC/F"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Simple installation method detector for external agents
3
+ * Detects whether agents were installed via npm or native installers
4
+ */
5
+ import { getCommandPath } from './processes.js';
6
+ /**
7
+ * Detect if a command was installed via npm by checking its path
8
+ *
9
+ * @param commandName - Command to check (e.g., 'claude')
10
+ * @returns Installation method: 'npm', 'native', or 'unknown'
11
+ *
12
+ * @example
13
+ * const method = await detectInstallationMethod('claude');
14
+ * if (method === 'npm') {
15
+ * console.log('Installed via npm (deprecated)');
16
+ * }
17
+ */
18
+ export async function detectInstallationMethod(commandName) {
19
+ try {
20
+ // Get the full path to the command
21
+ const commandPath = await getCommandPath(commandName);
22
+ if (!commandPath) {
23
+ return 'unknown';
24
+ }
25
+ // npm-specific path patterns (cross-platform)
26
+ const npmPatterns = [
27
+ '/node_modules/', // Unix: npm global/local
28
+ '/.nvm/', // Unix: nvm installations
29
+ '/.npm-global/', // Unix: npm custom prefix
30
+ '\\node_modules\\', // Windows: npm global/local
31
+ '\\npm\\', // Windows: npm directories
32
+ 'AppData\\npm', // Windows: user npm directory
33
+ 'Program Files\\nodejs\\node_modules', // Windows: system npm
34
+ ];
35
+ // Check if path contains any npm-specific pattern
36
+ for (const pattern of npmPatterns) {
37
+ if (commandPath.includes(pattern)) {
38
+ return 'npm';
39
+ }
40
+ }
41
+ // If not in npm directory, assume native installation
42
+ return 'native';
43
+ }
44
+ catch {
45
+ // If detection fails, return unknown
46
+ return 'unknown';
47
+ }
48
+ }
49
+ //# sourceMappingURL=installation-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"installation-detector.js","sourceRoot":"","sources":["../../src/utils/installation-detector.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAOhD;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,WAAmB;IACjE,IAAI,CAAC;QACJ,mCAAmC;QACnC,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,WAAW,CAAC,CAAC;QAEtD,IAAI,CAAC,WAAW,EAAE,CAAC;YAClB,OAAO,SAAS,CAAC;QAClB,CAAC;QAED,8CAA8C;QAC9C,MAAM,WAAW,GAAG;YACnB,gBAAgB,EAAM,yBAAyB;YAC/C,QAAQ,EAAc,0BAA0B;YAChD,eAAe,EAAO,0BAA0B;YAChD,kBAAkB,EAAI,4BAA4B;YAClD,SAAS,EAAa,2BAA2B;YACjD,cAAc,EAAQ,8BAA8B;YACpD,qCAAqC,EAAE,sBAAsB;SAC7D,CAAC;QAEF,kDAAkD;QAClD,KAAK,MAAM,OAAO,IAAI,WAAW,EAAE,CAAC;YACnC,IAAI,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;gBACnC,OAAO,KAAK,CAAC;YACd,CAAC;QACF,CAAC;QAED,sDAAsD;QACtD,OAAO,QAAQ,CAAC;IACjB,CAAC;IAAC,MAAM,CAAC;QACR,qCAAqC;QACrC,OAAO,SAAS,CAAC;IAClB,CAAC;AACF,CAAC"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Native installer utilities for platform-specific agent installation
3
+ * Used for Claude Code native installation management
4
+ */
5
+ /**
6
+ * Platform-specific installer URLs
7
+ */
8
+ export interface PlatformInstallerUrls {
9
+ macOS: string;
10
+ windows: string;
11
+ linux: string;
12
+ }
13
+ /**
14
+ * Native installation options
15
+ */
16
+ export interface NativeInstallOptions {
17
+ timeout?: number;
18
+ env?: Record<string, string>;
19
+ verifyCommand?: string;
20
+ installFlags?: string[];
21
+ }
22
+ /**
23
+ * Native installation result
24
+ */
25
+ export interface NativeInstallResult {
26
+ success: boolean;
27
+ installedVersion: string | null;
28
+ output: string;
29
+ }
30
+ /**
31
+ * Install agent using native platform installer
32
+ * Detects platform and executes appropriate installation script
33
+ *
34
+ * @param agentName - Agent name for logging (e.g., 'claude')
35
+ * @param installerUrls - Platform-specific installer URLs
36
+ * @param version - Version to install (e.g., '2.0.30', 'latest', 'stable', or undefined)
37
+ * @param options - Installation options (timeout, env, etc.)
38
+ * @returns Installation result with success status and installed version
39
+ * @throws {AgentInstallationError} If installation fails
40
+ *
41
+ * @example
42
+ * await installNativeAgent('claude', {
43
+ * macOS: 'https://claude.ai/install.sh',
44
+ * windows: 'https://claude.ai/install.ps1',
45
+ * linux: 'https://claude.ai/install.sh'
46
+ * }, '2.0.30');
47
+ */
48
+ export declare function installNativeAgent(agentName: string, installerUrls: PlatformInstallerUrls, version?: string, options?: NativeInstallOptions): Promise<NativeInstallResult>;
49
+ //# sourceMappingURL=native-installer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-installer.d.ts","sourceRoot":"","sources":["../../src/utils/native-installer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;CACf;AA0HD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,kBAAkB,CACvC,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,qBAAqB,EACpC,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,oBAAoB,GAC5B,OAAO,CAAC,mBAAmB,CAAC,CAuF9B"}
@@ -0,0 +1,194 @@
1
+ /**
2
+ * Native installer utilities for platform-specific agent installation
3
+ * Used for Claude Code native installation management
4
+ */
5
+ import { exec } from './processes.js';
6
+ import { AgentInstallationError } from './errors.js';
7
+ import { logger } from './logger.js';
8
+ import { sanitizeLogArgs, sanitizeValue } from './security.js';
9
+ import { isValidSemanticVersion } from './version-utils.js';
10
+ /**
11
+ * Detect current platform
12
+ * @returns Platform identifier: 'macOS' | 'windows' | 'linux'
13
+ */
14
+ function detectPlatform() {
15
+ const platform = process.platform;
16
+ if (platform === 'darwin') {
17
+ return 'macOS';
18
+ }
19
+ else if (platform === 'win32') {
20
+ return 'windows';
21
+ }
22
+ else {
23
+ // Assume Linux for all other platforms (linux, freebsd, etc.)
24
+ return 'linux';
25
+ }
26
+ }
27
+ /**
28
+ * Build installer command for the detected platform
29
+ *
30
+ * @param agentName - Agent name for error messages
31
+ * @param installerUrls - Platform-specific installer URLs
32
+ * @param version - Optional version to install
33
+ * @param platform - Detected platform
34
+ * @param installFlags - Additional flags to pass to installer (e.g., ['--force'])
35
+ * @returns Command string to execute
36
+ */
37
+ function buildInstallerCommand(agentName, installerUrls, version, platform, installFlags) {
38
+ // Validate installer URLs are HTTPS (security requirement)
39
+ const url = installerUrls[platform];
40
+ if (!url.startsWith('https://')) {
41
+ throw new AgentInstallationError(agentName, `Installer URL must use HTTPS: ${url}`);
42
+ }
43
+ // SECURITY: Validate version string to prevent command injection
44
+ // Only allow semantic versions or special channels (latest, stable)
45
+ if (version) {
46
+ const allowedChannels = ['latest', 'stable'];
47
+ const isValidChannel = allowedChannels.includes(version.toLowerCase());
48
+ const isValidVersion = isValidSemanticVersion(version);
49
+ if (!isValidChannel && !isValidVersion) {
50
+ throw new AgentInstallationError(agentName, `Invalid version format: "${version}". Expected semantic version (e.g., "2.0.30"), "latest", or "stable".`);
51
+ }
52
+ }
53
+ // SECURITY: Validate install flags against whitelist
54
+ // Only allow known safe flags to prevent command injection
55
+ const allowedFlags = ['--force', '--silent', '--yes', '-y', '-f', '--no-progress'];
56
+ if (installFlags && installFlags.length > 0) {
57
+ for (const flag of installFlags) {
58
+ if (!allowedFlags.includes(flag)) {
59
+ throw new AgentInstallationError(agentName, `Invalid install flag: "${flag}". Allowed flags: ${allowedFlags.join(', ')}`);
60
+ }
61
+ }
62
+ }
63
+ // Build platform-specific command
64
+ if (platform === 'windows') {
65
+ // Windows CMD command (simpler and more universal than PowerShell)
66
+ // Download install.cmd, execute with args, then delete
67
+ const versionArg = version ? ` ${version}` : '';
68
+ const flagsArg = installFlags && installFlags.length > 0 ? ` ${installFlags.join(' ')}` : '';
69
+ return `curl -fsSL ${url} -o install.cmd && install.cmd${versionArg}${flagsArg} && del install.cmd`;
70
+ }
71
+ else {
72
+ // macOS/Linux shell script command
73
+ const versionArg = version ? ` -s -- ${version}` : '';
74
+ const scriptFlags = installFlags && installFlags.length > 0 ? ` ${installFlags.join(' ')}` : '';
75
+ return `curl -fsSL ${url} | bash${versionArg}${scriptFlags}`;
76
+ }
77
+ }
78
+ /**
79
+ * Verify installation by running the verify command
80
+ *
81
+ * @param verifyCommand - Command to verify (e.g., 'claude')
82
+ * @returns Installed version string or null if verification failed
83
+ */
84
+ async function verifyInstallation(verifyCommand) {
85
+ try {
86
+ // Run version check command (e.g., 'claude --version')
87
+ const result = await exec(verifyCommand, ['--version'], {
88
+ timeout: 5000, // 5 second timeout for version check
89
+ });
90
+ if (result.code === 0 && result.stdout) {
91
+ // Parse version from output (usually first line, may have 'v' prefix)
92
+ const versionMatch = result.stdout.trim().match(/v?(\d+\.\d+\.\d+)/);
93
+ if (versionMatch) {
94
+ return versionMatch[1];
95
+ }
96
+ }
97
+ return null;
98
+ }
99
+ catch (error) {
100
+ logger.debug('Installation verification failed', ...sanitizeLogArgs({ error }));
101
+ return null;
102
+ }
103
+ }
104
+ /**
105
+ * Install agent using native platform installer
106
+ * Detects platform and executes appropriate installation script
107
+ *
108
+ * @param agentName - Agent name for logging (e.g., 'claude')
109
+ * @param installerUrls - Platform-specific installer URLs
110
+ * @param version - Version to install (e.g., '2.0.30', 'latest', 'stable', or undefined)
111
+ * @param options - Installation options (timeout, env, etc.)
112
+ * @returns Installation result with success status and installed version
113
+ * @throws {AgentInstallationError} If installation fails
114
+ *
115
+ * @example
116
+ * await installNativeAgent('claude', {
117
+ * macOS: 'https://claude.ai/install.sh',
118
+ * windows: 'https://claude.ai/install.ps1',
119
+ * linux: 'https://claude.ai/install.sh'
120
+ * }, '2.0.30');
121
+ */
122
+ export async function installNativeAgent(agentName, installerUrls, version, options) {
123
+ const platform = detectPlatform();
124
+ const timeout = options?.timeout || 120000; // 2 minute default timeout
125
+ logger.debug('Starting native agent installation', {
126
+ agentName,
127
+ platform,
128
+ version: version || 'latest',
129
+ });
130
+ try {
131
+ // Build installer command
132
+ const command = buildInstallerCommand(agentName, installerUrls, version, platform, options?.installFlags);
133
+ logger.debug('Executing installer command', {
134
+ agentName,
135
+ platform,
136
+ // Don't log full command (may contain sensitive URLs)
137
+ });
138
+ // Execute installer
139
+ const result = await exec(command, [], {
140
+ timeout,
141
+ env: options?.env,
142
+ shell: true, // Required for piped commands (curl | bash)
143
+ });
144
+ // Check if installation succeeded
145
+ if (result.code !== 0) {
146
+ // SECURITY: Sanitize output before including in error message
147
+ // Installer scripts might echo sensitive environment variables
148
+ const sanitizedOutput = sanitizeValue(result.stderr || result.stdout);
149
+ throw new AgentInstallationError(agentName, `Installer exited with code ${result.code}. Output: ${sanitizedOutput}`);
150
+ }
151
+ logger.debug('Installer completed successfully', {
152
+ agentName,
153
+ platform,
154
+ });
155
+ // Verify installation if verify command provided
156
+ let installedVersion = null;
157
+ if (options?.verifyCommand) {
158
+ logger.debug('Verifying installation', {
159
+ agentName,
160
+ verifyCommand: options.verifyCommand,
161
+ });
162
+ installedVersion = await verifyInstallation(options.verifyCommand);
163
+ if (!installedVersion) {
164
+ logger.warn('Installation verification failed', {
165
+ agentName,
166
+ verifyCommand: options.verifyCommand,
167
+ });
168
+ }
169
+ else {
170
+ logger.debug('Installation verified', {
171
+ agentName,
172
+ installedVersion,
173
+ });
174
+ }
175
+ }
176
+ // SECURITY: Sanitize output before returning
177
+ // Prevents exposure of sensitive data in logs or UI
178
+ const sanitizedOutput = sanitizeValue(result.stdout || result.stderr || '');
179
+ return {
180
+ success: true,
181
+ installedVersion,
182
+ output: sanitizedOutput,
183
+ };
184
+ }
185
+ catch (error) {
186
+ // If it's already an AgentInstallationError, rethrow
187
+ if (error instanceof AgentInstallationError) {
188
+ throw error;
189
+ }
190
+ // Wrap other errors
191
+ throw new AgentInstallationError(agentName, `Failed to install: ${error instanceof Error ? error.message : String(error)}`);
192
+ }
193
+ }
194
+ //# sourceMappingURL=native-installer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-installer.js","sourceRoot":"","sources":["../../src/utils/native-installer.ts"],"names":[],"mappings":"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"}