mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-11 21:57:14 +03:00
Organize skill script support modules
This commit is contained in:
@@ -46,7 +46,7 @@ Use ESM, semicolons, and the existing two-space indentation style in JS, HTML, a
|
||||
|
||||
Tests use Bun’s test runner plus Node’s built-in `--test`. Name tests `*.test.js` or `*.test.mjs` and place new fixtures near the behavior they cover, usually under `tests/fixtures/`. Prefer targeted test runs while iterating, then finish with `bun run test`. If you change generated outputs or provider transforms, verify both source parsing and at least one affected provider path in `dist/`.
|
||||
|
||||
For changes to `skill/scripts/live-*.{mjs,js}`, also run `bun run test:live-e2e` (kept out of the default suite because it does real `npm install` per fixture and boots framework dev servers). Scope to one fixture with `IMPECCABLE_E2E_ONLY=<fixture-name>` while iterating; pass `IMPECCABLE_E2E_DEBUG=1` for page-DOM and dev-server-log dumps on failure. Schema and authoring guide for new fixtures live in `tests/framework-fixtures/README.md`.
|
||||
For changes to `skill/scripts/live-*.{mjs,js}` or `skill/scripts/live/**`, also run `bun run test:live-e2e` (kept out of the default suite because it does real `npm install` per fixture and boots framework dev servers). Scope to one fixture with `IMPECCABLE_E2E_ONLY=<fixture-name>` while iterating; pass `IMPECCABLE_E2E_DEBUG=1` for page-DOM and dev-server-log dumps on failure. Schema and authoring guide for new fixtures live in `tests/framework-fixtures/README.md`.
|
||||
|
||||
Set `IMPECCABLE_E2E_AGENT=llm` to swap the deterministic fake agent for an API-backed one (`tests/live-e2e/agents/llm-agent.mjs`). Claude Haiku 4.5 is the primary path whenever `ANTHROPIC_API_KEY` is set. DeepSeek V4 Flash is the secondary cheap fallback when only `DEEPSEEK_API_KEY` is set, and can be forced with `IMPECCABLE_E2E_LLM_PROVIDER=deepseek` or `bun run test:live-e2e -- --llm-provider=deepseek`; override either model via `IMPECCABLE_E2E_LLM_MODEL` or `--llm-model=<model>`. Tests skip cleanly when the selected provider key is unset. This path hits the API — use it for verification, not CI.
|
||||
|
||||
|
||||
@@ -159,7 +159,7 @@ IMPECCABLE_E2E_DEBUG=1 bun run test:live-e2e # dump page DOM + de
|
||||
|
||||
**One-time setup**: `npx playwright install chromium` (the suite uses a specific Chromium build keyed to the bundled Playwright version).
|
||||
|
||||
**Kept out of the default `bun run test`** because (a) it does real `npm install` per fixture, (b) it boots framework dev servers, (c) wall time is ~2 minutes, and (d) it requires Playwright's browser cache. Run it locally before shipping changes to anything in `skill/scripts/live-*.{mjs,js}`.
|
||||
**Kept out of the default `bun run test`** because (a) it does real `npm install` per fixture, (b) it boots framework dev servers, (c) wall time is ~2 minutes, and (d) it requires Playwright's browser cache. Run it locally before shipping changes to anything in `skill/scripts/live-*.{mjs,js}` or `skill/scripts/live/**`.
|
||||
|
||||
The agent is pluggable via a one-method interface in `tests/live-e2e/agent.mjs`: `generateVariants(event, context) → { scopedCss, variants[] }`. The default fake agent emits canned variants that exercise all three param kinds (`range`, `steps`, `toggle`). The orchestrator (wrap, write, accept, carbonize) is agent-agnostic.
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ export const SUITES = {
|
||||
description: 'Fast live-mode unit and local-server integration tests, excluding full browser fixture sweeps.',
|
||||
triggers: [
|
||||
...COMMON_INFRA_PATTERNS,
|
||||
/^skill\/(reference\/live\.md|scripts\/(detect-csp|is-generated|live|live-|modern-screenshot|pin|palette))/,
|
||||
/^skill\/(reference\/live\.md|scripts\/(detect-csp|lib\/is-generated|live\/|live|live-|modern-screenshot|pin|palette))/,
|
||||
/^tests\/live-/,
|
||||
/^tests\/live-e2e\/(agent|agents\/llm-agent|cli-options|preactions|session|steer|ui)\.mjs$/,
|
||||
/^tests\/live-e2e\/agent-insert\.test\.mjs$/,
|
||||
@@ -138,7 +138,9 @@ export const SUITES = {
|
||||
...COMMON_INFRA_PATTERNS,
|
||||
/^tests\/framework-fixtures/,
|
||||
/^tests\/framework-fixtures\.test\.mjs$/,
|
||||
/^skill\/scripts\/(detect-csp|is-generated|live-inject|live-sveltekit-adapter|live-wrap)\.mjs$/,
|
||||
/^skill\/scripts\/(detect-csp|live-inject|live-wrap)\.mjs$/,
|
||||
/^skill\/scripts\/lib\/is-generated\.mjs$/,
|
||||
/^skill\/scripts\/live\/sveltekit-adapter\.mjs$/,
|
||||
],
|
||||
commands: [
|
||||
{
|
||||
@@ -197,7 +199,8 @@ export const SUITES = {
|
||||
needsPlaywright: true,
|
||||
triggers: [
|
||||
...COMMON_INFRA_PATTERNS,
|
||||
/^skill\/scripts\/(live-accept|live-browser|live-server|live-sveltekit-adapter|live-wrap)\.mjs$/,
|
||||
/^skill\/scripts\/(live-accept|live-browser|live-server|live-wrap)\.mjs$/,
|
||||
/^skill\/scripts\/live\/sveltekit-adapter\.mjs$/,
|
||||
/^tests\/live-e2e-accept-cleanup-regression\.test\.mjs$/,
|
||||
/^tests\/live-e2e\//,
|
||||
],
|
||||
@@ -242,7 +245,8 @@ export const SUITES = {
|
||||
needsPlaywright: true,
|
||||
triggers: [
|
||||
...COMMON_INFRA_PATTERNS,
|
||||
/^skill\/scripts\/(live-sveltekit-adapter|live-svelte-component|live-server|live-wrap)\.mjs$/,
|
||||
/^skill\/scripts\/(live-server|live-wrap)\.mjs$/,
|
||||
/^skill\/scripts\/live\/(sveltekit-adapter|svelte-component)\.mjs$/,
|
||||
/^tests\/framework-fixtures\/vite8-sveltekit-stateful\//,
|
||||
/^tests\/live-svelte-adapter-deepseek\.test\.mjs$/,
|
||||
],
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
// lands on the `pick` verb.
|
||||
//
|
||||
// Values/labels/icons come from the same canonical source the real picker uses
|
||||
// (skill/scripts/live-vocabulary.mjs), imported at build time, so the demo and
|
||||
// (skill/scripts/live/vocabulary.mjs), imported at build time, so the demo and
|
||||
// the product never drift.
|
||||
import { LIVE_COMMANDS } from '../../skill/scripts/live-vocabulary.mjs';
|
||||
import { LIVE_COMMANDS } from '../../skill/scripts/live/vocabulary.mjs';
|
||||
|
||||
interface Props {
|
||||
pick: string;
|
||||
|
||||
@@ -22,7 +22,7 @@ import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { execFileSync } from 'node:child_process';
|
||||
import { loadContext, extractRegister } from './context.mjs';
|
||||
import { getCritiqueDir } from './impeccable-paths.mjs';
|
||||
import { getCritiqueDir } from './lib/impeccable-paths.mjs';
|
||||
|
||||
/** Is there code here at all, or just context files / an empty repo? */
|
||||
function hasCode(cwd) {
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath, pathToFileURL } from 'node:url';
|
||||
import { getCritiqueDir } from './impeccable-paths.mjs';
|
||||
import { getCritiqueDir } from './lib/impeccable-paths.mjs';
|
||||
|
||||
const SLUG_MAX = 50;
|
||||
|
||||
|
||||
@@ -15,14 +15,14 @@
|
||||
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { isGeneratedFile } from './is-generated.mjs';
|
||||
import { readBuffer as readManualEditsBuffer, writeBuffer as writeManualEditsBuffer } from './live-manual-edits-buffer.mjs';
|
||||
import { isGeneratedFile } from './lib/is-generated.mjs';
|
||||
import { readBuffer as readManualEditsBuffer, writeBuffer as writeManualEditsBuffer } from './live/manual-edits-buffer.mjs';
|
||||
import {
|
||||
applyDeferredSvelteComponentAccepts,
|
||||
findSvelteComponentManifest,
|
||||
inlineSvelteComponentAccept,
|
||||
removeSvelteComponentSession,
|
||||
} from './live-svelte-component.mjs';
|
||||
} from './live/svelte-component.mjs';
|
||||
|
||||
const EXTENSIONS = ['.html', '.jsx', '.tsx', '.vue', '.svelte', '.astro'];
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
]);
|
||||
|
||||
// Command vocabulary (values + labels + icons) comes from the canonical source,
|
||||
// skill/scripts/live-vocabulary.mjs, which live-server.mjs serializes into
|
||||
// skill/scripts/live/vocabulary.mjs, which live-server.mjs serializes into
|
||||
// window.__IMPECCABLE_VOCAB__ when it serves /live.js (same injection path as
|
||||
// the token/port above, so it is always present here). The icons stack above
|
||||
// each chip label and recolor to C.brand when selected (strokes use
|
||||
@@ -1216,7 +1216,7 @@
|
||||
: (focused ? BP.accentSoft : BP.hairline);
|
||||
}
|
||||
|
||||
// Insert mode helpers (mirrors skill/scripts/live-insert-ui.mjs)
|
||||
// Insert mode helpers (mirrors skill/scripts/live/insert-ui.mjs)
|
||||
|
||||
function detectInsertAxisFromStyle(style) {
|
||||
const display = style?.display || 'block';
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
*/
|
||||
|
||||
import { buildManualEditEvidence } from './live-manual-edit-evidence.mjs';
|
||||
import { readBuffer, readBufferStrict, writeBuffer, countByPage } from './live-manual-edits-buffer.mjs';
|
||||
import { isGeneratedFile } from './is-generated.mjs';
|
||||
import { readBuffer, readBufferStrict, writeBuffer, countByPage } from './live/manual-edits-buffer.mjs';
|
||||
import { isGeneratedFile } from './lib/is-generated.mjs';
|
||||
import {
|
||||
runCopyEditBatchAgent,
|
||||
runCopyEditPostApplyChecks,
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
* Canonical durable completion acknowledgement for Impeccable live sessions.
|
||||
*/
|
||||
|
||||
import { createLiveSessionStore } from './live-session-store.mjs';
|
||||
import { readLiveServerInfo } from './impeccable-paths.mjs';
|
||||
import { createLiveSessionStore } from './live/session-store.mjs';
|
||||
import { readLiveServerInfo } from './lib/impeccable-paths.mjs';
|
||||
|
||||
function parseArgs(argv) {
|
||||
const out = { status: 'complete' };
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* Output JSON: { discarded: N, entries: [...discardedEntries], totalCount: N }
|
||||
*/
|
||||
|
||||
import { readBuffer, removeEntries, truncateBuffer } from './live-manual-edits-buffer.mjs';
|
||||
import { readBuffer, removeEntries, truncateBuffer } from './live/manual-edits-buffer.mjs';
|
||||
|
||||
function argVal(args, name) {
|
||||
const prefix = name + '=';
|
||||
|
||||
@@ -16,12 +16,12 @@
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { resolveLiveConfigPath } from './impeccable-paths.mjs';
|
||||
import { resolveLiveConfigPath } from './lib/impeccable-paths.mjs';
|
||||
import {
|
||||
applySvelteKitLiveAdapter,
|
||||
detectSvelteKitProject,
|
||||
removeSvelteKitLiveAdapter,
|
||||
} from './live-sveltekit-adapter.mjs';
|
||||
} from './live/sveltekit-adapter.mjs';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const CONFIG_PATH = resolveLiveConfigPath({ cwd: process.cwd(), scriptsDir: __dirname });
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { isGeneratedFile } from './is-generated.mjs';
|
||||
import { isGeneratedFile } from './lib/is-generated.mjs';
|
||||
import {
|
||||
buildSearchQueries,
|
||||
findElement,
|
||||
@@ -25,7 +25,7 @@ import {
|
||||
buildSvelteComponentCssAuthoring,
|
||||
scaffoldSvelteComponentInsertSession,
|
||||
shouldUseSvelteComponentInjection,
|
||||
} from './live-svelte-component.mjs';
|
||||
} from './live/svelte-component.mjs';
|
||||
|
||||
const INSERT_POSITIONS = new Set(['before', 'after']);
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { isGeneratedFile } from './is-generated.mjs';
|
||||
import { readBuffer, getBufferPath } from './live-manual-edits-buffer.mjs';
|
||||
import { isGeneratedFile } from './lib/is-generated.mjs';
|
||||
import { readBuffer, getBufferPath } from './live/manual-edits-buffer.mjs';
|
||||
|
||||
const EVIDENCE_VERSION = 1;
|
||||
const TEXT_EXTENSIONS = new Set(['.html', '.jsx', '.tsx', '.vue', '.svelte', '.astro', '.js', '.mjs', '.ts']);
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
import { execFileSync } from 'node:child_process';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { completionAckForAcceptResult, completionTypeForAcceptResult } from './live-completion.mjs';
|
||||
import { readLiveServerInfo } from './impeccable-paths.mjs';
|
||||
import { completionAckForAcceptResult, completionTypeForAcceptResult } from './live/completion.mjs';
|
||||
import { readLiveServerInfo } from './lib/impeccable-paths.mjs';
|
||||
|
||||
// Node's built-in fetch (undici under the hood) enforces a 300s headers
|
||||
// timeout that can't be lowered per-request. We cap each request below
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Recover the next agent action from the durable live-session journal.
|
||||
*/
|
||||
|
||||
import { createLiveSessionStore } from './live-session-store.mjs';
|
||||
import { createLiveSessionStore } from './live/session-store.mjs';
|
||||
|
||||
function manualApplyReplyCommand(eventOrId = 'EVENT_ID') {
|
||||
const id = typeof eventOrId === 'string' ? eventOrId : eventOrId?.id || 'EVENT_ID';
|
||||
|
||||
@@ -20,11 +20,11 @@ import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import net from 'node:net';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { parseDesignMd } from './design-parser.mjs';
|
||||
import { parseDesignMd } from './lib/design-parser.mjs';
|
||||
import { resolveContextDir } from './context.mjs';
|
||||
import { createLiveSessionStore } from './live-session-store.mjs';
|
||||
import { validateEvent } from './live-event-validation.mjs';
|
||||
import { LIVE_COMMANDS } from './live-vocabulary.mjs';
|
||||
import { createLiveSessionStore } from './live/session-store.mjs';
|
||||
import { validateEvent } from './live/event-validation.mjs';
|
||||
import { LIVE_COMMANDS } from './live/vocabulary.mjs';
|
||||
import {
|
||||
getDesignSidecarPath,
|
||||
getLiveDir,
|
||||
@@ -33,20 +33,20 @@ import {
|
||||
removeLiveServerInfo,
|
||||
resolveDesignSidecarPath,
|
||||
writeLiveServerInfo,
|
||||
} from './impeccable-paths.mjs';
|
||||
} from './lib/impeccable-paths.mjs';
|
||||
import {
|
||||
countByPage as countPendingByPage,
|
||||
readBuffer as readManualEditsBuffer,
|
||||
removeEntries as removeManualEditEntries,
|
||||
stageEntry as stageManualEditEntry,
|
||||
truncateBuffer as truncateManualEditsBuffer,
|
||||
} from './live-manual-edits-buffer.mjs';
|
||||
} from './live/manual-edits-buffer.mjs';
|
||||
import { buildManualEditEvidence } from './live-manual-edit-evidence.mjs';
|
||||
import { commitManualEdits } from './live-commit-manual-edits.mjs';
|
||||
import {
|
||||
applyDeferredSvelteComponentAccepts,
|
||||
removeAllSvelteComponentSessions,
|
||||
} from './live-svelte-component.mjs';
|
||||
} from './live/svelte-component.mjs';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
// PRODUCT.md / DESIGN.md live wherever context.mjs resolves. The generated
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
* Print durable recovery status for Impeccable live sessions.
|
||||
*/
|
||||
|
||||
import { createLiveSessionStore } from './live-session-store.mjs';
|
||||
import { readLiveServerInfo } from './impeccable-paths.mjs';
|
||||
import { createLiveSessionStore } from './live/session-store.mjs';
|
||||
import { readLiveServerInfo } from './lib/impeccable-paths.mjs';
|
||||
import { manualApplyResumeHint } from './live-resume.mjs';
|
||||
|
||||
function readServerInfo() {
|
||||
|
||||
@@ -13,13 +13,13 @@
|
||||
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { isGeneratedFile } from './is-generated.mjs';
|
||||
import { readBuffer as readManualEditsBuffer } from './live-manual-edits-buffer.mjs';
|
||||
import { isGeneratedFile } from './lib/is-generated.mjs';
|
||||
import { readBuffer as readManualEditsBuffer } from './live/manual-edits-buffer.mjs';
|
||||
import {
|
||||
buildSvelteComponentCssAuthoring,
|
||||
scaffoldSvelteComponentSession,
|
||||
shouldUseSvelteComponentInjection,
|
||||
} from './live-svelte-component.mjs';
|
||||
} from './live/svelte-component.mjs';
|
||||
|
||||
const EXTENSIONS = ['.html', '.jsx', '.tsx', '.vue', '.svelte', '.astro'];
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { loadContext } from './context.mjs';
|
||||
import { resolveFiles } from './live-inject.mjs';
|
||||
import { readLiveServerInfo } from './impeccable-paths.mjs';
|
||||
import { readLiveServerInfo } from './lib/impeccable-paths.mjs';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
* Extracted for unit testing (insert mode rules).
|
||||
*/
|
||||
|
||||
import { canCreateInsert } from './live-insert-ui.mjs';
|
||||
import { canCreateInsert } from './insert-ui.mjs';
|
||||
|
||||
// The accepted visual action values come from the canonical vocabulary so the
|
||||
// validator, the picker UI, and the marketing demo never drift. Imported (not
|
||||
// just re-exported) so it is also in scope for the validators below.
|
||||
import { VISUAL_ACTIONS } from './live-vocabulary.mjs';
|
||||
import { VISUAL_ACTIONS } from './vocabulary.mjs';
|
||||
export { VISUAL_ACTIONS };
|
||||
|
||||
const ID_PATTERN = /^[0-9a-f]{8}$/;
|
||||
+1
-1
@@ -12,7 +12,7 @@
|
||||
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { getLiveDir } from './impeccable-paths.mjs';
|
||||
import { getLiveDir } from '../lib/impeccable-paths.mjs';
|
||||
|
||||
const BUFFER_VERSION = 1;
|
||||
const BUFFER_FILENAME = 'pending-manual-edits.json';
|
||||
@@ -1,6 +1,6 @@
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { getLegacyLiveSessionsDir, getLiveSessionsDir } from './impeccable-paths.mjs';
|
||||
import { getLegacyLiveSessionsDir, getLiveSessionsDir } from '../lib/impeccable-paths.mjs';
|
||||
|
||||
const COMPLETED_PHASES = new Set(['completed', 'discarded']);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* so the icon recolors when its chip is selected.
|
||||
*
|
||||
* Single source of truth, consumed by:
|
||||
* - skill/scripts/live-event-validation.mjs — re-exports VISUAL_ACTIONS.
|
||||
* - skill/scripts/live/event-validation.mjs — re-exports VISUAL_ACTIONS.
|
||||
* - skill/scripts/live-browser.js — the real picker. It is served raw and
|
||||
* injected as an IIFE, so it cannot import this at runtime; live-server.mjs
|
||||
* serializes LIVE_COMMANDS into window.__IMPECCABLE_VOCAB__ alongside the
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { describe, it } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { parseDesignMd } from '../skill/scripts/design-parser.mjs';
|
||||
import { parseDesignMd } from '../skill/scripts/lib/design-parser.mjs';
|
||||
|
||||
describe('parseDesignMd frontmatter branch', () => {
|
||||
it('returns null frontmatter when the file has no YAML header', () => {
|
||||
|
||||
@@ -17,7 +17,7 @@ import { tmpdir } from 'node:os';
|
||||
import { join, dirname } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
import { isGeneratedFile } from '../skill/scripts/is-generated.mjs';
|
||||
import { isGeneratedFile } from '../skill/scripts/lib/is-generated.mjs';
|
||||
import { detectCsp } from '../skill/scripts/detect-csp.mjs';
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Framework fixtures
|
||||
|
||||
Representative project shapes for exercising live mode against different framework conventions. Each fixture is a small directory tree that the test harness copies into a temp git repo, then drives `live-inject.mjs`, `live-wrap.mjs`, `live-accept.mjs`, and `is-generated.mjs` against.
|
||||
Representative project shapes for exercising live mode against different framework conventions. Each fixture is a small directory tree that the test harness copies into a temp git repo, then drives `live-inject.mjs`, `live-wrap.mjs`, `live-accept.mjs`, and `lib/is-generated.mjs` against.
|
||||
|
||||
Fixtures can also opt into a **runtime E2E** pass that actually installs dependencies, boots the framework dev server, and drives a Playwright browser to verify the live handshake. See the `runtime` block below.
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
readLiveServerInfo,
|
||||
resolveDesignSidecarPath,
|
||||
resolveLiveConfigPath,
|
||||
} from '../skill/scripts/impeccable-paths.mjs';
|
||||
} from '../skill/scripts/lib/impeccable-paths.mjs';
|
||||
|
||||
describe('impeccable project paths', () => {
|
||||
let tmp;
|
||||
|
||||
@@ -3,7 +3,7 @@ import assert from 'node:assert';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import os from 'node:os';
|
||||
import { writeBuffer, readBuffer } from '../skill/scripts/live-manual-edits-buffer.mjs';
|
||||
import { writeBuffer, readBuffer } from '../skill/scripts/live/manual-edits-buffer.mjs';
|
||||
import { scrubManualEditsAgainstOriginalBlock } from '../skill/scripts/live-accept.mjs';
|
||||
|
||||
let tmpDir;
|
||||
|
||||
@@ -5,7 +5,7 @@ import path from 'node:path';
|
||||
import os from 'node:os';
|
||||
import { execFileSync } from 'node:child_process';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { writeBuffer, readBuffer } from '../skill/scripts/live-manual-edits-buffer.mjs';
|
||||
import { writeBuffer, readBuffer } from '../skill/scripts/live/manual-edits-buffer.mjs';
|
||||
import { buildManualEditEvidence } from '../skill/scripts/live-manual-edit-evidence.mjs';
|
||||
import { commitManualEdits } from '../skill/scripts/live-commit-manual-edits.mjs';
|
||||
import {
|
||||
|
||||
@@ -4,7 +4,7 @@ import assert from 'node:assert/strict';
|
||||
import {
|
||||
completionAckForAcceptResult,
|
||||
completionTypeForAcceptResult,
|
||||
} from '../skill/scripts/live-completion.mjs';
|
||||
} from '../skill/scripts/live/completion.mjs';
|
||||
|
||||
describe('live completion type classification', () => {
|
||||
it('treats generated-file fallback accept as normal agent handoff, not error', () => {
|
||||
|
||||
@@ -5,7 +5,7 @@ import path from 'node:path';
|
||||
import os from 'node:os';
|
||||
import { execFileSync } from 'node:child_process';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { writeBuffer, readBuffer } from '../skill/scripts/live-manual-edits-buffer.mjs';
|
||||
import { writeBuffer, readBuffer } from '../skill/scripts/live/manual-edits-buffer.mjs';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const REPO_ROOT = path.resolve(__dirname, '..');
|
||||
|
||||
@@ -26,7 +26,7 @@ import { readFileSync, readdirSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
import { execFile } from 'node:child_process';
|
||||
import { promisify } from 'node:util';
|
||||
import { completionTypeForAcceptResult } from '../../skill/scripts/live-completion.mjs';
|
||||
import { completionTypeForAcceptResult } from '../../skill/scripts/live/completion.mjs';
|
||||
|
||||
const execFileP = promisify(execFile);
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { describe, it } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { validateEvent } from '../skill/scripts/live-event-validation.mjs';
|
||||
import { validateEvent } from '../skill/scripts/live/event-validation.mjs';
|
||||
|
||||
const VALID_ID = 'a1b2c3d4';
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ import {
|
||||
resolveInsertSessionAnchor,
|
||||
buildInsertPlaceholderSnapshot,
|
||||
findInsertAnchorInDom,
|
||||
} from '../skill/scripts/live-insert-ui.mjs';
|
||||
} from '../skill/scripts/live/insert-ui.mjs';
|
||||
|
||||
describe('detectInsertAxisFromStyle', () => {
|
||||
it('maps flex row and grid multi-column to row axis', () => {
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
countByPage,
|
||||
truncateBuffer,
|
||||
getBufferPath,
|
||||
} from '../skill/scripts/live-manual-edits-buffer.mjs';
|
||||
} from '../skill/scripts/live/manual-edits-buffer.mjs';
|
||||
|
||||
let tmpDir;
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import { mkdtempSync, readFileSync, rmSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
import { spawn } from 'node:child_process';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { getLiveServerPath } from '../skill/scripts/impeccable-paths.mjs';
|
||||
import { getLiveServerPath } from '../skill/scripts/lib/impeccable-paths.mjs';
|
||||
import { postReply } from '../skill/scripts/live-poll.mjs';
|
||||
|
||||
const REPO_ROOT = process.cwd();
|
||||
|
||||
@@ -4,7 +4,7 @@ import { mkdtempSync, rmSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { execFileSync } from 'node:child_process';
|
||||
import { createLiveSessionStore } from '../skill/scripts/live-session-store.mjs';
|
||||
import { createLiveSessionStore } from '../skill/scripts/live/session-store.mjs';
|
||||
|
||||
const REPO_ROOT = process.cwd();
|
||||
const STATUS_SCRIPT = join(REPO_ROOT, 'skill/scripts/live-status.mjs');
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
getLiveDir,
|
||||
getLiveServerPath,
|
||||
getLiveSessionsDir,
|
||||
} from '../skill/scripts/impeccable-paths.mjs';
|
||||
} from '../skill/scripts/lib/impeccable-paths.mjs';
|
||||
|
||||
const REPO_ROOT = process.cwd();
|
||||
const SERVER_SCRIPT = join(REPO_ROOT, 'skill/scripts/live-server.mjs');
|
||||
@@ -162,7 +162,7 @@ describe('live-server integration', () => {
|
||||
// live-browser.js builds its action picker from window.__IMPECCABLE_VOCAB__
|
||||
// rather than an inline copy, so the server must serialize the canonical
|
||||
// vocabulary into /live.js (next to the token/port).
|
||||
const { LIVE_COMMANDS } = await import('../skill/scripts/live-vocabulary.mjs');
|
||||
const { LIVE_COMMANDS } = await import('../skill/scripts/live/vocabulary.mjs');
|
||||
const body = await (await fetch(`http://localhost:${server.port}/live.js`)).text();
|
||||
assert.match(body, /window\.__IMPECCABLE_VOCAB__\s*=/);
|
||||
const injected = JSON.parse(body.match(/window\.__IMPECCABLE_VOCAB__\s*=\s*(\[.*?\]);/s)[1]);
|
||||
|
||||
@@ -9,12 +9,12 @@ import { mkdirSync, mkdtempSync, rmSync, appendFileSync, readFileSync } from 'no
|
||||
import { join } from 'node:path';
|
||||
import { tmpdir } from 'node:os';
|
||||
|
||||
import { createLiveSessionStore } from '../skill/scripts/live-session-store.mjs';
|
||||
import { createLiveSessionStore } from '../skill/scripts/live/session-store.mjs';
|
||||
import {
|
||||
getLegacyLiveSessionsDir,
|
||||
getLiveAnnotationsDir,
|
||||
getLiveSessionsDir,
|
||||
} from '../skill/scripts/impeccable-paths.mjs';
|
||||
} from '../skill/scripts/lib/impeccable-paths.mjs';
|
||||
|
||||
describe('live-session-store', () => {
|
||||
let tmp;
|
||||
|
||||
@@ -5,7 +5,7 @@ import path from 'node:path';
|
||||
import os from 'node:os';
|
||||
import { execFileSync } from 'node:child_process';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { writeBuffer } from '../skill/scripts/live-manual-edits-buffer.mjs';
|
||||
import { writeBuffer } from '../skill/scripts/live/manual-edits-buffer.mjs';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const REPO_ROOT = path.resolve(__dirname, '..');
|
||||
|
||||
Reference in New Issue
Block a user