alpic 0.0.0-dev.gee3a480 → 0.0.0-dev.gee425da

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 (264) hide show
  1. package/README.md +18 -0
  2. package/bin/dev.js +0 -0
  3. package/bin/run.js +15 -1
  4. package/dist/__tests__/alpic-command.test.js +8 -4
  5. package/dist/__tests__/alpic-command.test.js.map +1 -1
  6. package/dist/__tests__/audit.e2e.test.js +17 -30
  7. package/dist/__tests__/audit.e2e.test.js.map +1 -1
  8. package/dist/__tests__/auth.e2e.test.js +9 -23
  9. package/dist/__tests__/auth.e2e.test.js.map +1 -1
  10. package/dist/__tests__/deploy-flags.e2e.test.js +6 -21
  11. package/dist/__tests__/deploy-flags.e2e.test.js.map +1 -1
  12. package/dist/__tests__/deploy.e2e.test.js +5 -21
  13. package/dist/__tests__/deploy.e2e.test.js.map +1 -1
  14. package/dist/__tests__/deployment-inspect.e2e.test.js +18 -31
  15. package/dist/__tests__/deployment-inspect.e2e.test.js.map +1 -1
  16. package/dist/__tests__/deployment-list.e2e.test.js +18 -31
  17. package/dist/__tests__/deployment-list.e2e.test.js.map +1 -1
  18. package/dist/__tests__/deployment-logs.e2e.test.js +15 -29
  19. package/dist/__tests__/deployment-logs.e2e.test.js.map +1 -1
  20. package/dist/__tests__/environment-delete.e2e.test.d.ts +1 -0
  21. package/dist/__tests__/environment-delete.e2e.test.js +95 -0
  22. package/dist/__tests__/environment-delete.e2e.test.js.map +1 -0
  23. package/dist/__tests__/environment-list.e2e.test.js +6 -22
  24. package/dist/__tests__/environment-list.e2e.test.js.map +1 -1
  25. package/dist/__tests__/environment-variable/environment-variable-add.e2e.test.js +19 -31
  26. package/dist/__tests__/environment-variable/environment-variable-add.e2e.test.js.map +1 -1
  27. package/dist/__tests__/environment-variable/environment-variable-list.e2e.test.js +19 -31
  28. package/dist/__tests__/environment-variable/environment-variable-list.e2e.test.js.map +1 -1
  29. package/dist/__tests__/environment-variable/environment-variable-remove.e2e.test.js +18 -31
  30. package/dist/__tests__/environment-variable/environment-variable-remove.e2e.test.js.map +1 -1
  31. package/dist/__tests__/environment-variable/environment-variable-update.e2e.test.js +18 -31
  32. package/dist/__tests__/environment-variable/environment-variable-update.e2e.test.js.map +1 -1
  33. package/dist/__tests__/git-flags.e2e.test.js +6 -22
  34. package/dist/__tests__/git-flags.e2e.test.js.map +1 -1
  35. package/dist/__tests__/git.e2e.test.js +7 -22
  36. package/dist/__tests__/git.e2e.test.js.map +1 -1
  37. package/dist/__tests__/insights-category.e2e.test.d.ts +1 -0
  38. package/dist/__tests__/insights-category.e2e.test.js +247 -0
  39. package/dist/__tests__/insights-category.e2e.test.js.map +1 -0
  40. package/dist/__tests__/insights.e2e.test.d.ts +1 -0
  41. package/dist/__tests__/insights.e2e.test.js +193 -0
  42. package/dist/__tests__/insights.e2e.test.js.map +1 -0
  43. package/dist/__tests__/logs.e2e.test.js +21 -35
  44. package/dist/__tests__/logs.e2e.test.js.map +1 -1
  45. package/dist/__tests__/mock-api.d.ts +28 -1
  46. package/dist/__tests__/mock-api.js +391 -46
  47. package/dist/__tests__/mock-api.js.map +1 -1
  48. package/dist/__tests__/playground/playground-configure.e2e.test.js +18 -26
  49. package/dist/__tests__/playground/playground-configure.e2e.test.js.map +1 -1
  50. package/dist/__tests__/playground/playground-enable-disable.e2e.test.js +18 -26
  51. package/dist/__tests__/playground/playground-enable-disable.e2e.test.js.map +1 -1
  52. package/dist/__tests__/playground/playground-example-prompt.e2e.test.js +24 -30
  53. package/dist/__tests__/playground/playground-example-prompt.e2e.test.js.map +1 -1
  54. package/dist/__tests__/playground/playground-headers.e2e.test.js +18 -26
  55. package/dist/__tests__/playground/playground-headers.e2e.test.js.map +1 -1
  56. package/dist/__tests__/playground/playground-status.e2e.test.js +18 -26
  57. package/dist/__tests__/playground/playground-status.e2e.test.js.map +1 -1
  58. package/dist/__tests__/project-list.e2e.test.js +5 -21
  59. package/dist/__tests__/project-list.e2e.test.js.map +1 -1
  60. package/dist/__tests__/publish.e2e.test.js +6 -24
  61. package/dist/__tests__/publish.e2e.test.js.map +1 -1
  62. package/dist/__tests__/submission.e2e.test.d.ts +1 -0
  63. package/dist/__tests__/submission.e2e.test.js +173 -0
  64. package/dist/__tests__/submission.e2e.test.js.map +1 -0
  65. package/dist/__tests__/team-inspect.e2e.test.js +26 -1
  66. package/dist/__tests__/team-inspect.e2e.test.js.map +1 -1
  67. package/dist/__tests__/team-list.e2e.test.js +5 -21
  68. package/dist/__tests__/team-list.e2e.test.js.map +1 -1
  69. package/dist/__tests__/telemetry-destinations.e2e.test.d.ts +1 -0
  70. package/dist/__tests__/telemetry-destinations.e2e.test.js +105 -0
  71. package/dist/__tests__/telemetry-destinations.e2e.test.js.map +1 -0
  72. package/dist/__tests__/tunnel.e2e.test.js +114 -23
  73. package/dist/__tests__/tunnel.e2e.test.js.map +1 -1
  74. package/dist/__tests__/utils.d.ts +17 -6
  75. package/dist/__tests__/utils.js +49 -20
  76. package/dist/__tests__/utils.js.map +1 -1
  77. package/dist/api.d.ts +1 -1
  78. package/dist/api.js +2 -21
  79. package/dist/api.js.map +1 -1
  80. package/dist/commands/audit.js +3 -1
  81. package/dist/commands/audit.js.map +1 -1
  82. package/dist/commands/deploy.js +71 -54
  83. package/dist/commands/deploy.js.map +1 -1
  84. package/dist/commands/deployment/list.js +3 -3
  85. package/dist/commands/deployment/list.js.map +1 -1
  86. package/dist/commands/environment/delete.d.ts +13 -0
  87. package/dist/commands/environment/delete.js +45 -0
  88. package/dist/commands/environment/delete.js.map +1 -0
  89. package/dist/commands/environment/inspect.js +3 -3
  90. package/dist/commands/environment/inspect.js.map +1 -1
  91. package/dist/commands/environment/list.js +3 -3
  92. package/dist/commands/environment/list.js.map +1 -1
  93. package/dist/commands/git/connect.js +2 -2
  94. package/dist/commands/git/connect.js.map +1 -1
  95. package/dist/commands/git/disconnect.js +2 -2
  96. package/dist/commands/git/disconnect.js.map +1 -1
  97. package/dist/commands/insights/category/create.d.ts +17 -0
  98. package/dist/commands/insights/category/create.js +63 -0
  99. package/dist/commands/insights/category/create.js.map +1 -0
  100. package/dist/commands/insights/category/delete.d.ts +13 -0
  101. package/dist/commands/insights/category/delete.js +40 -0
  102. package/dist/commands/insights/category/delete.js.map +1 -0
  103. package/dist/commands/insights/category/link.d.ts +14 -0
  104. package/dist/commands/insights/category/link.js +36 -0
  105. package/dist/commands/insights/category/link.js.map +1 -0
  106. package/dist/commands/insights/category/list.d.ts +13 -0
  107. package/dist/commands/insights/category/list.js +46 -0
  108. package/dist/commands/insights/category/list.js.map +1 -0
  109. package/dist/commands/insights/category/unlink.d.ts +14 -0
  110. package/dist/commands/insights/category/unlink.js +36 -0
  111. package/dist/commands/insights/category/unlink.js.map +1 -0
  112. package/dist/commands/insights/category/update.d.ts +16 -0
  113. package/dist/commands/insights/category/update.js +45 -0
  114. package/dist/commands/insights/category/update.js.map +1 -0
  115. package/dist/commands/insights/feedback/list.d.ts +19 -0
  116. package/dist/commands/insights/feedback/list.js +73 -0
  117. package/dist/commands/insights/feedback/list.js.map +1 -0
  118. package/dist/commands/insights/intent/list.d.ts +22 -0
  119. package/dist/commands/insights/intent/list.js +89 -0
  120. package/dist/commands/insights/intent/list.js.map +1 -0
  121. package/dist/commands/link.js +4 -3
  122. package/dist/commands/link.js.map +1 -1
  123. package/dist/commands/login.js +7 -5
  124. package/dist/commands/login.js.map +1 -1
  125. package/dist/commands/logout.js +1 -1
  126. package/dist/commands/logout.js.map +1 -1
  127. package/dist/commands/logs.js +1 -9
  128. package/dist/commands/logs.js.map +1 -1
  129. package/dist/commands/playground/example-prompt/add.js +1 -1
  130. package/dist/commands/project/inspect.js +3 -3
  131. package/dist/commands/project/inspect.js.map +1 -1
  132. package/dist/commands/project/list.js +3 -3
  133. package/dist/commands/project/list.js.map +1 -1
  134. package/dist/commands/submission/create.d.ts +15 -0
  135. package/dist/commands/submission/create.js +59 -0
  136. package/dist/commands/submission/create.js.map +1 -0
  137. package/dist/commands/submission/inspect.d.ts +10 -0
  138. package/dist/commands/submission/inspect.js +56 -0
  139. package/dist/commands/submission/inspect.js.map +1 -0
  140. package/dist/commands/submission/list.d.ts +13 -0
  141. package/dist/commands/submission/list.js +63 -0
  142. package/dist/commands/submission/list.js.map +1 -0
  143. package/dist/commands/submission/update.d.ts +12 -0
  144. package/dist/commands/submission/update.js +37 -0
  145. package/dist/commands/submission/update.js.map +1 -0
  146. package/dist/commands/team/inspect.js +25 -10
  147. package/dist/commands/team/inspect.js.map +1 -1
  148. package/dist/commands/team/list.js +3 -3
  149. package/dist/commands/team/list.js.map +1 -1
  150. package/dist/commands/telemetry/destinations/create.d.ts +19 -0
  151. package/dist/commands/telemetry/destinations/create.js +57 -0
  152. package/dist/commands/telemetry/destinations/create.js.map +1 -0
  153. package/dist/commands/telemetry/destinations/delete.d.ts +13 -0
  154. package/dist/commands/telemetry/destinations/delete.js +27 -0
  155. package/dist/commands/telemetry/destinations/delete.js.map +1 -0
  156. package/dist/commands/telemetry/destinations/list.d.ts +13 -0
  157. package/dist/commands/telemetry/destinations/list.js +48 -0
  158. package/dist/commands/telemetry/destinations/list.js.map +1 -0
  159. package/dist/commands/telemetry/destinations/update.d.ts +20 -0
  160. package/dist/commands/telemetry/destinations/update.js +62 -0
  161. package/dist/commands/telemetry/destinations/update.js.map +1 -0
  162. package/dist/commands/tunnel.js +30 -66
  163. package/dist/commands/tunnel.js.map +1 -1
  164. package/dist/commands/whoami.js +1 -1
  165. package/dist/commands/whoami.js.map +1 -1
  166. package/dist/lib/agent-mode.d.ts +8 -1
  167. package/dist/lib/agent-mode.js +25 -26
  168. package/dist/lib/agent-mode.js.map +1 -1
  169. package/dist/lib/alpic-command.d.ts +2 -1
  170. package/dist/lib/alpic-command.js +20 -8
  171. package/dist/lib/alpic-command.js.map +1 -1
  172. package/dist/lib/alpic-sdk.d.ts +2 -0
  173. package/dist/lib/alpic-sdk.js +8 -0
  174. package/dist/lib/alpic-sdk.js.map +1 -0
  175. package/dist/lib/audit.d.ts +1 -0
  176. package/dist/lib/audit.js +24 -15
  177. package/dist/lib/audit.js.map +1 -1
  178. package/dist/lib/base-workflow.d.ts +2 -1
  179. package/dist/lib/base-workflow.js +3 -3
  180. package/dist/lib/base-workflow.js.map +1 -1
  181. package/dist/lib/deployment.d.ts +0 -21
  182. package/dist/lib/deployment.js +20 -69
  183. package/dist/lib/deployment.js.map +1 -1
  184. package/dist/lib/environment-variable.js +14 -13
  185. package/dist/lib/environment-variable.js.map +1 -1
  186. package/dist/lib/insights.d.ts +19 -0
  187. package/dist/lib/insights.js +54 -0
  188. package/dist/lib/insights.js.map +1 -0
  189. package/dist/lib/link.d.ts +1 -2
  190. package/dist/lib/link.js +20 -75
  191. package/dist/lib/link.js.map +1 -1
  192. package/dist/lib/logs.js +4 -5
  193. package/dist/lib/logs.js.map +1 -1
  194. package/dist/lib/playground.js +27 -27
  195. package/dist/lib/playground.js.map +1 -1
  196. package/dist/lib/project-settings.d.ts +7 -0
  197. package/dist/lib/project-settings.js +140 -0
  198. package/dist/lib/project-settings.js.map +1 -0
  199. package/dist/lib/project-settings.test.d.ts +1 -0
  200. package/dist/lib/project-settings.test.js +56 -0
  201. package/dist/lib/project-settings.test.js.map +1 -0
  202. package/dist/lib/publish.js +3 -3
  203. package/dist/lib/publish.js.map +1 -1
  204. package/dist/lib/resolve.d.ts +7 -6
  205. package/dist/lib/resolve.js +27 -23
  206. package/dist/lib/resolve.js.map +1 -1
  207. package/dist/lib/submission.d.ts +13 -0
  208. package/dist/lib/submission.js +52 -0
  209. package/dist/lib/submission.js.map +1 -0
  210. package/dist/lib/telemetry-destinations.d.ts +9 -0
  211. package/dist/lib/telemetry-destinations.js +21 -0
  212. package/dist/lib/telemetry-destinations.js.map +1 -0
  213. package/dist/lib/telemetry-destinations.test.d.ts +1 -0
  214. package/dist/lib/telemetry-destinations.test.js +14 -0
  215. package/dist/lib/telemetry-destinations.test.js.map +1 -0
  216. package/dist/lib/telemetry.js +27 -17
  217. package/dist/lib/telemetry.js.map +1 -1
  218. package/dist/lib/utils.d.ts +9 -1
  219. package/dist/lib/utils.js +28 -2
  220. package/dist/lib/utils.js.map +1 -1
  221. package/dist/lib/utils.test.js +43 -5
  222. package/dist/lib/utils.test.js.map +1 -1
  223. package/dist/lib/whoami.js +17 -0
  224. package/dist/lib/whoami.js.map +1 -0
  225. package/dist/sentry.js +3 -6
  226. package/dist/sentry.js.map +1 -1
  227. package/package.json +29 -32
  228. package/dist/lib/archive.d.ts +0 -7
  229. package/dist/lib/archive.js +0 -57
  230. package/dist/lib/archive.js.map +0 -1
  231. package/dist/lib/auth/auth.d.ts +0 -5
  232. package/dist/lib/auth/auth.js +0 -50
  233. package/dist/lib/auth/auth.js.map +0 -1
  234. package/dist/lib/auth/oauth/client.d.ts +0 -28
  235. package/dist/lib/auth/oauth/client.js +0 -116
  236. package/dist/lib/auth/oauth/client.js.map +0 -1
  237. package/dist/lib/auth/oauth/constants.d.ts +0 -2
  238. package/dist/lib/auth/oauth/constants.js +0 -3
  239. package/dist/lib/auth/oauth/constants.js.map +0 -1
  240. package/dist/lib/auth/oauth/server/assets/alpic-mountain.png +0 -0
  241. package/dist/lib/auth/oauth/server/assets/authorize.html +0 -234
  242. package/dist/lib/auth/oauth/server/assets/callback.html +0 -88
  243. package/dist/lib/auth/oauth/server/index.d.ts +0 -9
  244. package/dist/lib/auth/oauth/server/index.js +0 -128
  245. package/dist/lib/auth/oauth/server/index.js.map +0 -1
  246. package/dist/lib/auth/whoami.js +0 -47
  247. package/dist/lib/auth/whoami.js.map +0 -1
  248. package/dist/lib/config.d.ts +0 -12
  249. package/dist/lib/config.js +0 -32
  250. package/dist/lib/config.js.map +0 -1
  251. package/dist/lib/global-store.d.ts +0 -28
  252. package/dist/lib/global-store.js +0 -76
  253. package/dist/lib/global-store.js.map +0 -1
  254. package/dist/lib/upload.d.ts +0 -1
  255. package/dist/lib/upload.js +0 -13
  256. package/dist/lib/upload.js.map +0 -1
  257. package/dist/lib/vendor/pipenet.d.ts +0 -1
  258. package/dist/lib/vendor/pipenet.js +0 -15626
  259. package/dist/lib/vendor/pipenet.js.LEGAL.txt +0 -17
  260. package/dist/lib/vendor/pipenet.js.map +0 -7
  261. package/dist/types.d.ts +0 -8
  262. package/dist/types.js +0 -2
  263. package/dist/types.js.map +0 -1
  264. /package/dist/lib/{auth/whoami.d.ts → whoami.d.ts} +0 -0
@@ -8,6 +8,32 @@ import { OpenAPIHandler } from "@orpc/openapi/node";
8
8
  import { implement, ORPCError } from "@orpc/server";
9
9
  import express, {} from "express";
10
10
  import { inc as semverInc } from "semver";
11
+ function createEmptyMockData() {
12
+ return {
13
+ tunnelTicket: null,
14
+ teams: null,
15
+ projects: new Map(),
16
+ environments: new Map(),
17
+ deployments: new Map(),
18
+ environmentVariables: new Map(),
19
+ runtimeLogs: new Map(),
20
+ runtimeLogPages: new Map(),
21
+ deploymentLogPages: new Map(),
22
+ deploymentLogCallCounts: new Map(),
23
+ publishedServers: new Map(),
24
+ beaconGetResponses: [],
25
+ beaconGetCallCount: 0,
26
+ playgrounds: new Map(),
27
+ teamUsages: new Map(),
28
+ intents: new Map(),
29
+ feedbacks: new Map(),
30
+ intentCategories: new Map(),
31
+ intentCategoryCounter: 0,
32
+ submissions: new Map(),
33
+ submissionPrefills: new Map(),
34
+ telemetryDestinations: new Map(),
35
+ };
36
+ }
11
37
  const __testDirname = dirname(fileURLToPath(import.meta.url));
12
38
  const FIXTURE_CERT_PATH = join(__testDirname, "fixtures", "certs", "localhost-cert.pem");
13
39
  const FIXTURE_KEY_PATH = join(__testDirname, "fixtures", "certs", "localhost-key.pem");
@@ -26,21 +52,7 @@ export class MockApiServer {
26
52
  callHistory = [];
27
53
  constructor() {
28
54
  this.app = express();
29
- this.mockData = {
30
- teams: null,
31
- projects: new Map(),
32
- environments: new Map(),
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(),
43
- };
55
+ this.mockData = createEmptyMockData();
44
56
  }
45
57
  async start() {
46
58
  if (this.server) {
@@ -115,11 +127,11 @@ export class MockApiServer {
115
127
  tunnels: {
116
128
  getTicket: {
117
129
  v1: implement(contract.tunnels.getTicket.v1).handler(async () => {
118
- return {
130
+ return (this.mockData.tunnelTicket ?? {
119
131
  subdomain: "cool-mongoose-123",
120
132
  ticket: "mock-ticket",
121
133
  tunnelHost: "tunnel.alpic.dev",
122
- };
134
+ });
123
135
  }),
124
136
  },
125
137
  },
@@ -139,6 +151,15 @@ export class MockApiServer {
139
151
  ];
140
152
  }),
141
153
  },
154
+ getUsage: {
155
+ v1: implement(contract.teams.getUsage.v1).handler(async ({ input }) => {
156
+ const usage = this.mockData.teamUsages.get(input.teamId);
157
+ if (!usage) {
158
+ throw new ORPCError("NOT_FOUND", { message: "Team usage not found" });
159
+ }
160
+ return usage;
161
+ }),
162
+ },
142
163
  },
143
164
  analytics: {
144
165
  get: {
@@ -171,6 +192,129 @@ export class MockApiServer {
171
192
  }),
172
193
  },
173
194
  },
195
+ intents: {
196
+ list: {
197
+ v1: implement(contract.intents.list.v1).handler(async ({ input }) => {
198
+ if (!this.mockData.environments.has(input.environmentId)) {
199
+ throw new ORPCError("NOT_FOUND", { message: "Environment not found" });
200
+ }
201
+ let intents = this.mockData.intents.get(input.environmentId) ?? [];
202
+ if (input.search) {
203
+ const search = input.search.toLowerCase();
204
+ intents = intents.filter((intent) => intent.message.toLowerCase().includes(search) ||
205
+ intent.toolName.toLowerCase().includes(search) ||
206
+ intent.categories.some(({ name }) => name.toLowerCase().includes(search)));
207
+ }
208
+ if (input.tools) {
209
+ intents = intents.filter(({ toolName }) => input.tools?.includes(toolName));
210
+ }
211
+ if (input.clientIds) {
212
+ intents = intents.filter(({ clientId }) => clientId !== null && input.clientIds?.includes(clientId));
213
+ }
214
+ if (input.categoryIds) {
215
+ intents = intents.filter(({ categories }) => categories.some(({ id }) => input.categoryIds?.includes(id)));
216
+ }
217
+ intents = [...intents].sort((left, right) => input.sortDir === "asc"
218
+ ? left.createdAt.getTime() - right.createdAt.getTime()
219
+ : right.createdAt.getTime() - left.createdAt.getTime());
220
+ return {
221
+ intents: intents.slice(input.offset, input.offset + input.limit),
222
+ totalCount: intents.length,
223
+ };
224
+ }),
225
+ },
226
+ },
227
+ intentCategories: {
228
+ list: {
229
+ v1: implement(contract.intentCategories.list.v1).handler(async ({ input }) => {
230
+ const categories = this.requireMockEnvironmentCategories(input.environmentId);
231
+ return categories.map(({ linkedIntentIds, ...category }) => ({
232
+ ...category,
233
+ intentCount: linkedIntentIds.size,
234
+ }));
235
+ }),
236
+ },
237
+ create: {
238
+ v1: implement(contract.intentCategories.create.v1).handler(async ({ input }) => {
239
+ const categories = this.requireMockEnvironmentCategories(input.environmentId);
240
+ this.requireMockIntents(input.environmentId, input.intentIds ?? [], "BAD_REQUEST");
241
+ const { linkedIntentIds, ...category } = {
242
+ id: `cat-mock-${++this.mockData.intentCategoryCounter}`,
243
+ createdAt: new Date("2026-08-13T00:00:00.000Z"),
244
+ environmentId: input.environmentId,
245
+ name: input.name,
246
+ color: input.color ?? "gray",
247
+ linkedIntentIds: new Set(input.intentIds ?? []),
248
+ };
249
+ categories.push({ ...category, linkedIntentIds });
250
+ return category;
251
+ }),
252
+ },
253
+ update: {
254
+ v1: implement(contract.intentCategories.update.v1).handler(async ({ input }) => {
255
+ const category = this.requireMockIntentCategory(input.environmentId, input.categoryId);
256
+ category.name = input.name ?? category.name;
257
+ category.color = input.color ?? category.color;
258
+ const { linkedIntentIds, ...updated } = category;
259
+ return updated;
260
+ }),
261
+ },
262
+ delete: {
263
+ v1: implement(contract.intentCategories.delete.v1).handler(async ({ input }) => {
264
+ const category = this.requireMockIntentCategory(input.environmentId, input.categoryId);
265
+ this.mockData.intentCategories.set(input.environmentId, (this.mockData.intentCategories.get(input.environmentId) ?? []).filter(({ id }) => id !== category.id));
266
+ this.removeCategoryFromIntents(input.environmentId, category.id, null);
267
+ return { success: true };
268
+ }),
269
+ },
270
+ link: {
271
+ v1: implement(contract.intentCategories.link.v1).handler(async ({ input }) => {
272
+ const category = this.requireMockIntentCategory(input.environmentId, input.categoryId);
273
+ this.requireMockIntents(input.environmentId, input.intentIds, "NOT_FOUND");
274
+ for (const intentId of input.intentIds) {
275
+ category.linkedIntentIds.add(intentId);
276
+ }
277
+ for (const intent of this.mockData.intents.get(input.environmentId) ?? []) {
278
+ const isLinked = intent.intentIds.some((intentId) => category.linkedIntentIds.has(intentId));
279
+ if (isLinked && !intent.categories.some(({ id }) => id === category.id)) {
280
+ intent.categories.push({ id: category.id, name: category.name, color: category.color });
281
+ }
282
+ }
283
+ return { success: true };
284
+ }),
285
+ },
286
+ unlink: {
287
+ v1: implement(contract.intentCategories.unlink.v1).handler(async ({ input }) => {
288
+ const category = this.requireMockIntentCategory(input.environmentId, input.categoryId);
289
+ for (const intentId of input.intentIds) {
290
+ category.linkedIntentIds.delete(intentId);
291
+ }
292
+ this.removeCategoryFromIntents(input.environmentId, category.id, category.linkedIntentIds);
293
+ return { success: true };
294
+ }),
295
+ },
296
+ },
297
+ feedbacks: {
298
+ list: {
299
+ v1: implement(contract.feedbacks.list.v1).handler(async ({ input }) => {
300
+ if (!this.mockData.environments.has(input.environmentId)) {
301
+ throw new ORPCError("NOT_FOUND", { message: "Environment not found" });
302
+ }
303
+ let feedbacks = this.mockData.feedbacks.get(input.environmentId) ?? [];
304
+ if (input.search) {
305
+ const search = input.search.toLowerCase();
306
+ feedbacks = feedbacks.filter((feedback) => feedback.content.toLowerCase().includes(search) || feedback.source.toLowerCase().includes(search));
307
+ }
308
+ if (input.clientIds) {
309
+ feedbacks = feedbacks.filter(({ clientId }) => clientId !== null && input.clientIds?.includes(clientId));
310
+ }
311
+ return {
312
+ feedbacks: feedbacks.slice(input.offset, input.offset + input.limit),
313
+ totalCount: feedbacks.length,
314
+ };
315
+ }),
316
+ },
317
+ },
174
318
  projects: {
175
319
  list: {
176
320
  v1: implement(contract.projects.list.v1).handler(async ({ input }) => {
@@ -237,7 +381,7 @@ export class MockApiServer {
237
381
  name: productionEnvName,
238
382
  sourceBranch: null,
239
383
  mcpServerUrl: `https://mcp-${projectId}.alpic.ai`,
240
- domains: [`https://mcp-${projectId}.alpic.ai`],
384
+ domains: [`mcp-${projectId}.alpic.ai`],
241
385
  createdAt: new Date(),
242
386
  projectId,
243
387
  };
@@ -305,14 +449,15 @@ export class MockApiServer {
305
449
  });
306
450
  }
307
451
  const environmentId = randomUUID();
308
- const mcpServerUrl = `https://mcp-${environmentId}.alpic.ai`;
452
+ const mcpServerHost = `mcp-${environmentId}.alpic.ai`;
453
+ const mcpServerUrl = `https://${mcpServerHost}`;
309
454
  const createdAt = new Date();
310
455
  const environment = {
311
456
  id: environmentId,
312
457
  name: input.name,
313
458
  sourceBranch: input.sourceBranch,
314
459
  mcpServerUrl,
315
- domains: [mcpServerUrl],
460
+ domains: [mcpServerHost],
316
461
  createdAt,
317
462
  projectId: input.projectId,
318
463
  };
@@ -353,6 +498,30 @@ export class MockApiServer {
353
498
  return environment;
354
499
  }),
355
500
  },
501
+ delete: {
502
+ v1: implement(contract.environments.delete.v1).handler(async ({ input }) => {
503
+ const environment = this.mockData.environments.get(input.environmentId);
504
+ if (!environment) {
505
+ throw new ORPCError("NOT_FOUND", {
506
+ message: "Environment not found",
507
+ });
508
+ }
509
+ const project = this.mockData.projects.get(environment.projectId);
510
+ if (project?.productionEnvironment?.id === input.environmentId) {
511
+ throw new ORPCError("BAD_REQUEST", {
512
+ message: "Cannot delete the production environment of the project",
513
+ });
514
+ }
515
+ this.mockData.environments.delete(input.environmentId);
516
+ if (project) {
517
+ this.mockData.projects.set(environment.projectId, {
518
+ ...project,
519
+ environments: project.environments.filter((env) => env.id !== input.environmentId),
520
+ });
521
+ }
522
+ return { success: true };
523
+ }),
524
+ },
356
525
  getLogs: {
357
526
  v1: implement(contract.environments.getLogs.v1).handler(async ({ input }) => {
358
527
  const environment = this.mockData.environments.get(input.environmentId);
@@ -420,6 +589,80 @@ export class MockApiServer {
420
589
  }),
421
590
  },
422
591
  },
592
+ telemetryDestinations: {
593
+ list: {
594
+ v1: implement(contract.telemetryDestinations.list.v1).handler(async ({ input }) => {
595
+ if (!this.mockData.environments.has(input.environmentId)) {
596
+ throw new ORPCError("NOT_FOUND", { message: "Environment not found" });
597
+ }
598
+ return this.mockData.telemetryDestinations.get(input.environmentId) ?? [];
599
+ }),
600
+ },
601
+ create: {
602
+ v1: implement(contract.telemetryDestinations.create.v1).handler(async ({ input }) => {
603
+ if (!this.mockData.environments.has(input.environmentId)) {
604
+ throw new ORPCError("NOT_FOUND", { message: "Environment not found" });
605
+ }
606
+ const destination = {
607
+ id: randomUUID(),
608
+ signal: input.signal,
609
+ endpoint: input.endpoint,
610
+ protocol: input.protocol,
611
+ status: "active",
612
+ lastFailureReason: null,
613
+ isScopedToIntentionalRequestsOnly: input.signal === "traces" && input.isScopedToIntentionalRequestsOnly,
614
+ headers: input.headers.map((header) => header.isSecret
615
+ ? { id: randomUUID(), name: header.name, value: null, isSecret: true }
616
+ : { id: randomUUID(), name: header.name, value: header.value, isSecret: false }),
617
+ };
618
+ this.mockData.telemetryDestinations.set(input.environmentId, [
619
+ ...(this.mockData.telemetryDestinations.get(input.environmentId) ?? []),
620
+ destination,
621
+ ]);
622
+ return destination;
623
+ }),
624
+ },
625
+ update: {
626
+ v1: implement(contract.telemetryDestinations.update.v1).handler(async ({ input }) => {
627
+ const destinations = this.mockData.telemetryDestinations.get(input.environmentId) ?? [];
628
+ const current = destinations.find(({ id }) => id === input.destinationId);
629
+ if (current === undefined) {
630
+ throw new ORPCError("NOT_FOUND", { message: "Telemetry destination not found" });
631
+ }
632
+ const updated = {
633
+ ...current,
634
+ endpoint: input.endpoint ?? current.endpoint,
635
+ protocol: input.protocol ?? current.protocol,
636
+ isScopedToIntentionalRequestsOnly: current.signal === "traces"
637
+ ? (input.isScopedToIntentionalRequestsOnly ?? current.isScopedToIntentionalRequestsOnly)
638
+ : false,
639
+ headers: input.headers?.map((header) => {
640
+ const previous = header.id === undefined ? undefined : current.headers.find(({ id }) => id === header.id);
641
+ const id = header.id ?? randomUUID();
642
+ if (header.isSecret) {
643
+ return { id, name: header.name, value: null, isSecret: true };
644
+ }
645
+ const value = header.value ?? previous?.value;
646
+ if (value === undefined || value === null) {
647
+ throw new ORPCError("BAD_REQUEST", { message: `Enter a value for the ${header.name} header` });
648
+ }
649
+ return { id, name: header.name, value, isSecret: false };
650
+ }) ?? current.headers,
651
+ };
652
+ this.mockData.telemetryDestinations.set(input.environmentId, destinations.map((destination) => (destination.id === updated.id ? updated : destination)));
653
+ return updated;
654
+ }),
655
+ },
656
+ delete: {
657
+ v1: implement(contract.telemetryDestinations.delete.v1).handler(async ({ input }) => {
658
+ if (!this.mockData.environments.has(input.environmentId)) {
659
+ throw new ORPCError("NOT_FOUND", { message: "Environment not found" });
660
+ }
661
+ this.mockData.telemetryDestinations.set(input.environmentId, (this.mockData.telemetryDestinations.get(input.environmentId) ?? []).filter(({ id }) => id !== input.destinationId));
662
+ return { success: true };
663
+ }),
664
+ },
665
+ },
423
666
  environmentVariables: {
424
667
  list: {
425
668
  v1: implement(contract.environmentVariables.list.v1).handler(async ({ input }) => {
@@ -638,6 +881,73 @@ export class MockApiServer {
638
881
  }),
639
882
  },
640
883
  },
884
+ submissions: {
885
+ create: {
886
+ v1: implement(contract.submissions.create.v1).handler(async ({ input }) => {
887
+ const environment = this.mockData.environments.get(input.environmentId);
888
+ if (!environment) {
889
+ throw new ORPCError("NOT_FOUND", { message: "Environment not found" });
890
+ }
891
+ const formData = this.mockData.submissionPrefills.get(input.platform) ?? {};
892
+ const now = new Date();
893
+ const submission = {
894
+ id: `sub-${randomUUID()}`,
895
+ environmentId: input.environmentId,
896
+ platform: input.platform,
897
+ formData,
898
+ prefillSnapshot: formData,
899
+ auditId: "audit-1",
900
+ urlVerification: null,
901
+ createdAt: now,
902
+ updatedAt: now,
903
+ };
904
+ this.mockData.submissions.set(submission.id, submission);
905
+ return submission;
906
+ }),
907
+ },
908
+ list: {
909
+ v1: implement(contract.submissions.list.v1).handler(async ({ input }) => {
910
+ const project = this.mockData.projects.get(input.projectId);
911
+ if (!project) {
912
+ throw new ORPCError("NOT_FOUND", { message: "Project not found" });
913
+ }
914
+ const environmentIds = new Set(project.environments.map((environment) => environment.id));
915
+ let submissions = [...this.mockData.submissions.values()].filter((submission) => environmentIds.has(submission.environmentId));
916
+ if (input.environmentId) {
917
+ submissions = submissions.filter((submission) => submission.environmentId === input.environmentId);
918
+ }
919
+ if (input.platform) {
920
+ submissions = submissions.filter((submission) => submission.platform === input.platform);
921
+ }
922
+ return submissions;
923
+ }),
924
+ },
925
+ get: {
926
+ v1: implement(contract.submissions.get.v1).handler(async ({ input }) => {
927
+ const submission = this.mockData.submissions.get(input.submissionId);
928
+ if (!submission) {
929
+ throw new ORPCError("NOT_FOUND", { message: "Submission not found" });
930
+ }
931
+ return submission;
932
+ }),
933
+ },
934
+ update: {
935
+ v1: implement(contract.submissions.update.v1).handler(async ({ input }) => {
936
+ const submission = this.mockData.submissions.get(input.submissionId);
937
+ if (!submission) {
938
+ throw new ORPCError("NOT_FOUND", { message: "Submission not found" });
939
+ }
940
+ if (submission.platform !== input.platform) {
941
+ throw new ORPCError("BAD_REQUEST", {
942
+ message: `Platform mismatch: submission ${submission.id} is ${submission.platform}, payload claims ${input.platform}`,
943
+ });
944
+ }
945
+ const updated = { ...submission, formData: input.formData, updatedAt: new Date() };
946
+ this.mockData.submissions.set(submission.id, updated);
947
+ return updated;
948
+ }),
949
+ },
950
+ },
641
951
  deployments: {
642
952
  list: {
643
953
  v1: implement(contract.deployments.list.v1).handler(async ({ input }) => {
@@ -746,21 +1056,7 @@ export class MockApiServer {
746
1056
  }
747
1057
  reset() {
748
1058
  this.callHistory = [];
749
- this.mockData = {
750
- teams: null,
751
- projects: new Map(),
752
- environments: new Map(),
753
- deployments: new Map(),
754
- environmentVariables: new Map(),
755
- runtimeLogs: new Map(),
756
- runtimeLogPages: new Map(),
757
- deploymentLogPages: new Map(),
758
- deploymentLogCallCounts: new Map(),
759
- publishedServers: new Map(),
760
- beaconGetResponses: [],
761
- beaconGetCallCount: 0,
762
- playgrounds: new Map(),
763
- };
1059
+ this.mockData = createEmptyMockData();
764
1060
  }
765
1061
  async stop() {
766
1062
  return new Promise((resolve, reject) => {
@@ -791,10 +1087,8 @@ export class MockApiServer {
791
1087
  return false;
792
1088
  }
793
1089
  }
794
- else {
795
- if (!pathPattern.test(call.path)) {
796
- return false;
797
- }
1090
+ else if (!pathPattern.test(call.path)) {
1091
+ return false;
798
1092
  }
799
1093
  }
800
1094
  return true;
@@ -815,23 +1109,27 @@ export class MockApiServer {
815
1109
  continue;
816
1110
  }
817
1111
  }
818
- else {
819
- if (!pathPattern.test(call.path)) {
820
- continue;
821
- }
1112
+ else if (!pathPattern.test(call.path)) {
1113
+ continue;
822
1114
  }
823
1115
  }
824
1116
  return call;
825
1117
  }
826
1118
  return undefined;
827
1119
  }
1120
+ setTunnelTicket(ticket) {
1121
+ this.mockData.tunnelTicket = ticket;
1122
+ }
828
1123
  setTeams(teams) {
829
1124
  this.mockData.teams = teams.map((team) => ({
830
1125
  ...team,
831
- createdAt: new Date("2024-01-01T00:00:00.000Z"),
1126
+ createdAt: new Date(Date.now() - 2 * 365 * 24 * 60 * 60 * 1000),
832
1127
  hasStripeAccount: false,
833
1128
  }));
834
1129
  }
1130
+ setTeamUsage(usage) {
1131
+ this.mockData.teamUsages.set(usage.teamId, usage);
1132
+ }
835
1133
  addEnvironmentVariables(environmentId, variables) {
836
1134
  this.mockData.environmentVariables.set(environmentId, variables);
837
1135
  }
@@ -865,6 +1163,53 @@ export class MockApiServer {
865
1163
  setPlayground(environmentId, playground) {
866
1164
  this.mockData.playgrounds.set(environmentId, playground);
867
1165
  }
1166
+ setIntents(environmentId, intents) {
1167
+ this.mockData.intents.set(environmentId, intents);
1168
+ }
1169
+ setIntentCategories(environmentId, categories) {
1170
+ this.mockData.intentCategories.set(environmentId, categories.map((category) => ({ ...category, linkedIntentIds: new Set(category.linkedIntentIds ?? []) })));
1171
+ }
1172
+ setTelemetryDestinations(environmentId, destinations) {
1173
+ this.mockData.telemetryDestinations.set(environmentId, destinations);
1174
+ }
1175
+ requireMockEnvironmentCategories(environmentId) {
1176
+ if (!this.mockData.environments.has(environmentId)) {
1177
+ throw new ORPCError("NOT_FOUND", { message: "Environment not found" });
1178
+ }
1179
+ const categories = this.mockData.intentCategories.get(environmentId) ?? [];
1180
+ this.mockData.intentCategories.set(environmentId, categories);
1181
+ return categories;
1182
+ }
1183
+ requireMockIntentCategory(environmentId, categoryId) {
1184
+ const category = this.requireMockEnvironmentCategories(environmentId).find(({ id }) => id === categoryId);
1185
+ if (!category) {
1186
+ throw new ORPCError("NOT_FOUND", { message: "Intent category not found" });
1187
+ }
1188
+ return category;
1189
+ }
1190
+ requireMockIntents(environmentId, intentIds, errorCode) {
1191
+ const knownIntentIds = new Set((this.mockData.intents.get(environmentId) ?? []).flatMap((intent) => intent.intentIds));
1192
+ if (intentIds.some((intentId) => !knownIntentIds.has(intentId))) {
1193
+ throw new ORPCError(errorCode, { message: "One or more intents not found" });
1194
+ }
1195
+ }
1196
+ removeCategoryFromIntents(environmentId, categoryId, remainingIntentIds) {
1197
+ for (const intent of this.mockData.intents.get(environmentId) ?? []) {
1198
+ const stillLinked = remainingIntentIds !== null && intent.intentIds.some((intentId) => remainingIntentIds.has(intentId));
1199
+ if (!stillLinked) {
1200
+ intent.categories = intent.categories.filter(({ id }) => id !== categoryId);
1201
+ }
1202
+ }
1203
+ }
1204
+ setFeedbacks(environmentId, feedbacks) {
1205
+ this.mockData.feedbacks.set(environmentId, feedbacks);
1206
+ }
1207
+ addSubmission(submission) {
1208
+ this.mockData.submissions.set(submission.id, submission);
1209
+ }
1210
+ setSubmissionPrefill(platform, formData) {
1211
+ this.mockData.submissionPrefills.set(platform, formData);
1212
+ }
868
1213
  addProject(project) {
869
1214
  this.mockData.projects.set(project.id, project);
870
1215
  if (project.productionEnvironment) {
@@ -873,7 +1218,7 @@ export class MockApiServer {
873
1218
  name: project.productionEnvironment.name,
874
1219
  sourceBranch: null,
875
1220
  mcpServerUrl: project.productionEnvironment.mcpServerUrl,
876
- domains: [project.productionEnvironment.mcpServerUrl],
1221
+ domains: [new URL(project.productionEnvironment.mcpServerUrl).host],
877
1222
  createdAt: new Date(),
878
1223
  projectId: project.id,
879
1224
  };
@@ -885,7 +1230,7 @@ export class MockApiServer {
885
1230
  name: env.name,
886
1231
  sourceBranch: env.sourceBranch,
887
1232
  mcpServerUrl: env.mcpServerUrl,
888
- domains: [env.mcpServerUrl],
1233
+ domains: [new URL(env.mcpServerUrl).host],
889
1234
  createdAt: env.createdAt,
890
1235
  projectId: project.id,
891
1236
  };