@intutic/cli 2.2.0 → 2.3.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 (344) hide show
  1. package/README.md +8 -8
  2. package/dist/cli.d.ts +0 -1
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/cli.js +481 -19
  5. package/dist/cli.js.map +1 -1
  6. package/dist/commands/apiCommand.d.ts +40 -0
  7. package/dist/commands/apiCommand.d.ts.map +1 -0
  8. package/dist/commands/apiCommand.js +88 -0
  9. package/dist/commands/apiCommand.js.map +1 -0
  10. package/dist/commands/budget.d.ts +4 -0
  11. package/dist/commands/budget.d.ts.map +1 -1
  12. package/dist/commands/budget.js +8 -0
  13. package/dist/commands/budget.js.map +1 -1
  14. package/dist/commands/compliance.d.ts +122 -0
  15. package/dist/commands/compliance.d.ts.map +1 -0
  16. package/dist/commands/compliance.js +278 -0
  17. package/dist/commands/compliance.js.map +1 -0
  18. package/dist/commands/connect.d.ts +26 -1
  19. package/dist/commands/connect.d.ts.map +1 -1
  20. package/dist/commands/connect.js +109 -51
  21. package/dist/commands/connect.js.map +1 -1
  22. package/dist/commands/credentials.d.ts +1 -1
  23. package/dist/commands/credentials.js +1 -1
  24. package/dist/commands/decision.d.ts +4 -4
  25. package/dist/commands/decision.js +4 -4
  26. package/dist/commands/disconnect.d.ts +4 -0
  27. package/dist/commands/disconnect.d.ts.map +1 -1
  28. package/dist/commands/disconnect.js +17 -3
  29. package/dist/commands/disconnect.js.map +1 -1
  30. package/dist/commands/doctor.d.ts +0 -1
  31. package/dist/commands/doctor.d.ts.map +1 -1
  32. package/dist/commands/doctor.js +0 -1
  33. package/dist/commands/doctor.js.map +1 -1
  34. package/dist/commands/enforce.d.ts +1 -1
  35. package/dist/commands/enforce.js +1 -1
  36. package/dist/commands/enterprise.d.ts +3 -2
  37. package/dist/commands/enterprise.d.ts.map +1 -1
  38. package/dist/commands/enterprise.js +11 -3
  39. package/dist/commands/enterprise.js.map +1 -1
  40. package/dist/commands/env.js +1 -1
  41. package/dist/commands/exec.d.ts +2 -3
  42. package/dist/commands/exec.d.ts.map +1 -1
  43. package/dist/commands/exec.js +4 -5
  44. package/dist/commands/exec.js.map +1 -1
  45. package/dist/commands/gateLiveness.d.ts +15 -0
  46. package/dist/commands/gateLiveness.d.ts.map +1 -0
  47. package/dist/commands/gateLiveness.js +34 -0
  48. package/dist/commands/gateLiveness.js.map +1 -0
  49. package/dist/commands/gateway.d.ts +14 -4
  50. package/dist/commands/gateway.d.ts.map +1 -1
  51. package/dist/commands/gateway.js +34 -4
  52. package/dist/commands/gateway.js.map +1 -1
  53. package/dist/commands/github.d.ts +20 -0
  54. package/dist/commands/github.d.ts.map +1 -0
  55. package/dist/commands/github.js +41 -0
  56. package/dist/commands/github.js.map +1 -0
  57. package/dist/commands/guardrails.d.ts +28 -2
  58. package/dist/commands/guardrails.d.ts.map +1 -1
  59. package/dist/commands/guardrails.js +233 -24
  60. package/dist/commands/guardrails.js.map +1 -1
  61. package/dist/commands/init.d.ts +1 -2
  62. package/dist/commands/init.d.ts.map +1 -1
  63. package/dist/commands/init.js +1 -2
  64. package/dist/commands/init.js.map +1 -1
  65. package/dist/commands/install-daemon.d.ts +1 -1
  66. package/dist/commands/install-daemon.js +2 -2
  67. package/dist/commands/integrity.d.ts +10 -2
  68. package/dist/commands/integrity.d.ts.map +1 -1
  69. package/dist/commands/integrity.js +3 -3
  70. package/dist/commands/integrity.js.map +1 -1
  71. package/dist/commands/inventory.d.ts +60 -0
  72. package/dist/commands/inventory.d.ts.map +1 -0
  73. package/dist/commands/inventory.js +141 -0
  74. package/dist/commands/inventory.js.map +1 -0
  75. package/dist/commands/judge.d.ts +1 -1
  76. package/dist/commands/judge.js +2 -2
  77. package/dist/commands/judge.js.map +1 -1
  78. package/dist/commands/login.d.ts +0 -1
  79. package/dist/commands/login.d.ts.map +1 -1
  80. package/dist/commands/login.js +0 -1
  81. package/dist/commands/login.js.map +1 -1
  82. package/dist/commands/logout.d.ts +0 -1
  83. package/dist/commands/logout.d.ts.map +1 -1
  84. package/dist/commands/logout.js +0 -1
  85. package/dist/commands/logout.js.map +1 -1
  86. package/dist/commands/mcp.d.ts +31 -0
  87. package/dist/commands/mcp.d.ts.map +1 -0
  88. package/dist/commands/mcp.js +65 -0
  89. package/dist/commands/mcp.js.map +1 -0
  90. package/dist/commands/notifications.d.ts +54 -0
  91. package/dist/commands/notifications.d.ts.map +1 -0
  92. package/dist/commands/notifications.js +151 -0
  93. package/dist/commands/notifications.js.map +1 -0
  94. package/dist/commands/org.d.ts +3 -3
  95. package/dist/commands/org.js +3 -3
  96. package/dist/commands/policy.d.ts +6 -1
  97. package/dist/commands/policy.d.ts.map +1 -1
  98. package/dist/commands/policy.js +77 -37
  99. package/dist/commands/policy.js.map +1 -1
  100. package/dist/commands/rollback.d.ts.map +1 -1
  101. package/dist/commands/rollback.js +3 -1
  102. package/dist/commands/rollback.js.map +1 -1
  103. package/dist/commands/routing.d.ts +1 -1
  104. package/dist/commands/routing.js +1 -1
  105. package/dist/commands/rules.d.ts +74 -0
  106. package/dist/commands/rules.d.ts.map +1 -0
  107. package/dist/commands/rules.js +283 -0
  108. package/dist/commands/rules.js.map +1 -0
  109. package/dist/commands/settings.d.ts +43 -0
  110. package/dist/commands/settings.d.ts.map +1 -0
  111. package/dist/commands/settings.js +108 -0
  112. package/dist/commands/settings.js.map +1 -0
  113. package/dist/commands/setup.d.ts +1 -1
  114. package/dist/commands/setup.js +1 -1
  115. package/dist/commands/siem.d.ts +53 -0
  116. package/dist/commands/siem.d.ts.map +1 -0
  117. package/dist/commands/siem.js +132 -0
  118. package/dist/commands/siem.js.map +1 -0
  119. package/dist/commands/skill.d.ts +5 -5
  120. package/dist/commands/skill.js +7 -7
  121. package/dist/commands/skill.js.map +1 -1
  122. package/dist/commands/status.d.ts +0 -1
  123. package/dist/commands/status.d.ts.map +1 -1
  124. package/dist/commands/status.js +2 -3
  125. package/dist/commands/status.js.map +1 -1
  126. package/dist/commands/syncContext.d.ts +0 -1
  127. package/dist/commands/syncContext.d.ts.map +1 -1
  128. package/dist/commands/syncContext.js +0 -1
  129. package/dist/commands/syncContext.js.map +1 -1
  130. package/dist/commands/team.d.ts +2 -2
  131. package/dist/commands/team.js +2 -2
  132. package/dist/commands/traces.d.ts +0 -3
  133. package/dist/commands/traces.d.ts.map +1 -1
  134. package/dist/commands/traces.js +0 -3
  135. package/dist/commands/traces.js.map +1 -1
  136. package/dist/commands/usage.d.ts +41 -0
  137. package/dist/commands/usage.d.ts.map +1 -0
  138. package/dist/commands/usage.js +129 -0
  139. package/dist/commands/usage.js.map +1 -0
  140. package/dist/commands/whoami.d.ts +0 -1
  141. package/dist/commands/whoami.d.ts.map +1 -1
  142. package/dist/commands/whoami.js +0 -1
  143. package/dist/commands/whoami.js.map +1 -1
  144. package/dist/config/keychain.d.ts +0 -1
  145. package/dist/config/keychain.d.ts.map +1 -1
  146. package/dist/config/keychain.js +0 -1
  147. package/dist/config/keychain.js.map +1 -1
  148. package/dist/config/paths.d.ts +0 -1
  149. package/dist/config/paths.d.ts.map +1 -1
  150. package/dist/config/paths.js +0 -1
  151. package/dist/config/paths.js.map +1 -1
  152. package/dist/config/store.d.ts +0 -1
  153. package/dist/config/store.d.ts.map +1 -1
  154. package/dist/config/store.js +0 -1
  155. package/dist/config/store.js.map +1 -1
  156. package/dist/harness/ag2.d.ts +1 -1
  157. package/dist/harness/ag2.js +1 -1
  158. package/dist/harness/agentFramework.d.ts +1 -1
  159. package/dist/harness/agentFramework.js +1 -1
  160. package/dist/harness/agenticOrchestrator.d.ts +1 -1
  161. package/dist/harness/agenticOrchestrator.js +2 -2
  162. package/dist/harness/agenticOrchestrator.js.map +1 -1
  163. package/dist/harness/agentsMd.d.ts +24 -0
  164. package/dist/harness/agentsMd.d.ts.map +1 -0
  165. package/dist/harness/agentsMd.js +28 -0
  166. package/dist/harness/agentsMd.js.map +1 -0
  167. package/dist/harness/aider.d.ts +3 -1
  168. package/dist/harness/aider.d.ts.map +1 -1
  169. package/dist/harness/aider.js +9 -7
  170. package/dist/harness/aider.js.map +1 -1
  171. package/dist/harness/antigravity.d.ts +23 -5
  172. package/dist/harness/antigravity.d.ts.map +1 -1
  173. package/dist/harness/antigravity.js +45 -55
  174. package/dist/harness/antigravity.js.map +1 -1
  175. package/dist/harness/autogen.d.ts +1 -1
  176. package/dist/harness/autogen.js +2 -2
  177. package/dist/harness/autogen.js.map +1 -1
  178. package/dist/harness/claudeCode.d.ts +22 -1
  179. package/dist/harness/claudeCode.d.ts.map +1 -1
  180. package/dist/harness/claudeCode.js +47 -3
  181. package/dist/harness/claudeCode.js.map +1 -1
  182. package/dist/harness/cline.d.ts.map +1 -1
  183. package/dist/harness/cline.js +14 -23
  184. package/dist/harness/cline.js.map +1 -1
  185. package/dist/harness/codex.d.ts +6 -1
  186. package/dist/harness/codex.d.ts.map +1 -1
  187. package/dist/harness/codex.js +23 -21
  188. package/dist/harness/codex.js.map +1 -1
  189. package/dist/harness/continue.d.ts +10 -4
  190. package/dist/harness/continue.d.ts.map +1 -1
  191. package/dist/harness/continue.js +22 -22
  192. package/dist/harness/continue.js.map +1 -1
  193. package/dist/harness/cursor.d.ts +5 -2
  194. package/dist/harness/cursor.d.ts.map +1 -1
  195. package/dist/harness/cursor.js +19 -23
  196. package/dist/harness/cursor.js.map +1 -1
  197. package/dist/harness/detector.d.ts +0 -1
  198. package/dist/harness/detector.d.ts.map +1 -1
  199. package/dist/harness/detector.js +0 -1
  200. package/dist/harness/detector.js.map +1 -1
  201. package/dist/harness/dsh.d.ts +5 -3
  202. package/dist/harness/dsh.d.ts.map +1 -1
  203. package/dist/harness/dsh.js +17 -29
  204. package/dist/harness/dsh.js.map +1 -1
  205. package/dist/harness/eve.d.ts +3 -4
  206. package/dist/harness/eve.d.ts.map +1 -1
  207. package/dist/harness/eve.js +3 -4
  208. package/dist/harness/eve.js.map +1 -1
  209. package/dist/harness/githubCopilot.d.ts +4 -1
  210. package/dist/harness/githubCopilot.d.ts.map +1 -1
  211. package/dist/harness/githubCopilot.js +12 -20
  212. package/dist/harness/githubCopilot.js.map +1 -1
  213. package/dist/harness/goose.d.ts +7 -3
  214. package/dist/harness/goose.d.ts.map +1 -1
  215. package/dist/harness/goose.js +18 -21
  216. package/dist/harness/goose.js.map +1 -1
  217. package/dist/harness/grok.d.ts +2 -2
  218. package/dist/harness/grok.d.ts.map +1 -1
  219. package/dist/harness/grok.js +13 -24
  220. package/dist/harness/grok.js.map +1 -1
  221. package/dist/harness/hermes.d.ts +6 -0
  222. package/dist/harness/hermes.d.ts.map +1 -1
  223. package/dist/harness/hermes.js +17 -16
  224. package/dist/harness/hermes.js.map +1 -1
  225. package/dist/harness/muse.d.ts +3 -7
  226. package/dist/harness/muse.d.ts.map +1 -1
  227. package/dist/harness/muse.js +15 -35
  228. package/dist/harness/muse.js.map +1 -1
  229. package/dist/harness/n8n.d.ts +13 -14
  230. package/dist/harness/n8n.d.ts.map +1 -1
  231. package/dist/harness/n8n.js +21 -181
  232. package/dist/harness/n8n.js.map +1 -1
  233. package/dist/harness/openWebUI.d.ts.map +1 -1
  234. package/dist/harness/openWebUI.js +5 -4
  235. package/dist/harness/openWebUI.js.map +1 -1
  236. package/dist/harness/openaiAgents.d.ts +1 -1
  237. package/dist/harness/openaiAgents.js +2 -2
  238. package/dist/harness/openaiAgents.js.map +1 -1
  239. package/dist/harness/openclaw.d.ts +8 -0
  240. package/dist/harness/openclaw.d.ts.map +1 -1
  241. package/dist/harness/openclaw.js +27 -12
  242. package/dist/harness/openclaw.js.map +1 -1
  243. package/dist/harness/opencode.d.ts +4 -5
  244. package/dist/harness/opencode.d.ts.map +1 -1
  245. package/dist/harness/opencode.js +15 -30
  246. package/dist/harness/opencode.js.map +1 -1
  247. package/dist/harness/openhands.d.ts +9 -3
  248. package/dist/harness/openhands.d.ts.map +1 -1
  249. package/dist/harness/openhands.js +30 -24
  250. package/dist/harness/openhands.js.map +1 -1
  251. package/dist/harness/pi.d.ts +7 -2
  252. package/dist/harness/pi.d.ts.map +1 -1
  253. package/dist/harness/pi.js +19 -18
  254. package/dist/harness/pi.js.map +1 -1
  255. package/dist/harness/rooCode.d.ts +12 -5
  256. package/dist/harness/rooCode.d.ts.map +1 -1
  257. package/dist/harness/rooCode.js +23 -39
  258. package/dist/harness/rooCode.js.map +1 -1
  259. package/dist/harness/rulesFiles.d.ts +53 -0
  260. package/dist/harness/rulesFiles.d.ts.map +1 -0
  261. package/dist/harness/rulesFiles.js +106 -0
  262. package/dist/harness/rulesFiles.js.map +1 -0
  263. package/dist/harness/smolagents.d.ts +2 -2
  264. package/dist/harness/smolagents.js +3 -3
  265. package/dist/harness/smolagents.js.map +1 -1
  266. package/dist/harness/types.d.ts +20 -6
  267. package/dist/harness/types.d.ts.map +1 -1
  268. package/dist/harness/types.js +1 -95
  269. package/dist/harness/types.js.map +1 -1
  270. package/dist/harness/windsurf.d.ts +6 -1
  271. package/dist/harness/windsurf.d.ts.map +1 -1
  272. package/dist/harness/windsurf.js +21 -24
  273. package/dist/harness/windsurf.js.map +1 -1
  274. package/dist/harness/xirp.d.ts +1 -2
  275. package/dist/harness/xirp.d.ts.map +1 -1
  276. package/dist/harness/xirp.js +2 -3
  277. package/dist/harness/xirp.js.map +1 -1
  278. package/dist/lib/api.d.ts +27 -1
  279. package/dist/lib/api.d.ts.map +1 -1
  280. package/dist/lib/api.js +55 -18
  281. package/dist/lib/api.js.map +1 -1
  282. package/dist/lib/ciscoScanner.d.ts +1 -1
  283. package/dist/lib/ciscoScanner.js +1 -1
  284. package/dist/lib/decisionsLogRefresh.d.ts.map +1 -1
  285. package/dist/lib/decisionsLogRefresh.js +6 -7
  286. package/dist/lib/decisionsLogRefresh.js.map +1 -1
  287. package/dist/lib/deviceReport.d.ts +15 -0
  288. package/dist/lib/deviceReport.d.ts.map +1 -1
  289. package/dist/lib/deviceReport.js +30 -0
  290. package/dist/lib/deviceReport.js.map +1 -1
  291. package/dist/lib/gitHooks.d.ts +0 -1
  292. package/dist/lib/gitHooks.d.ts.map +1 -1
  293. package/dist/lib/gitHooks.js +8 -9
  294. package/dist/lib/gitHooks.js.map +1 -1
  295. package/dist/lib/gracefulShutdown.d.ts +1 -1
  296. package/dist/lib/gracefulShutdown.js +1 -1
  297. package/dist/lib/hash.d.ts +0 -1
  298. package/dist/lib/hash.d.ts.map +1 -1
  299. package/dist/lib/hash.js +0 -1
  300. package/dist/lib/hash.js.map +1 -1
  301. package/dist/lib/inventory.d.ts +47 -0
  302. package/dist/lib/inventory.d.ts.map +1 -0
  303. package/dist/lib/inventory.js +106 -0
  304. package/dist/lib/inventory.js.map +1 -0
  305. package/dist/lib/logger.d.ts +0 -1
  306. package/dist/lib/logger.d.ts.map +1 -1
  307. package/dist/lib/logger.js +0 -1
  308. package/dist/lib/logger.js.map +1 -1
  309. package/dist/lib/mdmManifest.d.ts +30 -2
  310. package/dist/lib/mdmManifest.d.ts.map +1 -1
  311. package/dist/lib/mdmManifest.js +50 -2
  312. package/dist/lib/mdmManifest.js.map +1 -1
  313. package/dist/lib/onboarding.d.ts +0 -1
  314. package/dist/lib/onboarding.d.ts.map +1 -1
  315. package/dist/lib/onboarding.js +1 -2
  316. package/dist/lib/onboarding.js.map +1 -1
  317. package/dist/lib/policySnapshot.d.ts +3 -2
  318. package/dist/lib/policySnapshot.d.ts.map +1 -1
  319. package/dist/lib/policySnapshot.js +6 -3
  320. package/dist/lib/policySnapshot.js.map +1 -1
  321. package/dist/lib/process.d.ts +5 -1
  322. package/dist/lib/process.d.ts.map +1 -1
  323. package/dist/lib/process.js +13 -4
  324. package/dist/lib/process.js.map +1 -1
  325. package/dist/lib/providerProbe.d.ts +2 -2
  326. package/dist/lib/providerProbe.js +2 -2
  327. package/dist/lib/sandbox/firecracker.d.ts +3 -3
  328. package/dist/lib/sandbox/firecracker.js +3 -3
  329. package/dist/lib/sandbox/index.d.ts +2 -2
  330. package/dist/lib/sandbox/index.js +2 -2
  331. package/dist/lib/sandbox/oci.d.ts +1 -1
  332. package/dist/lib/sandbox/oci.js +1 -1
  333. package/dist/lib/sandbox/types.d.ts +1 -1
  334. package/dist/lib/sandbox/types.js +1 -1
  335. package/dist/lib/sopFrontMatter.d.ts +1 -1
  336. package/dist/lib/sopFrontMatter.js +1 -1
  337. package/package.json +6 -5
  338. package/resources/sandbox/Dockerfile +1 -1
  339. package/resources/sandbox/entrypoint.sh +4 -4
  340. package/resources/sandbox/firecracker-launch.sh +1 -1
  341. package/dist/harness/base.d.ts +0 -24
  342. package/dist/harness/base.d.ts.map +0 -1
  343. package/dist/harness/base.js +0 -74
  344. package/dist/harness/base.js.map +0 -1
@@ -0,0 +1,65 @@
1
+ /**
2
+ * `intutic mcp` — the workspace's MCP server registry and the decisions every
3
+ * MCP proxy enforces on it.
4
+ *
5
+ * Subcommands:
6
+ * - `intutic mcp list [--json]`
7
+ * - `intutic mcp approve|block|reset <server_id> [--json]`
8
+ * - `intutic mcp enable-tool|disable-tool <server_id> <tool> [--json]`
9
+ *
10
+ * Server side: services/control-plane/src/routes/mcpServers.ts. Approving,
11
+ * blocking, resetting and switching tools need OWNER or ADMIN; listing needs
12
+ * any member. The registry-wide settings (`mcpDefaultPolicy`,
13
+ * `mcpHighRiskToolChange`, `mcpBudgets`) are workspace settings, changed with
14
+ * `intutic settings set`.
15
+ *
16
+ * @module
17
+ */
18
+ import pc from 'picocolors';
19
+ import { log } from '../lib/logger.js';
20
+ import { runApiCommand } from './apiCommand.js';
21
+ const STATUS_FOR = { approve: 'approved', block: 'blocked', reset: 'candidate' };
22
+ function statusLabel(s) {
23
+ const label = s.status === 'approved' ? pc.green(s.status) : s.status === 'blocked' ? pc.red(s.status) : pc.yellow(s.status);
24
+ return s.heldForReview ? `${label} (held: high-risk tool change)` : label;
25
+ }
26
+ /** `intutic mcp list` */
27
+ export async function runMcpList(opts) {
28
+ await runApiCommand(opts, 'Failed to list MCP servers', (client) => client.get('/api/v1/mcp/servers'), (res) => {
29
+ log.header('Intutic — MCP Servers');
30
+ log.field('Default policy', res.defaultPolicy);
31
+ log.field('High-risk tool change', res.highRiskToolChange);
32
+ log.field('Awaiting a decision', String(res.pendingCount));
33
+ if (res.servers.length === 0) {
34
+ log.dim(' No MCP servers seen yet.');
35
+ return;
36
+ }
37
+ for (const s of res.servers) {
38
+ console.log('');
39
+ log.field('Server ID', s.serverId);
40
+ log.field('Name', s.serverName);
41
+ log.field('Status', statusLabel(s));
42
+ log.field('Tools', `${s.tools.length}${s.disabledTools.length > 0 ? ` (disabled: ${s.disabledTools.join(', ')})` : ''}`);
43
+ log.field('Last seen', s.lastSeenAt);
44
+ }
45
+ });
46
+ }
47
+ /** `intutic mcp approve|block|reset <server_id>` */
48
+ export async function runMcpDecide(action, serverId, opts) {
49
+ await runApiCommand(opts, `Failed to ${action} MCP server ${serverId}`, (client) => client.post(`/api/v1/mcp/servers/${encodeURIComponent(serverId)}/status`, {
50
+ status: STATUS_FOR[action],
51
+ }), (res) => {
52
+ if (action === 'reset')
53
+ log.success(`${res.server.serverName} is back in the approval queue.`);
54
+ else
55
+ log.success(`${res.server.serverName} ${STATUS_FOR[action]}.`);
56
+ });
57
+ }
58
+ /** `intutic mcp enable-tool|disable-tool <server_id> <tool>` */
59
+ export async function runMcpTool(serverId, tool, enabled, opts) {
60
+ await runApiCommand(opts, `Failed to ${enabled ? 'enable' : 'disable'} ${tool}`, (client) => client.post(`/api/v1/mcp/servers/${encodeURIComponent(serverId)}/tools`, {
61
+ tool,
62
+ enabled,
63
+ }), (res) => log.success(`${tool} on ${res.server.serverName} ${enabled ? 'enabled' : 'disabled'}.`));
64
+ }
65
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/commands/mcp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * `intutic notifications` — notification rules: which events go to which
3
+ * Slack channel, email addresses, webhook or PagerDuty service.
4
+ *
5
+ * Subcommands:
6
+ * - `intutic notifications list [--json]`
7
+ * - `intutic notifications create --event <type> --channel <channel> <target flag> [filters] [--json]`
8
+ * - `intutic notifications update <rule_id> [fields] [--json]`
9
+ * - `intutic notifications delete <rule_id> [--json]`
10
+ * - `intutic notifications rotate-secret <rule_id> [--json]`
11
+ *
12
+ * Server side: services/control-plane/src/routes/notifications.ts. A webhook
13
+ * rule's signing secret is generated by the server and returned once — in the
14
+ * response that created it (create, a switch to the webhook channel, or a
15
+ * rotation) — so this prints it once, with a warning to copy it.
16
+ *
17
+ * @module
18
+ */
19
+ import { type ApiCommandOpts } from './apiCommand.js';
20
+ /** The flags `create` and `update` share. */
21
+ export interface RuleFlags {
22
+ event?: string;
23
+ channel?: string;
24
+ slackChannel?: string;
25
+ email?: string;
26
+ webhookUrl?: string;
27
+ pagerdutyKey?: string;
28
+ severity?: string;
29
+ harness?: string;
30
+ user?: string;
31
+ cooldown?: string;
32
+ }
33
+ /**
34
+ * The request body for the given flags: only the fields a flag set, so an
35
+ * update leaves everything else as it is. Channel config and filters are each
36
+ * replaced whole when any of their flags is given, as the route stores them.
37
+ */
38
+ export declare function ruleBody(flags: RuleFlags): Record<string, unknown>;
39
+ /** `intutic notifications list` */
40
+ export declare function runNotificationsList(opts: ApiCommandOpts): Promise<void>;
41
+ /** `intutic notifications create` */
42
+ export declare function runNotificationsCreate(opts: ApiCommandOpts & RuleFlags & {
43
+ disabled?: boolean;
44
+ }): Promise<void>;
45
+ /** `intutic notifications update <rule_id>` */
46
+ export declare function runNotificationsUpdate(ruleId: string, opts: ApiCommandOpts & RuleFlags & {
47
+ enable?: boolean;
48
+ disable?: boolean;
49
+ }): Promise<void>;
50
+ /** `intutic notifications delete <rule_id>` */
51
+ export declare function runNotificationsDelete(ruleId: string, opts: ApiCommandOpts): Promise<void>;
52
+ /** `intutic notifications rotate-secret <rule_id>` */
53
+ export declare function runNotificationsRotateSecret(ruleId: string, opts: ApiCommandOpts): Promise<void>;
54
+ //# sourceMappingURL=notifications.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../../src/commands/notifications.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAKH,OAAO,EAA8D,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAwBjH,6CAA6C;AAC7C,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAkBD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA4BlE;AAsBD,mCAAmC;AACnC,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAiB9E;AAED,qCAAqC;AACrC,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,cAAc,GAAG,SAAS,GAAG;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAarH;AAED,+CAA+C;AAC/C,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,cAAc,GAAG,SAAS,GAAG;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GACzE,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED,+CAA+C;AAC/C,wBAAsB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAOhG;AAED,sDAAsD;AACtD,wBAAsB,4BAA4B,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAatG"}
@@ -0,0 +1,151 @@
1
+ /**
2
+ * `intutic notifications` — notification rules: which events go to which
3
+ * Slack channel, email addresses, webhook or PagerDuty service.
4
+ *
5
+ * Subcommands:
6
+ * - `intutic notifications list [--json]`
7
+ * - `intutic notifications create --event <type> --channel <channel> <target flag> [filters] [--json]`
8
+ * - `intutic notifications update <rule_id> [fields] [--json]`
9
+ * - `intutic notifications delete <rule_id> [--json]`
10
+ * - `intutic notifications rotate-secret <rule_id> [--json]`
11
+ *
12
+ * Server side: services/control-plane/src/routes/notifications.ts. A webhook
13
+ * rule's signing secret is generated by the server and returned once — in the
14
+ * response that created it (create, a switch to the webhook channel, or a
15
+ * rotation) — so this prints it once, with a warning to copy it.
16
+ *
17
+ * @module
18
+ */
19
+ import pc from 'picocolors';
20
+ import { NOTIFICATION_EVENT_TYPES } from '@intutic/shared-types';
21
+ import { log } from '../lib/logger.js';
22
+ import { fail, list, positiveInt, printSigningSecret, runApiCommand } from './apiCommand.js';
23
+ const CHANNELS = ['slack', 'email', 'webhook', 'pagerduty'];
24
+ /**
25
+ * Fails on an event type the API would refuse, suggesting the ones in the
26
+ * same family (`decision.pend` → `decision.pending`, …), or all of them when
27
+ * none share its first segment.
28
+ */
29
+ function checkEventType(event) {
30
+ if (NOTIFICATION_EVENT_TYPES.includes(event))
31
+ return;
32
+ const family = event.split('.')[0];
33
+ const near = NOTIFICATION_EVENT_TYPES.filter((t) => t.split('.')[0] === family);
34
+ fail(`--event "${event}" is not a notification event type. ` +
35
+ (near.length > 0 ? `Did you mean ${near.join(', ')}?` : `Valid types: ${NOTIFICATION_EVENT_TYPES.join(', ')}.`) +
36
+ ' Every type is described at https://docs.intutic.ai/guide/settings#notifications');
37
+ }
38
+ /**
39
+ * The request body for the given flags: only the fields a flag set, so an
40
+ * update leaves everything else as it is. Channel config and filters are each
41
+ * replaced whole when any of their flags is given, as the route stores them.
42
+ */
43
+ export function ruleBody(flags) {
44
+ const body = {};
45
+ if (flags.event !== undefined) {
46
+ checkEventType(flags.event);
47
+ body.eventType = flags.event;
48
+ }
49
+ if (flags.channel !== undefined) {
50
+ if (!CHANNELS.includes(flags.channel)) {
51
+ fail(`--channel must be one of ${CHANNELS.join(', ')}, got "${flags.channel}"`);
52
+ }
53
+ body.channel = flags.channel;
54
+ }
55
+ const config = {};
56
+ if (flags.slackChannel !== undefined)
57
+ config.slackChannelId = flags.slackChannel;
58
+ if (flags.email !== undefined)
59
+ config.emailRecipients = list(flags.email);
60
+ if (flags.webhookUrl !== undefined)
61
+ config.webhookUrl = flags.webhookUrl;
62
+ if (flags.pagerdutyKey !== undefined)
63
+ config.pagerdutyRoutingKey = flags.pagerdutyKey;
64
+ if (Object.keys(config).length > 0)
65
+ body.channelConfig = config;
66
+ const filters = {};
67
+ if (flags.severity !== undefined)
68
+ filters.severity = list(flags.severity);
69
+ if (flags.harness !== undefined)
70
+ filters.harnessType = list(flags.harness);
71
+ if (flags.user !== undefined)
72
+ filters.userId = list(flags.user);
73
+ if (Object.keys(filters).length > 0)
74
+ body.filters = filters;
75
+ if (flags.cooldown !== undefined)
76
+ body.cooldownMinutes = positiveInt(flags.cooldown, '--cooldown');
77
+ return body;
78
+ }
79
+ function target(rule) {
80
+ const c = rule.channelConfig;
81
+ switch (rule.channel) {
82
+ case 'slack': return c.slackChannelName ?? c.slackChannelId ?? '—';
83
+ case 'email': return c.emailRecipients?.join(', ') ?? '—';
84
+ case 'webhook': return c.webhookUrl ?? '—';
85
+ case 'pagerduty': return 'routing key set';
86
+ }
87
+ }
88
+ function printRule(rule) {
89
+ log.field('Rule ID', rule.ruleId);
90
+ log.field('Event', rule.eventType);
91
+ log.field('Channel', `${rule.channel} → ${target(rule)}`);
92
+ const filters = Object.entries(rule.filters).filter(([, v]) => v && v.length > 0);
93
+ if (filters.length > 0)
94
+ log.field('Filters', filters.map(([k, v]) => `${k}=${v.join(',')}`).join('; '));
95
+ log.field('Cooldown', `${rule.cooldownMinutes} min`);
96
+ log.field('Enabled', rule.enabled ? pc.green('yes') : pc.dim('no'));
97
+ }
98
+ /** `intutic notifications list` */
99
+ export async function runNotificationsList(opts) {
100
+ await runApiCommand(opts, 'Failed to list notification rules', (client) => client.get('/api/v1/notifications/rules'), (res) => {
101
+ log.header('Intutic — Notification Rules');
102
+ if (res.rules.length === 0) {
103
+ log.dim(' No notification rules.');
104
+ return;
105
+ }
106
+ for (const rule of res.rules) {
107
+ console.log('');
108
+ printRule(rule);
109
+ }
110
+ });
111
+ }
112
+ /** `intutic notifications create` */
113
+ export async function runNotificationsCreate(opts) {
114
+ const body = ruleBody(opts);
115
+ if (opts.disabled)
116
+ body.enabled = false;
117
+ await runApiCommand(opts, 'Failed to create notification rule', (client) => client.post('/api/v1/notifications/rules', body), (rule) => {
118
+ log.success('Notification rule created.');
119
+ printRule(rule);
120
+ printSigningSecret(rule.signingSecret);
121
+ });
122
+ }
123
+ /** `intutic notifications update <rule_id>` */
124
+ export async function runNotificationsUpdate(ruleId, opts) {
125
+ if (opts.enable && opts.disable)
126
+ fail('Pass --enable or --disable, not both.');
127
+ const body = ruleBody(opts);
128
+ if (opts.enable)
129
+ body.enabled = true;
130
+ if (opts.disable)
131
+ body.enabled = false;
132
+ if (Object.keys(body).length === 0)
133
+ fail('Nothing to update: pass at least one field to change.');
134
+ await runApiCommand(opts, `Failed to update notification rule ${ruleId}`, (client) => client.put(`/api/v1/notifications/rules/${encodeURIComponent(ruleId)}`, body), (rule) => {
135
+ log.success('Notification rule updated.');
136
+ printRule(rule);
137
+ printSigningSecret(rule.signingSecret);
138
+ });
139
+ }
140
+ /** `intutic notifications delete <rule_id>` */
141
+ export async function runNotificationsDelete(ruleId, opts) {
142
+ await runApiCommand(opts, `Failed to delete notification rule ${ruleId}`, (client) => client.del(`/api/v1/notifications/rules/${encodeURIComponent(ruleId)}`), () => log.success(`Notification rule ${ruleId} deleted.`));
143
+ }
144
+ /** `intutic notifications rotate-secret <rule_id>` */
145
+ export async function runNotificationsRotateSecret(ruleId, opts) {
146
+ await runApiCommand(opts, `Failed to replace the signing secret of ${ruleId}`, (client) => client.post(`/api/v1/notifications/rules/${encodeURIComponent(ruleId)}/signing-secret`), (res) => {
147
+ log.success(`New signing secret for ${res.ruleId}; deliveries are signed with it from now on.`);
148
+ printSigningSecret(res.signingSecret);
149
+ });
150
+ }
151
+ //# sourceMappingURL=notifications.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notifications.js","sourceRoot":"","sources":["../../src/commands/notifications.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAA;AAC3B,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAA;AAChE,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AACtC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,kBAAkB,EAAE,aAAa,EAAuB,MAAM,iBAAiB,CAAA;AAEjH,MAAM,QAAQ,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,CAAU,CAAA;AAoCpE;;;;GAIG;AACH,SAAS,cAAc,CAAC,KAAa;IACnC,IAAK,wBAA8C,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAM;IAC3E,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;IAClC,MAAM,IAAI,GAAG,wBAAwB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAA;IAC/E,IAAI,CACF,YAAY,KAAK,sCAAsC;QACrD,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,gBAAgB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,gBAAgB,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;QAC/G,kFAAkF,CACrF,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CAAC,KAAgB;IACvC,MAAM,IAAI,GAA4B,EAAE,CAAA;IACxC,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC9B,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QAC3B,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,KAAK,CAAA;IAC9B,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAChC,IAAI,CAAE,QAA8B,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;YAC7D,IAAI,CAAC,4BAA4B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,KAAK,CAAC,OAAO,GAAG,CAAC,CAAA;QACjF,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAA;IAC9B,CAAC;IAED,MAAM,MAAM,GAAkB,EAAE,CAAA;IAChC,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS;QAAE,MAAM,CAAC,cAAc,GAAG,KAAK,CAAC,YAAY,CAAA;IAChF,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;QAAE,MAAM,CAAC,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IACzE,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS;QAAE,MAAM,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAA;IACxE,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS;QAAE,MAAM,CAAC,mBAAmB,GAAG,KAAK,CAAC,YAAY,CAAA;IACrF,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC;QAAE,IAAI,CAAC,aAAa,GAAG,MAAM,CAAA;IAE/D,MAAM,OAAO,GAAgC,EAAE,CAAA;IAC/C,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS;QAAE,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;IACzE,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IAC1E,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAC/D,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC;QAAE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IAE3D,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS;QAAE,IAAI,CAAC,eAAe,GAAG,WAAW,CAAC,KAAK,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAA;IAClG,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAS,MAAM,CAAC,IAAsB;IACpC,MAAM,CAAC,GAAG,IAAI,CAAC,aAAa,CAAA;IAC5B,QAAQ,IAAI,CAAC,OAAO,EAAE,CAAC;QACrB,KAAK,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,gBAAgB,IAAI,CAAC,CAAC,cAAc,IAAI,GAAG,CAAA;QAClE,KAAK,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,eAAe,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,CAAA;QACzD,KAAK,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU,IAAI,GAAG,CAAA;QAC1C,KAAK,WAAW,CAAC,CAAC,OAAO,iBAAiB,CAAA;IAC5C,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,IAAsB;IACvC,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;IACjC,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;IAClC,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,GAAG,IAAI,CAAC,OAAO,MAAM,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACzD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IACjF,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;QAAE,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAK,CAAc,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;IACrH,GAAG,CAAC,KAAK,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,eAAe,MAAM,CAAC,CAAA;IACpD,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAA;AACrE,CAAC;AAED,mCAAmC;AACnC,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,IAAoB;IAC7D,MAAM,aAAa,CACjB,IAAI,EACJ,mCAAmC,EACnC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAgC,6BAA6B,CAAC,EACpF,CAAC,GAAG,EAAE,EAAE;QACN,GAAG,CAAC,MAAM,CAAC,8BAA8B,CAAC,CAAA;QAC1C,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,GAAG,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAA;YACnC,OAAM;QACR,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;YAC7B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;YACf,SAAS,CAAC,IAAI,CAAC,CAAA;QACjB,CAAC;IACH,CAAC,CACF,CAAA;AACH,CAAC;AAED,qCAAqC;AACrC,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,IAAyD;IACpG,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAA;IAC3B,IAAI,IAAI,CAAC,QAAQ;QAAE,IAAI,CAAC,OAAO,GAAG,KAAK,CAAA;IACvC,MAAM,aAAa,CACjB,IAAI,EACJ,oCAAoC,EACpC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAmB,6BAA6B,EAAE,IAAI,CAAC,EAC9E,CAAC,IAAI,EAAE,EAAE;QACP,GAAG,CAAC,OAAO,CAAC,4BAA4B,CAAC,CAAA;QACzC,SAAS,CAAC,IAAI,CAAC,CAAA;QACf,kBAAkB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;IACxC,CAAC,CACF,CAAA;AACH,CAAC;AAED,+CAA+C;AAC/C,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,MAAc,EACd,IAA0E;IAE1E,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO;QAAE,IAAI,CAAC,uCAAuC,CAAC,CAAA;IAC9E,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAA;IAC3B,IAAI,IAAI,CAAC,MAAM;QAAE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;IACpC,IAAI,IAAI,CAAC,OAAO;QAAE,IAAI,CAAC,OAAO,GAAG,KAAK,CAAA;IACtC,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,IAAI,CAAC,uDAAuD,CAAC,CAAA;IACjG,MAAM,aAAa,CACjB,IAAI,EACJ,sCAAsC,MAAM,EAAE,EAC9C,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAmB,+BAA+B,kBAAkB,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,EAC3G,CAAC,IAAI,EAAE,EAAE;QACP,GAAG,CAAC,OAAO,CAAC,4BAA4B,CAAC,CAAA;QACzC,SAAS,CAAC,IAAI,CAAC,CAAA;QACf,kBAAkB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;IACxC,CAAC,CACF,CAAA;AACH,CAAC;AAED,+CAA+C;AAC/C,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,MAAc,EAAE,IAAoB;IAC/E,MAAM,aAAa,CACjB,IAAI,EACJ,sCAAsC,MAAM,EAAE,EAC9C,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAkB,+BAA+B,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC,EACpG,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,qBAAqB,MAAM,WAAW,CAAC,CAC1D,CAAA;AACH,CAAC;AAED,sDAAsD;AACtD,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAAC,MAAc,EAAE,IAAoB;IACrF,MAAM,aAAa,CACjB,IAAI,EACJ,2CAA2C,MAAM,EAAE,EACnD,CAAC,MAAM,EAAE,EAAE,CACT,MAAM,CAAC,IAAI,CACT,+BAA+B,kBAAkB,CAAC,MAAM,CAAC,iBAAiB,CAC3E,EACH,CAAC,GAAG,EAAE,EAAE;QACN,GAAG,CAAC,OAAO,CAAC,0BAA0B,GAAG,CAAC,MAAM,8CAA8C,CAAC,CAAA;QAC/F,kBAAkB,CAAC,GAAG,CAAC,aAAa,CAAC,CAAA;IACvC,CAAC,CACF,CAAA;AACH,CAAC"}
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * `intutic org create` — create a real org from an already-authenticated
3
- * session (tenancy phase 4/7, LLD #65).
3
+ * session.
4
4
  *
5
- * Real org creation now requires DNS domain-ownership verification (LLD #71
6
- * follow-up): creating an org auto-provisions a real managed gateway cell,
5
+ * Real org creation now requires DNS domain-ownership verification:
6
+ * creating an org auto-provisions a real managed gateway cell,
7
7
  * so an org's claimed domain must be proven before `POST /api/v1/orgs` will
8
8
  * create it. There's no anonymous-compatible verification flow (no session
9
9
  * exists yet to own a verification attempt against), so the old anonymous
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * `intutic org create` — create a real org from an already-authenticated
3
- * session (tenancy phase 4/7, LLD #65).
3
+ * session.
4
4
  *
5
- * Real org creation now requires DNS domain-ownership verification (LLD #71
6
- * follow-up): creating an org auto-provisions a real managed gateway cell,
5
+ * Real org creation now requires DNS domain-ownership verification:
6
+ * creating an org auto-provisions a real managed gateway cell,
7
7
  * so an org's claimed domain must be proven before `POST /api/v1/orgs` will
8
8
  * create it. There's no anonymous-compatible verification flow (no session
9
9
  * exists yet to own a verification attempt against), so the old anonymous
@@ -113,11 +113,16 @@ export declare const explainUnsupportedImport: typeof explainWasmImport;
113
113
  * Instantiates a compiled rule with the proxy's host imports and evaluates it
114
114
  * against one mock context, returning the raw verdict code.
115
115
  *
116
+ * The rule is metered as the MCP proxy meters it, against the proxies'
117
+ * budget (`DEFAULT_FUEL_BUDGET`, the Rust proxy's `limits::NATIVE`): a rule
118
+ * that runs out of instructions there throws here, saying so. `budget` is
119
+ * for tests.
120
+ *
116
121
  * The import set here is the proxy's, not a convenient superset: a rule that
117
122
  * links in this sandbox must link in the proxy, or install validation passes
118
123
  * something the proxy then silently bypasses.
119
124
  */
120
- export declare function instantiateAndEvaluate(wasmBuffer: Uint8Array, mockStr: string): Promise<number>;
125
+ export declare function instantiateAndEvaluate(wasmBuffer: Uint8Array, mockStr: string, budget?: number): Promise<number>;
121
126
  export declare function runPolicyTest(opts: {
122
127
  wasm: string;
123
128
  mock: string;
@@ -1 +1 @@
1
- {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../src/commands/policy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../src/commands/policy.ts"],"names":[],"mappings":"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"}
@@ -5,7 +5,8 @@ import { createHash } from 'node:crypto';
5
5
  import { spawn } from 'node:child_process';
6
6
  import { log } from '../lib/logger.js';
7
7
  import { NOT_AUTHENTICATED } from '../lib/authMessages.js';
8
- import { WASM_HOST_IMPORTS, unsupportedWasmImports, explainWasmImport, } from '@intutic/shared-types';
8
+ import { DEFAULT_FUEL_BUDGET, FUEL_EXPORT, WASM_HOST_IMPORTS, unsupportedWasmImports, explainWasmImport, isOpaModule, meterFuel, } from '@intutic/shared-types';
9
+ import { decideCase, loadMeteredRegoRule } from './rules.js';
9
10
  import { loadCredentials, loadConfig } from '../config/store.js';
10
11
  import { resolveControlPlaneUrl } from '../config/paths.js';
11
12
  import { createApiClient } from '../lib/api.js';
@@ -230,7 +231,8 @@ function resolveGuestAbi(instance) {
230
231
  }
231
232
  // Accept exactly the allocator exports the proxy runner accepts
232
233
  // (packages/proxy/src/wasm/runner.rs: `allocate`, then `__new`) — anything
233
- // looser would validate rules the proxy then silently fails open on.
234
+ // looser would validate rules the proxy then cannot run: they reach no
235
+ // verdict on every call, so every call is refused.
234
236
  let allocate;
235
237
  const allocateExport = exportedFunction(exports, 'allocate');
236
238
  if (allocateExport) {
@@ -301,11 +303,16 @@ export const explainUnsupportedImport = explainWasmImport;
301
303
  * Instantiates a compiled rule with the proxy's host imports and evaluates it
302
304
  * against one mock context, returning the raw verdict code.
303
305
  *
306
+ * The rule is metered as the MCP proxy meters it, against the proxies'
307
+ * budget (`DEFAULT_FUEL_BUDGET`, the Rust proxy's `limits::NATIVE`): a rule
308
+ * that runs out of instructions there throws here, saying so. `budget` is
309
+ * for tests.
310
+ *
304
311
  * The import set here is the proxy's, not a convenient superset: a rule that
305
312
  * links in this sandbox must link in the proxy, or install validation passes
306
313
  * something the proxy then silently bypasses.
307
314
  */
308
- export async function instantiateAndEvaluate(wasmBuffer, mockStr) {
315
+ export async function instantiateAndEvaluate(wasmBuffer, mockStr, budget = DEFAULT_FUEL_BUDGET) {
309
316
  let instanceRef = null;
310
317
  /**
311
318
  * Guest memory, or null before `WebAssembly.instantiate` has resolved.
@@ -426,7 +433,7 @@ export async function instantiateAndEvaluate(wasmBuffer, mockStr) {
426
433
  // error: function import requires a callable". Same outcome either way — the
427
434
  // instantiate below would throw — but a rule author needs to know it was
428
435
  // `Math.random()`.
429
- const compiled = await WebAssembly.compile(new Uint8Array(wasmBuffer));
436
+ const compiled = await WebAssembly.compile(meterFuel(new Uint8Array(wasmBuffer), budget));
430
437
  const unsupported = unsupportedImports(compiled);
431
438
  if (unsupported.length > 0) {
432
439
  throw new Error(`rule imports ${unsupported.length} function(s) the proxy sandbox does not provide:\n` +
@@ -436,13 +443,22 @@ export async function instantiateAndEvaluate(wasmBuffer, mockStr) {
436
443
  const instance = await WebAssembly.instantiate(compiled, imports);
437
444
  instanceRef = instance;
438
445
  const abi = resolveGuestAbi(instance);
439
- const jsonBytes = Buffer.from(mockStr);
440
- const offset = abi.allocate(jsonBytes.length);
441
- // Re-read `abi.memory.buffer` here rather than caching a view: `allocate` can
442
- // grow the memory, which detaches every ArrayBuffer taken before the call.
443
- const memView = new Uint8Array(abi.memory.buffer, offset, jsonBytes.length);
444
- memView.set(jsonBytes);
445
- return abi.evaluate(offset, jsonBytes.length);
446
+ const fuel = instance.exports[FUEL_EXPORT];
447
+ try {
448
+ const jsonBytes = Buffer.from(mockStr);
449
+ const offset = abi.allocate(jsonBytes.length);
450
+ // Re-read `abi.memory.buffer` here rather than caching a view: `allocate` can
451
+ // grow the memory, which detaches every ArrayBuffer taken before the call.
452
+ const memView = new Uint8Array(abi.memory.buffer, offset, jsonBytes.length);
453
+ memView.set(jsonBytes);
454
+ return abi.evaluate(offset, jsonBytes.length);
455
+ }
456
+ catch (err) {
457
+ if (fuel instanceof WebAssembly.Global && fuel.value < 0) {
458
+ throw new Error(`WASM rule ran out of its ${budget}-instruction budget; a proxy reaches no verdict and refuses the call as GOVERNANCE_UNAVAILABLE`, { cause: err });
459
+ }
460
+ throw err;
461
+ }
446
462
  }
447
463
  export async function runPolicyTest(opts) {
448
464
  log.header('Intutic — Test Local WASM Policy Rule');
@@ -463,6 +479,10 @@ export async function runPolicyTest(opts) {
463
479
  log.error(`Failed to read or parse mock context JSON at "${opts.mock}": ${errMessage(err)}`);
464
480
  process.exit(1);
465
481
  }
482
+ if (isOpaModule(new WebAssembly.Module(new Uint8Array(wasmBuffer)))) {
483
+ log.error(`"${opts.wasm}" is a Rego rule. Test it with: intutic rules test ${opts.wasm} --input <cases.json>`);
484
+ process.exit(1);
485
+ }
466
486
  try {
467
487
  const verdict = await instantiateAndEvaluate(wasmBuffer, mockStr);
468
488
  log.info(`Dry-run evaluation executed successfully.`);
@@ -484,8 +504,8 @@ export async function runPolicyTest(opts) {
484
504
  }
485
505
  else {
486
506
  log.error(`Result: unmapped verdict code ${verdict}`);
487
- log.info(' Valid codes are 0 (allow), 1 (block) and 3 (reask). The proxy allows');
488
- log.info(' anything else, so a rule returning this enforces nothing.');
507
+ log.info(' Valid codes are 0 (allow), 1 (block) and 3 (reask). Anything else is');
508
+ log.info(' no verdict: the proxy refuses the call with GOVERNANCE_UNAVAILABLE.');
489
509
  }
490
510
  }
491
511
  catch (err) {
@@ -609,7 +629,7 @@ export async function uploadCandidateBundle(client, candidateId, wasmPath, sourc
609
629
  log.error(`Rule candidate "${candidateId}" was not found in this workspace.`);
610
630
  process.exit(1);
611
631
  }
612
- if (status === 400 || status === 409) {
632
+ if (status === 400 || status === 403 || status === 409) {
613
633
  log.error(`Refused: ${body.error ?? `HTTP ${status}`}${body.detail ? ` — ${body.detail}` : ''}`);
614
634
  process.exit(1);
615
635
  }
@@ -698,33 +718,46 @@ export async function runPolicyInstall(opts) {
698
718
  log.error(`Failed to read WASM file at "${opts.wasm}": ${errMessage(err)}`);
699
719
  process.exit(1);
700
720
  }
701
- // Refuse to install a rule that cannot instantiate or evaluate — a broken
702
- // rule enforces nothing (the proxy sandbox fails open).
721
+ // A Rego rule is validated by the Rego host: it must load (a builtin the
722
+ // host lacks is refused here, by name) and evaluate an input.
723
+ let rego;
703
724
  try {
704
- const validationVerdict = await instantiateAndEvaluate(wasmBuffer, DEFAULT_ALLOW_MOCK);
705
- // Refuse a code the proxy does not map. Everything outside {0,1,2,3} is
706
- // allowed at runtime with a warning, so a rule inventing a rung installs
707
- // clean and then enforces nothing — the same silent shape as a rule that
708
- // cannot link. 2 is accepted here because already-installed rules use it,
709
- // but it is deprecated and reported as such.
710
- if (validationVerdict === 2) {
711
- // Accepted, because refusing it would break reinstalling a rule that
712
- // already shipped — but never silently. The guest never receives the
713
- // request body, so redaction was never expressible, and the proxy maps 2
714
- // to a block. An author who believes they are redacting is blocking.
715
- log.warn('Rule returned verdict code 2 (REDACT), which is deprecated. The proxy treats it ' +
716
- 'as a block. Return 1 to block, or 3 to reask.');
717
- }
718
- if (![0, 1, 2, 3].includes(validationVerdict)) {
719
- log.error(`Rule returned verdict code ${validationVerdict}, which the proxy does not map — ` +
720
- 'it would be allowed on every request. Valid codes: 0 allow, 1 block, 3 reask.');
721
- process.exit(1);
722
- }
725
+ rego = loadMeteredRegoRule(wasmBuffer);
726
+ if (rego)
727
+ decideCase(rego, { tool: null, args: null });
723
728
  }
724
729
  catch (err) {
725
- log.error(`Rule failed validation and was NOT installed: ${errMessage(err)}`);
730
+ log.error(`Rego rule failed validation and was NOT installed: ${errMessage(err)}`);
726
731
  process.exit(1);
727
732
  }
733
+ // Refuse to install a rule that cannot instantiate or evaluate — a broken
734
+ // rule reaches no verdict on any call, so every call would be refused.
735
+ if (!rego) {
736
+ try {
737
+ const validationVerdict = await instantiateAndEvaluate(wasmBuffer, DEFAULT_ALLOW_MOCK);
738
+ // Refuse a code the proxy does not map. Everything outside {0,1,2,3} is
739
+ // no verdict at runtime, so a rule inventing a rung would install clean
740
+ // and then refuse every call. 2 is accepted here because already-installed rules use it,
741
+ // but it is deprecated and reported as such.
742
+ if (validationVerdict === 2) {
743
+ // Accepted, because refusing it would break reinstalling a rule that
744
+ // already shipped — but never silently. The guest never receives the
745
+ // request body, so redaction was never expressible, and the proxy maps 2
746
+ // to a block. An author who believes they are redacting is blocking.
747
+ log.warn('Rule returned verdict code 2 (REDACT), which is deprecated. The proxy treats it ' +
748
+ 'as a block. Return 1 to block, or 3 to reask.');
749
+ }
750
+ if (![0, 1, 2, 3].includes(validationVerdict)) {
751
+ log.error(`Rule returned verdict code ${validationVerdict}, which is not a verdict — ` +
752
+ 'the proxy would refuse every such call with GOVERNANCE_UNAVAILABLE. Valid codes: 0 allow, 1 block, 3 reask.');
753
+ process.exit(1);
754
+ }
755
+ }
756
+ catch (err) {
757
+ log.error(`Rule failed validation and was NOT installed: ${errMessage(err)}`);
758
+ process.exit(1);
759
+ }
760
+ }
728
761
  const priority = parseInt(opts.priority ?? '100', 10);
729
762
  if (isNaN(priority) || priority < 0) {
730
763
  log.error(`Invalid priority "${opts.priority}". Must be a non-negative integer.`);
@@ -743,7 +776,9 @@ export async function runPolicyInstall(opts) {
743
776
  process.exit(1);
744
777
  }
745
778
  const sha256 = createHash('sha256').update(wasmBuffer).digest('hex');
746
- log.success(`Installed rule "${name}"`);
779
+ log.success(`Installed ${rego ? 'Rego ' : ''}rule "${name}"`);
780
+ if (rego)
781
+ log.field('Entrypoint', rego.entrypoint);
747
782
  log.field('Path', dest);
748
783
  log.field('Priority', String(priority));
749
784
  log.field('SHA-256', sha256);
@@ -800,6 +835,11 @@ export async function runPolicyReplay(ruleId, opts) {
800
835
  }
801
836
  process.exit(1);
802
837
  }
838
+ if (status === 403) {
839
+ const detail = result.detail;
840
+ log.error(`Replay refused: ${detail ?? 'your role cannot replay rules'}`);
841
+ process.exit(1);
842
+ }
803
843
  if (status !== 200) {
804
844
  log.error(`Replay failed (${status}): ${JSON.stringify(result)}`);
805
845
  process.exit(1);