- 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 | "private": true, | 3 | "private": true, |
| 4 | "type": "module", | 4 | "type": "module", |
| 5 | "dependencies": { | 5 | "dependencies": { |
| 6 | "@executor/contracts": "workspace:*", | ||
| 6 | "@apidevtools/swagger-parser": "^12.1.0", | 7 | "@apidevtools/swagger-parser": "^12.1.0", |
| 7 | "@elysiajs/eden": "^1.4.6", | ||
| 8 | "@modelcontextprotocol/sdk": "^1.26.0", | 8 | "@modelcontextprotocol/sdk": "^1.26.0", |
| 9 | "@vercel/sandbox": "latest", | 9 | "@vercel/sandbox": "latest", |
| 10 | "convex": "latest", | 10 | "convex": "^1.31.7", |
| 11 | "elysia": "^1.4.22", | 11 | "elysia": "^1.4.22", |
| 12 | "openapi-typescript": "^7.10.1", | 12 | "openapi-typescript": "^7.10.1", |
| 13 | "zod": "^4.3.6" | 13 | "zod": "^4.3.6" |
| @@ -1,57 +1,25 @@ | |||
| 1 | export type TaskStatus = | 1 | // Re-export shared types from contracts |
| 2 | | "queued" | 2 | export type { |
| 3 | | "running" | 3 | TaskStatus, |
| 4 | | "completed" | 4 | ApprovalStatus, |
| 5 | | "failed" | 5 | PolicyDecision, |
| 6 | | "timed_out" | 6 | CredentialScope, |
| 7 | | "denied"; | 7 | ToolApprovalMode, |
| 8 | 8 | ToolSourceType, | |
| 9 | export type ApprovalStatus = "pending" | "approved" | "denied"; | 9 | TaskRecord, |
| 10 | 10 | ApprovalRecord, | |
| 11 | export interface TaskRecord { | 11 | PendingApprovalRecord, |
| 12 | id: string; | 12 | TaskEventRecord, |
| 13 | code: string; | 13 | AccessPolicyRecord, |
| 14 | runtimeId: string; | 14 | CredentialRecord, |
| 15 | status: TaskStatus; | 15 | ToolSourceRecord, |
| 16 | timeoutMs: number; | 16 | ToolDescriptor, |
| 17 | metadata: Record<string, unknown>; | 17 | AnonymousContext, |
| 18 | workspaceId: string; | 18 | } from "@executor/contracts"; |
| 19 | actorId?: string; | 19 | |
| 20 | clientId?: string; | 20 | import type { TaskStatus, CredentialScope, ToolApprovalMode } from "@executor/contracts"; |
| 21 | createdAt: number; | 21 | |
| 22 | updatedAt: number; | 22 | // ── Server-only types ───────────────────────────────────────────────────────── |
| 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 | } | ||
| 55 | 23 | ||
| 56 | export interface CreateTaskInput { | 24 | export interface CreateTaskInput { |
| 57 | code: string; | 25 | code: string; |
| @@ -63,15 +31,6 @@ export interface CreateTaskInput { · 5 unmodified lines | |||
| 63 | clientId?: string; | 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 | export interface SandboxExecutionRequest { | 34 | export interface SandboxExecutionRequest { |
| 76 | taskId: string; | 35 | taskId: string; |
| 77 | code: string; | 36 | code: string; |
| @@ -122,35 +81,6 @@ export interface SandboxRuntime { · 44 unmodified lines | |||
| 122 | ): Promise<SandboxExecutionResult>; | 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 | export type ToolCredentialAuthType = "bearer" | "apiKey" | "basic"; | 84 | export type ToolCredentialAuthType = "bearer" | "apiKey" | "basic"; |
| 155 | 85 | ||
| 156 | export interface ToolCredentialSpec { | 86 | export interface ToolCredentialSpec { |
| @@ -194,25 +124,3 @@ export interface ToolDefinition { · 37 unmodified lines | |||
| 194 | _pseudoTool?: boolean; | 124 | _pseudoTool?: boolean; |
| 195 | run(input: unknown, context: ToolRunContext): Promise<unknown>; | 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 | "lint": "eslint" | 9 | "lint": "eslint" |
| 10 | }, | 10 | }, |
| 11 | "dependencies": { | 11 | "dependencies": { |
| 12 | "@executor/contracts": "workspace:*", | ||
| 12 | "@monaco-editor/react": "^4.7.0", | 13 | "@monaco-editor/react": "^4.7.0", |
| 13 | "class-variance-authority": "^0.7.1", | 14 | "class-variance-authority": "^0.7.1", |
| 14 | "clsx": "^2.1.1", | 15 | "clsx": "^2.1.1", |
| 15 | "convex": "latest", | 16 | "convex": "^1.31.7", |
| 16 | "lucide-react": "^0.563.0", | 17 | "lucide-react": "^0.563.0", |
| 17 | "monaco-editor": "^0.55.1", | 18 | "monaco-editor": "^0.55.1", |
| 18 | "next": "16.1.6", | 19 | "next": "16.1.6", |
| @@ -1,18 +1,27 @@ | |||
| 1 | // Re-declare types locally since we can't use the monorepo contracts package | 1 | // Re-export shared types from contracts |
| 2 | // from the Next.js app easily. These mirror @executor/contracts exactly. | 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 | export type ApprovalDecision = "approved" | "denied"; | 24 | export type ApprovalDecision = "approved" | "denied"; |
| 14 | export type PolicyDecision = "allow" | "require_approval" | "deny"; | ||
| 15 | export type CredentialScope = "workspace" | "actor"; | ||
| 16 | 25 | ||
| 17 | export interface CreateTaskRequest { | 26 | export interface CreateTaskRequest { |
| 18 | code: string; | 27 | code: string; |
| @@ -29,45 +38,6 @@ export interface CreateTaskResponse { · 10 unmodified lines | |||
| 29 | status: TaskStatus; | 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 | export interface ResolveApprovalRequest { | 41 | export interface ResolveApprovalRequest { |
| 72 | workspaceId: string; | 42 | workspaceId: string; |
| 73 | decision: ApprovalDecision; | 43 | decision: ApprovalDecision; |
| @@ -75,42 +45,12 @@ export interface ResolveApprovalRequest { · 1 unmodified line | |||
| 75 | reason?: string; | 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 | export interface RuntimeTargetDescriptor { | 48 | export interface RuntimeTargetDescriptor { |
| 88 | id: string; | 49 | id: string; |
| 89 | label: string; | 50 | label: string; |
| 90 | description: string; | 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 | export interface CredentialDescriptor { | 54 | export interface CredentialDescriptor { |
| 115 | id: string; | 55 | id: string; |
| 116 | workspaceId: string; | 56 | workspaceId: string; |
| @@ -119,25 +59,3 @@ export interface CredentialDescriptor { · 2 unmodified lines | |||
| 119 | actorId?: string; | 59 | actorId?: string; |
| 120 | hasSecret: boolean; | 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 | "name": "executor-monorepo", | 2 | "name": "executor-monorepo", |
| 3 | "private": true, | 3 | "private": true, |
| 4 | "type": "module", | 4 | "type": "module", |
| 5 | "workspaces": [ | ||
| 6 | "apps/*", | ||
| 7 | "packages/*" | ||
| 8 | ], | ||
| 5 | "scripts": { | 9 | "scripts": { |
| 6 | "dev": "bun run --cwd apps/server dev", | 10 | "dev": "bun run --cwd apps/server dev", |
| 7 | "dev:worker": "bun run --cwd apps/server worker", | 11 | "dev:worker": "bun run --cwd apps/server worker", |
| @@ -14,12 +18,11 @@ · 6 unmodified lines | |||
| 14 | "typecheck": "bunx tsc --noEmit -p tsconfig.json" | 18 | "typecheck": "bunx tsc --noEmit -p tsconfig.json" |
| 15 | }, | 19 | }, |
| 16 | "dependencies": { | 20 | "dependencies": { |
| 17 | "convex": "latest" | 21 | "convex": "^1.31.7" |
| 18 | }, | 22 | }, |
| 19 | "devDependencies": { | 23 | "devDependencies": { |
| 20 | "@types/bun": "latest", | 24 | "@types/bun": "latest", |
| 21 | "convex-test": "^0.0.41", | 25 | "convex-test": "^0.0.41", |
| 22 | "esbuild": "^0.27.3", | ||
| 23 | "typescript": "latest" | 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 | } | ||