alpic 0.0.0-staging.2ab71bc → 0.0.0-staging.2ba052d

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 (271) hide show
  1. package/README.md +40 -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 +561 -0
  8. package/dist/__tests__/audit.e2e.test.js.map +1 -0
  9. package/dist/__tests__/auth.e2e.test.js +38 -18
  10. package/dist/__tests__/auth.e2e.test.js.map +1 -1
  11. package/dist/__tests__/deploy-flags.e2e.test.d.ts +1 -0
  12. package/dist/__tests__/deploy-flags.e2e.test.js +228 -0
  13. package/dist/__tests__/deploy-flags.e2e.test.js.map +1 -0
  14. package/dist/__tests__/deploy.e2e.test.js +33 -66
  15. package/dist/__tests__/deploy.e2e.test.js.map +1 -1
  16. package/dist/__tests__/deployment-inspect.e2e.test.d.ts +1 -0
  17. package/dist/__tests__/deployment-inspect.e2e.test.js +119 -0
  18. package/dist/__tests__/deployment-inspect.e2e.test.js.map +1 -0
  19. package/dist/__tests__/deployment-list.e2e.test.d.ts +1 -0
  20. package/dist/__tests__/deployment-list.e2e.test.js +121 -0
  21. package/dist/__tests__/deployment-list.e2e.test.js.map +1 -0
  22. package/dist/__tests__/deployment-logs.e2e.test.d.ts +1 -0
  23. package/dist/__tests__/deployment-logs.e2e.test.js +262 -0
  24. package/dist/__tests__/deployment-logs.e2e.test.js.map +1 -0
  25. package/dist/__tests__/environment-inspect.e2e.test.d.ts +1 -0
  26. package/dist/__tests__/environment-inspect.e2e.test.js +78 -0
  27. package/dist/__tests__/environment-inspect.e2e.test.js.map +1 -0
  28. package/dist/__tests__/environment-list.e2e.test.d.ts +1 -0
  29. package/dist/__tests__/environment-list.e2e.test.js +63 -0
  30. package/dist/__tests__/environment-list.e2e.test.js.map +1 -0
  31. package/dist/__tests__/environment-variable/environment-variable-add.e2e.test.d.ts +1 -0
  32. package/dist/__tests__/environment-variable/environment-variable-add.e2e.test.js +277 -0
  33. package/dist/__tests__/environment-variable/environment-variable-add.e2e.test.js.map +1 -0
  34. package/dist/__tests__/environment-variable/environment-variable-list.e2e.test.d.ts +1 -0
  35. package/dist/__tests__/environment-variable/environment-variable-list.e2e.test.js +146 -0
  36. package/dist/__tests__/environment-variable/environment-variable-list.e2e.test.js.map +1 -0
  37. package/dist/__tests__/environment-variable/environment-variable-remove.e2e.test.d.ts +1 -0
  38. package/dist/__tests__/environment-variable/environment-variable-remove.e2e.test.js +148 -0
  39. package/dist/__tests__/environment-variable/environment-variable-remove.e2e.test.js.map +1 -0
  40. package/dist/__tests__/environment-variable/environment-variable-update.e2e.test.d.ts +1 -0
  41. package/dist/__tests__/environment-variable/environment-variable-update.e2e.test.js +348 -0
  42. package/dist/__tests__/environment-variable/environment-variable-update.e2e.test.js.map +1 -0
  43. package/dist/__tests__/environment-variable/environment-variable-validation.test.d.ts +1 -0
  44. package/dist/__tests__/environment-variable/environment-variable-validation.test.js +20 -0
  45. package/dist/__tests__/environment-variable/environment-variable-validation.test.js.map +1 -0
  46. package/dist/__tests__/fixtures/demo-project/index.js +1 -1
  47. package/dist/__tests__/fixtures/demo-project/index.js.map +1 -1
  48. package/dist/__tests__/git-flags.e2e.test.d.ts +1 -0
  49. package/dist/__tests__/git-flags.e2e.test.js +129 -0
  50. package/dist/__tests__/git-flags.e2e.test.js.map +1 -0
  51. package/dist/__tests__/git.e2e.test.js +25 -17
  52. package/dist/__tests__/git.e2e.test.js.map +1 -1
  53. package/dist/__tests__/link.e2e.test.d.ts +1 -0
  54. package/dist/__tests__/link.e2e.test.js +282 -0
  55. package/dist/__tests__/link.e2e.test.js.map +1 -0
  56. package/dist/__tests__/logs.e2e.test.d.ts +1 -0
  57. package/dist/__tests__/logs.e2e.test.js +230 -0
  58. package/dist/__tests__/logs.e2e.test.js.map +1 -0
  59. package/dist/__tests__/mock-server.d.ts +25 -0
  60. package/dist/__tests__/mock-server.js +386 -23
  61. package/dist/__tests__/mock-server.js.map +1 -1
  62. package/dist/__tests__/playground/playground-configure.e2e.test.d.ts +1 -0
  63. package/dist/__tests__/playground/playground-configure.e2e.test.js +135 -0
  64. package/dist/__tests__/playground/playground-configure.e2e.test.js.map +1 -0
  65. package/dist/__tests__/playground/playground-enable-disable.e2e.test.d.ts +1 -0
  66. package/dist/__tests__/playground/playground-enable-disable.e2e.test.js +104 -0
  67. package/dist/__tests__/playground/playground-enable-disable.e2e.test.js.map +1 -0
  68. package/dist/__tests__/playground/playground-example-prompt.e2e.test.d.ts +1 -0
  69. package/dist/__tests__/playground/playground-example-prompt.e2e.test.js +282 -0
  70. package/dist/__tests__/playground/playground-example-prompt.e2e.test.js.map +1 -0
  71. package/dist/__tests__/playground/playground-headers.e2e.test.d.ts +1 -0
  72. package/dist/__tests__/playground/playground-headers.e2e.test.js +324 -0
  73. package/dist/__tests__/playground/playground-headers.e2e.test.js.map +1 -0
  74. package/dist/__tests__/playground/playground-status.e2e.test.d.ts +1 -0
  75. package/dist/__tests__/playground/playground-status.e2e.test.js +88 -0
  76. package/dist/__tests__/playground/playground-status.e2e.test.js.map +1 -0
  77. package/dist/__tests__/project-inspect.e2e.test.d.ts +1 -0
  78. package/dist/__tests__/project-inspect.e2e.test.js +83 -0
  79. package/dist/__tests__/project-inspect.e2e.test.js.map +1 -0
  80. package/dist/__tests__/project-list.e2e.test.d.ts +1 -0
  81. package/dist/__tests__/project-list.e2e.test.js +95 -0
  82. package/dist/__tests__/project-list.e2e.test.js.map +1 -0
  83. package/dist/__tests__/publish.e2e.test.d.ts +1 -0
  84. package/dist/__tests__/publish.e2e.test.js +575 -0
  85. package/dist/__tests__/publish.e2e.test.js.map +1 -0
  86. package/dist/__tests__/team-inspect.e2e.test.d.ts +1 -0
  87. package/dist/__tests__/team-inspect.e2e.test.js +86 -0
  88. package/dist/__tests__/team-inspect.e2e.test.js.map +1 -0
  89. package/dist/__tests__/team-list.e2e.test.d.ts +1 -0
  90. package/dist/__tests__/team-list.e2e.test.js +58 -0
  91. package/dist/__tests__/team-list.e2e.test.js.map +1 -0
  92. package/dist/__tests__/tunnel.e2e.test.d.ts +1 -0
  93. package/dist/__tests__/tunnel.e2e.test.js +66 -0
  94. package/dist/__tests__/tunnel.e2e.test.js.map +1 -0
  95. package/dist/__tests__/utils.d.ts +17 -5
  96. package/dist/__tests__/utils.js +120 -26
  97. package/dist/__tests__/utils.js.map +1 -1
  98. package/dist/api.d.ts +1 -1
  99. package/dist/api.js +10 -3
  100. package/dist/api.js.map +1 -1
  101. package/dist/commands/audit.d.ts +13 -0
  102. package/dist/commands/audit.js +45 -0
  103. package/dist/commands/audit.js.map +1 -0
  104. package/dist/commands/deploy.d.ts +7 -2
  105. package/dist/commands/deploy.js +67 -25
  106. package/dist/commands/deploy.js.map +1 -1
  107. package/dist/commands/deployment/inspect.d.ts +11 -0
  108. package/dist/commands/deployment/inspect.js +91 -0
  109. package/dist/commands/deployment/inspect.js.map +1 -0
  110. package/dist/commands/deployment/list.d.ts +11 -0
  111. package/dist/commands/deployment/list.js +97 -0
  112. package/dist/commands/deployment/list.js.map +1 -0
  113. package/dist/commands/deployment/logs.d.ts +12 -0
  114. package/dist/commands/deployment/logs.js +50 -0
  115. package/dist/commands/deployment/logs.js.map +1 -0
  116. package/dist/commands/environment/inspect.d.ts +10 -0
  117. package/dist/commands/environment/inspect.js +94 -0
  118. package/dist/commands/environment/inspect.js.map +1 -0
  119. package/dist/commands/environment/list.d.ts +10 -0
  120. package/dist/commands/environment/list.js +79 -0
  121. package/dist/commands/environment/list.js.map +1 -0
  122. package/dist/commands/environment-variable/add.d.ts +13 -0
  123. package/dist/commands/environment-variable/add.js +43 -0
  124. package/dist/commands/environment-variable/add.js.map +1 -0
  125. package/dist/commands/environment-variable/list.d.ts +9 -0
  126. package/dist/commands/environment-variable/list.js +45 -0
  127. package/dist/commands/environment-variable/list.js.map +1 -0
  128. package/dist/commands/environment-variable/remove.d.ts +10 -0
  129. package/dist/commands/environment-variable/remove.js +29 -0
  130. package/dist/commands/environment-variable/remove.js.map +1 -0
  131. package/dist/commands/environment-variable/update.d.ts +12 -0
  132. package/dist/commands/environment-variable/update.js +37 -0
  133. package/dist/commands/environment-variable/update.js.map +1 -0
  134. package/dist/commands/git/connect.d.ts +2 -2
  135. package/dist/commands/git/connect.js +25 -28
  136. package/dist/commands/git/connect.js.map +1 -1
  137. package/dist/commands/git/disconnect.d.ts +0 -3
  138. package/dist/commands/git/disconnect.js +14 -29
  139. package/dist/commands/git/disconnect.js.map +1 -1
  140. package/dist/commands/git.js +2 -2
  141. package/dist/commands/git.js.map +1 -1
  142. package/dist/commands/link.d.ts +16 -0
  143. package/dist/commands/link.js +97 -0
  144. package/dist/commands/link.js.map +1 -0
  145. package/dist/commands/login.js +6 -24
  146. package/dist/commands/login.js.map +1 -1
  147. package/dist/commands/logs.d.ts +16 -0
  148. package/dist/commands/logs.js +96 -0
  149. package/dist/commands/logs.js.map +1 -0
  150. package/dist/commands/playground/configure.d.ts +12 -0
  151. package/dist/commands/playground/configure.js +39 -0
  152. package/dist/commands/playground/configure.js.map +1 -0
  153. package/dist/commands/playground/disable.d.ts +9 -0
  154. package/dist/commands/playground/disable.js +24 -0
  155. package/dist/commands/playground/disable.js.map +1 -0
  156. package/dist/commands/playground/enable.d.ts +9 -0
  157. package/dist/commands/playground/enable.js +24 -0
  158. package/dist/commands/playground/enable.js.map +1 -0
  159. package/dist/commands/playground/example-prompt/add.d.ts +12 -0
  160. package/dist/commands/playground/example-prompt/add.js +39 -0
  161. package/dist/commands/playground/example-prompt/add.js.map +1 -0
  162. package/dist/commands/playground/example-prompt/list.d.ts +9 -0
  163. package/dist/commands/playground/example-prompt/list.js +24 -0
  164. package/dist/commands/playground/example-prompt/list.js.map +1 -0
  165. package/dist/commands/playground/example-prompt/remove.d.ts +11 -0
  166. package/dist/commands/playground/example-prompt/remove.js +34 -0
  167. package/dist/commands/playground/example-prompt/remove.js.map +1 -0
  168. package/dist/commands/playground/headers/add.d.ts +14 -0
  169. package/dist/commands/playground/headers/add.js +49 -0
  170. package/dist/commands/playground/headers/add.js.map +1 -0
  171. package/dist/commands/playground/headers/list.d.ts +9 -0
  172. package/dist/commands/playground/headers/list.js +24 -0
  173. package/dist/commands/playground/headers/list.js.map +1 -0
  174. package/dist/commands/playground/headers/remove.d.ts +11 -0
  175. package/dist/commands/playground/headers/remove.js +34 -0
  176. package/dist/commands/playground/headers/remove.js.map +1 -0
  177. package/dist/commands/playground/status.d.ts +9 -0
  178. package/dist/commands/playground/status.js +24 -0
  179. package/dist/commands/playground/status.js.map +1 -0
  180. package/dist/commands/project/inspect.d.ts +10 -0
  181. package/dist/commands/project/inspect.js +97 -0
  182. package/dist/commands/project/inspect.js.map +1 -0
  183. package/dist/commands/project/list.d.ts +10 -0
  184. package/dist/commands/project/list.js +50 -0
  185. package/dist/commands/project/list.js.map +1 -0
  186. package/dist/commands/publish.d.ts +14 -0
  187. package/dist/commands/publish.js +47 -0
  188. package/dist/commands/publish.js.map +1 -0
  189. package/dist/commands/team/inspect.d.ts +10 -0
  190. package/dist/commands/team/inspect.js +97 -0
  191. package/dist/commands/team/inspect.js.map +1 -0
  192. package/dist/commands/team/list.d.ts +9 -0
  193. package/dist/commands/team/list.js +40 -0
  194. package/dist/commands/team/list.js.map +1 -0
  195. package/dist/commands/tunnel.d.ts +10 -0
  196. package/dist/commands/tunnel.js +132 -0
  197. package/dist/commands/tunnel.js.map +1 -0
  198. package/dist/commands/whoami.js +2 -14
  199. package/dist/commands/whoami.js.map +1 -1
  200. package/dist/env.js +1 -1
  201. package/dist/env.js.map +1 -1
  202. package/dist/lib/alpic-command.d.ts +7 -0
  203. package/dist/lib/alpic-command.js +24 -6
  204. package/dist/lib/alpic-command.js.map +1 -1
  205. package/dist/lib/archive.d.ts +3 -3
  206. package/dist/lib/archive.js +21 -19
  207. package/dist/lib/archive.js.map +1 -1
  208. package/dist/lib/audit.d.ts +16 -0
  209. package/dist/lib/audit.js +258 -0
  210. package/dist/lib/audit.js.map +1 -0
  211. package/dist/lib/auth/auth.d.ts +3 -0
  212. package/dist/lib/auth/auth.js +26 -3
  213. package/dist/lib/auth/auth.js.map +1 -1
  214. package/dist/lib/auth/oauth/client.d.ts +1 -1
  215. package/dist/lib/auth/oauth/client.js +7 -1
  216. package/dist/lib/auth/oauth/client.js.map +1 -1
  217. package/dist/lib/auth/oauth/server/index.d.ts +2 -1
  218. package/dist/lib/auth/oauth/server/index.js +36 -10
  219. package/dist/lib/auth/oauth/server/index.js.map +1 -1
  220. package/dist/lib/auth/whoami.d.ts +1 -28
  221. package/dist/lib/auth/whoami.js +29 -19
  222. package/dist/lib/auth/whoami.js.map +1 -1
  223. package/dist/lib/base-workflow.d.ts +10 -0
  224. package/dist/lib/base-workflow.js +22 -0
  225. package/dist/lib/base-workflow.js.map +1 -0
  226. package/dist/lib/config.d.ts +3 -2
  227. package/dist/lib/config.js +8 -7
  228. package/dist/lib/config.js.map +1 -1
  229. package/dist/lib/deployment.d.ts +69 -1
  230. package/dist/lib/deployment.js +113 -5
  231. package/dist/lib/deployment.js.map +1 -1
  232. package/dist/lib/environment-variable.d.ts +37 -0
  233. package/dist/lib/environment-variable.js +305 -0
  234. package/dist/lib/environment-variable.js.map +1 -0
  235. package/dist/lib/git.d.ts +12 -4
  236. package/dist/lib/git.js +52 -26
  237. package/dist/lib/git.js.map +1 -1
  238. package/dist/lib/global-store.d.ts +1 -1
  239. package/dist/lib/global-store.js +4 -3
  240. package/dist/lib/global-store.js.map +1 -1
  241. package/dist/lib/link.d.ts +83 -0
  242. package/dist/lib/link.js +387 -0
  243. package/dist/lib/link.js.map +1 -0
  244. package/dist/lib/logs.d.ts +20 -0
  245. package/dist/lib/logs.js +87 -0
  246. package/dist/lib/logs.js.map +1 -0
  247. package/dist/lib/playground.d.ts +53 -0
  248. package/dist/lib/playground.js +288 -0
  249. package/dist/lib/playground.js.map +1 -0
  250. package/dist/lib/publish.d.ts +22 -0
  251. package/dist/lib/publish.js +201 -0
  252. package/dist/lib/publish.js.map +1 -0
  253. package/dist/lib/resolve.d.ts +6 -0
  254. package/dist/lib/resolve.js +26 -0
  255. package/dist/lib/resolve.js.map +1 -0
  256. package/dist/lib/table.d.ts +8 -0
  257. package/dist/lib/table.js +27 -0
  258. package/dist/lib/table.js.map +1 -0
  259. package/dist/lib/telemetry.js +1 -1
  260. package/dist/lib/telemetry.js.map +1 -1
  261. package/dist/lib/utils.d.ts +6 -0
  262. package/dist/lib/utils.js +54 -0
  263. package/dist/lib/utils.js.map +1 -0
  264. package/dist/lib/utils.test.d.ts +1 -0
  265. package/dist/lib/utils.test.js +27 -0
  266. package/dist/lib/utils.test.js.map +1 -0
  267. package/dist/types.d.ts +1 -0
  268. package/package.json +28 -21
  269. package/dist/lib/project.d.ts +0 -67
  270. package/dist/lib/project.js +0 -285
  271. package/dist/lib/project.js.map +0 -1
@@ -1,10 +1,23 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { readFileSync } from "node:fs";
1
3
  import * as https from "node:https";
4
+ import { dirname, join } from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+ import { contract } from "@alpic-ai/api";
2
7
  import { OpenAPIHandler } from "@orpc/openapi/node";
3
- import { ORPCError, implement } from "@orpc/server";
8
+ import { implement, ORPCError } from "@orpc/server";
4
9
  import express, {} from "express";
5
- import { randomUUID } from "node:crypto";
6
- import selfsigned from "selfsigned";
7
- import { contract } from "@alpic-ai/api";
10
+ import { inc as semverInc } from "semver";
11
+ const __testDirname = dirname(fileURLToPath(import.meta.url));
12
+ const FIXTURE_CERT_PATH = join(__testDirname, "fixtures", "certs", "localhost-cert.pem");
13
+ const FIXTURE_KEY_PATH = join(__testDirname, "fixtures", "certs", "localhost-key.pem");
14
+ function getTlsAssets() {
15
+ return {
16
+ key: readFileSync(FIXTURE_KEY_PATH, "utf8"),
17
+ cert: readFileSync(FIXTURE_CERT_PATH, "utf8"),
18
+ certPath: FIXTURE_CERT_PATH,
19
+ };
20
+ }
8
21
  export class MockApiServer {
9
22
  server = null;
10
23
  app;
@@ -14,9 +27,19 @@ export class MockApiServer {
14
27
  constructor() {
15
28
  this.app = express();
16
29
  this.mockData = {
30
+ teams: null,
17
31
  projects: new Map(),
18
32
  environments: new Map(),
19
33
  deployments: new Map(),
34
+ environmentVariables: new Map(),
35
+ runtimeLogs: new Map(),
36
+ runtimeLogPages: new Map(),
37
+ deploymentLogPages: new Map(),
38
+ deploymentLogCallCounts: new Map(),
39
+ publishedServers: new Map(),
40
+ beaconGetResponses: [],
41
+ beaconGetCallCount: 0,
42
+ playgrounds: new Map(),
20
43
  };
21
44
  }
22
45
  async start() {
@@ -24,8 +47,9 @@ export class MockApiServer {
24
47
  throw new Error("Server is already running");
25
48
  }
26
49
  this.configureServer();
27
- const pems = await selfsigned.generate();
28
- const httpsOptions = { key: pems.private, cert: pems.cert };
50
+ const tlsAssets = getTlsAssets();
51
+ process.env.NODE_EXTRA_CA_CERTS = tlsAssets.certPath;
52
+ const httpsOptions = { key: tlsAssets.key, cert: tlsAssets.cert };
29
53
  return new Promise((resolve) => {
30
54
  this.server = https.createServer(httpsOptions, this.app).listen(0, "127.0.0.1", () => {
31
55
  if (!this.server) {
@@ -88,16 +112,29 @@ export class MockApiServer {
88
112
  });
89
113
  });
90
114
  const router = implement(contract).router({
115
+ tunnels: {
116
+ getTicket: {
117
+ v1: implement(contract.tunnels.getTicket.v1).handler(async () => {
118
+ return {
119
+ subdomain: "cool-mongoose-123",
120
+ ticket: "mock-ticket",
121
+ tunnelHost: "tunnel.alpic.dev",
122
+ };
123
+ }),
124
+ },
125
+ },
91
126
  teams: {
92
127
  list: {
93
128
  v1: implement(contract.teams.list.v1).handler(async () => {
129
+ if (this.mockData.teams) {
130
+ return this.mockData.teams;
131
+ }
94
132
  return [
95
133
  {
96
134
  id: "mock-team-id",
97
135
  name: "Mock Team",
98
136
  createdAt: new Date(),
99
137
  hasStripeAccount: false,
100
- hasActiveSubscription: false,
101
138
  },
102
139
  ];
103
140
  }),
@@ -108,7 +145,9 @@ export class MockApiServer {
108
145
  v1: implement(contract.analytics.get.v1).handler(async ({ input }) => {
109
146
  const project = this.mockData.projects.get(input.projectId);
110
147
  if (!project) {
111
- throw new ORPCError("NOT_FOUND", { message: "Project not found" });
148
+ throw new ORPCError("NOT_FOUND", {
149
+ message: "Project not found",
150
+ });
112
151
  }
113
152
  const emptyTimeSeries = {
114
153
  sessions_count: [],
@@ -134,8 +173,12 @@ export class MockApiServer {
134
173
  },
135
174
  projects: {
136
175
  list: {
137
- v1: implement(contract.projects.list.v1).handler(async () => {
138
- return Array.from(this.mockData.projects.values()).map((project) => ({
176
+ v1: implement(contract.projects.list.v1).handler(async ({ input }) => {
177
+ let projects = Array.from(this.mockData.projects.values());
178
+ if (input?.teamId) {
179
+ projects = projects.filter((project) => project.teamId === input.teamId);
180
+ }
181
+ return projects.map((project) => ({
139
182
  id: project.id,
140
183
  name: project.name,
141
184
  teamId: project.teamId,
@@ -157,7 +200,9 @@ export class MockApiServer {
157
200
  v1: implement(contract.projects.get.v1).handler(async ({ input }) => {
158
201
  const project = this.mockData.projects.get(input.projectId);
159
202
  if (!project) {
160
- throw new ORPCError("NOT_FOUND", { message: "Project not found" });
203
+ throw new ORPCError("NOT_FOUND", {
204
+ message: "Project not found",
205
+ });
161
206
  }
162
207
  return project;
163
208
  }),
@@ -165,7 +210,7 @@ export class MockApiServer {
165
210
  create: {
166
211
  v1: implement(contract.projects.create.v1).handler(async ({ input }) => {
167
212
  const projectId = randomUUID();
168
- const teamId = "mock-team-id";
213
+ const teamId = input.teamId ?? "mock-team-id";
169
214
  const productionEnvId = randomUUID();
170
215
  const productionEnvName = "production";
171
216
  const project = {
@@ -203,6 +248,7 @@ export class MockApiServer {
203
248
  id: productionEnvId,
204
249
  name: productionEnvName,
205
250
  mcpServerUrl: `https://mcp-${projectId}.alpic.ai`,
251
+ domains: [],
206
252
  latestDeployment: null,
207
253
  },
208
254
  environments: [
@@ -225,7 +271,9 @@ export class MockApiServer {
225
271
  v1: implement(contract.projects.update.v1).handler(async ({ input }) => {
226
272
  const project = this.mockData.projects.get(input.projectId);
227
273
  if (!project) {
228
- throw new ORPCError("NOT_FOUND", { message: "Project not found" });
274
+ throw new ORPCError("NOT_FOUND", {
275
+ message: "Project not found",
276
+ });
229
277
  }
230
278
  if (input.sourceRepository !== undefined) {
231
279
  project.sourceRepository = input.sourceRepository;
@@ -238,7 +286,9 @@ export class MockApiServer {
238
286
  v1: implement(contract.projects.delete.v1).handler(async ({ input }) => {
239
287
  const project = this.mockData.projects.get(input.projectId);
240
288
  if (!project) {
241
- throw new ORPCError("NOT_FOUND", { message: "Project not found" });
289
+ throw new ORPCError("NOT_FOUND", {
290
+ message: "Project not found",
291
+ });
242
292
  }
243
293
  this.mockData.projects.delete(input.projectId);
244
294
  return { success: true };
@@ -250,7 +300,9 @@ export class MockApiServer {
250
300
  v1: implement(contract.environments.create.v1).handler(async ({ input }) => {
251
301
  const project = this.mockData.projects.get(input.projectId);
252
302
  if (!project) {
253
- throw new ORPCError("NOT_FOUND", { message: "Project not found" });
303
+ throw new ORPCError("NOT_FOUND", {
304
+ message: "Project not found",
305
+ });
254
306
  }
255
307
  const environmentId = randomUUID();
256
308
  const mcpServerUrl = `https://mcp-${environmentId}.alpic.ai`;
@@ -294,21 +346,50 @@ export class MockApiServer {
294
346
  v1: implement(contract.environments.get.v1).handler(async ({ input }) => {
295
347
  const environment = this.mockData.environments.get(input.environmentId);
296
348
  if (!environment) {
297
- throw new ORPCError("NOT_FOUND", { message: "Environment not found" });
349
+ throw new ORPCError("NOT_FOUND", {
350
+ message: "Environment not found",
351
+ });
298
352
  }
299
353
  return environment;
300
354
  }),
301
355
  },
356
+ getLogs: {
357
+ v1: implement(contract.environments.getLogs.v1).handler(async ({ input }) => {
358
+ const environment = this.mockData.environments.get(input.environmentId);
359
+ if (!environment) {
360
+ throw new ORPCError("NOT_FOUND", {
361
+ message: "Environment not found",
362
+ });
363
+ }
364
+ const pagedLogs = this.mockData.runtimeLogPages.get(input.environmentId);
365
+ const pageIndex = input.nextToken === undefined ? 0 : Number.parseInt(input.nextToken, 10);
366
+ const allLogs = pagedLogs === undefined
367
+ ? (this.mockData.runtimeLogs.get(input.environmentId) ?? [])
368
+ : (pagedLogs[pageIndex] ?? []);
369
+ let logs = allLogs;
370
+ if (input.level !== undefined) {
371
+ const levels = input.level;
372
+ logs = allLogs.filter((log) => levels.includes(log.type));
373
+ }
374
+ const nextToken = pagedLogs === undefined || pageIndex + 1 >= pagedLogs.length ? null : String(pageIndex + 1);
375
+ return { logs, nextToken };
376
+ }),
377
+ },
302
378
  deploy: {
303
379
  v1: implement(contract.environments.deploy.v1).handler(async ({ input }) => {
304
380
  const environment = this.mockData.environments.get(input.environmentId);
305
381
  if (!environment) {
306
- throw new ORPCError("NOT_FOUND", { message: "Environment not found" });
382
+ throw new ORPCError("NOT_FOUND", {
383
+ message: "Environment not found",
384
+ });
307
385
  }
308
386
  const deploymentId = randomUUID();
309
387
  const deployment = {
310
388
  id: deploymentId,
311
389
  status: "ongoing",
390
+ environmentId: environment.id,
391
+ environmentName: environment.name,
392
+ isCurrent: false,
312
393
  sourceRef: environment.sourceBranch,
313
394
  sourceCommitId: randomUUID().slice(0, 7),
314
395
  sourceCommitMessage: "Mock deployment",
@@ -323,17 +404,225 @@ export class MockApiServer {
323
404
  }),
324
405
  },
325
406
  },
407
+ environmentVariables: {
408
+ list: {
409
+ v1: implement(contract.environmentVariables.list.v1).handler(async ({ input }) => {
410
+ const environment = this.mockData.environments.get(input.environmentId);
411
+ if (!environment) {
412
+ throw new ORPCError("NOT_FOUND", {
413
+ message: "Environment not found",
414
+ });
415
+ }
416
+ return this.mockData.environmentVariables.get(input.environmentId) ?? [];
417
+ }),
418
+ },
419
+ create: {
420
+ v1: implement(contract.environmentVariables.create.v1).handler(async ({ input }) => {
421
+ const environment = this.mockData.environments.get(input.environmentId);
422
+ if (!environment) {
423
+ throw new ORPCError("NOT_FOUND", {
424
+ message: "Environment not found",
425
+ });
426
+ }
427
+ const existing = this.mockData.environmentVariables.get(input.environmentId) ?? [];
428
+ const newVars = input.environmentVariables.map((variable) => ({
429
+ id: randomUUID(),
430
+ key: variable.key,
431
+ value: variable.value,
432
+ isSecret: variable.isSecret,
433
+ createdAt: new Date(),
434
+ }));
435
+ for (const newVar of newVars) {
436
+ if (existing.some((existingVar) => existingVar.key === newVar.key)) {
437
+ throw new ORPCError("BAD_REQUEST", {
438
+ message: `Environment variable "${newVar.key}" already exists`,
439
+ });
440
+ }
441
+ }
442
+ this.mockData.environmentVariables.set(input.environmentId, [...existing, ...newVars]);
443
+ return { success: true };
444
+ }),
445
+ },
446
+ update: {
447
+ v1: implement(contract.environmentVariables.update.v1).handler(async ({ input }) => {
448
+ for (const [environmentId, variables] of this.mockData.environmentVariables.entries()) {
449
+ const index = variables.findIndex((variable) => variable.id === input.environmentVariableId);
450
+ if (index !== -1) {
451
+ const updated = variables.map((variable, i) => i === index
452
+ ? {
453
+ ...variable,
454
+ key: input.key,
455
+ value: input.value ?? variable.value,
456
+ isSecret: input.isSecret,
457
+ }
458
+ : variable);
459
+ this.mockData.environmentVariables.set(environmentId, updated);
460
+ return { success: true };
461
+ }
462
+ }
463
+ throw new ORPCError("NOT_FOUND", {
464
+ message: "Environment variable not found",
465
+ });
466
+ }),
467
+ },
468
+ delete: {
469
+ v1: implement(contract.environmentVariables.delete.v1).handler(async ({ input }) => {
470
+ for (const [environmentId, variables] of this.mockData.environmentVariables.entries()) {
471
+ const index = variables.findIndex((variable) => variable.id === input.environmentVariableId);
472
+ if (index !== -1) {
473
+ this.mockData.environmentVariables.set(environmentId, variables.filter((_, i) => i !== index));
474
+ return { success: true };
475
+ }
476
+ }
477
+ throw new ORPCError("NOT_FOUND", {
478
+ message: "Environment variable not found",
479
+ });
480
+ }),
481
+ },
482
+ },
483
+ playground: {
484
+ get: {
485
+ v1: implement(contract.playground.get.v1).handler(async ({ input }) => {
486
+ const environment = this.mockData.environments.get(input.environmentId);
487
+ if (!environment) {
488
+ throw new ORPCError("NOT_FOUND", { message: "Environment not found" });
489
+ }
490
+ return (this.mockData.playgrounds.get(input.environmentId) ?? { isPlaygroundEnabled: true, serverMetadata: null });
491
+ }),
492
+ },
493
+ upsert: {
494
+ v1: implement(contract.playground.upsert.v1).handler(async ({ input }) => {
495
+ const environment = this.mockData.environments.get(input.environmentId);
496
+ if (!environment) {
497
+ throw new ORPCError("NOT_FOUND", { message: "Environment not found" });
498
+ }
499
+ const current = this.mockData.playgrounds.get(input.environmentId) ?? {
500
+ isPlaygroundEnabled: true,
501
+ serverMetadata: null,
502
+ };
503
+ const hasMetadataFields = input.name !== undefined ||
504
+ input.description !== undefined ||
505
+ input.headers !== undefined ||
506
+ input.examplePrompts !== undefined;
507
+ const updated = {
508
+ isPlaygroundEnabled: input.isPlaygroundEnabled ?? current.isPlaygroundEnabled,
509
+ serverMetadata: hasMetadataFields
510
+ ? {
511
+ name: input.name ?? current.serverMetadata?.name ?? "",
512
+ description: input.description ?? current.serverMetadata?.description ?? "",
513
+ headers: (input.headers ?? current.serverMetadata?.headers ?? []).map((header) => ({
514
+ name: header.name,
515
+ description: header.description,
516
+ isRequired: header.isRequired ?? false,
517
+ isSecret: header.isSecret ?? false,
518
+ })),
519
+ examplePrompts: input.examplePrompts ?? current.serverMetadata?.examplePrompts ?? [],
520
+ }
521
+ : current.serverMetadata,
522
+ };
523
+ this.mockData.playgrounds.set(input.environmentId, updated);
524
+ return updated;
525
+ }),
526
+ },
527
+ },
528
+ distribution: {
529
+ get: {
530
+ v1: implement(contract.distribution.get.v1).handler(async ({ input }) => {
531
+ const existing = this.mockData.publishedServers.get(`${input.projectId}:${input.domain}`);
532
+ return {
533
+ serverFields: existing ?? {
534
+ $schema: "https://registry.modelcontextprotocol.io/schemas/1.0/server.json",
535
+ name: "",
536
+ description: "",
537
+ },
538
+ };
539
+ }),
540
+ },
541
+ publish: {
542
+ v1: implement(contract.distribution.publish.v1).handler(async ({ input }) => {
543
+ const project = this.mockData.projects.get(input.projectId);
544
+ if (!project) {
545
+ throw new ORPCError("NOT_FOUND", {
546
+ message: "Project not found",
547
+ });
548
+ }
549
+ const key = `${input.projectId}:${input.domain}`;
550
+ const existing = this.mockData.publishedServers.get(key);
551
+ const version = existing?.version ? (semverInc(existing.version, "patch") ?? "0.0.1") : "0.0.1";
552
+ const serverFields = {
553
+ $schema: "https://registry.modelcontextprotocol.io/schemas/1.0/server.json",
554
+ name: input.domain,
555
+ description: input.description,
556
+ title: input.title,
557
+ version,
558
+ ...(input.websiteUrl ? { websiteUrl: input.websiteUrl } : {}),
559
+ ...(input.iconSrc ? { icons: [{ src: input.iconSrc }] } : {}),
560
+ };
561
+ if (!input.dryRun) {
562
+ this.mockData.publishedServers.set(key, serverFields);
563
+ }
564
+ return { serverFields };
565
+ }),
566
+ },
567
+ },
568
+ beacon: {
569
+ create: {
570
+ v1: implement(contract.beacon.create.v1).handler(async () => {
571
+ return { id: "mock-analysis-id" };
572
+ }),
573
+ },
574
+ get: {
575
+ v1: implement(contract.beacon.get.v1).handler(async () => {
576
+ if (this.mockData.beaconGetResponses.length > 0) {
577
+ const index = Math.min(this.mockData.beaconGetCallCount, this.mockData.beaconGetResponses.length - 1);
578
+ this.mockData.beaconGetCallCount++;
579
+ const response = this.mockData.beaconGetResponses[index];
580
+ if (!response) {
581
+ throw new Error("Missing mocked beacon.get response");
582
+ }
583
+ return response;
584
+ }
585
+ return {
586
+ id: "mock-analysis-id",
587
+ targetUrl: "https://example.com/mcp",
588
+ status: "completed",
589
+ durationMs: 1234,
590
+ createdAt: new Date(),
591
+ report: {
592
+ schemaVersion: "v20260224",
593
+ auditId: "mock-analysis-id",
594
+ targetUrl: "https://example.com/mcp",
595
+ startedAt: new Date().toISOString(),
596
+ completedAt: new Date().toISOString(),
597
+ durationMs: 1234,
598
+ results: [],
599
+ requiresAuth: false,
600
+ hasViewSupport: false,
601
+ isReadyForPlatform: { chatgpt: true, claudeai: true },
602
+ },
603
+ };
604
+ }),
605
+ },
606
+ },
326
607
  deployments: {
327
608
  list: {
328
609
  v1: implement(contract.deployments.list.v1).handler(async ({ input }) => {
329
610
  const project = this.mockData.projects.get(input.projectId);
330
611
  if (!project) {
331
- throw new ORPCError("NOT_FOUND", { message: "Project not found" });
612
+ throw new ORPCError("NOT_FOUND", {
613
+ message: "Project not found",
614
+ });
615
+ }
616
+ let deployments = Array.from(this.mockData.deployments.values());
617
+ if (input.environmentId) {
618
+ deployments = deployments.filter((deployment) => deployment.environmentId === input.environmentId);
332
619
  }
333
- return Array.from(this.mockData.deployments.values()).map((deployment) => ({
620
+ if (input.status?.length) {
621
+ deployments = deployments.filter((deployment) => input.status.includes(deployment.status));
622
+ }
623
+ return deployments.map((deployment) => ({
334
624
  ...deployment,
335
625
  isCurrent: deployment.status === "deployed",
336
- environmentId: project.productionEnvironment?.id ?? "",
337
626
  }));
338
627
  }),
339
628
  },
@@ -341,7 +630,9 @@ export class MockApiServer {
341
630
  v1: implement(contract.deployments.get.v1).handler(async ({ input }) => {
342
631
  const deployment = this.mockData.deployments.get(input.deploymentId);
343
632
  if (!deployment) {
344
- throw new ORPCError("NOT_FOUND", { message: "Deployment not found" });
633
+ throw new ORPCError("NOT_FOUND", {
634
+ message: "Deployment not found",
635
+ });
345
636
  }
346
637
  if (deployment.status === "ongoing") {
347
638
  const updatedDeployment = {
@@ -360,7 +651,16 @@ export class MockApiServer {
360
651
  v1: implement(contract.deployments.getLogs.v1).handler(async ({ input }) => {
361
652
  const deployment = this.mockData.deployments.get(input.deploymentId);
362
653
  if (!deployment) {
363
- throw new ORPCError("NOT_FOUND", { message: "Deployment not found" });
654
+ throw new ORPCError("NOT_FOUND", {
655
+ message: "Deployment not found",
656
+ });
657
+ }
658
+ const pages = this.mockData.deploymentLogPages.get(input.deploymentId);
659
+ if (pages !== undefined) {
660
+ const callCount = this.mockData.deploymentLogCallCounts.get(input.deploymentId) ?? 0;
661
+ const pageIndex = Math.min(callCount, pages.length - 1);
662
+ this.mockData.deploymentLogCallCounts.set(input.deploymentId, callCount + 1);
663
+ return pages[pageIndex] ?? { logs: [], hasMoreLogs: false };
364
664
  }
365
665
  return {
366
666
  logs: [{ timestamp: new Date(), content: "Mock log entry" }],
@@ -389,7 +689,12 @@ export class MockApiServer {
389
689
  path: req.path,
390
690
  timestamp: new Date(),
391
691
  };
392
- if (req.body) {
692
+ if (req.method === "GET") {
693
+ if (Object.keys(req.query).length > 0) {
694
+ apiCall.input = req.query;
695
+ }
696
+ }
697
+ else if (req.body) {
393
698
  apiCall.input = req.body;
394
699
  }
395
700
  const result = await handler.handle(req, res, {
@@ -405,6 +710,24 @@ export class MockApiServer {
405
710
  this.callHistory.push(apiCall);
406
711
  });
407
712
  }
713
+ reset() {
714
+ this.callHistory = [];
715
+ this.mockData = {
716
+ teams: null,
717
+ projects: new Map(),
718
+ environments: new Map(),
719
+ deployments: new Map(),
720
+ environmentVariables: new Map(),
721
+ runtimeLogs: new Map(),
722
+ runtimeLogPages: new Map(),
723
+ deploymentLogPages: new Map(),
724
+ deploymentLogCallCounts: new Map(),
725
+ publishedServers: new Map(),
726
+ beaconGetResponses: [],
727
+ beaconGetCallCount: 0,
728
+ playgrounds: new Map(),
729
+ };
730
+ }
408
731
  async stop() {
409
732
  return new Promise((resolve, reject) => {
410
733
  if (!this.server) {
@@ -461,6 +784,46 @@ export class MockApiServer {
461
784
  }
462
785
  return undefined;
463
786
  }
787
+ setTeams(teams) {
788
+ this.mockData.teams = teams.map((team) => ({
789
+ ...team,
790
+ createdAt: new Date("2024-01-01T00:00:00.000Z"),
791
+ hasStripeAccount: false,
792
+ }));
793
+ }
794
+ addEnvironmentVariables(environmentId, variables) {
795
+ this.mockData.environmentVariables.set(environmentId, variables);
796
+ }
797
+ setRuntimeLogs(environmentId, logs) {
798
+ this.mockData.runtimeLogs.set(environmentId, logs);
799
+ this.mockData.runtimeLogPages.delete(environmentId);
800
+ }
801
+ setRuntimeLogPages(environmentId, pages) {
802
+ this.mockData.runtimeLogPages.set(environmentId, pages);
803
+ this.mockData.runtimeLogs.delete(environmentId);
804
+ }
805
+ setPublishedServer(projectId, domain, server) {
806
+ this.mockData.publishedServers.set(`${projectId}:${domain}`, server);
807
+ }
808
+ addDeployments(deployments) {
809
+ for (const deployment of deployments) {
810
+ this.mockData.deployments.set(deployment.id, {
811
+ ...deployment,
812
+ deploymentPageUrl: null,
813
+ });
814
+ }
815
+ }
816
+ setDeploymentLogPages(deploymentId, pages) {
817
+ this.mockData.deploymentLogPages.set(deploymentId, pages);
818
+ this.mockData.deploymentLogCallCounts.set(deploymentId, 0);
819
+ }
820
+ setBeaconGetResponses(responses) {
821
+ this.mockData.beaconGetResponses = responses;
822
+ this.mockData.beaconGetCallCount = 0;
823
+ }
824
+ setPlayground(environmentId, playground) {
825
+ this.mockData.playgrounds.set(environmentId, playground);
826
+ }
464
827
  addProject(project) {
465
828
  this.mockData.projects.set(project.id, project);
466
829
  if (project.productionEnvironment) {