From 5b585c0885a7c7d68523169b5b1934711794b80d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 1 Sep 2026 03:49:18 +0000 Subject: [PATCH] Sync generated provider output --- .../impeccable/scripts/concept-seed.mjs | 25 +++++++++++++++++-- .../impeccable/scripts/concept-seed.mjs | 25 +++++++++++++++++-- .../impeccable/scripts/concept-seed.mjs | 25 +++++++++++++++++-- .../impeccable/scripts/concept-seed.mjs | 25 +++++++++++++++++-- .../impeccable/scripts/concept-seed.mjs | 25 +++++++++++++++++-- .../impeccable/scripts/concept-seed.mjs | 25 +++++++++++++++++-- .../impeccable/scripts/concept-seed.mjs | 25 +++++++++++++++++-- .../impeccable/scripts/concept-seed.mjs | 25 +++++++++++++++++-- .../impeccable/scripts/concept-seed.mjs | 25 +++++++++++++++++-- .../impeccable/scripts/concept-seed.mjs | 25 +++++++++++++++++-- .../impeccable/scripts/concept-seed.mjs | 25 +++++++++++++++++-- .../impeccable/scripts/concept-seed.mjs | 25 +++++++++++++++++-- .../impeccable/scripts/concept-seed.mjs | 25 +++++++++++++++++-- .../impeccable/scripts/concept-seed.mjs | 25 +++++++++++++++++-- .../impeccable/scripts/concept-seed.mjs | 25 +++++++++++++++++-- .../impeccable/scripts/concept-seed.mjs | 25 +++++++++++++++++-- 16 files changed, 368 insertions(+), 32 deletions(-) diff --git a/.agents/skills/impeccable/scripts/concept-seed.mjs b/.agents/skills/impeccable/scripts/concept-seed.mjs index 991dc629b..8887f9b32 100644 --- a/.agents/skills/impeccable/scripts/concept-seed.mjs +++ b/.agents/skills/impeccable/scripts/concept-seed.mjs @@ -91,7 +91,7 @@ import crypto from 'node:crypto'; import { dirname, join, relative, resolve } from 'node:path'; -import { readFileSync } from 'node:fs'; +import { readFileSync, realpathSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; import { approvedPoolRevision, @@ -703,7 +703,28 @@ export function nextStepAfterChoice({ key, scope, cwd = process.cwd(), env = pro return `NEXT (comp-led, ${why}): the world is chosen; the composition is not. Run: node ${scripts}/build-phase.mjs start${seed} and follow its NEXT lines: it opens the comps phase (three comps under .impeccable/mocks/, one approved by the user through the decision page or structured question, sidecar "approved": true), then spec, plates, hero, sections, motion, responsive, review. Do not write page code before those gates close. Reference: reference/visualize.md for the comp round.\n`; } -if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) { +export function sameMainModulePath(left, right, platform = process.platform) { + if (platform !== 'win32') return left === right; + const normalizeDriveLetter = (value) => value.replace(/^([a-z]):/i, (_, drive) => `${drive.toUpperCase()}:`); + return normalizeDriveLetter(left) === normalizeDriveLetter(right); +} + +function isMainModule() { + if (!process.argv[1]) return false; + try { + // Node resolves import.meta.url through symlinks but leaves argv[1] as the + // invoked path. Compare real paths so a linked skill still runs its CLI, + // normalizing the drive-letter casing that Windows junctions can change. + return sameMainModulePath( + realpathSync(process.argv[1]), + realpathSync(fileURLToPath(import.meta.url)) + ); + } catch { + return false; + } +} + +if (isMainModule()) { const args = process.argv.slice(2); const fromIdx = args.indexOf('--from'); const scopeIdx = args.indexOf('--scope'); diff --git a/.claude/skills/impeccable/scripts/concept-seed.mjs b/.claude/skills/impeccable/scripts/concept-seed.mjs index 991dc629b..8887f9b32 100644 --- a/.claude/skills/impeccable/scripts/concept-seed.mjs +++ b/.claude/skills/impeccable/scripts/concept-seed.mjs @@ -91,7 +91,7 @@ import crypto from 'node:crypto'; import { dirname, join, relative, resolve } from 'node:path'; -import { readFileSync } from 'node:fs'; +import { readFileSync, realpathSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; import { approvedPoolRevision, @@ -703,7 +703,28 @@ export function nextStepAfterChoice({ key, scope, cwd = process.cwd(), env = pro return `NEXT (comp-led, ${why}): the world is chosen; the composition is not. Run: node ${scripts}/build-phase.mjs start${seed} and follow its NEXT lines: it opens the comps phase (three comps under .impeccable/mocks/, one approved by the user through the decision page or structured question, sidecar "approved": true), then spec, plates, hero, sections, motion, responsive, review. Do not write page code before those gates close. Reference: reference/visualize.md for the comp round.\n`; } -if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) { +export function sameMainModulePath(left, right, platform = process.platform) { + if (platform !== 'win32') return left === right; + const normalizeDriveLetter = (value) => value.replace(/^([a-z]):/i, (_, drive) => `${drive.toUpperCase()}:`); + return normalizeDriveLetter(left) === normalizeDriveLetter(right); +} + +function isMainModule() { + if (!process.argv[1]) return false; + try { + // Node resolves import.meta.url through symlinks but leaves argv[1] as the + // invoked path. Compare real paths so a linked skill still runs its CLI, + // normalizing the drive-letter casing that Windows junctions can change. + return sameMainModulePath( + realpathSync(process.argv[1]), + realpathSync(fileURLToPath(import.meta.url)) + ); + } catch { + return false; + } +} + +if (isMainModule()) { const args = process.argv.slice(2); const fromIdx = args.indexOf('--from'); const scopeIdx = args.indexOf('--scope'); diff --git a/.cursor/skills/impeccable/scripts/concept-seed.mjs b/.cursor/skills/impeccable/scripts/concept-seed.mjs index 991dc629b..8887f9b32 100644 --- a/.cursor/skills/impeccable/scripts/concept-seed.mjs +++ b/.cursor/skills/impeccable/scripts/concept-seed.mjs @@ -91,7 +91,7 @@ import crypto from 'node:crypto'; import { dirname, join, relative, resolve } from 'node:path'; -import { readFileSync } from 'node:fs'; +import { readFileSync, realpathSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; import { approvedPoolRevision, @@ -703,7 +703,28 @@ export function nextStepAfterChoice({ key, scope, cwd = process.cwd(), env = pro return `NEXT (comp-led, ${why}): the world is chosen; the composition is not. Run: node ${scripts}/build-phase.mjs start${seed} and follow its NEXT lines: it opens the comps phase (three comps under .impeccable/mocks/, one approved by the user through the decision page or structured question, sidecar "approved": true), then spec, plates, hero, sections, motion, responsive, review. Do not write page code before those gates close. Reference: reference/visualize.md for the comp round.\n`; } -if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) { +export function sameMainModulePath(left, right, platform = process.platform) { + if (platform !== 'win32') return left === right; + const normalizeDriveLetter = (value) => value.replace(/^([a-z]):/i, (_, drive) => `${drive.toUpperCase()}:`); + return normalizeDriveLetter(left) === normalizeDriveLetter(right); +} + +function isMainModule() { + if (!process.argv[1]) return false; + try { + // Node resolves import.meta.url through symlinks but leaves argv[1] as the + // invoked path. Compare real paths so a linked skill still runs its CLI, + // normalizing the drive-letter casing that Windows junctions can change. + return sameMainModulePath( + realpathSync(process.argv[1]), + realpathSync(fileURLToPath(import.meta.url)) + ); + } catch { + return false; + } +} + +if (isMainModule()) { const args = process.argv.slice(2); const fromIdx = args.indexOf('--from'); const scopeIdx = args.indexOf('--scope'); diff --git a/.gemini/skills/impeccable/scripts/concept-seed.mjs b/.gemini/skills/impeccable/scripts/concept-seed.mjs index 991dc629b..8887f9b32 100644 --- a/.gemini/skills/impeccable/scripts/concept-seed.mjs +++ b/.gemini/skills/impeccable/scripts/concept-seed.mjs @@ -91,7 +91,7 @@ import crypto from 'node:crypto'; import { dirname, join, relative, resolve } from 'node:path'; -import { readFileSync } from 'node:fs'; +import { readFileSync, realpathSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; import { approvedPoolRevision, @@ -703,7 +703,28 @@ export function nextStepAfterChoice({ key, scope, cwd = process.cwd(), env = pro return `NEXT (comp-led, ${why}): the world is chosen; the composition is not. Run: node ${scripts}/build-phase.mjs start${seed} and follow its NEXT lines: it opens the comps phase (three comps under .impeccable/mocks/, one approved by the user through the decision page or structured question, sidecar "approved": true), then spec, plates, hero, sections, motion, responsive, review. Do not write page code before those gates close. Reference: reference/visualize.md for the comp round.\n`; } -if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) { +export function sameMainModulePath(left, right, platform = process.platform) { + if (platform !== 'win32') return left === right; + const normalizeDriveLetter = (value) => value.replace(/^([a-z]):/i, (_, drive) => `${drive.toUpperCase()}:`); + return normalizeDriveLetter(left) === normalizeDriveLetter(right); +} + +function isMainModule() { + if (!process.argv[1]) return false; + try { + // Node resolves import.meta.url through symlinks but leaves argv[1] as the + // invoked path. Compare real paths so a linked skill still runs its CLI, + // normalizing the drive-letter casing that Windows junctions can change. + return sameMainModulePath( + realpathSync(process.argv[1]), + realpathSync(fileURLToPath(import.meta.url)) + ); + } catch { + return false; + } +} + +if (isMainModule()) { const args = process.argv.slice(2); const fromIdx = args.indexOf('--from'); const scopeIdx = args.indexOf('--scope'); diff --git a/.github/skills/impeccable/scripts/concept-seed.mjs b/.github/skills/impeccable/scripts/concept-seed.mjs index 991dc629b..8887f9b32 100644 --- a/.github/skills/impeccable/scripts/concept-seed.mjs +++ b/.github/skills/impeccable/scripts/concept-seed.mjs @@ -91,7 +91,7 @@ import crypto from 'node:crypto'; import { dirname, join, relative, resolve } from 'node:path'; -import { readFileSync } from 'node:fs'; +import { readFileSync, realpathSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; import { approvedPoolRevision, @@ -703,7 +703,28 @@ export function nextStepAfterChoice({ key, scope, cwd = process.cwd(), env = pro return `NEXT (comp-led, ${why}): the world is chosen; the composition is not. Run: node ${scripts}/build-phase.mjs start${seed} and follow its NEXT lines: it opens the comps phase (three comps under .impeccable/mocks/, one approved by the user through the decision page or structured question, sidecar "approved": true), then spec, plates, hero, sections, motion, responsive, review. Do not write page code before those gates close. Reference: reference/visualize.md for the comp round.\n`; } -if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) { +export function sameMainModulePath(left, right, platform = process.platform) { + if (platform !== 'win32') return left === right; + const normalizeDriveLetter = (value) => value.replace(/^([a-z]):/i, (_, drive) => `${drive.toUpperCase()}:`); + return normalizeDriveLetter(left) === normalizeDriveLetter(right); +} + +function isMainModule() { + if (!process.argv[1]) return false; + try { + // Node resolves import.meta.url through symlinks but leaves argv[1] as the + // invoked path. Compare real paths so a linked skill still runs its CLI, + // normalizing the drive-letter casing that Windows junctions can change. + return sameMainModulePath( + realpathSync(process.argv[1]), + realpathSync(fileURLToPath(import.meta.url)) + ); + } catch { + return false; + } +} + +if (isMainModule()) { const args = process.argv.slice(2); const fromIdx = args.indexOf('--from'); const scopeIdx = args.indexOf('--scope'); diff --git a/.grok/skills/impeccable/scripts/concept-seed.mjs b/.grok/skills/impeccable/scripts/concept-seed.mjs index 991dc629b..8887f9b32 100644 --- a/.grok/skills/impeccable/scripts/concept-seed.mjs +++ b/.grok/skills/impeccable/scripts/concept-seed.mjs @@ -91,7 +91,7 @@ import crypto from 'node:crypto'; import { dirname, join, relative, resolve } from 'node:path'; -import { readFileSync } from 'node:fs'; +import { readFileSync, realpathSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; import { approvedPoolRevision, @@ -703,7 +703,28 @@ export function nextStepAfterChoice({ key, scope, cwd = process.cwd(), env = pro return `NEXT (comp-led, ${why}): the world is chosen; the composition is not. Run: node ${scripts}/build-phase.mjs start${seed} and follow its NEXT lines: it opens the comps phase (three comps under .impeccable/mocks/, one approved by the user through the decision page or structured question, sidecar "approved": true), then spec, plates, hero, sections, motion, responsive, review. Do not write page code before those gates close. Reference: reference/visualize.md for the comp round.\n`; } -if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) { +export function sameMainModulePath(left, right, platform = process.platform) { + if (platform !== 'win32') return left === right; + const normalizeDriveLetter = (value) => value.replace(/^([a-z]):/i, (_, drive) => `${drive.toUpperCase()}:`); + return normalizeDriveLetter(left) === normalizeDriveLetter(right); +} + +function isMainModule() { + if (!process.argv[1]) return false; + try { + // Node resolves import.meta.url through symlinks but leaves argv[1] as the + // invoked path. Compare real paths so a linked skill still runs its CLI, + // normalizing the drive-letter casing that Windows junctions can change. + return sameMainModulePath( + realpathSync(process.argv[1]), + realpathSync(fileURLToPath(import.meta.url)) + ); + } catch { + return false; + } +} + +if (isMainModule()) { const args = process.argv.slice(2); const fromIdx = args.indexOf('--from'); const scopeIdx = args.indexOf('--scope'); diff --git a/.hermes/skills/impeccable/scripts/concept-seed.mjs b/.hermes/skills/impeccable/scripts/concept-seed.mjs index 991dc629b..8887f9b32 100644 --- a/.hermes/skills/impeccable/scripts/concept-seed.mjs +++ b/.hermes/skills/impeccable/scripts/concept-seed.mjs @@ -91,7 +91,7 @@ import crypto from 'node:crypto'; import { dirname, join, relative, resolve } from 'node:path'; -import { readFileSync } from 'node:fs'; +import { readFileSync, realpathSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; import { approvedPoolRevision, @@ -703,7 +703,28 @@ export function nextStepAfterChoice({ key, scope, cwd = process.cwd(), env = pro return `NEXT (comp-led, ${why}): the world is chosen; the composition is not. Run: node ${scripts}/build-phase.mjs start${seed} and follow its NEXT lines: it opens the comps phase (three comps under .impeccable/mocks/, one approved by the user through the decision page or structured question, sidecar "approved": true), then spec, plates, hero, sections, motion, responsive, review. Do not write page code before those gates close. Reference: reference/visualize.md for the comp round.\n`; } -if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) { +export function sameMainModulePath(left, right, platform = process.platform) { + if (platform !== 'win32') return left === right; + const normalizeDriveLetter = (value) => value.replace(/^([a-z]):/i, (_, drive) => `${drive.toUpperCase()}:`); + return normalizeDriveLetter(left) === normalizeDriveLetter(right); +} + +function isMainModule() { + if (!process.argv[1]) return false; + try { + // Node resolves import.meta.url through symlinks but leaves argv[1] as the + // invoked path. Compare real paths so a linked skill still runs its CLI, + // normalizing the drive-letter casing that Windows junctions can change. + return sameMainModulePath( + realpathSync(process.argv[1]), + realpathSync(fileURLToPath(import.meta.url)) + ); + } catch { + return false; + } +} + +if (isMainModule()) { const args = process.argv.slice(2); const fromIdx = args.indexOf('--from'); const scopeIdx = args.indexOf('--scope'); diff --git a/.kiro/skills/impeccable/scripts/concept-seed.mjs b/.kiro/skills/impeccable/scripts/concept-seed.mjs index 991dc629b..8887f9b32 100644 --- a/.kiro/skills/impeccable/scripts/concept-seed.mjs +++ b/.kiro/skills/impeccable/scripts/concept-seed.mjs @@ -91,7 +91,7 @@ import crypto from 'node:crypto'; import { dirname, join, relative, resolve } from 'node:path'; -import { readFileSync } from 'node:fs'; +import { readFileSync, realpathSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; import { approvedPoolRevision, @@ -703,7 +703,28 @@ export function nextStepAfterChoice({ key, scope, cwd = process.cwd(), env = pro return `NEXT (comp-led, ${why}): the world is chosen; the composition is not. Run: node ${scripts}/build-phase.mjs start${seed} and follow its NEXT lines: it opens the comps phase (three comps under .impeccable/mocks/, one approved by the user through the decision page or structured question, sidecar "approved": true), then spec, plates, hero, sections, motion, responsive, review. Do not write page code before those gates close. Reference: reference/visualize.md for the comp round.\n`; } -if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) { +export function sameMainModulePath(left, right, platform = process.platform) { + if (platform !== 'win32') return left === right; + const normalizeDriveLetter = (value) => value.replace(/^([a-z]):/i, (_, drive) => `${drive.toUpperCase()}:`); + return normalizeDriveLetter(left) === normalizeDriveLetter(right); +} + +function isMainModule() { + if (!process.argv[1]) return false; + try { + // Node resolves import.meta.url through symlinks but leaves argv[1] as the + // invoked path. Compare real paths so a linked skill still runs its CLI, + // normalizing the drive-letter casing that Windows junctions can change. + return sameMainModulePath( + realpathSync(process.argv[1]), + realpathSync(fileURLToPath(import.meta.url)) + ); + } catch { + return false; + } +} + +if (isMainModule()) { const args = process.argv.slice(2); const fromIdx = args.indexOf('--from'); const scopeIdx = args.indexOf('--scope'); diff --git a/.opencode/skills/impeccable/scripts/concept-seed.mjs b/.opencode/skills/impeccable/scripts/concept-seed.mjs index 991dc629b..8887f9b32 100644 --- a/.opencode/skills/impeccable/scripts/concept-seed.mjs +++ b/.opencode/skills/impeccable/scripts/concept-seed.mjs @@ -91,7 +91,7 @@ import crypto from 'node:crypto'; import { dirname, join, relative, resolve } from 'node:path'; -import { readFileSync } from 'node:fs'; +import { readFileSync, realpathSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; import { approvedPoolRevision, @@ -703,7 +703,28 @@ export function nextStepAfterChoice({ key, scope, cwd = process.cwd(), env = pro return `NEXT (comp-led, ${why}): the world is chosen; the composition is not. Run: node ${scripts}/build-phase.mjs start${seed} and follow its NEXT lines: it opens the comps phase (three comps under .impeccable/mocks/, one approved by the user through the decision page or structured question, sidecar "approved": true), then spec, plates, hero, sections, motion, responsive, review. Do not write page code before those gates close. Reference: reference/visualize.md for the comp round.\n`; } -if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) { +export function sameMainModulePath(left, right, platform = process.platform) { + if (platform !== 'win32') return left === right; + const normalizeDriveLetter = (value) => value.replace(/^([a-z]):/i, (_, drive) => `${drive.toUpperCase()}:`); + return normalizeDriveLetter(left) === normalizeDriveLetter(right); +} + +function isMainModule() { + if (!process.argv[1]) return false; + try { + // Node resolves import.meta.url through symlinks but leaves argv[1] as the + // invoked path. Compare real paths so a linked skill still runs its CLI, + // normalizing the drive-letter casing that Windows junctions can change. + return sameMainModulePath( + realpathSync(process.argv[1]), + realpathSync(fileURLToPath(import.meta.url)) + ); + } catch { + return false; + } +} + +if (isMainModule()) { const args = process.argv.slice(2); const fromIdx = args.indexOf('--from'); const scopeIdx = args.indexOf('--scope'); diff --git a/.pi/skills/impeccable/scripts/concept-seed.mjs b/.pi/skills/impeccable/scripts/concept-seed.mjs index 991dc629b..8887f9b32 100644 --- a/.pi/skills/impeccable/scripts/concept-seed.mjs +++ b/.pi/skills/impeccable/scripts/concept-seed.mjs @@ -91,7 +91,7 @@ import crypto from 'node:crypto'; import { dirname, join, relative, resolve } from 'node:path'; -import { readFileSync } from 'node:fs'; +import { readFileSync, realpathSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; import { approvedPoolRevision, @@ -703,7 +703,28 @@ export function nextStepAfterChoice({ key, scope, cwd = process.cwd(), env = pro return `NEXT (comp-led, ${why}): the world is chosen; the composition is not. Run: node ${scripts}/build-phase.mjs start${seed} and follow its NEXT lines: it opens the comps phase (three comps under .impeccable/mocks/, one approved by the user through the decision page or structured question, sidecar "approved": true), then spec, plates, hero, sections, motion, responsive, review. Do not write page code before those gates close. Reference: reference/visualize.md for the comp round.\n`; } -if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) { +export function sameMainModulePath(left, right, platform = process.platform) { + if (platform !== 'win32') return left === right; + const normalizeDriveLetter = (value) => value.replace(/^([a-z]):/i, (_, drive) => `${drive.toUpperCase()}:`); + return normalizeDriveLetter(left) === normalizeDriveLetter(right); +} + +function isMainModule() { + if (!process.argv[1]) return false; + try { + // Node resolves import.meta.url through symlinks but leaves argv[1] as the + // invoked path. Compare real paths so a linked skill still runs its CLI, + // normalizing the drive-letter casing that Windows junctions can change. + return sameMainModulePath( + realpathSync(process.argv[1]), + realpathSync(fileURLToPath(import.meta.url)) + ); + } catch { + return false; + } +} + +if (isMainModule()) { const args = process.argv.slice(2); const fromIdx = args.indexOf('--from'); const scopeIdx = args.indexOf('--scope'); diff --git a/.qoder/skills/impeccable/scripts/concept-seed.mjs b/.qoder/skills/impeccable/scripts/concept-seed.mjs index 991dc629b..8887f9b32 100644 --- a/.qoder/skills/impeccable/scripts/concept-seed.mjs +++ b/.qoder/skills/impeccable/scripts/concept-seed.mjs @@ -91,7 +91,7 @@ import crypto from 'node:crypto'; import { dirname, join, relative, resolve } from 'node:path'; -import { readFileSync } from 'node:fs'; +import { readFileSync, realpathSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; import { approvedPoolRevision, @@ -703,7 +703,28 @@ export function nextStepAfterChoice({ key, scope, cwd = process.cwd(), env = pro return `NEXT (comp-led, ${why}): the world is chosen; the composition is not. Run: node ${scripts}/build-phase.mjs start${seed} and follow its NEXT lines: it opens the comps phase (three comps under .impeccable/mocks/, one approved by the user through the decision page or structured question, sidecar "approved": true), then spec, plates, hero, sections, motion, responsive, review. Do not write page code before those gates close. Reference: reference/visualize.md for the comp round.\n`; } -if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) { +export function sameMainModulePath(left, right, platform = process.platform) { + if (platform !== 'win32') return left === right; + const normalizeDriveLetter = (value) => value.replace(/^([a-z]):/i, (_, drive) => `${drive.toUpperCase()}:`); + return normalizeDriveLetter(left) === normalizeDriveLetter(right); +} + +function isMainModule() { + if (!process.argv[1]) return false; + try { + // Node resolves import.meta.url through symlinks but leaves argv[1] as the + // invoked path. Compare real paths so a linked skill still runs its CLI, + // normalizing the drive-letter casing that Windows junctions can change. + return sameMainModulePath( + realpathSync(process.argv[1]), + realpathSync(fileURLToPath(import.meta.url)) + ); + } catch { + return false; + } +} + +if (isMainModule()) { const args = process.argv.slice(2); const fromIdx = args.indexOf('--from'); const scopeIdx = args.indexOf('--scope'); diff --git a/.rovodev/skills/impeccable/scripts/concept-seed.mjs b/.rovodev/skills/impeccable/scripts/concept-seed.mjs index 991dc629b..8887f9b32 100644 --- a/.rovodev/skills/impeccable/scripts/concept-seed.mjs +++ b/.rovodev/skills/impeccable/scripts/concept-seed.mjs @@ -91,7 +91,7 @@ import crypto from 'node:crypto'; import { dirname, join, relative, resolve } from 'node:path'; -import { readFileSync } from 'node:fs'; +import { readFileSync, realpathSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; import { approvedPoolRevision, @@ -703,7 +703,28 @@ export function nextStepAfterChoice({ key, scope, cwd = process.cwd(), env = pro return `NEXT (comp-led, ${why}): the world is chosen; the composition is not. Run: node ${scripts}/build-phase.mjs start${seed} and follow its NEXT lines: it opens the comps phase (three comps under .impeccable/mocks/, one approved by the user through the decision page or structured question, sidecar "approved": true), then spec, plates, hero, sections, motion, responsive, review. Do not write page code before those gates close. Reference: reference/visualize.md for the comp round.\n`; } -if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) { +export function sameMainModulePath(left, right, platform = process.platform) { + if (platform !== 'win32') return left === right; + const normalizeDriveLetter = (value) => value.replace(/^([a-z]):/i, (_, drive) => `${drive.toUpperCase()}:`); + return normalizeDriveLetter(left) === normalizeDriveLetter(right); +} + +function isMainModule() { + if (!process.argv[1]) return false; + try { + // Node resolves import.meta.url through symlinks but leaves argv[1] as the + // invoked path. Compare real paths so a linked skill still runs its CLI, + // normalizing the drive-letter casing that Windows junctions can change. + return sameMainModulePath( + realpathSync(process.argv[1]), + realpathSync(fileURLToPath(import.meta.url)) + ); + } catch { + return false; + } +} + +if (isMainModule()) { const args = process.argv.slice(2); const fromIdx = args.indexOf('--from'); const scopeIdx = args.indexOf('--scope'); diff --git a/.trae-cn/skills/impeccable/scripts/concept-seed.mjs b/.trae-cn/skills/impeccable/scripts/concept-seed.mjs index 991dc629b..8887f9b32 100644 --- a/.trae-cn/skills/impeccable/scripts/concept-seed.mjs +++ b/.trae-cn/skills/impeccable/scripts/concept-seed.mjs @@ -91,7 +91,7 @@ import crypto from 'node:crypto'; import { dirname, join, relative, resolve } from 'node:path'; -import { readFileSync } from 'node:fs'; +import { readFileSync, realpathSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; import { approvedPoolRevision, @@ -703,7 +703,28 @@ export function nextStepAfterChoice({ key, scope, cwd = process.cwd(), env = pro return `NEXT (comp-led, ${why}): the world is chosen; the composition is not. Run: node ${scripts}/build-phase.mjs start${seed} and follow its NEXT lines: it opens the comps phase (three comps under .impeccable/mocks/, one approved by the user through the decision page or structured question, sidecar "approved": true), then spec, plates, hero, sections, motion, responsive, review. Do not write page code before those gates close. Reference: reference/visualize.md for the comp round.\n`; } -if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) { +export function sameMainModulePath(left, right, platform = process.platform) { + if (platform !== 'win32') return left === right; + const normalizeDriveLetter = (value) => value.replace(/^([a-z]):/i, (_, drive) => `${drive.toUpperCase()}:`); + return normalizeDriveLetter(left) === normalizeDriveLetter(right); +} + +function isMainModule() { + if (!process.argv[1]) return false; + try { + // Node resolves import.meta.url through symlinks but leaves argv[1] as the + // invoked path. Compare real paths so a linked skill still runs its CLI, + // normalizing the drive-letter casing that Windows junctions can change. + return sameMainModulePath( + realpathSync(process.argv[1]), + realpathSync(fileURLToPath(import.meta.url)) + ); + } catch { + return false; + } +} + +if (isMainModule()) { const args = process.argv.slice(2); const fromIdx = args.indexOf('--from'); const scopeIdx = args.indexOf('--scope'); diff --git a/.trae/skills/impeccable/scripts/concept-seed.mjs b/.trae/skills/impeccable/scripts/concept-seed.mjs index 991dc629b..8887f9b32 100644 --- a/.trae/skills/impeccable/scripts/concept-seed.mjs +++ b/.trae/skills/impeccable/scripts/concept-seed.mjs @@ -91,7 +91,7 @@ import crypto from 'node:crypto'; import { dirname, join, relative, resolve } from 'node:path'; -import { readFileSync } from 'node:fs'; +import { readFileSync, realpathSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; import { approvedPoolRevision, @@ -703,7 +703,28 @@ export function nextStepAfterChoice({ key, scope, cwd = process.cwd(), env = pro return `NEXT (comp-led, ${why}): the world is chosen; the composition is not. Run: node ${scripts}/build-phase.mjs start${seed} and follow its NEXT lines: it opens the comps phase (three comps under .impeccable/mocks/, one approved by the user through the decision page or structured question, sidecar "approved": true), then spec, plates, hero, sections, motion, responsive, review. Do not write page code before those gates close. Reference: reference/visualize.md for the comp round.\n`; } -if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) { +export function sameMainModulePath(left, right, platform = process.platform) { + if (platform !== 'win32') return left === right; + const normalizeDriveLetter = (value) => value.replace(/^([a-z]):/i, (_, drive) => `${drive.toUpperCase()}:`); + return normalizeDriveLetter(left) === normalizeDriveLetter(right); +} + +function isMainModule() { + if (!process.argv[1]) return false; + try { + // Node resolves import.meta.url through symlinks but leaves argv[1] as the + // invoked path. Compare real paths so a linked skill still runs its CLI, + // normalizing the drive-letter casing that Windows junctions can change. + return sameMainModulePath( + realpathSync(process.argv[1]), + realpathSync(fileURLToPath(import.meta.url)) + ); + } catch { + return false; + } +} + +if (isMainModule()) { const args = process.argv.slice(2); const fromIdx = args.indexOf('--from'); const scopeIdx = args.indexOf('--scope'); diff --git a/.vibe/skills/impeccable/scripts/concept-seed.mjs b/.vibe/skills/impeccable/scripts/concept-seed.mjs index 991dc629b..8887f9b32 100644 --- a/.vibe/skills/impeccable/scripts/concept-seed.mjs +++ b/.vibe/skills/impeccable/scripts/concept-seed.mjs @@ -91,7 +91,7 @@ import crypto from 'node:crypto'; import { dirname, join, relative, resolve } from 'node:path'; -import { readFileSync } from 'node:fs'; +import { readFileSync, realpathSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; import { approvedPoolRevision, @@ -703,7 +703,28 @@ export function nextStepAfterChoice({ key, scope, cwd = process.cwd(), env = pro return `NEXT (comp-led, ${why}): the world is chosen; the composition is not. Run: node ${scripts}/build-phase.mjs start${seed} and follow its NEXT lines: it opens the comps phase (three comps under .impeccable/mocks/, one approved by the user through the decision page or structured question, sidecar "approved": true), then spec, plates, hero, sections, motion, responsive, review. Do not write page code before those gates close. Reference: reference/visualize.md for the comp round.\n`; } -if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) { +export function sameMainModulePath(left, right, platform = process.platform) { + if (platform !== 'win32') return left === right; + const normalizeDriveLetter = (value) => value.replace(/^([a-z]):/i, (_, drive) => `${drive.toUpperCase()}:`); + return normalizeDriveLetter(left) === normalizeDriveLetter(right); +} + +function isMainModule() { + if (!process.argv[1]) return false; + try { + // Node resolves import.meta.url through symlinks but leaves argv[1] as the + // invoked path. Compare real paths so a linked skill still runs its CLI, + // normalizing the drive-letter casing that Windows junctions can change. + return sameMainModulePath( + realpathSync(process.argv[1]), + realpathSync(fileURLToPath(import.meta.url)) + ); + } catch { + return false; + } +} + +if (isMainModule()) { const args = process.argv.slice(2); const fromIdx = args.indexOf('--from'); const scopeIdx = args.indexOf('--scope'); diff --git a/plugin/skills/impeccable/scripts/concept-seed.mjs b/plugin/skills/impeccable/scripts/concept-seed.mjs index 991dc629b..8887f9b32 100644 --- a/plugin/skills/impeccable/scripts/concept-seed.mjs +++ b/plugin/skills/impeccable/scripts/concept-seed.mjs @@ -91,7 +91,7 @@ import crypto from 'node:crypto'; import { dirname, join, relative, resolve } from 'node:path'; -import { readFileSync } from 'node:fs'; +import { readFileSync, realpathSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; import { approvedPoolRevision, @@ -703,7 +703,28 @@ export function nextStepAfterChoice({ key, scope, cwd = process.cwd(), env = pro return `NEXT (comp-led, ${why}): the world is chosen; the composition is not. Run: node ${scripts}/build-phase.mjs start${seed} and follow its NEXT lines: it opens the comps phase (three comps under .impeccable/mocks/, one approved by the user through the decision page or structured question, sidecar "approved": true), then spec, plates, hero, sections, motion, responsive, review. Do not write page code before those gates close. Reference: reference/visualize.md for the comp round.\n`; } -if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) { +export function sameMainModulePath(left, right, platform = process.platform) { + if (platform !== 'win32') return left === right; + const normalizeDriveLetter = (value) => value.replace(/^([a-z]):/i, (_, drive) => `${drive.toUpperCase()}:`); + return normalizeDriveLetter(left) === normalizeDriveLetter(right); +} + +function isMainModule() { + if (!process.argv[1]) return false; + try { + // Node resolves import.meta.url through symlinks but leaves argv[1] as the + // invoked path. Compare real paths so a linked skill still runs its CLI, + // normalizing the drive-letter casing that Windows junctions can change. + return sameMainModulePath( + realpathSync(process.argv[1]), + realpathSync(fileURLToPath(import.meta.url)) + ); + } catch { + return false; + } +} + +if (isMainModule()) { const args = process.argv.slice(2); const fromIdx = args.indexOf('--from'); const scopeIdx = args.indexOf('--scope');