pi-lens
Version:
Real-time code feedback for pi — LSP, linters, formatters, type-checking, structural analysis & booboo
147 lines (143 loc) • 5 kB
JavaScript
import { createRequire as __pilensCreateRequire } from "node:module"; const require = __pilensCreateRequire(import.meta.url);
import {
recordDegradationOnce
} from "./chunk-N3YQJI6O.js";
// dist/clients/deadline-utils.js
function combineAbortSignals(...signals) {
const live = signals.filter((s) => s !== void 0);
if (live.length <= 1)
return live[0];
if (typeof AbortSignal.any === "function")
return AbortSignal.any(live);
const controller = new AbortController();
for (const s of live) {
if (s.aborted) {
controller.abort(s.reason);
break;
}
s.addEventListener("abort", () => controller.abort(s.reason), {
once: true
});
}
return controller.signal;
}
function withDeadline(promise, options) {
const onTimeout = options.onTimeout ?? "reject";
const onReject = options.onReject ?? "propagate";
const ms = options.ms ?? (options.deadlineAt !== void 0 ? options.deadlineAt - Date.now() : 0);
if (ms <= 0) {
promise.catch(() => {
});
return onTimeout === "undefined" ? Promise.resolve(void 0) : Promise.reject(new Error(`Timeout after ${Math.max(0, ms)}ms`));
}
const base = onReject === "undefined" ? promise.catch(() => void 0) : promise;
if (onReject === "propagate")
promise.catch(() => {
});
let timer;
const timeoutPromise = new Promise((resolve, reject) => {
timer = setTimeout(() => {
if (onTimeout === "undefined")
resolve(void 0);
else
reject(new Error(`Timeout after ${ms}ms`));
}, ms);
});
return Promise.race([base, timeoutPromise]).finally(() => {
if (timer)
clearTimeout(timer);
});
}
function withTimeout(promise, timeoutMs) {
return withDeadline(promise, { ms: timeoutMs });
}
var BOUND_ABORTED = /* @__PURE__ */ Symbol("pi-lens/bounded/aborted");
async function bounded(promise, options) {
const { signal, shutdownSignal, hook, label } = options;
const ms = Number.isFinite(options.ms) ? Math.max(0, options.ms) : 0;
const startedAt = Date.now();
const boxed = promise.then((value) => ({ value }));
void boxed.catch(() => {
});
let cause;
let timer;
let onCallerAbort;
let onShutdownAbort;
const abandoned = new Promise((resolve) => {
const fire = (reason) => {
cause ??= reason;
resolve(BOUND_ABORTED);
};
if (signal?.aborted)
return fire("caller-abort");
if (shutdownSignal?.aborted)
return fire("shutdown");
if (ms <= 0)
return fire("deadline");
timer = setTimeout(() => fire("deadline"), ms);
timer.unref?.();
onCallerAbort = () => fire("caller-abort");
signal?.addEventListener("abort", onCallerAbort, { once: true });
if (shutdownSignal) {
onShutdownAbort = () => fire("shutdown");
shutdownSignal.addEventListener("abort", onShutdownAbort, {
once: true
});
}
});
try {
const settled = await Promise.race([boxed, abandoned]);
if (settled !== BOUND_ABORTED)
return settled.value;
const elapsedMs = Date.now() - startedAt;
const fired = cause ?? "deadline";
if (fired === "deadline" || fired === "shutdown") {
recordDegradationOnce({
kind: fired === "deadline" ? "hook-await-exceeded" : "hook-await-abandoned",
subject: `${hook}:${label}`,
reason: fired === "deadline" ? `exceeded ${ms}ms budget after ${elapsedMs}ms` : `abandoned after ${elapsedMs}ms: session is shutting down (budget ${ms}ms)`,
metadata: { hook, label, budgetMs: ms, elapsedMs, cause: fired }
});
}
return void 0;
} finally {
if (timer !== void 0)
clearTimeout(timer);
if (onCallerAbort)
signal?.removeEventListener("abort", onCallerAbort);
if (onShutdownAbort) {
shutdownSignal?.removeEventListener("abort", onShutdownAbort);
}
}
}
// dist/clients/hook-budgets.js
var HOOK_WALL_BUDGET_MS = Object.freeze({
/** Visible startup work; the user is watching a progress line. */
session_start: 5e3,
/** Pure bookkeeping — nothing here may await (#2523 contract). */
turn_start: 0,
/** Measured p50 3687 ms / p90 14246 ms today. The gap IS the issue. */
turn_end: 3e3,
/** Measured p90 10043 ms today, from one unbounded pipeline re-entry. */
agent_end: 1e3,
/** The designated place for settled-time sweeps; the widest non-edit budget. */
agent_settled: 1e4,
/** Read/Grep/Glob/Bash: must never await analyzer bootstrap (AC5). */
tool_result_read_only: 500,
/** The ONLY path the contract lets block the host, and only this long. */
tool_result_edit: 1e4,
/** Teardown: spawning or awaiting here aborts libuv (#234). */
session_shutdown: 0,
/** Synchronous message contribution; the host is blocked on the answer. */
context: 0,
/** Fork bookkeeping; the session is being replaced under it. */
session_before_fork: 0
});
var HOOK_BUDGET_KEYS = Object.keys(HOOK_WALL_BUDGET_MS);
export {
combineAbortSignals,
withDeadline,
withTimeout,
bounded,
HOOK_WALL_BUDGET_MS
};