Lines 1-29javascript
1// Liveness watchdog proxy (RTSC-44). A stdio MCP server the harness (Claude Code,
2// Codex, OpenCode, …) spawns. It transparently forwards every JSON-RPC message to
3// the remote Retasc MCP over HTTP and — by watching claim tokens in the responses —
4// keeps claimed issues' leases alive with out-of-band `heartbeat` calls. The LLM
5// never heartbeats. Fail-safe: if this process dies, heartbeats stop and the server
6// reclaims the lease (the correct default) — a broken watchdog is never worse than
7// no watchdog. Self-enforcing: no proxy → no Retasc tools → can't orphan a lease.
8import { createInterface } from "node:readline";
9import { hostname } from "node:os";
10import { spawn, spawnSync } from "node:child_process";
11import { dirname, resolve } from "node:path";
HighChild Process
Package source references child process execution.
dist/proxy.jsView on unpkg · L9 12import { fileURLToPath } from "node:url";
13import { applyObservation, heartbeatRequest, isClaimLost, shouldReapOnClose, } from "./lib/watchdog.js";
14import { resolveConn } from "./lib/keystore.js";
15import { toolResult as parseTool } from "./lib/toolresult.js";
16import { mintSessionKey, appendFallbackNotice } from "./lib/session.js";
17// RTSC-92/98: resolve the workspace key via the SHARED resolver, so the proxy and
18// the direct commands (claim/tidy/done) can never diverge. The proxy carries its
19// binding in its own env (RETASC_MCP_KEY legacy, or RETASC_WORKSPACE → keystore).
20const resolved = resolveConn({ env: process.env, defaultUrl: "https://mcp.retasc.com/mcp" });
21let MCP_URL = resolved.url;
HighSame File Env Network Execution
A single source file combines environment access, network access, and code or shell execution; review context before blocking.
dist/proxy.jsView on unpkg · L9 22const KEY = resolved.key;
23const HEARTBEAT_MS = Number(process.env.RETASC_HEARTBEAT_MS) || 10 * 60 * 1000;
24const leases = new Map();
25let hbSeq = -1; // out-of-band heartbeat ids are negative — never collide with the harness's
26// Per-session key (RTSC-50): starts as the workspace key; on startup we mint a
27// session key and switch to it so this session is distinguishable from others.
29// Set when session-key minting failed and we fell back to the workspace key —