alpic 0.0.0-dev.ge67feab → 0.0.0-dev.ge69cd96

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 (243) 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 +26 -1
  46. package/dist/__tests__/mock-api.js +313 -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__/tunnel.e2e.test.js +114 -23
  70. package/dist/__tests__/tunnel.e2e.test.js.map +1 -1
  71. package/dist/__tests__/utils.d.ts +17 -6
  72. package/dist/__tests__/utils.js +49 -20
  73. package/dist/__tests__/utils.js.map +1 -1
  74. package/dist/api.d.ts +1 -1
  75. package/dist/api.js +2 -21
  76. package/dist/api.js.map +1 -1
  77. package/dist/commands/audit.js +3 -1
  78. package/dist/commands/audit.js.map +1 -1
  79. package/dist/commands/deploy.js +71 -54
  80. package/dist/commands/deploy.js.map +1 -1
  81. package/dist/commands/deployment/list.js +3 -3
  82. package/dist/commands/deployment/list.js.map +1 -1
  83. package/dist/commands/environment/delete.d.ts +13 -0
  84. package/dist/commands/environment/delete.js +45 -0
  85. package/dist/commands/environment/delete.js.map +1 -0
  86. package/dist/commands/environment/inspect.js +3 -3
  87. package/dist/commands/environment/inspect.js.map +1 -1
  88. package/dist/commands/environment/list.js +3 -3
  89. package/dist/commands/environment/list.js.map +1 -1
  90. package/dist/commands/git/connect.js +2 -2
  91. package/dist/commands/git/connect.js.map +1 -1
  92. package/dist/commands/git/disconnect.js +2 -2
  93. package/dist/commands/git/disconnect.js.map +1 -1
  94. package/dist/commands/insights/category/create.d.ts +17 -0
  95. package/dist/commands/insights/category/create.js +63 -0
  96. package/dist/commands/insights/category/create.js.map +1 -0
  97. package/dist/commands/insights/category/delete.d.ts +13 -0
  98. package/dist/commands/insights/category/delete.js +40 -0
  99. package/dist/commands/insights/category/delete.js.map +1 -0
  100. package/dist/commands/insights/category/link.d.ts +14 -0
  101. package/dist/commands/insights/category/link.js +36 -0
  102. package/dist/commands/insights/category/link.js.map +1 -0
  103. package/dist/commands/insights/category/list.d.ts +13 -0
  104. package/dist/commands/insights/category/list.js +46 -0
  105. package/dist/commands/insights/category/list.js.map +1 -0
  106. package/dist/commands/insights/category/unlink.d.ts +14 -0
  107. package/dist/commands/insights/category/unlink.js +36 -0
  108. package/dist/commands/insights/category/unlink.js.map +1 -0
  109. package/dist/commands/insights/category/update.d.ts +16 -0
  110. package/dist/commands/insights/category/update.js +45 -0
  111. package/dist/commands/insights/category/update.js.map +1 -0
  112. package/dist/commands/insights/feedback/list.d.ts +19 -0
  113. package/dist/commands/insights/feedback/list.js +73 -0
  114. package/dist/commands/insights/feedback/list.js.map +1 -0
  115. package/dist/commands/insights/intent/list.d.ts +22 -0
  116. package/dist/commands/insights/intent/list.js +89 -0
  117. package/dist/commands/insights/intent/list.js.map +1 -0
  118. package/dist/commands/link.js +4 -3
  119. package/dist/commands/link.js.map +1 -1
  120. package/dist/commands/login.js +7 -5
  121. package/dist/commands/login.js.map +1 -1
  122. package/dist/commands/logout.js +1 -1
  123. package/dist/commands/logout.js.map +1 -1
  124. package/dist/commands/logs.js +1 -9
  125. package/dist/commands/logs.js.map +1 -1
  126. package/dist/commands/playground/example-prompt/add.js +1 -1
  127. package/dist/commands/project/inspect.js +3 -3
  128. package/dist/commands/project/inspect.js.map +1 -1
  129. package/dist/commands/project/list.js +3 -3
  130. package/dist/commands/project/list.js.map +1 -1
  131. package/dist/commands/submission/create.d.ts +15 -0
  132. package/dist/commands/submission/create.js +59 -0
  133. package/dist/commands/submission/create.js.map +1 -0
  134. package/dist/commands/submission/inspect.d.ts +10 -0
  135. package/dist/commands/submission/inspect.js +56 -0
  136. package/dist/commands/submission/inspect.js.map +1 -0
  137. package/dist/commands/submission/list.d.ts +13 -0
  138. package/dist/commands/submission/list.js +63 -0
  139. package/dist/commands/submission/list.js.map +1 -0
  140. package/dist/commands/submission/update.d.ts +12 -0
  141. package/dist/commands/submission/update.js +37 -0
  142. package/dist/commands/submission/update.js.map +1 -0
  143. package/dist/commands/team/inspect.js +25 -10
  144. package/dist/commands/team/inspect.js.map +1 -1
  145. package/dist/commands/team/list.js +3 -3
  146. package/dist/commands/team/list.js.map +1 -1
  147. package/dist/commands/tunnel.js +30 -66
  148. package/dist/commands/tunnel.js.map +1 -1
  149. package/dist/commands/whoami.js +1 -1
  150. package/dist/commands/whoami.js.map +1 -1
  151. package/dist/lib/agent-mode.d.ts +8 -1
  152. package/dist/lib/agent-mode.js +25 -26
  153. package/dist/lib/agent-mode.js.map +1 -1
  154. package/dist/lib/alpic-command.d.ts +2 -1
  155. package/dist/lib/alpic-command.js +20 -8
  156. package/dist/lib/alpic-command.js.map +1 -1
  157. package/dist/lib/alpic-sdk.d.ts +2 -0
  158. package/dist/lib/alpic-sdk.js +8 -0
  159. package/dist/lib/alpic-sdk.js.map +1 -0
  160. package/dist/lib/audit.d.ts +1 -0
  161. package/dist/lib/audit.js +24 -15
  162. package/dist/lib/audit.js.map +1 -1
  163. package/dist/lib/base-workflow.d.ts +2 -1
  164. package/dist/lib/base-workflow.js +3 -3
  165. package/dist/lib/base-workflow.js.map +1 -1
  166. package/dist/lib/deployment.d.ts +0 -21
  167. package/dist/lib/deployment.js +20 -69
  168. package/dist/lib/deployment.js.map +1 -1
  169. package/dist/lib/environment-variable.js +14 -13
  170. package/dist/lib/environment-variable.js.map +1 -1
  171. package/dist/lib/insights.d.ts +19 -0
  172. package/dist/lib/insights.js +54 -0
  173. package/dist/lib/insights.js.map +1 -0
  174. package/dist/lib/link.d.ts +1 -2
  175. package/dist/lib/link.js +20 -75
  176. package/dist/lib/link.js.map +1 -1
  177. package/dist/lib/logs.js +4 -5
  178. package/dist/lib/logs.js.map +1 -1
  179. package/dist/lib/playground.js +27 -27
  180. package/dist/lib/playground.js.map +1 -1
  181. package/dist/lib/project-settings.d.ts +7 -0
  182. package/dist/lib/project-settings.js +140 -0
  183. package/dist/lib/project-settings.js.map +1 -0
  184. package/dist/lib/project-settings.test.d.ts +1 -0
  185. package/dist/lib/project-settings.test.js +56 -0
  186. package/dist/lib/project-settings.test.js.map +1 -0
  187. package/dist/lib/publish.js +3 -3
  188. package/dist/lib/publish.js.map +1 -1
  189. package/dist/lib/resolve.d.ts +7 -6
  190. package/dist/lib/resolve.js +27 -23
  191. package/dist/lib/resolve.js.map +1 -1
  192. package/dist/lib/submission.d.ts +13 -0
  193. package/dist/lib/submission.js +52 -0
  194. package/dist/lib/submission.js.map +1 -0
  195. package/dist/lib/telemetry.js +27 -17
  196. package/dist/lib/telemetry.js.map +1 -1
  197. package/dist/lib/utils.d.ts +9 -1
  198. package/dist/lib/utils.js +28 -2
  199. package/dist/lib/utils.js.map +1 -1
  200. package/dist/lib/utils.test.js +43 -5
  201. package/dist/lib/utils.test.js.map +1 -1
  202. package/dist/lib/whoami.js +17 -0
  203. package/dist/lib/whoami.js.map +1 -0
  204. package/dist/sentry.js +3 -6
  205. package/dist/sentry.js.map +1 -1
  206. package/package.json +29 -32
  207. package/dist/lib/archive.d.ts +0 -7
  208. package/dist/lib/archive.js +0 -57
  209. package/dist/lib/archive.js.map +0 -1
  210. package/dist/lib/auth/auth.d.ts +0 -5
  211. package/dist/lib/auth/auth.js +0 -50
  212. package/dist/lib/auth/auth.js.map +0 -1
  213. package/dist/lib/auth/oauth/client.d.ts +0 -28
  214. package/dist/lib/auth/oauth/client.js +0 -116
  215. package/dist/lib/auth/oauth/client.js.map +0 -1
  216. package/dist/lib/auth/oauth/constants.d.ts +0 -2
  217. package/dist/lib/auth/oauth/constants.js +0 -3
  218. package/dist/lib/auth/oauth/constants.js.map +0 -1
  219. package/dist/lib/auth/oauth/server/assets/alpic-mountain.png +0 -0
  220. package/dist/lib/auth/oauth/server/assets/authorize.html +0 -234
  221. package/dist/lib/auth/oauth/server/assets/callback.html +0 -88
  222. package/dist/lib/auth/oauth/server/index.d.ts +0 -9
  223. package/dist/lib/auth/oauth/server/index.js +0 -128
  224. package/dist/lib/auth/oauth/server/index.js.map +0 -1
  225. package/dist/lib/auth/whoami.js +0 -47
  226. package/dist/lib/auth/whoami.js.map +0 -1
  227. package/dist/lib/config.d.ts +0 -12
  228. package/dist/lib/config.js +0 -32
  229. package/dist/lib/config.js.map +0 -1
  230. package/dist/lib/global-store.d.ts +0 -28
  231. package/dist/lib/global-store.js +0 -76
  232. package/dist/lib/global-store.js.map +0 -1
  233. package/dist/lib/upload.d.ts +0 -1
  234. package/dist/lib/upload.js +0 -13
  235. package/dist/lib/upload.js.map +0 -1
  236. package/dist/lib/vendor/pipenet.d.ts +0 -1
  237. package/dist/lib/vendor/pipenet.js +0 -15626
  238. package/dist/lib/vendor/pipenet.js.LEGAL.txt +0 -17
  239. package/dist/lib/vendor/pipenet.js.map +0 -7
  240. package/dist/types.d.ts +0 -8
  241. package/dist/types.js +0 -2
  242. package/dist/types.js.map +0 -1
  243. /package/dist/lib/{auth/whoami.d.ts → whoami.d.ts} +0 -0
@@ -8,6 +8,31 @@ 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
+ };
35
+ }
11
36
  const __testDirname = dirname(fileURLToPath(import.meta.url));
12
37
  const FIXTURE_CERT_PATH = join(__testDirname, "fixtures", "certs", "localhost-cert.pem");
13
38
  const FIXTURE_KEY_PATH = join(__testDirname, "fixtures", "certs", "localhost-key.pem");
@@ -26,21 +51,7 @@ export class MockApiServer {
26
51
  callHistory = [];
27
52
  constructor() {
28
53
  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
- };
54
+ this.mockData = createEmptyMockData();
44
55
  }
45
56
  async start() {
46
57
  if (this.server) {
@@ -115,11 +126,11 @@ export class MockApiServer {
115
126
  tunnels: {
116
127
  getTicket: {
117
128
  v1: implement(contract.tunnels.getTicket.v1).handler(async () => {
118
- return {
129
+ return (this.mockData.tunnelTicket ?? {
119
130
  subdomain: "cool-mongoose-123",
120
131
  ticket: "mock-ticket",
121
132
  tunnelHost: "tunnel.alpic.dev",
122
- };
133
+ });
123
134
  }),
124
135
  },
125
136
  },
@@ -139,6 +150,15 @@ export class MockApiServer {
139
150
  ];
140
151
  }),
141
152
  },
153
+ getUsage: {
154
+ v1: implement(contract.teams.getUsage.v1).handler(async ({ input }) => {
155
+ const usage = this.mockData.teamUsages.get(input.teamId);
156
+ if (!usage) {
157
+ throw new ORPCError("NOT_FOUND", { message: "Team usage not found" });
158
+ }
159
+ return usage;
160
+ }),
161
+ },
142
162
  },
143
163
  analytics: {
144
164
  get: {
@@ -171,6 +191,129 @@ export class MockApiServer {
171
191
  }),
172
192
  },
173
193
  },
194
+ intents: {
195
+ list: {
196
+ v1: implement(contract.intents.list.v1).handler(async ({ input }) => {
197
+ if (!this.mockData.environments.has(input.environmentId)) {
198
+ throw new ORPCError("NOT_FOUND", { message: "Environment not found" });
199
+ }
200
+ let intents = this.mockData.intents.get(input.environmentId) ?? [];
201
+ if (input.search) {
202
+ const search = input.search.toLowerCase();
203
+ intents = intents.filter((intent) => intent.message.toLowerCase().includes(search) ||
204
+ intent.toolName.toLowerCase().includes(search) ||
205
+ intent.categories.some(({ name }) => name.toLowerCase().includes(search)));
206
+ }
207
+ if (input.tools) {
208
+ intents = intents.filter(({ toolName }) => input.tools?.includes(toolName));
209
+ }
210
+ if (input.clientIds) {
211
+ intents = intents.filter(({ clientId }) => clientId !== null && input.clientIds?.includes(clientId));
212
+ }
213
+ if (input.categoryIds) {
214
+ intents = intents.filter(({ categories }) => categories.some(({ id }) => input.categoryIds?.includes(id)));
215
+ }
216
+ intents = [...intents].sort((left, right) => input.sortDir === "asc"
217
+ ? left.createdAt.getTime() - right.createdAt.getTime()
218
+ : right.createdAt.getTime() - left.createdAt.getTime());
219
+ return {
220
+ intents: intents.slice(input.offset, input.offset + input.limit),
221
+ totalCount: intents.length,
222
+ };
223
+ }),
224
+ },
225
+ },
226
+ intentCategories: {
227
+ list: {
228
+ v1: implement(contract.intentCategories.list.v1).handler(async ({ input }) => {
229
+ const categories = this.requireMockEnvironmentCategories(input.environmentId);
230
+ return categories.map(({ linkedIntentIds, ...category }) => ({
231
+ ...category,
232
+ intentCount: linkedIntentIds.size,
233
+ }));
234
+ }),
235
+ },
236
+ create: {
237
+ v1: implement(contract.intentCategories.create.v1).handler(async ({ input }) => {
238
+ const categories = this.requireMockEnvironmentCategories(input.environmentId);
239
+ this.requireMockIntents(input.environmentId, input.intentIds ?? [], "BAD_REQUEST");
240
+ const { linkedIntentIds, ...category } = {
241
+ id: `cat-mock-${++this.mockData.intentCategoryCounter}`,
242
+ createdAt: new Date("2026-08-13T00:00:00.000Z"),
243
+ environmentId: input.environmentId,
244
+ name: input.name,
245
+ color: input.color ?? "gray",
246
+ linkedIntentIds: new Set(input.intentIds ?? []),
247
+ };
248
+ categories.push({ ...category, linkedIntentIds });
249
+ return category;
250
+ }),
251
+ },
252
+ update: {
253
+ v1: implement(contract.intentCategories.update.v1).handler(async ({ input }) => {
254
+ const category = this.requireMockIntentCategory(input.environmentId, input.categoryId);
255
+ category.name = input.name ?? category.name;
256
+ category.color = input.color ?? category.color;
257
+ const { linkedIntentIds, ...updated } = category;
258
+ return updated;
259
+ }),
260
+ },
261
+ delete: {
262
+ v1: implement(contract.intentCategories.delete.v1).handler(async ({ input }) => {
263
+ const category = this.requireMockIntentCategory(input.environmentId, input.categoryId);
264
+ this.mockData.intentCategories.set(input.environmentId, (this.mockData.intentCategories.get(input.environmentId) ?? []).filter(({ id }) => id !== category.id));
265
+ this.removeCategoryFromIntents(input.environmentId, category.id, null);
266
+ return { success: true };
267
+ }),
268
+ },
269
+ link: {
270
+ v1: implement(contract.intentCategories.link.v1).handler(async ({ input }) => {
271
+ const category = this.requireMockIntentCategory(input.environmentId, input.categoryId);
272
+ this.requireMockIntents(input.environmentId, input.intentIds, "NOT_FOUND");
273
+ for (const intentId of input.intentIds) {
274
+ category.linkedIntentIds.add(intentId);
275
+ }
276
+ for (const intent of this.mockData.intents.get(input.environmentId) ?? []) {
277
+ const isLinked = intent.intentIds.some((intentId) => category.linkedIntentIds.has(intentId));
278
+ if (isLinked && !intent.categories.some(({ id }) => id === category.id)) {
279
+ intent.categories.push({ id: category.id, name: category.name, color: category.color });
280
+ }
281
+ }
282
+ return { success: true };
283
+ }),
284
+ },
285
+ unlink: {
286
+ v1: implement(contract.intentCategories.unlink.v1).handler(async ({ input }) => {
287
+ const category = this.requireMockIntentCategory(input.environmentId, input.categoryId);
288
+ for (const intentId of input.intentIds) {
289
+ category.linkedIntentIds.delete(intentId);
290
+ }
291
+ this.removeCategoryFromIntents(input.environmentId, category.id, category.linkedIntentIds);
292
+ return { success: true };
293
+ }),
294
+ },
295
+ },
296
+ feedbacks: {
297
+ list: {
298
+ v1: implement(contract.feedbacks.list.v1).handler(async ({ input }) => {
299
+ if (!this.mockData.environments.has(input.environmentId)) {
300
+ throw new ORPCError("NOT_FOUND", { message: "Environment not found" });
301
+ }
302
+ let feedbacks = this.mockData.feedbacks.get(input.environmentId) ?? [];
303
+ if (input.search) {
304
+ const search = input.search.toLowerCase();
305
+ feedbacks = feedbacks.filter((feedback) => feedback.content.toLowerCase().includes(search) || feedback.source.toLowerCase().includes(search));
306
+ }
307
+ if (input.clientIds) {
308
+ feedbacks = feedbacks.filter(({ clientId }) => clientId !== null && input.clientIds?.includes(clientId));
309
+ }
310
+ return {
311
+ feedbacks: feedbacks.slice(input.offset, input.offset + input.limit),
312
+ totalCount: feedbacks.length,
313
+ };
314
+ }),
315
+ },
316
+ },
174
317
  projects: {
175
318
  list: {
176
319
  v1: implement(contract.projects.list.v1).handler(async ({ input }) => {
@@ -237,7 +380,7 @@ export class MockApiServer {
237
380
  name: productionEnvName,
238
381
  sourceBranch: null,
239
382
  mcpServerUrl: `https://mcp-${projectId}.alpic.ai`,
240
- domains: [`https://mcp-${projectId}.alpic.ai`],
383
+ domains: [`mcp-${projectId}.alpic.ai`],
241
384
  createdAt: new Date(),
242
385
  projectId,
243
386
  };
@@ -305,14 +448,15 @@ export class MockApiServer {
305
448
  });
306
449
  }
307
450
  const environmentId = randomUUID();
308
- const mcpServerUrl = `https://mcp-${environmentId}.alpic.ai`;
451
+ const mcpServerHost = `mcp-${environmentId}.alpic.ai`;
452
+ const mcpServerUrl = `https://${mcpServerHost}`;
309
453
  const createdAt = new Date();
310
454
  const environment = {
311
455
  id: environmentId,
312
456
  name: input.name,
313
457
  sourceBranch: input.sourceBranch,
314
458
  mcpServerUrl,
315
- domains: [mcpServerUrl],
459
+ domains: [mcpServerHost],
316
460
  createdAt,
317
461
  projectId: input.projectId,
318
462
  };
@@ -353,6 +497,30 @@ export class MockApiServer {
353
497
  return environment;
354
498
  }),
355
499
  },
500
+ delete: {
501
+ v1: implement(contract.environments.delete.v1).handler(async ({ input }) => {
502
+ const environment = this.mockData.environments.get(input.environmentId);
503
+ if (!environment) {
504
+ throw new ORPCError("NOT_FOUND", {
505
+ message: "Environment not found",
506
+ });
507
+ }
508
+ const project = this.mockData.projects.get(environment.projectId);
509
+ if (project?.productionEnvironment?.id === input.environmentId) {
510
+ throw new ORPCError("BAD_REQUEST", {
511
+ message: "Cannot delete the production environment of the project",
512
+ });
513
+ }
514
+ this.mockData.environments.delete(input.environmentId);
515
+ if (project) {
516
+ this.mockData.projects.set(environment.projectId, {
517
+ ...project,
518
+ environments: project.environments.filter((env) => env.id !== input.environmentId),
519
+ });
520
+ }
521
+ return { success: true };
522
+ }),
523
+ },
356
524
  getLogs: {
357
525
  v1: implement(contract.environments.getLogs.v1).handler(async ({ input }) => {
358
526
  const environment = this.mockData.environments.get(input.environmentId);
@@ -638,6 +806,73 @@ export class MockApiServer {
638
806
  }),
639
807
  },
640
808
  },
809
+ submissions: {
810
+ create: {
811
+ v1: implement(contract.submissions.create.v1).handler(async ({ input }) => {
812
+ const environment = this.mockData.environments.get(input.environmentId);
813
+ if (!environment) {
814
+ throw new ORPCError("NOT_FOUND", { message: "Environment not found" });
815
+ }
816
+ const formData = this.mockData.submissionPrefills.get(input.platform) ?? {};
817
+ const now = new Date();
818
+ const submission = {
819
+ id: `sub-${randomUUID()}`,
820
+ environmentId: input.environmentId,
821
+ platform: input.platform,
822
+ formData,
823
+ prefillSnapshot: formData,
824
+ auditId: "audit-1",
825
+ urlVerification: null,
826
+ createdAt: now,
827
+ updatedAt: now,
828
+ };
829
+ this.mockData.submissions.set(submission.id, submission);
830
+ return submission;
831
+ }),
832
+ },
833
+ list: {
834
+ v1: implement(contract.submissions.list.v1).handler(async ({ input }) => {
835
+ const project = this.mockData.projects.get(input.projectId);
836
+ if (!project) {
837
+ throw new ORPCError("NOT_FOUND", { message: "Project not found" });
838
+ }
839
+ const environmentIds = new Set(project.environments.map((environment) => environment.id));
840
+ let submissions = [...this.mockData.submissions.values()].filter((submission) => environmentIds.has(submission.environmentId));
841
+ if (input.environmentId) {
842
+ submissions = submissions.filter((submission) => submission.environmentId === input.environmentId);
843
+ }
844
+ if (input.platform) {
845
+ submissions = submissions.filter((submission) => submission.platform === input.platform);
846
+ }
847
+ return submissions;
848
+ }),
849
+ },
850
+ get: {
851
+ v1: implement(contract.submissions.get.v1).handler(async ({ input }) => {
852
+ const submission = this.mockData.submissions.get(input.submissionId);
853
+ if (!submission) {
854
+ throw new ORPCError("NOT_FOUND", { message: "Submission not found" });
855
+ }
856
+ return submission;
857
+ }),
858
+ },
859
+ update: {
860
+ v1: implement(contract.submissions.update.v1).handler(async ({ input }) => {
861
+ const submission = this.mockData.submissions.get(input.submissionId);
862
+ if (!submission) {
863
+ throw new ORPCError("NOT_FOUND", { message: "Submission not found" });
864
+ }
865
+ if (submission.platform !== input.platform) {
866
+ throw new ORPCError("BAD_REQUEST", {
867
+ message: `Platform mismatch: submission ${submission.id} is ${submission.platform}, payload claims ${input.platform}`,
868
+ });
869
+ }
870
+ const updated = { ...submission, formData: input.formData, updatedAt: new Date() };
871
+ this.mockData.submissions.set(submission.id, updated);
872
+ return updated;
873
+ }),
874
+ },
875
+ },
641
876
  deployments: {
642
877
  list: {
643
878
  v1: implement(contract.deployments.list.v1).handler(async ({ input }) => {
@@ -746,21 +981,7 @@ export class MockApiServer {
746
981
  }
747
982
  reset() {
748
983
  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
- };
984
+ this.mockData = createEmptyMockData();
764
985
  }
765
986
  async stop() {
766
987
  return new Promise((resolve, reject) => {
@@ -791,10 +1012,8 @@ export class MockApiServer {
791
1012
  return false;
792
1013
  }
793
1014
  }
794
- else {
795
- if (!pathPattern.test(call.path)) {
796
- return false;
797
- }
1015
+ else if (!pathPattern.test(call.path)) {
1016
+ return false;
798
1017
  }
799
1018
  }
800
1019
  return true;
@@ -815,23 +1034,27 @@ export class MockApiServer {
815
1034
  continue;
816
1035
  }
817
1036
  }
818
- else {
819
- if (!pathPattern.test(call.path)) {
820
- continue;
821
- }
1037
+ else if (!pathPattern.test(call.path)) {
1038
+ continue;
822
1039
  }
823
1040
  }
824
1041
  return call;
825
1042
  }
826
1043
  return undefined;
827
1044
  }
1045
+ setTunnelTicket(ticket) {
1046
+ this.mockData.tunnelTicket = ticket;
1047
+ }
828
1048
  setTeams(teams) {
829
1049
  this.mockData.teams = teams.map((team) => ({
830
1050
  ...team,
831
- createdAt: new Date("2024-01-01T00:00:00.000Z"),
1051
+ createdAt: new Date(Date.now() - 2 * 365 * 24 * 60 * 60 * 1000),
832
1052
  hasStripeAccount: false,
833
1053
  }));
834
1054
  }
1055
+ setTeamUsage(usage) {
1056
+ this.mockData.teamUsages.set(usage.teamId, usage);
1057
+ }
835
1058
  addEnvironmentVariables(environmentId, variables) {
836
1059
  this.mockData.environmentVariables.set(environmentId, variables);
837
1060
  }
@@ -865,6 +1088,50 @@ export class MockApiServer {
865
1088
  setPlayground(environmentId, playground) {
866
1089
  this.mockData.playgrounds.set(environmentId, playground);
867
1090
  }
1091
+ setIntents(environmentId, intents) {
1092
+ this.mockData.intents.set(environmentId, intents);
1093
+ }
1094
+ setIntentCategories(environmentId, categories) {
1095
+ this.mockData.intentCategories.set(environmentId, categories.map((category) => ({ ...category, linkedIntentIds: new Set(category.linkedIntentIds ?? []) })));
1096
+ }
1097
+ requireMockEnvironmentCategories(environmentId) {
1098
+ if (!this.mockData.environments.has(environmentId)) {
1099
+ throw new ORPCError("NOT_FOUND", { message: "Environment not found" });
1100
+ }
1101
+ const categories = this.mockData.intentCategories.get(environmentId) ?? [];
1102
+ this.mockData.intentCategories.set(environmentId, categories);
1103
+ return categories;
1104
+ }
1105
+ requireMockIntentCategory(environmentId, categoryId) {
1106
+ const category = this.requireMockEnvironmentCategories(environmentId).find(({ id }) => id === categoryId);
1107
+ if (!category) {
1108
+ throw new ORPCError("NOT_FOUND", { message: "Intent category not found" });
1109
+ }
1110
+ return category;
1111
+ }
1112
+ requireMockIntents(environmentId, intentIds, errorCode) {
1113
+ const knownIntentIds = new Set((this.mockData.intents.get(environmentId) ?? []).flatMap((intent) => intent.intentIds));
1114
+ if (intentIds.some((intentId) => !knownIntentIds.has(intentId))) {
1115
+ throw new ORPCError(errorCode, { message: "One or more intents not found" });
1116
+ }
1117
+ }
1118
+ removeCategoryFromIntents(environmentId, categoryId, remainingIntentIds) {
1119
+ for (const intent of this.mockData.intents.get(environmentId) ?? []) {
1120
+ const stillLinked = remainingIntentIds !== null && intent.intentIds.some((intentId) => remainingIntentIds.has(intentId));
1121
+ if (!stillLinked) {
1122
+ intent.categories = intent.categories.filter(({ id }) => id !== categoryId);
1123
+ }
1124
+ }
1125
+ }
1126
+ setFeedbacks(environmentId, feedbacks) {
1127
+ this.mockData.feedbacks.set(environmentId, feedbacks);
1128
+ }
1129
+ addSubmission(submission) {
1130
+ this.mockData.submissions.set(submission.id, submission);
1131
+ }
1132
+ setSubmissionPrefill(platform, formData) {
1133
+ this.mockData.submissionPrefills.set(platform, formData);
1134
+ }
868
1135
  addProject(project) {
869
1136
  this.mockData.projects.set(project.id, project);
870
1137
  if (project.productionEnvironment) {
@@ -873,7 +1140,7 @@ export class MockApiServer {
873
1140
  name: project.productionEnvironment.name,
874
1141
  sourceBranch: null,
875
1142
  mcpServerUrl: project.productionEnvironment.mcpServerUrl,
876
- domains: [project.productionEnvironment.mcpServerUrl],
1143
+ domains: [new URL(project.productionEnvironment.mcpServerUrl).host],
877
1144
  createdAt: new Date(),
878
1145
  projectId: project.id,
879
1146
  };
@@ -885,7 +1152,7 @@ export class MockApiServer {
885
1152
  name: env.name,
886
1153
  sourceBranch: env.sourceBranch,
887
1154
  mcpServerUrl: env.mcpServerUrl,
888
- domains: [env.mcpServerUrl],
1155
+ domains: [new URL(env.mcpServerUrl).host],
889
1156
  createdAt: env.createdAt,
890
1157
  projectId: project.id,
891
1158
  };