import { c as createSseStream, S as SSE_HEADERS } from './http-CoxxIFTY.js';
import { s as summarizeTokenUsage } from './dist4-CiQ5cizO.js';
import { l as listSessions } from './sessions-j73dkbCI.js';
import './paths-2M_UxD_H.js';
import 'node:fs';
import 'node:path';
import 'node:os';
import 'node:events';
import 'node:diagnostics_channel';
import 'fs';
import 'events';
import 'util';
import 'path';
import 'assert';
import 'worker_threads';
import 'module';
import 'node:url';
import 'url';
import 'buffer';
import 'node:module';
import 'node:child_process';
import 'node:crypto';
import 'node:process';
import 'node:async_hooks';
import 'crypto';
import './dual-scope-db-ATrwq0LH.js';
import './indexes-aYlULWG3.js';
import './utils-BvHPJOVk.js';
import './adapters-D2gEs_5L.js';
import './registry2-BSyCTA3q.js';
import './data-accessor-CVbz8X_7.js';
import './tasks-CnwUAUXf.js';
import './conduit-Ca_OFWR_.js';
import './unique-constraint-BM-Apx1H.js';
import './chunk-DDP5xfzh.js';
import './sqlite-Dsbe0wec.js';
import './memory-schema-Bi7cChwo.js';
import './agent-registry-BtE5uhMO.js';
import './nexus-sqlite2-DgTuv9BQ.js';
import './nexus-schema2-BEd-ol6e.js';
import './logger-ChCwlV5k.js';
import 'node:sqlite';
import './lock-BoHF25mx.js';
import './index-IVoIz4D5.js';
import 'constants';
import 'stream';
import 'node:fs/promises';
import 'jsonc-parser';
import '@cleocode/cant';
import 'node:util';
import 'node:buffer';
import 'child_process';
import './branch-lock-qP1EkZ7p.js';
import './src2-DK8DKufK.js';
import 'llmtxt/identity';
import './storage-B9UA3BHR.js';
import './mvi-helpers-BNsJ8ZpQ.js';
import './session-store-OwQWMSf_.js';
import './config-B0nEjgSh.js';
import './json-DXl7iDYg.js';
import './index-Ca4C2M45.js';
import './data-safety-central-vmfu_Y4J.js';
import './sqlite-data-accessor-C59wZ0zp.js';
import './cross-db-cleanup-C_FLyd-6.js';
import './query-ops-BDMaTdYw.js';
import 'node:net';
import './src3-CMSGYxDI.js';
import './local-model-fit2-J1xCIhC_.js';
import './credential-pool-B04qO8at.js';
import './catalog-model-resolver2-Cexk2TN0.js';
import './role-resolver-DF9BQ_U6.js';
import './identity2-DeAB5RXE.js';
import './role-executor-C4-3bmgC.js';
import 'node:stream';
import 'os';
import 'node:http2';
import 'fs/promises';
import './models-catalog-DG3aPok8.js';
import './catalog-resolver2-c0qfF34B.js';
import './providers-CmIcBfg-.js';
import './brain-maintenance-bSR6GwAG.js';
import './graph-auto-populate2-DYsUNGSL.js';
import './temporal-supersession-BZ46j30w.js';
import './typed-query-l1D_QElt.js';
import './llm-backend-resolver-BPbvttS4.js';
import '@ai-sdk/provider-utils';
import './observer-reflector2-D8nxuglX.js';
import './learnings2-2m2p7lzT.js';
import './memory-accessor2-BzlgmY-Z.js';
import './quality-scoring-CCPuRQmJ.js';
import './patterns2-DYKfsbwN.js';
import './graph-memory-bridge2-C7Y32Mk4.js';
import './sigil2-DftKm7Um.js';
import './services-Dlf3Gefq.js';
import './audit4-S87oN-BC.js';
import 'process';
import './session-manifest-ZHrj54LR.js';

//#region src/routes/api/tasks/[id]/stream/+server.ts
/**
* GET /api/tasks/[id]/stream — per-task LIVE WORKER stream for a Running-lane
* card (T11929 · M5).
*
* A Running card on `/tasks/kanban` subscribes here to render the worker's
* live output tail + a usage / cost meter + proof checkpoints. The wire mirrors
* the existing `/api/tasks/events` SSE pattern (the shared `createSseStream`
* primitive), so the board reuses ONE EventSource-per-card with the same
* connected → frames → heartbeat cadence — no per-card polling.
*
* ## Source (gateway-ready, Studio-local today)
*
* The ratified realtime transport is the `/v1` gateway SSE
* (`GET /v1/orchestrate/events`, T11921). That stream currently carries a
* generic tick source until the daemon injects the real agent/worker/board
* origin-tailing source. Until then — and so the board is useful in Studio dev
* without a running daemon — this route derives the worker view from the
* EXISTING Studio data layer the read-only board already reads: the active
* session claiming this task (`listSessions`) plus its token usage
* (`metrics.summarizeTokenUsage` scoped by `taskId`).
*
* TODO: subscribe to the gateway `orchestrate.events` SSE filtered to this task
* once the daemon injects its real worker-output/usage source (T11559 / M5).
*
* Frame kinds match the pure
* {@link import('$lib/components/tasks/worker-stream.js').WorkerStreamFrame}
* fold: `connected` · `output` · `usage` · `checkpoint` · `heartbeat` · `done`.
*
* @task T11929
* @epic T11559
*/
/** Poll cadence (ms) for the per-task worker change detector. */
var POLL_INTERVAL_MS = 2e3;
/** Resolve the active session (if any) currently claiming this task. */
async function activeSessionForTask(projectPath, taskId) {
	try {
		const owner = (await listSessions(projectPath, { status: "active" })).find((s) => s.taskWork?.taskId === taskId);
		return owner ? {
			id: owner.id,
			startedAt: owner.startedAt
		} : null;
	} catch {
		return null;
	}
}
/** Resolve the cumulative usage snapshot for this task. */
async function usageForTask(projectPath, taskId) {
	try {
		const summary = await summarizeTokenUsage(projectPath, { taskId });
		return {
			inputTokens: summary.inputTokens,
			outputTokens: summary.outputTokens,
			totalTokens: summary.totalTokens,
			records: summary.totalRecords
		};
	} catch {
		return {
			inputTokens: 0,
			outputTokens: 0,
			totalTokens: 0,
			records: 0
		};
	}
}
var GET = ({ locals, params, request }) => {
	const ctx = locals.projectCtx;
	const taskId = params.id;
	const stream = createSseStream((emitter) => {
		/** Emit one named SSE event (dropped after close, never throws). */
		function send(event, data) {
			emitter.send({
				event,
				data
			});
		}
		let started = false;
		/** Last usage total emitted — only re-emit on change to keep the wire quiet. */
		let lastTotalTokens = -1;
		/** Whether we have announced the worker as gone (terminal `done`). */
		let endedAnnounced = false;
		send("connected", {
			ts: (/* @__PURE__ */ new Date()).toISOString(),
			taskId
		});
		/** One poll tick: detect worker presence + usage delta and emit frames. */
		async function tick() {
			if (emitter.closed) return;
			const ts = (/* @__PURE__ */ new Date()).toISOString();
			const session = await activeSessionForTask(ctx.projectPath, taskId);
			const usage = await usageForTask(ctx.projectPath, taskId);
			if (session && !started) {
				started = true;
				send("output", {
					ts,
					line: `▶ worker ${session.id} active on ${taskId} (since ${session.startedAt})`
				});
			}
			if (usage.totalTokens !== lastTotalTokens) {
				lastTotalTokens = usage.totalTokens;
				send("usage", {
					ts,
					usage
				});
			}
			if (!session && started && !endedAnnounced) {
				endedAnnounced = true;
				send("output", {
					ts,
					line: `■ worker on ${taskId} ended`
				});
				send("done", {
					ts,
					reason: "worker-ended"
				});
				return;
			}
			send("heartbeat", { ts });
		}
		tick();
		const interval = setInterval(() => {
			if (emitter.closed) {
				clearInterval(interval);
				return;
			}
			tick();
		}, POLL_INTERVAL_MS);
		return () => clearInterval(interval);
	}, request.signal);
	return new Response(stream, { headers: { ...SSE_HEADERS } });
};

export { GET };
//# sourceMappingURL=_server.ts-BD2Cbpqt.js.map
