- Create executor/packages/contracts/ with all shared type definitions - Server and web now import from @executor/contracts instead of maintaining copies - Fixes type drift (e.g. TaskEventRecord.eventName was narrower in web) - Remove empty package stubs (confect/, convex/, database/) - Pin convex versions consistently, remove unused deps (@elysiajs/eden, esbuild)
Unified · Split
| @@ -3,11 +3,11 @@ · 2 unmodified lines | ||
| 3 | 3 | "private": true, |
| 4 | 4 | "type": "module", |
| 5 | 5 | "dependencies": { |
| 6 | + "@executor/contracts": "workspace:*", | |
| 6 | 7 | "@apidevtools/swagger-parser": "^12.1.0", |
| 7 | − "@elysiajs/eden": "^1.4.6", | |
| 8 | 8 | "@modelcontextprotocol/sdk": "^1.26.0", |
| 9 | 9 | "@vercel/sandbox": "latest", |
| 10 | − "convex": "latest", | |
| 10 | + "convex": "^1.31.7", | |
| 11 | 11 | "elysia": "^1.4.22", |
| 12 | 12 | "openapi-typescript": "^7.10.1", |
| 13 | 13 | "zod": "^4.3.6" |
| @@ -1,57 +1,25 @@ | ||
| 1 | −export type TaskStatus = | |
| 2 | − | "queued" | |
| 3 | − | "running" | |
| 4 | − | "completed" | |
| 5 | − | "failed" | |
| 6 | − | "timed_out" | |
| 7 | − | "denied"; | |
| 8 | − | |
| 9 | −export type ApprovalStatus = "pending" | "approved" | "denied"; | |
| 10 | − | |
| 11 | −export interface TaskRecord { | |
| 12 | − id: string; | |
| 13 | − code: string; | |
| 14 | − runtimeId: string; | |
| 15 | − status: TaskStatus; | |
| 16 | − timeoutMs: number; | |
| 17 | − metadata: Record<string, unknown>; | |
| 18 | − workspaceId: string; | |
| 19 | − actorId?: string; | |
| 20 | − clientId?: string; | |
| 21 | − createdAt: number; | |
| 22 | − updatedAt: number; | |
| 23 | − startedAt?: number; | |
| 24 | − completedAt?: number; | |
| 25 | − error?: string; | |
| 26 | − stdout?: string; | |
| 27 | − stderr?: string; | |
| 28 | − exitCode?: number; | |
| 29 | −} | |
| 30 | − | |
| 31 | −export interface ApprovalRecord { | |
| 32 | − id: string; | |
| 33 | − taskId: string; | |
| 34 | − toolPath: string; | |
| 35 | − input: unknown; | |
| 36 | − status: ApprovalStatus; | |
| 37 | − reason?: string; | |
| 38 | − reviewerId?: string; | |
| 39 | − createdAt: number; | |
| 40 | − resolvedAt?: number; | |
| 41 | −} | |
| 42 | − | |
| 43 | −export interface PendingApprovalRecord extends ApprovalRecord { | |
| 44 | − task: Pick<TaskRecord, "id" | "status" | "runtimeId" | "timeoutMs" | "createdAt">; | |
| 45 | −} | |
| 46 | − | |
| 47 | −export interface TaskEventRecord { | |
| 48 | − id: number; | |
| 49 | − taskId: string; | |
| 50 | − eventName: string; | |
| 51 | − type: string; | |
| 52 | − payload: unknown; | |
| 53 | − createdAt: number; | |
| 54 | −} | |
| 1 | +// Re-export shared types from contracts | |
| 2 | +export type { | |
| 3 | + TaskStatus, | |
| 4 | + ApprovalStatus, | |
| 5 | + PolicyDecision, | |
| 6 | + CredentialScope, | |
| 7 | + ToolApprovalMode, | |
| 8 | + ToolSourceType, | |
| 9 | + TaskRecord, | |
| 10 | + ApprovalRecord, | |
| 11 | + PendingApprovalRecord, | |
| 12 | + TaskEventRecord, | |
| 13 | + AccessPolicyRecord, | |
| 14 | + CredentialRecord, | |
| 15 | + ToolSourceRecord, | |
| 16 | + ToolDescriptor, | |
| 17 | + AnonymousContext, | |
| 18 | +} from "@executor/contracts"; | |
| 19 | + | |
| 20 | +import type { TaskStatus, CredentialScope, ToolApprovalMode } from "@executor/contracts"; | |
| 21 | + | |
| 22 | +// ── Server-only types ───────────────────────────────────────────────────────── | |
| 55 | 23 | |
| 56 | 24 | export interface CreateTaskInput { |
| 57 | 25 | code: string; |
| @@ -63,15 +31,6 @@ export interface CreateTaskInput { · 5 unmodified lines | ||
| 63 | 31 | clientId?: string; |
| 64 | 32 | } |
| 65 | 33 | |
| 66 | −export interface AnonymousContext { | |
| 67 | − sessionId: string; | |
| 68 | − workspaceId: string; | |
| 69 | − actorId: string; | |
| 70 | − clientId: string; | |
| 71 | − createdAt: number; | |
| 72 | − lastSeenAt: number; | |
| 73 | −} | |
| 74 | − | |
| 75 | 34 | export interface SandboxExecutionRequest { |
| 76 | 35 | taskId: string; |
| 77 | 36 | code: string; |
| @@ -122,35 +81,6 @@ export interface SandboxRuntime { · 44 unmodified lines | ||
| 122 | 81 | ): Promise<SandboxExecutionResult>; |
| 123 | 82 | } |
| 124 | 83 | |
| 125 | −export type ToolApprovalMode = "auto" | "required"; | |
| 126 | − | |
| 127 | −export type PolicyDecision = "allow" | "require_approval" | "deny"; | |
| 128 | − | |
| 129 | −export interface AccessPolicyRecord { | |
| 130 | − id: string; | |
| 131 | − workspaceId: string; | |
| 132 | − actorId?: string; | |
| 133 | − clientId?: string; | |
| 134 | − toolPathPattern: string; | |
| 135 | − decision: PolicyDecision; | |
| 136 | − priority: number; | |
| 137 | − createdAt: number; | |
| 138 | − updatedAt: number; | |
| 139 | −} | |
| 140 | − | |
| 141 | −export type CredentialScope = "workspace" | "actor"; | |
| 142 | − | |
| 143 | −export interface CredentialRecord { | |
| 144 | − id: string; | |
| 145 | − workspaceId: string; | |
| 146 | − sourceKey: string; | |
| 147 | − scope: CredentialScope; | |
| 148 | − actorId?: string; | |
| 149 | − secretJson: Record<string, unknown>; | |
| 150 | − createdAt: number; | |
| 151 | − updatedAt: number; | |
| 152 | −} | |
| 153 | − | |
| 154 | 84 | export type ToolCredentialAuthType = "bearer" | "apiKey" | "basic"; |
| 155 | 85 | |
| 156 | 86 | export interface ToolCredentialSpec { |
| @@ -194,25 +124,3 @@ export interface ToolDefinition { · 37 unmodified lines | ||
| 194 | 124 | _pseudoTool?: boolean; |
| 195 | 125 | run(input: unknown, context: ToolRunContext): Promise<unknown>; |
| 196 | 126 | } |
| 197 | − | |
| 198 | −export interface ToolDescriptor { | |
| 199 | − path: string; | |
| 200 | − description: string; | |
| 201 | − approval: ToolApprovalMode; | |
| 202 | − source?: string; | |
| 203 | − argsType?: string; | |
| 204 | − returnsType?: string; | |
| 205 | −} | |
| 206 | − | |
| 207 | −export type ToolSourceType = "mcp" | "openapi" | "graphql"; | |
| 208 | − | |
| 209 | −export interface ToolSourceRecord { | |
| 210 | − id: string; | |
| 211 | − workspaceId: string; | |
| 212 | − name: string; | |
| 213 | − type: ToolSourceType; | |
| 214 | − config: Record<string, unknown>; | |
| 215 | − enabled: boolean; | |
| 216 | − createdAt: number; | |
| 217 | − updatedAt: number; | |
| 218 | −} | |
| @@ -9,10 +9,11 @@ · 8 unmodified lines | ||
| 9 | 9 | "lint": "eslint" |
| 10 | 10 | }, |
| 11 | 11 | "dependencies": { |
| 12 | + "@executor/contracts": "workspace:*", | |
| 12 | 13 | "@monaco-editor/react": "^4.7.0", |
| 13 | 14 | "class-variance-authority": "^0.7.1", |
| 14 | 15 | "clsx": "^2.1.1", |
| 15 | − "convex": "latest", | |
| 16 | + "convex": "^1.31.7", | |
| 16 | 17 | "lucide-react": "^0.563.0", |
| 17 | 18 | "monaco-editor": "^0.55.1", |
| 18 | 19 | "next": "16.1.6", |
| @@ -1,18 +1,27 @@ | ||
| 1 | −// Re-declare types locally since we can't use the monorepo contracts package | |
| 2 | −// from the Next.js app easily. These mirror @executor/contracts exactly. | |
| 1 | +// Re-export shared types from contracts | |
| 2 | +export type { | |
| 3 | + TaskStatus, | |
| 4 | + ApprovalStatus, | |
| 5 | + PolicyDecision, | |
| 6 | + CredentialScope, | |
| 7 | + ToolApprovalMode, | |
| 8 | + ToolSourceType, | |
| 9 | + TaskRecord, | |
| 10 | + ApprovalRecord, | |
| 11 | + PendingApprovalRecord, | |
| 12 | + TaskEventRecord, | |
| 13 | + AccessPolicyRecord, | |
| 14 | + CredentialRecord, | |
| 15 | + ToolSourceRecord, | |
| 16 | + ToolDescriptor, | |
| 17 | + AnonymousContext, | |
| 18 | +} from "@executor/contracts"; | |
| 19 | + | |
| 20 | +// ── Web-only types ──────────────────────────────────────────────────────────── | |
| 21 | + | |
| 22 | +import type { TaskStatus, ApprovalStatus, CredentialScope } from "@executor/contracts"; | |
| 3 | 23 | |
| 4 | −export type TaskStatus = | |
| 5 | − | "queued" | |
| 6 | − | "running" | |
| 7 | − | "completed" | |
| 8 | − | "failed" | |
| 9 | − | "timed_out" | |
| 10 | − | "denied"; | |
| 11 | − | |
| 12 | −export type ApprovalStatus = "pending" | "approved" | "denied"; | |
| 13 | 24 | export type ApprovalDecision = "approved" | "denied"; |
| 14 | −export type PolicyDecision = "allow" | "require_approval" | "deny"; | |
| 15 | −export type CredentialScope = "workspace" | "actor"; | |
| 16 | 25 | |
| 17 | 26 | export interface CreateTaskRequest { |
| 18 | 27 | code: string; |
| @@ -29,45 +38,6 @@ export interface CreateTaskResponse { · 10 unmodified lines | ||
| 29 | 38 | status: TaskStatus; |
| 30 | 39 | } |
| 31 | 40 | |
| 32 | −export interface TaskRecord { | |
| 33 | − id: string; | |
| 34 | − code: string; | |
| 35 | − runtimeId: string; | |
| 36 | − timeoutMs: number; | |
| 37 | − metadata: Record<string, unknown>; | |
| 38 | − workspaceId: string; | |
| 39 | − actorId?: string; | |
| 40 | − clientId?: string; | |
| 41 | − status: TaskStatus; | |
| 42 | − createdAt: number; | |
| 43 | − updatedAt: number; | |
| 44 | − startedAt?: number; | |
| 45 | − completedAt?: number; | |
| 46 | − stdout?: string; | |
| 47 | − stderr?: string; | |
| 48 | − exitCode?: number; | |
| 49 | − error?: string; | |
| 50 | −} | |
| 51 | − | |
| 52 | −export interface ApprovalRecord { | |
| 53 | − id: string; | |
| 54 | − taskId: string; | |
| 55 | − toolPath: string; | |
| 56 | − input: unknown; | |
| 57 | − status: ApprovalStatus; | |
| 58 | − createdAt: number; | |
| 59 | − resolvedAt?: number; | |
| 60 | − reviewerId?: string; | |
| 61 | − reason?: string; | |
| 62 | −} | |
| 63 | − | |
| 64 | −export interface PendingApprovalRecord extends ApprovalRecord { | |
| 65 | − task: Pick< | |
| 66 | − TaskRecord, | |
| 67 | − "id" | "status" | "runtimeId" | "timeoutMs" | "createdAt" | |
| 68 | − >; | |
| 69 | −} | |
| 70 | − | |
| 71 | 41 | export interface ResolveApprovalRequest { |
| 72 | 42 | workspaceId: string; |
| 73 | 43 | decision: ApprovalDecision; |
| @@ -75,42 +45,12 @@ export interface ResolveApprovalRequest { · 1 unmodified line | ||
| 75 | 45 | reason?: string; |
| 76 | 46 | } |
| 77 | 47 | |
| 78 | −export interface AnonymousContext { | |
| 79 | − sessionId: string; | |
| 80 | − workspaceId: string; | |
| 81 | − actorId: string; | |
| 82 | − clientId: string; | |
| 83 | − createdAt: number; | |
| 84 | − lastSeenAt: number; | |
| 85 | −} | |
| 86 | − | |
| 87 | 48 | export interface RuntimeTargetDescriptor { |
| 88 | 49 | id: string; |
| 89 | 50 | label: string; |
| 90 | 51 | description: string; |
| 91 | 52 | } |
| 92 | 53 | |
| 93 | −export interface ToolDescriptor { | |
| 94 | − path: string; | |
| 95 | − description: string; | |
| 96 | − approval: "auto" | "required"; | |
| 97 | − source?: string; | |
| 98 | − argsType?: string; | |
| 99 | − returnsType?: string; | |
| 100 | −} | |
| 101 | − | |
| 102 | −export interface AccessPolicyRecord { | |
| 103 | − id: string; | |
| 104 | − workspaceId: string; | |
| 105 | − actorId?: string; | |
| 106 | − clientId?: string; | |
| 107 | − toolPathPattern: string; | |
| 108 | − decision: PolicyDecision; | |
| 109 | − priority: number; | |
| 110 | − createdAt: number; | |
| 111 | − updatedAt: number; | |
| 112 | −} | |
| 113 | − | |
| 114 | 54 | export interface CredentialDescriptor { |
| 115 | 55 | id: string; |
| 116 | 56 | workspaceId: string; |
| @@ -119,25 +59,3 @@ export interface CredentialDescriptor { · 2 unmodified lines | ||
| 119 | 59 | actorId?: string; |
| 120 | 60 | hasSecret: boolean; |
| 121 | 61 | } |
| 122 | − | |
| 123 | −export type ToolSourceType = "mcp" | "openapi" | "graphql"; | |
| 124 | − | |
| 125 | −export interface ToolSourceRecord { | |
| 126 | − id: string; | |
| 127 | − workspaceId: string; | |
| 128 | − name: string; | |
| 129 | − type: ToolSourceType; | |
| 130 | − config: Record<string, unknown>; | |
| 131 | − enabled: boolean; | |
| 132 | − createdAt: number; | |
| 133 | − updatedAt: number; | |
| 134 | −} | |
| 135 | − | |
| 136 | −export interface TaskEventRecord { | |
| 137 | − id: number; | |
| 138 | − taskId: string; | |
| 139 | − eventName: "task" | "approval"; | |
| 140 | − type: string; | |
| 141 | − payload: Record<string, unknown>; | |
| 142 | − createdAt: number; | |
| 143 | −} | |
| @@ -2,6 +2,10 @@ · 1 unmodified line | ||
| 2 | 2 | "name": "executor-monorepo", |
| 3 | 3 | "private": true, |
| 4 | 4 | "type": "module", |
| 5 | + "workspaces": [ | |
| 6 | + "apps/*", | |
| 7 | + "packages/*" | |
| 8 | + ], | |
| 5 | 9 | "scripts": { |
| 6 | 10 | "dev": "bun run --cwd apps/server dev", |
| 7 | 11 | "dev:worker": "bun run --cwd apps/server worker", |
| @@ -14,12 +18,11 @@ · 6 unmodified lines | ||
| 14 | 18 | "typecheck": "bunx tsc --noEmit -p tsconfig.json" |
| 15 | 19 | }, |
| 16 | 20 | "dependencies": { |
| 17 | − "convex": "latest" | |
| 21 | + "convex": "^1.31.7" | |
| 18 | 22 | }, |
| 19 | 23 | "devDependencies": { |
| 20 | 24 | "@types/bun": "latest", |
| 21 | 25 | "convex-test": "^0.0.41", |
| 22 | − "esbuild": "^0.27.3", | |
| 23 | 26 | "typescript": "latest" |
| 24 | 27 | } |
| 25 | 28 | } |
| @@ -0,0 +1,7 @@ | ||
| 1 | +{ | |
| 2 | + "name": "@executor/contracts", | |
| 3 | + "version": "0.0.1", | |
| 4 | + "private": true, | |
| 5 | + "main": "src/index.ts", | |
| 6 | + "types": "src/index.ts" | |
| 7 | +} | |
| @@ -0,0 +1,120 @@ | ||
| 1 | +// ── Status enums ────────────────────────────────────────────────────────────── | |
| 2 | + | |
| 3 | +export type TaskStatus = | |
| 4 | + | "queued" | |
| 5 | + | "running" | |
| 6 | + | "completed" | |
| 7 | + | "failed" | |
| 8 | + | "timed_out" | |
| 9 | + | "denied"; | |
| 10 | + | |
| 11 | +export type ApprovalStatus = "pending" | "approved" | "denied"; | |
| 12 | + | |
| 13 | +export type PolicyDecision = "allow" | "require_approval" | "deny"; | |
| 14 | + | |
| 15 | +export type CredentialScope = "workspace" | "actor"; | |
| 16 | + | |
| 17 | +export type ToolApprovalMode = "auto" | "required"; | |
| 18 | + | |
| 19 | +export type ToolSourceType = "mcp" | "openapi" | "graphql"; | |
| 20 | + | |
| 21 | +// ── Records ─────────────────────────────────────────────────────────────────── | |
| 22 | + | |
| 23 | +export interface TaskRecord { | |
| 24 | + id: string; | |
| 25 | + code: string; | |
| 26 | + runtimeId: string; | |
| 27 | + status: TaskStatus; | |
| 28 | + timeoutMs: number; | |
| 29 | + metadata: Record<string, unknown>; | |
| 30 | + workspaceId: string; | |
| 31 | + actorId?: string; | |
| 32 | + clientId?: string; | |
| 33 | + createdAt: number; | |
| 34 | + updatedAt: number; | |
| 35 | + startedAt?: number; | |
| 36 | + completedAt?: number; | |
| 37 | + error?: string; | |
| 38 | + stdout?: string; | |
| 39 | + stderr?: string; | |
| 40 | + exitCode?: number; | |
| 41 | +} | |
| 42 | + | |
| 43 | +export interface ApprovalRecord { | |
| 44 | + id: string; | |
| 45 | + taskId: string; | |
| 46 | + toolPath: string; | |
| 47 | + input: unknown; | |
| 48 | + status: ApprovalStatus; | |
| 49 | + reason?: string; | |
| 50 | + reviewerId?: string; | |
| 51 | + createdAt: number; | |
| 52 | + resolvedAt?: number; | |
| 53 | +} | |
| 54 | + | |
| 55 | +export interface PendingApprovalRecord extends ApprovalRecord { | |
| 56 | + task: Pick<TaskRecord, "id" | "status" | "runtimeId" | "timeoutMs" | "createdAt">; | |
| 57 | +} | |
| 58 | + | |
| 59 | +export interface TaskEventRecord { | |
| 60 | + id: number; | |
| 61 | + taskId: string; | |
| 62 | + eventName: string; | |
| 63 | + type: string; | |
| 64 | + payload: unknown; | |
| 65 | + createdAt: number; | |
| 66 | +} | |
| 67 | + | |
| 68 | +export interface AccessPolicyRecord { | |
| 69 | + id: string; | |
| 70 | + workspaceId: string; | |
| 71 | + actorId?: string; | |
| 72 | + clientId?: string; | |
| 73 | + toolPathPattern: string; | |
| 74 | + decision: PolicyDecision; | |
| 75 | + priority: number; | |
| 76 | + createdAt: number; | |
| 77 | + updatedAt: number; | |
| 78 | +} | |
| 79 | + | |
| 80 | +export interface CredentialRecord { | |
| 81 | + id: string; | |
| 82 | + workspaceId: string; | |
| 83 | + sourceKey: string; | |
| 84 | + scope: CredentialScope; | |
| 85 | + actorId?: string; | |
| 86 | + secretJson: Record<string, unknown>; | |
| 87 | + createdAt: number; | |
| 88 | + updatedAt: number; | |
| 89 | +} | |
| 90 | + | |
| 91 | +export interface ToolSourceRecord { | |
| 92 | + id: string; | |
| 93 | + workspaceId: string; | |
| 94 | + name: string; | |
| 95 | + type: ToolSourceType; | |
| 96 | + config: Record<string, unknown>; | |
| 97 | + enabled: boolean; | |
| 98 | + createdAt: number; | |
| 99 | + updatedAt: number; | |
| 100 | +} | |
| 101 | + | |
| 102 | +// ── Descriptors ─────────────────────────────────────────────────────────────── | |
| 103 | + | |
| 104 | +export interface ToolDescriptor { | |
| 105 | + path: string; | |
| 106 | + description: string; | |
| 107 | + approval: ToolApprovalMode; | |
| 108 | + source?: string; | |
| 109 | + argsType?: string; | |
| 110 | + returnsType?: string; | |
| 111 | +} | |
| 112 | + | |
| 113 | +export interface AnonymousContext { | |
| 114 | + sessionId: string; | |
| 115 | + workspaceId: string; | |
| 116 | + actorId: string; | |
| 117 | + clientId: string; | |
| 118 | + createdAt: number; | |
| 119 | + lastSeenAt: number; | |
| 120 | +} | |
| @@ -0,0 +1,11 @@ | ||
| 1 | +{ | |
| 2 | + "compilerOptions": { | |
| 3 | + "strict": true, | |
| 4 | + "moduleResolution": "bundler", | |
| 5 | + "target": "ESNext", | |
| 6 | + "module": "ESNext", | |
| 7 | + "noEmit": true, | |
| 8 | + "skipLibCheck": true | |
| 9 | + }, | |
| 10 | + "include": ["src/**/*.ts"] | |
| 11 | +} | |