@indemn/cli 1.5.0 → 1.7.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 (311) hide show
  1. package/.claude-plugin/marketplace.json +3 -3
  2. package/.claude-plugin/plugin.json +9 -4
  3. package/.github/workflows/ci.yml +10 -0
  4. package/.github/workflows/publish.yml +2 -2
  5. package/.mcp.json +1 -4
  6. package/CONTRIBUTING.md +3 -1
  7. package/README.md +69 -176
  8. package/dist/cli/agents.d.ts.map +1 -1
  9. package/dist/cli/agents.js +226 -18
  10. package/dist/cli/agents.js.map +1 -1
  11. package/dist/cli/analytics.d.ts +3 -0
  12. package/dist/cli/analytics.d.ts.map +1 -0
  13. package/dist/cli/analytics.js +133 -0
  14. package/dist/cli/analytics.js.map +1 -0
  15. package/dist/cli/auth.d.ts.map +1 -1
  16. package/dist/cli/auth.js +62 -17
  17. package/dist/cli/auth.js.map +1 -1
  18. package/dist/cli/billing.d.ts +3 -0
  19. package/dist/cli/billing.d.ts.map +1 -0
  20. package/dist/cli/billing.js +23 -0
  21. package/dist/cli/billing.js.map +1 -0
  22. package/dist/cli/campaigns.d.ts +3 -0
  23. package/dist/cli/campaigns.d.ts.map +1 -0
  24. package/dist/cli/campaigns.js +34 -0
  25. package/dist/cli/campaigns.js.map +1 -0
  26. package/dist/cli/chat.d.ts.map +1 -1
  27. package/dist/cli/chat.js +69 -102
  28. package/dist/cli/chat.js.map +1 -1
  29. package/dist/cli/config.d.ts.map +1 -1
  30. package/dist/cli/config.js +71 -27
  31. package/dist/cli/config.js.map +1 -1
  32. package/dist/cli/conversations.d.ts +3 -0
  33. package/dist/cli/conversations.d.ts.map +1 -0
  34. package/dist/cli/conversations.js +129 -0
  35. package/dist/cli/conversations.js.map +1 -0
  36. package/dist/cli/distribution.d.ts +3 -0
  37. package/dist/cli/distribution.d.ts.map +1 -0
  38. package/dist/cli/distribution.js +122 -0
  39. package/dist/cli/distribution.js.map +1 -0
  40. package/dist/cli/eval.d.ts.map +1 -1
  41. package/dist/cli/eval.js +315 -71
  42. package/dist/cli/eval.js.map +1 -1
  43. package/dist/cli/functions.d.ts.map +1 -1
  44. package/dist/cli/functions.js +125 -35
  45. package/dist/cli/functions.js.map +1 -1
  46. package/dist/cli/index.js +63 -54
  47. package/dist/cli/index.js.map +1 -1
  48. package/dist/cli/init.d.ts +27 -0
  49. package/dist/cli/init.d.ts.map +1 -0
  50. package/dist/cli/init.js +152 -0
  51. package/dist/cli/init.js.map +1 -0
  52. package/dist/cli/kb.d.ts.map +1 -1
  53. package/dist/cli/kb.js +141 -15
  54. package/dist/cli/kb.js.map +1 -1
  55. package/dist/cli/link.d.ts +21 -0
  56. package/dist/cli/link.d.ts.map +1 -0
  57. package/dist/cli/link.js +112 -0
  58. package/dist/cli/link.js.map +1 -0
  59. package/dist/cli/org.d.ts.map +1 -1
  60. package/dist/cli/org.js +79 -67
  61. package/dist/cli/org.js.map +1 -1
  62. package/dist/cli/platform.d.ts +3 -0
  63. package/dist/cli/platform.d.ts.map +1 -0
  64. package/dist/cli/platform.js +133 -0
  65. package/dist/cli/platform.js.map +1 -0
  66. package/dist/cli/tickets.d.ts +3 -0
  67. package/dist/cli/tickets.d.ts.map +1 -0
  68. package/dist/cli/tickets.js +125 -0
  69. package/dist/cli/tickets.js.map +1 -0
  70. package/dist/cli/utils/output.d.ts +15 -9
  71. package/dist/cli/utils/output.d.ts.map +1 -1
  72. package/dist/cli/utils/output.js +53 -46
  73. package/dist/cli/utils/output.js.map +1 -1
  74. package/dist/cli/voice.d.ts +3 -0
  75. package/dist/cli/voice.d.ts.map +1 -0
  76. package/dist/cli/voice.js +206 -0
  77. package/dist/cli/voice.js.map +1 -0
  78. package/dist/core/diff.d.ts +16 -0
  79. package/dist/core/diff.d.ts.map +1 -0
  80. package/dist/core/diff.js +57 -0
  81. package/dist/core/diff.js.map +1 -0
  82. package/dist/core/org-resolver.d.ts +37 -0
  83. package/dist/core/org-resolver.d.ts.map +1 -0
  84. package/dist/core/org-resolver.js +73 -0
  85. package/dist/core/org-resolver.js.map +1 -0
  86. package/dist/core/runtime.d.ts +36 -0
  87. package/dist/core/runtime.d.ts.map +1 -0
  88. package/dist/core/runtime.js +62 -0
  89. package/dist/core/runtime.js.map +1 -0
  90. package/dist/core/scope.d.ts +33 -0
  91. package/dist/core/scope.d.ts.map +1 -0
  92. package/dist/core/scope.js +37 -0
  93. package/dist/core/scope.js.map +1 -0
  94. package/dist/mcp/registry.d.ts +67 -0
  95. package/dist/mcp/registry.d.ts.map +1 -0
  96. package/dist/mcp/registry.js +195 -0
  97. package/dist/mcp/registry.js.map +1 -0
  98. package/dist/mcp/server.d.ts +9 -0
  99. package/dist/mcp/server.d.ts.map +1 -1
  100. package/dist/mcp/server.js +87 -2
  101. package/dist/mcp/server.js.map +1 -1
  102. package/dist/mcp/tool-meta.d.ts +21 -0
  103. package/dist/mcp/tool-meta.d.ts.map +1 -0
  104. package/dist/mcp/tool-meta.js +203 -0
  105. package/dist/mcp/tool-meta.js.map +1 -0
  106. package/dist/mcp/tools.d.ts +2 -1
  107. package/dist/mcp/tools.d.ts.map +1 -1
  108. package/dist/mcp/tools.js +1462 -215
  109. package/dist/mcp/tools.js.map +1 -1
  110. package/dist/sdk/agent-bundle.d.ts +99 -0
  111. package/dist/sdk/agent-bundle.d.ts.map +1 -0
  112. package/dist/sdk/agent-bundle.js +211 -0
  113. package/dist/sdk/agent-bundle.js.map +1 -0
  114. package/dist/sdk/agents.d.ts +54 -1
  115. package/dist/sdk/agents.d.ts.map +1 -1
  116. package/dist/sdk/agents.js +59 -5
  117. package/dist/sdk/agents.js.map +1 -1
  118. package/dist/sdk/analytics.d.ts +158 -0
  119. package/dist/sdk/analytics.d.ts.map +1 -0
  120. package/dist/sdk/analytics.js +185 -0
  121. package/dist/sdk/analytics.js.map +1 -0
  122. package/dist/sdk/auth.d.ts +34 -12
  123. package/dist/sdk/auth.d.ts.map +1 -1
  124. package/dist/sdk/auth.js +60 -77
  125. package/dist/sdk/auth.js.map +1 -1
  126. package/dist/sdk/billing.d.ts +25 -0
  127. package/dist/sdk/billing.d.ts.map +1 -0
  128. package/dist/sdk/billing.js +61 -0
  129. package/dist/sdk/billing.js.map +1 -0
  130. package/dist/sdk/campaigns.d.ts +35 -0
  131. package/dist/sdk/campaigns.d.ts.map +1 -0
  132. package/dist/sdk/campaigns.js +59 -0
  133. package/dist/sdk/campaigns.js.map +1 -0
  134. package/dist/sdk/chat.d.ts +25 -2
  135. package/dist/sdk/chat.d.ts.map +1 -1
  136. package/dist/sdk/chat.js +37 -10
  137. package/dist/sdk/chat.js.map +1 -1
  138. package/dist/sdk/client.d.ts +93 -5
  139. package/dist/sdk/client.d.ts.map +1 -1
  140. package/dist/sdk/client.js +362 -100
  141. package/dist/sdk/client.js.map +1 -1
  142. package/dist/sdk/config-change.d.ts +74 -0
  143. package/dist/sdk/config-change.d.ts.map +1 -0
  144. package/dist/sdk/config-change.js +117 -0
  145. package/dist/sdk/config-change.js.map +1 -0
  146. package/dist/sdk/config.d.ts.map +1 -1
  147. package/dist/sdk/config.js +2 -1
  148. package/dist/sdk/config.js.map +1 -1
  149. package/dist/sdk/conversations.d.ts +101 -0
  150. package/dist/sdk/conversations.d.ts.map +1 -0
  151. package/dist/sdk/conversations.js +155 -0
  152. package/dist/sdk/conversations.js.map +1 -0
  153. package/dist/sdk/credentials.d.ts +25 -0
  154. package/dist/sdk/credentials.d.ts.map +1 -0
  155. package/dist/sdk/credentials.js +44 -0
  156. package/dist/sdk/credentials.js.map +1 -0
  157. package/dist/sdk/distribution.d.ts +94 -0
  158. package/dist/sdk/distribution.d.ts.map +1 -0
  159. package/dist/sdk/distribution.js +100 -0
  160. package/dist/sdk/distribution.js.map +1 -0
  161. package/dist/sdk/eval.d.ts +81 -0
  162. package/dist/sdk/eval.d.ts.map +1 -1
  163. package/dist/sdk/eval.js +117 -0
  164. package/dist/sdk/eval.js.map +1 -1
  165. package/dist/sdk/functions.d.ts +14 -1
  166. package/dist/sdk/functions.d.ts.map +1 -1
  167. package/dist/sdk/functions.js +48 -5
  168. package/dist/sdk/functions.js.map +1 -1
  169. package/dist/sdk/index.d.ts +2 -0
  170. package/dist/sdk/index.d.ts.map +1 -1
  171. package/dist/sdk/index.js +2 -0
  172. package/dist/sdk/index.js.map +1 -1
  173. package/dist/sdk/jarvis-chat.d.ts +28 -0
  174. package/dist/sdk/jarvis-chat.d.ts.map +1 -0
  175. package/dist/sdk/jarvis-chat.js +117 -0
  176. package/dist/sdk/jarvis-chat.js.map +1 -0
  177. package/dist/sdk/kb.d.ts +69 -1
  178. package/dist/sdk/kb.d.ts.map +1 -1
  179. package/dist/sdk/kb.js +111 -24
  180. package/dist/sdk/kb.js.map +1 -1
  181. package/dist/sdk/orgs.d.ts +13 -0
  182. package/dist/sdk/orgs.d.ts.map +1 -0
  183. package/dist/sdk/orgs.js +59 -0
  184. package/dist/sdk/orgs.js.map +1 -0
  185. package/dist/sdk/platform.d.ts +62 -0
  186. package/dist/sdk/platform.d.ts.map +1 -0
  187. package/dist/sdk/platform.js +95 -0
  188. package/dist/sdk/platform.js.map +1 -0
  189. package/dist/sdk/session.d.ts +25 -0
  190. package/dist/sdk/session.d.ts.map +1 -0
  191. package/dist/sdk/session.js +69 -0
  192. package/dist/sdk/session.js.map +1 -0
  193. package/dist/sdk/skills.d.ts +46 -0
  194. package/dist/sdk/skills.d.ts.map +1 -0
  195. package/dist/sdk/skills.js +203 -0
  196. package/dist/sdk/skills.js.map +1 -0
  197. package/dist/sdk/test-chat.d.ts +52 -0
  198. package/dist/sdk/test-chat.d.ts.map +1 -0
  199. package/dist/sdk/test-chat.js +134 -0
  200. package/dist/sdk/test-chat.js.map +1 -0
  201. package/dist/sdk/tickets.d.ts +98 -0
  202. package/dist/sdk/tickets.d.ts.map +1 -0
  203. package/dist/sdk/tickets.js +91 -0
  204. package/dist/sdk/tickets.js.map +1 -0
  205. package/dist/sdk/types.d.ts +91 -6
  206. package/dist/sdk/types.d.ts.map +1 -1
  207. package/dist/sdk/voice.d.ts +147 -0
  208. package/dist/sdk/voice.d.ts.map +1 -0
  209. package/dist/sdk/voice.js +236 -0
  210. package/dist/sdk/voice.js.map +1 -0
  211. package/package.json +22 -3
  212. package/scripts/check-skills.mjs +25 -0
  213. package/skills/agent-builder/SKILL.md +89 -252
  214. package/skills/evaluations/SKILL.md +23 -234
  215. package/skills/evaluations/references/analysis.md +95 -0
  216. package/skills/evaluations/references/cli-reference.md +28 -0
  217. package/skills/evaluations/references/json-formats.md +100 -0
  218. package/src/cli/agents.ts +202 -22
  219. package/src/cli/analytics.ts +138 -0
  220. package/src/cli/auth.ts +56 -18
  221. package/src/cli/billing.ts +25 -0
  222. package/src/cli/campaigns.ts +33 -0
  223. package/src/cli/chat.ts +66 -115
  224. package/src/cli/config.ts +65 -31
  225. package/src/cli/conversations.ts +133 -0
  226. package/src/cli/distribution.ts +116 -0
  227. package/src/cli/eval.ts +254 -70
  228. package/src/cli/functions.ts +122 -36
  229. package/src/cli/index.ts +58 -55
  230. package/src/cli/init.ts +154 -0
  231. package/src/cli/kb.ts +120 -17
  232. package/src/cli/link.ts +117 -0
  233. package/src/cli/org.ts +81 -75
  234. package/src/cli/platform.ts +128 -0
  235. package/src/cli/tickets.ts +130 -0
  236. package/src/cli/utils/output.ts +51 -42
  237. package/src/cli/voice.ts +204 -0
  238. package/src/core/diff.ts +52 -0
  239. package/src/core/org-resolver.ts +113 -0
  240. package/src/core/runtime.ts +73 -0
  241. package/src/core/scope.ts +64 -0
  242. package/src/mcp/registry.ts +236 -0
  243. package/src/mcp/server.ts +84 -2
  244. package/src/mcp/tool-meta.ts +241 -0
  245. package/src/mcp/tools.ts +1529 -265
  246. package/src/sdk/agent-bundle.ts +245 -0
  247. package/src/sdk/agents.ts +74 -5
  248. package/src/sdk/analytics.ts +220 -0
  249. package/src/sdk/auth.ts +87 -107
  250. package/src/sdk/billing.ts +59 -0
  251. package/src/sdk/campaigns.ts +60 -0
  252. package/src/sdk/chat.ts +44 -10
  253. package/src/sdk/client.ts +373 -102
  254. package/src/sdk/config-change.ts +148 -0
  255. package/src/sdk/config.ts +2 -1
  256. package/src/sdk/conversations.ts +199 -0
  257. package/src/sdk/credentials.ts +53 -0
  258. package/src/sdk/distribution.ts +132 -0
  259. package/src/sdk/eval.ts +140 -0
  260. package/src/sdk/functions.ts +52 -6
  261. package/src/sdk/index.ts +2 -0
  262. package/src/sdk/jarvis-chat.ts +112 -0
  263. package/src/sdk/kb.ts +116 -29
  264. package/src/sdk/orgs.ts +62 -0
  265. package/src/sdk/platform.ts +115 -0
  266. package/src/sdk/session.ts +90 -0
  267. package/src/sdk/skills.ts +188 -0
  268. package/src/sdk/test-chat.ts +151 -0
  269. package/src/sdk/tickets.ts +120 -0
  270. package/src/sdk/types.ts +88 -6
  271. package/src/sdk/voice.ts +262 -0
  272. package/test/cli/entry.test.ts +34 -0
  273. package/test/cli/init.test.ts +66 -0
  274. package/test/cli/link.test.ts +57 -0
  275. package/test/core/org-resolver.test.ts +92 -0
  276. package/test/core/runtime.test.ts +30 -0
  277. package/test/core/scope.test.ts +93 -0
  278. package/test/harness.test.ts +24 -0
  279. package/test/helpers/config-home.ts +22 -0
  280. package/test/helpers/fake-middleware.ts +56 -0
  281. package/test/helpers/fetch-recorder.ts +75 -0
  282. package/test/helpers/jwt.ts +9 -0
  283. package/test/helpers/mcp-pair.ts +38 -0
  284. package/test/mcp/__snapshots__/tools-snapshot.test.ts.snap +145 -0
  285. package/test/mcp/askers.test.ts +60 -0
  286. package/test/mcp/elicit-timeout.test.ts +29 -0
  287. package/test/mcp/registry.test.ts +169 -0
  288. package/test/mcp/shaping.test.ts +41 -0
  289. package/test/mcp/tools-snapshot.test.ts +42 -0
  290. package/test/sdk/agents.test.ts +232 -0
  291. package/test/sdk/analytics.test.ts +89 -0
  292. package/test/sdk/auth.test.ts +70 -0
  293. package/test/sdk/billing.test.ts +47 -0
  294. package/test/sdk/campaigns.test.ts +43 -0
  295. package/test/sdk/client.test.ts +80 -0
  296. package/test/sdk/config-change.test.ts +142 -0
  297. package/test/sdk/conversations.test.ts +80 -0
  298. package/test/sdk/credentials.test.ts +33 -0
  299. package/test/sdk/distribution.test.ts +55 -0
  300. package/test/sdk/eval.test.ts +155 -0
  301. package/test/sdk/kb-upload.test.ts +50 -0
  302. package/test/sdk/kb.test.ts +95 -0
  303. package/test/sdk/orgs.test.ts +48 -0
  304. package/test/sdk/platform.test.ts +89 -0
  305. package/test/sdk/renewal.test.ts +115 -0
  306. package/test/sdk/session.test.ts +60 -0
  307. package/test/sdk/skills.test.ts +235 -0
  308. package/test/sdk/test-chat.test.ts +112 -0
  309. package/test/sdk/tickets.test.ts +42 -0
  310. package/test/sdk/voice.test.ts +147 -0
  311. package/vitest.config.ts +11 -0
package/dist/cli/index.js CHANGED
@@ -1,8 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
  import { Command } from 'commander';
3
- import { fileURLToPath } from 'node:url';
4
- import { dirname, join, resolve } from 'node:path';
5
- import { cpSync, mkdirSync, writeFileSync, existsSync } from 'node:fs';
6
3
  import { registerAuthCommands } from './auth.js';
7
4
  import { registerAgentCommands } from './agents.js';
8
5
  import { registerConfigCommands } from './config.js';
@@ -11,13 +8,26 @@ import { registerKBCommands } from './kb.js';
11
8
  import { registerEvalCommands } from './eval.js';
12
9
  import { registerChatCommand } from './chat.js';
13
10
  import { registerOrgCommands } from './org.js';
14
- import { printBanner } from './utils/output.js';
11
+ import { registerLinkCommands } from './link.js';
12
+ import { registerConversationCommands } from './conversations.js';
13
+ import { registerVoiceCommands } from './voice.js';
14
+ import { registerDistributionCommands } from './distribution.js';
15
+ import { registerAnalyticsCommands } from './analytics.js';
16
+ import { registerTicketCommands } from './tickets.js';
17
+ import { registerBillingCommands } from './billing.js';
18
+ import { registerCampaignCommands } from './campaigns.js';
19
+ import { registerPlatformCommands } from './platform.js';
20
+ import { registerInitCommand } from './init.js';
21
+ import { askMfaInTerminal, askOrgInTerminal, installBanner } from './utils/output.js';
22
+ import { setAskers, setOrgFlag } from '../core/scope.js';
23
+ import { cliVersion, isNonInteractive } from '../core/runtime.js';
15
24
  const program = new Command();
16
25
  program
17
26
  .name('indemn')
18
27
  .description('CLI for managing Indemn AI agents')
19
- .version('1.5.0');
20
- program.option('--env <environment>', 'Environment (dev or production)');
28
+ .version(cliVersion());
29
+ program.option('--debug', 'Print every request and response status to stderr');
30
+ program.option('--org <id>', 'Organization to act on (otherwise: linked folder, your only org, or you are asked)');
21
31
  program.option('--no-banner', 'Suppress the active-org banner');
22
32
  // Commands that already surface org identity themselves — no banner needed.
23
33
  const BANNER_SKIP = new Set([
@@ -26,7 +36,10 @@ const BANNER_SKIP = new Set([
26
36
  'whoami',
27
37
  'init',
28
38
  'org list',
39
+ 'org current',
29
40
  'org switch',
41
+ 'link',
42
+ 'unlink',
30
43
  'mcp serve',
31
44
  ]);
32
45
  function fullCommandName(cmd) {
@@ -41,8 +54,14 @@ function fullCommandName(cmd) {
41
54
  // Hook runs before any command action
42
55
  program.hook('preAction', async (thisCommand, actionCommand) => {
43
56
  const globalOpts = thisCommand.opts();
44
- if (globalOpts.env) {
45
- process.env.INDEMN_ENV = globalOpts.env;
57
+ // The environment is fixed by `indemn login --env`; there is no per-command switch.
58
+ if (globalOpts.debug) {
59
+ process.env.INDEMN_DEBUG = '1';
60
+ }
61
+ setOrgFlag(globalOpts.org);
62
+ // Ask in the terminal only when a person can answer; agents and CI get exit code 2 instead.
63
+ if (fullCommandName(actionCommand) !== 'mcp serve' && !isNonInteractive()) {
64
+ setAskers({ chooseOrg: askOrgInTerminal, mfaCode: askMfaInTerminal });
46
65
  }
47
66
  // Banner suppression: global flag, env var, command opts-out, or JSON output mode.
48
67
  if (globalOpts.banner === false)
@@ -54,17 +73,50 @@ program.hook('preAction', async (thisCommand, actionCommand) => {
54
73
  return;
55
74
  if (BANNER_SKIP.has(fullCommandName(actionCommand)))
56
75
  return;
57
- await printBanner();
76
+ installBanner();
58
77
  });
59
78
  // Register all command groups
60
79
  registerAuthCommands(program);
80
+ // Groups other modules extend (org, agents) are registered first.
81
+ registerOrgCommands(program);
82
+ registerLinkCommands(program);
61
83
  registerAgentCommands(program);
62
84
  registerConfigCommands(program);
63
85
  registerFunctionCommands(program);
64
86
  registerKBCommands(program);
65
87
  registerEvalCommands(program);
66
88
  registerChatCommand(program);
67
- registerOrgCommands(program);
89
+ registerConversationCommands(program);
90
+ registerVoiceCommands(program);
91
+ registerDistributionCommands(program);
92
+ registerAnalyticsCommands(program);
93
+ registerTicketCommands(program);
94
+ registerBillingCommands(program);
95
+ registerCampaignCommands(program);
96
+ registerPlatformCommands(program);
97
+ program
98
+ .command('channels')
99
+ .description('Channels an agent can be published on')
100
+ .command('list')
101
+ .description('List channels')
102
+ .option('--json', 'Output as JSON')
103
+ .action(async (options) => {
104
+ const { IndemnClient } = await import('../sdk/client.js');
105
+ const { OrgsSDK } = await import('../sdk/orgs.js');
106
+ const { formatTable, printJson, printError } = await import('./utils/output.js');
107
+ try {
108
+ const channels = await new OrgsSDK(new IndemnClient()).listChannels();
109
+ if (options.json) {
110
+ printJson(channels);
111
+ return;
112
+ }
113
+ console.log(formatTable(['ID', 'Name', 'Type', 'Description'], channels.map((c) => [c._id, c.name, c.type ?? '', c.description ?? ''])));
114
+ }
115
+ catch (err) {
116
+ printError(err);
117
+ process.exit(1);
118
+ }
119
+ });
68
120
  // MCP serve command
69
121
  const mcp = program.command('mcp').description('MCP server commands');
70
122
  mcp
@@ -97,49 +149,6 @@ program
97
149
  process.exit(1);
98
150
  }
99
151
  });
100
- // Init command — set up Claude Code integration
101
- program
102
- .command('init')
103
- .description('Set up Claude Code skills in the current project')
104
- .option('--force', 'Overwrite existing files')
105
- .action(async (options) => {
106
- const __filename = fileURLToPath(import.meta.url);
107
- const __dirname = dirname(__filename);
108
- const packageRoot = resolve(__dirname, '..', '..');
109
- const skillsSource = join(packageRoot, 'skills');
110
- const cwd = process.cwd();
111
- const skillsTarget = join(cwd, '.claude', 'skills', 'indemn');
112
- const rulesTarget = join(cwd, '.claude', 'rules');
113
- if (existsSync(skillsTarget) && !options.force) {
114
- console.log('Indemn skills already installed. Use --force to overwrite.');
115
- return;
116
- }
117
- // Copy skills
118
- mkdirSync(skillsTarget, { recursive: true });
119
- cpSync(skillsSource, skillsTarget, { recursive: true });
120
- // Write rules file
121
- mkdirSync(rulesTarget, { recursive: true });
122
- const rulesPath = join(rulesTarget, 'indemn.md');
123
- if (!existsSync(rulesPath) || options.force) {
124
- writeFileSync(rulesPath, [
125
- '# Indemn CLI',
126
- '',
127
- 'The `indemn` CLI is available for managing AI agents. Run `indemn whoami` to verify authentication.',
128
- '',
129
- '## Skills',
130
- '',
131
- '- **agent-builder** — Create, configure, and test agents (prompts, functions, knowledge bases, chat)',
132
- '- **evaluations** — Create rubrics and test sets, run evaluations, analyze results, export reports',
133
- '',
134
- 'Use these skills for any agent management or evaluation task. They contain the complete command reference.',
135
- '',
136
- ].join('\n'));
137
- }
138
- console.log('Indemn CLI integration set up:');
139
- console.log(` Skills: ${skillsTarget}/`);
140
- console.log(` Rules: ${rulesPath}`);
141
- console.log('');
142
- console.log('Claude Code will now discover the indemn skills automatically.');
143
- });
152
+ registerInitCommand(program);
144
153
  program.parse();
145
154
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { Command } from 'commander';
2
+ export declare const MCP_SERVER_ENTRY: {
3
+ command: string;
4
+ args: string[];
5
+ };
6
+ /** Claude Code permission rules: read-only tools run without asking, anything that changes the platform asks every time. */
7
+ export declare function permissionBlock(): {
8
+ allow: string[];
9
+ ask: string[];
10
+ };
11
+ export interface InitReport {
12
+ skills: string;
13
+ rules: string;
14
+ mcp: 'added' | 'kept' | 'skipped';
15
+ permissions: 'added' | 'merged' | 'skipped';
16
+ }
17
+ /** Set up Claude Code in `cwd`. Existing files are merged, never overwritten, unless force is set for skills and rules. */
18
+ export declare function initProject(cwd: string, opts?: {
19
+ force?: boolean;
20
+ mcp?: boolean;
21
+ permissions?: boolean;
22
+ packageRoot?: string;
23
+ }): InitReport;
24
+ /** What is set up in `cwd`, for `indemn init --status`. */
25
+ export declare function initStatus(cwd: string): Array<[string, boolean, string]>;
26
+ export declare function registerInitCommand(program: Command): void;
27
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,eAAO,MAAM,gBAAgB;;;CAAkE,CAAC;AAEhG,4HAA4H;AAC5H,wBAAgB,eAAe,IAAI;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,GAAG,EAAE,MAAM,EAAE,CAAA;CAAE,CASpE;AA0BD,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;IAClC,WAAW,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;CAC7C;AAED,2HAA2H;AAC3H,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,UAAU,CAiD/I;AAED,2DAA2D;AAC3D,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAcxE;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA6B1D"}
@@ -0,0 +1,152 @@
1
+ import chalk from 'chalk';
2
+ import { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';
3
+ import { dirname, join, resolve } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { TOOL_META } from '../mcp/tool-meta.js';
6
+ import { IndemnClient } from '../sdk/client.js';
7
+ import { findLinkFile } from '../core/org-resolver.js';
8
+ import { printError, printSuccess } from './utils/output.js';
9
+ export const MCP_SERVER_ENTRY = { command: 'npx', args: ['-y', '@indemn/cli', 'mcp', 'serve'] };
10
+ /** Claude Code permission rules: read-only tools run without asking, anything that changes the platform asks every time. */
11
+ export function permissionBlock() {
12
+ const allow = [];
13
+ const ask = [];
14
+ for (const [name, meta] of Object.entries(TOOL_META)) {
15
+ const rule = `mcp__indemn__${name}`;
16
+ if (meta.annotations.readOnlyHint && !meta.guard)
17
+ allow.push(rule);
18
+ else
19
+ ask.push(rule);
20
+ }
21
+ return { allow: allow.sort(), ask: ask.sort() };
22
+ }
23
+ function readJson(path) {
24
+ if (!existsSync(path))
25
+ return {};
26
+ try {
27
+ return JSON.parse(readFileSync(path, 'utf8'));
28
+ }
29
+ catch {
30
+ throw new Error(`${path} is not valid JSON; fix it or move it away, then run init again.`);
31
+ }
32
+ }
33
+ const RULES = `# Indemn CLI
34
+
35
+ The \`indemn\` CLI and its MCP server manage Indemn AI agents. Run \`indemn whoami\` to see the platform (dev or production), the user and which org commands here act on.
36
+
37
+ - Every chat with an agent is a test conversation: never billed, never in analytics, shown with the tester's name.
38
+ - Actions that change or delete something are approved by the user first. When an approval form appears, that form is the question: call the tool and do not ask again in chat. When a tool returns a dry_run instead, show it and pass confirm: true only after the user agreed to that exact change.
39
+ - If a tool returns needs_input (for example which org), ask the user and call again with their answer.
40
+ - Talk in names: call agents, knowledge bases, test sets and runs by their names; show ids only when asked or to tell two items apart. Plain words, short answers, details on request.
41
+
42
+ ## Skills
43
+
44
+ - **agent-builder**: create, configure and test agents (prompt, skills, knowledge bases, voice, chat).
45
+ - **evaluations**: rubrics, test sets, runs, CI gates, reports.
46
+ `;
47
+ /** Set up Claude Code in `cwd`. Existing files are merged, never overwritten, unless force is set for skills and rules. */
48
+ export function initProject(cwd, opts = {}) {
49
+ const packageRoot = opts.packageRoot ?? resolve(dirname(fileURLToPath(import.meta.url)), '..', '..');
50
+ // Claude Code finds project skills at .claude/skills/<name>/SKILL.md, one folder per skill.
51
+ const skillsTarget = join(cwd, '.claude', 'skills');
52
+ for (const skill of readdirSync(join(packageRoot, 'skills'), { withFileTypes: true }).filter((d) => d.isDirectory())) {
53
+ const target = join(skillsTarget, skill.name);
54
+ if (!existsSync(target) || opts.force) {
55
+ mkdirSync(target, { recursive: true });
56
+ cpSync(join(packageRoot, 'skills', skill.name), target, { recursive: true });
57
+ }
58
+ }
59
+ const rulesPath = join(cwd, '.claude', 'rules', 'indemn.md');
60
+ if (!existsSync(rulesPath) || opts.force) {
61
+ mkdirSync(dirname(rulesPath), { recursive: true });
62
+ writeFileSync(rulesPath, RULES);
63
+ }
64
+ let mcp = 'skipped';
65
+ if (opts.mcp !== false) {
66
+ const path = join(cwd, '.mcp.json');
67
+ const cfg = readJson(path);
68
+ cfg.mcpServers = cfg.mcpServers ?? {};
69
+ if (cfg.mcpServers.indemn) {
70
+ mcp = 'kept';
71
+ }
72
+ else {
73
+ cfg.mcpServers.indemn = MCP_SERVER_ENTRY;
74
+ writeFileSync(path, JSON.stringify(cfg, null, 2) + '\n');
75
+ mcp = 'added';
76
+ }
77
+ }
78
+ let permissions = 'skipped';
79
+ if (opts.permissions !== false) {
80
+ const path = join(cwd, '.claude', 'settings.json');
81
+ const cfg = readJson(path);
82
+ const had = Boolean(cfg.permissions);
83
+ cfg.permissions = cfg.permissions ?? {};
84
+ const block = permissionBlock();
85
+ const denied = new Set(cfg.permissions.deny ?? []);
86
+ const askSet = new Set([...(cfg.permissions.ask ?? []), ...block.ask]);
87
+ // A tool the user already restricted is never loosened.
88
+ const allowSet = new Set([...(cfg.permissions.allow ?? []), ...block.allow.filter((r) => !askSet.has(r) && !denied.has(r))]);
89
+ cfg.permissions.allow = [...allowSet].sort();
90
+ cfg.permissions.ask = [...askSet].filter((r) => !denied.has(r)).sort();
91
+ mkdirSync(dirname(path), { recursive: true });
92
+ writeFileSync(path, JSON.stringify(cfg, null, 2) + '\n');
93
+ permissions = had ? 'merged' : 'added';
94
+ }
95
+ return { skills: skillsTarget, rules: rulesPath, mcp, permissions };
96
+ }
97
+ /** What is set up in `cwd`, for `indemn init --status`. */
98
+ export function initStatus(cwd) {
99
+ const mcp = readJson(join(cwd, '.mcp.json'));
100
+ const settings = readJson(join(cwd, '.claude', 'settings.json'));
101
+ const login = IndemnClient.loadConfig();
102
+ let link = null;
103
+ try {
104
+ link = findLinkFile(cwd)?.path ?? null;
105
+ }
106
+ catch {
107
+ link = null;
108
+ }
109
+ return [
110
+ ['Skills', existsSync(join(cwd, '.claude', 'skills', 'agent-builder', 'SKILL.md')), '.claude/skills/agent-builder, evaluations'],
111
+ ['Rules', existsSync(join(cwd, '.claude', 'rules', 'indemn.md')), '.claude/rules/indemn.md'],
112
+ ['MCP server', Boolean(mcp.mcpServers?.indemn), '.mcp.json'],
113
+ ['Permissions', (settings.permissions?.ask ?? []).some((r) => r.startsWith('mcp__indemn__')), '.claude/settings.json'],
114
+ ['Logged in', Boolean(login), login ? `${login.email ?? login.user_id} on ${login.environment}` : 'run `indemn login`'],
115
+ ['Folder linked', Boolean(link), link ?? 'optional: `indemn link --org <id>`'],
116
+ ];
117
+ }
118
+ export function registerInitCommand(program) {
119
+ program
120
+ .command('init')
121
+ .description('Set up Claude Code here: skills, rules, the MCP server in .mcp.json, and permissions (reads allowed, changes ask)')
122
+ .option('--force', 'Overwrite the installed skills and rules')
123
+ .option('--no-mcp', 'Do not add the MCP server to .mcp.json')
124
+ .option('--no-permissions', 'Do not add permission rules to .claude/settings.json')
125
+ .option('--status', 'Show what is set up and stop')
126
+ .action((options) => {
127
+ try {
128
+ const cwd = process.cwd();
129
+ if (options.status) {
130
+ for (const [what, ok, detail] of initStatus(cwd))
131
+ console.log(`${ok ? chalk.green('✓') : chalk.yellow('·')} ${what.padEnd(14)} ${chalk.dim(detail)}`);
132
+ return;
133
+ }
134
+ const r = initProject(cwd, { force: options.force, mcp: options.mcp, permissions: options.permissions });
135
+ printSuccess('Indemn CLI set up for Claude Code:');
136
+ console.log(` Skills: ${r.skills}`);
137
+ console.log(` Rules: ${r.rules}`);
138
+ console.log(` MCP server: ${r.mcp === 'added' ? 'added to .mcp.json' : r.mcp === 'kept' ? 'already in .mcp.json (kept)' : 'skipped'}`);
139
+ console.log(` Permissions: ${r.permissions === 'skipped' ? 'skipped' : `${r.permissions} in .claude/settings.json (reads allowed, changes ask)`}`);
140
+ const login = IndemnClient.loadConfig();
141
+ if (!login)
142
+ console.log(chalk.yellow('Next: run `indemn login --env dev` (or production).'));
143
+ else if ((login.orgs?.length ?? 0) > 1 && !findLinkFile(cwd))
144
+ console.log(chalk.dim('Tip: pin this folder to one org with `indemn link --org <id>`.'));
145
+ }
146
+ catch (err) {
147
+ printError(err);
148
+ process.exit(1);
149
+ }
150
+ });
151
+ }
152
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"kb.d.ts","sourceRoot":"","sources":["../../src/cli/kb.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA0azD"}
1
+ {"version":3,"file":"kb.d.ts","sourceRoot":"","sources":["../../src/cli/kb.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA6gBzD"}
package/dist/cli/kb.js CHANGED
@@ -1,7 +1,11 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { confirmOrExit } from './link.js';
3
+ import { CliError } from '../core/runtime.js';
4
+ import chalk from 'chalk';
1
5
  import ora from 'ora';
2
6
  import { IndemnClient } from '../sdk/client.js';
3
7
  import { KBSDK } from '../sdk/kb.js';
4
- import { formatTable, printJson, printError, printSuccess, confirm } from './utils/output.js';
8
+ import { formatTable, printJson, printError, printSuccess } from './utils/output.js';
5
9
  export function registerKBCommands(program) {
6
10
  const kb = program.command('kb').description('Manage knowledge bases');
7
11
  kb.command('list')
@@ -122,16 +126,22 @@ export function registerKBCommands(program) {
122
126
  });
123
127
  kb.command('delete')
124
128
  .argument('<kb-id>', 'Knowledge base ID')
125
- .description('Delete a knowledge base')
126
- .action(async (kbId) => {
129
+ .option('--dry-run', 'Show what would be deleted and stop')
130
+ .option('--yes', 'Do not ask for confirmation')
131
+ .description('Delete a knowledge base and all its sources (unlink it from agents first)')
132
+ .action(async (kbId, options) => {
127
133
  try {
128
- const confirmed = await confirm(`Delete knowledge base ${kbId}? This cannot be undone.`);
129
- if (!confirmed) {
130
- console.log('Cancelled.');
131
- return;
132
- }
133
134
  const client = new IndemnClient();
134
135
  const sdk = new KBSDK(client);
136
+ const target = await sdk.getKB(kbId);
137
+ const agents = (target.aiAgents ?? []).map((a) => a.name).filter(Boolean);
138
+ console.log(`Would delete "${target.name ?? kbId}" with ${target.totalDataSourceCount ?? '?'} source(s).`);
139
+ if (agents.length) {
140
+ throw new CliError(`It is linked to ${agents.join(', ')}. Unlink it first: indemn kb unlink <agent-id> ${kbId}`);
141
+ }
142
+ if (options.dryRun)
143
+ return;
144
+ await confirmOrExit(`Delete knowledge base "${target.name ?? kbId}"? Its vectors are removed too.`, Boolean(options.yes));
135
145
  const spinner = ora('Deleting knowledge base...').start();
136
146
  await sdk.deleteKB(kbId);
137
147
  spinner.stop();
@@ -265,13 +275,10 @@ export function registerKBCommands(program) {
265
275
  .argument('<kb-id>', 'Knowledge base ID')
266
276
  .argument('<source-id>', 'Data source ID')
267
277
  .description('Delete a data source')
268
- .action(async (kbId, sourceId) => {
278
+ .option('--yes', 'Do not ask for confirmation')
279
+ .action(async (kbId, sourceId, options) => {
269
280
  try {
270
- const confirmed = await confirm(`Delete data source ${sourceId}? This cannot be undone.`);
271
- if (!confirmed) {
272
- console.log('Cancelled.');
273
- return;
274
- }
281
+ await confirmOrExit(`Delete data source ${sourceId} from knowledge base ${kbId}? Its vectors are removed too.`, Boolean(options.yes));
275
282
  const client = new IndemnClient();
276
283
  const sdk = new KBSDK(client);
277
284
  const spinner = ora('Deleting data source...').start();
@@ -284,6 +291,121 @@ export function registerKBCommands(program) {
284
291
  process.exit(1);
285
292
  }
286
293
  });
294
+ data.command('chunks')
295
+ .argument('<kb-id>', 'Knowledge base ID')
296
+ .argument('<source-id>', 'Data source ID')
297
+ .option('--json', 'Output as JSON')
298
+ .description('Show the text chunks the agent actually retrieves from a source')
299
+ .action(async (kbId, sourceId, options) => {
300
+ try {
301
+ const res = await new KBSDK(new IndemnClient()).chunks(kbId, sourceId);
302
+ if (options.json) {
303
+ printJson(res);
304
+ return;
305
+ }
306
+ console.log(chalk.bold(`${res.source ?? sourceId}`) + chalk.dim(` ${res.status ?? ''} · ${res.chunks.length} chunk(s)`));
307
+ res.chunks.forEach((c, i) => console.log(`${chalk.dim(`#${i + 1}`)} ${c}\n`));
308
+ }
309
+ catch (err) {
310
+ printError(err);
311
+ process.exit(1);
312
+ }
313
+ });
314
+ data.command('reimport')
315
+ .argument('<kb-id>', 'Knowledge base ID')
316
+ .argument('<source-id>', 'URL data source ID')
317
+ .option('--js-script <file>', 'Script to run on each page before reading it')
318
+ .option('--yes', 'Do not ask for confirmation')
319
+ .description('Crawl a URL source again after the website changed (runs in the background; see `kb status`)')
320
+ .action(async (kbId, sourceId, options) => {
321
+ try {
322
+ await confirmOrExit(`Re-crawl source ${sourceId}? Its chunks are replaced when the crawl finishes.`, Boolean(options.yes));
323
+ const js = options.jsScript ? readFileSync(options.jsScript, 'utf8') : undefined;
324
+ await new KBSDK(new IndemnClient()).reimport(kbId, sourceId, js);
325
+ printSuccess(`Re-import started. Follow it with: indemn kb status ${kbId}`);
326
+ }
327
+ catch (err) {
328
+ printError(err);
329
+ process.exit(1);
330
+ }
331
+ });
332
+ kb.command('status')
333
+ .argument('<kb-id>', 'Knowledge base ID')
334
+ .option('--json', 'Output as JSON')
335
+ .description('Progress of website crawls and file imports')
336
+ .action(async (kbId, options) => {
337
+ try {
338
+ const rows = await new KBSDK(new IndemnClient()).scrapeStatus(kbId);
339
+ if (options.json) {
340
+ printJson(rows);
341
+ return;
342
+ }
343
+ if (!rows.length) {
344
+ console.log('No website or file sources yet.');
345
+ return;
346
+ }
347
+ console.log(formatTable(['Source', 'Status', 'Job', 'Error'], rows.map((r) => [r.source ?? '', r.status ?? '', r.job_status ?? '', r.error ?? ''])));
348
+ }
349
+ catch (err) {
350
+ printError(err);
351
+ process.exit(1);
352
+ }
353
+ });
354
+ kb.command('gaps')
355
+ .option('--agent <id>', 'Only questions asked to this agent')
356
+ .option('--kb <id>', 'Only questions for this knowledge base')
357
+ .option('--themes', 'Group into themes instead of listing questions')
358
+ .option('--days <n>', 'With --themes: look back this many days')
359
+ .option('--include-test', 'Include questions from test conversations')
360
+ .option('--page <n>', 'Page, starting at 0', '0')
361
+ .option('--limit <n>', 'Rows per page (at most 100)', '20')
362
+ .option('--json', 'Output as JSON')
363
+ .description('Questions the agents could not answer: what to add to the knowledge base next')
364
+ .action(async (options) => {
365
+ try {
366
+ const sdk = new KBSDK(new IndemnClient());
367
+ if (options.themes) {
368
+ printJson(await sdk.gapClusters({ days: options.days ? Number(options.days) : undefined, page: Number(options.page), limit: Number(options.limit) }));
369
+ return;
370
+ }
371
+ const res = await sdk.gaps({ agentId: options.agent, kbId: options.kb, includeTest: options.includeTest, page: Number(options.page), limit: Number(options.limit) });
372
+ if (options.json) {
373
+ printJson(res);
374
+ return;
375
+ }
376
+ const rows = res.responses ?? [];
377
+ if (!rows.length) {
378
+ console.log('No unanswered questions.');
379
+ return;
380
+ }
381
+ console.log(formatTable(['Question', 'Status', 'Channel'], rows.map((r) => [String(r.user_query ?? '').slice(0, 80), String(r.status ?? ''), String(r.channel ?? '')])));
382
+ console.log(chalk.dim(`${res.total ?? rows.length} in total.`));
383
+ }
384
+ catch (err) {
385
+ printError(err);
386
+ process.exit(1);
387
+ }
388
+ });
389
+ kb.command('check')
390
+ .argument('<question>', 'A question a customer might ask')
391
+ .option('--json', 'Output as JSON')
392
+ .description('Could the org\'s knowledge answer this? Shows the best matching chunks')
393
+ .action(async (question, options) => {
394
+ try {
395
+ const res = await new KBSDK(new IndemnClient()).check(question);
396
+ if (options.json) {
397
+ printJson(res);
398
+ return;
399
+ }
400
+ console.log(res.answerable ? chalk.green(`Answerable (score ${res.top_score})`) : chalk.yellow(`Not answerable (best score ${res.top_score ?? 0})`));
401
+ for (const src of (res.sources ?? []).slice(0, 3))
402
+ console.log(chalk.dim(`- (${src.score}) ${String(src.text ?? '').slice(0, 200)}`));
403
+ }
404
+ catch (err) {
405
+ printError(err);
406
+ process.exit(1);
407
+ }
408
+ });
287
409
  // Link/unlink commands
288
410
  kb.command('link')
289
411
  .argument('<agent-id>', 'Agent ID')
@@ -307,8 +429,10 @@ export function registerKBCommands(program) {
307
429
  .argument('<agent-id>', 'Agent ID')
308
430
  .argument('<kb-id>', 'Knowledge base ID')
309
431
  .description('Unlink a knowledge base from an agent')
310
- .action(async (agentId, kbId) => {
432
+ .option('--yes', 'Do not ask for confirmation')
433
+ .action(async (agentId, kbId, options) => {
311
434
  try {
435
+ await confirmOrExit(`Unlink knowledge base ${kbId} from agent ${agentId}? The agent stops using it immediately.`, Boolean(options.yes));
312
436
  const client = new IndemnClient();
313
437
  const sdk = new KBSDK(client);
314
438
  const spinner = ora('Unlinking knowledge base...').start();
@@ -343,8 +467,10 @@ export function registerKBCommands(program) {
343
467
  .argument('<kb-id>', 'Knowledge base ID')
344
468
  .description('Import QNA pairs from a JSON file into a knowledge base')
345
469
  .requiredOption('--file <path>', 'Path to JSON file with array of {question, answer} pairs')
470
+ .option('--yes', 'Do not ask for confirmation')
346
471
  .action(async (kbId, options) => {
347
472
  try {
473
+ await confirmOrExit(`Import into knowledge base ${kbId}? The agent starts answering from the new content once processed.`, Boolean(options.yes));
348
474
  const fs = await import('fs');
349
475
  const filePath = options.file;
350
476
  if (!fs.existsSync(filePath)) {