- database.test.ts: Remove assertions on non-existent workspaceDocId field (mapAnonymousContext no longer returns it) - executor-mcp.e2e.test.ts: Use internal.executorNode.runTask instead of api.executorNode.runTask (runTask is an internalAction) - executor-mcp.e2e.test.ts: Cast input to Request for .url access - credentialsNode.ts: Narrow string|null in async closure, add explicit return type and typed variables - tsconfig.json: Exclude apps/ from root tsconfig (web app has its own tsconfig with path aliases) - convex.config.ts: Add TODO comment noting actionCache can be removed
Unified · Split
| @@ -7,6 +7,8 @@ const app = defineApp(); · 6 unmodified lines | ||
| 7 | 7 | |
| 8 | 8 | app.use(workOSAuthKit); |
| 9 | 9 | app.use(stripe); |
| 10 | +// TODO: Remove actionCache component after confirming no deployments depend on it. | |
| 11 | +// All OpenAPI spec caching now uses Convex file storage (openApiSpecCache / workspaceToolCache tables). | |
| 10 | 12 | app.use(actionCache); |
| 11 | 13 | |
| 12 | 14 | export default app; |
| @@ -115,9 +115,10 @@ async function upsertVaultObject(args: { · 114 unmodified lines | ||
| 115 | 115 | const value = JSON.stringify(args.payload); |
| 116 | 116 | |
| 117 | 117 | if (args.existingObjectId) { |
| 118 | + const objectId: string = args.existingObjectId; | |
| 118 | 119 | const updated = await withVaultRetry(async () => { |
| 119 | 120 | return await workos.vault.updateObject({ |
| 120 | − id: args.existingObjectId, | |
| 121 | + id: objectId, | |
| 121 | 122 | value, |
| 122 | 123 | }); |
| 123 | 124 | }); |
| @@ -147,7 +148,7 @@ export const upsertCredential = action({ · 23 unmodified lines | ||
| 147 | 148 | provider: v.optional(credentialProviderValidator), |
| 148 | 149 | secretJson: v.any(), |
| 149 | 150 | }, |
| 150 | − handler: async (ctx, args) => { | |
| 151 | + handler: async (ctx, args): Promise<Record<string, unknown>> => { | |
| 151 | 152 | const provider = args.provider ?? "managed"; |
| 152 | 153 | const actorId = normalizedActorId(args.scope, args.actorId); |
| 153 | 154 | const submittedSecret = asRecord(args.secretJson); |
| @@ -166,13 +167,13 @@ export const upsertCredential = action({ · 12 unmodified lines | ||
| 166 | 167 | throw new Error("Encrypted storage value looks like a GitHub token. Paste the token in the token field."); |
| 167 | 168 | } |
| 168 | 169 | |
| 169 | − const existing = await ctx.runQuery(api.database.resolveCredential, { | |
| 170 | + const existing: Record<string, unknown> | null = await ctx.runQuery(api.database.resolveCredential, { | |
| 170 | 171 | workspaceId: args.workspaceId, |
| 171 | 172 | sourceKey: args.sourceKey, |
| 172 | 173 | scope: args.scope, |
| 173 | 174 | ...(args.scope === "actor" ? { actorId } : {}), |
| 174 | 175 | }); |
| 175 | − const existingObjectId = existing ? extractObjectId(asRecord(existing.secretJson)) : null; | |
| 176 | + const existingObjectId: string | null = existing ? extractObjectId(asRecord(existing.secretJson)) : null; | |
| 176 | 177 | |
| 177 | 178 | const objectId = (() => { |
| 178 | 179 | if (submittedObjectId) return submittedObjectId; |
| @@ -90,7 +90,6 @@ test("anonymous bootstrap links guest account membership", async () => { · 89 unmodified lines | ||
| 90 | 90 | expect(first.workspaceId).toContain("ws_"); |
| 91 | 91 | expect(first.actorId).toContain("anon_"); |
| 92 | 92 | expect(first.accountId).toBeDefined(); |
| 93 | − expect(first.workspaceDocId).toBeDefined(); | |
| 94 | 93 | expect(first.userId).toBeDefined(); |
| 95 | 94 | |
| 96 | 95 | const again = await t.mutation(api.database.bootstrapAnonymousSession, { |
| @@ -99,7 +98,6 @@ test("anonymous bootstrap links guest account membership", async () => { · 2 unmodified lines | ||
| 99 | 98 | |
| 100 | 99 | expect(again.sessionId).toBe(first.sessionId); |
| 101 | 100 | expect(again.accountId).toBe(first.accountId); |
| 102 | − expect(again.workspaceDocId).toBe(first.workspaceDocId); | |
| 103 | 101 | expect(again.userId).toBe(first.userId); |
| 104 | 102 | }); |
| 105 | 103 | |
| @@ -2,7 +2,7 @@ import { expect, test } from "bun:test"; · 1 unmodified line | ||
| 2 | 2 | import { convexTest } from "convex-test"; |
| 3 | 3 | import { Client } from "@modelcontextprotocol/sdk/client/index.js"; |
| 4 | 4 | import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js"; |
| 5 | −import { api } from "./_generated/api"; | |
| 5 | +import { api, internal } from "./_generated/api"; | |
| 6 | 6 | import schema from "./schema"; |
| 7 | 7 | |
| 8 | 8 | function setup() { |
| @@ -24,7 +24,7 @@ function createMcpTransport(t: ReturnType<typeof setup>, workspaceId: string, ac · 15 unmodified lines | ||
| 24 | 24 | |
| 25 | 25 | return new StreamableHTTPClientTransport(url, { |
| 26 | 26 | fetch: async (input, init) => { |
| 27 | − const raw = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url; | |
| 27 | + const raw = typeof input === "string" ? input : input instanceof URL ? input.toString() : (input as Request).url; | |
| 28 | 28 | const parsed = new URL(raw); |
| 29 | 29 | const path = `${parsed.pathname}${parsed.search}${parsed.hash}`; |
| 30 | 30 | return await t.fetch(path, init); |
| @@ -82,7 +82,7 @@ test("MCP run_code survives delayed approval and completes", async () => { · 51 unmodified lines | ||
| 82 | 82 | }); |
| 83 | 83 | |
| 84 | 84 | const taskId = await waitForTaskId(t, session.workspaceId); |
| 85 | − const runTask = t.action(api.executorNode.runTask, { taskId }); | |
| 85 | + const runTask = t.action(internal.executorNode.runTask, { taskId }); | |
| 86 | 86 | |
| 87 | 87 | const approvalId = await waitForPendingApproval(t, session.workspaceId, "admin.send_announcement"); |
| 88 | 88 | |
| @@ -133,7 +133,7 @@ test("MCP run_code returns denied after approval denial", async () => { · 44 unmodified lines | ||
| 133 | 133 | }); |
| 134 | 134 | |
| 135 | 135 | const taskId = await waitForTaskId(t, session.workspaceId); |
| 136 | − const runTask = t.action(api.executorNode.runTask, { taskId }); | |
| 136 | + const runTask = t.action(internal.executorNode.runTask, { taskId }); | |
| 137 | 137 | |
| 138 | 138 | const approvalId = await waitForPendingApproval(t, session.workspaceId, "admin.delete_data"); |
| 139 | 139 | await t.mutation(api.executor.resolveApproval, { |
| @@ -16,7 +16,6 @@ · 15 unmodified lines | ||
| 16 | 16 | "baseUrl": "." |
| 17 | 17 | }, |
| 18 | 18 | "include": [ |
| 19 | − "apps/**/*.ts", | |
| 20 | 19 | "packages/**/*.ts", |
| 21 | 20 | "convex/**/*.ts" |
| 22 | 21 | ] |