Unified · Split
| @@ -0,0 +1,286 @@ | |||
| 1 | import path from "node:path"; | ||
| 2 | |||
| 3 | type ApprovalStatus = "pending" | "approved" | "denied"; | ||
| 4 | |||
| 5 | interface ApprovalItem { | ||
| 6 | id: string; | ||
| 7 | title: string; | ||
| 8 | details: string; | ||
| 9 | status: ApprovalStatus; | ||
| 10 | createdAt: number; | ||
| 11 | } | ||
| 12 | |||
| 13 | function parseArgs(argv: string[]): { session: string; inline: boolean; tmuxSession: string; agentCommand: string } { | ||
| 14 | const session = argv[0] && !argv[0].startsWith("-") ? argv[0] : "claude"; | ||
| 15 | const inline = argv.includes("--inline"); | ||
| 16 | |||
| 17 | const tmuxSessionFlagIndex = argv.indexOf("--tmux-session"); | ||
| 18 | const tmuxSession = tmuxSessionFlagIndex >= 0 && argv[tmuxSessionFlagIndex + 1] | ||
| 19 | ? String(argv[tmuxSessionFlagIndex + 1]) | ||
| 20 | : "executor-approvals"; | ||
| 21 | |||
| 22 | const agentCommandFlagIndex = argv.indexOf("--agent-cmd"); | ||
| 23 | const agentCommand = agentCommandFlagIndex >= 0 && argv[agentCommandFlagIndex + 1] | ||
| 24 | ? String(argv[agentCommandFlagIndex + 1]) | ||
| 25 | : session; | ||
| 26 | |||
| 27 | return { session, inline, tmuxSession, agentCommand }; | ||
| 28 | } | ||
| 29 | |||
| 30 | function hasTmuxBinary(): boolean { | ||
| 31 | const result = Bun.spawnSync({ cmd: ["tmux", "-V"] }); | ||
| 32 | return result.exitCode === 0; | ||
| 33 | } | ||
| 34 | |||
| 35 | function getTmuxClients(): string[] { | ||
| 36 | const result = Bun.spawnSync({ cmd: ["tmux", "list-clients", "-F", "#{client_name}"] }); | ||
| 37 | if (result.exitCode !== 0) return []; | ||
| 38 | |||
| 39 | return Buffer.from(result.stdout) | ||
| 40 | .toString("utf8") | ||
| 41 | .split("\n") | ||
| 42 | .map((line) => line.trim()) | ||
| 43 | .filter((line) => line.length > 0 && line !== "no current client"); | ||
| 44 | } | ||
| 45 | |||
| 46 | async function launchTmuxPopup(session: string, clientTarget: string): Promise<void> { | ||
| 47 | const scriptPath = path.resolve(import.meta.dir, "approval-client.ts"); | ||
| 48 | const command = `bun run ${scriptPath} ${session} --inline`; | ||
| 49 | Bun.spawnSync({ | ||
| 50 | cmd: ["tmux", "display-popup", "-t", clientTarget, "-E", "-w", "82%", "-h", "70%", command], | ||
| 51 | stdin: "inherit", | ||
| 52 | stdout: "inherit", | ||
| 53 | stderr: "inherit", | ||
| 54 | }); | ||
| 55 | } | ||
| 56 | |||
| 57 | function shellQuote(value: string): string { | ||
| 58 | return `'${value.replace(/'/g, "'\\''")}'`; | ||
| 59 | } | ||
| 60 | |||
| 61 | function tmuxSessionExists(tmuxSession: string): boolean { | ||
| 62 | const result = Bun.spawnSync({ cmd: ["tmux", "has-session", "-t", tmuxSession] }); | ||
| 63 | return result.exitCode === 0; | ||
| 64 | } | ||
| 65 | |||
| 66 | function runTmuxCommand(cmd: string[]): boolean { | ||
| 67 | const result = Bun.spawnSync({ | ||
| 68 | cmd, | ||
| 69 | stdin: "inherit", | ||
| 70 | stdout: "inherit", | ||
| 71 | stderr: "inherit", | ||
| 72 | }); | ||
| 73 | return result.exitCode === 0; | ||
| 74 | } | ||
| 75 | |||
| 76 | function ensureSessionUiOptions(tmuxSession: string): void { | ||
| 77 | runTmuxCommand(["tmux", "set-option", "-t", tmuxSession, "mouse", "on"]); | ||
| 78 | runTmuxCommand(["tmux", "set-option", "-t", tmuxSession, "pane-border-status", "top"]); | ||
| 79 | runTmuxCommand(["tmux", "set-option", "-t", tmuxSession, "pane-border-format", "#{pane_index}: #{pane_title}"]); | ||
| 80 | } | ||
| 81 | |||
| 82 | function setPaneTitles(windowTarget: string): void { | ||
| 83 | runTmuxCommand(["tmux", "select-pane", "-t", `${windowTarget}.0`, "-T", "Claude"]); | ||
| 84 | runTmuxCommand(["tmux", "select-pane", "-t", `${windowTarget}.1`, "-T", "Approvals"]); | ||
| 85 | } | ||
| 86 | |||
| 87 | async function launchManagedTmuxWorkspace(session: string, tmuxSession: string, agentCommand: string): Promise<boolean> { | ||
| 88 | const scriptPath = path.resolve(import.meta.dir, "approval-client.ts"); | ||
| 89 | const approvalCommand = `bun run ${shellQuote(scriptPath)} ${shellQuote(session)} --inline`; | ||
| 90 | |||
| 91 | if (!tmuxSessionExists(tmuxSession)) { | ||
| 92 | const created = runTmuxCommand(["tmux", "new-session", "-d", "-s", tmuxSession, agentCommand]); | ||
| 93 | if (!created) return false; | ||
| 94 | |||
| 95 | ensureSessionUiOptions(tmuxSession); | ||
| 96 | |||
| 97 | const split = runTmuxCommand(["tmux", "split-window", "-t", `${tmuxSession}:0`, "-v", "-p", "30", approvalCommand]); | ||
| 98 | if (!split) return false; | ||
| 99 | |||
| 100 | setPaneTitles(`${tmuxSession}:0`); | ||
| 101 | runTmuxCommand(["tmux", "select-pane", "-t", `${tmuxSession}:0.0`]); | ||
| 102 | return runTmuxCommand(["tmux", "attach-session", "-t", tmuxSession]); | ||
| 103 | } | ||
| 104 | |||
| 105 | const windowName = `exec-${Date.now()}`; | ||
| 106 | const windowTarget = `${tmuxSession}:${windowName}`; | ||
| 107 | ensureSessionUiOptions(tmuxSession); | ||
| 108 | |||
| 109 | const createdWindow = runTmuxCommand(["tmux", "new-window", "-t", `${tmuxSession}:`, "-n", windowName, agentCommand]); | ||
| 110 | if (!createdWindow) return false; | ||
| 111 | |||
| 112 | const splitWindow = runTmuxCommand(["tmux", "split-window", "-t", windowTarget, "-v", "-p", "30", approvalCommand]); | ||
| 113 | if (!splitWindow) return false; | ||
| 114 | |||
| 115 | setPaneTitles(windowTarget); | ||
| 116 | runTmuxCommand(["tmux", "select-pane", "-t", `${windowTarget}.0`]); | ||
| 117 | return runTmuxCommand(["tmux", "attach-session", "-t", tmuxSession]); | ||
| 118 | } | ||
| 119 | |||
| 120 | function makeApproval(session: string, index: number): ApprovalItem { | ||
| 121 | const actions = [ | ||
| 122 | "Write DNS record", | ||
| 123 | "Delete production file", | ||
| 124 | "Rotate API token", | ||
| 125 | "Deploy migration", | ||
| 126 | "Run destructive cleanup", | ||
| 127 | ]; | ||
| 128 | |||
| 129 | const title = actions[index % actions.length] ?? "Tool action"; | ||
| 130 | const id = `appr_${crypto.randomUUID().slice(0, 8)}`; | ||
| 131 | |||
| 132 | return { | ||
| 133 | id, | ||
| 134 | title, | ||
| 135 | details: `Session: ${session} -> tools.example.action()`, | ||
| 136 | status: "pending", | ||
| 137 | createdAt: Date.now(), | ||
| 138 | }; | ||
| 139 | } | ||
| 140 | |||
| 141 | function statusMarker(status: ApprovalStatus): string { | ||
| 142 | if (status === "approved") return "[approved]"; | ||
| 143 | if (status === "denied") return "[denied]"; | ||
| 144 | return "[pending]"; | ||
| 145 | } | ||
| 146 | |||
| 147 | function clearAndRender(session: string, approvals: ApprovalItem[], selected: number): void { | ||
| 148 | process.stdout.write("\x1Bc"); | ||
| 149 | process.stdout.write("Approval Popup Demo\n"); | ||
| 150 | process.stdout.write(`Session: ${session}\n`); | ||
| 151 | process.stdout.write("Controls: j/k move a approve d deny n new request q quit\n"); | ||
| 152 | process.stdout.write("tmux tip: Ctrl+b then o to switch panes (mouse is enabled).\n"); | ||
| 153 | process.stdout.write("-".repeat(72) + "\n"); | ||
| 154 | |||
| 155 | if (approvals.length === 0) { | ||
| 156 | process.stdout.write("No approvals. Press n to enqueue one.\n"); | ||
| 157 | return; | ||
| 158 | } | ||
| 159 | |||
| 160 | approvals.forEach((item, idx) => { | ||
| 161 | const pointer = idx === selected ? ">" : " "; | ||
| 162 | const time = new Date(item.createdAt).toLocaleTimeString(); | ||
| 163 | process.stdout.write(`${pointer} ${statusMarker(item.status)} ${item.id} ${item.title} (${time})\n`); | ||
| 164 | process.stdout.write(` ${item.details}\n`); | ||
| 165 | }); | ||
| 166 | } | ||
| 167 | |||
| 168 | async function runInlineUi(session: string): Promise<number> { | ||
| 169 | const approvals: ApprovalItem[] = [makeApproval(session, 0)]; | ||
| 170 | let selected = 0; | ||
| 171 | let sequence = 1; | ||
| 172 | |||
| 173 | const enqueueTimer = setInterval(() => { | ||
| 174 | approvals.unshift(makeApproval(session, sequence)); | ||
| 175 | sequence += 1; | ||
| 176 | selected = 0; | ||
| 177 | clearAndRender(session, approvals, selected); | ||
| 178 | }, 12000); | ||
| 179 | |||
| 180 | const cleanup = (): void => { | ||
| 181 | clearInterval(enqueueTimer); | ||
| 182 | if (process.stdin.isTTY) { | ||
| 183 | process.stdin.setRawMode(false); | ||
| 184 | } | ||
| 185 | process.stdin.pause(); | ||
| 186 | }; | ||
| 187 | |||
| 188 | clearAndRender(session, approvals, selected); | ||
| 189 | |||
| 190 | return await new Promise<number>((resolve) => { | ||
| 191 | if (process.stdin.isTTY) { | ||
| 192 | process.stdin.setRawMode(true); | ||
| 193 | } | ||
| 194 | |||
| 195 | process.stdin.setEncoding("utf8"); | ||
| 196 | process.stdin.resume(); | ||
| 197 | |||
| 198 | const finish = (code: number) => { | ||
| 199 | cleanup(); | ||
| 200 | resolve(code); | ||
| 201 | }; | ||
| 202 | |||
| 203 | process.stdin.on("data", (chunk) => { | ||
| 204 | const key = typeof chunk === "string" ? chunk : chunk.toString("utf8"); | ||
| 205 | |||
| 206 | if (key === "\u0003" || key === "q") { | ||
| 207 | finish(0); | ||
| 208 | return; | ||
| 209 | } | ||
| 210 | |||
| 211 | if (key === "j" || key === "\u001B[B") { | ||
| 212 | if (approvals.length > 0) { | ||
| 213 | selected = Math.min(approvals.length - 1, selected + 1); | ||
| 214 | } | ||
| 215 | clearAndRender(session, approvals, selected); | ||
| 216 | return; | ||
| 217 | } | ||
| 218 | |||
| 219 | if (key === "k" || key === "\u001B[A") { | ||
| 220 | if (approvals.length > 0) { | ||
| 221 | selected = Math.max(0, selected - 1); | ||
| 222 | } | ||
| 223 | clearAndRender(session, approvals, selected); | ||
| 224 | return; | ||
| 225 | } | ||
| 226 | |||
| 227 | if (key === "n") { | ||
| 228 | approvals.unshift(makeApproval(session, sequence)); | ||
| 229 | sequence += 1; | ||
| 230 | selected = 0; | ||
| 231 | clearAndRender(session, approvals, selected); | ||
| 232 | return; | ||
| 233 | } | ||
| 234 | |||
| 235 | const current = approvals[selected]; | ||
| 236 | if (!current || current.status !== "pending") { | ||
| 237 | return; | ||
| 238 | } | ||
| 239 | |||
| 240 | if (key === "a") { | ||
| 241 | current.status = "approved"; | ||
| 242 | clearAndRender(session, approvals, selected); | ||
| 243 | return; | ||
| 244 | } | ||
| 245 | |||
| 246 | if (key === "d") { | ||
| 247 | current.status = "denied"; | ||
| 248 | clearAndRender(session, approvals, selected); | ||
| 249 | } | ||
| 250 | }); | ||
| 251 | }); | ||
| 252 | } | ||
| 253 | |||
| 254 | async function main(): Promise<number> { | ||
| 255 | const { session, inline, tmuxSession, agentCommand } = parseArgs(process.argv.slice(2)); | ||
| 256 | |||
| 257 | if (!inline) { | ||
| 258 | if (!hasTmuxBinary()) { | ||
| 259 | console.error("tmux is not installed."); | ||
| 260 | console.error("Install tmux, or rerun with --inline."); | ||
| 261 | return 1; | ||
| 262 | } | ||
| 263 | |||
| 264 | const clients = getTmuxClients(); | ||
| 265 | const target = clients[0]; | ||
| 266 | if (target) { | ||
| 267 | await launchTmuxPopup(session, target); | ||
| 268 | return 0; | ||
| 269 | } | ||
| 270 | |||
| 271 | console.log(`No active tmux clients. Launching '${agentCommand}' with approvals in session '${tmuxSession}'...`); | ||
| 272 | const started = await launchManagedTmuxWorkspace(session, tmuxSession, agentCommand); | ||
| 273 | if (started) { | ||
| 274 | return 0; | ||
| 275 | } | ||
| 276 | |||
| 277 | console.error("Unable to launch managed tmux workspace."); | ||
| 278 | console.error("You can still run the inline demo with --inline."); | ||
| 279 | return 1; | ||
| 280 | } | ||
| 281 | |||
| 282 | return await runInlineUi(session); | ||
| 283 | } | ||
| 284 | |||
| 285 | const code = await main(); | ||
| 286 | process.exit(code); | ||
| @@ -0,0 +1,11 @@ | |||
| 1 | { | ||
| 2 | "mcpServers": { | ||
| 3 | "memory-approval-demo": { | ||
| 4 | "command": "bun", | ||
| 5 | "args": [ | ||
| 6 | "run", | ||
| 7 | "/home/rhys/assistant/experiemental/mcp-memory-approvals.ts" | ||
| 8 | ] | ||
| 9 | } | ||
| 10 | } | ||
| 11 | } | ||
| @@ -0,0 +1,133 @@ | |||
| 1 | import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; | ||
| 2 | import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; | ||
| 3 | import { z } from "zod"; | ||
| 4 | |||
| 5 | type ApprovalDecision = "approved" | "denied"; | ||
| 6 | |||
| 7 | interface ApprovalRecord { | ||
| 8 | id: string; | ||
| 9 | action: string; | ||
| 10 | justification: string; | ||
| 11 | createdAt: number; | ||
| 12 | decision: ApprovalDecision; | ||
| 13 | decidedAt: number; | ||
| 14 | } | ||
| 15 | |||
| 16 | const approvals: ApprovalRecord[] = []; | ||
| 17 | |||
| 18 | const mcp = new McpServer( | ||
| 19 | { name: "memory-approval-demo", version: "0.0.1" }, | ||
| 20 | { | ||
| 21 | capabilities: { | ||
| 22 | tools: {}, | ||
| 23 | experimental: { | ||
| 24 | elicitation: { | ||
| 25 | form: {}, | ||
| 26 | }, | ||
| 27 | }, | ||
| 28 | }, | ||
| 29 | }, | ||
| 30 | ); | ||
| 31 | |||
| 32 | mcp.registerTool( | ||
| 33 | "dangerous_action", | ||
| 34 | { | ||
| 35 | description: "Runs a fake dangerous action after explicit approval.", | ||
| 36 | inputSchema: { | ||
| 37 | action: z.string().min(1), | ||
| 38 | justification: z.string().optional(), | ||
| 39 | }, | ||
| 40 | }, | ||
| 41 | async ({ action, justification }) => { | ||
| 42 | const approvalId = `appr_${crypto.randomUUID().slice(0, 8)}`; | ||
| 43 | |||
| 44 | let decision: ApprovalDecision = "denied"; | ||
| 45 | |||
| 46 | try { | ||
| 47 | const response = await mcp.server.elicitInput({ | ||
| 48 | mode: "form", | ||
| 49 | message: `Approve dangerous action '${action}'?`, | ||
| 50 | requestedSchema: { | ||
| 51 | type: "object", | ||
| 52 | properties: { | ||
| 53 | decision: { | ||
| 54 | type: "string", | ||
| 55 | oneOf: [ | ||
| 56 | { const: "approved", title: "Approve" }, | ||
| 57 | { const: "denied", title: "Deny" }, | ||
| 58 | ], | ||
| 59 | }, | ||
| 60 | }, | ||
| 61 | required: ["decision"], | ||
| 62 | }, | ||
| 63 | }); | ||
| 64 | |||
| 65 | if (response.action === "accept" && response.content?.decision === "approved") { | ||
| 66 | decision = "approved"; | ||
| 67 | } | ||
| 68 | } catch (error) { | ||
| 69 | console.error("elicitation failed", error); | ||
| 70 | decision = "denied"; | ||
| 71 | } | ||
| 72 | |||
| 73 | const now = Date.now(); | ||
| 74 | approvals.unshift({ | ||
| 75 | id: approvalId, | ||
| 76 | action, | ||
| 77 | justification: justification ?? "", | ||
| 78 | createdAt: now, | ||
| 79 | decision, | ||
| 80 | decidedAt: now, | ||
| 81 | }); | ||
| 82 | |||
| 83 | if (decision === "denied") { | ||
| 84 | return { | ||
| 85 | content: [{ type: "text", text: `Denied '${action}'.` }], | ||
| 86 | structuredContent: { | ||
| 87 | approvalId, | ||
| 88 | status: "denied", | ||
| 89 | action, | ||
| 90 | }, | ||
| 91 | }; | ||
| 92 | } | ||
| 93 | |||
| 94 | return { | ||
| 95 | content: [{ type: "text", text: `Approved and executed '${action}'.` }], | ||
| 96 | structuredContent: { | ||
| 97 | approvalId, | ||
| 98 | status: "approved", | ||
| 99 | action, | ||
| 100 | executed: true, | ||
| 101 | }, | ||
| 102 | }; | ||
| 103 | }, | ||
| 104 | ); | ||
| 105 | |||
| 106 | mcp.registerTool( | ||
| 107 | "approval_history", | ||
| 108 | { | ||
| 109 | description: "Lists in-memory approval decisions for this MCP server process.", | ||
| 110 | inputSchema: { | ||
| 111 | limit: z.number().int().min(1).max(100).optional(), | ||
| 112 | }, | ||
| 113 | }, | ||
| 114 | async ({ limit }) => { | ||
| 115 | const max = limit ?? 20; | ||
| 116 | const items = approvals.slice(0, max).map((entry) => ({ | ||
| 117 | id: entry.id, | ||
| 118 | action: entry.action, | ||
| 119 | justification: entry.justification, | ||
| 120 | decision: entry.decision, | ||
| 121 | createdAt: entry.createdAt, | ||
| 122 | decidedAt: entry.decidedAt, | ||
| 123 | })); | ||
| 124 | |||
| 125 | return { | ||
| 126 | content: [{ type: "text", text: `Returning ${items.length} approval entries.` }], | ||
| 127 | structuredContent: { items }, | ||
| 128 | }; | ||
| 129 | }, | ||
| 130 | ); | ||
| 131 | |||
| 132 | const transport = new StdioServerTransport(); | ||
| 133 | await mcp.connect(transport); | ||
| @@ -0,0 +1,9 @@ | |||
| 1 | # Executor v2 Scaffold | ||
| 2 | |||
| 3 | This directory is a fresh monorepo scaffold for the Executor v2 architecture. | ||
| 4 | |||
| 5 | ## Included | ||
| 6 | |||
| 7 | - Workspace root `package.json` and `tsconfig.json` | ||
| 8 | - App and package folders with `src/`, `package.json`, `tsconfig.json`, and `README.md` | ||
| 9 | - No implementation files yet | ||
| @@ -0,0 +1,3 @@ | |||
| 1 | # app-cli | ||
| 2 | |||
| 3 | CLI app scaffold for Executor v2. | ||
| @@ -0,0 +1,8 @@ | |||
| 1 | { | ||
| 2 | "name": "@executor-v2/app-cli", | ||
| 3 | "private": true, | ||
| 4 | "type": "module", | ||
| 5 | "scripts": { | ||
| 6 | "typecheck": "bunx tsc --noEmit -p tsconfig.json" | ||
| 7 | } | ||
| 8 | } | ||
| @@ -0,0 +1,4 @@ | |||
| 1 | { | ||
| 2 | "extends": "../../tsconfig.json", | ||
| 3 | "include": ["src"] | ||
| 4 | } | ||
| @@ -0,0 +1,3 @@ | |||
| 1 | # app-convex | ||
| 2 | |||
| 3 | Convex remote server app scaffold for Executor v2. | ||
| @@ -0,0 +1,8 @@ | |||
| 1 | { | ||
| 2 | "name": "@executor-v2/app-convex", | ||
| 3 | "private": true, | ||
| 4 | "type": "module", | ||
| 5 | "scripts": { | ||
| 6 | "typecheck": "bunx tsc --noEmit -p tsconfig.json" | ||
| 7 | } | ||
| 8 | } | ||
| @@ -0,0 +1,4 @@ | |||
| 1 | { | ||
| 2 | "extends": "../../tsconfig.json", | ||
| 3 | "include": ["src"] | ||
| 4 | } | ||
| @@ -0,0 +1,3 @@ | |||
| 1 | # app-pm | ||
| 2 | |||
| 3 | Local Process Manager app scaffold for Executor v2. | ||
| @@ -0,0 +1,8 @@ | |||
| 1 | { | ||
| 2 | "name": "@executor-v2/app-pm", | ||
| 3 | "private": true, | ||
| 4 | "type": "module", | ||
| 5 | "scripts": { | ||
| 6 | "typecheck": "bunx tsc --noEmit -p tsconfig.json" | ||
| 7 | } | ||
| 8 | } | ||
| @@ -0,0 +1,4 @@ | |||
| 1 | { | ||
| 2 | "extends": "../../tsconfig.json", | ||
| 3 | "include": ["src"] | ||
| 4 | } | ||
| @@ -0,0 +1,3 @@ | |||
| 1 | # app-web | ||
| 2 | |||
| 3 | Web UI app scaffold for Executor v2. | ||
| @@ -0,0 +1,8 @@ | |||
| 1 | { | ||
| 2 | "name": "@executor-v2/app-web", | ||
| 3 | "private": true, | ||
| 4 | "type": "module", | ||
| 5 | "scripts": { | ||
| 6 | "typecheck": "bunx tsc --noEmit -p tsconfig.json" | ||
| 7 | } | ||
| 8 | } | ||
| @@ -0,0 +1,4 @@ | |||
| 1 | { | ||
| 2 | "extends": "../../tsconfig.json", | ||
| 3 | "include": ["src"] | ||
| 4 | } | ||
| @@ -0,0 +1,13 @@ | |||
| 1 | { | ||
| 2 | "name": "executor-v2", | ||
| 3 | "private": true, | ||
| 4 | "type": "module", | ||
| 5 | "packageManager": "bun@1.2.22", | ||
| 6 | "workspaces": [ | ||
| 7 | "apps/*", | ||
| 8 | "packages/*" | ||
| 9 | ], | ||
| 10 | "scripts": { | ||
| 11 | "typecheck": "bunx tsc --noEmit" | ||
| 12 | } | ||
| 13 | } | ||
| @@ -0,0 +1,3 @@ | |||
| 1 | # ai-sdk-adapter | ||
| 2 | |||
| 3 | AI SDK adapter scaffold for Executor v2. | ||
| @@ -0,0 +1,8 @@ | |||
| 1 | { | ||
| 2 | "name": "@executor-v2/ai-sdk-adapter", | ||
| 3 | "private": true, | ||
| 4 | "type": "module", | ||
| 5 | "scripts": { | ||
| 6 | "typecheck": "bunx tsc --noEmit -p tsconfig.json" | ||
| 7 | } | ||
| 8 | } | ||
| @@ -0,0 +1,4 @@ | |||
| 1 | { | ||
| 2 | "extends": "../../tsconfig.json", | ||
| 3 | "include": ["src"] | ||
| 4 | } | ||
| @@ -0,0 +1,3 @@ | |||
| 1 | # approvals | ||
| 2 | |||
| 3 | Approval and input broker scaffold for Executor v2. | ||
| @@ -0,0 +1,8 @@ | |||
| 1 | { | ||
| 2 | "name": "@executor-v2/approvals", | ||
| 3 | "private": true, | ||
| 4 | "type": "module", | ||
| 5 | "scripts": { | ||
| 6 | "typecheck": "bunx tsc --noEmit -p tsconfig.json" | ||
| 7 | } | ||
| 8 | } | ||
| @@ -0,0 +1,4 @@ | |||
| 1 | { | ||
| 2 | "extends": "../../tsconfig.json", | ||
| 3 | "include": ["src"] | ||
| 4 | } | ||
| @@ -0,0 +1,5 @@ | |||
| 1 | # confect-core | ||
| 2 | |||
| 3 | Effect schema helper primitives scaffold for Executor v2. | ||
| 4 | |||
| 5 | Current scaffold includes basic helpers in `src/schema.ts`. | ||
| @@ -0,0 +1,14 @@ | |||
| 1 | { | ||
| 2 | "name": "@executor-v2/confect-core", | ||
| 3 | "private": true, | ||
| 4 | "type": "module", | ||
| 5 | "exports": { | ||
| 6 | ".": "./src/index.ts" | ||
| 7 | }, | ||
| 8 | "scripts": { | ||
| 9 | "typecheck": "bunx tsc --noEmit -p tsconfig.json" | ||
| 10 | }, | ||
| 11 | "dependencies": { | ||
| 12 | "effect": "^3.19.4" | ||
| 13 | } | ||
| 14 | } | ||
| @@ -0,0 +1 @@ | |||
| 1 | export * from "./schema"; | ||
| @@ -0,0 +1,6 @@ | |||
| 1 | import { Schema } from "effect"; | ||
| 2 | |||
| 3 | export const TimestampMsSchema = Schema.Number; | ||
| 4 | |||
| 5 | export const makeIdSchema = (brandName: string) => | ||
| 6 | Schema.String.pipe(Schema.brand(brandName)); | ||
| @@ -0,0 +1,4 @@ | |||
| 1 | { | ||
| 2 | "extends": "../../tsconfig.json", | ||
| 3 | "include": ["src"] | ||
| 4 | } | ||
| @@ -0,0 +1,3 @@ | |||
| 1 | # domain | ||
| 2 | |||
| 3 | Domain service layer scaffold for Executor v2. | ||
| @@ -0,0 +1,8 @@ | |||
| 1 | { | ||
| 2 | "name": "@executor-v2/domain", | ||
| 3 | "private": true, | ||
| 4 | "type": "module", | ||
| 5 | "scripts": { | ||
| 6 | "typecheck": "bunx tsc --noEmit -p tsconfig.json" | ||
| 7 | } | ||
| 8 | } | ||
| @@ -0,0 +1,4 @@ | |||
| 1 | { | ||
| 2 | "extends": "../../tsconfig.json", | ||
| 3 | "include": ["src"] | ||
| 4 | } | ||
| @@ -0,0 +1,3 @@ | |||
| 1 | # engine | ||
| 2 | |||
| 3 | Runtime execution engine scaffold for Executor v2. | ||
| @@ -0,0 +1,8 @@ | |||
| 1 | { | ||
| 2 | "name": "@executor-v2/engine", | ||
| 3 | "private": true, | ||
| 4 | "type": "module", | ||
| 5 | "scripts": { | ||
| 6 | "typecheck": "bunx tsc --noEmit -p tsconfig.json" | ||
| 7 | } | ||
| 8 | } | ||
| @@ -0,0 +1,4 @@ | |||
| 1 | { | ||
| 2 | "extends": "../../tsconfig.json", | ||
| 3 | "include": ["src"] | ||
| 4 | } | ||
| @@ -0,0 +1,3 @@ | |||
| 1 | # mcp-gateway | ||
| 2 | |||
| 3 | MCP gateway surface scaffold for Executor v2. | ||
| @@ -0,0 +1,8 @@ | |||
| 1 | { | ||
| 2 | "name": "@executor-v2/mcp-gateway", | ||
| 3 | "private": true, | ||
| 4 | "type": "module", | ||
| 5 | "scripts": { | ||
| 6 | "typecheck": "bunx tsc --noEmit -p tsconfig.json" | ||
| 7 | } | ||
| 8 | } | ||
| @@ -0,0 +1,4 @@ | |||
| 1 | { | ||
| 2 | "extends": "../../tsconfig.json", | ||
| 3 | "include": ["src"] | ||
| 4 | } | ||
| @@ -0,0 +1,3 @@ | |||
| 1 | # oauth | ||
| 2 | |||
| 3 | OAuth primitives scaffold for Executor v2. | ||
| @@ -0,0 +1,8 @@ | |||
| 1 | { | ||
| 2 | "name": "@executor-v2/oauth", | ||
| 3 | "private": true, | ||
| 4 | "type": "module", | ||
| 5 | "scripts": { | ||
| 6 | "typecheck": "bunx tsc --noEmit -p tsconfig.json" | ||
| 7 | } | ||
| 8 | } | ||
| @@ -0,0 +1,4 @@ | |||
| 1 | { | ||
| 2 | "extends": "../../tsconfig.json", | ||
| 3 | "include": ["src"] | ||
| 4 | } | ||
| @@ -0,0 +1,3 @@ | |||
| 1 | # rpc | ||
| 2 | |||
| 3 | Effect RPC contract scaffold for Executor v2. | ||
| @@ -0,0 +1,8 @@ | |||
| 1 | { | ||
| 2 | "name": "@executor-v2/rpc", | ||
| 3 | "private": true, | ||
| 4 | "type": "module", | ||
| 5 | "scripts": { | ||
| 6 | "typecheck": "bunx tsc --noEmit -p tsconfig.json" | ||
| 7 | } | ||
| 8 | } | ||
| @@ -0,0 +1,4 @@ | |||
| 1 | { | ||
| 2 | "extends": "../../tsconfig.json", | ||
| 3 | "include": ["src"] | ||
| 4 | } | ||
| @@ -0,0 +1,9 @@ | |||
| 1 | # schema | ||
| 2 | |||
| 3 | Canonical Effect schema package scaffold for Executor v2. | ||
| 4 | |||
| 5 | Current scaffold includes: | ||
| 6 | - branded IDs (`src/ids.ts`) | ||
| 7 | - shared enums and primitives (`src/enums.ts`, `src/common.ts`) | ||
| 8 | - core model schemas in `src/models/*` | ||
| 9 | - local snapshot/event schemas (`src/snapshot.ts`) | ||
| @@ -0,0 +1,14 @@ | |||
| 1 | { | ||
| 2 | "name": "@executor-v2/schema", | ||
| 3 | "private": true, | ||
| 4 | "type": "module", | ||
| 5 | "exports": { | ||
| 6 | ".": "./src/index.ts" | ||
| 7 | }, | ||
| 8 | "scripts": { | ||
| 9 | "typecheck": "bunx tsc --noEmit -p tsconfig.json" | ||
| 10 | }, | ||
| 11 | "dependencies": { | ||
| 12 | "effect": "^3.19.4" | ||
| 13 | } | ||
| 14 | } | ||
| @@ -0,0 +1,8 @@ | |||
| 1 | import { Schema } from "effect"; | ||
| 2 | |||
| 3 | export const SchemaVersionSchema = Schema.Number; | ||
| 4 | export const TimestampMsSchema = Schema.Number; | ||
| 5 | export const JsonStringSchema = Schema.String; | ||
| 6 | |||
| 7 | export type SchemaVersion = typeof SchemaVersionSchema.Type; | ||
| 8 | export type TimestampMs = typeof TimestampMsSchema.Type; | ||
| @@ -0,0 +1,19 @@ | |||
| 1 | import { Schema } from "effect"; | ||
| 2 | |||
| 3 | export const RuntimeModeSchema = Schema.Literal("local", "linked", "remote"); | ||
| 4 | export const SourceKindSchema = Schema.Literal("mcp", "openapi", "graphql", "internal"); | ||
| 5 | export const SourceStatusSchema = Schema.Literal("draft", "probing", "auth_required", "connected", "error"); | ||
| 6 | export const PolicyDecisionSchema = Schema.Literal("allow", "require_approval", "deny"); | ||
| 7 | export const ApprovalStatusSchema = Schema.Literal("pending", "approved", "denied", "expired"); | ||
| 8 | export const TaskRunStatusSchema = Schema.Literal("queued", "running", "completed", "failed", "timed_out", "denied"); | ||
| 9 | export const CredentialModeSchema = Schema.Literal("none", "api_key", "bearer", "oauth2", "custom"); | ||
| 10 | export const SyncTargetSchema = Schema.Literal("remote"); | ||
| 11 | |||
| 12 | export type RuntimeMode = typeof RuntimeModeSchema.Type; | ||
| 13 | export type SourceKind = typeof SourceKindSchema.Type; | ||
| 14 | export type SourceStatus = typeof SourceStatusSchema.Type; | ||
| 15 | export type PolicyDecision = typeof PolicyDecisionSchema.Type; | ||
| 16 | export type ApprovalStatus = typeof ApprovalStatusSchema.Type; | ||
| 17 | export type TaskRunStatus = typeof TaskRunStatusSchema.Type; | ||
| 18 | export type CredentialMode = typeof CredentialModeSchema.Type; | ||
| 19 | export type SyncTarget = typeof SyncTargetSchema.Type; | ||
| @@ -0,0 +1,25 @@ | |||
| 1 | import { Schema } from "effect"; | ||
| 2 | |||
| 3 | export const ProfileIdSchema = Schema.String.pipe(Schema.brand("ProfileId")); | ||
| 4 | export const WorkspaceIdSchema = Schema.String.pipe(Schema.brand("WorkspaceId")); | ||
| 5 | export const SourceIdSchema = Schema.String.pipe(Schema.brand("SourceId")); | ||
| 6 | export const ToolArtifactIdSchema = Schema.String.pipe(Schema.brand("ToolArtifactId")); | ||
| 7 | export const CredentialRefIdSchema = Schema.String.pipe(Schema.brand("CredentialRefId")); | ||
| 8 | export const OAuthTokenIdSchema = Schema.String.pipe(Schema.brand("OAuthTokenId")); | ||
| 9 | export const PolicyIdSchema = Schema.String.pipe(Schema.brand("PolicyId")); | ||
| 10 | export const ApprovalIdSchema = Schema.String.pipe(Schema.brand("ApprovalId")); | ||
| 11 | export const TaskRunIdSchema = Schema.String.pipe(Schema.brand("TaskRunId")); | ||
| 12 | export const SyncStateIdSchema = Schema.String.pipe(Schema.brand("SyncStateId")); | ||
| 13 | export const EventIdSchema = Schema.String.pipe(Schema.brand("EventId")); | ||
| 14 | |||
| 15 | export type ProfileId = typeof ProfileIdSchema.Type; | ||
| 16 | export type WorkspaceId = typeof WorkspaceIdSchema.Type; | ||
| 17 | export type SourceId = typeof SourceIdSchema.Type; | ||
| 18 | export type ToolArtifactId = typeof ToolArtifactIdSchema.Type; | ||
| 19 | export type CredentialRefId = typeof CredentialRefIdSchema.Type; | ||
| 20 | export type OAuthTokenId = typeof OAuthTokenIdSchema.Type; | ||
| 21 | export type PolicyId = typeof PolicyIdSchema.Type; | ||
| 22 | export type ApprovalId = typeof ApprovalIdSchema.Type; | ||
| 23 | export type TaskRunId = typeof TaskRunIdSchema.Type; | ||
| 24 | export type SyncStateId = typeof SyncStateIdSchema.Type; | ||
| 25 | export type EventId = typeof EventIdSchema.Type; | ||
| @@ -0,0 +1,17 @@ | |||
| 1 | export * from "./common"; | ||
| 2 | export * from "./enums"; | ||
| 3 | export * from "./ids"; | ||
| 4 | |||
| 5 | export * from "./models/profile"; | ||
| 6 | export * from "./models/workspace"; | ||
| 7 | export * from "./models/source"; | ||
| 8 | export * from "./models/tool-artifact"; | ||
| 9 | export * from "./models/credential-ref"; | ||
| 10 | export * from "./models/oauth-token"; | ||
| 11 | export * from "./models/policy"; | ||
| 12 | export * from "./models/approval"; | ||
| 13 | export * from "./models/task-run"; | ||
| 14 | export * from "./models/sync-state"; | ||
| 15 | export * from "./models/event-envelope"; | ||
| 16 | |||
| 17 | export * from "./snapshot"; | ||
| @@ -0,0 +1,19 @@ | |||
| 1 | import { Schema } from "effect"; | ||
| 2 | |||
| 3 | import { TimestampMsSchema } from "../common"; | ||
| 4 | import { ApprovalStatusSchema } from "../enums"; | ||
| 5 | import { ApprovalIdSchema, TaskRunIdSchema, WorkspaceIdSchema } from "../ids"; | ||
| 6 | |||
| 7 | export const ApprovalSchema = Schema.Struct({ | ||
| 8 | id: ApprovalIdSchema, | ||
| 9 | workspaceId: WorkspaceIdSchema, | ||
| 10 | taskRunId: TaskRunIdSchema, | ||
| 11 | toolPath: Schema.String, | ||
| 12 | status: ApprovalStatusSchema, | ||
| 13 | inputPreviewJson: Schema.String, | ||
| 14 | reason: Schema.NullOr(Schema.String), | ||
| 15 | requestedAt: TimestampMsSchema, | ||
| 16 | resolvedAt: Schema.NullOr(TimestampMsSchema), | ||
| 17 | }); | ||
| 18 | |||
| 19 | export type Approval = typeof ApprovalSchema.Type; | ||
| @@ -0,0 +1,19 @@ | |||
| 1 | import { Schema } from "effect"; | ||
| 2 | |||
| 3 | import { TimestampMsSchema } from "../common"; | ||
| 4 | import { CredentialModeSchema } from "../enums"; | ||
| 5 | import { CredentialRefIdSchema, SourceIdSchema, WorkspaceIdSchema } from "../ids"; | ||
| 6 | |||
| 7 | export const CredentialRefSchema = Schema.Struct({ | ||
| 8 | id: CredentialRefIdSchema, | ||
| 9 | workspaceId: WorkspaceIdSchema, | ||
| 10 | sourceId: SourceIdSchema, | ||
| 11 | mode: CredentialModeSchema, | ||
| 12 | label: Schema.String, | ||
| 13 | secretRef: Schema.String, | ||
| 14 | headerName: Schema.NullOr(Schema.String), | ||
| 15 | createdAt: TimestampMsSchema, | ||
| 16 | updatedAt: TimestampMsSchema, | ||
| 17 | }); | ||
| 18 | |||
| 19 | export type CredentialRef = typeof CredentialRefSchema.Type; | ||
| @@ -0,0 +1,16 @@ | |||
| 1 | import { Schema } from "effect"; | ||
| 2 | |||
| 3 | import { SchemaVersionSchema, TimestampMsSchema } from "../common"; | ||
| 4 | import { EventIdSchema, WorkspaceIdSchema } from "../ids"; | ||
| 5 | |||
| 6 | export const EventEnvelopeSchema = Schema.Struct({ | ||
| 7 | id: EventIdSchema, | ||
| 8 | workspaceId: WorkspaceIdSchema, | ||
| 9 | sequence: Schema.Number, | ||
| 10 | schemaVersion: SchemaVersionSchema, | ||
| 11 | eventType: Schema.String, | ||
| 12 | payloadJson: Schema.String, | ||
| 13 | createdAt: TimestampMsSchema, | ||
| 14 | }); | ||
| 15 | |||
| 16 | export type EventEnvelope = typeof EventEnvelopeSchema.Type; | ||
| @@ -0,0 +1,19 @@ | |||
| 1 | import { Schema } from "effect"; | ||
| 2 | |||
| 3 | import { TimestampMsSchema } from "../common"; | ||
| 4 | import { OAuthTokenIdSchema, SourceIdSchema, WorkspaceIdSchema } from "../ids"; | ||
| 5 | |||
| 6 | export const OAuthTokenSchema = Schema.Struct({ | ||
| 7 | id: OAuthTokenIdSchema, | ||
| 8 | workspaceId: WorkspaceIdSchema, | ||
| 9 | sourceId: SourceIdSchema, | ||
| 10 | issuer: Schema.String, | ||
| 11 | accessTokenRef: Schema.String, | ||
| 12 | refreshTokenRef: Schema.NullOr(Schema.String), | ||
| 13 | scope: Schema.Array(Schema.String), | ||
| 14 | expiresAt: Schema.NullOr(TimestampMsSchema), | ||
| 15 | createdAt: TimestampMsSchema, | ||
| 16 | updatedAt: TimestampMsSchema, | ||
| 17 | }); | ||
| 18 | |||
| 19 | export type OAuthToken = typeof OAuthTokenSchema.Type; | ||
| @@ -0,0 +1,16 @@ | |||
| 1 | import { Schema } from "effect"; | ||
| 2 | |||
| 3 | import { TimestampMsSchema } from "../common"; | ||
| 4 | import { PolicyDecisionSchema } from "../enums"; | ||
| 5 | import { PolicyIdSchema, WorkspaceIdSchema } from "../ids"; | ||
| 6 | |||
| 7 | export const PolicySchema = Schema.Struct({ | ||
| 8 | id: PolicyIdSchema, | ||
| 9 | workspaceId: WorkspaceIdSchema, | ||
| 10 | toolPathPattern: Schema.String, | ||
| 11 | decision: PolicyDecisionSchema, | ||
| 12 | createdAt: TimestampMsSchema, | ||
| 13 | updatedAt: TimestampMsSchema, | ||
| 14 | }); | ||
| 15 | |||
| 16 | export type Policy = typeof PolicySchema.Type; | ||
| @@ -0,0 +1,16 @@ | |||
| 1 | import { Schema } from "effect"; | ||
| 2 | |||
| 3 | import { TimestampMsSchema } from "../common"; | ||
| 4 | import { RuntimeModeSchema } from "../enums"; | ||
| 5 | import { ProfileIdSchema, WorkspaceIdSchema } from "../ids"; | ||
| 6 | |||
| 7 | export const ProfileSchema = Schema.Struct({ | ||
| 8 | id: ProfileIdSchema, | ||
| 9 | defaultWorkspaceId: Schema.NullOr(WorkspaceIdSchema), | ||
| 10 | displayName: Schema.String, | ||
| 11 | runtimeMode: RuntimeModeSchema, | ||
| 12 | createdAt: TimestampMsSchema, | ||
| 13 | updatedAt: TimestampMsSchema, | ||
| 14 | }); | ||
| 15 | |||
| 16 | export type Profile = typeof ProfileSchema.Type; | ||
| @@ -0,0 +1,22 @@ | |||
| 1 | import { Schema } from "effect"; | ||
| 2 | |||
| 3 | import { TimestampMsSchema } from "../common"; | ||
| 4 | import { SourceKindSchema, SourceStatusSchema } from "../enums"; | ||
| 5 | import { SourceIdSchema, WorkspaceIdSchema } from "../ids"; | ||
| 6 | |||
| 7 | export const SourceSchema = Schema.Struct({ | ||
| 8 | id: SourceIdSchema, | ||
| 9 | workspaceId: WorkspaceIdSchema, | ||
| 10 | name: Schema.String, | ||
| 11 | kind: SourceKindSchema, | ||
| 12 | endpoint: Schema.String, | ||
| 13 | status: SourceStatusSchema, | ||
| 14 | enabled: Schema.Boolean, | ||
| 15 | configJson: Schema.String, | ||
| 16 | sourceHash: Schema.NullOr(Schema.String), | ||
| 17 | lastError: Schema.NullOr(Schema.String), | ||
| 18 | createdAt: TimestampMsSchema, | ||
| 19 | updatedAt: TimestampMsSchema, | ||
| 20 | }); | ||
| 21 | |||
| 22 | export type Source = typeof SourceSchema.Type; | ||
| @@ -0,0 +1,18 @@ | |||
| 1 | import { Schema } from "effect"; | ||
| 2 | |||
| 3 | import { TimestampMsSchema } from "../common"; | ||
| 4 | import { SyncTargetSchema } from "../enums"; | ||
| 5 | import { SyncStateIdSchema, WorkspaceIdSchema } from "../ids"; | ||
| 6 | |||
| 7 | export const SyncStateSchema = Schema.Struct({ | ||
| 8 | id: SyncStateIdSchema, | ||
| 9 | workspaceId: WorkspaceIdSchema, | ||
| 10 | target: SyncTargetSchema, | ||
| 11 | targetUrl: Schema.String, | ||
| 12 | linkedSubject: Schema.NullOr(Schema.String), | ||
| 13 | cursor: Schema.NullOr(Schema.String), | ||
| 14 | lastSyncAt: Schema.NullOr(TimestampMsSchema), | ||
| 15 | updatedAt: TimestampMsSchema, | ||
| 16 | }); | ||
| 17 | |||
| 18 | export type SyncState = typeof SyncStateSchema.Type; | ||
| @@ -0,0 +1,20 @@ | |||
| 1 | import { Schema } from "effect"; | ||
| 2 | |||
| 3 | import { TimestampMsSchema } from "../common"; | ||
| 4 | import { TaskRunStatusSchema } from "../enums"; | ||
| 5 | import { TaskRunIdSchema, WorkspaceIdSchema } from "../ids"; | ||
| 6 | |||
| 7 | export const TaskRunSchema = Schema.Struct({ | ||
| 8 | id: TaskRunIdSchema, | ||
| 9 | workspaceId: WorkspaceIdSchema, | ||
| 10 | sessionId: Schema.String, | ||
| 11 | runtimeId: Schema.String, | ||
| 12 | codeHash: Schema.String, | ||
| 13 | status: TaskRunStatusSchema, | ||
| 14 | startedAt: Schema.NullOr(TimestampMsSchema), | ||
| 15 | completedAt: Schema.NullOr(TimestampMsSchema), | ||
| 16 | exitCode: Schema.NullOr(Schema.Number), | ||
| 17 | error: Schema.NullOr(Schema.String), | ||
| 18 | }); | ||
| 19 | |||
| 20 | export type TaskRun = typeof TaskRunSchema.Type; | ||
| @@ -0,0 +1,17 @@ | |||
| 1 | import { Schema } from "effect"; | ||
| 2 | |||
| 3 | import { TimestampMsSchema } from "../common"; | ||
| 4 | import { SourceIdSchema, ToolArtifactIdSchema, WorkspaceIdSchema } from "../ids"; | ||
| 5 | |||
| 6 | export const ToolArtifactSchema = Schema.Struct({ | ||
| 7 | id: ToolArtifactIdSchema, | ||
| 8 | workspaceId: WorkspaceIdSchema, | ||
| 9 | sourceId: SourceIdSchema, | ||
| 10 | sourceHash: Schema.String, | ||
| 11 | toolCount: Schema.Number, | ||
| 12 | manifestJson: Schema.String, | ||
| 13 | createdAt: TimestampMsSchema, | ||
| 14 | updatedAt: TimestampMsSchema, | ||
| 15 | }); | ||
| 16 | |||
| 17 | export type ToolArtifact = typeof ToolArtifactSchema.Type; | ||
| @@ -0,0 +1,14 @@ | |||
| 1 | import { Schema } from "effect"; | ||
| 2 | |||
| 3 | import { TimestampMsSchema } from "../common"; | ||
| 4 | import { ProfileIdSchema, WorkspaceIdSchema } from "../ids"; | ||
| 5 | |||
| 6 | export const WorkspaceSchema = Schema.Struct({ | ||
| 7 | id: WorkspaceIdSchema, | ||
| 8 | profileId: ProfileIdSchema, | ||
| 9 | name: Schema.String, | ||
| 10 | createdAt: TimestampMsSchema, | ||
| 11 | updatedAt: TimestampMsSchema, | ||
| 12 | }); | ||
| 13 | |||
| 14 | export type Workspace = typeof WorkspaceSchema.Type; | ||
| @@ -0,0 +1,34 @@ | |||
| 1 | import { Schema } from "effect"; | ||
| 2 | |||
| 3 | import { SchemaVersionSchema, TimestampMsSchema } from "./common"; | ||
| 4 | import { EventEnvelopeSchema } from "./models/event-envelope"; | ||
| 5 | import { ApprovalSchema } from "./models/approval"; | ||
| 6 | import { CredentialRefSchema } from "./models/credential-ref"; | ||
| 7 | import { OAuthTokenSchema } from "./models/oauth-token"; | ||
| 8 | import { PolicySchema } from "./models/policy"; | ||
| 9 | import { ProfileSchema } from "./models/profile"; | ||
| 10 | import { SourceSchema } from "./models/source"; | ||
| 11 | import { SyncStateSchema } from "./models/sync-state"; | ||
| 12 | import { TaskRunSchema } from "./models/task-run"; | ||
| 13 | import { ToolArtifactSchema } from "./models/tool-artifact"; | ||
| 14 | import { WorkspaceSchema } from "./models/workspace"; | ||
| 15 | |||
| 16 | export const StateSnapshotSchema = Schema.Struct({ | ||
| 17 | schemaVersion: SchemaVersionSchema, | ||
| 18 | generatedAt: TimestampMsSchema, | ||
| 19 | profile: ProfileSchema, | ||
| 20 | workspaces: Schema.Array(WorkspaceSchema), | ||
| 21 | sources: Schema.Array(SourceSchema), | ||
| 22 | toolArtifacts: Schema.Array(ToolArtifactSchema), | ||
| 23 | credentials: Schema.Array(CredentialRefSchema), | ||
| 24 | oauthTokens: Schema.Array(OAuthTokenSchema), | ||
| 25 | policies: Schema.Array(PolicySchema), | ||
| 26 | approvals: Schema.Array(ApprovalSchema), | ||
| 27 | taskRuns: Schema.Array(TaskRunSchema), | ||
| 28 | syncStates: Schema.Array(SyncStateSchema), | ||
| 29 | }); | ||
| 30 | |||
| 31 | export const StateEventLogSchema = Schema.Array(EventEnvelopeSchema); | ||
| 32 | |||
| 33 | export type StateSnapshot = typeof StateSnapshotSchema.Type; | ||
| 34 | export type StateEventLog = typeof StateEventLogSchema.Type; | ||
| @@ -0,0 +1,4 @@ | |||
| 1 | { | ||
| 2 | "extends": "../../tsconfig.json", | ||
| 3 | "include": ["src"] | ||
| 4 | } | ||
| @@ -0,0 +1,3 @@ | |||
| 1 | # sdk | ||
| 2 | |||
| 3 | Typed client SDK scaffold for Executor v2. | ||
| @@ -0,0 +1,8 @@ | |||
| 1 | { | ||
| 2 | "name": "@executor-v2/sdk", | ||
| 3 | "private": true, | ||
| 4 | "type": "module", | ||
| 5 | "scripts": { | ||
| 6 | "typecheck": "bunx tsc --noEmit -p tsconfig.json" | ||
| 7 | } | ||
| 8 | } | ||
| @@ -0,0 +1,4 @@ | |||
| 1 | { | ||
| 2 | "extends": "../../tsconfig.json", | ||
| 3 | "include": ["src"] | ||
| 4 | } | ||
| @@ -0,0 +1,3 @@ | |||
| 1 | # secrets | ||
| 2 | |||
| 3 | Secret-store abstraction scaffold for Executor v2. | ||
| @@ -0,0 +1,8 @@ | |||
| 1 | { | ||
| 2 | "name": "@executor-v2/secrets", | ||
| 3 | "private": true, | ||
| 4 | "type": "module", | ||
| 5 | "scripts": { | ||
| 6 | "typecheck": "bunx tsc --noEmit -p tsconfig.json" | ||
| 7 | } | ||
| 8 | } | ||
| @@ -0,0 +1,4 @@ | |||
| 1 | { | ||
| 2 | "extends": "../../tsconfig.json", | ||
| 3 | "include": ["src"] | ||
| 4 | } | ||
| @@ -0,0 +1,3 @@ | |||
| 1 | # source-manager | ||
| 2 | |||
| 3 | Dynamic source registration scaffold for Executor v2. | ||
| @@ -0,0 +1,8 @@ | |||
| 1 | { | ||
| 2 | "name": "@executor-v2/source-manager", | ||
| 3 | "private": true, | ||
| 4 | "type": "module", | ||
| 5 | "scripts": { | ||
| 6 | "typecheck": "bunx tsc --noEmit -p tsconfig.json" | ||
| 7 | } | ||
| 8 | } | ||
| @@ -0,0 +1,4 @@ | |||
| 1 | { | ||
| 2 | "extends": "../../tsconfig.json", | ||
| 3 | "include": ["src"] | ||
| 4 | } | ||
| @@ -0,0 +1,3 @@ | |||
| 1 | # state-contracts | ||
| 2 | |||
| 3 | Storage and repository interface scaffold for Executor v2. | ||
| @@ -0,0 +1,8 @@ | |||
| 1 | { | ||
| 2 | "name": "@executor-v2/state-contracts", | ||
| 3 | "private": true, | ||
| 4 | "type": "module", | ||
| 5 | "scripts": { | ||
| 6 | "typecheck": "bunx tsc --noEmit -p tsconfig.json" | ||
| 7 | } | ||
| 8 | } | ||
| @@ -0,0 +1,4 @@ | |||
| 1 | { | ||
| 2 | "extends": "../../tsconfig.json", | ||
| 3 | "include": ["src"] | ||
| 4 | } | ||
| @@ -0,0 +1,3 @@ | |||
| 1 | # state-convex | ||
| 2 | |||
| 3 | Convex-backed state adapter scaffold for Executor v2. | ||
| @@ -0,0 +1,8 @@ | |||
| 1 | { | ||
| 2 | "name": "@executor-v2/state-convex", | ||
| 3 | "private": true, | ||
| 4 | "type": "module", | ||
| 5 | "scripts": { | ||
| 6 | "typecheck": "bunx tsc --noEmit -p tsconfig.json" | ||
| 7 | } | ||
| 8 | } | ||
| @@ -0,0 +1,4 @@ | |||
| 1 | { | ||
| 2 | "extends": "../../tsconfig.json", | ||
| 3 | "include": ["src"] | ||
| 4 | } | ||
| @@ -0,0 +1,3 @@ | |||
| 1 | # state-local-file | ||
| 2 | |||
| 3 | Local file-backed state adapter scaffold for Executor v2. | ||
| @@ -0,0 +1,8 @@ | |||
| 1 | { | ||
| 2 | "name": "@executor-v2/state-local-file", | ||
| 3 | "private": true, | ||
| 4 | "type": "module", | ||
| 5 | "scripts": { | ||
| 6 | "typecheck": "bunx tsc --noEmit -p tsconfig.json" | ||
| 7 | } | ||
| 8 | } | ||
| @@ -0,0 +1,4 @@ | |||
| 1 | { | ||
| 2 | "extends": "../../tsconfig.json", | ||
| 3 | "include": ["src"] | ||
| 4 | } | ||
| @@ -0,0 +1,3 @@ | |||
| 1 | # sync | ||
| 2 | |||
| 3 | Local and remote sync/promote scaffold for Executor v2. | ||
| @@ -0,0 +1,8 @@ | |||
| 1 | { | ||
| 2 | "name": "@executor-v2/sync", | ||
| 3 | "private": true, | ||
| 4 | "type": "module", | ||
| 5 | "scripts": { | ||
| 6 | "typecheck": "bunx tsc --noEmit -p tsconfig.json" | ||
| 7 | } | ||
| 8 | } | ||
| @@ -0,0 +1,4 @@ | |||
| 1 | { | ||
| 2 | "extends": "../../tsconfig.json", | ||
| 3 | "include": ["src"] | ||
| 4 | } | ||
| @@ -0,0 +1,20 @@ | |||
| 1 | { | ||
| 2 | "compilerOptions": { | ||
| 3 | "target": "ES2023", | ||
| 4 | "module": "ESNext", | ||
| 5 | "moduleResolution": "Bundler", | ||
| 6 | "strict": true, | ||
| 7 | "noEmit": true, | ||
| 8 | "verbatimModuleSyntax": true, | ||
| 9 | "skipLibCheck": true, | ||
| 10 | "resolveJsonModule": true, | ||
| 11 | "allowSyntheticDefaultImports": true, | ||
| 12 | "types": [] | ||
| 13 | }, | ||
| 14 | "include": [ | ||
| 15 | "apps/**/*.ts", | ||
| 16 | "apps/**/*.tsx", | ||
| 17 | "packages/**/*.ts", | ||
| 18 | "packages/**/*.tsx" | ||
| 19 | ] | ||
| 20 | } | ||