diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 600a481..5520d73 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: - uses: actions/checkout@v7 - name: Setup Node.js - uses: actions/setup-node@v6 + uses: actions/setup-node@v7 with: node-version: '22' @@ -28,7 +28,7 @@ jobs: uses: oven-sh/setup-bun@v2 - name: Cache bun dependencies - uses: actions/cache@v5 + uses: actions/cache@v6 with: path: ~/.bun/install/cache key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }} @@ -36,7 +36,7 @@ jobs: ${{ runner.os }}-bun- - name: Cache turbo - uses: actions/cache@v5 + uses: actions/cache@v6 with: path: .turbo key: ${{ runner.os }}-turbo-${{ github.sha }} @@ -66,7 +66,7 @@ jobs: uses: oven-sh/setup-bun@v2 - name: Cache bun dependencies - uses: actions/cache@v5 + uses: actions/cache@v6 with: path: ~/.bun/install/cache key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }} diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index f761678..ff3b3b3 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -23,7 +23,7 @@ jobs: - uses: actions/checkout@v7 - name: Setup Node.js - uses: actions/setup-node@v6 + uses: actions/setup-node@v7 with: node-version: '22' @@ -31,7 +31,7 @@ jobs: uses: oven-sh/setup-bun@v2 - name: Cache bun dependencies - uses: actions/cache@v5 + uses: actions/cache@v6 with: path: ~/.bun/install/cache key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 21427e7..ecf925f 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -17,7 +17,7 @@ jobs: - name: Setup Bun uses: oven-sh/setup-bun@v2 - - uses: actions/setup-node@v6 + - uses: actions/setup-node@v7 with: node-version: 22 registry-url: 'https://registry.npmjs.org' @@ -29,7 +29,7 @@ jobs: run: npm install -g npm@latest - name: Cache bun dependencies - uses: actions/cache@v5 + uses: actions/cache@v6 with: path: ~/.bun/install/cache key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d6c692e..0d4a6c5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -3,7 +3,10 @@ name: Release Binaries on: push: tags: - - 'v*' + # Plain semver only. 'v*' also matched scratch tags (e.g. v0.18.1-hooktest), + # which kicked off the full four-target binary matrix and failed noisily + # once the tag was deleted. Every real release here is plain semver. + - 'v[0-9]+.[0-9]+.[0-9]+' jobs: build: @@ -34,7 +37,7 @@ jobs: bun-version: "latest" - name: Cache bun dependencies - uses: actions/cache@v5 + uses: actions/cache@v6 with: path: ~/.bun/install/cache key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }} diff --git a/apps/agent-sdk/package.json b/apps/agent-sdk/package.json index 118a566..8ad8c45 100644 --- a/apps/agent-sdk/package.json +++ b/apps/agent-sdk/package.json @@ -41,7 +41,7 @@ }, "devDependencies": { "@types/bun": "^1.2.0", - "@types/node": "^25.2.0", + "@types/node": "^26.1.2", "effect": "^3.19.15", "typescript": "^5.7.0", "vitest": "^4.0.18" diff --git a/apps/cli/package.json b/apps/cli/package.json index ea93236..fe2f78b 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -111,7 +111,7 @@ }, "devDependencies": { "@types/bun": "^1.2.0", - "@types/node": "^25.2.0", + "@types/node": "^26.1.2", "typescript": "^5.7.0", "vitest": "^4.0.18" }, diff --git a/apps/dashboard/package.json b/apps/dashboard/package.json index 0d54948..6473311 100644 --- a/apps/dashboard/package.json +++ b/apps/dashboard/package.json @@ -15,13 +15,11 @@ }, "dependencies": { "@effect/platform": "^0.96.0", - "@hono/node-server": "^1.14.0", "@jamesaphoenix/tx": "*", "@tanstack/react-query": "^5.66.0", "@tanstack/react-store": "^0.11.0", "@tanstack/store": "^0.11.0", "effect": "^3.19.15", - "hono": "^4.7.4", "react": "^19.0.0", "react-dom": "^19.0.0", "react-markdown": "^10.1.0", @@ -33,7 +31,7 @@ "@playwright/test": "^1.58.2", "@tailwindcss/typography": "0.5.20", "@tailwindcss/vite": "^4.0.0", - "@testing-library/jest-dom": "^6.6.3", + "@testing-library/jest-dom": "^7.0.0", "@testing-library/react": "^16.2.0", "@testing-library/user-event": "^14.6.1", "@types/bun": "^1.2.0", @@ -42,7 +40,7 @@ "@types/react-dom": "^19.0.3", "@vitejs/plugin-react": "^6.0.1", "concurrently": "^10.0.3", - "jsdom": "^29.0.1", + "jsdom": "^30.0.1", "msw": "^2.7.0", "tailwindcss": "^4.0.0", "tsx": "^4.19.2", diff --git a/apps/dashboard/server/index.d.ts b/apps/dashboard/server/index.d.ts deleted file mode 100644 index e26a57a..0000000 --- a/apps/dashboard/server/index.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/apps/dashboard/server/index.d.ts.map b/apps/dashboard/server/index.d.ts.map deleted file mode 100644 index 82335e7..0000000 --- a/apps/dashboard/server/index.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/apps/dashboard/server/index.js b/apps/dashboard/server/index.js deleted file mode 100644 index a3b69a0..0000000 --- a/apps/dashboard/server/index.js +++ /dev/null @@ -1,450 +0,0 @@ -import { serve } from "@hono/node-server"; -import { Hono } from "hono"; -import { cors } from "hono/cors"; -import Database from "better-sqlite3"; -import { readFileSync, existsSync } from "fs"; -import { resolve, dirname } from "path"; -import { homedir } from "os"; -import { fileURLToPath } from "url"; -const __dirname = dirname(fileURLToPath(import.meta.url)); -const projectRoot = resolve(__dirname, "../../.."); -const dbPath = resolve(projectRoot, ".tx/tasks.db"); -const ralphLogPath = resolve(projectRoot, ".tx/ralph-output.log"); -const ralphPidPath = resolve(projectRoot, ".tx/ralph.pid"); -const txDir = resolve(projectRoot, ".tx"); -const claudeDir = resolve(homedir(), ".claude"); -/** - * Validate that a file path is within an allowed directory. - * Allows paths within: - * - .tx/ directory (locally stored transcripts) - * - ~/.claude/ directory (Claude Code native transcripts) - * Prevents path traversal attacks (e.g., ../../etc/passwd). - * Returns the resolved absolute path if valid, null if invalid. - */ -const validateTranscriptPath = (filePath) => { - const resolved = resolve(projectRoot, filePath); - // Allow paths within the .tx directory - if (resolved.startsWith(txDir + "/") || resolved === txDir) { - return resolved; - } - // Allow paths within ~/.claude directory (Claude Code transcripts) - if (resolved.startsWith(claudeDir + "/") || resolved === claudeDir) { - return resolved; - } - return null; -}; -const app = new Hono(); -app.use("/*", cors()); -// Lazy DB connection -let db = null; -const getDb = () => { - if (!db) { - if (!existsSync(dbPath)) { - throw new Error(`Database not found at ${dbPath}. Run 'tx init' first.`); - } - db = new Database(dbPath, { readonly: true }); - } - return db; -}; -// Pagination helpers -function parseTaskCursor(cursor) { - const colonIndex = cursor.lastIndexOf(':'); - return { - score: parseInt(cursor.slice(0, colonIndex), 10), - id: cursor.slice(colonIndex + 1), - }; -} -function parseRunCursor(cursor) { - // Format: "2026-01-30T10:00:00Z:run-abc123" - // Find the last colon that separates timestamp from id - const match = cursor.match(/^(.+):(run-.+)$/); - if (!match) { - return { startedAt: cursor, id: '' }; - } - return { startedAt: match[1], id: match[2] }; -} -function buildTaskCursor(task) { - return `${task.score}:${task.id}`; -} -function buildRunCursor(run) { - return `${run.started_at}:${run.id}`; -} -// Helper to enrich tasks with dependency info -function enrichTasksWithDeps(db, tasks, allTasks) { - // Get all dependencies - const deps = db.prepare("SELECT blocker_id, blocked_id FROM task_dependencies").all(); - // Build maps - const blockedByMap = new Map(); - const blocksMap = new Map(); - for (const dep of deps) { - const existing = blockedByMap.get(dep.blocked_id) ?? []; - blockedByMap.set(dep.blocked_id, [...existing, dep.blocker_id]); - const existingBlocks = blocksMap.get(dep.blocker_id) ?? []; - blocksMap.set(dep.blocker_id, [...existingBlocks, dep.blocked_id]); - } - // Build children map from all tasks if provided, otherwise query - const tasksForChildren = allTasks ?? db.prepare("SELECT id, parent_id FROM tasks").all(); - const childrenMap = new Map(); - for (const task of tasksForChildren) { - if (task.parent_id) { - const existing = childrenMap.get(task.parent_id) ?? []; - childrenMap.set(task.parent_id, [...existing, task.id]); - } - } - // Status of all tasks for ready check - const allTasksForStatus = allTasks ?? db.prepare("SELECT id, status FROM tasks").all(); - const statusMap = new Map(allTasksForStatus.map(t => [t.id, t.status])); - const workableStatuses = ["backlog", "ready", "planning"]; - return tasks.map(task => { - const blockedBy = blockedByMap.get(task.id) ?? []; - const blocks = blocksMap.get(task.id) ?? []; - const children = childrenMap.get(task.id) ?? []; - const allBlockersDone = blockedBy.every(id => statusMap.get(id) === "done"); - const isReady = workableStatuses.includes(task.status) && allBlockersDone; - return { ...task, blockedBy, blocks, children, isReady }; - }); -} -// GET /api/tasks - with cursor-based pagination -app.get("/api/tasks", (c) => { - try { - const db = getDb(); - const cursor = c.req.query("cursor"); - const limit = Math.min(parseInt(c.req.query("limit") ?? "20"), 100); - const statusFilter = c.req.query("status")?.split(",").filter(Boolean); - const search = c.req.query("search"); - // Build WHERE clauses - const conditions = []; - const params = []; - if (statusFilter?.length) { - conditions.push(`status IN (${statusFilter.map(() => "?").join(",")})`); - params.push(...statusFilter); - } - if (search) { - conditions.push("(title LIKE ? OR description LIKE ?)"); - params.push(`%${search}%`, `%${search}%`); - } - if (cursor) { - const { score, id } = parseTaskCursor(cursor); - conditions.push("(score < ? OR (score = ? AND id > ?))"); - params.push(score, score, id); - } - const whereClause = conditions.length ? `WHERE ${conditions.join(" AND ")}` : ""; - // Fetch limit + 1 to check hasMore - const sql = ` - SELECT * FROM tasks - ${whereClause} - ORDER BY score DESC, id ASC - LIMIT ? - `; - params.push(limit + 1); - const rows = db.prepare(sql).all(...params); - const hasMore = rows.length > limit; - const tasks = hasMore ? rows.slice(0, limit) : rows; - // Get total count for display (without cursor condition) - const countConditions = conditions.filter((_, i) => { - // Remove cursor condition (last 3 params if cursor exists) - return !cursor || i < conditions.length - 1; - }); - const countParams = cursor ? params.slice(0, -4) : params.slice(0, -1); // Remove limit and cursor params - const countWhereClause = countConditions.length ? `WHERE ${countConditions.join(" AND ")}` : ""; - const total = db.prepare(`SELECT COUNT(*) as count FROM tasks ${countWhereClause}`).get(...countParams).count; - // Enrich with deps - const enriched = enrichTasksWithDeps(db, tasks); - // Summary (from all tasks matching filter, not just current page) - const summaryRows = db.prepare(`SELECT status, COUNT(*) as count FROM tasks ${countWhereClause} GROUP BY status`).all(...countParams); - const byStatus = summaryRows.reduce((acc, r) => { - acc[r.status] = r.count; - return acc; - }, {}); - return c.json({ - tasks: enriched, - nextCursor: hasMore && tasks.length ? buildTaskCursor(tasks[tasks.length - 1]) : null, - hasMore, - total, - summary: { total, byStatus }, - }); - } - catch (e) { - return c.json({ error: String(e) }, 500); - } -}); -// GET /api/tasks/ready - Returns ALL ready tasks (not paginated) -app.get("/api/tasks/ready", (c) => { - try { - const db = getDb(); - // Get all tasks to compute ready status and children - const allTasks = db.prepare("SELECT * FROM tasks ORDER BY score DESC").all(); - const deps = db.prepare("SELECT blocker_id, blocked_id FROM task_dependencies").all(); - const blockedByMap = new Map(); - for (const dep of deps) { - const existing = blockedByMap.get(dep.blocked_id) ?? []; - blockedByMap.set(dep.blocked_id, [...existing, dep.blocker_id]); - } - const statusMap = new Map(allTasks.map(t => [t.id, t.status])); - const workableStatuses = ["backlog", "ready", "planning"]; - // Filter to ready tasks - const readyTasks = allTasks.filter(task => { - const blockedBy = blockedByMap.get(task.id) ?? []; - const allBlockersDone = blockedBy.every(id => statusMap.get(id) === "done"); - return workableStatuses.includes(task.status) && allBlockersDone; - }); - // Enrich with full dependency info (Rule 1: every API response MUST include TaskWithDeps) - const enriched = enrichTasksWithDeps(db, readyTasks, allTasks); - return c.json({ tasks: enriched }); - } - catch (e) { - return c.json({ error: String(e) }, 500); - } -}); -// GET /api/ralph -app.get("/api/ralph", (c) => { - try { - // Check if ralph is running - let running = false; - let pid = null; - if (existsSync(ralphPidPath)) { - const pidStr = readFileSync(ralphPidPath, "utf-8").trim(); - pid = parseInt(pidStr, 10); - try { - process.kill(pid, 0); // Check if process exists - running = true; - } - catch { - running = false; - } - } - // Parse ralph log for recent activity - const recentActivity = []; - let currentIteration = 0; - let currentTask = null; - if (existsSync(ralphLogPath)) { - const log = readFileSync(ralphLogPath, "utf-8"); - const lines = log.split("\n"); - for (const line of lines) { - // Match iteration start - const iterMatch = line.match(/\[([^\]]+)\] --- Iteration (\d+) ---/); - if (iterMatch) { - currentIteration = parseInt(iterMatch[2], 10); - } - // Match task assignment - const taskMatch = line.match(/\[([^\]]+)\] Task: (tx-[a-z0-9]+) — (.+)/); - if (taskMatch) { - currentTask = taskMatch[2]; - recentActivity.push({ - timestamp: taskMatch[1], - iteration: currentIteration, - task: taskMatch[2], - taskTitle: taskMatch[3], - agent: "", - status: "started", - }); - } - // Match agent - const agentMatch = line.match(/\[([^\]]+)\] Agent: (.+)/); - if (agentMatch && recentActivity.length > 0) { - recentActivity[recentActivity.length - 1].agent = agentMatch[2]; - } - // Match completion - const completeMatch = line.match(/\[([^\]]+)\] Agent completed successfully/); - if (completeMatch && recentActivity.length > 0) { - recentActivity.push({ - ...recentActivity[recentActivity.length - 1], - timestamp: completeMatch[1], - status: "completed", - }); - } - // Match failure - const failMatch = line.match(/\[([^\]]+)\] Agent failed/); - if (failMatch && recentActivity.length > 0) { - recentActivity.push({ - ...recentActivity[recentActivity.length - 1], - timestamp: failMatch[1], - status: "failed", - }); - } - } - } - return c.json({ - running, - pid, - currentIteration, - currentTask, - recentActivity: recentActivity.slice(-20).reverse(), // Last 20, newest first - }); - } - catch (e) { - return c.json({ error: String(e) }, 500); - } -}); -// GET /api/stats -app.get("/api/stats", (c) => { - try { - const db = getDb(); - const taskCount = db.prepare("SELECT COUNT(*) as count FROM tasks").get().count; - const doneCount = db.prepare("SELECT COUNT(*) as count FROM tasks WHERE status = 'done'").get().count; - const readyCount = db.prepare(` - SELECT COUNT(*) as count FROM tasks t - WHERE t.status IN ('backlog', 'ready', 'planning') - AND NOT EXISTS ( - SELECT 1 FROM task_dependencies d - JOIN tasks blocker ON d.blocker_id = blocker.id - WHERE d.blocked_id = t.id AND blocker.status != 'done' - ) - `).get().count; - // Learnings count (if table exists) - let learningsCount = 0; - try { - learningsCount = db.prepare("SELECT COUNT(*) as count FROM learnings").get().count; - } - catch { - // Table doesn't exist yet - } - // Runs count (if table exists) - let runsRunning = 0; - let runsTotal = 0; - try { - runsRunning = db.prepare("SELECT COUNT(*) as count FROM runs WHERE status = 'running'").get().count; - runsTotal = db.prepare("SELECT COUNT(*) as count FROM runs").get().count; - } - catch { - // Table doesn't exist yet - } - return c.json({ - tasks: taskCount, - done: doneCount, - ready: readyCount, - learnings: learningsCount, - runsRunning, - runsTotal, - }); - } - catch (e) { - return c.json({ error: String(e) }, 500); - } -}); -// GET /api/runs - List runs with cursor-based pagination -app.get("/api/runs", (c) => { - try { - const db = getDb(); - const cursor = c.req.query("cursor"); - const limit = Math.min(parseInt(c.req.query("limit") ?? "20"), 100); - const agentFilter = c.req.query("agent"); - const statusFilter = c.req.query("status")?.split(",").filter(Boolean); - // Build WHERE clauses - const conditions = []; - const params = []; - if (agentFilter) { - conditions.push("agent = ?"); - params.push(agentFilter); - } - if (statusFilter?.length) { - conditions.push(`status IN (${statusFilter.map(() => "?").join(",")})`); - params.push(...statusFilter); - } - if (cursor) { - const { startedAt, id } = parseRunCursor(cursor); - conditions.push("(started_at < ? OR (started_at = ? AND id > ?))"); - params.push(startedAt, startedAt, id); - } - const whereClause = conditions.length ? `WHERE ${conditions.join(" AND ")}` : ""; - let runs = []; - try { - const sql = ` - SELECT id, task_id, agent, started_at, ended_at, status, exit_code, transcript_path, summary, error_message - FROM runs - ${whereClause} - ORDER BY started_at DESC, id ASC - LIMIT ? - `; - params.push(limit + 1); - runs = db.prepare(sql).all(...params); - } - catch { - // Table doesn't exist yet - return c.json({ runs: [], nextCursor: null, hasMore: false }); - } - const hasMore = runs.length > limit; - const pagedRuns = hasMore ? runs.slice(0, limit) : runs; - // Enrich with task titles - const enriched = pagedRuns.map(run => { - let taskTitle = null; - if (run.task_id) { - const task = db.prepare("SELECT title FROM tasks WHERE id = ?").get(run.task_id); - taskTitle = task?.title ?? null; - } - return { ...run, taskTitle }; - }); - return c.json({ - runs: enriched, - nextCursor: hasMore && pagedRuns.length ? buildRunCursor(pagedRuns[pagedRuns.length - 1]) : null, - hasMore, - }); - } - catch (e) { - return c.json({ error: String(e) }, 500); - } -}); -// GET /api/tasks/:id - Get task detail with related tasks -app.get("/api/tasks/:id", (c) => { - try { - const db = getDb(); - const id = c.req.param("id"); - const task = db.prepare("SELECT * FROM tasks WHERE id = ?").get(id); - if (!task) { - return c.json({ error: "Task not found" }, 404); - } - // Get dependency info - const blockedByIds = db.prepare("SELECT blocker_id FROM task_dependencies WHERE blocked_id = ?").all(id); - const blocksIds = db.prepare("SELECT blocked_id FROM task_dependencies WHERE blocker_id = ?").all(id); - const childIds = db.prepare("SELECT id FROM tasks WHERE parent_id = ?").all(id); - // Fetch full task data for related tasks - const fetchTasksByIds = (ids) => { - if (ids.length === 0) - return []; - const placeholders = ids.map(() => "?").join(","); - const tasks = db.prepare(`SELECT * FROM tasks WHERE id IN (${placeholders})`).all(...ids); - return enrichTasksWithDeps(db, tasks); - }; - const blockedByTasks = fetchTasksByIds(blockedByIds.map(r => r.blocker_id)); - const blocksTasks = fetchTasksByIds(blocksIds.map(r => r.blocked_id)); - const childTasks = fetchTasksByIds(childIds.map(r => r.id)); - // Enrich the main task - const [enrichedTask] = enrichTasksWithDeps(db, [task]); - return c.json({ - task: enrichedTask, - blockedByTasks, - blocksTasks, - childTasks, - }); - } - catch (e) { - return c.json({ error: String(e) }, 500); - } -}); -// GET /api/runs/:id - Get run details with transcript -app.get("/api/runs/:id", (c) => { - try { - const db = getDb(); - const id = c.req.param("id"); - const run = db.prepare("SELECT * FROM runs WHERE id = ?").get(id); - if (!run) { - return c.json({ error: "Run not found" }, 404); - } - // Try to read transcript if it exists and path is valid - let transcript = null; - if (run.transcript_path) { - const validatedPath = validateTranscriptPath(run.transcript_path); - if (validatedPath && existsSync(validatedPath)) { - transcript = readFileSync(validatedPath, "utf-8"); - } - } - return c.json({ run, transcript }); - } - catch (e) { - return c.json({ error: String(e) }, 500); - } -}); -const port = 3001; -console.log(`Dashboard API running on http://localhost:${port}`); -serve({ fetch: app.fetch, port }); -//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/apps/dashboard/server/index.js.map b/apps/dashboard/server/index.js.map deleted file mode 100644 index 2e178cc..0000000 --- a/apps/dashboard/server/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/apps/docs/package.json b/apps/docs/package.json index 90f871e..1ed1d56 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -21,7 +21,7 @@ "devDependencies": { "@opennextjs/cloudflare": "^1.20.1", "@tailwindcss/postcss": "^4.0.0", - "@types/node": "^25.2.0", + "@types/node": "^26.1.2", "@types/react": "^19.0.8", "@types/react-dom": "^19.0.3", "tailwindcss": "^4.0.0", diff --git a/bun.lock b/bun.lock index 7e2483c..3e0262f 100644 --- a/bun.lock +++ b/bun.lock @@ -15,7 +15,7 @@ "devDependencies": { "@eslint/js": "^9.39.2", "@types/bun": "^1.3.9", - "@types/node": "^25.2.3", + "@types/node": "^26.1.2", "@typescript-eslint/eslint-plugin": "^8.55.0", "@typescript-eslint/parser": "^8.55.0", "eslint": "^10.0.1", @@ -31,13 +31,13 @@ }, "apps/agent-sdk": { "name": "@jamesaphoenix/tx-agent-sdk", - "version": "0.16.0", + "version": "0.18.0", "dependencies": { "@jamesaphoenix/tx": "*", }, "devDependencies": { "@types/bun": "^1.2.0", - "@types/node": "^25.2.0", + "@types/node": "^26.1.2", "effect": "^3.19.15", "typescript": "^5.7.0", "vitest": "^4.0.18", @@ -48,7 +48,7 @@ }, "apps/cli": { "name": "@jamesaphoenix/tx-cli", - "version": "0.16.0", + "version": "0.18.0", "bin": { "tx": "./dist/cli.js", "tx-mcp": "./dist/mcp/server.js", @@ -66,23 +66,21 @@ }, "devDependencies": { "@types/bun": "^1.2.0", - "@types/node": "^25.2.0", + "@types/node": "^26.1.2", "typescript": "^5.7.0", "vitest": "^4.0.18", }, }, "apps/dashboard": { "name": "@jamesaphoenix/tx-dashboard", - "version": "0.16.0", + "version": "0.18.0", "dependencies": { "@effect/platform": "^0.96.0", - "@hono/node-server": "^1.14.0", "@jamesaphoenix/tx": "*", "@tanstack/react-query": "^5.66.0", "@tanstack/react-store": "^0.11.0", "@tanstack/store": "^0.11.0", "effect": "^3.19.15", - "hono": "^4.7.4", "react": "^19.0.0", "react-dom": "^19.0.0", "react-markdown": "^10.1.0", @@ -94,7 +92,7 @@ "@playwright/test": "^1.58.2", "@tailwindcss/typography": "0.5.20", "@tailwindcss/vite": "^4.0.0", - "@testing-library/jest-dom": "^6.6.3", + "@testing-library/jest-dom": "^7.0.0", "@testing-library/react": "^16.2.0", "@testing-library/user-event": "^14.6.1", "@types/bun": "^1.2.0", @@ -103,7 +101,7 @@ "@types/react-dom": "^19.0.3", "@vitejs/plugin-react": "^6.0.1", "concurrently": "^10.0.3", - "jsdom": "^29.0.1", + "jsdom": "^30.0.1", "msw": "^2.7.0", "tailwindcss": "^4.0.0", "tsx": "^4.19.2", @@ -114,7 +112,7 @@ }, "apps/docs": { "name": "@jamesaphoenix/tx-docs", - "version": "0.16.0", + "version": "0.18.0", "dependencies": { "fumadocs-core": "^16.5.0", "fumadocs-mdx": "^14.2.6", @@ -127,7 +125,7 @@ "devDependencies": { "@opennextjs/cloudflare": "^1.20.1", "@tailwindcss/postcss": "^4.0.0", - "@types/node": "^25.2.0", + "@types/node": "^26.1.2", "@types/react": "^19.0.8", "@types/react-dom": "^19.0.3", "tailwindcss": "^4.0.0", @@ -137,7 +135,7 @@ }, "packages/core": { "name": "@jamesaphoenix/tx", - "version": "0.16.0", + "version": "0.18.0", "dependencies": { "chokidar": "^5.0.0", "effect": "^3.19.15", @@ -165,11 +163,9 @@ "@antfu/install-pkg": ["@antfu/install-pkg@1.1.0", "", { "dependencies": { "package-manager-detector": "^1.3.0", "tinyexec": "^1.0.1" } }, "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ=="], - "@asamuzakjp/css-color": ["@asamuzakjp/css-color@5.1.5", "", { "dependencies": { "@csstools/css-calc": "^3.1.1", "@csstools/css-color-parser": "^4.0.2", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "lru-cache": "^11.2.7" } }, "sha512-8cMAA1bE66Mb/tfmkhcfJLjEPgyT7SSy6lW6id5XL113ai1ky76d/1L27sGnXCMsLfq66DInAU3OzuahB4lu9Q=="], + "@asamuzakjp/css-color": ["@asamuzakjp/css-color@6.0.7", "", { "dependencies": { "@csstools/css-calc": "^3.3.0", "@csstools/css-color-parser": "^4.1.10", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "lru-cache": "^11.5.2" } }, "sha512-vC/bk1Lz7Tn/EfU9/apOTBk80/8dyGyWMowPoV1tJ52muDGsDqt2HPT2klrFUiY60MQmQv9q8yIht15JnBgDGw=="], - "@asamuzakjp/dom-selector": ["@asamuzakjp/dom-selector@7.0.6", "", { "dependencies": { "@asamuzakjp/nwsapi": "^2.3.9", "bidi-js": "^1.0.3", "css-tree": "^3.2.1", "is-potential-custom-element-name": "^1.0.1", "lru-cache": "^11.2.7" } }, "sha512-Tgmk6EQM0nc9xvp7sEHRVavbknhb/vGKht+04yAT3t5KQwZ02CSobCtcFgaHH04ZrjD1BhEKNA8tRhzFV20gkA=="], - - "@asamuzakjp/nwsapi": ["@asamuzakjp/nwsapi@2.3.9", "", {}, "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q=="], + "@asamuzakjp/dom-selector": ["@asamuzakjp/dom-selector@8.3.2", "", { "dependencies": { "bidi-js": "^1.0.3", "css-tree": "^3.2.1", "is-potential-custom-element-name": "^1.0.1", "lru-cache": "^11.5.2" } }, "sha512-93Z1N+BQNXysodoicpOIyNh2drHfz/CTf9nnT0FEx72GJcIiwgydD7tGAr78j41LsYn3hlRn+LdGPuBLn1Bl8Q=="], "@ast-grep/napi": ["@ast-grep/napi@0.40.5", "", { "optionalDependencies": { "@ast-grep/napi-darwin-arm64": "0.40.5", "@ast-grep/napi-darwin-x64": "0.40.5", "@ast-grep/napi-linux-arm64-gnu": "0.40.5", "@ast-grep/napi-linux-arm64-musl": "0.40.5", "@ast-grep/napi-linux-x64-gnu": "0.40.5", "@ast-grep/napi-linux-x64-musl": "0.40.5", "@ast-grep/napi-win32-arm64-msvc": "0.40.5", "@ast-grep/napi-win32-ia32-msvc": "0.40.5", "@ast-grep/napi-win32-x64-msvc": "0.40.5" } }, "sha512-hJA62OeBKUQT68DD2gDyhOqJxZxycqg8wLxbqjgqSzYttCMSDL9tiAQ9abgekBYNHudbJosm9sWOEbmCDfpX2A=="], @@ -337,15 +333,15 @@ "@cspotcode/source-map-support": ["@cspotcode/source-map-support@0.8.1", "", { "dependencies": { "@jridgewell/trace-mapping": "0.3.9" } }, "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw=="], - "@csstools/color-helpers": ["@csstools/color-helpers@6.0.2", "", {}, "sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q=="], + "@csstools/color-helpers": ["@csstools/color-helpers@6.1.0", "", {}, "sha512-064IFJdjTfUqnjpCVpMOdbr8FLQBhinbZj6yRv2An2E41O/pLEXqfFRWqGq/SxlE5PEUYTlvWsG2r8MswAVvkg=="], - "@csstools/css-calc": ["@csstools/css-calc@3.1.1", "", { "peerDependencies": { "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" } }, "sha512-HJ26Z/vmsZQqs/o3a6bgKslXGFAungXGbinULZO3eMsOyNJHeBBZfup5FiZInOghgoM4Hwnmw+OgbJCNg1wwUQ=="], + "@csstools/css-calc": ["@csstools/css-calc@3.3.0", "", { "peerDependencies": { "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" } }, "sha512-c5ihYsPkdG6JCkU2zTMm4+k6r7RXuGxtWYhu5DHMIiF1FHzrfmHL5so11AoFpUv/tu61xfcmT4AmKoFfMPoqdQ=="], - "@csstools/css-color-parser": ["@csstools/css-color-parser@4.0.2", "", { "dependencies": { "@csstools/color-helpers": "^6.0.2", "@csstools/css-calc": "^3.1.1" }, "peerDependencies": { "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" } }, "sha512-0GEfbBLmTFf0dJlpsNU7zwxRIH0/BGEMuXLTCvFYxuL1tNhqzTbtnFICyJLTNK4a+RechKP75e7w42ClXSnJQw=="], + "@csstools/css-color-parser": ["@csstools/css-color-parser@4.1.10", "", { "dependencies": { "@csstools/color-helpers": "^6.1.0", "@csstools/css-calc": "^3.3.0" }, "peerDependencies": { "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" } }, "sha512-UZhQLIUyJaaMepqehrCODwCg2KW25vFvLWBmqYFaPclYvvxzj/sG8LBOhBFCp11i9uE7t1EyS+RAoV9tztPFyw=="], "@csstools/css-parser-algorithms": ["@csstools/css-parser-algorithms@4.0.0", "", { "peerDependencies": { "@csstools/css-tokenizer": "^4.0.0" } }, "sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w=="], - "@csstools/css-syntax-patches-for-csstree": ["@csstools/css-syntax-patches-for-csstree@1.1.2", "", { "peerDependencies": { "css-tree": "^3.2.1" }, "optionalPeers": ["css-tree"] }, "sha512-5GkLzz4prTIpoyeUiIu3iV6CSG3Plo7xRVOFPKI7FVEJ3mZ0A8SwK0XU3Gl7xAkiQ+mDyam+NNp875/C5y+jSA=="], + "@csstools/css-syntax-patches-for-csstree": ["@csstools/css-syntax-patches-for-csstree@1.1.7", "", { "peerDependencies": { "css-tree": "^3.2.1" }, "optionalPeers": ["css-tree"] }, "sha512-fQ+05118eQS1cofO3aJpB5efgpBZMvIzwr/sbC8kDLVA5XLG8q1kJV5yzrUAI1f7lvhPnm8fgIjzFB8/O/5Dig=="], "@csstools/css-tokenizer": ["@csstools/css-tokenizer@4.0.0", "", {}, "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA=="], @@ -473,7 +469,7 @@ "@eslint/plugin-kit": ["@eslint/plugin-kit@0.6.0", "", { "dependencies": { "@eslint/core": "^1.1.0", "levn": "^0.4.1" } }, "sha512-bIZEUzOI1jkhviX2cp5vNyXQc6olzb2ohewQubuYlMXZ2Q/XjBO0x0XhGPvc9fjSIiUN0vw+0hq53BJ4eQSJKQ=="], - "@exodus/bytes": ["@exodus/bytes@1.15.0", "", { "peerDependencies": { "@noble/hashes": "^1.8.0 || ^2.0.0" }, "optionalPeers": ["@noble/hashes"] }, "sha512-UY0nlA+feH81UGSHv92sLEPLCeZFjXOuHhrIo0HQydScuQc8s0A7kL/UdgwgDq8g8ilksmuoF35YVTNphV2aBQ=="], + "@exodus/bytes": ["@exodus/bytes@1.15.1", "", { "peerDependencies": { "@noble/hashes": "^1.8.0 || ^2.0.0" }, "optionalPeers": ["@noble/hashes"] }, "sha512-S6mL0yNB/Abt9Ei4tq8gDhcczc4S3+vQ4ra7vxnAf+YHC02srtqxKKZghx2Dq6p0e66THKwR6r8N6P95wEty7Q=="], "@floating-ui/core": ["@floating-ui/core@1.7.4", "", { "dependencies": { "@floating-ui/utils": "^0.2.10" } }, "sha512-C3HlIdsBxszvm5McXlB8PeOEWfBhcGBTZGkGlWc2U0KFY5IwG5OQEuQ8rq52DZmcHDlPLd+YFBK+cZcytwIFWg=="], @@ -1087,7 +1083,7 @@ "@testing-library/dom": ["@testing-library/dom@10.4.1", "", { "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", "@types/aria-query": "^5.0.1", "aria-query": "5.3.0", "dom-accessibility-api": "^0.5.9", "lz-string": "^1.5.0", "picocolors": "1.1.1", "pretty-format": "^27.0.2" } }, "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg=="], - "@testing-library/jest-dom": ["@testing-library/jest-dom@6.9.1", "", { "dependencies": { "@adobe/css-tools": "^4.4.0", "aria-query": "^5.0.0", "css.escape": "^1.5.1", "dom-accessibility-api": "^0.6.3", "picocolors": "^1.1.1", "redent": "^3.0.0" } }, "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA=="], + "@testing-library/jest-dom": ["@testing-library/jest-dom@7.0.1", "", { "dependencies": { "@adobe/css-tools": "^4.4.0", "aria-query": "^5.0.0", "css.escape": "^1.5.1", "dom-accessibility-api": "^0.6.3", "picocolors": "^1.1.1", "redent": "^3.0.0" }, "peerDependencies": { "@testing-library/dom": ">=10 <11", "vitest": ">= 0.32" }, "optionalPeers": ["vitest"] }, "sha512-oMDTC3oA+6CXSO2JZnvOI7CA6oVub6kij5ggk9ohwye5slmkwxYDXcPOVxgMw/RQlticjtO0C1RZkR97HgrWMw=="], "@testing-library/react": ["@testing-library/react@16.3.2", "", { "dependencies": { "@babel/runtime": "^7.12.5" }, "peerDependencies": { "@testing-library/dom": "^10.0.0", "@types/react": "^18.0.0 || ^19.0.0", "@types/react-dom": "^18.0.0 || ^19.0.0", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g=="], @@ -1193,7 +1189,7 @@ "@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="], - "@types/node": ["@types/node@25.2.3", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ=="], + "@types/node": ["@types/node@26.2.0", "", { "dependencies": { "undici-types": "~8.3.0" } }, "sha512-5IviulTZeRNp2vAJ514cc/HUlY5nZ9fCbq9DMyC52BrhFZACo3nI0R7qBxhQmo/d27NFe96ur/b7Wwxklda+kg=="], "@types/node-fetch": ["@types/node-fetch@2.6.13", "", { "dependencies": { "@types/node": "*", "form-data": "^4.0.4" } }, "sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw=="], @@ -1853,7 +1849,7 @@ "js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="], - "jsdom": ["jsdom@29.0.1", "", { "dependencies": { "@asamuzakjp/css-color": "^5.0.1", "@asamuzakjp/dom-selector": "^7.0.3", "@bramus/specificity": "^2.4.2", "@csstools/css-syntax-patches-for-csstree": "^1.1.1", "@exodus/bytes": "^1.15.0", "css-tree": "^3.2.1", "data-urls": "^7.0.0", "decimal.js": "^10.6.0", "html-encoding-sniffer": "^6.0.0", "is-potential-custom-element-name": "^1.0.1", "lru-cache": "^11.2.7", "parse5": "^8.0.0", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", "tough-cookie": "^6.0.1", "undici": "^7.24.5", "w3c-xmlserializer": "^5.0.0", "webidl-conversions": "^8.0.1", "whatwg-mimetype": "^5.0.0", "whatwg-url": "^16.0.1", "xml-name-validator": "^5.0.0" }, "peerDependencies": { "canvas": "^3.0.0" }, "optionalPeers": ["canvas"] }, "sha512-z6JOK5gRO7aMybVq/y/MlIpKh8JIi68FBKMUtKkK2KH/wMSRlCxQ682d08LB9fYXplyY/UXG8P4XXTScmdjApg=="], + "jsdom": ["jsdom@30.0.1", "", { "dependencies": { "@asamuzakjp/css-color": "^6.0.5", "@asamuzakjp/dom-selector": "^8.3.0", "@bramus/specificity": "^2.4.2", "@csstools/css-syntax-patches-for-csstree": "^1.1.7", "@exodus/bytes": "^1.15.1", "css-tree": "^3.2.1", "data-urls": "^7.0.0", "decimal.js": "^10.6.0", "html-encoding-sniffer": "^6.0.0", "is-potential-custom-element-name": "^1.0.1", "lru-cache": "^11.5.2", "parse5": "^8.0.1", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", "tough-cookie": "^6.0.2", "undici": "^8.9.0", "w3c-xmlserializer": "^5.0.0", "webidl-conversions": "^8.0.1", "whatwg-mimetype": "^5.0.0", "whatwg-url": "^17.1.0", "xml-name-validator": "^5.0.0" }, "peerDependencies": { "canvas": "^3.2.3" }, "optionalPeers": ["canvas"] }, "sha512-52v7mUVUfNQVYYqE1lcdaymWL0njO7lTLUog6ZvW2U5KsbiLk/GnZlVJ+qx0xfNJZ6Gn+KSpPNE52vurbxZwrA=="], "jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="], @@ -1927,7 +1923,7 @@ "lowdb": ["lowdb@7.0.1", "", { "dependencies": { "steno": "^4.0.2" } }, "sha512-neJAj8GwF0e8EpycYIDFqEPcx9Qz4GUho20jWFR7YiFeXzF1YMLdxB36PypcTSPMA+4+LvgyMacYhlr18Zlymw=="], - "lru-cache": ["lru-cache@11.2.7", "", {}, "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA=="], + "lru-cache": ["lru-cache@11.5.2", "", {}, "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g=="], "lucide-react": ["lucide-react@0.563.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-8dXPB2GI4dI8jV4MgUDGBeLdGk8ekfqVZ0BdLcrRzocGgG75ltNEmWS+gE7uokKF/0oSUuczNDT+g9hFJ23FkA=="], @@ -2469,7 +2465,7 @@ "toml": ["toml@3.0.0", "", {}, "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w=="], - "tough-cookie": ["tough-cookie@6.0.1", "", { "dependencies": { "tldts": "^7.0.5" } }, "sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw=="], + "tough-cookie": ["tough-cookie@6.0.2", "", { "dependencies": { "tldts": "^7.0.5" } }, "sha512-exgYmnmL/sJpR3upZfXG5PoatXQii55xAiXGXzY+sROLZ/Y+SLcp9PgJNI9Vz37HpQ74WvDcLT8eqm+kV3FzrA=="], "tr46": ["tr46@6.0.0", "", { "dependencies": { "punycode": "^2.3.1" } }, "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw=="], @@ -2515,7 +2511,7 @@ "undici": ["undici@7.24.7", "", {}, "sha512-H/nlJ/h0ggGC+uRL3ovD+G0i4bqhvsDOpbDv7At5eFLlj2b41L8QliGbnl2H7SnDiYhENphh1tQFJZf+MyfLsQ=="], - "undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], + "undici-types": ["undici-types@8.3.0", "", {}, "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ=="], "unenv": ["unenv@2.0.0-rc.24", "", { "dependencies": { "pathe": "^2.0.3" } }, "sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw=="], @@ -2597,7 +2593,7 @@ "whatwg-mimetype": ["whatwg-mimetype@5.0.0", "", {}, "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw=="], - "whatwg-url": ["whatwg-url@16.0.1", "", { "dependencies": { "@exodus/bytes": "^1.11.0", "tr46": "^6.0.0", "webidl-conversions": "^8.0.1" } }, "sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw=="], + "whatwg-url": ["whatwg-url@17.1.0", "", { "dependencies": { "@exodus/bytes": "^1.15.1", "tr46": "^6.0.0", "webidl-conversions": "^8.0.1" } }, "sha512-3GeworPmc2ZfEEHP7lEbUfBX/L75wdEsi0rLNhXcXxnoN5jyq0SL5gCy06SGW2cyTIZdTvWIDQNQoza++vKeaw=="], "which": ["which@5.0.0", "", { "dependencies": { "isexe": "^3.1.1" }, "bin": { "node-which": "bin/which.js" } }, "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ=="], @@ -2725,8 +2721,12 @@ "@testing-library/dom/dom-accessibility-api": ["dom-accessibility-api@0.5.16", "", {}, "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg=="], + "@types/jsdom/@types/node": ["@types/node@25.2.3", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ=="], + "@types/jsdom/undici-types": ["undici-types@7.22.0", "", {}, "sha512-RKZvifiL60xdsIuC80UY0dq8Z7DbJUV8/l2hOVbyZAxBzEeQU4Z58+4ZzJ6WN2Lidi9KzT5EbiGX+PI/UGYuRw=="], + "@types/node-fetch/@types/node": ["@types/node@25.2.3", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ=="], + "@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], "@typescript-eslint/visitor-keys/eslint-visitor-keys": ["eslint-visitor-keys@4.2.1", "", {}, "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ=="], @@ -2735,6 +2735,8 @@ "ajv-formats/ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="], + "bun-types/@types/node": ["@types/node@25.2.3", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ=="], + "cliui/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], "cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], @@ -2793,7 +2795,9 @@ "ipull/pretty-ms": ["pretty-ms@8.0.0", "", { "dependencies": { "parse-ms": "^3.0.0" } }, "sha512-ASJqOugUF1bbzI35STMBUpZqdfYKlJugy6JBziGi2EE+AL5JPJGSzvpeVXojxrr0ViUYoToUjb5kjSEGf7Y83Q=="], - "jsdom/parse5": ["parse5@8.0.0", "", { "dependencies": { "entities": "^6.0.0" } }, "sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA=="], + "jsdom/parse5": ["parse5@8.0.1", "", { "dependencies": { "entities": "^8.0.0" } }, "sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw=="], + + "jsdom/undici": ["undici@8.10.0", "", {}, "sha512-HvltHd7avK13QIw/oLe4qoOLyoVSoafqJ2jYOrtMRBkbYT31eiBQ8O0ehRKZiEZCMEyLFQNIADpgCWC5fALvYQ=="], "katex/commander": ["commander@8.3.0", "", {}, "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww=="], @@ -2819,6 +2823,8 @@ "parse-json/@babel/code-frame": ["@babel/code-frame@7.29.0", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw=="], + "path-scurry/lru-cache": ["lru-cache@11.2.7", "", {}, "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA=="], + "playwright/fsevents": ["fsevents@2.3.2", "", { "os": "darwin" }, "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA=="], "postcss/nanoid": ["nanoid@3.3.11", "", { "bin": "bin/nanoid.cjs" }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], @@ -2959,6 +2965,10 @@ "@tailwindcss/vite/vite/postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="], + "@types/jsdom/@types/node/undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], + + "@types/node-fetch/@types/node/undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], + "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], "@vitest/mocker/vite/esbuild": ["esbuild@0.27.2", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.2", "@esbuild/android-arm": "0.27.2", "@esbuild/android-arm64": "0.27.2", "@esbuild/android-x64": "0.27.2", "@esbuild/darwin-arm64": "0.27.2", "@esbuild/darwin-x64": "0.27.2", "@esbuild/freebsd-arm64": "0.27.2", "@esbuild/freebsd-x64": "0.27.2", "@esbuild/linux-arm": "0.27.2", "@esbuild/linux-arm64": "0.27.2", "@esbuild/linux-ia32": "0.27.2", "@esbuild/linux-loong64": "0.27.2", "@esbuild/linux-mips64el": "0.27.2", "@esbuild/linux-ppc64": "0.27.2", "@esbuild/linux-riscv64": "0.27.2", "@esbuild/linux-s390x": "0.27.2", "@esbuild/linux-x64": "0.27.2", "@esbuild/netbsd-arm64": "0.27.2", "@esbuild/netbsd-x64": "0.27.2", "@esbuild/openbsd-arm64": "0.27.2", "@esbuild/openbsd-x64": "0.27.2", "@esbuild/openharmony-arm64": "0.27.2", "@esbuild/sunos-x64": "0.27.2", "@esbuild/win32-arm64": "0.27.2", "@esbuild/win32-ia32": "0.27.2", "@esbuild/win32-x64": "0.27.2" }, "bin": "bin/esbuild" }, "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw=="], @@ -2967,6 +2977,8 @@ "ajv-formats/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], + "bun-types/@types/node/undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], + "cliui/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], "cliui/string-width/is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="], @@ -3057,6 +3069,8 @@ "ipull/pretty-ms/parse-ms": ["parse-ms@3.0.0", "", {}, "sha512-Tpb8Z7r7XbbtBTrM9UhpkzzaMrqA2VXMT3YChzYltwV3P3pM6t8wl7TvpMnSTosz1aQAdVib7kdoys7vYOPerw=="], + "jsdom/parse5/entities": ["entities@8.0.0", "", {}, "sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA=="], + "next/postcss/nanoid": ["nanoid@3.3.11", "", { "bin": "bin/nanoid.cjs" }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], "node-fetch/whatwg-url/tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="], diff --git a/package.json b/package.json index f68c1bc..43124e3 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "devDependencies": { "@eslint/js": "^9.39.2", "@types/bun": "^1.3.9", - "@types/node": "^25.2.3", + "@types/node": "^26.1.2", "@typescript-eslint/eslint-plugin": "^8.55.0", "@typescript-eslint/parser": "^8.55.0", "eslint": "^10.0.1", diff --git a/test/integration/ralph-script.test.ts b/test/integration/ralph-script.test.ts index 8b5e84d..eca7032 100644 --- a/test/integration/ralph-script.test.ts +++ b/test/integration/ralph-script.test.ts @@ -28,6 +28,14 @@ import { } from "@jamesaphoenix/tx" import { fixtureId } from "../fixtures.js" +/** + * These tests start real subprocesses and poll for lock/pid effects, budgeting + * up to ~8.3s of waiting. Against vitest's global 10s testTimeout that leaves + * almost no headroom for process startup under CI load, so the test would be + * killed before its own waits could report a useful failure. + */ +const PROCESS_RACE_TIMEOUT_MS = 45000 + interface Harness { tmpDir: string stateDir: string @@ -654,7 +662,7 @@ describeIf("ralph.sh integration", () => { } finally { await terminateChild(ownerProc) } - }) + }, PROCESS_RACE_TIMEOUT_MS) it("stale-race: allows only one winner when concurrent starters race against a stale lock", async () => { const h = setupHarness() @@ -707,7 +715,7 @@ describeIf("ralph.sh integration", () => { await terminateChild(proc1) await terminateChild(proc2) } - }) + }, PROCESS_RACE_TIMEOUT_MS) itIfSqlite3("cancels orphaned runs and expires active claims for linked tasks", () => { const h = setupHarness() diff --git a/test/integration/ralph-watchdog-script.test.ts b/test/integration/ralph-watchdog-script.test.ts index ce74a6a..cbe8a51 100644 --- a/test/integration/ralph-watchdog-script.test.ts +++ b/test/integration/ralph-watchdog-script.test.ts @@ -365,6 +365,17 @@ afterEach(() => { } }) +/** + * Every test in this file spawns bash subprocesses and polls for their effects. + * Their internal guards (waitForCondition/waitForExit, and the 30s spawnSync cap) + * budget well past vitest's global 10s testTimeout, so without an explicit + * per-test timeout vitest kills the test before its own guards can report a + * useful failure. That is what made these tests pass locally and time out under + * CI load. Keep this comfortably above the largest internal budget + * (8s lock wait + 15s exit wait + 8s release wait = 31s). + */ +const PROCESS_TEST_TIMEOUT_MS = 60000 + describe("watchdog launcher integration", () => { it("enforces single-instance lock and restarts cleanly", () => { const harness = createHarness({ stubWatchdog: true }) @@ -398,7 +409,7 @@ describe("watchdog launcher integration", () => { expect(stop.status).toBe(0) expect(`${stop.stdout}\n${stop.stderr}`).toContain("Watchdog stopped") expect(existsSync(pidFile)).toBe(false) - }) + }, PROCESS_TEST_TIMEOUT_MS) }) describe("ralph-watchdog singleton lock integration", () => { @@ -470,11 +481,11 @@ describe("ralph-watchdog singleton lock integration", () => { it("allows only one winner when concurrent starts race with an empty pid file", async () => { await expectSingleWinner() - }) + }, PROCESS_TEST_TIMEOUT_MS) it("allows only one winner when concurrent starts race with a stale pid file", async () => { await expectSingleWinner({ preseedStalePidFile: true }) - }) + }, PROCESS_TEST_TIMEOUT_MS) }) describe("ralph-watchdog signal trap integration", () => { @@ -535,11 +546,11 @@ describe("ralph-watchdog signal trap integration", () => { it("exits cleanly on SIGTERM after releasing the watchdog lock", async () => { await expectSignalStopsWatchdog("SIGTERM", 143) - }) + }, PROCESS_TEST_TIMEOUT_MS) it("exits cleanly on SIGINT after releasing the watchdog lock", async () => { await expectSignalStopsWatchdog("SIGINT", 130) - }) + }, PROCESS_TEST_TIMEOUT_MS) }) describeIfSqlite3("ralph-watchdog reconcile integration", () => { @@ -591,7 +602,7 @@ describeIfSqlite3("ralph-watchdog reconcile integration", () => { const watchdogLog = readFileSync(join(harness.tmpDir, ".tx", "ralph-watchdog.log"), "utf-8") expect(watchdogLog).toContain(`Reconciled run=${runId} (missing pid)`) expect(existsSync(join(harness.tmpDir, ".tx", "ralph-watchdog.pid"))).toBe(false) - }) + }, PROCESS_TEST_TIMEOUT_MS) it("cancels running rows with dead pid, resets task, and expires active claims", () => { const harness = createHarness() @@ -637,7 +648,7 @@ describeIfSqlite3("ralph-watchdog reconcile integration", () => { const resetsLogPath = join(harness.stateDir, "resets.log") expect(existsSync(resetsLogPath)).toBe(true) expect(readFileSync(resetsLogPath, "utf-8")).toContain(taskId) - }) + }, PROCESS_TEST_TIMEOUT_MS) it("does not cancel non-worker running rows that do not report a pid", () => { const harness = createHarness() @@ -671,7 +682,7 @@ describeIfSqlite3("ralph-watchdog reconcile integration", () => { const watchdogLog = readFileSync(join(harness.tmpDir, ".tx", "ralph-watchdog.log"), "utf-8") expect(watchdogLog).toContain(`Skipping run=${runId} pid reconciliation`) - }) + }, PROCESS_TEST_TIMEOUT_MS) it("cancels stale running rows, resets task, and expires active claims", () => { const harness = createHarness() @@ -729,7 +740,7 @@ describeIfSqlite3("ralph-watchdog reconcile integration", () => { } finally { terminatePid(stalePid) } - }) + }, PROCESS_TEST_TIMEOUT_MS) it("cancels stale runs without killing unrelated live PIDs when ownership cannot be confirmed", () => { const harness = createHarness() @@ -788,7 +799,7 @@ describeIfSqlite3("ralph-watchdog reconcile integration", () => { } finally { terminatePid(unrelatedPid) } - }) + }, PROCESS_TEST_TIMEOUT_MS) it("resets orphaned active tasks and expires active claims", () => { const harness = createHarness() @@ -822,5 +833,5 @@ describeIfSqlite3("ralph-watchdog reconcile integration", () => { const watchdogLog = readFileSync(join(harness.tmpDir, ".tx", "ralph-watchdog.log"), "utf-8") expect(watchdogLog).toContain("Reset 1 orphaned active task(s)") - }) + }, PROCESS_TEST_TIMEOUT_MS) })