cli4ai 0.9.2 → 1.0.1
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.
- package/LICENSE +109 -0
- package/README.md +95 -177
- package/package.json +2 -2
- package/src/bin.ts +2 -4
- package/src/commands/add.ts +26 -14
- package/src/commands/init.ts +1 -1
- package/src/core/registry.ts +165 -0
- package/src/commands/init.test.ts +0 -211
- package/src/core/config.test.ts +0 -188
- package/src/core/link.test.ts +0 -238
- package/src/core/lockfile.test.ts +0 -337
- package/src/core/manifest.test.ts +0 -327
- package/src/core/routine-engine.test.ts +0 -139
- package/src/core/scheduler.test.ts +0 -291
- package/src/core/secrets.test.ts +0 -79
- package/src/mcp/adapter.test.ts +0 -132
- package/src/mcp/config-gen.test.ts +0 -214
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for mcp/config-gen.ts
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { describe, test, expect, beforeEach, afterEach } from 'vitest';
|
|
6
|
-
import { mkdtempSync, rmSync, writeFileSync, mkdirSync } from 'fs';
|
|
7
|
-
import { join } from 'path';
|
|
8
|
-
import { tmpdir } from 'os';
|
|
9
|
-
import {
|
|
10
|
-
generateServerConfig,
|
|
11
|
-
generateClaudeCodeConfig,
|
|
12
|
-
formatClaudeCodeConfig,
|
|
13
|
-
generateConfigSnippet
|
|
14
|
-
} from './config-gen.js';
|
|
15
|
-
import type { Manifest } from '../core/manifest.js';
|
|
16
|
-
|
|
17
|
-
describe('mcp/config-gen', () => {
|
|
18
|
-
let tempDir: string;
|
|
19
|
-
|
|
20
|
-
beforeEach(() => {
|
|
21
|
-
tempDir = mkdtempSync(join(tmpdir(), 'cli4ai-config-gen-test-'));
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
afterEach(() => {
|
|
25
|
-
rmSync(tempDir, { recursive: true, force: true });
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
describe('generateServerConfig', () => {
|
|
29
|
-
test('generates config with cli4ai start command', () => {
|
|
30
|
-
const manifest: Manifest = {
|
|
31
|
-
name: 'github',
|
|
32
|
-
version: '1.0.0',
|
|
33
|
-
entry: 'run.ts'
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
const config = generateServerConfig(manifest, '/path/to/package');
|
|
37
|
-
|
|
38
|
-
expect(config.command).toBe('cli4ai');
|
|
39
|
-
expect(config.args).toEqual(['start', 'github']);
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
test('uses package name from manifest', () => {
|
|
43
|
-
const manifest: Manifest = {
|
|
44
|
-
name: 'custom-tool',
|
|
45
|
-
version: '2.0.0',
|
|
46
|
-
entry: 'index.ts'
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
const config = generateServerConfig(manifest, '/any/path');
|
|
50
|
-
|
|
51
|
-
expect(config.args).toEqual(['start', 'custom-tool']);
|
|
52
|
-
});
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
describe('formatClaudeCodeConfig', () => {
|
|
56
|
-
test('formats empty config', () => {
|
|
57
|
-
const config = { mcpServers: {} };
|
|
58
|
-
|
|
59
|
-
const output = formatClaudeCodeConfig(config);
|
|
60
|
-
const parsed = JSON.parse(output);
|
|
61
|
-
|
|
62
|
-
expect(parsed).toEqual({ mcpServers: {} });
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
test('formats config with servers', () => {
|
|
66
|
-
const config = {
|
|
67
|
-
mcpServers: {
|
|
68
|
-
'cli4ai-github': {
|
|
69
|
-
command: 'cli4ai',
|
|
70
|
-
args: ['start', 'github']
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
const output = formatClaudeCodeConfig(config);
|
|
76
|
-
const parsed = JSON.parse(output);
|
|
77
|
-
|
|
78
|
-
expect(parsed.mcpServers['cli4ai-github'].command).toBe('cli4ai');
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
test('produces pretty-printed JSON', () => {
|
|
82
|
-
const config = { mcpServers: {} };
|
|
83
|
-
|
|
84
|
-
const output = formatClaudeCodeConfig(config);
|
|
85
|
-
|
|
86
|
-
expect(output).toContain('\n');
|
|
87
|
-
expect(output).toContain(' ');
|
|
88
|
-
});
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
describe('generateConfigSnippet', () => {
|
|
92
|
-
test('generates snippet for single package', () => {
|
|
93
|
-
const manifest: Manifest = {
|
|
94
|
-
name: 'slack',
|
|
95
|
-
version: '1.0.0',
|
|
96
|
-
entry: 'run.ts'
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
const snippet = generateConfigSnippet(manifest, '/path/to/slack');
|
|
100
|
-
|
|
101
|
-
expect(snippet).toContain('"cli4ai-slack"');
|
|
102
|
-
expect(snippet).toContain('cli4ai');
|
|
103
|
-
expect(snippet).toContain('start');
|
|
104
|
-
expect(snippet).toContain('slack');
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
test('snippet is valid JSON when wrapped', () => {
|
|
108
|
-
const manifest: Manifest = {
|
|
109
|
-
name: 'tool',
|
|
110
|
-
version: '1.0.0',
|
|
111
|
-
entry: 'run.ts'
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
const snippet = generateConfigSnippet(manifest, '/path');
|
|
115
|
-
|
|
116
|
-
// Should be valid when wrapped in braces
|
|
117
|
-
const wrapped = `{${snippet}}`;
|
|
118
|
-
const parsed = JSON.parse(wrapped);
|
|
119
|
-
|
|
120
|
-
expect(parsed['cli4ai-tool']).toBeDefined();
|
|
121
|
-
});
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
describe('generateClaudeCodeConfig', () => {
|
|
125
|
-
test('returns config with only local packages when no local packages exist', () => {
|
|
126
|
-
// Note: This may include global packages, so we just check it returns a valid config
|
|
127
|
-
const config = generateClaudeCodeConfig(tempDir);
|
|
128
|
-
|
|
129
|
-
expect(config.mcpServers).toBeDefined();
|
|
130
|
-
expect(typeof config.mcpServers).toBe('object');
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
test('includes MCP-enabled packages', () => {
|
|
134
|
-
// Create a local package directory
|
|
135
|
-
const localDir = join(tempDir, '.cli4ai', 'packages', 'test-mcp');
|
|
136
|
-
mkdirSync(localDir, { recursive: true });
|
|
137
|
-
writeFileSync(
|
|
138
|
-
join(localDir, 'cli4ai.json'),
|
|
139
|
-
JSON.stringify({
|
|
140
|
-
name: 'test-mcp',
|
|
141
|
-
version: '1.0.0',
|
|
142
|
-
entry: 'run.ts',
|
|
143
|
-
mcp: { enabled: true }
|
|
144
|
-
})
|
|
145
|
-
);
|
|
146
|
-
|
|
147
|
-
const config = generateClaudeCodeConfig(tempDir);
|
|
148
|
-
|
|
149
|
-
expect(config.mcpServers['cli4ai-test-mcp']).toBeDefined();
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
test('excludes packages without MCP enabled', () => {
|
|
153
|
-
// Create a package without MCP
|
|
154
|
-
const localDir = join(tempDir, '.cli4ai', 'packages', 'no-mcp');
|
|
155
|
-
mkdirSync(localDir, { recursive: true });
|
|
156
|
-
writeFileSync(
|
|
157
|
-
join(localDir, 'cli4ai.json'),
|
|
158
|
-
JSON.stringify({
|
|
159
|
-
name: 'no-mcp',
|
|
160
|
-
version: '1.0.0',
|
|
161
|
-
entry: 'run.ts'
|
|
162
|
-
// No mcp field
|
|
163
|
-
})
|
|
164
|
-
);
|
|
165
|
-
|
|
166
|
-
const config = generateClaudeCodeConfig(tempDir);
|
|
167
|
-
|
|
168
|
-
expect(config.mcpServers['cli4ai-no-mcp']).toBeUndefined();
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
test('excludes packages with mcp.enabled=false', () => {
|
|
172
|
-
const localDir = join(tempDir, '.cli4ai', 'packages', 'disabled-mcp');
|
|
173
|
-
mkdirSync(localDir, { recursive: true });
|
|
174
|
-
writeFileSync(
|
|
175
|
-
join(localDir, 'cli4ai.json'),
|
|
176
|
-
JSON.stringify({
|
|
177
|
-
name: 'disabled-mcp',
|
|
178
|
-
version: '1.0.0',
|
|
179
|
-
entry: 'run.ts',
|
|
180
|
-
mcp: { enabled: false }
|
|
181
|
-
})
|
|
182
|
-
);
|
|
183
|
-
|
|
184
|
-
const config = generateClaudeCodeConfig(tempDir);
|
|
185
|
-
|
|
186
|
-
expect(config.mcpServers['cli4ai-disabled-mcp']).toBeUndefined();
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
test('filters by specific packages', () => {
|
|
190
|
-
// Create multiple packages
|
|
191
|
-
for (const name of ['pkg-a', 'pkg-b', 'pkg-c']) {
|
|
192
|
-
const localDir = join(tempDir, '.cli4ai', 'packages', name);
|
|
193
|
-
mkdirSync(localDir, { recursive: true });
|
|
194
|
-
writeFileSync(
|
|
195
|
-
join(localDir, 'cli4ai.json'),
|
|
196
|
-
JSON.stringify({
|
|
197
|
-
name,
|
|
198
|
-
version: '1.0.0',
|
|
199
|
-
entry: 'run.ts',
|
|
200
|
-
mcp: { enabled: true }
|
|
201
|
-
})
|
|
202
|
-
);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
const config = generateClaudeCodeConfig(tempDir, {
|
|
206
|
-
packages: ['pkg-a', 'pkg-c']
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
expect(config.mcpServers['cli4ai-pkg-a']).toBeDefined();
|
|
210
|
-
expect(config.mcpServers['cli4ai-pkg-b']).toBeUndefined();
|
|
211
|
-
expect(config.mcpServers['cli4ai-pkg-c']).toBeDefined();
|
|
212
|
-
});
|
|
213
|
-
});
|
|
214
|
-
});
|