@deimoscloud/coreai 0.1.9 → 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 +1 -1
  2. package/dist/cli/index.js.map +1 -1
  3. package/dist/index.js +1 -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 -410
  126. package/src/agents/compiler.ts +0 -424
  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
package/src/cli/index.ts DELETED
@@ -1,493 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * CoreAI CLI - Entry point
5
- *
6
- * A configurable, team-ready AI agent orchestration platform.
7
- */
8
-
9
- import { join, dirname } from 'path';
10
- import { fileURLToPath } from 'url';
11
- import { Command } from 'commander';
12
- import { VERSION } from '../index.js';
13
- import { loadAllAgents, generateAgentMarkdown } from '../agents/index.js';
14
- import {
15
- cacheStatus,
16
- cacheClear,
17
- cacheClearExpired,
18
- formatCacheStatus,
19
- sync,
20
- formatSyncResult,
21
- init,
22
- formatInitResult,
23
- build,
24
- formatBuildResult,
25
- validate,
26
- formatValidateResult,
27
- status,
28
- formatStatusResult,
29
- skillsGenerate,
30
- formatSkillsGenerateResult,
31
- skillsList,
32
- formatSkillsListResult,
33
- } from './commands/index.js';
34
-
35
- const __filename = fileURLToPath(import.meta.url);
36
- const __dirname = dirname(__filename);
37
-
38
- /**
39
- * Get the path to built-in core agents
40
- */
41
- function getCoreAgentsPath(): string {
42
- // Navigate from dist/cli/index.js to agents/
43
- return join(__dirname, '..', '..', 'agents');
44
- }
45
-
46
- const program = new Command();
47
-
48
- program
49
- .name('coreai')
50
- .description('A configurable, team-ready AI agent orchestration platform')
51
- .version(VERSION, '-v, --version', 'output the current version');
52
-
53
- // Init command - initialize a new CoreAI project
54
- program
55
- .command('init')
56
- .description('Initialize a new CoreAI project')
57
- .option('-f, --force', 'overwrite existing configuration')
58
- .option('-n, --name <name>', 'project name')
59
- .option('-t, --type <type>', 'project type (software, infrastructure, data, mobile)')
60
- .option('--skip-dirs', 'skip creating directory structure')
61
- .action((options: { force?: boolean; name?: string; type?: string; skipDirs?: boolean }) => {
62
- const result = init({
63
- projectRoot: process.cwd(),
64
- force: options.force,
65
- name: options.name,
66
- type: options.type as 'software' | 'infrastructure' | 'data' | 'mobile',
67
- skipDirs: options.skipDirs,
68
- });
69
-
70
- console.log(formatInitResult(result));
71
-
72
- if (!result.success) {
73
- process.exit(1);
74
- }
75
- });
76
-
77
- // Build command - compile agents to .claude/agents/
78
- program
79
- .command('build')
80
- .description('Compile agent definitions to Claude-compatible markdown')
81
- .option('-w, --watch', 'watch for changes and rebuild')
82
- .option('-o, --output <dir>', 'output directory (default: .claude/agents)')
83
- .option('--agents <agents>', 'comma-separated list of agents to build')
84
- .option('--init-knowledge-library', 'initialize KnowledgeLibrary directories for agents')
85
- .action(
86
- (options: {
87
- watch?: boolean;
88
- output?: string;
89
- agents?: string;
90
- initKnowledgeLibrary?: boolean;
91
- }) => {
92
- if (options.watch) {
93
- console.log('Watch mode is not yet implemented');
94
- process.exit(1);
95
- }
96
-
97
- console.log('Building agents...\n');
98
-
99
- const result = build({
100
- projectRoot: process.cwd(),
101
- coreAgentsDir: getCoreAgentsPath(),
102
- outputDir: options.output,
103
- agents: options.agents?.split(',').map((a) => a.trim()),
104
- initKnowledgeLibrary: options.initKnowledgeLibrary,
105
- });
106
-
107
- console.log(formatBuildResult(result));
108
-
109
- if (!result.success) {
110
- process.exit(1);
111
- }
112
- }
113
- );
114
-
115
- // Sync command - sync shared context from remote sources
116
- program
117
- .command('sync')
118
- .description('Sync shared context from remote sources')
119
- .option('--force', 'force refresh all cached content')
120
- .option('--source <source>', 'filter by source (github, confluence, notion)')
121
- .option('--concurrency <n>', 'max concurrent fetches', '5')
122
- .action(async (options: { force?: boolean; source?: string; concurrency?: string }) => {
123
- try {
124
- console.log('Syncing shared context...\n');
125
-
126
- const result = await sync({
127
- projectRoot: process.cwd(),
128
- force: options.force,
129
- source: options.source as 'github' | 'confluence' | 'notion' | 'local' | 'custom',
130
- concurrency: parseInt(options.concurrency ?? '5', 10),
131
- continueOnError: true,
132
- onProgress: (completed, total, message) => {
133
- process.stdout.write(`\r${message}`);
134
- },
135
- });
136
-
137
- // Clear the progress line
138
- process.stdout.write('\r' + ' '.repeat(60) + '\r');
139
-
140
- console.log(formatSyncResult(result));
141
-
142
- if (!result.success) {
143
- process.exit(1);
144
- }
145
- } catch (error) {
146
- console.error(`Sync failed: ${error instanceof Error ? error.message : error}`);
147
- process.exit(1);
148
- }
149
- });
150
-
151
- // Validate command - validate configuration and setup
152
- program
153
- .command('validate')
154
- .description('Validate configuration and project setup')
155
- .option('--skip-agents', 'skip agent validation')
156
- .option('--skip-dirs', 'skip directory validation')
157
- .option('--json', 'output as JSON')
158
- .action((options: { skipAgents?: boolean; skipDirs?: boolean; json?: boolean }) => {
159
- const result = validate({
160
- projectRoot: process.cwd(),
161
- coreAgentsDir: getCoreAgentsPath(),
162
- checkAgents: !options.skipAgents,
163
- checkDirs: !options.skipDirs,
164
- });
165
-
166
- if (options.json) {
167
- console.log(JSON.stringify(result, null, 2));
168
- } else {
169
- console.log(formatValidateResult(result));
170
- }
171
-
172
- if (!result.valid) {
173
- process.exit(1);
174
- }
175
- });
176
-
177
- // Agents subcommand group
178
- const agents = program.command('agents').description('Manage agent definitions');
179
-
180
- agents
181
- .command('list')
182
- .description('List available agents')
183
- .option('--core', 'show only core agents')
184
- .option('--custom', 'show only custom agents')
185
- .action((options: { core?: boolean; custom?: boolean }) => {
186
- try {
187
- const customAgentsDir = join(process.cwd(), 'coreai', 'agents');
188
-
189
- const allAgents = loadAllAgents({
190
- coreAgentsDir: getCoreAgentsPath(),
191
- customAgentsDir,
192
- });
193
-
194
- if (allAgents.size === 0) {
195
- console.log('No agents found.');
196
- return;
197
- }
198
-
199
- // Filter by source if requested
200
- const agents = Array.from(allAgents.entries()).filter(([, meta]) => {
201
- if (options.core && meta.source !== 'core') return false;
202
- if (options.custom && meta.source !== 'custom' && meta.source !== 'override') return false;
203
- return true;
204
- });
205
-
206
- if (agents.length === 0) {
207
- console.log('No matching agents found.');
208
- return;
209
- }
210
-
211
- console.log('Available agents:\n');
212
-
213
- // Group by source
214
- const coreAgents = agents.filter(([, m]) => m.source === 'core');
215
- const customAgents = agents.filter(([, m]) => m.source === 'custom');
216
- const overrideAgents = agents.filter(([, m]) => m.source === 'override');
217
-
218
- if (coreAgents.length > 0 && !options.custom) {
219
- console.log('Core agents:');
220
- for (const [role, meta] of coreAgents) {
221
- console.log(` ${role} (${meta.definition.type})`);
222
- console.log(` ${meta.definition.display_name}`);
223
- }
224
- console.log();
225
- }
226
-
227
- if (customAgents.length > 0 && !options.core) {
228
- console.log('Custom agents:');
229
- for (const [role, meta] of customAgents) {
230
- console.log(` ${role} (${meta.definition.type})`);
231
- console.log(` ${meta.definition.display_name}`);
232
- }
233
- console.log();
234
- }
235
-
236
- if (overrideAgents.length > 0 && !options.core) {
237
- console.log('Override agents:');
238
- for (const [role, meta] of overrideAgents) {
239
- console.log(` ${role} (${meta.definition.type})`);
240
- console.log(` ${meta.definition.display_name} [overrides core]`);
241
- }
242
- console.log();
243
- }
244
-
245
- console.log(`Total: ${agents.length} agent(s)`);
246
- } catch (error) {
247
- console.error(`Failed to list agents: ${error instanceof Error ? error.message : error}`);
248
- process.exit(1);
249
- }
250
- });
251
-
252
- agents
253
- .command('show <name>')
254
- .description('Show details for a specific agent')
255
- .option('--markdown', 'output as compiled markdown')
256
- .option('--json', 'output as JSON')
257
- .action((name: string, options: { markdown?: boolean; json?: boolean }) => {
258
- try {
259
- const customAgentsDir = join(process.cwd(), 'coreai', 'agents');
260
-
261
- const allAgents = loadAllAgents({
262
- coreAgentsDir: getCoreAgentsPath(),
263
- customAgentsDir,
264
- });
265
-
266
- const agentMeta = allAgents.get(name);
267
-
268
- if (!agentMeta) {
269
- console.error(`Agent not found: ${name}`);
270
- console.log('\nAvailable agents:');
271
- for (const role of allAgents.keys()) {
272
- console.log(` - ${role}`);
273
- }
274
- process.exit(1);
275
- }
276
-
277
- const agent = agentMeta.definition;
278
-
279
- if (options.json) {
280
- console.log(JSON.stringify(agent, null, 2));
281
- return;
282
- }
283
-
284
- if (options.markdown) {
285
- console.log(generateAgentMarkdown(agent));
286
- return;
287
- }
288
-
289
- // Default: human-readable output
290
- console.log(`\n${agent.display_name}`);
291
- console.log('='.repeat(agent.display_name.length));
292
- console.log();
293
- console.log(`Role: ${agent.role}`);
294
- console.log(`Type: ${agent.type}`);
295
- console.log(`Source: ${agentMeta.source}`);
296
- console.log();
297
- console.log('Description:');
298
- console.log(` ${agent.description}`);
299
-
300
- if (agent.responsibilities && agent.responsibilities.length > 0) {
301
- console.log();
302
- console.log('Responsibilities:');
303
- for (const r of agent.responsibilities) {
304
- console.log(` - ${r}`);
305
- }
306
- }
307
-
308
- if (agent.expertise?.primary && agent.expertise.primary.length > 0) {
309
- console.log();
310
- console.log('Expertise:');
311
- for (const e of agent.expertise.primary) {
312
- console.log(` - ${e}`);
313
- }
314
- }
315
-
316
- if (agent.skills && agent.skills.length > 0) {
317
- console.log();
318
- console.log('Skills:');
319
- for (const s of agent.skills) {
320
- console.log(` - ${s}`);
321
- }
322
- }
323
-
324
- if (agent.behaviors?.workflow) {
325
- console.log();
326
- console.log(`Workflow: ${agent.behaviors.workflow}`);
327
- }
328
-
329
- console.log();
330
- console.log(`File: ${agentMeta.filePath}`);
331
- } catch (error) {
332
- console.error(`Failed to show agent: ${error instanceof Error ? error.message : error}`);
333
- process.exit(1);
334
- }
335
- });
336
-
337
- // Cache subcommand group
338
- const cacheCmd = program.command('cache').description('Manage local cache');
339
-
340
- cacheCmd
341
- .command('clear')
342
- .description('Clear the local cache')
343
- .option('--expired', 'only clear expired entries')
344
- .option('--json', 'output as JSON')
345
- .action(async (options: { expired?: boolean; json?: boolean }) => {
346
- try {
347
- const result = options.expired
348
- ? await cacheClearExpired({ projectRoot: process.cwd() })
349
- : await cacheClear({ projectRoot: process.cwd() });
350
-
351
- if (options.json) {
352
- console.log(JSON.stringify(result, null, 2));
353
- return;
354
- }
355
-
356
- if (!result.success) {
357
- console.error(`Failed to clear cache: ${result.error}`);
358
- process.exit(1);
359
- }
360
-
361
- if (result.cleared === 0) {
362
- console.log('Cache is already empty.');
363
- } else {
364
- const word = result.cleared === 1 ? 'entry' : 'entries';
365
- console.log(`Cleared ${result.cleared} cache ${word}.`);
366
- }
367
- } catch (error) {
368
- const msg = error instanceof Error ? error.message : error;
369
- console.error(`Failed to clear cache: ${msg}`);
370
- process.exit(1);
371
- }
372
- });
373
-
374
- cacheCmd
375
- .command('status')
376
- .description('Show cache status')
377
- .option('--json', 'output as JSON')
378
- .action(async (options: { json?: boolean }) => {
379
- try {
380
- const result = await cacheStatus({ projectRoot: process.cwd() });
381
-
382
- if (options.json) {
383
- console.log(JSON.stringify(result, null, 2));
384
- return;
385
- }
386
-
387
- console.log(formatCacheStatus(result));
388
- } catch (error) {
389
- const msg = error instanceof Error ? error.message : error;
390
- console.error(`Failed to get cache status: ${msg}`);
391
- process.exit(1);
392
- }
393
- });
394
-
395
- // Status command - show agent states and pending messages
396
- program
397
- .command('status')
398
- .description('Show agent states and pending messages')
399
- .option('-a, --agent <name>', 'show status for a specific agent')
400
- .option('-d, --detailed', 'show detailed message information')
401
- .option('--init', 'initialize KnowledgeLibrary if not exists')
402
- .option('--json', 'output as JSON')
403
- .action((options: { agent?: string; detailed?: boolean; init?: boolean; json?: boolean }) => {
404
- const result = status({
405
- projectRoot: process.cwd(),
406
- agent: options.agent,
407
- detailed: options.detailed,
408
- init: options.init,
409
- });
410
-
411
- if (options.json) {
412
- console.log(JSON.stringify(result, null, 2));
413
- return;
414
- }
415
-
416
- console.log(formatStatusResult(result));
417
-
418
- if (!result.success) {
419
- process.exit(1);
420
- }
421
- });
422
-
423
- // Skills subcommand group
424
- const skillsCmd = program.command('skills').description('Manage Claude skills');
425
-
426
- skillsCmd
427
- .command('generate')
428
- .description('Generate Claude skills from templates')
429
- .option('-o, --output <dir>', 'output directory (default: .claude/commands)')
430
- .option('--skills <skills>', 'comma-separated list of skills to generate')
431
- .option('--no-core', 'exclude core skills')
432
- .option('--no-optional', 'exclude optional skills')
433
- .option('--overwrite', 'overwrite existing skill files')
434
- .option('--json', 'output as JSON')
435
- .action(
436
- (options: {
437
- output?: string;
438
- skills?: string;
439
- core?: boolean;
440
- optional?: boolean;
441
- overwrite?: boolean;
442
- json?: boolean;
443
- }) => {
444
- console.log('Generating skills...\n');
445
-
446
- const result = skillsGenerate({
447
- projectRoot: process.cwd(),
448
- outputDir: options.output,
449
- skills: options.skills?.split(',').map((s) => s.trim()),
450
- includeCoreSkills: options.core !== false,
451
- includeOptionalSkills: options.optional !== false,
452
- overwrite: options.overwrite,
453
- });
454
-
455
- if (options.json) {
456
- console.log(JSON.stringify(result, null, 2));
457
- return;
458
- }
459
-
460
- console.log(formatSkillsGenerateResult(result));
461
-
462
- if (!result.success) {
463
- process.exit(1);
464
- }
465
- }
466
- );
467
-
468
- skillsCmd
469
- .command('list')
470
- .description('List available skills')
471
- .option('--no-core', 'exclude core skills')
472
- .option('--no-optional', 'exclude optional skills')
473
- .option('--json', 'output as JSON')
474
- .action((options: { core?: boolean; optional?: boolean; json?: boolean }) => {
475
- const result = skillsList({
476
- projectRoot: process.cwd(),
477
- includeCoreSkills: options.core !== false,
478
- includeOptionalSkills: options.optional !== false,
479
- });
480
-
481
- if (options.json) {
482
- console.log(JSON.stringify(result, null, 2));
483
- return;
484
- }
485
-
486
- console.log(formatSkillsListResult(result));
487
-
488
- if (!result.success) {
489
- process.exit(1);
490
- }
491
- });
492
-
493
- program.parse();
@@ -1,163 +0,0 @@
1
- /**
2
- * Command Context Tests
3
- */
4
-
5
- import { promises as fs } from 'fs';
6
- import { join } from 'path';
7
- import { tmpdir } from 'os';
8
- import { createCommandContext, cleanupContext, withContext } from './context.js';
9
-
10
- describe('Command Context', () => {
11
- let testDir: string;
12
-
13
- beforeEach(async () => {
14
- testDir = join(
15
- tmpdir(),
16
- `cmd-context-test-${Date.now()}-${Math.random().toString(36).slice(2)}`
17
- );
18
- await fs.mkdir(testDir, { recursive: true });
19
- });
20
-
21
- afterEach(async () => {
22
- try {
23
- await fs.rm(testDir, { recursive: true, force: true });
24
- } catch {
25
- // Ignore cleanup errors
26
- }
27
- });
28
-
29
- describe('createCommandContext', () => {
30
- it('should create context with defaults', () => {
31
- const context = createCommandContext();
32
-
33
- expect(context.projectRoot).toBe(process.cwd());
34
- expect(context.config).toBeNull();
35
- expect(context.adapterFactory).toBeNull();
36
- });
37
-
38
- it('should use provided project root', () => {
39
- const context = createCommandContext({ projectRoot: testDir });
40
-
41
- expect(context.projectRoot).toBe(testDir);
42
- });
43
-
44
- it('should use provided config', () => {
45
- const mockConfig = {
46
- version: '1.0' as const,
47
- project: { name: 'test' },
48
- };
49
-
50
- const context = createCommandContext({ config: mockConfig });
51
-
52
- expect(context.config).toBe(mockConfig);
53
- });
54
-
55
- it('should load config from project root if exists', async () => {
56
- // Create a config file
57
- const configPath = join(testDir, 'coreai.config.yaml');
58
- await fs.writeFile(configPath, 'version: "1.0"\nproject:\n name: test-project\n');
59
-
60
- const context = createCommandContext({ projectRoot: testDir });
61
-
62
- expect(context.config).not.toBeNull();
63
- expect(context.config?.project?.name).toBe('test-project');
64
- });
65
-
66
- it('should handle missing config gracefully', () => {
67
- const context = createCommandContext({ projectRoot: testDir });
68
-
69
- expect(context.config).toBeNull();
70
- });
71
- });
72
-
73
- describe('hasIntegration', () => {
74
- it('should return false when no adapter factory', () => {
75
- const context = createCommandContext();
76
-
77
- expect(context.hasIntegration('git')).toBe(false);
78
- expect(context.hasIntegration('issue_tracker')).toBe(false);
79
- });
80
-
81
- it('should check adapter factory for integrations', async () => {
82
- // Create a config with integrations
83
- const configPath = join(testDir, 'coreai.config.yaml');
84
- await fs.writeFile(
85
- configPath,
86
- `version: "1.0"
87
- project:
88
- name: test
89
- integrations:
90
- git:
91
- provider: github
92
- `
93
- );
94
-
95
- const context = createCommandContext({ projectRoot: testDir });
96
-
97
- // Note: hasIntegration checks if the integration is configured
98
- // The actual adapter creation would require registered creators
99
- expect(context.hasIntegration('git')).toBe(true);
100
- expect(context.hasIntegration('issue_tracker')).toBe(false);
101
- });
102
- });
103
-
104
- describe('getAdapterSafe', () => {
105
- it('should return null when no adapter factory', async () => {
106
- const context = createCommandContext();
107
-
108
- const adapter = await context.getAdapterSafe('git');
109
-
110
- expect(adapter).toBeNull();
111
- });
112
-
113
- it('should return null for unconfigured integrations', async () => {
114
- const configPath = join(testDir, 'coreai.config.yaml');
115
- await fs.writeFile(configPath, 'version: "1.0"\nproject:\n name: test\n');
116
-
117
- const context = createCommandContext({ projectRoot: testDir });
118
-
119
- const adapter = await context.getAdapterSafe('issue_tracker');
120
-
121
- expect(adapter).toBeNull();
122
- });
123
- });
124
-
125
- describe('cleanupContext', () => {
126
- it('should handle context without adapter factory', async () => {
127
- const context = createCommandContext();
128
-
129
- // Should not throw
130
- await expect(cleanupContext(context)).resolves.toBeUndefined();
131
- });
132
- });
133
-
134
- describe('withContext', () => {
135
- it('should create context and execute function', async () => {
136
- const result = await withContext({ projectRoot: testDir }, async (ctx) => {
137
- expect(ctx.projectRoot).toBe(testDir);
138
- return 'success';
139
- });
140
-
141
- expect(result).toBe('success');
142
- });
143
-
144
- it('should cleanup context after execution', async () => {
145
- let capturedContext: Awaited<ReturnType<typeof createCommandContext>> | null = null;
146
-
147
- await withContext({ projectRoot: testDir }, async (ctx) => {
148
- capturedContext = ctx;
149
- return true;
150
- });
151
-
152
- expect(capturedContext).not.toBeNull();
153
- });
154
-
155
- it('should cleanup context even on error', async () => {
156
- await expect(
157
- withContext({ projectRoot: testDir }, async () => {
158
- throw new Error('Test error');
159
- })
160
- ).rejects.toThrow('Test error');
161
- });
162
- });
163
- });