Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
One-time setup that gathers your project's design context and saves it to CLAUDE.md for future sessions.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
scripts/live-complete.mjs
1#!/usr/bin/env node2/**3* Canonical durable completion acknowledgement for Impeccable live sessions.4*/56import { createLiveSessionStore } from './live-session-store.mjs';7import { readLiveServerInfo } from './impeccable-paths.mjs';89function parseArgs(argv) {10const out = { status: 'complete' };11for (let i = 0; i < argv.length; i++) {12const arg = argv[i];13if (arg === '--id') out.id = argv[++i];14else if (arg.startsWith('--id=')) out.id = arg.slice('--id='.length);15else if (arg === '--discarded' || arg === '--discard') out.status = 'discarded';16else if (arg === '--error') { out.status = 'agent_error'; out.message = argv[++i] || 'unknown error'; }17else if (arg.startsWith('--error=')) { out.status = 'agent_error'; out.message = arg.slice('--error='.length); }18else if (arg === '--help' || arg === '-h') out.help = true;19}20return out;21}2223export async function completeCli() {24const args = parseArgs(process.argv.slice(2));25if (args.help || !args.id) {26console.log(`Usage: node live-complete.mjs --id SESSION_ID [--discarded|--error MESSAGE]\n\nAppend the final durable session acknowledgement. Use after accept/discard cleanup is verified.`);27process.exit(args.help ? 0 : 1);28}2930const serverInfo = readServerInfo();31const serverResult = serverInfo ? await completeThroughServer(serverInfo, args) : null;32if (serverResult?.ok) {33const store = createLiveSessionStore({ cwd: process.cwd(), sessionId: args.id });34const snapshot = store.getSnapshot(args.id, { includeCompleted: true });35console.log(JSON.stringify({ ok: true, id: args.id, phase: snapshot?.phase || args.status, snapshot }, null, 2));36return;37}3839const store = createLiveSessionStore({ cwd: process.cwd(), sessionId: args.id });40const event = args.status === 'discarded'41? { type: 'discarded', id: args.id }42: args.status === 'agent_error'43? { type: 'agent_error', id: args.id, message: args.message || 'unknown error' }44: { type: 'complete', id: args.id };45const snapshot = store.appendEvent(event);46console.log(JSON.stringify({ ok: true, id: args.id, phase: snapshot.phase, snapshot }, null, 2));47}4849function readServerInfo() {50return readLiveServerInfo(process.cwd())?.info || null;51}5253async function completeThroughServer(info, args) {54const type = args.status === 'discarded'55? 'discarded'56: args.status === 'agent_error'57? 'error'58: 'complete';59try {60const res = await fetch(`http://localhost:${info.port}/poll`, {61method: 'POST',62headers: { 'Content-Type': 'application/json' },63body: JSON.stringify({ token: info.token, id: args.id, type, message: args.message }),64});65if (!res.ok) return null;66return await res.json();67} catch {68return null;69}70}7172const _running = process.argv[1];73if (_running?.endsWith('live-complete.mjs') || _running?.endsWith('live-complete.mjs/')) {74completeCli();75}76