@indemn/cli 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/.claude-plugin/plugin.json +13 -0
  2. package/.mcp.json +9 -0
  3. package/README.md +225 -0
  4. package/dist/cli/agents.d.ts +3 -0
  5. package/dist/cli/agents.d.ts.map +1 -0
  6. package/dist/cli/agents.js +187 -0
  7. package/dist/cli/agents.js.map +1 -0
  8. package/dist/cli/auth.d.ts +3 -0
  9. package/dist/cli/auth.d.ts.map +1 -0
  10. package/dist/cli/auth.js +161 -0
  11. package/dist/cli/auth.js.map +1 -0
  12. package/dist/cli/chat.d.ts +3 -0
  13. package/dist/cli/chat.d.ts.map +1 -0
  14. package/dist/cli/chat.js +142 -0
  15. package/dist/cli/chat.js.map +1 -0
  16. package/dist/cli/config.d.ts +3 -0
  17. package/dist/cli/config.d.ts.map +1 -0
  18. package/dist/cli/config.js +119 -0
  19. package/dist/cli/config.js.map +1 -0
  20. package/dist/cli/eval.d.ts +3 -0
  21. package/dist/cli/eval.d.ts.map +1 -0
  22. package/dist/cli/eval.js +717 -0
  23. package/dist/cli/eval.js.map +1 -0
  24. package/dist/cli/functions.d.ts +3 -0
  25. package/dist/cli/functions.d.ts.map +1 -0
  26. package/dist/cli/functions.js +346 -0
  27. package/dist/cli/functions.js.map +1 -0
  28. package/dist/cli/index.d.ts +3 -0
  29. package/dist/cli/index.d.ts.map +1 -0
  30. package/dist/cli/index.js +64 -0
  31. package/dist/cli/index.js.map +1 -0
  32. package/dist/cli/kb.d.ts +3 -0
  33. package/dist/cli/kb.d.ts.map +1 -0
  34. package/dist/cli/kb.js +377 -0
  35. package/dist/cli/kb.js.map +1 -0
  36. package/dist/cli/utils/output.d.ts +6 -0
  37. package/dist/cli/utils/output.d.ts.map +1 -0
  38. package/dist/cli/utils/output.js +36 -0
  39. package/dist/cli/utils/output.js.map +1 -0
  40. package/dist/mcp/server.d.ts +2 -0
  41. package/dist/mcp/server.d.ts.map +1 -0
  42. package/dist/mcp/server.js +15 -0
  43. package/dist/mcp/server.js.map +1 -0
  44. package/dist/mcp/tools.d.ts +4 -0
  45. package/dist/mcp/tools.d.ts.map +1 -0
  46. package/dist/mcp/tools.js +814 -0
  47. package/dist/mcp/tools.js.map +1 -0
  48. package/dist/sdk/agents.d.ts +13 -0
  49. package/dist/sdk/agents.d.ts.map +1 -0
  50. package/dist/sdk/agents.js +27 -0
  51. package/dist/sdk/agents.js.map +1 -0
  52. package/dist/sdk/auth.d.ts +18 -0
  53. package/dist/sdk/auth.d.ts.map +1 -0
  54. package/dist/sdk/auth.js +98 -0
  55. package/dist/sdk/auth.js.map +1 -0
  56. package/dist/sdk/chat.d.ts +17 -0
  57. package/dist/sdk/chat.d.ts.map +1 -0
  58. package/dist/sdk/chat.js +113 -0
  59. package/dist/sdk/chat.js.map +1 -0
  60. package/dist/sdk/client.d.ts +36 -0
  61. package/dist/sdk/client.d.ts.map +1 -0
  62. package/dist/sdk/client.js +219 -0
  63. package/dist/sdk/client.js.map +1 -0
  64. package/dist/sdk/config.d.ts +11 -0
  65. package/dist/sdk/config.d.ts.map +1 -0
  66. package/dist/sdk/config.js +20 -0
  67. package/dist/sdk/config.js.map +1 -0
  68. package/dist/sdk/eval.d.ts +13 -0
  69. package/dist/sdk/eval.d.ts.map +1 -0
  70. package/dist/sdk/eval.js +36 -0
  71. package/dist/sdk/eval.js.map +1 -0
  72. package/dist/sdk/functions.d.ts +30 -0
  73. package/dist/sdk/functions.d.ts.map +1 -0
  74. package/dist/sdk/functions.js +59 -0
  75. package/dist/sdk/functions.js.map +1 -0
  76. package/dist/sdk/index.d.ts +12 -0
  77. package/dist/sdk/index.d.ts.map +1 -0
  78. package/dist/sdk/index.js +12 -0
  79. package/dist/sdk/index.js.map +1 -0
  80. package/dist/sdk/kb.d.ts +30 -0
  81. package/dist/sdk/kb.d.ts.map +1 -0
  82. package/dist/sdk/kb.js +102 -0
  83. package/dist/sdk/kb.js.map +1 -0
  84. package/dist/sdk/rubrics.d.ts +14 -0
  85. package/dist/sdk/rubrics.d.ts.map +1 -0
  86. package/dist/sdk/rubrics.js +29 -0
  87. package/dist/sdk/rubrics.js.map +1 -0
  88. package/dist/sdk/test-sets.d.ts +14 -0
  89. package/dist/sdk/test-sets.d.ts.map +1 -0
  90. package/dist/sdk/test-sets.js +29 -0
  91. package/dist/sdk/test-sets.js.map +1 -0
  92. package/dist/sdk/types.d.ts +305 -0
  93. package/dist/sdk/types.d.ts.map +1 -0
  94. package/dist/sdk/types.js +3 -0
  95. package/dist/sdk/types.js.map +1 -0
  96. package/package.json +40 -0
  97. package/skills/agent-setup/SKILL.md +131 -0
  98. package/skills/eval-orchestration/SKILL.md +257 -0
  99. package/skills/rubric-creation/SKILL.md +163 -0
  100. package/skills/test-set-creation/SKILL.md +250 -0
  101. package/src/cli/agents.ts +206 -0
  102. package/src/cli/auth.ts +170 -0
  103. package/src/cli/chat.ts +161 -0
  104. package/src/cli/config.ts +131 -0
  105. package/src/cli/eval.ts +750 -0
  106. package/src/cli/functions.ts +330 -0
  107. package/src/cli/index.ts +68 -0
  108. package/src/cli/kb.ts +412 -0
  109. package/src/cli/utils/output.ts +42 -0
  110. package/src/mcp/server.ts +17 -0
  111. package/src/mcp/tools.ts +971 -0
  112. package/src/sdk/agents.ts +47 -0
  113. package/src/sdk/auth.ts +132 -0
  114. package/src/sdk/chat.ts +133 -0
  115. package/src/sdk/client.ts +238 -0
  116. package/src/sdk/config.ts +28 -0
  117. package/src/sdk/eval.ts +57 -0
  118. package/src/sdk/functions.ts +103 -0
  119. package/src/sdk/index.ts +11 -0
  120. package/src/sdk/kb.ts +183 -0
  121. package/src/sdk/rubrics.ts +35 -0
  122. package/src/sdk/test-sets.ts +35 -0
  123. package/src/sdk/types.ts +347 -0
  124. package/test/fixtures/test-rubric.json +66 -0
  125. package/test/fixtures/test-testset.json +55 -0
  126. package/tsconfig.json +19 -0
@@ -0,0 +1,330 @@
1
+ import { Command } from 'commander';
2
+ import ora from 'ora';
3
+ import { IndemnClient } from '../sdk/client.js';
4
+ import { FunctionsSDK } from '../sdk/functions.js';
5
+ import { formatTable, printJson, printError, printSuccess, confirm } from './utils/output.js';
6
+
7
+ export function registerFunctionCommands(program: Command): void {
8
+ const functions = program.command('functions').description('Manage agent functions/tools');
9
+
10
+ functions
11
+ .command('list')
12
+ .argument('<agent-id>', 'Agent ID')
13
+ .description('List functions for an agent')
14
+ .option('--json', 'Output as JSON')
15
+ .option('--limit <n>', 'Limit number of results')
16
+ .option('--page <n>', 'Page number (use with --limit)')
17
+ .action(async (agentId: string, options) => {
18
+ try {
19
+ const client = new IndemnClient();
20
+ const sdk = new FunctionsSDK(client);
21
+ const spinner = ora('Fetching functions...').start();
22
+
23
+ let funcs = await sdk.listFunctions(agentId);
24
+ spinner.stop();
25
+
26
+ if (options.page && options.limit) {
27
+ const page = parseInt(options.page, 10);
28
+ const limit = parseInt(options.limit, 10);
29
+ funcs = funcs.slice((page - 1) * limit, page * limit);
30
+ } else if (options.limit) {
31
+ funcs = funcs.slice(0, parseInt(options.limit, 10));
32
+ }
33
+
34
+ if (options.json) {
35
+ printJson(funcs);
36
+ return;
37
+ }
38
+
39
+ if (funcs.length === 0) {
40
+ console.log('No functions found for this agent.');
41
+ return;
42
+ }
43
+
44
+ const rows = funcs.map((f) => [
45
+ f._id,
46
+ f.name || '',
47
+ f.type || '',
48
+ f.description || '',
49
+ ]);
50
+
51
+ console.log(formatTable(['ID', 'Name', 'Type', 'Description'], rows));
52
+ } catch (err) {
53
+ printError(err);
54
+ process.exit(1);
55
+ }
56
+ });
57
+
58
+ functions
59
+ .command('create')
60
+ .argument('<agent-id>', 'Agent ID')
61
+ .description('Create a function for an agent')
62
+ .requiredOption('--type <type>', 'Function type')
63
+ .option('--name <name>', 'Function name')
64
+ .option('--description <description>', 'Function description')
65
+ .action(async (agentId: string, options) => {
66
+ try {
67
+ const client = new IndemnClient();
68
+ const sdk = new FunctionsSDK(client);
69
+ const spinner = ora('Creating function...').start();
70
+
71
+ const func = await sdk.createFunction(agentId, {
72
+ type: options.type,
73
+ name: options.name,
74
+ description: options.description,
75
+ });
76
+ spinner.stop();
77
+
78
+ printSuccess(`Function created: ${func._id}`);
79
+ console.log(` Name: ${func.name || '(none)'}`);
80
+ console.log(` Type: ${func.type}`);
81
+ } catch (err) {
82
+ printError(err);
83
+ process.exit(1);
84
+ }
85
+ });
86
+
87
+ functions
88
+ .command('update')
89
+ .argument('<agent-id>', 'Agent ID')
90
+ .argument('<func-id>', 'Function ID')
91
+ .description('Update a function')
92
+ .option('--name <name>', 'Function name')
93
+ .option('--description <description>', 'Function description')
94
+ .action(async (agentId: string, funcId: string, options) => {
95
+ try {
96
+ const input: Record<string, unknown> = {};
97
+ if (options.name) input.name = options.name;
98
+ if (options.description) input.description = options.description;
99
+
100
+ if (Object.keys(input).length === 0) {
101
+ printError('No update options provided. Use --name or --description.');
102
+ process.exit(1);
103
+ }
104
+
105
+ const client = new IndemnClient();
106
+ const sdk = new FunctionsSDK(client);
107
+ const spinner = ora('Updating function...').start();
108
+
109
+ await sdk.updateFunction(agentId, funcId, input);
110
+ spinner.stop();
111
+
112
+ printSuccess(`Function ${funcId} updated.`);
113
+ } catch (err) {
114
+ printError(err);
115
+ process.exit(1);
116
+ }
117
+ });
118
+
119
+ functions
120
+ .command('delete')
121
+ .argument('<agent-id>', 'Agent ID')
122
+ .argument('<func-id>', 'Function ID')
123
+ .description('Delete a function')
124
+ .action(async (agentId: string, funcId: string) => {
125
+ try {
126
+ const confirmed = await confirm(`Delete function ${funcId}? This cannot be undone.`);
127
+ if (!confirmed) {
128
+ console.log('Cancelled.');
129
+ return;
130
+ }
131
+
132
+ const client = new IndemnClient();
133
+ const sdk = new FunctionsSDK(client);
134
+ const spinner = ora('Deleting function...').start();
135
+
136
+ await sdk.deleteFunction(agentId, funcId);
137
+ spinner.stop();
138
+
139
+ printSuccess(`Function ${funcId} deleted.`);
140
+ } catch (err) {
141
+ printError(err);
142
+ process.exit(1);
143
+ }
144
+ });
145
+
146
+ functions
147
+ .command('test')
148
+ .argument('<agent-id>', 'Agent ID')
149
+ .argument('<func-id>', 'Function ID')
150
+ .description('Test a function')
151
+ .option('--json', 'Output as JSON')
152
+ .action(async (agentId: string, funcId: string, options) => {
153
+ try {
154
+ const client = new IndemnClient();
155
+ const sdk = new FunctionsSDK(client);
156
+ const spinner = ora('Testing function...').start();
157
+
158
+ const result = await sdk.testFunction(agentId, funcId);
159
+ spinner.stop();
160
+
161
+ if (options.json) {
162
+ printJson(result);
163
+ } else {
164
+ printSuccess('Function test completed:');
165
+ printJson(result);
166
+ }
167
+ } catch (err) {
168
+ printError(err);
169
+ process.exit(1);
170
+ }
171
+ });
172
+
173
+ functions
174
+ .command('export')
175
+ .argument('<agent-id>', 'Agent ID')
176
+ .description('Export all functions for an agent')
177
+ .option('--json', 'Output as JSON')
178
+ .action(async (agentId: string, options) => {
179
+ try {
180
+ const client = new IndemnClient();
181
+ const sdk = new FunctionsSDK(client);
182
+ const spinner = ora('Exporting functions...').start();
183
+
184
+ const result = await sdk.exportFunctions(agentId);
185
+ spinner.stop();
186
+
187
+ if (options.json) {
188
+ printJson(result);
189
+ } else {
190
+ printSuccess('Functions exported:');
191
+ printJson(result);
192
+ }
193
+ } catch (err) {
194
+ printError(err);
195
+ process.exit(1);
196
+ }
197
+ });
198
+
199
+ functions
200
+ .command('import')
201
+ .argument('<agent-id>', 'Agent ID')
202
+ .description('Import functions from a URL')
203
+ .requiredOption('--url <url>', 'URL to import from')
204
+ .action(async (agentId: string, options) => {
205
+ try {
206
+ const client = new IndemnClient();
207
+ const sdk = new FunctionsSDK(client);
208
+ const spinner = ora('Importing functions...').start();
209
+
210
+ const result = await sdk.importFunctions(agentId, options.url);
211
+ spinner.stop();
212
+
213
+ printSuccess('Functions imported successfully.');
214
+ printJson(result);
215
+ } catch (err) {
216
+ printError(err);
217
+ process.exit(1);
218
+ }
219
+ });
220
+
221
+ const params = functions.command('params').description('Manage function parameters');
222
+
223
+ params
224
+ .command('list')
225
+ .argument('<agent-id>', 'Agent ID')
226
+ .argument('<func-id>', 'Function ID')
227
+ .description('List parameters for a function')
228
+ .option('--json', 'Output as JSON')
229
+ .action(async (agentId: string, funcId: string, options) => {
230
+ try {
231
+ const client = new IndemnClient();
232
+ const sdk = new FunctionsSDK(client);
233
+ const spinner = ora('Fetching parameters...').start();
234
+ const parameters = await sdk.listParameters(agentId, funcId);
235
+ spinner.stop();
236
+ if (options.json) { printJson(parameters); return; }
237
+ if (parameters.length === 0) { console.log('No parameters found.'); return; }
238
+ const rows = parameters.map((p) => [p._id || '', p.name, p.type, p.description || '', String(p.required || false)]);
239
+ console.log(formatTable(['ID', 'Name', 'Type', 'Description', 'Required'], rows));
240
+ } catch (err) { printError(err); process.exit(1); }
241
+ });
242
+
243
+ params
244
+ .command('add')
245
+ .argument('<agent-id>', 'Agent ID')
246
+ .argument('<func-id>', 'Function ID')
247
+ .description('Add a parameter to a function')
248
+ .requiredOption('--name <name>', 'Parameter name')
249
+ .requiredOption('--type <type>', 'Parameter type (e.g. string, number, boolean)')
250
+ .option('--description <desc>', 'Parameter description')
251
+ .option('--required', 'Mark as required')
252
+ .action(async (agentId: string, funcId: string, options) => {
253
+ try {
254
+ const client = new IndemnClient();
255
+ const sdk = new FunctionsSDK(client);
256
+ const spinner = ora('Adding parameter...').start();
257
+ const result = await sdk.addParameter(agentId, funcId, {
258
+ name: options.name, type: options.type,
259
+ description: options.description, required: options.required || false,
260
+ });
261
+ spinner.stop();
262
+ // Server returns array of upserted params; extract the first one
263
+ const param = Array.isArray(result) ? result[0] : result;
264
+ printSuccess(`Parameter added: ${param._id || param.name}`);
265
+ } catch (err) { printError(err); process.exit(1); }
266
+ });
267
+
268
+ params
269
+ .command('update')
270
+ .argument('<agent-id>', 'Agent ID')
271
+ .argument('<func-id>', 'Function ID')
272
+ .argument('<param-id>', 'Parameter ID')
273
+ .description('Update a function parameter')
274
+ .option('--name <name>', 'Parameter name')
275
+ .option('--type <type>', 'Parameter type')
276
+ .option('--description <desc>', 'Parameter description')
277
+ .option('--required', 'Mark as required')
278
+ .action(async (agentId: string, funcId: string, paramId: string, options) => {
279
+ try {
280
+ const input: Record<string, unknown> = {};
281
+ if (options.name) input.name = options.name;
282
+ if (options.type) input.type = options.type;
283
+ if (options.description) input.description = options.description;
284
+ if (options.required !== undefined) input.required = options.required;
285
+ if (Object.keys(input).length === 0) { printError('No options provided.'); process.exit(1); }
286
+ const client = new IndemnClient();
287
+ const sdk = new FunctionsSDK(client);
288
+ const spinner = ora('Updating parameter...').start();
289
+ await sdk.updateParameter(agentId, funcId, paramId, input);
290
+ spinner.stop();
291
+ printSuccess(`Parameter ${paramId} updated.`);
292
+ } catch (err) { printError(err); process.exit(1); }
293
+ });
294
+
295
+ params
296
+ .command('delete')
297
+ .argument('<agent-id>', 'Agent ID')
298
+ .argument('<func-id>', 'Function ID')
299
+ .argument('<param-id>', 'Parameter ID')
300
+ .description('Delete a function parameter')
301
+ .action(async (agentId: string, funcId: string, paramId: string) => {
302
+ try {
303
+ const confirmed = await confirm(`Delete parameter ${paramId}?`);
304
+ if (!confirmed) { console.log('Cancelled.'); return; }
305
+ const client = new IndemnClient();
306
+ const sdk = new FunctionsSDK(client);
307
+ const spinner = ora('Deleting parameter...').start();
308
+ await sdk.deleteParameter(agentId, funcId, paramId);
309
+ spinner.stop();
310
+ printSuccess(`Parameter ${paramId} deleted.`);
311
+ } catch (err) { printError(err); process.exit(1); }
312
+ });
313
+
314
+ // Master functions
315
+ functions
316
+ .command('master-list')
317
+ .description('List available master function templates')
318
+ .option('--json', 'Output as JSON')
319
+ .action(async (options) => {
320
+ try {
321
+ const client = new IndemnClient();
322
+ const sdk = new FunctionsSDK(client);
323
+ const spinner = ora('Fetching master functions...').start();
324
+ const result = await sdk.listMasterFunctions();
325
+ spinner.stop();
326
+ if (options.json) { printJson(result); return; }
327
+ printJson(result);
328
+ } catch (err) { printError(err); process.exit(1); }
329
+ });
330
+ }
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { registerAuthCommands } from './auth.js';
4
+ import { registerAgentCommands } from './agents.js';
5
+ import { registerConfigCommands } from './config.js';
6
+ import { registerFunctionCommands } from './functions.js';
7
+ import { registerKBCommands } from './kb.js';
8
+ import { registerEvalCommands } from './eval.js';
9
+ import { registerChatCommand } from './chat.js';
10
+
11
+ const program = new Command();
12
+
13
+ program
14
+ .name('indemn')
15
+ .description('CLI for managing Indemn AI agents')
16
+ .version('1.0.0');
17
+
18
+ program.option('--env <environment>', 'Environment (dev or production)');
19
+
20
+ // Hook to set environment before any command runs
21
+ program.hook('preAction', (thisCommand) => {
22
+ const opts = thisCommand.opts();
23
+ if (opts.env) {
24
+ process.env.INDEMN_ENV = opts.env;
25
+ }
26
+ });
27
+
28
+ // Register all command groups
29
+ registerAuthCommands(program);
30
+ registerAgentCommands(program);
31
+ registerConfigCommands(program);
32
+ registerFunctionCommands(program);
33
+ registerKBCommands(program);
34
+ registerEvalCommands(program);
35
+ registerChatCommand(program);
36
+
37
+ // MCP serve command
38
+ const mcp = program.command('mcp').description('MCP server commands');
39
+
40
+ mcp
41
+ .command('serve')
42
+ .description('Start MCP server')
43
+ .action(async () => {
44
+ const { startServer } = await import('../mcp/server.js');
45
+ await startServer();
46
+ });
47
+
48
+ // Models command
49
+ program
50
+ .command('models')
51
+ .description('List available LLM models')
52
+ .option('--json', 'Output as JSON')
53
+ .action(async (options) => {
54
+ const { IndemnClient } = await import('../sdk/client.js');
55
+ const { FunctionsSDK } = await import('../sdk/functions.js');
56
+ const ora = (await import('ora')).default;
57
+ const { printJson, printError } = await import('./utils/output.js');
58
+ try {
59
+ const client = new IndemnClient();
60
+ const sdk = new FunctionsSDK(client);
61
+ const spinner = ora('Fetching models...').start();
62
+ const models = await sdk.listLLMModels();
63
+ spinner.stop();
64
+ printJson(models);
65
+ } catch (err) { printError(err); process.exit(1); }
66
+ });
67
+
68
+ program.parse();