@deimoscloud/coreai 0.1.8 → 0.1.10

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 (196) hide show
  1. package/dist/cli/index.js +5 -0
  2. package/dist/cli/index.js.map +1 -1
  3. package/dist/index.js +3 -1
  4. package/dist/index.js.map +1 -1
  5. package/package.json +6 -1
  6. package/.prettierrc +0 -9
  7. package/AGENT_SPEC.md +0 -347
  8. package/ARCHITECTURE.md +0 -547
  9. package/DRAFT_PRD.md +0 -1440
  10. package/IMPLEMENTATION_PLAN.md +0 -256
  11. package/PRODUCT.md +0 -473
  12. package/WORKFLOWS.md +0 -295
  13. package/commands/core/check-inbox.md +0 -34
  14. package/commands/core/delegate.md +0 -30
  15. package/commands/core/git-commit.md +0 -144
  16. package/commands/core/pr-create.md +0 -193
  17. package/commands/core/review.md +0 -56
  18. package/commands/core/sprint-status.md +0 -65
  19. package/commands/optional/docs-update.md +0 -200
  20. package/commands/optional/jira-create.md +0 -200
  21. package/commands/optional/jira-transition.md +0 -184
  22. package/commands/optional/worktree-cleanup.md +0 -167
  23. package/commands/optional/worktree-setup.md +0 -110
  24. package/eslint.config.js +0 -29
  25. package/jest.config.js +0 -22
  26. package/knowledge-library/README.md +0 -118
  27. package/knowledge-library/android-engineer/context/current.txt +0 -42
  28. package/knowledge-library/android-engineer/control/decisions.txt +0 -9
  29. package/knowledge-library/android-engineer/control/dependencies.txt +0 -19
  30. package/knowledge-library/android-engineer/control/objectives.txt +0 -26
  31. package/knowledge-library/android-engineer/history/.gitkeep +0 -0
  32. package/knowledge-library/android-engineer/inbox/processed/.gitkeep +0 -0
  33. package/knowledge-library/android-engineer/outbox/.gitkeep +0 -0
  34. package/knowledge-library/android-engineer/tech/.gitkeep +0 -0
  35. package/knowledge-library/architecture.txt +0 -61
  36. package/knowledge-library/backend-engineer/context/current.txt +0 -42
  37. package/knowledge-library/backend-engineer/control/decisions.txt +0 -9
  38. package/knowledge-library/backend-engineer/control/dependencies.txt +0 -19
  39. package/knowledge-library/backend-engineer/control/objectives.txt +0 -26
  40. package/knowledge-library/backend-engineer/history/.gitkeep +0 -0
  41. package/knowledge-library/backend-engineer/inbox/processed/.gitkeep +0 -0
  42. package/knowledge-library/backend-engineer/outbox/.gitkeep +0 -0
  43. package/knowledge-library/backend-engineer/tech/.gitkeep +0 -0
  44. package/knowledge-library/context.txt +0 -52
  45. package/knowledge-library/devops-engineer/context/current.txt +0 -42
  46. package/knowledge-library/devops-engineer/control/decisions.txt +0 -9
  47. package/knowledge-library/devops-engineer/control/dependencies.txt +0 -19
  48. package/knowledge-library/devops-engineer/control/objectives.txt +0 -26
  49. package/knowledge-library/devops-engineer/history/.gitkeep +0 -0
  50. package/knowledge-library/devops-engineer/inbox/processed/.gitkeep +0 -0
  51. package/knowledge-library/devops-engineer/outbox/.gitkeep +0 -0
  52. package/knowledge-library/devops-engineer/tech/.gitkeep +0 -0
  53. package/knowledge-library/engineering-manager/context/current.txt +0 -40
  54. package/knowledge-library/engineering-manager/control/decisions.txt +0 -9
  55. package/knowledge-library/engineering-manager/control/objectives.txt +0 -27
  56. package/knowledge-library/engineering-manager/history/.gitkeep +0 -0
  57. package/knowledge-library/engineering-manager/inbox/processed/.gitkeep +0 -0
  58. package/knowledge-library/engineering-manager/outbox/.gitkeep +0 -0
  59. package/knowledge-library/engineering-manager/tech/.gitkeep +0 -0
  60. package/knowledge-library/prd.txt +0 -81
  61. package/knowledge-library/product-manager/context/current.txt +0 -42
  62. package/knowledge-library/product-manager/control/decisions.txt +0 -9
  63. package/knowledge-library/product-manager/control/dependencies.txt +0 -19
  64. package/knowledge-library/product-manager/control/objectives.txt +0 -26
  65. package/knowledge-library/product-manager/history/.gitkeep +0 -0
  66. package/knowledge-library/product-manager/inbox/processed/.gitkeep +0 -0
  67. package/knowledge-library/product-manager/outbox/.gitkeep +0 -0
  68. package/knowledge-library/product-manager/tech/.gitkeep +0 -0
  69. package/knowledge-library/qa-engineer/context/current.txt +0 -42
  70. package/knowledge-library/qa-engineer/control/decisions.txt +0 -9
  71. package/knowledge-library/qa-engineer/control/dependencies.txt +0 -19
  72. package/knowledge-library/qa-engineer/control/objectives.txt +0 -26
  73. package/knowledge-library/qa-engineer/history/.gitkeep +0 -0
  74. package/knowledge-library/qa-engineer/inbox/processed/.gitkeep +0 -0
  75. package/knowledge-library/qa-engineer/outbox/.gitkeep +0 -0
  76. package/knowledge-library/qa-engineer/tech/.gitkeep +0 -0
  77. package/knowledge-library/security-engineer/context/current.txt +0 -42
  78. package/knowledge-library/security-engineer/control/decisions.txt +0 -9
  79. package/knowledge-library/security-engineer/control/dependencies.txt +0 -19
  80. package/knowledge-library/security-engineer/control/objectives.txt +0 -26
  81. package/knowledge-library/security-engineer/history/.gitkeep +0 -0
  82. package/knowledge-library/security-engineer/inbox/processed/.gitkeep +0 -0
  83. package/knowledge-library/security-engineer/outbox/.gitkeep +0 -0
  84. package/knowledge-library/security-engineer/tech/.gitkeep +0 -0
  85. package/knowledge-library/solutions-architect/context/current.txt +0 -42
  86. package/knowledge-library/solutions-architect/control/decisions.txt +0 -9
  87. package/knowledge-library/solutions-architect/control/dependencies.txt +0 -19
  88. package/knowledge-library/solutions-architect/control/objectives.txt +0 -26
  89. package/knowledge-library/solutions-architect/history/.gitkeep +0 -0
  90. package/knowledge-library/solutions-architect/inbox/processed/.gitkeep +0 -0
  91. package/knowledge-library/solutions-architect/outbox/.gitkeep +0 -0
  92. package/knowledge-library/solutions-architect/tech/.gitkeep +0 -0
  93. package/knowledge-library/wearos-engineer/context/current.txt +0 -42
  94. package/knowledge-library/wearos-engineer/control/decisions.txt +0 -9
  95. package/knowledge-library/wearos-engineer/control/dependencies.txt +0 -19
  96. package/knowledge-library/wearos-engineer/control/objectives.txt +0 -26
  97. package/knowledge-library/wearos-engineer/history/.gitkeep +0 -0
  98. package/knowledge-library/wearos-engineer/inbox/processed/.gitkeep +0 -0
  99. package/knowledge-library/wearos-engineer/outbox/.gitkeep +0 -0
  100. package/knowledge-library/wearos-engineer/tech/.gitkeep +0 -0
  101. package/scripts/add-agent.sh +0 -323
  102. package/scripts/install.sh +0 -354
  103. package/src/adapters/factory.test.ts +0 -386
  104. package/src/adapters/factory.ts +0 -305
  105. package/src/adapters/index.ts +0 -113
  106. package/src/adapters/interfaces.ts +0 -268
  107. package/src/adapters/mcp/client.test.ts +0 -130
  108. package/src/adapters/mcp/client.ts +0 -451
  109. package/src/adapters/mcp/discovery.test.ts +0 -315
  110. package/src/adapters/mcp/discovery.ts +0 -340
  111. package/src/adapters/mcp/index.ts +0 -66
  112. package/src/adapters/mcp/mapper.test.ts +0 -218
  113. package/src/adapters/mcp/mapper.ts +0 -536
  114. package/src/adapters/mcp/registry.test.ts +0 -433
  115. package/src/adapters/mcp/registry.ts +0 -550
  116. package/src/adapters/mcp/types.ts +0 -258
  117. package/src/adapters/native/filesystem.test.ts +0 -350
  118. package/src/adapters/native/filesystem.ts +0 -393
  119. package/src/adapters/native/github.test.ts +0 -173
  120. package/src/adapters/native/github.ts +0 -627
  121. package/src/adapters/native/index.ts +0 -22
  122. package/src/adapters/native/selector.test.ts +0 -224
  123. package/src/adapters/native/selector.ts +0 -150
  124. package/src/adapters/types.ts +0 -270
  125. package/src/agents/compiler.test.ts +0 -399
  126. package/src/agents/compiler.ts +0 -422
  127. package/src/agents/index.ts +0 -37
  128. package/src/agents/loader.test.ts +0 -319
  129. package/src/agents/loader.ts +0 -143
  130. package/src/agents/resolver.test.ts +0 -282
  131. package/src/agents/resolver.ts +0 -262
  132. package/src/agents/types.ts +0 -97
  133. package/src/cache/index.ts +0 -38
  134. package/src/cache/interfaces.ts +0 -283
  135. package/src/cache/manager.test.ts +0 -266
  136. package/src/cache/manager.ts +0 -388
  137. package/src/cache/provider.test.ts +0 -485
  138. package/src/cache/provider.ts +0 -745
  139. package/src/cache/types.test.ts +0 -192
  140. package/src/cache/types.ts +0 -313
  141. package/src/cli/commands/build.test.ts +0 -248
  142. package/src/cli/commands/build.ts +0 -284
  143. package/src/cli/commands/cache.test.ts +0 -221
  144. package/src/cli/commands/cache.ts +0 -229
  145. package/src/cli/commands/index.ts +0 -63
  146. package/src/cli/commands/init.test.ts +0 -173
  147. package/src/cli/commands/init.ts +0 -296
  148. package/src/cli/commands/skills.test.ts +0 -272
  149. package/src/cli/commands/skills.ts +0 -348
  150. package/src/cli/commands/status.test.ts +0 -392
  151. package/src/cli/commands/status.ts +0 -332
  152. package/src/cli/commands/sync.test.ts +0 -213
  153. package/src/cli/commands/sync.ts +0 -251
  154. package/src/cli/commands/validate.test.ts +0 -216
  155. package/src/cli/commands/validate.ts +0 -340
  156. package/src/cli/index.test.ts +0 -190
  157. package/src/cli/index.ts +0 -493
  158. package/src/commands/context.test.ts +0 -163
  159. package/src/commands/context.ts +0 -111
  160. package/src/commands/index.ts +0 -56
  161. package/src/commands/loader.test.ts +0 -273
  162. package/src/commands/loader.ts +0 -355
  163. package/src/commands/registry.test.ts +0 -384
  164. package/src/commands/registry.ts +0 -248
  165. package/src/commands/runner.test.ts +0 -297
  166. package/src/commands/runner.ts +0 -222
  167. package/src/commands/types.ts +0 -361
  168. package/src/config/index.ts +0 -19
  169. package/src/config/loader.test.ts +0 -262
  170. package/src/config/loader.ts +0 -188
  171. package/src/config/types.ts +0 -154
  172. package/src/context/index.ts +0 -14
  173. package/src/context/loader.test.ts +0 -334
  174. package/src/context/loader.ts +0 -357
  175. package/src/index.test.ts +0 -13
  176. package/src/index.ts +0 -268
  177. package/src/knowledge-library/index.ts +0 -44
  178. package/src/knowledge-library/manager.test.ts +0 -536
  179. package/src/knowledge-library/manager.ts +0 -804
  180. package/src/knowledge-library/types.ts +0 -432
  181. package/src/skills/generator.test.ts +0 -602
  182. package/src/skills/generator.ts +0 -491
  183. package/src/skills/index.ts +0 -27
  184. package/src/skills/templates.ts +0 -520
  185. package/src/skills/types.ts +0 -251
  186. package/templates/completion-report.md +0 -72
  187. package/templates/feedback.md +0 -56
  188. package/templates/project-files/CLAUDE.md.template +0 -109
  189. package/templates/project-files/coreai.json.example +0 -47
  190. package/templates/project-files/mcp.json.template +0 -20
  191. package/templates/review-complete.md +0 -64
  192. package/templates/review-request.md +0 -67
  193. package/templates/task-assignment.md +0 -51
  194. package/tsconfig.build.json +0 -4
  195. package/tsconfig.json +0 -26
  196. package/tsup.config.ts +0 -23
@@ -1,296 +0,0 @@
1
- /**
2
- * Init Command
3
- *
4
- * Initializes a new CoreAI project with configuration file and directory structure.
5
- */
6
-
7
- import { existsSync, writeFileSync, mkdirSync, readFileSync } from 'fs';
8
- import { join, basename } from 'path';
9
- import { execSync } from 'child_process';
10
- import type { ProjectType, GitProvider } from '../../config/types.js';
11
- import { configExists } from '../../config/loader.js';
12
-
13
- /**
14
- * Options for init command
15
- */
16
- export interface InitCommandOptions {
17
- /**
18
- * Project root directory
19
- */
20
- projectRoot?: string;
21
-
22
- /**
23
- * Overwrite existing configuration
24
- */
25
- force?: boolean;
26
-
27
- /**
28
- * Skip interactive prompts
29
- */
30
- nonInteractive?: boolean;
31
-
32
- /**
33
- * Project name (for non-interactive mode)
34
- */
35
- name?: string;
36
-
37
- /**
38
- * Project type (for non-interactive mode)
39
- */
40
- type?: ProjectType;
41
-
42
- /**
43
- * Skip creating directory structure
44
- */
45
- skipDirs?: boolean;
46
- }
47
-
48
- /**
49
- * Result of init command
50
- */
51
- export interface InitCommandResult {
52
- success: boolean;
53
- configPath?: string;
54
- createdDirs?: string[];
55
- error?: string;
56
- gitInfo?: {
57
- provider?: GitProvider;
58
- owner?: string;
59
- repo?: string;
60
- };
61
- }
62
-
63
- /**
64
- * Detect git remote information
65
- */
66
- function detectGitInfo(): { provider?: GitProvider; owner?: string; repo?: string } | null {
67
- try {
68
- const remoteUrl = execSync('git remote get-url origin', { encoding: 'utf-8' }).trim();
69
-
70
- // GitHub HTTPS: https://github.com/owner/repo.git
71
- const httpsMatch = remoteUrl.match(/https:\/\/github\.com\/([^/]+)\/([^/.]+)/);
72
- if (httpsMatch) {
73
- return { provider: 'github', owner: httpsMatch[1], repo: httpsMatch[2] };
74
- }
75
-
76
- // GitHub SSH: git@github.com:owner/repo.git
77
- const sshMatch = remoteUrl.match(/git@github\.com:([^/]+)\/([^/.]+)/);
78
- if (sshMatch) {
79
- return { provider: 'github', owner: sshMatch[1], repo: sshMatch[2] };
80
- }
81
-
82
- // GitLab HTTPS
83
- const gitlabHttps = remoteUrl.match(/https:\/\/gitlab\.com\/([^/]+)\/([^/.]+)/);
84
- if (gitlabHttps) {
85
- return { provider: 'gitlab', owner: gitlabHttps[1], repo: gitlabHttps[2] };
86
- }
87
-
88
- // GitLab SSH
89
- const gitlabSsh = remoteUrl.match(/git@gitlab\.com:([^/]+)\/([^/.]+)/);
90
- if (gitlabSsh) {
91
- return { provider: 'gitlab', owner: gitlabSsh[1], repo: gitlabSsh[2] };
92
- }
93
-
94
- return null;
95
- } catch {
96
- // Not a git repo or no remote
97
- return null;
98
- }
99
- }
100
-
101
- /**
102
- * Detect project name from directory or package.json
103
- */
104
- function detectProjectName(projectRoot: string): string {
105
- // Try package.json first
106
- const packageJsonPath = join(projectRoot, 'package.json');
107
- if (existsSync(packageJsonPath)) {
108
- try {
109
- const content = JSON.parse(readFileSync(packageJsonPath, 'utf-8')) as { name?: string };
110
- if (content.name) {
111
- return content.name;
112
- }
113
- } catch {
114
- // Ignore parse errors
115
- }
116
- }
117
-
118
- // Fall back to directory name
119
- return basename(projectRoot);
120
- }
121
-
122
- /**
123
- * Generate config file content
124
- */
125
- function generateConfigYaml(options: {
126
- name: string;
127
- type: ProjectType;
128
- gitInfo?: { provider?: GitProvider; owner?: string; repo?: string } | null;
129
- }): string {
130
- let yaml = `# CoreAI Configuration
131
- # See https://coreai.dev/docs/config for full schema
132
-
133
- version: "1.0"
134
-
135
- project:
136
- name: "${options.name}"
137
- type: ${options.type}
138
-
139
- team:
140
- agents:
141
- - backend-engineer
142
- - frontend-engineer
143
- - devops-engineer
144
- - engineering-manager
145
- `;
146
-
147
- if (options.gitInfo?.provider) {
148
- yaml += `
149
- integrations:
150
- git:
151
- provider: ${options.gitInfo.provider}
152
- config:
153
- owner: "${options.gitInfo.owner}"
154
- repo: "${options.gitInfo.repo}"
155
- `;
156
- }
157
-
158
- yaml += `
159
- # quality_gates:
160
- # lint:
161
- # command: npm run lint
162
- # required: true
163
- # test:
164
- # command: npm test
165
- # required: true
166
- # build:
167
- # command: npm run build
168
- # required: true
169
-
170
- # tech_stack:
171
- # primary_language: typescript
172
- # frameworks:
173
- # - node.js
174
- # - express
175
- `;
176
-
177
- return yaml;
178
- }
179
-
180
- /**
181
- * Create directory structure for CoreAI
182
- */
183
- function createDirectories(projectRoot: string): string[] {
184
- const dirs = [
185
- join(projectRoot, 'coreai', 'agents'),
186
- join(projectRoot, 'coreai', 'commands'),
187
- join(projectRoot, '.coreai', 'cache'),
188
- ];
189
-
190
- const created: string[] = [];
191
-
192
- for (const dir of dirs) {
193
- if (!existsSync(dir)) {
194
- mkdirSync(dir, { recursive: true });
195
- created.push(dir);
196
- }
197
- }
198
-
199
- return created;
200
- }
201
-
202
- /**
203
- * Initialize a new CoreAI project
204
- */
205
- export function init(options: InitCommandOptions = {}): InitCommandResult {
206
- const projectRoot = options.projectRoot ?? process.cwd();
207
-
208
- // Check if config already exists
209
- if (configExists(projectRoot) && !options.force) {
210
- return {
211
- success: false,
212
- error: 'CoreAI configuration already exists. Use --force to overwrite.',
213
- };
214
- }
215
-
216
- // Detect git info
217
- const gitInfo = detectGitInfo();
218
-
219
- // Determine project name
220
- const name = options.name ?? detectProjectName(projectRoot);
221
-
222
- // Determine project type
223
- const type = options.type ?? 'software';
224
-
225
- // Generate config
226
- const configContent = generateConfigYaml({ name, type, gitInfo });
227
-
228
- // Write config file
229
- const configPath = join(projectRoot, 'coreai.config.yaml');
230
- try {
231
- writeFileSync(configPath, configContent, 'utf-8');
232
- } catch (error) {
233
- return {
234
- success: false,
235
- error: `Failed to write config file: ${error instanceof Error ? error.message : String(error)}`,
236
- };
237
- }
238
-
239
- // Create directories unless skipped
240
- let createdDirs: string[] = [];
241
- if (!options.skipDirs) {
242
- try {
243
- createdDirs = createDirectories(projectRoot);
244
- } catch (error) {
245
- return {
246
- success: false,
247
- configPath,
248
- error: `Failed to create directories: ${error instanceof Error ? error.message : String(error)}`,
249
- };
250
- }
251
- }
252
-
253
- return {
254
- success: true,
255
- configPath,
256
- createdDirs,
257
- gitInfo: gitInfo ?? undefined,
258
- };
259
- }
260
-
261
- /**
262
- * Format init result for display
263
- */
264
- export function formatInitResult(result: InitCommandResult): string {
265
- if (!result.success) {
266
- return `Error: ${result.error}`;
267
- }
268
-
269
- const lines: string[] = [];
270
-
271
- lines.push('CoreAI project initialized successfully!\n');
272
-
273
- if (result.configPath) {
274
- lines.push(`Created: ${result.configPath}`);
275
- }
276
-
277
- if (result.createdDirs && result.createdDirs.length > 0) {
278
- lines.push('\nCreated directories:');
279
- for (const dir of result.createdDirs) {
280
- lines.push(` - ${dir}`);
281
- }
282
- }
283
-
284
- if (result.gitInfo?.provider) {
285
- lines.push(
286
- `\nDetected ${result.gitInfo.provider} repository: ${result.gitInfo.owner}/${result.gitInfo.repo}`
287
- );
288
- }
289
-
290
- lines.push('\nNext steps:');
291
- lines.push(' 1. Edit coreai.config.yaml to configure your project');
292
- lines.push(' 2. Run `coreai build` to compile agents');
293
- lines.push(' 3. Run `coreai validate` to check your setup');
294
-
295
- return lines.join('\n');
296
- }
@@ -1,272 +0,0 @@
1
- /**
2
- * Skills Command Tests
3
- */
4
-
5
- import { promises as fs } from 'fs';
6
- import { join } from 'path';
7
- import { tmpdir } from 'os';
8
- import {
9
- skillsGenerate,
10
- formatSkillsGenerateResult,
11
- skillsList,
12
- formatSkillsListResult,
13
- } from './skills.js';
14
-
15
- describe('Skills Command', () => {
16
- let testDir: string;
17
-
18
- beforeEach(async () => {
19
- testDir = join(
20
- tmpdir(),
21
- `skills-cmd-test-${Date.now()}-${Math.random().toString(36).slice(2)}`
22
- );
23
- await fs.mkdir(testDir, { recursive: true });
24
- });
25
-
26
- afterEach(async () => {
27
- try {
28
- await fs.rm(testDir, { recursive: true, force: true });
29
- } catch {
30
- // Ignore cleanup errors
31
- }
32
- });
33
-
34
- describe('skillsGenerate', () => {
35
- it('should generate skills with defaults', () => {
36
- const result = skillsGenerate({
37
- projectRoot: testDir,
38
- });
39
-
40
- expect(result.success).toBe(true);
41
- expect(result.result).toBeDefined();
42
- expect(result.result?.generated.length).toBeGreaterThan(0);
43
- });
44
-
45
- it('should generate skills without config', () => {
46
- const result = skillsGenerate({
47
- projectRoot: testDir,
48
- });
49
-
50
- expect(result.success).toBe(true);
51
- expect(result.warnings).toContain(
52
- 'No configuration file found. Generating skills with defaults.'
53
- );
54
- });
55
-
56
- it('should generate only core skills', () => {
57
- const result = skillsGenerate({
58
- projectRoot: testDir,
59
- includeCoreSkills: true,
60
- includeOptionalSkills: false,
61
- });
62
-
63
- expect(result.success).toBe(true);
64
- const generated = result.result?.generated ?? [];
65
- expect(generated.every((g) => g.category === 'core')).toBe(true);
66
- });
67
-
68
- it('should generate specific skills', () => {
69
- const result = skillsGenerate({
70
- projectRoot: testDir,
71
- skills: ['check-inbox', 'delegate'],
72
- });
73
-
74
- expect(result.success).toBe(true);
75
- expect(result.result?.generated).toHaveLength(2);
76
- });
77
-
78
- it('should fail with invalid config', async () => {
79
- // Create invalid config
80
- await fs.writeFile(join(testDir, 'coreai.config.yaml'), 'invalid: yaml: syntax:::');
81
-
82
- const result = skillsGenerate({
83
- projectRoot: testDir,
84
- });
85
-
86
- expect(result.success).toBe(false);
87
- expect(result.error).toContain('Configuration error');
88
- });
89
-
90
- it('should use custom output directory', async () => {
91
- const customOutputDir = join(testDir, 'custom', 'skills');
92
-
93
- const result = skillsGenerate({
94
- projectRoot: testDir,
95
- outputDir: customOutputDir,
96
- skills: ['check-inbox'],
97
- });
98
-
99
- expect(result.success).toBe(true);
100
-
101
- // Verify file created in custom directory
102
- const stat = await fs.stat(join(customOutputDir, 'check-inbox.md'));
103
- expect(stat.isFile()).toBe(true);
104
- });
105
-
106
- it('should pass custom variables', () => {
107
- const result = skillsGenerate({
108
- projectRoot: testDir,
109
- skills: ['check-inbox'],
110
- variables: {
111
- CUSTOM_VAR: 'custom-value',
112
- },
113
- });
114
-
115
- expect(result.success).toBe(true);
116
- expect(result.result?.variables.CUSTOM_VAR).toBe('custom-value');
117
- });
118
- });
119
-
120
- describe('formatSkillsGenerateResult', () => {
121
- it('should format success result', () => {
122
- const result = skillsGenerate({
123
- projectRoot: testDir,
124
- skills: ['check-inbox'],
125
- });
126
-
127
- const output = formatSkillsGenerateResult(result);
128
- expect(output).toContain('Created');
129
- expect(output).toContain('check-inbox');
130
- });
131
-
132
- it('should format error result', () => {
133
- const result = {
134
- success: false,
135
- error: 'Something went wrong',
136
- };
137
-
138
- const output = formatSkillsGenerateResult(result);
139
- expect(output).toContain('failed');
140
- expect(output).toContain('Something went wrong');
141
- });
142
-
143
- it('should include warnings', () => {
144
- const result = skillsGenerate({
145
- projectRoot: testDir,
146
- skills: ['check-inbox'],
147
- });
148
-
149
- const output = formatSkillsGenerateResult(result);
150
- // Should show warning about missing config
151
- expect(output.includes('warning') || output.includes('No configuration')).toBe(false);
152
- // This should have the created message
153
- expect(output).toContain('Created');
154
- });
155
- });
156
-
157
- describe('skillsList', () => {
158
- it('should list all built-in skills', () => {
159
- const result = skillsList();
160
-
161
- expect(result.success).toBe(true);
162
- expect(result.skills).toBeDefined();
163
- expect(result.skills?.length).toBeGreaterThan(0);
164
- });
165
-
166
- it('should list only core skills', () => {
167
- const result = skillsList({
168
- includeCoreSkills: true,
169
- includeOptionalSkills: false,
170
- });
171
-
172
- expect(result.success).toBe(true);
173
- expect(result.skills?.every((s) => s.category === 'core')).toBe(true);
174
- });
175
-
176
- it('should list only optional skills', () => {
177
- const result = skillsList({
178
- includeCoreSkills: false,
179
- includeOptionalSkills: true,
180
- });
181
-
182
- expect(result.success).toBe(true);
183
- expect(result.skills?.every((s) => s.category === 'optional')).toBe(true);
184
- });
185
-
186
- it('should include skill metadata', () => {
187
- const result = skillsList();
188
-
189
- expect(result.success).toBe(true);
190
- const skill = result.skills?.[0];
191
- expect(skill?.name).toBeDefined();
192
- expect(skill?.description).toBeDefined();
193
- expect(skill?.category).toBeDefined();
194
- });
195
-
196
- it('should load custom templates when directory provided', async () => {
197
- const customDir = join(testDir, 'templates');
198
- await fs.mkdir(customDir, { recursive: true });
199
- await fs.writeFile(
200
- join(customDir, 'custom-skill.md'),
201
- '---\ndescription: My custom skill\n---\nContent'
202
- );
203
-
204
- const result = skillsList({
205
- customTemplatesDir: customDir,
206
- });
207
-
208
- expect(result.success).toBe(true);
209
- const customSkill = result.skills?.find((s) => s.name === 'custom-skill');
210
- expect(customSkill).toBeDefined();
211
- expect(customSkill?.description).toBe('My custom skill');
212
- });
213
- });
214
-
215
- describe('formatSkillsListResult', () => {
216
- it('should format skills list', () => {
217
- const result = skillsList();
218
- const output = formatSkillsListResult(result);
219
-
220
- expect(output).toContain('Available skills');
221
- expect(output).toContain('Core skills');
222
- });
223
-
224
- it('should format error result', () => {
225
- const result = {
226
- success: false,
227
- error: 'Failed to list skills',
228
- };
229
-
230
- const output = formatSkillsListResult(result);
231
- expect(output).toContain('Error');
232
- expect(output).toContain('Failed to list skills');
233
- });
234
-
235
- it('should show no skills message', () => {
236
- const result = {
237
- success: true,
238
- skills: [],
239
- };
240
-
241
- const output = formatSkillsListResult(result);
242
- expect(output).toContain('No skills available');
243
- });
244
-
245
- it('should group skills by category', () => {
246
- const result = skillsList();
247
- const output = formatSkillsListResult(result);
248
-
249
- // Should have at least core skills section
250
- expect(output).toContain('Core skills');
251
- });
252
-
253
- it('should show argument hints', () => {
254
- const result = skillsList();
255
- const output = formatSkillsListResult(result);
256
-
257
- // Many skills have argument hints
258
- expect(output).toContain('Argument:');
259
- });
260
-
261
- it('should show dependencies for optional skills', () => {
262
- const result = skillsList({
263
- includeCoreSkills: false,
264
- includeOptionalSkills: true,
265
- });
266
-
267
- const output = formatSkillsListResult(result);
268
- // Optional skills have dependencies
269
- expect(output).toContain('requires:');
270
- });
271
- });
272
- });