From c39b6425fa54a093749b9a236adcd003818167c1 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Sun, 23 Aug 2026 23:33:14 +0000
Subject: [PATCH] Sync generated provider output
---
.../skills/impeccable/scripts/live-poll.mjs | 9 ++--
.../skills/impeccable/scripts/live-server.mjs | 9 ++++
.../scripts/live/sveltekit-adapter.mjs | 42 +++++++------------
.../scripts/live/tanstack-adapter.mjs | 29 ++-----------
.../skills/impeccable/scripts/live-poll.mjs | 9 ++--
.../skills/impeccable/scripts/live-server.mjs | 9 ++++
.../scripts/live/sveltekit-adapter.mjs | 42 +++++++------------
.../scripts/live/tanstack-adapter.mjs | 29 ++-----------
.../skills/impeccable/scripts/live-poll.mjs | 9 ++--
.../skills/impeccable/scripts/live-server.mjs | 9 ++++
.../scripts/live/sveltekit-adapter.mjs | 42 +++++++------------
.../scripts/live/tanstack-adapter.mjs | 29 ++-----------
.../skills/impeccable/scripts/live-poll.mjs | 9 ++--
.../skills/impeccable/scripts/live-server.mjs | 9 ++++
.../scripts/live/sveltekit-adapter.mjs | 42 +++++++------------
.../scripts/live/tanstack-adapter.mjs | 29 ++-----------
.../skills/impeccable/scripts/live-poll.mjs | 9 ++--
.../skills/impeccable/scripts/live-server.mjs | 9 ++++
.../scripts/live/sveltekit-adapter.mjs | 42 +++++++------------
.../scripts/live/tanstack-adapter.mjs | 29 ++-----------
.grok/skills/impeccable/scripts/live-poll.mjs | 9 ++--
.../skills/impeccable/scripts/live-server.mjs | 9 ++++
.../scripts/live/sveltekit-adapter.mjs | 42 +++++++------------
.../scripts/live/tanstack-adapter.mjs | 29 ++-----------
.../skills/impeccable/scripts/live-poll.mjs | 9 ++--
.../skills/impeccable/scripts/live-server.mjs | 9 ++++
.../scripts/live/sveltekit-adapter.mjs | 42 +++++++------------
.../scripts/live/tanstack-adapter.mjs | 29 ++-----------
.kiro/skills/impeccable/scripts/live-poll.mjs | 9 ++--
.../skills/impeccable/scripts/live-server.mjs | 9 ++++
.../scripts/live/sveltekit-adapter.mjs | 42 +++++++------------
.../scripts/live/tanstack-adapter.mjs | 29 ++-----------
.../skills/impeccable/scripts/live-poll.mjs | 9 ++--
.../skills/impeccable/scripts/live-server.mjs | 9 ++++
.../scripts/live/sveltekit-adapter.mjs | 42 +++++++------------
.../scripts/live/tanstack-adapter.mjs | 29 ++-----------
.pi/skills/impeccable/scripts/live-poll.mjs | 9 ++--
.pi/skills/impeccable/scripts/live-server.mjs | 9 ++++
.../scripts/live/sveltekit-adapter.mjs | 42 +++++++------------
.../scripts/live/tanstack-adapter.mjs | 29 ++-----------
.../skills/impeccable/scripts/live-poll.mjs | 9 ++--
.../skills/impeccable/scripts/live-server.mjs | 9 ++++
.../scripts/live/sveltekit-adapter.mjs | 42 +++++++------------
.../scripts/live/tanstack-adapter.mjs | 29 ++-----------
.../skills/impeccable/scripts/live-poll.mjs | 9 ++--
.../skills/impeccable/scripts/live-server.mjs | 9 ++++
.../scripts/live/sveltekit-adapter.mjs | 42 +++++++------------
.../scripts/live/tanstack-adapter.mjs | 29 ++-----------
.../skills/impeccable/scripts/live-poll.mjs | 9 ++--
.../skills/impeccable/scripts/live-server.mjs | 9 ++++
.../scripts/live/sveltekit-adapter.mjs | 42 +++++++------------
.../scripts/live/tanstack-adapter.mjs | 29 ++-----------
.trae/skills/impeccable/scripts/live-poll.mjs | 9 ++--
.../skills/impeccable/scripts/live-server.mjs | 9 ++++
.../scripts/live/sveltekit-adapter.mjs | 42 +++++++------------
.../scripts/live/tanstack-adapter.mjs | 29 ++-----------
.vibe/skills/impeccable/scripts/live-poll.mjs | 9 ++--
.../skills/impeccable/scripts/live-server.mjs | 9 ++++
.../scripts/live/sveltekit-adapter.mjs | 42 +++++++------------
.../scripts/live/tanstack-adapter.mjs | 29 ++-----------
.../skills/impeccable/scripts/live-poll.mjs | 9 ++--
.../skills/impeccable/scripts/live-server.mjs | 9 ++++
.../scripts/live/sveltekit-adapter.mjs | 42 +++++++------------
.../scripts/live/tanstack-adapter.mjs | 29 ++-----------
64 files changed, 528 insertions(+), 896 deletions(-)
diff --git a/.agents/skills/impeccable/scripts/live-poll.mjs b/.agents/skills/impeccable/scripts/live-poll.mjs
index 3b2f08c9f..59e21b9d3 100644
--- a/.agents/skills/impeccable/scripts/live-poll.mjs
+++ b/.agents/skills/impeccable/scripts/live-poll.mjs
@@ -238,10 +238,9 @@ export async function completeAcceptHandling(event, base, token) {
});
} catch (err) {
event._completionAck = { ok: false, error: err.message };
+ return event;
}
- if (!event._completionAck) {
- event._completionAck = completionAckForAcceptResult(event.id, completionType, event._acceptResult);
- }
+ event._completionAck = completionAckForAcceptResult(event.id, completionType, event._acceptResult);
return event;
}
@@ -269,9 +268,11 @@ export function printPollEvent(event) {
// Situational plumbing rides with the event itself: `_instructions` is the
// authoritative next step, with real ids and paths substituted, so the
// reference doc can stay lean and can never drift from script behavior.
- if (event && typeof event === 'object' && !event._instructions) {
+ // A wire-supplied value must never win over the locally generated one.
+ if (event && typeof event === 'object') {
const instructions = instructionsForEvent(event, { scriptsPath: SELF_DIR });
if (instructions) event._instructions = instructions;
+ else delete event._instructions;
}
console.log(JSON.stringify(event));
}
diff --git a/.agents/skills/impeccable/scripts/live-server.mjs b/.agents/skills/impeccable/scripts/live-server.mjs
index cba3a222e..dafa8bd0c 100644
--- a/.agents/skills/impeccable/scripts/live-server.mjs
+++ b/.agents/skills/impeccable/scripts/live-server.mjs
@@ -181,8 +181,16 @@ function chatAgentLikelyActive() {
// cap at 10 MB to guard against runaway writes from a misbehaving client.
const MAX_ANNOTATION_BYTES = 10 * 1024 * 1024;
+const POLLER_OWNED_EVENT_FIELDS = ['_instructions', '_completionAck', '_acceptResult'];
+
+function stripPollerOwnedEventFields(event) {
+ if (!event || typeof event !== 'object') return;
+ for (const key of POLLER_OWNED_EVENT_FIELDS) delete event[key];
+}
+
function enqueueEvent(event) {
if (!event) return;
+ stripPollerOwnedEventFields(event);
// Dedupe by (session, type), except mount failures, which are per-variant:
// variant 2 failing must not be swallowed because variant 1's failure is
// still queued.
@@ -1034,6 +1042,7 @@ function createRequestHandler({ detectScript, liveScriptParts }) {
res.end(JSON.stringify({ error }));
return;
}
+ stripPollerOwnedEventFields(msg);
if (msg.type === 'agent_phase') {
recordAgentPhase(msg.id, msg.phase, {
...(Number.isFinite(msg.durationMs) ? { durationMs: msg.durationMs } : {}),
diff --git a/.agents/skills/impeccable/scripts/live/sveltekit-adapter.mjs b/.agents/skills/impeccable/scripts/live/sveltekit-adapter.mjs
index e94c54f1e..b96e955a6 100644
--- a/.agents/skills/impeccable/scripts/live/sveltekit-adapter.mjs
+++ b/.agents/skills/impeccable/scripts/live/sveltekit-adapter.mjs
@@ -11,6 +11,8 @@ import crypto from 'node:crypto';
import fs from 'node:fs';
import path from 'node:path';
+import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs';
+
export const SVELTE_LIVE_ROOT_COMPONENT = 'src/lib/impeccable/ImpeccableLiveRoot.svelte';
export const SVELTE_LAYOUT_MARKER_OPEN = '';
export const SVELTE_LAYOUT_MARKER_CLOSE = '';
@@ -45,11 +47,17 @@ export function detectSvelteKitProject(cwd = process.cwd(), config = null) {
&& fileIncludes(path.join(cwd, appHtml), '%sveltekit.head%');
if (!hasTemplateMarkers) return null;
- const hasSvelteConfig = fs.existsSync(path.join(cwd, 'svelte.config.js'))
- || fs.existsSync(path.join(cwd, 'svelte.config.mjs'))
- || fs.existsSync(path.join(cwd, 'svelte.config.cjs'))
- || fs.existsSync(path.join(cwd, 'svelte.config.ts'));
- const hasKitPackage = packageHasSvelteKit(cwd);
+ const hasSvelteConfig = Boolean(firstExistingFile(cwd, [
+ 'svelte.config.js',
+ 'svelte.config.mjs',
+ 'svelte.config.cjs',
+ 'svelte.config.ts',
+ ]));
+ const hasKitPackage = hasAnyDependency(cwd, [
+ '@sveltejs/kit',
+ '@sveltejs/vite-plugin-svelte',
+ 'svelte',
+ ]);
if (!hasSvelteConfig && !hasKitPackage) return null;
return {
@@ -260,36 +268,16 @@ function findSvelteKitAppHtml(cwd, config) {
}
function findSvelteKitLayout(cwd) {
- const candidates = [
+ return firstExistingFile(cwd, [
'src/routes/+layout.svelte',
'src/routes/(app)/+layout.svelte',
- ];
- for (const rel of candidates) {
- if (fs.existsSync(path.join(cwd, rel))) return rel;
- }
- return 'src/routes/+layout.svelte';
+ ]) || 'src/routes/+layout.svelte';
}
function defaultSvelteLayout() {
return `\n\n{@render children?.()}\n`;
}
-function packageHasSvelteKit(cwd) {
- const file = path.join(cwd, 'package.json');
- if (!fs.existsSync(file)) return false;
- try {
- const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
- const deps = {
- ...(pkg.dependencies || {}),
- ...(pkg.devDependencies || {}),
- ...(pkg.peerDependencies || {}),
- };
- return Boolean(deps['@sveltejs/kit'] || deps['@sveltejs/vite-plugin-svelte'] || deps.svelte);
- } catch {
- return false;
- }
-}
-
function fileIncludes(file, text) {
try {
return fs.readFileSync(file, 'utf-8').includes(text);
diff --git a/.agents/skills/impeccable/scripts/live/tanstack-adapter.mjs b/.agents/skills/impeccable/scripts/live/tanstack-adapter.mjs
index 4a1c81a97..b53978f4f 100644
--- a/.agents/skills/impeccable/scripts/live/tanstack-adapter.mjs
+++ b/.agents/skills/impeccable/scripts/live/tanstack-adapter.mjs
@@ -19,6 +19,8 @@
import fs from 'node:fs';
import path from 'node:path';
+
+import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs';
import { buildLiveScriptSrc } from './frameworks/script-src.mjs';
export const TANSTACK_MARKER_OPEN = '{/* impeccable-live-tanstack-start */}';
@@ -42,8 +44,8 @@ const START_PACKAGES = [
];
export function detectTanStackStartProject(cwd = process.cwd()) {
- if (!packageHasTanStackStart(cwd)) return null;
- const rootRoute = findRootRouteFile(cwd);
+ if (!hasAnyDependency(cwd, START_PACKAGES)) return null;
+ const rootRoute = firstExistingFile(cwd, ROOT_ROUTE_CANDIDATES);
if (!rootRoute) return null;
const ext = path.extname(rootRoute);
@@ -218,29 +220,6 @@ function isManagedComponent(content) {
return String(content || '').includes('impeccable-live-tanstack');
}
-function findRootRouteFile(cwd) {
- for (const rel of ROOT_ROUTE_CANDIDATES) {
- if (fs.existsSync(path.join(cwd, rel))) return rel;
- }
- return null;
-}
-
-function packageHasTanStackStart(cwd) {
- const file = path.join(cwd, 'package.json');
- if (!fs.existsSync(file)) return false;
- try {
- const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
- const deps = {
- ...(pkg.dependencies || {}),
- ...(pkg.devDependencies || {}),
- ...(pkg.peerDependencies || {}),
- };
- return START_PACKAGES.some((name) => Boolean(deps[name]));
- } catch {
- return false;
- }
-}
-
function relativeImportSpecifier(fromFile, toFile) {
const rel = path.posix.relative(
path.posix.dirname(fromFile.split(path.sep).join('/')),
diff --git a/.claude/skills/impeccable/scripts/live-poll.mjs b/.claude/skills/impeccable/scripts/live-poll.mjs
index 3b2f08c9f..59e21b9d3 100644
--- a/.claude/skills/impeccable/scripts/live-poll.mjs
+++ b/.claude/skills/impeccable/scripts/live-poll.mjs
@@ -238,10 +238,9 @@ export async function completeAcceptHandling(event, base, token) {
});
} catch (err) {
event._completionAck = { ok: false, error: err.message };
+ return event;
}
- if (!event._completionAck) {
- event._completionAck = completionAckForAcceptResult(event.id, completionType, event._acceptResult);
- }
+ event._completionAck = completionAckForAcceptResult(event.id, completionType, event._acceptResult);
return event;
}
@@ -269,9 +268,11 @@ export function printPollEvent(event) {
// Situational plumbing rides with the event itself: `_instructions` is the
// authoritative next step, with real ids and paths substituted, so the
// reference doc can stay lean and can never drift from script behavior.
- if (event && typeof event === 'object' && !event._instructions) {
+ // A wire-supplied value must never win over the locally generated one.
+ if (event && typeof event === 'object') {
const instructions = instructionsForEvent(event, { scriptsPath: SELF_DIR });
if (instructions) event._instructions = instructions;
+ else delete event._instructions;
}
console.log(JSON.stringify(event));
}
diff --git a/.claude/skills/impeccable/scripts/live-server.mjs b/.claude/skills/impeccable/scripts/live-server.mjs
index cba3a222e..dafa8bd0c 100644
--- a/.claude/skills/impeccable/scripts/live-server.mjs
+++ b/.claude/skills/impeccable/scripts/live-server.mjs
@@ -181,8 +181,16 @@ function chatAgentLikelyActive() {
// cap at 10 MB to guard against runaway writes from a misbehaving client.
const MAX_ANNOTATION_BYTES = 10 * 1024 * 1024;
+const POLLER_OWNED_EVENT_FIELDS = ['_instructions', '_completionAck', '_acceptResult'];
+
+function stripPollerOwnedEventFields(event) {
+ if (!event || typeof event !== 'object') return;
+ for (const key of POLLER_OWNED_EVENT_FIELDS) delete event[key];
+}
+
function enqueueEvent(event) {
if (!event) return;
+ stripPollerOwnedEventFields(event);
// Dedupe by (session, type), except mount failures, which are per-variant:
// variant 2 failing must not be swallowed because variant 1's failure is
// still queued.
@@ -1034,6 +1042,7 @@ function createRequestHandler({ detectScript, liveScriptParts }) {
res.end(JSON.stringify({ error }));
return;
}
+ stripPollerOwnedEventFields(msg);
if (msg.type === 'agent_phase') {
recordAgentPhase(msg.id, msg.phase, {
...(Number.isFinite(msg.durationMs) ? { durationMs: msg.durationMs } : {}),
diff --git a/.claude/skills/impeccable/scripts/live/sveltekit-adapter.mjs b/.claude/skills/impeccable/scripts/live/sveltekit-adapter.mjs
index e94c54f1e..b96e955a6 100644
--- a/.claude/skills/impeccable/scripts/live/sveltekit-adapter.mjs
+++ b/.claude/skills/impeccable/scripts/live/sveltekit-adapter.mjs
@@ -11,6 +11,8 @@ import crypto from 'node:crypto';
import fs from 'node:fs';
import path from 'node:path';
+import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs';
+
export const SVELTE_LIVE_ROOT_COMPONENT = 'src/lib/impeccable/ImpeccableLiveRoot.svelte';
export const SVELTE_LAYOUT_MARKER_OPEN = '';
export const SVELTE_LAYOUT_MARKER_CLOSE = '';
@@ -45,11 +47,17 @@ export function detectSvelteKitProject(cwd = process.cwd(), config = null) {
&& fileIncludes(path.join(cwd, appHtml), '%sveltekit.head%');
if (!hasTemplateMarkers) return null;
- const hasSvelteConfig = fs.existsSync(path.join(cwd, 'svelte.config.js'))
- || fs.existsSync(path.join(cwd, 'svelte.config.mjs'))
- || fs.existsSync(path.join(cwd, 'svelte.config.cjs'))
- || fs.existsSync(path.join(cwd, 'svelte.config.ts'));
- const hasKitPackage = packageHasSvelteKit(cwd);
+ const hasSvelteConfig = Boolean(firstExistingFile(cwd, [
+ 'svelte.config.js',
+ 'svelte.config.mjs',
+ 'svelte.config.cjs',
+ 'svelte.config.ts',
+ ]));
+ const hasKitPackage = hasAnyDependency(cwd, [
+ '@sveltejs/kit',
+ '@sveltejs/vite-plugin-svelte',
+ 'svelte',
+ ]);
if (!hasSvelteConfig && !hasKitPackage) return null;
return {
@@ -260,36 +268,16 @@ function findSvelteKitAppHtml(cwd, config) {
}
function findSvelteKitLayout(cwd) {
- const candidates = [
+ return firstExistingFile(cwd, [
'src/routes/+layout.svelte',
'src/routes/(app)/+layout.svelte',
- ];
- for (const rel of candidates) {
- if (fs.existsSync(path.join(cwd, rel))) return rel;
- }
- return 'src/routes/+layout.svelte';
+ ]) || 'src/routes/+layout.svelte';
}
function defaultSvelteLayout() {
return `\n\n{@render children?.()}\n`;
}
-function packageHasSvelteKit(cwd) {
- const file = path.join(cwd, 'package.json');
- if (!fs.existsSync(file)) return false;
- try {
- const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
- const deps = {
- ...(pkg.dependencies || {}),
- ...(pkg.devDependencies || {}),
- ...(pkg.peerDependencies || {}),
- };
- return Boolean(deps['@sveltejs/kit'] || deps['@sveltejs/vite-plugin-svelte'] || deps.svelte);
- } catch {
- return false;
- }
-}
-
function fileIncludes(file, text) {
try {
return fs.readFileSync(file, 'utf-8').includes(text);
diff --git a/.claude/skills/impeccable/scripts/live/tanstack-adapter.mjs b/.claude/skills/impeccable/scripts/live/tanstack-adapter.mjs
index 4a1c81a97..b53978f4f 100644
--- a/.claude/skills/impeccable/scripts/live/tanstack-adapter.mjs
+++ b/.claude/skills/impeccable/scripts/live/tanstack-adapter.mjs
@@ -19,6 +19,8 @@
import fs from 'node:fs';
import path from 'node:path';
+
+import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs';
import { buildLiveScriptSrc } from './frameworks/script-src.mjs';
export const TANSTACK_MARKER_OPEN = '{/* impeccable-live-tanstack-start */}';
@@ -42,8 +44,8 @@ const START_PACKAGES = [
];
export function detectTanStackStartProject(cwd = process.cwd()) {
- if (!packageHasTanStackStart(cwd)) return null;
- const rootRoute = findRootRouteFile(cwd);
+ if (!hasAnyDependency(cwd, START_PACKAGES)) return null;
+ const rootRoute = firstExistingFile(cwd, ROOT_ROUTE_CANDIDATES);
if (!rootRoute) return null;
const ext = path.extname(rootRoute);
@@ -218,29 +220,6 @@ function isManagedComponent(content) {
return String(content || '').includes('impeccable-live-tanstack');
}
-function findRootRouteFile(cwd) {
- for (const rel of ROOT_ROUTE_CANDIDATES) {
- if (fs.existsSync(path.join(cwd, rel))) return rel;
- }
- return null;
-}
-
-function packageHasTanStackStart(cwd) {
- const file = path.join(cwd, 'package.json');
- if (!fs.existsSync(file)) return false;
- try {
- const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
- const deps = {
- ...(pkg.dependencies || {}),
- ...(pkg.devDependencies || {}),
- ...(pkg.peerDependencies || {}),
- };
- return START_PACKAGES.some((name) => Boolean(deps[name]));
- } catch {
- return false;
- }
-}
-
function relativeImportSpecifier(fromFile, toFile) {
const rel = path.posix.relative(
path.posix.dirname(fromFile.split(path.sep).join('/')),
diff --git a/.cursor/skills/impeccable/scripts/live-poll.mjs b/.cursor/skills/impeccable/scripts/live-poll.mjs
index 3b2f08c9f..59e21b9d3 100644
--- a/.cursor/skills/impeccable/scripts/live-poll.mjs
+++ b/.cursor/skills/impeccable/scripts/live-poll.mjs
@@ -238,10 +238,9 @@ export async function completeAcceptHandling(event, base, token) {
});
} catch (err) {
event._completionAck = { ok: false, error: err.message };
+ return event;
}
- if (!event._completionAck) {
- event._completionAck = completionAckForAcceptResult(event.id, completionType, event._acceptResult);
- }
+ event._completionAck = completionAckForAcceptResult(event.id, completionType, event._acceptResult);
return event;
}
@@ -269,9 +268,11 @@ export function printPollEvent(event) {
// Situational plumbing rides with the event itself: `_instructions` is the
// authoritative next step, with real ids and paths substituted, so the
// reference doc can stay lean and can never drift from script behavior.
- if (event && typeof event === 'object' && !event._instructions) {
+ // A wire-supplied value must never win over the locally generated one.
+ if (event && typeof event === 'object') {
const instructions = instructionsForEvent(event, { scriptsPath: SELF_DIR });
if (instructions) event._instructions = instructions;
+ else delete event._instructions;
}
console.log(JSON.stringify(event));
}
diff --git a/.cursor/skills/impeccable/scripts/live-server.mjs b/.cursor/skills/impeccable/scripts/live-server.mjs
index cba3a222e..dafa8bd0c 100644
--- a/.cursor/skills/impeccable/scripts/live-server.mjs
+++ b/.cursor/skills/impeccable/scripts/live-server.mjs
@@ -181,8 +181,16 @@ function chatAgentLikelyActive() {
// cap at 10 MB to guard against runaway writes from a misbehaving client.
const MAX_ANNOTATION_BYTES = 10 * 1024 * 1024;
+const POLLER_OWNED_EVENT_FIELDS = ['_instructions', '_completionAck', '_acceptResult'];
+
+function stripPollerOwnedEventFields(event) {
+ if (!event || typeof event !== 'object') return;
+ for (const key of POLLER_OWNED_EVENT_FIELDS) delete event[key];
+}
+
function enqueueEvent(event) {
if (!event) return;
+ stripPollerOwnedEventFields(event);
// Dedupe by (session, type), except mount failures, which are per-variant:
// variant 2 failing must not be swallowed because variant 1's failure is
// still queued.
@@ -1034,6 +1042,7 @@ function createRequestHandler({ detectScript, liveScriptParts }) {
res.end(JSON.stringify({ error }));
return;
}
+ stripPollerOwnedEventFields(msg);
if (msg.type === 'agent_phase') {
recordAgentPhase(msg.id, msg.phase, {
...(Number.isFinite(msg.durationMs) ? { durationMs: msg.durationMs } : {}),
diff --git a/.cursor/skills/impeccable/scripts/live/sveltekit-adapter.mjs b/.cursor/skills/impeccable/scripts/live/sveltekit-adapter.mjs
index e94c54f1e..b96e955a6 100644
--- a/.cursor/skills/impeccable/scripts/live/sveltekit-adapter.mjs
+++ b/.cursor/skills/impeccable/scripts/live/sveltekit-adapter.mjs
@@ -11,6 +11,8 @@ import crypto from 'node:crypto';
import fs from 'node:fs';
import path from 'node:path';
+import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs';
+
export const SVELTE_LIVE_ROOT_COMPONENT = 'src/lib/impeccable/ImpeccableLiveRoot.svelte';
export const SVELTE_LAYOUT_MARKER_OPEN = '';
export const SVELTE_LAYOUT_MARKER_CLOSE = '';
@@ -45,11 +47,17 @@ export function detectSvelteKitProject(cwd = process.cwd(), config = null) {
&& fileIncludes(path.join(cwd, appHtml), '%sveltekit.head%');
if (!hasTemplateMarkers) return null;
- const hasSvelteConfig = fs.existsSync(path.join(cwd, 'svelte.config.js'))
- || fs.existsSync(path.join(cwd, 'svelte.config.mjs'))
- || fs.existsSync(path.join(cwd, 'svelte.config.cjs'))
- || fs.existsSync(path.join(cwd, 'svelte.config.ts'));
- const hasKitPackage = packageHasSvelteKit(cwd);
+ const hasSvelteConfig = Boolean(firstExistingFile(cwd, [
+ 'svelte.config.js',
+ 'svelte.config.mjs',
+ 'svelte.config.cjs',
+ 'svelte.config.ts',
+ ]));
+ const hasKitPackage = hasAnyDependency(cwd, [
+ '@sveltejs/kit',
+ '@sveltejs/vite-plugin-svelte',
+ 'svelte',
+ ]);
if (!hasSvelteConfig && !hasKitPackage) return null;
return {
@@ -260,36 +268,16 @@ function findSvelteKitAppHtml(cwd, config) {
}
function findSvelteKitLayout(cwd) {
- const candidates = [
+ return firstExistingFile(cwd, [
'src/routes/+layout.svelte',
'src/routes/(app)/+layout.svelte',
- ];
- for (const rel of candidates) {
- if (fs.existsSync(path.join(cwd, rel))) return rel;
- }
- return 'src/routes/+layout.svelte';
+ ]) || 'src/routes/+layout.svelte';
}
function defaultSvelteLayout() {
return `\n\n{@render children?.()}\n`;
}
-function packageHasSvelteKit(cwd) {
- const file = path.join(cwd, 'package.json');
- if (!fs.existsSync(file)) return false;
- try {
- const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
- const deps = {
- ...(pkg.dependencies || {}),
- ...(pkg.devDependencies || {}),
- ...(pkg.peerDependencies || {}),
- };
- return Boolean(deps['@sveltejs/kit'] || deps['@sveltejs/vite-plugin-svelte'] || deps.svelte);
- } catch {
- return false;
- }
-}
-
function fileIncludes(file, text) {
try {
return fs.readFileSync(file, 'utf-8').includes(text);
diff --git a/.cursor/skills/impeccable/scripts/live/tanstack-adapter.mjs b/.cursor/skills/impeccable/scripts/live/tanstack-adapter.mjs
index 4a1c81a97..b53978f4f 100644
--- a/.cursor/skills/impeccable/scripts/live/tanstack-adapter.mjs
+++ b/.cursor/skills/impeccable/scripts/live/tanstack-adapter.mjs
@@ -19,6 +19,8 @@
import fs from 'node:fs';
import path from 'node:path';
+
+import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs';
import { buildLiveScriptSrc } from './frameworks/script-src.mjs';
export const TANSTACK_MARKER_OPEN = '{/* impeccable-live-tanstack-start */}';
@@ -42,8 +44,8 @@ const START_PACKAGES = [
];
export function detectTanStackStartProject(cwd = process.cwd()) {
- if (!packageHasTanStackStart(cwd)) return null;
- const rootRoute = findRootRouteFile(cwd);
+ if (!hasAnyDependency(cwd, START_PACKAGES)) return null;
+ const rootRoute = firstExistingFile(cwd, ROOT_ROUTE_CANDIDATES);
if (!rootRoute) return null;
const ext = path.extname(rootRoute);
@@ -218,29 +220,6 @@ function isManagedComponent(content) {
return String(content || '').includes('impeccable-live-tanstack');
}
-function findRootRouteFile(cwd) {
- for (const rel of ROOT_ROUTE_CANDIDATES) {
- if (fs.existsSync(path.join(cwd, rel))) return rel;
- }
- return null;
-}
-
-function packageHasTanStackStart(cwd) {
- const file = path.join(cwd, 'package.json');
- if (!fs.existsSync(file)) return false;
- try {
- const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
- const deps = {
- ...(pkg.dependencies || {}),
- ...(pkg.devDependencies || {}),
- ...(pkg.peerDependencies || {}),
- };
- return START_PACKAGES.some((name) => Boolean(deps[name]));
- } catch {
- return false;
- }
-}
-
function relativeImportSpecifier(fromFile, toFile) {
const rel = path.posix.relative(
path.posix.dirname(fromFile.split(path.sep).join('/')),
diff --git a/.gemini/skills/impeccable/scripts/live-poll.mjs b/.gemini/skills/impeccable/scripts/live-poll.mjs
index 3b2f08c9f..59e21b9d3 100644
--- a/.gemini/skills/impeccable/scripts/live-poll.mjs
+++ b/.gemini/skills/impeccable/scripts/live-poll.mjs
@@ -238,10 +238,9 @@ export async function completeAcceptHandling(event, base, token) {
});
} catch (err) {
event._completionAck = { ok: false, error: err.message };
+ return event;
}
- if (!event._completionAck) {
- event._completionAck = completionAckForAcceptResult(event.id, completionType, event._acceptResult);
- }
+ event._completionAck = completionAckForAcceptResult(event.id, completionType, event._acceptResult);
return event;
}
@@ -269,9 +268,11 @@ export function printPollEvent(event) {
// Situational plumbing rides with the event itself: `_instructions` is the
// authoritative next step, with real ids and paths substituted, so the
// reference doc can stay lean and can never drift from script behavior.
- if (event && typeof event === 'object' && !event._instructions) {
+ // A wire-supplied value must never win over the locally generated one.
+ if (event && typeof event === 'object') {
const instructions = instructionsForEvent(event, { scriptsPath: SELF_DIR });
if (instructions) event._instructions = instructions;
+ else delete event._instructions;
}
console.log(JSON.stringify(event));
}
diff --git a/.gemini/skills/impeccable/scripts/live-server.mjs b/.gemini/skills/impeccable/scripts/live-server.mjs
index cba3a222e..dafa8bd0c 100644
--- a/.gemini/skills/impeccable/scripts/live-server.mjs
+++ b/.gemini/skills/impeccable/scripts/live-server.mjs
@@ -181,8 +181,16 @@ function chatAgentLikelyActive() {
// cap at 10 MB to guard against runaway writes from a misbehaving client.
const MAX_ANNOTATION_BYTES = 10 * 1024 * 1024;
+const POLLER_OWNED_EVENT_FIELDS = ['_instructions', '_completionAck', '_acceptResult'];
+
+function stripPollerOwnedEventFields(event) {
+ if (!event || typeof event !== 'object') return;
+ for (const key of POLLER_OWNED_EVENT_FIELDS) delete event[key];
+}
+
function enqueueEvent(event) {
if (!event) return;
+ stripPollerOwnedEventFields(event);
// Dedupe by (session, type), except mount failures, which are per-variant:
// variant 2 failing must not be swallowed because variant 1's failure is
// still queued.
@@ -1034,6 +1042,7 @@ function createRequestHandler({ detectScript, liveScriptParts }) {
res.end(JSON.stringify({ error }));
return;
}
+ stripPollerOwnedEventFields(msg);
if (msg.type === 'agent_phase') {
recordAgentPhase(msg.id, msg.phase, {
...(Number.isFinite(msg.durationMs) ? { durationMs: msg.durationMs } : {}),
diff --git a/.gemini/skills/impeccable/scripts/live/sveltekit-adapter.mjs b/.gemini/skills/impeccable/scripts/live/sveltekit-adapter.mjs
index e94c54f1e..b96e955a6 100644
--- a/.gemini/skills/impeccable/scripts/live/sveltekit-adapter.mjs
+++ b/.gemini/skills/impeccable/scripts/live/sveltekit-adapter.mjs
@@ -11,6 +11,8 @@ import crypto from 'node:crypto';
import fs from 'node:fs';
import path from 'node:path';
+import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs';
+
export const SVELTE_LIVE_ROOT_COMPONENT = 'src/lib/impeccable/ImpeccableLiveRoot.svelte';
export const SVELTE_LAYOUT_MARKER_OPEN = '';
export const SVELTE_LAYOUT_MARKER_CLOSE = '';
@@ -45,11 +47,17 @@ export function detectSvelteKitProject(cwd = process.cwd(), config = null) {
&& fileIncludes(path.join(cwd, appHtml), '%sveltekit.head%');
if (!hasTemplateMarkers) return null;
- const hasSvelteConfig = fs.existsSync(path.join(cwd, 'svelte.config.js'))
- || fs.existsSync(path.join(cwd, 'svelte.config.mjs'))
- || fs.existsSync(path.join(cwd, 'svelte.config.cjs'))
- || fs.existsSync(path.join(cwd, 'svelte.config.ts'));
- const hasKitPackage = packageHasSvelteKit(cwd);
+ const hasSvelteConfig = Boolean(firstExistingFile(cwd, [
+ 'svelte.config.js',
+ 'svelte.config.mjs',
+ 'svelte.config.cjs',
+ 'svelte.config.ts',
+ ]));
+ const hasKitPackage = hasAnyDependency(cwd, [
+ '@sveltejs/kit',
+ '@sveltejs/vite-plugin-svelte',
+ 'svelte',
+ ]);
if (!hasSvelteConfig && !hasKitPackage) return null;
return {
@@ -260,36 +268,16 @@ function findSvelteKitAppHtml(cwd, config) {
}
function findSvelteKitLayout(cwd) {
- const candidates = [
+ return firstExistingFile(cwd, [
'src/routes/+layout.svelte',
'src/routes/(app)/+layout.svelte',
- ];
- for (const rel of candidates) {
- if (fs.existsSync(path.join(cwd, rel))) return rel;
- }
- return 'src/routes/+layout.svelte';
+ ]) || 'src/routes/+layout.svelte';
}
function defaultSvelteLayout() {
return `\n\n{@render children?.()}\n`;
}
-function packageHasSvelteKit(cwd) {
- const file = path.join(cwd, 'package.json');
- if (!fs.existsSync(file)) return false;
- try {
- const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
- const deps = {
- ...(pkg.dependencies || {}),
- ...(pkg.devDependencies || {}),
- ...(pkg.peerDependencies || {}),
- };
- return Boolean(deps['@sveltejs/kit'] || deps['@sveltejs/vite-plugin-svelte'] || deps.svelte);
- } catch {
- return false;
- }
-}
-
function fileIncludes(file, text) {
try {
return fs.readFileSync(file, 'utf-8').includes(text);
diff --git a/.gemini/skills/impeccable/scripts/live/tanstack-adapter.mjs b/.gemini/skills/impeccable/scripts/live/tanstack-adapter.mjs
index 4a1c81a97..b53978f4f 100644
--- a/.gemini/skills/impeccable/scripts/live/tanstack-adapter.mjs
+++ b/.gemini/skills/impeccable/scripts/live/tanstack-adapter.mjs
@@ -19,6 +19,8 @@
import fs from 'node:fs';
import path from 'node:path';
+
+import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs';
import { buildLiveScriptSrc } from './frameworks/script-src.mjs';
export const TANSTACK_MARKER_OPEN = '{/* impeccable-live-tanstack-start */}';
@@ -42,8 +44,8 @@ const START_PACKAGES = [
];
export function detectTanStackStartProject(cwd = process.cwd()) {
- if (!packageHasTanStackStart(cwd)) return null;
- const rootRoute = findRootRouteFile(cwd);
+ if (!hasAnyDependency(cwd, START_PACKAGES)) return null;
+ const rootRoute = firstExistingFile(cwd, ROOT_ROUTE_CANDIDATES);
if (!rootRoute) return null;
const ext = path.extname(rootRoute);
@@ -218,29 +220,6 @@ function isManagedComponent(content) {
return String(content || '').includes('impeccable-live-tanstack');
}
-function findRootRouteFile(cwd) {
- for (const rel of ROOT_ROUTE_CANDIDATES) {
- if (fs.existsSync(path.join(cwd, rel))) return rel;
- }
- return null;
-}
-
-function packageHasTanStackStart(cwd) {
- const file = path.join(cwd, 'package.json');
- if (!fs.existsSync(file)) return false;
- try {
- const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
- const deps = {
- ...(pkg.dependencies || {}),
- ...(pkg.devDependencies || {}),
- ...(pkg.peerDependencies || {}),
- };
- return START_PACKAGES.some((name) => Boolean(deps[name]));
- } catch {
- return false;
- }
-}
-
function relativeImportSpecifier(fromFile, toFile) {
const rel = path.posix.relative(
path.posix.dirname(fromFile.split(path.sep).join('/')),
diff --git a/.github/skills/impeccable/scripts/live-poll.mjs b/.github/skills/impeccable/scripts/live-poll.mjs
index 3b2f08c9f..59e21b9d3 100644
--- a/.github/skills/impeccable/scripts/live-poll.mjs
+++ b/.github/skills/impeccable/scripts/live-poll.mjs
@@ -238,10 +238,9 @@ export async function completeAcceptHandling(event, base, token) {
});
} catch (err) {
event._completionAck = { ok: false, error: err.message };
+ return event;
}
- if (!event._completionAck) {
- event._completionAck = completionAckForAcceptResult(event.id, completionType, event._acceptResult);
- }
+ event._completionAck = completionAckForAcceptResult(event.id, completionType, event._acceptResult);
return event;
}
@@ -269,9 +268,11 @@ export function printPollEvent(event) {
// Situational plumbing rides with the event itself: `_instructions` is the
// authoritative next step, with real ids and paths substituted, so the
// reference doc can stay lean and can never drift from script behavior.
- if (event && typeof event === 'object' && !event._instructions) {
+ // A wire-supplied value must never win over the locally generated one.
+ if (event && typeof event === 'object') {
const instructions = instructionsForEvent(event, { scriptsPath: SELF_DIR });
if (instructions) event._instructions = instructions;
+ else delete event._instructions;
}
console.log(JSON.stringify(event));
}
diff --git a/.github/skills/impeccable/scripts/live-server.mjs b/.github/skills/impeccable/scripts/live-server.mjs
index cba3a222e..dafa8bd0c 100644
--- a/.github/skills/impeccable/scripts/live-server.mjs
+++ b/.github/skills/impeccable/scripts/live-server.mjs
@@ -181,8 +181,16 @@ function chatAgentLikelyActive() {
// cap at 10 MB to guard against runaway writes from a misbehaving client.
const MAX_ANNOTATION_BYTES = 10 * 1024 * 1024;
+const POLLER_OWNED_EVENT_FIELDS = ['_instructions', '_completionAck', '_acceptResult'];
+
+function stripPollerOwnedEventFields(event) {
+ if (!event || typeof event !== 'object') return;
+ for (const key of POLLER_OWNED_EVENT_FIELDS) delete event[key];
+}
+
function enqueueEvent(event) {
if (!event) return;
+ stripPollerOwnedEventFields(event);
// Dedupe by (session, type), except mount failures, which are per-variant:
// variant 2 failing must not be swallowed because variant 1's failure is
// still queued.
@@ -1034,6 +1042,7 @@ function createRequestHandler({ detectScript, liveScriptParts }) {
res.end(JSON.stringify({ error }));
return;
}
+ stripPollerOwnedEventFields(msg);
if (msg.type === 'agent_phase') {
recordAgentPhase(msg.id, msg.phase, {
...(Number.isFinite(msg.durationMs) ? { durationMs: msg.durationMs } : {}),
diff --git a/.github/skills/impeccable/scripts/live/sveltekit-adapter.mjs b/.github/skills/impeccable/scripts/live/sveltekit-adapter.mjs
index e94c54f1e..b96e955a6 100644
--- a/.github/skills/impeccable/scripts/live/sveltekit-adapter.mjs
+++ b/.github/skills/impeccable/scripts/live/sveltekit-adapter.mjs
@@ -11,6 +11,8 @@ import crypto from 'node:crypto';
import fs from 'node:fs';
import path from 'node:path';
+import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs';
+
export const SVELTE_LIVE_ROOT_COMPONENT = 'src/lib/impeccable/ImpeccableLiveRoot.svelte';
export const SVELTE_LAYOUT_MARKER_OPEN = '';
export const SVELTE_LAYOUT_MARKER_CLOSE = '';
@@ -45,11 +47,17 @@ export function detectSvelteKitProject(cwd = process.cwd(), config = null) {
&& fileIncludes(path.join(cwd, appHtml), '%sveltekit.head%');
if (!hasTemplateMarkers) return null;
- const hasSvelteConfig = fs.existsSync(path.join(cwd, 'svelte.config.js'))
- || fs.existsSync(path.join(cwd, 'svelte.config.mjs'))
- || fs.existsSync(path.join(cwd, 'svelte.config.cjs'))
- || fs.existsSync(path.join(cwd, 'svelte.config.ts'));
- const hasKitPackage = packageHasSvelteKit(cwd);
+ const hasSvelteConfig = Boolean(firstExistingFile(cwd, [
+ 'svelte.config.js',
+ 'svelte.config.mjs',
+ 'svelte.config.cjs',
+ 'svelte.config.ts',
+ ]));
+ const hasKitPackage = hasAnyDependency(cwd, [
+ '@sveltejs/kit',
+ '@sveltejs/vite-plugin-svelte',
+ 'svelte',
+ ]);
if (!hasSvelteConfig && !hasKitPackage) return null;
return {
@@ -260,36 +268,16 @@ function findSvelteKitAppHtml(cwd, config) {
}
function findSvelteKitLayout(cwd) {
- const candidates = [
+ return firstExistingFile(cwd, [
'src/routes/+layout.svelte',
'src/routes/(app)/+layout.svelte',
- ];
- for (const rel of candidates) {
- if (fs.existsSync(path.join(cwd, rel))) return rel;
- }
- return 'src/routes/+layout.svelte';
+ ]) || 'src/routes/+layout.svelte';
}
function defaultSvelteLayout() {
return `\n\n{@render children?.()}\n`;
}
-function packageHasSvelteKit(cwd) {
- const file = path.join(cwd, 'package.json');
- if (!fs.existsSync(file)) return false;
- try {
- const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
- const deps = {
- ...(pkg.dependencies || {}),
- ...(pkg.devDependencies || {}),
- ...(pkg.peerDependencies || {}),
- };
- return Boolean(deps['@sveltejs/kit'] || deps['@sveltejs/vite-plugin-svelte'] || deps.svelte);
- } catch {
- return false;
- }
-}
-
function fileIncludes(file, text) {
try {
return fs.readFileSync(file, 'utf-8').includes(text);
diff --git a/.github/skills/impeccable/scripts/live/tanstack-adapter.mjs b/.github/skills/impeccable/scripts/live/tanstack-adapter.mjs
index 4a1c81a97..b53978f4f 100644
--- a/.github/skills/impeccable/scripts/live/tanstack-adapter.mjs
+++ b/.github/skills/impeccable/scripts/live/tanstack-adapter.mjs
@@ -19,6 +19,8 @@
import fs from 'node:fs';
import path from 'node:path';
+
+import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs';
import { buildLiveScriptSrc } from './frameworks/script-src.mjs';
export const TANSTACK_MARKER_OPEN = '{/* impeccable-live-tanstack-start */}';
@@ -42,8 +44,8 @@ const START_PACKAGES = [
];
export function detectTanStackStartProject(cwd = process.cwd()) {
- if (!packageHasTanStackStart(cwd)) return null;
- const rootRoute = findRootRouteFile(cwd);
+ if (!hasAnyDependency(cwd, START_PACKAGES)) return null;
+ const rootRoute = firstExistingFile(cwd, ROOT_ROUTE_CANDIDATES);
if (!rootRoute) return null;
const ext = path.extname(rootRoute);
@@ -218,29 +220,6 @@ function isManagedComponent(content) {
return String(content || '').includes('impeccable-live-tanstack');
}
-function findRootRouteFile(cwd) {
- for (const rel of ROOT_ROUTE_CANDIDATES) {
- if (fs.existsSync(path.join(cwd, rel))) return rel;
- }
- return null;
-}
-
-function packageHasTanStackStart(cwd) {
- const file = path.join(cwd, 'package.json');
- if (!fs.existsSync(file)) return false;
- try {
- const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
- const deps = {
- ...(pkg.dependencies || {}),
- ...(pkg.devDependencies || {}),
- ...(pkg.peerDependencies || {}),
- };
- return START_PACKAGES.some((name) => Boolean(deps[name]));
- } catch {
- return false;
- }
-}
-
function relativeImportSpecifier(fromFile, toFile) {
const rel = path.posix.relative(
path.posix.dirname(fromFile.split(path.sep).join('/')),
diff --git a/.grok/skills/impeccable/scripts/live-poll.mjs b/.grok/skills/impeccable/scripts/live-poll.mjs
index 3b2f08c9f..59e21b9d3 100644
--- a/.grok/skills/impeccable/scripts/live-poll.mjs
+++ b/.grok/skills/impeccable/scripts/live-poll.mjs
@@ -238,10 +238,9 @@ export async function completeAcceptHandling(event, base, token) {
});
} catch (err) {
event._completionAck = { ok: false, error: err.message };
+ return event;
}
- if (!event._completionAck) {
- event._completionAck = completionAckForAcceptResult(event.id, completionType, event._acceptResult);
- }
+ event._completionAck = completionAckForAcceptResult(event.id, completionType, event._acceptResult);
return event;
}
@@ -269,9 +268,11 @@ export function printPollEvent(event) {
// Situational plumbing rides with the event itself: `_instructions` is the
// authoritative next step, with real ids and paths substituted, so the
// reference doc can stay lean and can never drift from script behavior.
- if (event && typeof event === 'object' && !event._instructions) {
+ // A wire-supplied value must never win over the locally generated one.
+ if (event && typeof event === 'object') {
const instructions = instructionsForEvent(event, { scriptsPath: SELF_DIR });
if (instructions) event._instructions = instructions;
+ else delete event._instructions;
}
console.log(JSON.stringify(event));
}
diff --git a/.grok/skills/impeccable/scripts/live-server.mjs b/.grok/skills/impeccable/scripts/live-server.mjs
index cba3a222e..dafa8bd0c 100644
--- a/.grok/skills/impeccable/scripts/live-server.mjs
+++ b/.grok/skills/impeccable/scripts/live-server.mjs
@@ -181,8 +181,16 @@ function chatAgentLikelyActive() {
// cap at 10 MB to guard against runaway writes from a misbehaving client.
const MAX_ANNOTATION_BYTES = 10 * 1024 * 1024;
+const POLLER_OWNED_EVENT_FIELDS = ['_instructions', '_completionAck', '_acceptResult'];
+
+function stripPollerOwnedEventFields(event) {
+ if (!event || typeof event !== 'object') return;
+ for (const key of POLLER_OWNED_EVENT_FIELDS) delete event[key];
+}
+
function enqueueEvent(event) {
if (!event) return;
+ stripPollerOwnedEventFields(event);
// Dedupe by (session, type), except mount failures, which are per-variant:
// variant 2 failing must not be swallowed because variant 1's failure is
// still queued.
@@ -1034,6 +1042,7 @@ function createRequestHandler({ detectScript, liveScriptParts }) {
res.end(JSON.stringify({ error }));
return;
}
+ stripPollerOwnedEventFields(msg);
if (msg.type === 'agent_phase') {
recordAgentPhase(msg.id, msg.phase, {
...(Number.isFinite(msg.durationMs) ? { durationMs: msg.durationMs } : {}),
diff --git a/.grok/skills/impeccable/scripts/live/sveltekit-adapter.mjs b/.grok/skills/impeccable/scripts/live/sveltekit-adapter.mjs
index e94c54f1e..b96e955a6 100644
--- a/.grok/skills/impeccable/scripts/live/sveltekit-adapter.mjs
+++ b/.grok/skills/impeccable/scripts/live/sveltekit-adapter.mjs
@@ -11,6 +11,8 @@ import crypto from 'node:crypto';
import fs from 'node:fs';
import path from 'node:path';
+import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs';
+
export const SVELTE_LIVE_ROOT_COMPONENT = 'src/lib/impeccable/ImpeccableLiveRoot.svelte';
export const SVELTE_LAYOUT_MARKER_OPEN = '';
export const SVELTE_LAYOUT_MARKER_CLOSE = '';
@@ -45,11 +47,17 @@ export function detectSvelteKitProject(cwd = process.cwd(), config = null) {
&& fileIncludes(path.join(cwd, appHtml), '%sveltekit.head%');
if (!hasTemplateMarkers) return null;
- const hasSvelteConfig = fs.existsSync(path.join(cwd, 'svelte.config.js'))
- || fs.existsSync(path.join(cwd, 'svelte.config.mjs'))
- || fs.existsSync(path.join(cwd, 'svelte.config.cjs'))
- || fs.existsSync(path.join(cwd, 'svelte.config.ts'));
- const hasKitPackage = packageHasSvelteKit(cwd);
+ const hasSvelteConfig = Boolean(firstExistingFile(cwd, [
+ 'svelte.config.js',
+ 'svelte.config.mjs',
+ 'svelte.config.cjs',
+ 'svelte.config.ts',
+ ]));
+ const hasKitPackage = hasAnyDependency(cwd, [
+ '@sveltejs/kit',
+ '@sveltejs/vite-plugin-svelte',
+ 'svelte',
+ ]);
if (!hasSvelteConfig && !hasKitPackage) return null;
return {
@@ -260,36 +268,16 @@ function findSvelteKitAppHtml(cwd, config) {
}
function findSvelteKitLayout(cwd) {
- const candidates = [
+ return firstExistingFile(cwd, [
'src/routes/+layout.svelte',
'src/routes/(app)/+layout.svelte',
- ];
- for (const rel of candidates) {
- if (fs.existsSync(path.join(cwd, rel))) return rel;
- }
- return 'src/routes/+layout.svelte';
+ ]) || 'src/routes/+layout.svelte';
}
function defaultSvelteLayout() {
return `\n\n{@render children?.()}\n`;
}
-function packageHasSvelteKit(cwd) {
- const file = path.join(cwd, 'package.json');
- if (!fs.existsSync(file)) return false;
- try {
- const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
- const deps = {
- ...(pkg.dependencies || {}),
- ...(pkg.devDependencies || {}),
- ...(pkg.peerDependencies || {}),
- };
- return Boolean(deps['@sveltejs/kit'] || deps['@sveltejs/vite-plugin-svelte'] || deps.svelte);
- } catch {
- return false;
- }
-}
-
function fileIncludes(file, text) {
try {
return fs.readFileSync(file, 'utf-8').includes(text);
diff --git a/.grok/skills/impeccable/scripts/live/tanstack-adapter.mjs b/.grok/skills/impeccable/scripts/live/tanstack-adapter.mjs
index 4a1c81a97..b53978f4f 100644
--- a/.grok/skills/impeccable/scripts/live/tanstack-adapter.mjs
+++ b/.grok/skills/impeccable/scripts/live/tanstack-adapter.mjs
@@ -19,6 +19,8 @@
import fs from 'node:fs';
import path from 'node:path';
+
+import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs';
import { buildLiveScriptSrc } from './frameworks/script-src.mjs';
export const TANSTACK_MARKER_OPEN = '{/* impeccable-live-tanstack-start */}';
@@ -42,8 +44,8 @@ const START_PACKAGES = [
];
export function detectTanStackStartProject(cwd = process.cwd()) {
- if (!packageHasTanStackStart(cwd)) return null;
- const rootRoute = findRootRouteFile(cwd);
+ if (!hasAnyDependency(cwd, START_PACKAGES)) return null;
+ const rootRoute = firstExistingFile(cwd, ROOT_ROUTE_CANDIDATES);
if (!rootRoute) return null;
const ext = path.extname(rootRoute);
@@ -218,29 +220,6 @@ function isManagedComponent(content) {
return String(content || '').includes('impeccable-live-tanstack');
}
-function findRootRouteFile(cwd) {
- for (const rel of ROOT_ROUTE_CANDIDATES) {
- if (fs.existsSync(path.join(cwd, rel))) return rel;
- }
- return null;
-}
-
-function packageHasTanStackStart(cwd) {
- const file = path.join(cwd, 'package.json');
- if (!fs.existsSync(file)) return false;
- try {
- const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
- const deps = {
- ...(pkg.dependencies || {}),
- ...(pkg.devDependencies || {}),
- ...(pkg.peerDependencies || {}),
- };
- return START_PACKAGES.some((name) => Boolean(deps[name]));
- } catch {
- return false;
- }
-}
-
function relativeImportSpecifier(fromFile, toFile) {
const rel = path.posix.relative(
path.posix.dirname(fromFile.split(path.sep).join('/')),
diff --git a/.hermes/skills/impeccable/scripts/live-poll.mjs b/.hermes/skills/impeccable/scripts/live-poll.mjs
index 3b2f08c9f..59e21b9d3 100644
--- a/.hermes/skills/impeccable/scripts/live-poll.mjs
+++ b/.hermes/skills/impeccable/scripts/live-poll.mjs
@@ -238,10 +238,9 @@ export async function completeAcceptHandling(event, base, token) {
});
} catch (err) {
event._completionAck = { ok: false, error: err.message };
+ return event;
}
- if (!event._completionAck) {
- event._completionAck = completionAckForAcceptResult(event.id, completionType, event._acceptResult);
- }
+ event._completionAck = completionAckForAcceptResult(event.id, completionType, event._acceptResult);
return event;
}
@@ -269,9 +268,11 @@ export function printPollEvent(event) {
// Situational plumbing rides with the event itself: `_instructions` is the
// authoritative next step, with real ids and paths substituted, so the
// reference doc can stay lean and can never drift from script behavior.
- if (event && typeof event === 'object' && !event._instructions) {
+ // A wire-supplied value must never win over the locally generated one.
+ if (event && typeof event === 'object') {
const instructions = instructionsForEvent(event, { scriptsPath: SELF_DIR });
if (instructions) event._instructions = instructions;
+ else delete event._instructions;
}
console.log(JSON.stringify(event));
}
diff --git a/.hermes/skills/impeccable/scripts/live-server.mjs b/.hermes/skills/impeccable/scripts/live-server.mjs
index cba3a222e..dafa8bd0c 100644
--- a/.hermes/skills/impeccable/scripts/live-server.mjs
+++ b/.hermes/skills/impeccable/scripts/live-server.mjs
@@ -181,8 +181,16 @@ function chatAgentLikelyActive() {
// cap at 10 MB to guard against runaway writes from a misbehaving client.
const MAX_ANNOTATION_BYTES = 10 * 1024 * 1024;
+const POLLER_OWNED_EVENT_FIELDS = ['_instructions', '_completionAck', '_acceptResult'];
+
+function stripPollerOwnedEventFields(event) {
+ if (!event || typeof event !== 'object') return;
+ for (const key of POLLER_OWNED_EVENT_FIELDS) delete event[key];
+}
+
function enqueueEvent(event) {
if (!event) return;
+ stripPollerOwnedEventFields(event);
// Dedupe by (session, type), except mount failures, which are per-variant:
// variant 2 failing must not be swallowed because variant 1's failure is
// still queued.
@@ -1034,6 +1042,7 @@ function createRequestHandler({ detectScript, liveScriptParts }) {
res.end(JSON.stringify({ error }));
return;
}
+ stripPollerOwnedEventFields(msg);
if (msg.type === 'agent_phase') {
recordAgentPhase(msg.id, msg.phase, {
...(Number.isFinite(msg.durationMs) ? { durationMs: msg.durationMs } : {}),
diff --git a/.hermes/skills/impeccable/scripts/live/sveltekit-adapter.mjs b/.hermes/skills/impeccable/scripts/live/sveltekit-adapter.mjs
index e94c54f1e..b96e955a6 100644
--- a/.hermes/skills/impeccable/scripts/live/sveltekit-adapter.mjs
+++ b/.hermes/skills/impeccable/scripts/live/sveltekit-adapter.mjs
@@ -11,6 +11,8 @@ import crypto from 'node:crypto';
import fs from 'node:fs';
import path from 'node:path';
+import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs';
+
export const SVELTE_LIVE_ROOT_COMPONENT = 'src/lib/impeccable/ImpeccableLiveRoot.svelte';
export const SVELTE_LAYOUT_MARKER_OPEN = '';
export const SVELTE_LAYOUT_MARKER_CLOSE = '';
@@ -45,11 +47,17 @@ export function detectSvelteKitProject(cwd = process.cwd(), config = null) {
&& fileIncludes(path.join(cwd, appHtml), '%sveltekit.head%');
if (!hasTemplateMarkers) return null;
- const hasSvelteConfig = fs.existsSync(path.join(cwd, 'svelte.config.js'))
- || fs.existsSync(path.join(cwd, 'svelte.config.mjs'))
- || fs.existsSync(path.join(cwd, 'svelte.config.cjs'))
- || fs.existsSync(path.join(cwd, 'svelte.config.ts'));
- const hasKitPackage = packageHasSvelteKit(cwd);
+ const hasSvelteConfig = Boolean(firstExistingFile(cwd, [
+ 'svelte.config.js',
+ 'svelte.config.mjs',
+ 'svelte.config.cjs',
+ 'svelte.config.ts',
+ ]));
+ const hasKitPackage = hasAnyDependency(cwd, [
+ '@sveltejs/kit',
+ '@sveltejs/vite-plugin-svelte',
+ 'svelte',
+ ]);
if (!hasSvelteConfig && !hasKitPackage) return null;
return {
@@ -260,36 +268,16 @@ function findSvelteKitAppHtml(cwd, config) {
}
function findSvelteKitLayout(cwd) {
- const candidates = [
+ return firstExistingFile(cwd, [
'src/routes/+layout.svelte',
'src/routes/(app)/+layout.svelte',
- ];
- for (const rel of candidates) {
- if (fs.existsSync(path.join(cwd, rel))) return rel;
- }
- return 'src/routes/+layout.svelte';
+ ]) || 'src/routes/+layout.svelte';
}
function defaultSvelteLayout() {
return `\n\n{@render children?.()}\n`;
}
-function packageHasSvelteKit(cwd) {
- const file = path.join(cwd, 'package.json');
- if (!fs.existsSync(file)) return false;
- try {
- const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
- const deps = {
- ...(pkg.dependencies || {}),
- ...(pkg.devDependencies || {}),
- ...(pkg.peerDependencies || {}),
- };
- return Boolean(deps['@sveltejs/kit'] || deps['@sveltejs/vite-plugin-svelte'] || deps.svelte);
- } catch {
- return false;
- }
-}
-
function fileIncludes(file, text) {
try {
return fs.readFileSync(file, 'utf-8').includes(text);
diff --git a/.hermes/skills/impeccable/scripts/live/tanstack-adapter.mjs b/.hermes/skills/impeccable/scripts/live/tanstack-adapter.mjs
index 4a1c81a97..b53978f4f 100644
--- a/.hermes/skills/impeccable/scripts/live/tanstack-adapter.mjs
+++ b/.hermes/skills/impeccable/scripts/live/tanstack-adapter.mjs
@@ -19,6 +19,8 @@
import fs from 'node:fs';
import path from 'node:path';
+
+import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs';
import { buildLiveScriptSrc } from './frameworks/script-src.mjs';
export const TANSTACK_MARKER_OPEN = '{/* impeccable-live-tanstack-start */}';
@@ -42,8 +44,8 @@ const START_PACKAGES = [
];
export function detectTanStackStartProject(cwd = process.cwd()) {
- if (!packageHasTanStackStart(cwd)) return null;
- const rootRoute = findRootRouteFile(cwd);
+ if (!hasAnyDependency(cwd, START_PACKAGES)) return null;
+ const rootRoute = firstExistingFile(cwd, ROOT_ROUTE_CANDIDATES);
if (!rootRoute) return null;
const ext = path.extname(rootRoute);
@@ -218,29 +220,6 @@ function isManagedComponent(content) {
return String(content || '').includes('impeccable-live-tanstack');
}
-function findRootRouteFile(cwd) {
- for (const rel of ROOT_ROUTE_CANDIDATES) {
- if (fs.existsSync(path.join(cwd, rel))) return rel;
- }
- return null;
-}
-
-function packageHasTanStackStart(cwd) {
- const file = path.join(cwd, 'package.json');
- if (!fs.existsSync(file)) return false;
- try {
- const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
- const deps = {
- ...(pkg.dependencies || {}),
- ...(pkg.devDependencies || {}),
- ...(pkg.peerDependencies || {}),
- };
- return START_PACKAGES.some((name) => Boolean(deps[name]));
- } catch {
- return false;
- }
-}
-
function relativeImportSpecifier(fromFile, toFile) {
const rel = path.posix.relative(
path.posix.dirname(fromFile.split(path.sep).join('/')),
diff --git a/.kiro/skills/impeccable/scripts/live-poll.mjs b/.kiro/skills/impeccable/scripts/live-poll.mjs
index 3b2f08c9f..59e21b9d3 100644
--- a/.kiro/skills/impeccable/scripts/live-poll.mjs
+++ b/.kiro/skills/impeccable/scripts/live-poll.mjs
@@ -238,10 +238,9 @@ export async function completeAcceptHandling(event, base, token) {
});
} catch (err) {
event._completionAck = { ok: false, error: err.message };
+ return event;
}
- if (!event._completionAck) {
- event._completionAck = completionAckForAcceptResult(event.id, completionType, event._acceptResult);
- }
+ event._completionAck = completionAckForAcceptResult(event.id, completionType, event._acceptResult);
return event;
}
@@ -269,9 +268,11 @@ export function printPollEvent(event) {
// Situational plumbing rides with the event itself: `_instructions` is the
// authoritative next step, with real ids and paths substituted, so the
// reference doc can stay lean and can never drift from script behavior.
- if (event && typeof event === 'object' && !event._instructions) {
+ // A wire-supplied value must never win over the locally generated one.
+ if (event && typeof event === 'object') {
const instructions = instructionsForEvent(event, { scriptsPath: SELF_DIR });
if (instructions) event._instructions = instructions;
+ else delete event._instructions;
}
console.log(JSON.stringify(event));
}
diff --git a/.kiro/skills/impeccable/scripts/live-server.mjs b/.kiro/skills/impeccable/scripts/live-server.mjs
index cba3a222e..dafa8bd0c 100644
--- a/.kiro/skills/impeccable/scripts/live-server.mjs
+++ b/.kiro/skills/impeccable/scripts/live-server.mjs
@@ -181,8 +181,16 @@ function chatAgentLikelyActive() {
// cap at 10 MB to guard against runaway writes from a misbehaving client.
const MAX_ANNOTATION_BYTES = 10 * 1024 * 1024;
+const POLLER_OWNED_EVENT_FIELDS = ['_instructions', '_completionAck', '_acceptResult'];
+
+function stripPollerOwnedEventFields(event) {
+ if (!event || typeof event !== 'object') return;
+ for (const key of POLLER_OWNED_EVENT_FIELDS) delete event[key];
+}
+
function enqueueEvent(event) {
if (!event) return;
+ stripPollerOwnedEventFields(event);
// Dedupe by (session, type), except mount failures, which are per-variant:
// variant 2 failing must not be swallowed because variant 1's failure is
// still queued.
@@ -1034,6 +1042,7 @@ function createRequestHandler({ detectScript, liveScriptParts }) {
res.end(JSON.stringify({ error }));
return;
}
+ stripPollerOwnedEventFields(msg);
if (msg.type === 'agent_phase') {
recordAgentPhase(msg.id, msg.phase, {
...(Number.isFinite(msg.durationMs) ? { durationMs: msg.durationMs } : {}),
diff --git a/.kiro/skills/impeccable/scripts/live/sveltekit-adapter.mjs b/.kiro/skills/impeccable/scripts/live/sveltekit-adapter.mjs
index e94c54f1e..b96e955a6 100644
--- a/.kiro/skills/impeccable/scripts/live/sveltekit-adapter.mjs
+++ b/.kiro/skills/impeccable/scripts/live/sveltekit-adapter.mjs
@@ -11,6 +11,8 @@ import crypto from 'node:crypto';
import fs from 'node:fs';
import path from 'node:path';
+import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs';
+
export const SVELTE_LIVE_ROOT_COMPONENT = 'src/lib/impeccable/ImpeccableLiveRoot.svelte';
export const SVELTE_LAYOUT_MARKER_OPEN = '';
export const SVELTE_LAYOUT_MARKER_CLOSE = '';
@@ -45,11 +47,17 @@ export function detectSvelteKitProject(cwd = process.cwd(), config = null) {
&& fileIncludes(path.join(cwd, appHtml), '%sveltekit.head%');
if (!hasTemplateMarkers) return null;
- const hasSvelteConfig = fs.existsSync(path.join(cwd, 'svelte.config.js'))
- || fs.existsSync(path.join(cwd, 'svelte.config.mjs'))
- || fs.existsSync(path.join(cwd, 'svelte.config.cjs'))
- || fs.existsSync(path.join(cwd, 'svelte.config.ts'));
- const hasKitPackage = packageHasSvelteKit(cwd);
+ const hasSvelteConfig = Boolean(firstExistingFile(cwd, [
+ 'svelte.config.js',
+ 'svelte.config.mjs',
+ 'svelte.config.cjs',
+ 'svelte.config.ts',
+ ]));
+ const hasKitPackage = hasAnyDependency(cwd, [
+ '@sveltejs/kit',
+ '@sveltejs/vite-plugin-svelte',
+ 'svelte',
+ ]);
if (!hasSvelteConfig && !hasKitPackage) return null;
return {
@@ -260,36 +268,16 @@ function findSvelteKitAppHtml(cwd, config) {
}
function findSvelteKitLayout(cwd) {
- const candidates = [
+ return firstExistingFile(cwd, [
'src/routes/+layout.svelte',
'src/routes/(app)/+layout.svelte',
- ];
- for (const rel of candidates) {
- if (fs.existsSync(path.join(cwd, rel))) return rel;
- }
- return 'src/routes/+layout.svelte';
+ ]) || 'src/routes/+layout.svelte';
}
function defaultSvelteLayout() {
return `\n\n{@render children?.()}\n`;
}
-function packageHasSvelteKit(cwd) {
- const file = path.join(cwd, 'package.json');
- if (!fs.existsSync(file)) return false;
- try {
- const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
- const deps = {
- ...(pkg.dependencies || {}),
- ...(pkg.devDependencies || {}),
- ...(pkg.peerDependencies || {}),
- };
- return Boolean(deps['@sveltejs/kit'] || deps['@sveltejs/vite-plugin-svelte'] || deps.svelte);
- } catch {
- return false;
- }
-}
-
function fileIncludes(file, text) {
try {
return fs.readFileSync(file, 'utf-8').includes(text);
diff --git a/.kiro/skills/impeccable/scripts/live/tanstack-adapter.mjs b/.kiro/skills/impeccable/scripts/live/tanstack-adapter.mjs
index 4a1c81a97..b53978f4f 100644
--- a/.kiro/skills/impeccable/scripts/live/tanstack-adapter.mjs
+++ b/.kiro/skills/impeccable/scripts/live/tanstack-adapter.mjs
@@ -19,6 +19,8 @@
import fs from 'node:fs';
import path from 'node:path';
+
+import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs';
import { buildLiveScriptSrc } from './frameworks/script-src.mjs';
export const TANSTACK_MARKER_OPEN = '{/* impeccable-live-tanstack-start */}';
@@ -42,8 +44,8 @@ const START_PACKAGES = [
];
export function detectTanStackStartProject(cwd = process.cwd()) {
- if (!packageHasTanStackStart(cwd)) return null;
- const rootRoute = findRootRouteFile(cwd);
+ if (!hasAnyDependency(cwd, START_PACKAGES)) return null;
+ const rootRoute = firstExistingFile(cwd, ROOT_ROUTE_CANDIDATES);
if (!rootRoute) return null;
const ext = path.extname(rootRoute);
@@ -218,29 +220,6 @@ function isManagedComponent(content) {
return String(content || '').includes('impeccable-live-tanstack');
}
-function findRootRouteFile(cwd) {
- for (const rel of ROOT_ROUTE_CANDIDATES) {
- if (fs.existsSync(path.join(cwd, rel))) return rel;
- }
- return null;
-}
-
-function packageHasTanStackStart(cwd) {
- const file = path.join(cwd, 'package.json');
- if (!fs.existsSync(file)) return false;
- try {
- const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
- const deps = {
- ...(pkg.dependencies || {}),
- ...(pkg.devDependencies || {}),
- ...(pkg.peerDependencies || {}),
- };
- return START_PACKAGES.some((name) => Boolean(deps[name]));
- } catch {
- return false;
- }
-}
-
function relativeImportSpecifier(fromFile, toFile) {
const rel = path.posix.relative(
path.posix.dirname(fromFile.split(path.sep).join('/')),
diff --git a/.opencode/skills/impeccable/scripts/live-poll.mjs b/.opencode/skills/impeccable/scripts/live-poll.mjs
index 3b2f08c9f..59e21b9d3 100644
--- a/.opencode/skills/impeccable/scripts/live-poll.mjs
+++ b/.opencode/skills/impeccable/scripts/live-poll.mjs
@@ -238,10 +238,9 @@ export async function completeAcceptHandling(event, base, token) {
});
} catch (err) {
event._completionAck = { ok: false, error: err.message };
+ return event;
}
- if (!event._completionAck) {
- event._completionAck = completionAckForAcceptResult(event.id, completionType, event._acceptResult);
- }
+ event._completionAck = completionAckForAcceptResult(event.id, completionType, event._acceptResult);
return event;
}
@@ -269,9 +268,11 @@ export function printPollEvent(event) {
// Situational plumbing rides with the event itself: `_instructions` is the
// authoritative next step, with real ids and paths substituted, so the
// reference doc can stay lean and can never drift from script behavior.
- if (event && typeof event === 'object' && !event._instructions) {
+ // A wire-supplied value must never win over the locally generated one.
+ if (event && typeof event === 'object') {
const instructions = instructionsForEvent(event, { scriptsPath: SELF_DIR });
if (instructions) event._instructions = instructions;
+ else delete event._instructions;
}
console.log(JSON.stringify(event));
}
diff --git a/.opencode/skills/impeccable/scripts/live-server.mjs b/.opencode/skills/impeccable/scripts/live-server.mjs
index cba3a222e..dafa8bd0c 100644
--- a/.opencode/skills/impeccable/scripts/live-server.mjs
+++ b/.opencode/skills/impeccable/scripts/live-server.mjs
@@ -181,8 +181,16 @@ function chatAgentLikelyActive() {
// cap at 10 MB to guard against runaway writes from a misbehaving client.
const MAX_ANNOTATION_BYTES = 10 * 1024 * 1024;
+const POLLER_OWNED_EVENT_FIELDS = ['_instructions', '_completionAck', '_acceptResult'];
+
+function stripPollerOwnedEventFields(event) {
+ if (!event || typeof event !== 'object') return;
+ for (const key of POLLER_OWNED_EVENT_FIELDS) delete event[key];
+}
+
function enqueueEvent(event) {
if (!event) return;
+ stripPollerOwnedEventFields(event);
// Dedupe by (session, type), except mount failures, which are per-variant:
// variant 2 failing must not be swallowed because variant 1's failure is
// still queued.
@@ -1034,6 +1042,7 @@ function createRequestHandler({ detectScript, liveScriptParts }) {
res.end(JSON.stringify({ error }));
return;
}
+ stripPollerOwnedEventFields(msg);
if (msg.type === 'agent_phase') {
recordAgentPhase(msg.id, msg.phase, {
...(Number.isFinite(msg.durationMs) ? { durationMs: msg.durationMs } : {}),
diff --git a/.opencode/skills/impeccable/scripts/live/sveltekit-adapter.mjs b/.opencode/skills/impeccable/scripts/live/sveltekit-adapter.mjs
index e94c54f1e..b96e955a6 100644
--- a/.opencode/skills/impeccable/scripts/live/sveltekit-adapter.mjs
+++ b/.opencode/skills/impeccable/scripts/live/sveltekit-adapter.mjs
@@ -11,6 +11,8 @@ import crypto from 'node:crypto';
import fs from 'node:fs';
import path from 'node:path';
+import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs';
+
export const SVELTE_LIVE_ROOT_COMPONENT = 'src/lib/impeccable/ImpeccableLiveRoot.svelte';
export const SVELTE_LAYOUT_MARKER_OPEN = '';
export const SVELTE_LAYOUT_MARKER_CLOSE = '';
@@ -45,11 +47,17 @@ export function detectSvelteKitProject(cwd = process.cwd(), config = null) {
&& fileIncludes(path.join(cwd, appHtml), '%sveltekit.head%');
if (!hasTemplateMarkers) return null;
- const hasSvelteConfig = fs.existsSync(path.join(cwd, 'svelte.config.js'))
- || fs.existsSync(path.join(cwd, 'svelte.config.mjs'))
- || fs.existsSync(path.join(cwd, 'svelte.config.cjs'))
- || fs.existsSync(path.join(cwd, 'svelte.config.ts'));
- const hasKitPackage = packageHasSvelteKit(cwd);
+ const hasSvelteConfig = Boolean(firstExistingFile(cwd, [
+ 'svelte.config.js',
+ 'svelte.config.mjs',
+ 'svelte.config.cjs',
+ 'svelte.config.ts',
+ ]));
+ const hasKitPackage = hasAnyDependency(cwd, [
+ '@sveltejs/kit',
+ '@sveltejs/vite-plugin-svelte',
+ 'svelte',
+ ]);
if (!hasSvelteConfig && !hasKitPackage) return null;
return {
@@ -260,36 +268,16 @@ function findSvelteKitAppHtml(cwd, config) {
}
function findSvelteKitLayout(cwd) {
- const candidates = [
+ return firstExistingFile(cwd, [
'src/routes/+layout.svelte',
'src/routes/(app)/+layout.svelte',
- ];
- for (const rel of candidates) {
- if (fs.existsSync(path.join(cwd, rel))) return rel;
- }
- return 'src/routes/+layout.svelte';
+ ]) || 'src/routes/+layout.svelte';
}
function defaultSvelteLayout() {
return `\n\n{@render children?.()}\n`;
}
-function packageHasSvelteKit(cwd) {
- const file = path.join(cwd, 'package.json');
- if (!fs.existsSync(file)) return false;
- try {
- const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
- const deps = {
- ...(pkg.dependencies || {}),
- ...(pkg.devDependencies || {}),
- ...(pkg.peerDependencies || {}),
- };
- return Boolean(deps['@sveltejs/kit'] || deps['@sveltejs/vite-plugin-svelte'] || deps.svelte);
- } catch {
- return false;
- }
-}
-
function fileIncludes(file, text) {
try {
return fs.readFileSync(file, 'utf-8').includes(text);
diff --git a/.opencode/skills/impeccable/scripts/live/tanstack-adapter.mjs b/.opencode/skills/impeccable/scripts/live/tanstack-adapter.mjs
index 4a1c81a97..b53978f4f 100644
--- a/.opencode/skills/impeccable/scripts/live/tanstack-adapter.mjs
+++ b/.opencode/skills/impeccable/scripts/live/tanstack-adapter.mjs
@@ -19,6 +19,8 @@
import fs from 'node:fs';
import path from 'node:path';
+
+import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs';
import { buildLiveScriptSrc } from './frameworks/script-src.mjs';
export const TANSTACK_MARKER_OPEN = '{/* impeccable-live-tanstack-start */}';
@@ -42,8 +44,8 @@ const START_PACKAGES = [
];
export function detectTanStackStartProject(cwd = process.cwd()) {
- if (!packageHasTanStackStart(cwd)) return null;
- const rootRoute = findRootRouteFile(cwd);
+ if (!hasAnyDependency(cwd, START_PACKAGES)) return null;
+ const rootRoute = firstExistingFile(cwd, ROOT_ROUTE_CANDIDATES);
if (!rootRoute) return null;
const ext = path.extname(rootRoute);
@@ -218,29 +220,6 @@ function isManagedComponent(content) {
return String(content || '').includes('impeccable-live-tanstack');
}
-function findRootRouteFile(cwd) {
- for (const rel of ROOT_ROUTE_CANDIDATES) {
- if (fs.existsSync(path.join(cwd, rel))) return rel;
- }
- return null;
-}
-
-function packageHasTanStackStart(cwd) {
- const file = path.join(cwd, 'package.json');
- if (!fs.existsSync(file)) return false;
- try {
- const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
- const deps = {
- ...(pkg.dependencies || {}),
- ...(pkg.devDependencies || {}),
- ...(pkg.peerDependencies || {}),
- };
- return START_PACKAGES.some((name) => Boolean(deps[name]));
- } catch {
- return false;
- }
-}
-
function relativeImportSpecifier(fromFile, toFile) {
const rel = path.posix.relative(
path.posix.dirname(fromFile.split(path.sep).join('/')),
diff --git a/.pi/skills/impeccable/scripts/live-poll.mjs b/.pi/skills/impeccable/scripts/live-poll.mjs
index 3b2f08c9f..59e21b9d3 100644
--- a/.pi/skills/impeccable/scripts/live-poll.mjs
+++ b/.pi/skills/impeccable/scripts/live-poll.mjs
@@ -238,10 +238,9 @@ export async function completeAcceptHandling(event, base, token) {
});
} catch (err) {
event._completionAck = { ok: false, error: err.message };
+ return event;
}
- if (!event._completionAck) {
- event._completionAck = completionAckForAcceptResult(event.id, completionType, event._acceptResult);
- }
+ event._completionAck = completionAckForAcceptResult(event.id, completionType, event._acceptResult);
return event;
}
@@ -269,9 +268,11 @@ export function printPollEvent(event) {
// Situational plumbing rides with the event itself: `_instructions` is the
// authoritative next step, with real ids and paths substituted, so the
// reference doc can stay lean and can never drift from script behavior.
- if (event && typeof event === 'object' && !event._instructions) {
+ // A wire-supplied value must never win over the locally generated one.
+ if (event && typeof event === 'object') {
const instructions = instructionsForEvent(event, { scriptsPath: SELF_DIR });
if (instructions) event._instructions = instructions;
+ else delete event._instructions;
}
console.log(JSON.stringify(event));
}
diff --git a/.pi/skills/impeccable/scripts/live-server.mjs b/.pi/skills/impeccable/scripts/live-server.mjs
index cba3a222e..dafa8bd0c 100644
--- a/.pi/skills/impeccable/scripts/live-server.mjs
+++ b/.pi/skills/impeccable/scripts/live-server.mjs
@@ -181,8 +181,16 @@ function chatAgentLikelyActive() {
// cap at 10 MB to guard against runaway writes from a misbehaving client.
const MAX_ANNOTATION_BYTES = 10 * 1024 * 1024;
+const POLLER_OWNED_EVENT_FIELDS = ['_instructions', '_completionAck', '_acceptResult'];
+
+function stripPollerOwnedEventFields(event) {
+ if (!event || typeof event !== 'object') return;
+ for (const key of POLLER_OWNED_EVENT_FIELDS) delete event[key];
+}
+
function enqueueEvent(event) {
if (!event) return;
+ stripPollerOwnedEventFields(event);
// Dedupe by (session, type), except mount failures, which are per-variant:
// variant 2 failing must not be swallowed because variant 1's failure is
// still queued.
@@ -1034,6 +1042,7 @@ function createRequestHandler({ detectScript, liveScriptParts }) {
res.end(JSON.stringify({ error }));
return;
}
+ stripPollerOwnedEventFields(msg);
if (msg.type === 'agent_phase') {
recordAgentPhase(msg.id, msg.phase, {
...(Number.isFinite(msg.durationMs) ? { durationMs: msg.durationMs } : {}),
diff --git a/.pi/skills/impeccable/scripts/live/sveltekit-adapter.mjs b/.pi/skills/impeccable/scripts/live/sveltekit-adapter.mjs
index e94c54f1e..b96e955a6 100644
--- a/.pi/skills/impeccable/scripts/live/sveltekit-adapter.mjs
+++ b/.pi/skills/impeccable/scripts/live/sveltekit-adapter.mjs
@@ -11,6 +11,8 @@ import crypto from 'node:crypto';
import fs from 'node:fs';
import path from 'node:path';
+import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs';
+
export const SVELTE_LIVE_ROOT_COMPONENT = 'src/lib/impeccable/ImpeccableLiveRoot.svelte';
export const SVELTE_LAYOUT_MARKER_OPEN = '';
export const SVELTE_LAYOUT_MARKER_CLOSE = '';
@@ -45,11 +47,17 @@ export function detectSvelteKitProject(cwd = process.cwd(), config = null) {
&& fileIncludes(path.join(cwd, appHtml), '%sveltekit.head%');
if (!hasTemplateMarkers) return null;
- const hasSvelteConfig = fs.existsSync(path.join(cwd, 'svelte.config.js'))
- || fs.existsSync(path.join(cwd, 'svelte.config.mjs'))
- || fs.existsSync(path.join(cwd, 'svelte.config.cjs'))
- || fs.existsSync(path.join(cwd, 'svelte.config.ts'));
- const hasKitPackage = packageHasSvelteKit(cwd);
+ const hasSvelteConfig = Boolean(firstExistingFile(cwd, [
+ 'svelte.config.js',
+ 'svelte.config.mjs',
+ 'svelte.config.cjs',
+ 'svelte.config.ts',
+ ]));
+ const hasKitPackage = hasAnyDependency(cwd, [
+ '@sveltejs/kit',
+ '@sveltejs/vite-plugin-svelte',
+ 'svelte',
+ ]);
if (!hasSvelteConfig && !hasKitPackage) return null;
return {
@@ -260,36 +268,16 @@ function findSvelteKitAppHtml(cwd, config) {
}
function findSvelteKitLayout(cwd) {
- const candidates = [
+ return firstExistingFile(cwd, [
'src/routes/+layout.svelte',
'src/routes/(app)/+layout.svelte',
- ];
- for (const rel of candidates) {
- if (fs.existsSync(path.join(cwd, rel))) return rel;
- }
- return 'src/routes/+layout.svelte';
+ ]) || 'src/routes/+layout.svelte';
}
function defaultSvelteLayout() {
return `\n\n{@render children?.()}\n`;
}
-function packageHasSvelteKit(cwd) {
- const file = path.join(cwd, 'package.json');
- if (!fs.existsSync(file)) return false;
- try {
- const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
- const deps = {
- ...(pkg.dependencies || {}),
- ...(pkg.devDependencies || {}),
- ...(pkg.peerDependencies || {}),
- };
- return Boolean(deps['@sveltejs/kit'] || deps['@sveltejs/vite-plugin-svelte'] || deps.svelte);
- } catch {
- return false;
- }
-}
-
function fileIncludes(file, text) {
try {
return fs.readFileSync(file, 'utf-8').includes(text);
diff --git a/.pi/skills/impeccable/scripts/live/tanstack-adapter.mjs b/.pi/skills/impeccable/scripts/live/tanstack-adapter.mjs
index 4a1c81a97..b53978f4f 100644
--- a/.pi/skills/impeccable/scripts/live/tanstack-adapter.mjs
+++ b/.pi/skills/impeccable/scripts/live/tanstack-adapter.mjs
@@ -19,6 +19,8 @@
import fs from 'node:fs';
import path from 'node:path';
+
+import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs';
import { buildLiveScriptSrc } from './frameworks/script-src.mjs';
export const TANSTACK_MARKER_OPEN = '{/* impeccable-live-tanstack-start */}';
@@ -42,8 +44,8 @@ const START_PACKAGES = [
];
export function detectTanStackStartProject(cwd = process.cwd()) {
- if (!packageHasTanStackStart(cwd)) return null;
- const rootRoute = findRootRouteFile(cwd);
+ if (!hasAnyDependency(cwd, START_PACKAGES)) return null;
+ const rootRoute = firstExistingFile(cwd, ROOT_ROUTE_CANDIDATES);
if (!rootRoute) return null;
const ext = path.extname(rootRoute);
@@ -218,29 +220,6 @@ function isManagedComponent(content) {
return String(content || '').includes('impeccable-live-tanstack');
}
-function findRootRouteFile(cwd) {
- for (const rel of ROOT_ROUTE_CANDIDATES) {
- if (fs.existsSync(path.join(cwd, rel))) return rel;
- }
- return null;
-}
-
-function packageHasTanStackStart(cwd) {
- const file = path.join(cwd, 'package.json');
- if (!fs.existsSync(file)) return false;
- try {
- const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
- const deps = {
- ...(pkg.dependencies || {}),
- ...(pkg.devDependencies || {}),
- ...(pkg.peerDependencies || {}),
- };
- return START_PACKAGES.some((name) => Boolean(deps[name]));
- } catch {
- return false;
- }
-}
-
function relativeImportSpecifier(fromFile, toFile) {
const rel = path.posix.relative(
path.posix.dirname(fromFile.split(path.sep).join('/')),
diff --git a/.qoder/skills/impeccable/scripts/live-poll.mjs b/.qoder/skills/impeccable/scripts/live-poll.mjs
index 3b2f08c9f..59e21b9d3 100644
--- a/.qoder/skills/impeccable/scripts/live-poll.mjs
+++ b/.qoder/skills/impeccable/scripts/live-poll.mjs
@@ -238,10 +238,9 @@ export async function completeAcceptHandling(event, base, token) {
});
} catch (err) {
event._completionAck = { ok: false, error: err.message };
+ return event;
}
- if (!event._completionAck) {
- event._completionAck = completionAckForAcceptResult(event.id, completionType, event._acceptResult);
- }
+ event._completionAck = completionAckForAcceptResult(event.id, completionType, event._acceptResult);
return event;
}
@@ -269,9 +268,11 @@ export function printPollEvent(event) {
// Situational plumbing rides with the event itself: `_instructions` is the
// authoritative next step, with real ids and paths substituted, so the
// reference doc can stay lean and can never drift from script behavior.
- if (event && typeof event === 'object' && !event._instructions) {
+ // A wire-supplied value must never win over the locally generated one.
+ if (event && typeof event === 'object') {
const instructions = instructionsForEvent(event, { scriptsPath: SELF_DIR });
if (instructions) event._instructions = instructions;
+ else delete event._instructions;
}
console.log(JSON.stringify(event));
}
diff --git a/.qoder/skills/impeccable/scripts/live-server.mjs b/.qoder/skills/impeccable/scripts/live-server.mjs
index cba3a222e..dafa8bd0c 100644
--- a/.qoder/skills/impeccable/scripts/live-server.mjs
+++ b/.qoder/skills/impeccable/scripts/live-server.mjs
@@ -181,8 +181,16 @@ function chatAgentLikelyActive() {
// cap at 10 MB to guard against runaway writes from a misbehaving client.
const MAX_ANNOTATION_BYTES = 10 * 1024 * 1024;
+const POLLER_OWNED_EVENT_FIELDS = ['_instructions', '_completionAck', '_acceptResult'];
+
+function stripPollerOwnedEventFields(event) {
+ if (!event || typeof event !== 'object') return;
+ for (const key of POLLER_OWNED_EVENT_FIELDS) delete event[key];
+}
+
function enqueueEvent(event) {
if (!event) return;
+ stripPollerOwnedEventFields(event);
// Dedupe by (session, type), except mount failures, which are per-variant:
// variant 2 failing must not be swallowed because variant 1's failure is
// still queued.
@@ -1034,6 +1042,7 @@ function createRequestHandler({ detectScript, liveScriptParts }) {
res.end(JSON.stringify({ error }));
return;
}
+ stripPollerOwnedEventFields(msg);
if (msg.type === 'agent_phase') {
recordAgentPhase(msg.id, msg.phase, {
...(Number.isFinite(msg.durationMs) ? { durationMs: msg.durationMs } : {}),
diff --git a/.qoder/skills/impeccable/scripts/live/sveltekit-adapter.mjs b/.qoder/skills/impeccable/scripts/live/sveltekit-adapter.mjs
index e94c54f1e..b96e955a6 100644
--- a/.qoder/skills/impeccable/scripts/live/sveltekit-adapter.mjs
+++ b/.qoder/skills/impeccable/scripts/live/sveltekit-adapter.mjs
@@ -11,6 +11,8 @@ import crypto from 'node:crypto';
import fs from 'node:fs';
import path from 'node:path';
+import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs';
+
export const SVELTE_LIVE_ROOT_COMPONENT = 'src/lib/impeccable/ImpeccableLiveRoot.svelte';
export const SVELTE_LAYOUT_MARKER_OPEN = '';
export const SVELTE_LAYOUT_MARKER_CLOSE = '';
@@ -45,11 +47,17 @@ export function detectSvelteKitProject(cwd = process.cwd(), config = null) {
&& fileIncludes(path.join(cwd, appHtml), '%sveltekit.head%');
if (!hasTemplateMarkers) return null;
- const hasSvelteConfig = fs.existsSync(path.join(cwd, 'svelte.config.js'))
- || fs.existsSync(path.join(cwd, 'svelte.config.mjs'))
- || fs.existsSync(path.join(cwd, 'svelte.config.cjs'))
- || fs.existsSync(path.join(cwd, 'svelte.config.ts'));
- const hasKitPackage = packageHasSvelteKit(cwd);
+ const hasSvelteConfig = Boolean(firstExistingFile(cwd, [
+ 'svelte.config.js',
+ 'svelte.config.mjs',
+ 'svelte.config.cjs',
+ 'svelte.config.ts',
+ ]));
+ const hasKitPackage = hasAnyDependency(cwd, [
+ '@sveltejs/kit',
+ '@sveltejs/vite-plugin-svelte',
+ 'svelte',
+ ]);
if (!hasSvelteConfig && !hasKitPackage) return null;
return {
@@ -260,36 +268,16 @@ function findSvelteKitAppHtml(cwd, config) {
}
function findSvelteKitLayout(cwd) {
- const candidates = [
+ return firstExistingFile(cwd, [
'src/routes/+layout.svelte',
'src/routes/(app)/+layout.svelte',
- ];
- for (const rel of candidates) {
- if (fs.existsSync(path.join(cwd, rel))) return rel;
- }
- return 'src/routes/+layout.svelte';
+ ]) || 'src/routes/+layout.svelte';
}
function defaultSvelteLayout() {
return `\n\n{@render children?.()}\n`;
}
-function packageHasSvelteKit(cwd) {
- const file = path.join(cwd, 'package.json');
- if (!fs.existsSync(file)) return false;
- try {
- const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
- const deps = {
- ...(pkg.dependencies || {}),
- ...(pkg.devDependencies || {}),
- ...(pkg.peerDependencies || {}),
- };
- return Boolean(deps['@sveltejs/kit'] || deps['@sveltejs/vite-plugin-svelte'] || deps.svelte);
- } catch {
- return false;
- }
-}
-
function fileIncludes(file, text) {
try {
return fs.readFileSync(file, 'utf-8').includes(text);
diff --git a/.qoder/skills/impeccable/scripts/live/tanstack-adapter.mjs b/.qoder/skills/impeccable/scripts/live/tanstack-adapter.mjs
index 4a1c81a97..b53978f4f 100644
--- a/.qoder/skills/impeccable/scripts/live/tanstack-adapter.mjs
+++ b/.qoder/skills/impeccable/scripts/live/tanstack-adapter.mjs
@@ -19,6 +19,8 @@
import fs from 'node:fs';
import path from 'node:path';
+
+import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs';
import { buildLiveScriptSrc } from './frameworks/script-src.mjs';
export const TANSTACK_MARKER_OPEN = '{/* impeccable-live-tanstack-start */}';
@@ -42,8 +44,8 @@ const START_PACKAGES = [
];
export function detectTanStackStartProject(cwd = process.cwd()) {
- if (!packageHasTanStackStart(cwd)) return null;
- const rootRoute = findRootRouteFile(cwd);
+ if (!hasAnyDependency(cwd, START_PACKAGES)) return null;
+ const rootRoute = firstExistingFile(cwd, ROOT_ROUTE_CANDIDATES);
if (!rootRoute) return null;
const ext = path.extname(rootRoute);
@@ -218,29 +220,6 @@ function isManagedComponent(content) {
return String(content || '').includes('impeccable-live-tanstack');
}
-function findRootRouteFile(cwd) {
- for (const rel of ROOT_ROUTE_CANDIDATES) {
- if (fs.existsSync(path.join(cwd, rel))) return rel;
- }
- return null;
-}
-
-function packageHasTanStackStart(cwd) {
- const file = path.join(cwd, 'package.json');
- if (!fs.existsSync(file)) return false;
- try {
- const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
- const deps = {
- ...(pkg.dependencies || {}),
- ...(pkg.devDependencies || {}),
- ...(pkg.peerDependencies || {}),
- };
- return START_PACKAGES.some((name) => Boolean(deps[name]));
- } catch {
- return false;
- }
-}
-
function relativeImportSpecifier(fromFile, toFile) {
const rel = path.posix.relative(
path.posix.dirname(fromFile.split(path.sep).join('/')),
diff --git a/.rovodev/skills/impeccable/scripts/live-poll.mjs b/.rovodev/skills/impeccable/scripts/live-poll.mjs
index 3b2f08c9f..59e21b9d3 100644
--- a/.rovodev/skills/impeccable/scripts/live-poll.mjs
+++ b/.rovodev/skills/impeccable/scripts/live-poll.mjs
@@ -238,10 +238,9 @@ export async function completeAcceptHandling(event, base, token) {
});
} catch (err) {
event._completionAck = { ok: false, error: err.message };
+ return event;
}
- if (!event._completionAck) {
- event._completionAck = completionAckForAcceptResult(event.id, completionType, event._acceptResult);
- }
+ event._completionAck = completionAckForAcceptResult(event.id, completionType, event._acceptResult);
return event;
}
@@ -269,9 +268,11 @@ export function printPollEvent(event) {
// Situational plumbing rides with the event itself: `_instructions` is the
// authoritative next step, with real ids and paths substituted, so the
// reference doc can stay lean and can never drift from script behavior.
- if (event && typeof event === 'object' && !event._instructions) {
+ // A wire-supplied value must never win over the locally generated one.
+ if (event && typeof event === 'object') {
const instructions = instructionsForEvent(event, { scriptsPath: SELF_DIR });
if (instructions) event._instructions = instructions;
+ else delete event._instructions;
}
console.log(JSON.stringify(event));
}
diff --git a/.rovodev/skills/impeccable/scripts/live-server.mjs b/.rovodev/skills/impeccable/scripts/live-server.mjs
index cba3a222e..dafa8bd0c 100644
--- a/.rovodev/skills/impeccable/scripts/live-server.mjs
+++ b/.rovodev/skills/impeccable/scripts/live-server.mjs
@@ -181,8 +181,16 @@ function chatAgentLikelyActive() {
// cap at 10 MB to guard against runaway writes from a misbehaving client.
const MAX_ANNOTATION_BYTES = 10 * 1024 * 1024;
+const POLLER_OWNED_EVENT_FIELDS = ['_instructions', '_completionAck', '_acceptResult'];
+
+function stripPollerOwnedEventFields(event) {
+ if (!event || typeof event !== 'object') return;
+ for (const key of POLLER_OWNED_EVENT_FIELDS) delete event[key];
+}
+
function enqueueEvent(event) {
if (!event) return;
+ stripPollerOwnedEventFields(event);
// Dedupe by (session, type), except mount failures, which are per-variant:
// variant 2 failing must not be swallowed because variant 1's failure is
// still queued.
@@ -1034,6 +1042,7 @@ function createRequestHandler({ detectScript, liveScriptParts }) {
res.end(JSON.stringify({ error }));
return;
}
+ stripPollerOwnedEventFields(msg);
if (msg.type === 'agent_phase') {
recordAgentPhase(msg.id, msg.phase, {
...(Number.isFinite(msg.durationMs) ? { durationMs: msg.durationMs } : {}),
diff --git a/.rovodev/skills/impeccable/scripts/live/sveltekit-adapter.mjs b/.rovodev/skills/impeccable/scripts/live/sveltekit-adapter.mjs
index e94c54f1e..b96e955a6 100644
--- a/.rovodev/skills/impeccable/scripts/live/sveltekit-adapter.mjs
+++ b/.rovodev/skills/impeccable/scripts/live/sveltekit-adapter.mjs
@@ -11,6 +11,8 @@ import crypto from 'node:crypto';
import fs from 'node:fs';
import path from 'node:path';
+import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs';
+
export const SVELTE_LIVE_ROOT_COMPONENT = 'src/lib/impeccable/ImpeccableLiveRoot.svelte';
export const SVELTE_LAYOUT_MARKER_OPEN = '';
export const SVELTE_LAYOUT_MARKER_CLOSE = '';
@@ -45,11 +47,17 @@ export function detectSvelteKitProject(cwd = process.cwd(), config = null) {
&& fileIncludes(path.join(cwd, appHtml), '%sveltekit.head%');
if (!hasTemplateMarkers) return null;
- const hasSvelteConfig = fs.existsSync(path.join(cwd, 'svelte.config.js'))
- || fs.existsSync(path.join(cwd, 'svelte.config.mjs'))
- || fs.existsSync(path.join(cwd, 'svelte.config.cjs'))
- || fs.existsSync(path.join(cwd, 'svelte.config.ts'));
- const hasKitPackage = packageHasSvelteKit(cwd);
+ const hasSvelteConfig = Boolean(firstExistingFile(cwd, [
+ 'svelte.config.js',
+ 'svelte.config.mjs',
+ 'svelte.config.cjs',
+ 'svelte.config.ts',
+ ]));
+ const hasKitPackage = hasAnyDependency(cwd, [
+ '@sveltejs/kit',
+ '@sveltejs/vite-plugin-svelte',
+ 'svelte',
+ ]);
if (!hasSvelteConfig && !hasKitPackage) return null;
return {
@@ -260,36 +268,16 @@ function findSvelteKitAppHtml(cwd, config) {
}
function findSvelteKitLayout(cwd) {
- const candidates = [
+ return firstExistingFile(cwd, [
'src/routes/+layout.svelte',
'src/routes/(app)/+layout.svelte',
- ];
- for (const rel of candidates) {
- if (fs.existsSync(path.join(cwd, rel))) return rel;
- }
- return 'src/routes/+layout.svelte';
+ ]) || 'src/routes/+layout.svelte';
}
function defaultSvelteLayout() {
return `\n\n{@render children?.()}\n`;
}
-function packageHasSvelteKit(cwd) {
- const file = path.join(cwd, 'package.json');
- if (!fs.existsSync(file)) return false;
- try {
- const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
- const deps = {
- ...(pkg.dependencies || {}),
- ...(pkg.devDependencies || {}),
- ...(pkg.peerDependencies || {}),
- };
- return Boolean(deps['@sveltejs/kit'] || deps['@sveltejs/vite-plugin-svelte'] || deps.svelte);
- } catch {
- return false;
- }
-}
-
function fileIncludes(file, text) {
try {
return fs.readFileSync(file, 'utf-8').includes(text);
diff --git a/.rovodev/skills/impeccable/scripts/live/tanstack-adapter.mjs b/.rovodev/skills/impeccable/scripts/live/tanstack-adapter.mjs
index 4a1c81a97..b53978f4f 100644
--- a/.rovodev/skills/impeccable/scripts/live/tanstack-adapter.mjs
+++ b/.rovodev/skills/impeccable/scripts/live/tanstack-adapter.mjs
@@ -19,6 +19,8 @@
import fs from 'node:fs';
import path from 'node:path';
+
+import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs';
import { buildLiveScriptSrc } from './frameworks/script-src.mjs';
export const TANSTACK_MARKER_OPEN = '{/* impeccable-live-tanstack-start */}';
@@ -42,8 +44,8 @@ const START_PACKAGES = [
];
export function detectTanStackStartProject(cwd = process.cwd()) {
- if (!packageHasTanStackStart(cwd)) return null;
- const rootRoute = findRootRouteFile(cwd);
+ if (!hasAnyDependency(cwd, START_PACKAGES)) return null;
+ const rootRoute = firstExistingFile(cwd, ROOT_ROUTE_CANDIDATES);
if (!rootRoute) return null;
const ext = path.extname(rootRoute);
@@ -218,29 +220,6 @@ function isManagedComponent(content) {
return String(content || '').includes('impeccable-live-tanstack');
}
-function findRootRouteFile(cwd) {
- for (const rel of ROOT_ROUTE_CANDIDATES) {
- if (fs.existsSync(path.join(cwd, rel))) return rel;
- }
- return null;
-}
-
-function packageHasTanStackStart(cwd) {
- const file = path.join(cwd, 'package.json');
- if (!fs.existsSync(file)) return false;
- try {
- const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
- const deps = {
- ...(pkg.dependencies || {}),
- ...(pkg.devDependencies || {}),
- ...(pkg.peerDependencies || {}),
- };
- return START_PACKAGES.some((name) => Boolean(deps[name]));
- } catch {
- return false;
- }
-}
-
function relativeImportSpecifier(fromFile, toFile) {
const rel = path.posix.relative(
path.posix.dirname(fromFile.split(path.sep).join('/')),
diff --git a/.trae-cn/skills/impeccable/scripts/live-poll.mjs b/.trae-cn/skills/impeccable/scripts/live-poll.mjs
index 3b2f08c9f..59e21b9d3 100644
--- a/.trae-cn/skills/impeccable/scripts/live-poll.mjs
+++ b/.trae-cn/skills/impeccable/scripts/live-poll.mjs
@@ -238,10 +238,9 @@ export async function completeAcceptHandling(event, base, token) {
});
} catch (err) {
event._completionAck = { ok: false, error: err.message };
+ return event;
}
- if (!event._completionAck) {
- event._completionAck = completionAckForAcceptResult(event.id, completionType, event._acceptResult);
- }
+ event._completionAck = completionAckForAcceptResult(event.id, completionType, event._acceptResult);
return event;
}
@@ -269,9 +268,11 @@ export function printPollEvent(event) {
// Situational plumbing rides with the event itself: `_instructions` is the
// authoritative next step, with real ids and paths substituted, so the
// reference doc can stay lean and can never drift from script behavior.
- if (event && typeof event === 'object' && !event._instructions) {
+ // A wire-supplied value must never win over the locally generated one.
+ if (event && typeof event === 'object') {
const instructions = instructionsForEvent(event, { scriptsPath: SELF_DIR });
if (instructions) event._instructions = instructions;
+ else delete event._instructions;
}
console.log(JSON.stringify(event));
}
diff --git a/.trae-cn/skills/impeccable/scripts/live-server.mjs b/.trae-cn/skills/impeccable/scripts/live-server.mjs
index cba3a222e..dafa8bd0c 100644
--- a/.trae-cn/skills/impeccable/scripts/live-server.mjs
+++ b/.trae-cn/skills/impeccable/scripts/live-server.mjs
@@ -181,8 +181,16 @@ function chatAgentLikelyActive() {
// cap at 10 MB to guard against runaway writes from a misbehaving client.
const MAX_ANNOTATION_BYTES = 10 * 1024 * 1024;
+const POLLER_OWNED_EVENT_FIELDS = ['_instructions', '_completionAck', '_acceptResult'];
+
+function stripPollerOwnedEventFields(event) {
+ if (!event || typeof event !== 'object') return;
+ for (const key of POLLER_OWNED_EVENT_FIELDS) delete event[key];
+}
+
function enqueueEvent(event) {
if (!event) return;
+ stripPollerOwnedEventFields(event);
// Dedupe by (session, type), except mount failures, which are per-variant:
// variant 2 failing must not be swallowed because variant 1's failure is
// still queued.
@@ -1034,6 +1042,7 @@ function createRequestHandler({ detectScript, liveScriptParts }) {
res.end(JSON.stringify({ error }));
return;
}
+ stripPollerOwnedEventFields(msg);
if (msg.type === 'agent_phase') {
recordAgentPhase(msg.id, msg.phase, {
...(Number.isFinite(msg.durationMs) ? { durationMs: msg.durationMs } : {}),
diff --git a/.trae-cn/skills/impeccable/scripts/live/sveltekit-adapter.mjs b/.trae-cn/skills/impeccable/scripts/live/sveltekit-adapter.mjs
index e94c54f1e..b96e955a6 100644
--- a/.trae-cn/skills/impeccable/scripts/live/sveltekit-adapter.mjs
+++ b/.trae-cn/skills/impeccable/scripts/live/sveltekit-adapter.mjs
@@ -11,6 +11,8 @@ import crypto from 'node:crypto';
import fs from 'node:fs';
import path from 'node:path';
+import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs';
+
export const SVELTE_LIVE_ROOT_COMPONENT = 'src/lib/impeccable/ImpeccableLiveRoot.svelte';
export const SVELTE_LAYOUT_MARKER_OPEN = '';
export const SVELTE_LAYOUT_MARKER_CLOSE = '';
@@ -45,11 +47,17 @@ export function detectSvelteKitProject(cwd = process.cwd(), config = null) {
&& fileIncludes(path.join(cwd, appHtml), '%sveltekit.head%');
if (!hasTemplateMarkers) return null;
- const hasSvelteConfig = fs.existsSync(path.join(cwd, 'svelte.config.js'))
- || fs.existsSync(path.join(cwd, 'svelte.config.mjs'))
- || fs.existsSync(path.join(cwd, 'svelte.config.cjs'))
- || fs.existsSync(path.join(cwd, 'svelte.config.ts'));
- const hasKitPackage = packageHasSvelteKit(cwd);
+ const hasSvelteConfig = Boolean(firstExistingFile(cwd, [
+ 'svelte.config.js',
+ 'svelte.config.mjs',
+ 'svelte.config.cjs',
+ 'svelte.config.ts',
+ ]));
+ const hasKitPackage = hasAnyDependency(cwd, [
+ '@sveltejs/kit',
+ '@sveltejs/vite-plugin-svelte',
+ 'svelte',
+ ]);
if (!hasSvelteConfig && !hasKitPackage) return null;
return {
@@ -260,36 +268,16 @@ function findSvelteKitAppHtml(cwd, config) {
}
function findSvelteKitLayout(cwd) {
- const candidates = [
+ return firstExistingFile(cwd, [
'src/routes/+layout.svelte',
'src/routes/(app)/+layout.svelte',
- ];
- for (const rel of candidates) {
- if (fs.existsSync(path.join(cwd, rel))) return rel;
- }
- return 'src/routes/+layout.svelte';
+ ]) || 'src/routes/+layout.svelte';
}
function defaultSvelteLayout() {
return `\n\n{@render children?.()}\n`;
}
-function packageHasSvelteKit(cwd) {
- const file = path.join(cwd, 'package.json');
- if (!fs.existsSync(file)) return false;
- try {
- const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
- const deps = {
- ...(pkg.dependencies || {}),
- ...(pkg.devDependencies || {}),
- ...(pkg.peerDependencies || {}),
- };
- return Boolean(deps['@sveltejs/kit'] || deps['@sveltejs/vite-plugin-svelte'] || deps.svelte);
- } catch {
- return false;
- }
-}
-
function fileIncludes(file, text) {
try {
return fs.readFileSync(file, 'utf-8').includes(text);
diff --git a/.trae-cn/skills/impeccable/scripts/live/tanstack-adapter.mjs b/.trae-cn/skills/impeccable/scripts/live/tanstack-adapter.mjs
index 4a1c81a97..b53978f4f 100644
--- a/.trae-cn/skills/impeccable/scripts/live/tanstack-adapter.mjs
+++ b/.trae-cn/skills/impeccable/scripts/live/tanstack-adapter.mjs
@@ -19,6 +19,8 @@
import fs from 'node:fs';
import path from 'node:path';
+
+import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs';
import { buildLiveScriptSrc } from './frameworks/script-src.mjs';
export const TANSTACK_MARKER_OPEN = '{/* impeccable-live-tanstack-start */}';
@@ -42,8 +44,8 @@ const START_PACKAGES = [
];
export function detectTanStackStartProject(cwd = process.cwd()) {
- if (!packageHasTanStackStart(cwd)) return null;
- const rootRoute = findRootRouteFile(cwd);
+ if (!hasAnyDependency(cwd, START_PACKAGES)) return null;
+ const rootRoute = firstExistingFile(cwd, ROOT_ROUTE_CANDIDATES);
if (!rootRoute) return null;
const ext = path.extname(rootRoute);
@@ -218,29 +220,6 @@ function isManagedComponent(content) {
return String(content || '').includes('impeccable-live-tanstack');
}
-function findRootRouteFile(cwd) {
- for (const rel of ROOT_ROUTE_CANDIDATES) {
- if (fs.existsSync(path.join(cwd, rel))) return rel;
- }
- return null;
-}
-
-function packageHasTanStackStart(cwd) {
- const file = path.join(cwd, 'package.json');
- if (!fs.existsSync(file)) return false;
- try {
- const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
- const deps = {
- ...(pkg.dependencies || {}),
- ...(pkg.devDependencies || {}),
- ...(pkg.peerDependencies || {}),
- };
- return START_PACKAGES.some((name) => Boolean(deps[name]));
- } catch {
- return false;
- }
-}
-
function relativeImportSpecifier(fromFile, toFile) {
const rel = path.posix.relative(
path.posix.dirname(fromFile.split(path.sep).join('/')),
diff --git a/.trae/skills/impeccable/scripts/live-poll.mjs b/.trae/skills/impeccable/scripts/live-poll.mjs
index 3b2f08c9f..59e21b9d3 100644
--- a/.trae/skills/impeccable/scripts/live-poll.mjs
+++ b/.trae/skills/impeccable/scripts/live-poll.mjs
@@ -238,10 +238,9 @@ export async function completeAcceptHandling(event, base, token) {
});
} catch (err) {
event._completionAck = { ok: false, error: err.message };
+ return event;
}
- if (!event._completionAck) {
- event._completionAck = completionAckForAcceptResult(event.id, completionType, event._acceptResult);
- }
+ event._completionAck = completionAckForAcceptResult(event.id, completionType, event._acceptResult);
return event;
}
@@ -269,9 +268,11 @@ export function printPollEvent(event) {
// Situational plumbing rides with the event itself: `_instructions` is the
// authoritative next step, with real ids and paths substituted, so the
// reference doc can stay lean and can never drift from script behavior.
- if (event && typeof event === 'object' && !event._instructions) {
+ // A wire-supplied value must never win over the locally generated one.
+ if (event && typeof event === 'object') {
const instructions = instructionsForEvent(event, { scriptsPath: SELF_DIR });
if (instructions) event._instructions = instructions;
+ else delete event._instructions;
}
console.log(JSON.stringify(event));
}
diff --git a/.trae/skills/impeccable/scripts/live-server.mjs b/.trae/skills/impeccable/scripts/live-server.mjs
index cba3a222e..dafa8bd0c 100644
--- a/.trae/skills/impeccable/scripts/live-server.mjs
+++ b/.trae/skills/impeccable/scripts/live-server.mjs
@@ -181,8 +181,16 @@ function chatAgentLikelyActive() {
// cap at 10 MB to guard against runaway writes from a misbehaving client.
const MAX_ANNOTATION_BYTES = 10 * 1024 * 1024;
+const POLLER_OWNED_EVENT_FIELDS = ['_instructions', '_completionAck', '_acceptResult'];
+
+function stripPollerOwnedEventFields(event) {
+ if (!event || typeof event !== 'object') return;
+ for (const key of POLLER_OWNED_EVENT_FIELDS) delete event[key];
+}
+
function enqueueEvent(event) {
if (!event) return;
+ stripPollerOwnedEventFields(event);
// Dedupe by (session, type), except mount failures, which are per-variant:
// variant 2 failing must not be swallowed because variant 1's failure is
// still queued.
@@ -1034,6 +1042,7 @@ function createRequestHandler({ detectScript, liveScriptParts }) {
res.end(JSON.stringify({ error }));
return;
}
+ stripPollerOwnedEventFields(msg);
if (msg.type === 'agent_phase') {
recordAgentPhase(msg.id, msg.phase, {
...(Number.isFinite(msg.durationMs) ? { durationMs: msg.durationMs } : {}),
diff --git a/.trae/skills/impeccable/scripts/live/sveltekit-adapter.mjs b/.trae/skills/impeccable/scripts/live/sveltekit-adapter.mjs
index e94c54f1e..b96e955a6 100644
--- a/.trae/skills/impeccable/scripts/live/sveltekit-adapter.mjs
+++ b/.trae/skills/impeccable/scripts/live/sveltekit-adapter.mjs
@@ -11,6 +11,8 @@ import crypto from 'node:crypto';
import fs from 'node:fs';
import path from 'node:path';
+import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs';
+
export const SVELTE_LIVE_ROOT_COMPONENT = 'src/lib/impeccable/ImpeccableLiveRoot.svelte';
export const SVELTE_LAYOUT_MARKER_OPEN = '';
export const SVELTE_LAYOUT_MARKER_CLOSE = '';
@@ -45,11 +47,17 @@ export function detectSvelteKitProject(cwd = process.cwd(), config = null) {
&& fileIncludes(path.join(cwd, appHtml), '%sveltekit.head%');
if (!hasTemplateMarkers) return null;
- const hasSvelteConfig = fs.existsSync(path.join(cwd, 'svelte.config.js'))
- || fs.existsSync(path.join(cwd, 'svelte.config.mjs'))
- || fs.existsSync(path.join(cwd, 'svelte.config.cjs'))
- || fs.existsSync(path.join(cwd, 'svelte.config.ts'));
- const hasKitPackage = packageHasSvelteKit(cwd);
+ const hasSvelteConfig = Boolean(firstExistingFile(cwd, [
+ 'svelte.config.js',
+ 'svelte.config.mjs',
+ 'svelte.config.cjs',
+ 'svelte.config.ts',
+ ]));
+ const hasKitPackage = hasAnyDependency(cwd, [
+ '@sveltejs/kit',
+ '@sveltejs/vite-plugin-svelte',
+ 'svelte',
+ ]);
if (!hasSvelteConfig && !hasKitPackage) return null;
return {
@@ -260,36 +268,16 @@ function findSvelteKitAppHtml(cwd, config) {
}
function findSvelteKitLayout(cwd) {
- const candidates = [
+ return firstExistingFile(cwd, [
'src/routes/+layout.svelte',
'src/routes/(app)/+layout.svelte',
- ];
- for (const rel of candidates) {
- if (fs.existsSync(path.join(cwd, rel))) return rel;
- }
- return 'src/routes/+layout.svelte';
+ ]) || 'src/routes/+layout.svelte';
}
function defaultSvelteLayout() {
return `\n\n{@render children?.()}\n`;
}
-function packageHasSvelteKit(cwd) {
- const file = path.join(cwd, 'package.json');
- if (!fs.existsSync(file)) return false;
- try {
- const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
- const deps = {
- ...(pkg.dependencies || {}),
- ...(pkg.devDependencies || {}),
- ...(pkg.peerDependencies || {}),
- };
- return Boolean(deps['@sveltejs/kit'] || deps['@sveltejs/vite-plugin-svelte'] || deps.svelte);
- } catch {
- return false;
- }
-}
-
function fileIncludes(file, text) {
try {
return fs.readFileSync(file, 'utf-8').includes(text);
diff --git a/.trae/skills/impeccable/scripts/live/tanstack-adapter.mjs b/.trae/skills/impeccable/scripts/live/tanstack-adapter.mjs
index 4a1c81a97..b53978f4f 100644
--- a/.trae/skills/impeccable/scripts/live/tanstack-adapter.mjs
+++ b/.trae/skills/impeccable/scripts/live/tanstack-adapter.mjs
@@ -19,6 +19,8 @@
import fs from 'node:fs';
import path from 'node:path';
+
+import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs';
import { buildLiveScriptSrc } from './frameworks/script-src.mjs';
export const TANSTACK_MARKER_OPEN = '{/* impeccable-live-tanstack-start */}';
@@ -42,8 +44,8 @@ const START_PACKAGES = [
];
export function detectTanStackStartProject(cwd = process.cwd()) {
- if (!packageHasTanStackStart(cwd)) return null;
- const rootRoute = findRootRouteFile(cwd);
+ if (!hasAnyDependency(cwd, START_PACKAGES)) return null;
+ const rootRoute = firstExistingFile(cwd, ROOT_ROUTE_CANDIDATES);
if (!rootRoute) return null;
const ext = path.extname(rootRoute);
@@ -218,29 +220,6 @@ function isManagedComponent(content) {
return String(content || '').includes('impeccable-live-tanstack');
}
-function findRootRouteFile(cwd) {
- for (const rel of ROOT_ROUTE_CANDIDATES) {
- if (fs.existsSync(path.join(cwd, rel))) return rel;
- }
- return null;
-}
-
-function packageHasTanStackStart(cwd) {
- const file = path.join(cwd, 'package.json');
- if (!fs.existsSync(file)) return false;
- try {
- const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
- const deps = {
- ...(pkg.dependencies || {}),
- ...(pkg.devDependencies || {}),
- ...(pkg.peerDependencies || {}),
- };
- return START_PACKAGES.some((name) => Boolean(deps[name]));
- } catch {
- return false;
- }
-}
-
function relativeImportSpecifier(fromFile, toFile) {
const rel = path.posix.relative(
path.posix.dirname(fromFile.split(path.sep).join('/')),
diff --git a/.vibe/skills/impeccable/scripts/live-poll.mjs b/.vibe/skills/impeccable/scripts/live-poll.mjs
index 3b2f08c9f..59e21b9d3 100644
--- a/.vibe/skills/impeccable/scripts/live-poll.mjs
+++ b/.vibe/skills/impeccable/scripts/live-poll.mjs
@@ -238,10 +238,9 @@ export async function completeAcceptHandling(event, base, token) {
});
} catch (err) {
event._completionAck = { ok: false, error: err.message };
+ return event;
}
- if (!event._completionAck) {
- event._completionAck = completionAckForAcceptResult(event.id, completionType, event._acceptResult);
- }
+ event._completionAck = completionAckForAcceptResult(event.id, completionType, event._acceptResult);
return event;
}
@@ -269,9 +268,11 @@ export function printPollEvent(event) {
// Situational plumbing rides with the event itself: `_instructions` is the
// authoritative next step, with real ids and paths substituted, so the
// reference doc can stay lean and can never drift from script behavior.
- if (event && typeof event === 'object' && !event._instructions) {
+ // A wire-supplied value must never win over the locally generated one.
+ if (event && typeof event === 'object') {
const instructions = instructionsForEvent(event, { scriptsPath: SELF_DIR });
if (instructions) event._instructions = instructions;
+ else delete event._instructions;
}
console.log(JSON.stringify(event));
}
diff --git a/.vibe/skills/impeccable/scripts/live-server.mjs b/.vibe/skills/impeccable/scripts/live-server.mjs
index cba3a222e..dafa8bd0c 100644
--- a/.vibe/skills/impeccable/scripts/live-server.mjs
+++ b/.vibe/skills/impeccable/scripts/live-server.mjs
@@ -181,8 +181,16 @@ function chatAgentLikelyActive() {
// cap at 10 MB to guard against runaway writes from a misbehaving client.
const MAX_ANNOTATION_BYTES = 10 * 1024 * 1024;
+const POLLER_OWNED_EVENT_FIELDS = ['_instructions', '_completionAck', '_acceptResult'];
+
+function stripPollerOwnedEventFields(event) {
+ if (!event || typeof event !== 'object') return;
+ for (const key of POLLER_OWNED_EVENT_FIELDS) delete event[key];
+}
+
function enqueueEvent(event) {
if (!event) return;
+ stripPollerOwnedEventFields(event);
// Dedupe by (session, type), except mount failures, which are per-variant:
// variant 2 failing must not be swallowed because variant 1's failure is
// still queued.
@@ -1034,6 +1042,7 @@ function createRequestHandler({ detectScript, liveScriptParts }) {
res.end(JSON.stringify({ error }));
return;
}
+ stripPollerOwnedEventFields(msg);
if (msg.type === 'agent_phase') {
recordAgentPhase(msg.id, msg.phase, {
...(Number.isFinite(msg.durationMs) ? { durationMs: msg.durationMs } : {}),
diff --git a/.vibe/skills/impeccable/scripts/live/sveltekit-adapter.mjs b/.vibe/skills/impeccable/scripts/live/sveltekit-adapter.mjs
index e94c54f1e..b96e955a6 100644
--- a/.vibe/skills/impeccable/scripts/live/sveltekit-adapter.mjs
+++ b/.vibe/skills/impeccable/scripts/live/sveltekit-adapter.mjs
@@ -11,6 +11,8 @@ import crypto from 'node:crypto';
import fs from 'node:fs';
import path from 'node:path';
+import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs';
+
export const SVELTE_LIVE_ROOT_COMPONENT = 'src/lib/impeccable/ImpeccableLiveRoot.svelte';
export const SVELTE_LAYOUT_MARKER_OPEN = '';
export const SVELTE_LAYOUT_MARKER_CLOSE = '';
@@ -45,11 +47,17 @@ export function detectSvelteKitProject(cwd = process.cwd(), config = null) {
&& fileIncludes(path.join(cwd, appHtml), '%sveltekit.head%');
if (!hasTemplateMarkers) return null;
- const hasSvelteConfig = fs.existsSync(path.join(cwd, 'svelte.config.js'))
- || fs.existsSync(path.join(cwd, 'svelte.config.mjs'))
- || fs.existsSync(path.join(cwd, 'svelte.config.cjs'))
- || fs.existsSync(path.join(cwd, 'svelte.config.ts'));
- const hasKitPackage = packageHasSvelteKit(cwd);
+ const hasSvelteConfig = Boolean(firstExistingFile(cwd, [
+ 'svelte.config.js',
+ 'svelte.config.mjs',
+ 'svelte.config.cjs',
+ 'svelte.config.ts',
+ ]));
+ const hasKitPackage = hasAnyDependency(cwd, [
+ '@sveltejs/kit',
+ '@sveltejs/vite-plugin-svelte',
+ 'svelte',
+ ]);
if (!hasSvelteConfig && !hasKitPackage) return null;
return {
@@ -260,36 +268,16 @@ function findSvelteKitAppHtml(cwd, config) {
}
function findSvelteKitLayout(cwd) {
- const candidates = [
+ return firstExistingFile(cwd, [
'src/routes/+layout.svelte',
'src/routes/(app)/+layout.svelte',
- ];
- for (const rel of candidates) {
- if (fs.existsSync(path.join(cwd, rel))) return rel;
- }
- return 'src/routes/+layout.svelte';
+ ]) || 'src/routes/+layout.svelte';
}
function defaultSvelteLayout() {
return `\n\n{@render children?.()}\n`;
}
-function packageHasSvelteKit(cwd) {
- const file = path.join(cwd, 'package.json');
- if (!fs.existsSync(file)) return false;
- try {
- const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
- const deps = {
- ...(pkg.dependencies || {}),
- ...(pkg.devDependencies || {}),
- ...(pkg.peerDependencies || {}),
- };
- return Boolean(deps['@sveltejs/kit'] || deps['@sveltejs/vite-plugin-svelte'] || deps.svelte);
- } catch {
- return false;
- }
-}
-
function fileIncludes(file, text) {
try {
return fs.readFileSync(file, 'utf-8').includes(text);
diff --git a/.vibe/skills/impeccable/scripts/live/tanstack-adapter.mjs b/.vibe/skills/impeccable/scripts/live/tanstack-adapter.mjs
index 4a1c81a97..b53978f4f 100644
--- a/.vibe/skills/impeccable/scripts/live/tanstack-adapter.mjs
+++ b/.vibe/skills/impeccable/scripts/live/tanstack-adapter.mjs
@@ -19,6 +19,8 @@
import fs from 'node:fs';
import path from 'node:path';
+
+import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs';
import { buildLiveScriptSrc } from './frameworks/script-src.mjs';
export const TANSTACK_MARKER_OPEN = '{/* impeccable-live-tanstack-start */}';
@@ -42,8 +44,8 @@ const START_PACKAGES = [
];
export function detectTanStackStartProject(cwd = process.cwd()) {
- if (!packageHasTanStackStart(cwd)) return null;
- const rootRoute = findRootRouteFile(cwd);
+ if (!hasAnyDependency(cwd, START_PACKAGES)) return null;
+ const rootRoute = firstExistingFile(cwd, ROOT_ROUTE_CANDIDATES);
if (!rootRoute) return null;
const ext = path.extname(rootRoute);
@@ -218,29 +220,6 @@ function isManagedComponent(content) {
return String(content || '').includes('impeccable-live-tanstack');
}
-function findRootRouteFile(cwd) {
- for (const rel of ROOT_ROUTE_CANDIDATES) {
- if (fs.existsSync(path.join(cwd, rel))) return rel;
- }
- return null;
-}
-
-function packageHasTanStackStart(cwd) {
- const file = path.join(cwd, 'package.json');
- if (!fs.existsSync(file)) return false;
- try {
- const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
- const deps = {
- ...(pkg.dependencies || {}),
- ...(pkg.devDependencies || {}),
- ...(pkg.peerDependencies || {}),
- };
- return START_PACKAGES.some((name) => Boolean(deps[name]));
- } catch {
- return false;
- }
-}
-
function relativeImportSpecifier(fromFile, toFile) {
const rel = path.posix.relative(
path.posix.dirname(fromFile.split(path.sep).join('/')),
diff --git a/plugin/skills/impeccable/scripts/live-poll.mjs b/plugin/skills/impeccable/scripts/live-poll.mjs
index 3b2f08c9f..59e21b9d3 100644
--- a/plugin/skills/impeccable/scripts/live-poll.mjs
+++ b/plugin/skills/impeccable/scripts/live-poll.mjs
@@ -238,10 +238,9 @@ export async function completeAcceptHandling(event, base, token) {
});
} catch (err) {
event._completionAck = { ok: false, error: err.message };
+ return event;
}
- if (!event._completionAck) {
- event._completionAck = completionAckForAcceptResult(event.id, completionType, event._acceptResult);
- }
+ event._completionAck = completionAckForAcceptResult(event.id, completionType, event._acceptResult);
return event;
}
@@ -269,9 +268,11 @@ export function printPollEvent(event) {
// Situational plumbing rides with the event itself: `_instructions` is the
// authoritative next step, with real ids and paths substituted, so the
// reference doc can stay lean and can never drift from script behavior.
- if (event && typeof event === 'object' && !event._instructions) {
+ // A wire-supplied value must never win over the locally generated one.
+ if (event && typeof event === 'object') {
const instructions = instructionsForEvent(event, { scriptsPath: SELF_DIR });
if (instructions) event._instructions = instructions;
+ else delete event._instructions;
}
console.log(JSON.stringify(event));
}
diff --git a/plugin/skills/impeccable/scripts/live-server.mjs b/plugin/skills/impeccable/scripts/live-server.mjs
index cba3a222e..dafa8bd0c 100644
--- a/plugin/skills/impeccable/scripts/live-server.mjs
+++ b/plugin/skills/impeccable/scripts/live-server.mjs
@@ -181,8 +181,16 @@ function chatAgentLikelyActive() {
// cap at 10 MB to guard against runaway writes from a misbehaving client.
const MAX_ANNOTATION_BYTES = 10 * 1024 * 1024;
+const POLLER_OWNED_EVENT_FIELDS = ['_instructions', '_completionAck', '_acceptResult'];
+
+function stripPollerOwnedEventFields(event) {
+ if (!event || typeof event !== 'object') return;
+ for (const key of POLLER_OWNED_EVENT_FIELDS) delete event[key];
+}
+
function enqueueEvent(event) {
if (!event) return;
+ stripPollerOwnedEventFields(event);
// Dedupe by (session, type), except mount failures, which are per-variant:
// variant 2 failing must not be swallowed because variant 1's failure is
// still queued.
@@ -1034,6 +1042,7 @@ function createRequestHandler({ detectScript, liveScriptParts }) {
res.end(JSON.stringify({ error }));
return;
}
+ stripPollerOwnedEventFields(msg);
if (msg.type === 'agent_phase') {
recordAgentPhase(msg.id, msg.phase, {
...(Number.isFinite(msg.durationMs) ? { durationMs: msg.durationMs } : {}),
diff --git a/plugin/skills/impeccable/scripts/live/sveltekit-adapter.mjs b/plugin/skills/impeccable/scripts/live/sveltekit-adapter.mjs
index e94c54f1e..b96e955a6 100644
--- a/plugin/skills/impeccable/scripts/live/sveltekit-adapter.mjs
+++ b/plugin/skills/impeccable/scripts/live/sveltekit-adapter.mjs
@@ -11,6 +11,8 @@ import crypto from 'node:crypto';
import fs from 'node:fs';
import path from 'node:path';
+import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs';
+
export const SVELTE_LIVE_ROOT_COMPONENT = 'src/lib/impeccable/ImpeccableLiveRoot.svelte';
export const SVELTE_LAYOUT_MARKER_OPEN = '';
export const SVELTE_LAYOUT_MARKER_CLOSE = '';
@@ -45,11 +47,17 @@ export function detectSvelteKitProject(cwd = process.cwd(), config = null) {
&& fileIncludes(path.join(cwd, appHtml), '%sveltekit.head%');
if (!hasTemplateMarkers) return null;
- const hasSvelteConfig = fs.existsSync(path.join(cwd, 'svelte.config.js'))
- || fs.existsSync(path.join(cwd, 'svelte.config.mjs'))
- || fs.existsSync(path.join(cwd, 'svelte.config.cjs'))
- || fs.existsSync(path.join(cwd, 'svelte.config.ts'));
- const hasKitPackage = packageHasSvelteKit(cwd);
+ const hasSvelteConfig = Boolean(firstExistingFile(cwd, [
+ 'svelte.config.js',
+ 'svelte.config.mjs',
+ 'svelte.config.cjs',
+ 'svelte.config.ts',
+ ]));
+ const hasKitPackage = hasAnyDependency(cwd, [
+ '@sveltejs/kit',
+ '@sveltejs/vite-plugin-svelte',
+ 'svelte',
+ ]);
if (!hasSvelteConfig && !hasKitPackage) return null;
return {
@@ -260,36 +268,16 @@ function findSvelteKitAppHtml(cwd, config) {
}
function findSvelteKitLayout(cwd) {
- const candidates = [
+ return firstExistingFile(cwd, [
'src/routes/+layout.svelte',
'src/routes/(app)/+layout.svelte',
- ];
- for (const rel of candidates) {
- if (fs.existsSync(path.join(cwd, rel))) return rel;
- }
- return 'src/routes/+layout.svelte';
+ ]) || 'src/routes/+layout.svelte';
}
function defaultSvelteLayout() {
return `\n\n{@render children?.()}\n`;
}
-function packageHasSvelteKit(cwd) {
- const file = path.join(cwd, 'package.json');
- if (!fs.existsSync(file)) return false;
- try {
- const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
- const deps = {
- ...(pkg.dependencies || {}),
- ...(pkg.devDependencies || {}),
- ...(pkg.peerDependencies || {}),
- };
- return Boolean(deps['@sveltejs/kit'] || deps['@sveltejs/vite-plugin-svelte'] || deps.svelte);
- } catch {
- return false;
- }
-}
-
function fileIncludes(file, text) {
try {
return fs.readFileSync(file, 'utf-8').includes(text);
diff --git a/plugin/skills/impeccable/scripts/live/tanstack-adapter.mjs b/plugin/skills/impeccable/scripts/live/tanstack-adapter.mjs
index 4a1c81a97..b53978f4f 100644
--- a/plugin/skills/impeccable/scripts/live/tanstack-adapter.mjs
+++ b/plugin/skills/impeccable/scripts/live/tanstack-adapter.mjs
@@ -19,6 +19,8 @@
import fs from 'node:fs';
import path from 'node:path';
+
+import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs';
import { buildLiveScriptSrc } from './frameworks/script-src.mjs';
export const TANSTACK_MARKER_OPEN = '{/* impeccable-live-tanstack-start */}';
@@ -42,8 +44,8 @@ const START_PACKAGES = [
];
export function detectTanStackStartProject(cwd = process.cwd()) {
- if (!packageHasTanStackStart(cwd)) return null;
- const rootRoute = findRootRouteFile(cwd);
+ if (!hasAnyDependency(cwd, START_PACKAGES)) return null;
+ const rootRoute = firstExistingFile(cwd, ROOT_ROUTE_CANDIDATES);
if (!rootRoute) return null;
const ext = path.extname(rootRoute);
@@ -218,29 +220,6 @@ function isManagedComponent(content) {
return String(content || '').includes('impeccable-live-tanstack');
}
-function findRootRouteFile(cwd) {
- for (const rel of ROOT_ROUTE_CANDIDATES) {
- if (fs.existsSync(path.join(cwd, rel))) return rel;
- }
- return null;
-}
-
-function packageHasTanStackStart(cwd) {
- const file = path.join(cwd, 'package.json');
- if (!fs.existsSync(file)) return false;
- try {
- const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
- const deps = {
- ...(pkg.dependencies || {}),
- ...(pkg.devDependencies || {}),
- ...(pkg.peerDependencies || {}),
- };
- return START_PACKAGES.some((name) => Boolean(deps[name]));
- } catch {
- return false;
- }
-}
-
function relativeImportSpecifier(fromFile, toFile) {
const rel = path.posix.relative(
path.posix.dirname(fromFile.split(path.sep).join('/')),