alpic 0.0.0-staging.dfd352e → 0.0.0-staging.e051bb2

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 (296) hide show
  1. package/README.md +72 -0
  2. package/bin/run.js +5 -0
  3. package/dist/__tests__/alpic-command.test.d.ts +1 -0
  4. package/dist/__tests__/alpic-command.test.js +41 -0
  5. package/dist/__tests__/alpic-command.test.js.map +1 -0
  6. package/dist/__tests__/audit.e2e.test.d.ts +1 -0
  7. package/dist/__tests__/audit.e2e.test.js +764 -0
  8. package/dist/__tests__/audit.e2e.test.js.map +1 -0
  9. package/dist/__tests__/auth.e2e.test.d.ts +1 -0
  10. package/dist/__tests__/auth.e2e.test.js +162 -0
  11. package/dist/__tests__/auth.e2e.test.js.map +1 -0
  12. package/dist/__tests__/deploy-flags.e2e.test.d.ts +1 -0
  13. package/dist/__tests__/deploy-flags.e2e.test.js +228 -0
  14. package/dist/__tests__/deploy-flags.e2e.test.js.map +1 -0
  15. package/dist/__tests__/deploy.e2e.test.js +65 -66
  16. package/dist/__tests__/deploy.e2e.test.js.map +1 -1
  17. package/dist/__tests__/deployment-inspect.e2e.test.d.ts +1 -0
  18. package/dist/__tests__/deployment-inspect.e2e.test.js +119 -0
  19. package/dist/__tests__/deployment-inspect.e2e.test.js.map +1 -0
  20. package/dist/__tests__/deployment-list.e2e.test.d.ts +1 -0
  21. package/dist/__tests__/deployment-list.e2e.test.js +181 -0
  22. package/dist/__tests__/deployment-list.e2e.test.js.map +1 -0
  23. package/dist/__tests__/deployment-logs.e2e.test.d.ts +1 -0
  24. package/dist/__tests__/deployment-logs.e2e.test.js +276 -0
  25. package/dist/__tests__/deployment-logs.e2e.test.js.map +1 -0
  26. package/dist/__tests__/environment-inspect.e2e.test.d.ts +1 -0
  27. package/dist/__tests__/environment-inspect.e2e.test.js +110 -0
  28. package/dist/__tests__/environment-inspect.e2e.test.js.map +1 -0
  29. package/dist/__tests__/environment-list.e2e.test.d.ts +1 -0
  30. package/dist/__tests__/environment-list.e2e.test.js +89 -0
  31. package/dist/__tests__/environment-list.e2e.test.js.map +1 -0
  32. package/dist/__tests__/environment-variable/environment-variable-add.e2e.test.d.ts +1 -0
  33. package/dist/__tests__/environment-variable/environment-variable-add.e2e.test.js +368 -0
  34. package/dist/__tests__/environment-variable/environment-variable-add.e2e.test.js.map +1 -0
  35. package/dist/__tests__/environment-variable/environment-variable-list.e2e.test.d.ts +1 -0
  36. package/dist/__tests__/environment-variable/environment-variable-list.e2e.test.js +224 -0
  37. package/dist/__tests__/environment-variable/environment-variable-list.e2e.test.js.map +1 -0
  38. package/dist/__tests__/environment-variable/environment-variable-remove.e2e.test.d.ts +1 -0
  39. package/dist/__tests__/environment-variable/environment-variable-remove.e2e.test.js +148 -0
  40. package/dist/__tests__/environment-variable/environment-variable-remove.e2e.test.js.map +1 -0
  41. package/dist/__tests__/environment-variable/environment-variable-update.e2e.test.d.ts +1 -0
  42. package/dist/__tests__/environment-variable/environment-variable-update.e2e.test.js +337 -0
  43. package/dist/__tests__/environment-variable/environment-variable-update.e2e.test.js.map +1 -0
  44. package/dist/__tests__/environment-variable/environment-variable-validation.test.d.ts +1 -0
  45. package/dist/__tests__/environment-variable/environment-variable-validation.test.js +20 -0
  46. package/dist/__tests__/environment-variable/environment-variable-validation.test.js.map +1 -0
  47. package/dist/__tests__/fixtures/demo-project/index.js +1 -1
  48. package/dist/__tests__/fixtures/demo-project/index.js.map +1 -1
  49. package/dist/__tests__/git-flags.e2e.test.d.ts +1 -0
  50. package/dist/__tests__/git-flags.e2e.test.js +133 -0
  51. package/dist/__tests__/git-flags.e2e.test.js.map +1 -0
  52. package/dist/__tests__/git.e2e.test.js +76 -25
  53. package/dist/__tests__/git.e2e.test.js.map +1 -1
  54. package/dist/__tests__/link.e2e.test.d.ts +1 -0
  55. package/dist/__tests__/link.e2e.test.js +473 -0
  56. package/dist/__tests__/link.e2e.test.js.map +1 -0
  57. package/dist/__tests__/logs.e2e.test.d.ts +1 -0
  58. package/dist/__tests__/logs.e2e.test.js +330 -0
  59. package/dist/__tests__/logs.e2e.test.js.map +1 -0
  60. package/dist/__tests__/mock-api.d.ts +47 -0
  61. package/dist/__tests__/mock-api.js +886 -0
  62. package/dist/__tests__/mock-api.js.map +1 -0
  63. package/dist/__tests__/playground/playground-configure.e2e.test.d.ts +1 -0
  64. package/dist/__tests__/playground/playground-configure.e2e.test.js +135 -0
  65. package/dist/__tests__/playground/playground-configure.e2e.test.js.map +1 -0
  66. package/dist/__tests__/playground/playground-enable-disable.e2e.test.d.ts +1 -0
  67. package/dist/__tests__/playground/playground-enable-disable.e2e.test.js +104 -0
  68. package/dist/__tests__/playground/playground-enable-disable.e2e.test.js.map +1 -0
  69. package/dist/__tests__/playground/playground-example-prompt.e2e.test.d.ts +1 -0
  70. package/dist/__tests__/playground/playground-example-prompt.e2e.test.js +282 -0
  71. package/dist/__tests__/playground/playground-example-prompt.e2e.test.js.map +1 -0
  72. package/dist/__tests__/playground/playground-headers.e2e.test.d.ts +1 -0
  73. package/dist/__tests__/playground/playground-headers.e2e.test.js +324 -0
  74. package/dist/__tests__/playground/playground-headers.e2e.test.js.map +1 -0
  75. package/dist/__tests__/playground/playground-status.e2e.test.d.ts +1 -0
  76. package/dist/__tests__/playground/playground-status.e2e.test.js +88 -0
  77. package/dist/__tests__/playground/playground-status.e2e.test.js.map +1 -0
  78. package/dist/__tests__/project-inspect.e2e.test.d.ts +1 -0
  79. package/dist/__tests__/project-inspect.e2e.test.js +84 -0
  80. package/dist/__tests__/project-inspect.e2e.test.js.map +1 -0
  81. package/dist/__tests__/project-list.e2e.test.d.ts +1 -0
  82. package/dist/__tests__/project-list.e2e.test.js +95 -0
  83. package/dist/__tests__/project-list.e2e.test.js.map +1 -0
  84. package/dist/__tests__/publish.e2e.test.d.ts +1 -0
  85. package/dist/__tests__/publish.e2e.test.js +575 -0
  86. package/dist/__tests__/publish.e2e.test.js.map +1 -0
  87. package/dist/__tests__/team-inspect.e2e.test.d.ts +1 -0
  88. package/dist/__tests__/team-inspect.e2e.test.js +86 -0
  89. package/dist/__tests__/team-inspect.e2e.test.js.map +1 -0
  90. package/dist/__tests__/team-list.e2e.test.d.ts +1 -0
  91. package/dist/__tests__/team-list.e2e.test.js +58 -0
  92. package/dist/__tests__/team-list.e2e.test.js.map +1 -0
  93. package/dist/__tests__/tunnel.e2e.test.d.ts +1 -0
  94. package/dist/__tests__/tunnel.e2e.test.js +74 -0
  95. package/dist/__tests__/tunnel.e2e.test.js.map +1 -0
  96. package/dist/__tests__/utils.d.ts +24 -5
  97. package/dist/__tests__/utils.js +144 -25
  98. package/dist/__tests__/utils.js.map +1 -1
  99. package/dist/api.d.ts +1 -2
  100. package/dist/api.js +13 -10
  101. package/dist/api.js.map +1 -1
  102. package/dist/commands/audit.d.ts +13 -0
  103. package/dist/commands/audit.js +45 -0
  104. package/dist/commands/audit.js.map +1 -0
  105. package/dist/commands/deploy.d.ts +8 -2
  106. package/dist/commands/deploy.js +73 -30
  107. package/dist/commands/deploy.js.map +1 -1
  108. package/dist/commands/deployment/inspect.d.ts +11 -0
  109. package/dist/commands/deployment/inspect.js +91 -0
  110. package/dist/commands/deployment/inspect.js.map +1 -0
  111. package/dist/commands/deployment/list.d.ts +12 -0
  112. package/dist/commands/deployment/list.js +94 -0
  113. package/dist/commands/deployment/list.js.map +1 -0
  114. package/dist/commands/deployment/logs.d.ts +12 -0
  115. package/dist/commands/deployment/logs.js +53 -0
  116. package/dist/commands/deployment/logs.js.map +1 -0
  117. package/dist/commands/environment/inspect.d.ts +13 -0
  118. package/dist/commands/environment/inspect.js +51 -0
  119. package/dist/commands/environment/inspect.js.map +1 -0
  120. package/dist/commands/environment/list.d.ts +11 -0
  121. package/dist/commands/environment/list.js +56 -0
  122. package/dist/commands/environment/list.js.map +1 -0
  123. package/dist/commands/environment-variable/add.d.ts +13 -0
  124. package/dist/commands/environment-variable/add.js +46 -0
  125. package/dist/commands/environment-variable/add.js.map +1 -0
  126. package/dist/commands/environment-variable/list.d.ts +9 -0
  127. package/dist/commands/environment-variable/list.js +45 -0
  128. package/dist/commands/environment-variable/list.js.map +1 -0
  129. package/dist/commands/environment-variable/remove.d.ts +10 -0
  130. package/dist/commands/environment-variable/remove.js +29 -0
  131. package/dist/commands/environment-variable/remove.js.map +1 -0
  132. package/dist/commands/environment-variable/update.d.ts +12 -0
  133. package/dist/commands/environment-variable/update.js +37 -0
  134. package/dist/commands/environment-variable/update.js.map +1 -0
  135. package/dist/commands/git/connect.d.ts +2 -2
  136. package/dist/commands/git/connect.js +26 -35
  137. package/dist/commands/git/connect.js.map +1 -1
  138. package/dist/commands/git/disconnect.d.ts +0 -3
  139. package/dist/commands/git/disconnect.js +14 -33
  140. package/dist/commands/git/disconnect.js.map +1 -1
  141. package/dist/commands/git.js +3 -3
  142. package/dist/commands/git.js.map +1 -1
  143. package/dist/commands/link.d.ts +17 -0
  144. package/dist/commands/link.js +102 -0
  145. package/dist/commands/link.js.map +1 -0
  146. package/dist/commands/login.d.ts +6 -0
  147. package/dist/commands/login.js +21 -0
  148. package/dist/commands/login.js.map +1 -0
  149. package/dist/commands/logout.d.ts +6 -0
  150. package/dist/commands/logout.js +20 -0
  151. package/dist/commands/logout.js.map +1 -0
  152. package/dist/commands/logs.d.ts +16 -0
  153. package/dist/commands/logs.js +123 -0
  154. package/dist/commands/logs.js.map +1 -0
  155. package/dist/commands/playground/configure.d.ts +12 -0
  156. package/dist/commands/playground/configure.js +39 -0
  157. package/dist/commands/playground/configure.js.map +1 -0
  158. package/dist/commands/playground/disable.d.ts +9 -0
  159. package/dist/commands/playground/disable.js +24 -0
  160. package/dist/commands/playground/disable.js.map +1 -0
  161. package/dist/commands/playground/enable.d.ts +9 -0
  162. package/dist/commands/playground/enable.js +24 -0
  163. package/dist/commands/playground/enable.js.map +1 -0
  164. package/dist/commands/playground/example-prompt/add.d.ts +12 -0
  165. package/dist/commands/playground/example-prompt/add.js +39 -0
  166. package/dist/commands/playground/example-prompt/add.js.map +1 -0
  167. package/dist/commands/playground/example-prompt/list.d.ts +9 -0
  168. package/dist/commands/playground/example-prompt/list.js +24 -0
  169. package/dist/commands/playground/example-prompt/list.js.map +1 -0
  170. package/dist/commands/playground/example-prompt/remove.d.ts +11 -0
  171. package/dist/commands/playground/example-prompt/remove.js +34 -0
  172. package/dist/commands/playground/example-prompt/remove.js.map +1 -0
  173. package/dist/commands/playground/headers/add.d.ts +14 -0
  174. package/dist/commands/playground/headers/add.js +49 -0
  175. package/dist/commands/playground/headers/add.js.map +1 -0
  176. package/dist/commands/playground/headers/list.d.ts +9 -0
  177. package/dist/commands/playground/headers/list.js +24 -0
  178. package/dist/commands/playground/headers/list.js.map +1 -0
  179. package/dist/commands/playground/headers/remove.d.ts +11 -0
  180. package/dist/commands/playground/headers/remove.js +34 -0
  181. package/dist/commands/playground/headers/remove.js.map +1 -0
  182. package/dist/commands/playground/status.d.ts +9 -0
  183. package/dist/commands/playground/status.js +24 -0
  184. package/dist/commands/playground/status.js.map +1 -0
  185. package/dist/commands/project/inspect.d.ts +11 -0
  186. package/dist/commands/project/inspect.js +75 -0
  187. package/dist/commands/project/inspect.js.map +1 -0
  188. package/dist/commands/project/list.d.ts +10 -0
  189. package/dist/commands/project/list.js +50 -0
  190. package/dist/commands/project/list.js.map +1 -0
  191. package/dist/commands/publish.d.ts +15 -0
  192. package/dist/commands/publish.js +44 -0
  193. package/dist/commands/publish.js.map +1 -0
  194. package/dist/commands/team/inspect.d.ts +10 -0
  195. package/dist/commands/team/inspect.js +97 -0
  196. package/dist/commands/team/inspect.js.map +1 -0
  197. package/dist/commands/team/list.d.ts +9 -0
  198. package/dist/commands/team/list.js +40 -0
  199. package/dist/commands/team/list.js.map +1 -0
  200. package/dist/commands/tunnel.d.ts +10 -0
  201. package/dist/commands/tunnel.js +137 -0
  202. package/dist/commands/tunnel.js.map +1 -0
  203. package/dist/commands/whoami.d.ts +6 -0
  204. package/dist/commands/whoami.js +13 -0
  205. package/dist/commands/whoami.js.map +1 -0
  206. package/dist/env.d.ts +5 -0
  207. package/dist/env.js +11 -0
  208. package/dist/env.js.map +1 -0
  209. package/dist/lib/agent-mode.d.ts +3 -0
  210. package/dist/lib/agent-mode.js +33 -0
  211. package/dist/lib/agent-mode.js.map +1 -0
  212. package/dist/lib/alpic-command.d.ts +9 -0
  213. package/dist/lib/alpic-command.js +32 -8
  214. package/dist/lib/alpic-command.js.map +1 -1
  215. package/dist/lib/archive.d.ts +3 -3
  216. package/dist/lib/archive.js +21 -19
  217. package/dist/lib/archive.js.map +1 -1
  218. package/dist/lib/audit.d.ts +16 -0
  219. package/dist/lib/audit.js +271 -0
  220. package/dist/lib/audit.js.map +1 -0
  221. package/dist/lib/auth/auth.d.ts +5 -0
  222. package/dist/lib/auth/auth.js +46 -0
  223. package/dist/lib/auth/auth.js.map +1 -0
  224. package/dist/lib/auth/oauth/client.d.ts +28 -0
  225. package/dist/lib/auth/oauth/client.js +116 -0
  226. package/dist/lib/auth/oauth/client.js.map +1 -0
  227. package/dist/lib/auth/oauth/constants.d.ts +2 -0
  228. package/dist/lib/auth/oauth/constants.js +3 -0
  229. package/dist/lib/auth/oauth/constants.js.map +1 -0
  230. package/dist/lib/auth/oauth/server/assets/alpic-mountain.png +0 -0
  231. package/dist/lib/auth/oauth/server/assets/authorize.html +195 -0
  232. package/dist/lib/auth/oauth/server/assets/callback.html +88 -0
  233. package/dist/lib/auth/oauth/server/index.d.ts +9 -0
  234. package/dist/lib/auth/oauth/server/index.js +128 -0
  235. package/dist/lib/auth/oauth/server/index.js.map +1 -0
  236. package/dist/lib/auth/whoami.d.ts +1 -0
  237. package/dist/lib/auth/whoami.js +45 -0
  238. package/dist/lib/auth/whoami.js.map +1 -0
  239. package/dist/lib/base-workflow.d.ts +12 -0
  240. package/dist/lib/base-workflow.js +30 -0
  241. package/dist/lib/base-workflow.js.map +1 -0
  242. package/dist/lib/config.d.ts +3 -2
  243. package/dist/lib/config.js +8 -7
  244. package/dist/lib/config.js.map +1 -1
  245. package/dist/lib/deployment.d.ts +74 -4
  246. package/dist/lib/deployment.js +125 -10
  247. package/dist/lib/deployment.js.map +1 -1
  248. package/dist/lib/environment-variable.d.ts +37 -0
  249. package/dist/lib/environment-variable.js +302 -0
  250. package/dist/lib/environment-variable.js.map +1 -0
  251. package/dist/lib/git.d.ts +13 -4
  252. package/dist/lib/git.js +68 -28
  253. package/dist/lib/git.js.map +1 -1
  254. package/dist/lib/global-store.d.ts +28 -0
  255. package/dist/lib/global-store.js +76 -0
  256. package/dist/lib/global-store.js.map +1 -0
  257. package/dist/lib/link.d.ts +85 -0
  258. package/dist/lib/link.js +469 -0
  259. package/dist/lib/link.js.map +1 -0
  260. package/dist/lib/logs.d.ts +20 -0
  261. package/dist/lib/logs.js +89 -0
  262. package/dist/lib/logs.js.map +1 -0
  263. package/dist/lib/playground.d.ts +53 -0
  264. package/dist/lib/playground.js +289 -0
  265. package/dist/lib/playground.js.map +1 -0
  266. package/dist/lib/publish.d.ts +22 -0
  267. package/dist/lib/publish.js +201 -0
  268. package/dist/lib/publish.js.map +1 -0
  269. package/dist/lib/resolve.d.ts +24 -0
  270. package/dist/lib/resolve.js +122 -0
  271. package/dist/lib/resolve.js.map +1 -0
  272. package/dist/lib/table.d.ts +8 -0
  273. package/dist/lib/table.js +27 -0
  274. package/dist/lib/table.js.map +1 -0
  275. package/dist/lib/telemetry.js +8 -7
  276. package/dist/lib/telemetry.js.map +1 -1
  277. package/dist/lib/utils.d.ts +38 -0
  278. package/dist/lib/utils.js +57 -0
  279. package/dist/lib/utils.js.map +1 -0
  280. package/dist/lib/utils.test.d.ts +1 -0
  281. package/dist/lib/utils.test.js +44 -0
  282. package/dist/lib/utils.test.js.map +1 -0
  283. package/dist/types.d.ts +1 -0
  284. package/package.json +37 -22
  285. package/dist/__tests__/mock-server.d.ts +0 -22
  286. package/dist/__tests__/mock-server.js +0 -445
  287. package/dist/__tests__/mock-server.js.map +0 -1
  288. package/dist/lib/auth.d.ts +0 -1
  289. package/dist/lib/auth.js +0 -10
  290. package/dist/lib/auth.js.map +0 -1
  291. package/dist/lib/global-config.d.ts +0 -9
  292. package/dist/lib/global-config.js +0 -48
  293. package/dist/lib/global-config.js.map +0 -1
  294. package/dist/lib/project.d.ts +0 -67
  295. package/dist/lib/project.js +0 -285
  296. package/dist/lib/project.js.map +0 -1
@@ -0,0 +1,764 @@
1
+ import { rmSync } from "node:fs";
2
+ import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
3
+ import { MockApiServer } from "./mock-api.js";
4
+ import { buildMockProject, cliSession, createConfigFile, expectSuccessfulApiCall, setupTestDirectory, } from "./utils.js";
5
+ const TEAM_ID = "mock-team-id";
6
+ const PROJECT_ID = "mock-project-id";
7
+ const ENV_ID = "mock-env-id";
8
+ const STAGING_ENV_ID = "staging-env-id";
9
+ const DEPLOYED_DEPLOYMENT = {
10
+ id: "mock-deployment-id",
11
+ status: "deployed",
12
+ sourceCommitId: "abc1234",
13
+ sourceCommitMessage: "initial deploy",
14
+ completedAt: new Date(),
15
+ };
16
+ describe("alpic audit (E2E)", () => {
17
+ let mockServer;
18
+ let serverUrl;
19
+ let cwd;
20
+ let binPath;
21
+ beforeAll(async () => {
22
+ mockServer = new MockApiServer();
23
+ serverUrl = await mockServer.start();
24
+ });
25
+ afterAll(async () => {
26
+ await mockServer.stop();
27
+ });
28
+ beforeEach(async () => {
29
+ mockServer.reset();
30
+ const setup = await setupTestDirectory();
31
+ cwd = setup.cwd;
32
+ binPath = setup.binPath;
33
+ mockServer.addProject(buildMockProject({
34
+ projectId: PROJECT_ID,
35
+ teamId: TEAM_ID,
36
+ projectName: "my-project",
37
+ environmentId: ENV_ID,
38
+ environmentName: "production",
39
+ latestDeployment: DEPLOYED_DEPLOYMENT,
40
+ }));
41
+ });
42
+ afterEach(() => {
43
+ if (cwd) {
44
+ rmSync(cwd, { recursive: true, force: true });
45
+ }
46
+ });
47
+ describe("standalone mode (--url)", () => {
48
+ it("runs audit with --url and no project association", async () => {
49
+ const { exitCode } = await cliSession(process.execPath, [binPath, "audit", "--url", "https://example.com/mcp"], {
50
+ cwd,
51
+ env: {
52
+ ALPIC_API_BASE_URL: serverUrl,
53
+ ALPIC_API_KEY: "test-api-key",
54
+ },
55
+ }, async (cli) => {
56
+ await cli.expect("Beacon Report");
57
+ });
58
+ expect(exitCode).toBe(0);
59
+ const createCall = mockServer.getLastCall("POST", "/v1/beacon/audits");
60
+ expectSuccessfulApiCall(createCall, (call) => {
61
+ expect(call.input).toMatchObject({ targetUrl: "https://example.com/mcp", excludeCategories: ["e2e"] });
62
+ expect(call.input.projectId).toBeUndefined();
63
+ });
64
+ });
65
+ it("errors when --url and --project-id are both provided", async () => {
66
+ const { exitCode } = await cliSession(process.execPath, [binPath, "audit", "--url", "https://example.com/mcp", "--project-id", PROJECT_ID], {
67
+ cwd,
68
+ env: {
69
+ ALPIC_API_BASE_URL: serverUrl,
70
+ ALPIC_API_KEY: "test-api-key",
71
+ },
72
+ }, async (cli) => {
73
+ await cli.expect("--url and --project-id cannot be used together");
74
+ });
75
+ expect(exitCode).toBe(1);
76
+ });
77
+ it("errors when --team-id is used without --url", async () => {
78
+ const { exitCode } = await cliSession(process.execPath, [binPath, "audit", "--team-id", TEAM_ID], {
79
+ cwd,
80
+ env: {
81
+ ALPIC_API_BASE_URL: serverUrl,
82
+ ALPIC_API_KEY: "test-api-key",
83
+ },
84
+ }, async (cli) => {
85
+ await cli.expect("--team-id can only be used with --url");
86
+ });
87
+ expect(exitCode).toBe(1);
88
+ });
89
+ });
90
+ describe("project mode", () => {
91
+ it("uses linked project config after confirmation", async () => {
92
+ createConfigFile(cwd, PROJECT_ID, TEAM_ID, "my-project", ENV_ID, "production", "Mock Team");
93
+ const { exitCode } = await cliSession(process.execPath, [binPath, "audit"], {
94
+ cwd,
95
+ env: {
96
+ ALPIC_API_BASE_URL: serverUrl,
97
+ ALPIC_API_KEY: "test-api-key",
98
+ },
99
+ }, async (cli) => {
100
+ await cli.expect("Using project config from .alpic");
101
+ await cli.expect('Run audit for project "my-project"?');
102
+ await cli.send("");
103
+ await cli.expect("Beacon Report");
104
+ });
105
+ expect(exitCode).toBe(0);
106
+ const createCall = mockServer.getLastCall("POST", "/v1/beacon/audits");
107
+ expectSuccessfulApiCall(createCall, (call) => {
108
+ expect(call.input).toMatchObject({
109
+ teamId: TEAM_ID,
110
+ projectId: PROJECT_ID,
111
+ });
112
+ });
113
+ });
114
+ it("uses linked project config without prompt in --non-interactive mode", async () => {
115
+ createConfigFile(cwd, PROJECT_ID, TEAM_ID, "my-project", ENV_ID, "production", "Mock Team");
116
+ const { exitCode, output } = await cliSession(process.execPath, [binPath, "audit", "--non-interactive"], {
117
+ cwd,
118
+ env: {
119
+ ALPIC_API_BASE_URL: serverUrl,
120
+ ALPIC_API_KEY: "test-api-key",
121
+ },
122
+ }, async (cli) => {
123
+ await cli.expect("Beacon Report");
124
+ });
125
+ expect(exitCode).toBe(0);
126
+ expect(output).not.toContain("Run audit for project");
127
+ });
128
+ it("uses explicit --project-id flag", async () => {
129
+ const { exitCode, output } = await cliSession(process.execPath, [binPath, "audit", "--project-id", PROJECT_ID], {
130
+ cwd,
131
+ env: {
132
+ ALPIC_API_BASE_URL: serverUrl,
133
+ ALPIC_API_KEY: "test-api-key",
134
+ },
135
+ }, async (cli) => {
136
+ await cli.expect("Beacon Report");
137
+ });
138
+ expect(exitCode).toBe(0);
139
+ expect(output).not.toContain("Using project config from .alpic");
140
+ const createCall = mockServer.getLastCall("POST", "/v1/beacon/audits");
141
+ expectSuccessfulApiCall(createCall, (call) => {
142
+ expect(call.input).toMatchObject({
143
+ projectId: PROJECT_ID,
144
+ teamId: TEAM_ID,
145
+ });
146
+ });
147
+ });
148
+ it("prompts for team and project selection in interactive mode without config", async () => {
149
+ const { exitCode } = await cliSession(process.execPath, [binPath, "audit"], {
150
+ cwd,
151
+ env: {
152
+ ALPIC_API_BASE_URL: serverUrl,
153
+ ALPIC_API_KEY: "test-api-key",
154
+ },
155
+ }, async (cli) => {
156
+ await cli.expect("Using team");
157
+ await cli.expect("Choose a project");
158
+ await cli.send("");
159
+ await cli.expect("Beacon Report");
160
+ });
161
+ expect(exitCode).toBe(0);
162
+ });
163
+ it("uses --environment-id to audit a specific environment", async () => {
164
+ const multiEnvProject = {
165
+ ...buildMockProject({
166
+ projectId: PROJECT_ID,
167
+ teamId: TEAM_ID,
168
+ projectName: "my-project",
169
+ environmentId: ENV_ID,
170
+ environmentName: "production",
171
+ latestDeployment: DEPLOYED_DEPLOYMENT,
172
+ }),
173
+ environments: [
174
+ {
175
+ id: ENV_ID,
176
+ name: "production",
177
+ sourceBranch: null,
178
+ mcpServerUrl: "https://mcp-production.alpic.ai",
179
+ createdAt: new Date(),
180
+ projectId: PROJECT_ID,
181
+ latestDeployment: DEPLOYED_DEPLOYMENT,
182
+ },
183
+ {
184
+ id: STAGING_ENV_ID,
185
+ name: "staging",
186
+ sourceBranch: "develop",
187
+ mcpServerUrl: "https://mcp-staging.alpic.ai",
188
+ createdAt: new Date(),
189
+ projectId: PROJECT_ID,
190
+ latestDeployment: null,
191
+ },
192
+ ],
193
+ };
194
+ mockServer.addProject(multiEnvProject);
195
+ const { exitCode } = await cliSession(process.execPath, [binPath, "audit", "--project-id", PROJECT_ID, "--environment-id", STAGING_ENV_ID], {
196
+ cwd,
197
+ env: {
198
+ ALPIC_API_BASE_URL: serverUrl,
199
+ ALPIC_API_KEY: "test-api-key",
200
+ },
201
+ }, async (cli) => {
202
+ await cli.expect("Beacon Report");
203
+ });
204
+ expect(exitCode).toBe(0);
205
+ const createCall = mockServer.getLastCall("POST", "/v1/beacon/audits");
206
+ expectSuccessfulApiCall(createCall, (call) => {
207
+ expect(call.input).toMatchObject({
208
+ targetUrl: "https://mcp-staging.alpic.ai",
209
+ projectId: PROJECT_ID,
210
+ });
211
+ });
212
+ });
213
+ it("errors when --environment-id is used with --url", async () => {
214
+ const { exitCode } = await cliSession(process.execPath, [binPath, "audit", "--url", "https://example.com/mcp", "--environment-id", ENV_ID], {
215
+ cwd,
216
+ env: {
217
+ ALPIC_API_BASE_URL: serverUrl,
218
+ ALPIC_API_KEY: "test-api-key",
219
+ },
220
+ }, async (cli) => {
221
+ await cli.expect("--environment-id cannot be used with --url");
222
+ });
223
+ expect(exitCode).toBe(1);
224
+ });
225
+ it("hides projects without successful deployments in interactive selection", async () => {
226
+ mockServer.reset();
227
+ mockServer.addProject(buildMockProject({
228
+ projectId: "deployed-project",
229
+ teamId: TEAM_ID,
230
+ projectName: "deployed-project",
231
+ environmentId: "deployed-env",
232
+ environmentName: "production",
233
+ latestDeployment: DEPLOYED_DEPLOYMENT,
234
+ }));
235
+ mockServer.addProject(buildMockProject({
236
+ projectId: "undeployed-project",
237
+ teamId: TEAM_ID,
238
+ projectName: "undeployed-project",
239
+ environmentId: "undeployed-env",
240
+ environmentName: "production",
241
+ }));
242
+ const { exitCode, output } = await cliSession(process.execPath, [binPath, "audit"], {
243
+ cwd,
244
+ env: {
245
+ ALPIC_API_BASE_URL: serverUrl,
246
+ ALPIC_API_KEY: "test-api-key",
247
+ },
248
+ }, async (cli) => {
249
+ await cli.expect("Choose a project");
250
+ await cli.send("");
251
+ await cli.expect("Beacon Report");
252
+ });
253
+ expect(exitCode).toBe(0);
254
+ expect(output).toContain("deployed-project");
255
+ expect(output).not.toContain("undeployed-project");
256
+ });
257
+ it("errors when no projects have successful deployments in interactive mode", async () => {
258
+ mockServer.reset();
259
+ mockServer.addProject(buildMockProject({
260
+ projectId: "failed-project",
261
+ teamId: TEAM_ID,
262
+ projectName: "failed-project",
263
+ environmentId: "failed-env",
264
+ environmentName: "production",
265
+ }));
266
+ const { exitCode } = await cliSession(process.execPath, [binPath, "audit"], {
267
+ cwd,
268
+ env: {
269
+ ALPIC_API_BASE_URL: serverUrl,
270
+ ALPIC_API_KEY: "test-api-key",
271
+ },
272
+ }, async (cli) => {
273
+ await cli.expect("No projects with a successful deployment found");
274
+ });
275
+ expect(exitCode).toBe(1);
276
+ });
277
+ it("only shows deployed environments when selecting interactively", async () => {
278
+ mockServer.reset();
279
+ const multiEnvProject = {
280
+ ...buildMockProject({
281
+ projectId: PROJECT_ID,
282
+ teamId: TEAM_ID,
283
+ projectName: "my-project",
284
+ environmentId: ENV_ID,
285
+ environmentName: "production",
286
+ latestDeployment: DEPLOYED_DEPLOYMENT,
287
+ }),
288
+ environments: [
289
+ {
290
+ id: ENV_ID,
291
+ name: "production",
292
+ sourceBranch: null,
293
+ mcpServerUrl: "https://mcp-production.alpic.ai",
294
+ createdAt: new Date(),
295
+ projectId: PROJECT_ID,
296
+ latestDeployment: DEPLOYED_DEPLOYMENT,
297
+ },
298
+ {
299
+ id: STAGING_ENV_ID,
300
+ name: "staging",
301
+ sourceBranch: "develop",
302
+ mcpServerUrl: "https://mcp-staging.alpic.ai",
303
+ createdAt: new Date(),
304
+ projectId: PROJECT_ID,
305
+ latestDeployment: null,
306
+ },
307
+ ],
308
+ };
309
+ mockServer.addProject(multiEnvProject);
310
+ const { exitCode, output } = await cliSession(process.execPath, [binPath, "audit", "--project-id", PROJECT_ID], {
311
+ cwd,
312
+ env: {
313
+ ALPIC_API_BASE_URL: serverUrl,
314
+ ALPIC_API_KEY: "test-api-key",
315
+ },
316
+ }, async (cli) => {
317
+ await cli.expect('Using environment "production"');
318
+ await cli.expect("Beacon Report");
319
+ });
320
+ expect(exitCode).toBe(0);
321
+ expect(output).not.toContain("staging");
322
+ });
323
+ it("errors in --non-interactive mode when production environment is not deployed but others are", async () => {
324
+ mockServer.reset();
325
+ const multiEnvProject = {
326
+ ...buildMockProject({
327
+ projectId: PROJECT_ID,
328
+ teamId: TEAM_ID,
329
+ projectName: "my-project",
330
+ environmentId: ENV_ID,
331
+ environmentName: "production",
332
+ }),
333
+ environments: [
334
+ {
335
+ id: ENV_ID,
336
+ name: "production",
337
+ sourceBranch: null,
338
+ mcpServerUrl: "https://mcp-production.alpic.ai",
339
+ createdAt: new Date(),
340
+ projectId: PROJECT_ID,
341
+ latestDeployment: null,
342
+ },
343
+ {
344
+ id: STAGING_ENV_ID,
345
+ name: "staging",
346
+ sourceBranch: "develop",
347
+ mcpServerUrl: "https://mcp-staging.alpic.ai",
348
+ createdAt: new Date(),
349
+ projectId: PROJECT_ID,
350
+ latestDeployment: DEPLOYED_DEPLOYMENT,
351
+ },
352
+ {
353
+ id: "feature-env-id",
354
+ name: "feature-x",
355
+ sourceBranch: "feature-x",
356
+ mcpServerUrl: "https://mcp-feature.alpic.ai",
357
+ createdAt: new Date(),
358
+ projectId: PROJECT_ID,
359
+ latestDeployment: DEPLOYED_DEPLOYMENT,
360
+ },
361
+ ],
362
+ };
363
+ mockServer.addProject(multiEnvProject);
364
+ const { exitCode } = await cliSession(process.execPath, [binPath, "audit", "--project-id", PROJECT_ID, "--non-interactive"], {
365
+ cwd,
366
+ env: {
367
+ ALPIC_API_BASE_URL: serverUrl,
368
+ ALPIC_API_KEY: "test-api-key",
369
+ },
370
+ }, async (cli) => {
371
+ await cli.expect("Multiple environments found. Use --environment-id to specify which one to audit.");
372
+ });
373
+ expect(exitCode).toBe(1);
374
+ });
375
+ it("--environment-id bypasses deployment filter and audits an undeployed environment", async () => {
376
+ mockServer.reset();
377
+ mockServer.addProject(buildMockProject({
378
+ projectId: PROJECT_ID,
379
+ teamId: TEAM_ID,
380
+ projectName: "my-project",
381
+ environmentId: ENV_ID,
382
+ environmentName: "production",
383
+ }));
384
+ const { exitCode } = await cliSession(process.execPath, [binPath, "audit", "--project-id", PROJECT_ID, "--environment-id", ENV_ID], {
385
+ cwd,
386
+ env: {
387
+ ALPIC_API_BASE_URL: serverUrl,
388
+ ALPIC_API_KEY: "test-api-key",
389
+ },
390
+ }, async (cli) => {
391
+ await cli.expect("Beacon Report");
392
+ });
393
+ expect(exitCode).toBe(0);
394
+ const createCall = mockServer.getLastCall("POST", "/v1/beacon/audits");
395
+ expectSuccessfulApiCall(createCall, (call) => {
396
+ expect(call.input).toMatchObject({ projectId: PROJECT_ID });
397
+ });
398
+ });
399
+ it("errors in --non-interactive mode without flags or config", async () => {
400
+ const { exitCode } = await cliSession(process.execPath, [binPath, "audit", "--non-interactive"], {
401
+ cwd,
402
+ env: {
403
+ ALPIC_API_BASE_URL: serverUrl,
404
+ ALPIC_API_KEY: "test-api-key",
405
+ },
406
+ }, async (cli) => {
407
+ await cli.expect("Either --url or --project-id is required");
408
+ });
409
+ expect(exitCode).toBe(1);
410
+ });
411
+ });
412
+ describe("audit lifecycle", () => {
413
+ it("polls until audit completes", async () => {
414
+ const pendingResponse = {
415
+ id: "mock-analysis-id",
416
+ targetUrl: "https://example.com/mcp",
417
+ status: "pending",
418
+ durationMs: null,
419
+ createdAt: new Date(),
420
+ report: null,
421
+ };
422
+ const completedResponse = {
423
+ id: "mock-analysis-id",
424
+ targetUrl: "https://example.com/mcp",
425
+ status: "completed",
426
+ durationMs: 1234,
427
+ createdAt: new Date(),
428
+ report: {
429
+ schemaVersion: "v20260224",
430
+ auditId: "mock-analysis-id",
431
+ targetUrl: "https://example.com/mcp",
432
+ startedAt: new Date().toISOString(),
433
+ completedAt: new Date().toISOString(),
434
+ durationMs: 1234,
435
+ results: [],
436
+ requiresAuth: false,
437
+ hasViewSupport: false,
438
+ isReadyForPlatform: { chatgpt: true, claudeai: true },
439
+ },
440
+ };
441
+ mockServer.setBeaconGetResponses([pendingResponse, pendingResponse, completedResponse]);
442
+ const { exitCode } = await cliSession(process.execPath, [binPath, "audit", "--url", "https://example.com/mcp"], {
443
+ cwd,
444
+ env: {
445
+ ALPIC_API_BASE_URL: serverUrl,
446
+ ALPIC_API_KEY: "test-api-key",
447
+ },
448
+ }, async (cli) => {
449
+ await cli.expect("Beacon Report");
450
+ });
451
+ expect(exitCode).toBe(0);
452
+ const getCalls = mockServer.getCalls("GET", "/v1/beacon/audits");
453
+ expect(getCalls.length).toBeGreaterThanOrEqual(3);
454
+ }, 15_000);
455
+ it("handles failed audit", async () => {
456
+ mockServer.setBeaconGetResponses([
457
+ {
458
+ id: "mock-analysis-id",
459
+ targetUrl: "https://example.com/mcp",
460
+ status: "failed",
461
+ durationMs: null,
462
+ createdAt: new Date(),
463
+ report: null,
464
+ },
465
+ ]);
466
+ const { exitCode } = await cliSession(process.execPath, [binPath, "audit", "--url", "https://example.com/mcp"], {
467
+ cwd,
468
+ env: {
469
+ ALPIC_API_BASE_URL: serverUrl,
470
+ ALPIC_API_KEY: "test-api-key",
471
+ },
472
+ }, async (cli) => {
473
+ await cli.expect("The audit failed");
474
+ });
475
+ expect(exitCode).toBe(1);
476
+ });
477
+ });
478
+ describe("report rendering", () => {
479
+ it("renders errors and warnings from check results", async () => {
480
+ mockServer.setBeaconGetResponses([
481
+ {
482
+ id: "mock-analysis-id",
483
+ targetUrl: "https://example.com/mcp",
484
+ status: "completed",
485
+ durationMs: 2000,
486
+ createdAt: new Date(),
487
+ report: {
488
+ schemaVersion: "v20260224",
489
+ auditId: "mock-analysis-id",
490
+ targetUrl: "https://example.com/mcp",
491
+ startedAt: new Date().toISOString(),
492
+ completedAt: new Date().toISOString(),
493
+ durationMs: 2000,
494
+ results: [
495
+ {
496
+ checkId: "check-pass",
497
+ checkName: "Server Responds",
498
+ description: "Check server connectivity",
499
+ status: "pass",
500
+ message: "Server is reachable",
501
+ severity: "error",
502
+ category: "connectivity",
503
+ scope: "server",
504
+ durationMs: 100,
505
+ },
506
+ {
507
+ checkId: "check-error",
508
+ checkName: "Tool Description",
509
+ description: "Check tool descriptions",
510
+ status: "fail",
511
+ message: "Missing tool description",
512
+ severity: "error",
513
+ category: "tool-metadata",
514
+ scope: "server",
515
+ durationMs: 50,
516
+ hint: { text: "Add a description to your tool" },
517
+ },
518
+ {
519
+ checkId: "check-warning",
520
+ checkName: "Response Time",
521
+ description: "Check response time",
522
+ status: "fail",
523
+ message: "Slow response time",
524
+ severity: "warning",
525
+ category: "performance",
526
+ scope: "server",
527
+ durationMs: 200,
528
+ },
529
+ ],
530
+ requiresAuth: false,
531
+ hasViewSupport: false,
532
+ isReadyForPlatform: { chatgpt: false, claudeai: true },
533
+ },
534
+ },
535
+ ]);
536
+ const { exitCode, output } = await cliSession(process.execPath, [binPath, "audit", "--url", "https://example.com/mcp"], {
537
+ cwd,
538
+ env: {
539
+ ALPIC_API_BASE_URL: serverUrl,
540
+ ALPIC_API_KEY: "test-api-key",
541
+ },
542
+ }, async (cli) => {
543
+ await cli.expect("Beacon Report");
544
+ });
545
+ expect(exitCode).toBe(1);
546
+ expect(output).toContain("1/3");
547
+ expect(output).toContain("Missing tool description");
548
+ expect(output).toContain("Add a description to your tool");
549
+ expect(output).toContain("Slow response time");
550
+ expect(output).toContain("1 error");
551
+ expect(output).toContain("1 warning");
552
+ });
553
+ it("shows auth required message and skips report when server requires authentication", async () => {
554
+ mockServer.setBeaconGetResponses([
555
+ {
556
+ id: "mock-analysis-id",
557
+ targetUrl: "https://example.com/mcp",
558
+ status: "completed",
559
+ durationMs: 500,
560
+ createdAt: new Date(),
561
+ report: {
562
+ schemaVersion: "v20260224",
563
+ auditId: "mock-analysis-id",
564
+ targetUrl: "https://example.com/mcp",
565
+ startedAt: new Date().toISOString(),
566
+ completedAt: new Date().toISOString(),
567
+ durationMs: 500,
568
+ results: [
569
+ {
570
+ checkId: "server-responds",
571
+ checkName: "Server Responds",
572
+ description: "Check server connectivity",
573
+ status: "skip",
574
+ message: "Server requires authentication",
575
+ skipReason: "The server returned HTTP 401",
576
+ severity: "error",
577
+ category: "connectivity",
578
+ scope: "server",
579
+ durationMs: 100,
580
+ },
581
+ ],
582
+ requiresAuth: true,
583
+ hasViewSupport: false,
584
+ isReadyForPlatform: { chatgpt: false, claudeai: false },
585
+ },
586
+ },
587
+ ]);
588
+ const { exitCode, output } = await cliSession(process.execPath, [binPath, "audit", "--url", "https://example.com/mcp"], {
589
+ cwd,
590
+ env: {
591
+ ALPIC_API_BASE_URL: serverUrl,
592
+ ALPIC_API_KEY: "test-api-key",
593
+ },
594
+ }, async (cli) => {
595
+ await cli.expect("requires credentials");
596
+ });
597
+ expect(exitCode).toBe(0);
598
+ expect(output).toContain("requires credentials to connect");
599
+ expect(output).toContain("all checks have been skipped");
600
+ expect(output).not.toContain("Beacon Report");
601
+ });
602
+ });
603
+ describe("report snapshot", () => {
604
+ it("matches snapshot for a report with errors, warnings, and skipped checks", async () => {
605
+ mockServer.setBeaconGetResponses([
606
+ {
607
+ id: "mock-analysis-id",
608
+ targetUrl: "https://example.com/mcp",
609
+ status: "completed",
610
+ durationMs: 2000,
611
+ createdAt: new Date(),
612
+ report: {
613
+ schemaVersion: "v20260224",
614
+ auditId: "mock-analysis-id",
615
+ targetUrl: "https://example.com/mcp",
616
+ startedAt: "2026-03-01T00:00:00.000Z",
617
+ completedAt: "2026-03-01T00:00:02.000Z",
618
+ durationMs: 2000,
619
+ results: [
620
+ {
621
+ checkId: "connectivity-check",
622
+ checkName: "Server Responds",
623
+ description: "Check server connectivity",
624
+ status: "pass",
625
+ message: "Server is reachable",
626
+ severity: "error",
627
+ category: "connectivity",
628
+ scope: "server",
629
+ durationMs: 100,
630
+ },
631
+ {
632
+ checkId: "tool-description-check",
633
+ checkName: "Tool Description",
634
+ description: "Check tool descriptions",
635
+ status: "fail",
636
+ message: "Missing tool description",
637
+ severity: "error",
638
+ category: "tool-metadata",
639
+ scope: "server",
640
+ durationMs: 50,
641
+ hint: { text: "Add a description to your tool" },
642
+ },
643
+ {
644
+ checkId: "response-time-check",
645
+ checkName: "Response Time",
646
+ description: "Check response time",
647
+ status: "fail",
648
+ message: "Slow response time",
649
+ severity: "warning",
650
+ category: "performance",
651
+ scope: "server",
652
+ durationMs: 200,
653
+ },
654
+ {
655
+ checkId: "view-check",
656
+ checkName: "View Support",
657
+ description: "Check if the server has view support",
658
+ status: "skip",
659
+ message: "View support check",
660
+ skipReason: "No view resources found",
661
+ severity: "info",
662
+ category: "resource-metadata",
663
+ scope: "view",
664
+ durationMs: 0,
665
+ },
666
+ ],
667
+ requiresAuth: false,
668
+ hasViewSupport: false,
669
+ isReadyForPlatform: { chatgpt: false, claudeai: true },
670
+ },
671
+ },
672
+ ]);
673
+ const { exitCode, output } = await cliSession(process.execPath, [binPath, "audit", "--url", "https://example.com/mcp"], {
674
+ cwd,
675
+ env: {
676
+ ALPIC_API_BASE_URL: serverUrl,
677
+ ALPIC_API_KEY: "test-api-key",
678
+ },
679
+ }, async (cli) => {
680
+ await cli.expect("Beacon Report");
681
+ });
682
+ expect(exitCode).toBe(1);
683
+ const startIdx = output.indexOf("Beacon Report");
684
+ expect(startIdx).toBeGreaterThanOrEqual(0);
685
+ expect(output.slice(startIdx)).toMatchSnapshot();
686
+ });
687
+ it("matches snapshot for a clean report with all checks passed", async () => {
688
+ mockServer.setBeaconGetResponses([
689
+ {
690
+ id: "mock-analysis-id",
691
+ targetUrl: "https://example.com/mcp",
692
+ status: "completed",
693
+ durationMs: 500,
694
+ createdAt: new Date(),
695
+ report: {
696
+ schemaVersion: "v20260224",
697
+ auditId: "mock-analysis-id",
698
+ targetUrl: "https://example.com/mcp",
699
+ startedAt: "2026-03-01T00:00:00.000Z",
700
+ completedAt: "2026-03-01T00:00:00.500Z",
701
+ durationMs: 500,
702
+ results: [
703
+ {
704
+ checkId: "connectivity-check",
705
+ checkName: "Server Responds",
706
+ description: "Check server connectivity",
707
+ status: "pass",
708
+ message: "Server is reachable",
709
+ severity: "error",
710
+ category: "connectivity",
711
+ scope: "server",
712
+ durationMs: 100,
713
+ },
714
+ {
715
+ checkId: "tool-description-check",
716
+ checkName: "Tool Description",
717
+ description: "Check tool descriptions",
718
+ status: "pass",
719
+ message: "Tool descriptions are present",
720
+ severity: "error",
721
+ category: "tool-metadata",
722
+ scope: "server",
723
+ durationMs: 50,
724
+ },
725
+ ],
726
+ requiresAuth: false,
727
+ hasViewSupport: false,
728
+ isReadyForPlatform: { chatgpt: true, claudeai: true },
729
+ },
730
+ },
731
+ ]);
732
+ const { exitCode, output } = await cliSession(process.execPath, [binPath, "audit", "--url", "https://example.com/mcp"], {
733
+ cwd,
734
+ env: {
735
+ ALPIC_API_BASE_URL: serverUrl,
736
+ ALPIC_API_KEY: "test-api-key",
737
+ },
738
+ }, async (cli) => {
739
+ await cli.expect("Beacon Report");
740
+ });
741
+ expect(exitCode).toBe(0);
742
+ const startIdx = output.indexOf("Beacon Report");
743
+ expect(startIdx).toBeGreaterThanOrEqual(0);
744
+ expect(output.slice(startIdx)).toMatchSnapshot();
745
+ });
746
+ });
747
+ describe("output", () => {
748
+ it("outputs JSON with --json flag", async () => {
749
+ const { exitCode, output } = await cliSession(process.execPath, [binPath, "audit", "--url", "https://example.com/mcp", "--json"], {
750
+ cwd,
751
+ env: {
752
+ ALPIC_API_BASE_URL: serverUrl,
753
+ ALPIC_API_KEY: "test-api-key",
754
+ },
755
+ }, async (cli) => {
756
+ await cli.expect("schemaVersion");
757
+ });
758
+ expect(exitCode).toBe(0);
759
+ expect(output).toContain('"schemaVersion"');
760
+ expect(output).not.toContain("Beacon Report");
761
+ });
762
+ });
763
+ });
764
+ //# sourceMappingURL=audit.e2e.test.js.map