diff --git a/.agents/skills/impeccable/scripts/lib/surface-briefs.mjs b/.agents/skills/impeccable/scripts/lib/surface-briefs.mjs index f83416f69..83783517f 100644 --- a/.agents/skills/impeccable/scripts/lib/surface-briefs.mjs +++ b/.agents/skills/impeccable/scripts/lib/surface-briefs.mjs @@ -8,6 +8,12 @@ export function getSurfaceBriefDir(projectRoot) { return path.join(projectRoot, '.impeccable', 'surfaces'); } +function normalizeRouteTarget(route) { + if (!route.startsWith('/') || route.includes('..')) return null; + const normalized = route.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; + return `route:${normalized}`; +} + export function normalizeSurfaceTarget(target, { projectRoot = process.cwd() } = {}) { if (!target || typeof target !== 'string' || !target.trim()) return null; const trimmed = target.trim(); @@ -21,21 +27,13 @@ export function normalizeSurfaceTarget(target, { projectRoot = process.cwd() } = return null; } } - if (/^route:/i.test(trimmed)) { - const route = trimmed.slice(trimmed.indexOf(':') + 1).trim(); - if (!route.startsWith('/') || route.includes('..')) return null; - const normalizedRoute = route.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; - return `route:${normalizedRoute}`; - } - if (trimmed === '/') return 'route:/'; + if (/^route:/i.test(trimmed)) return normalizeRouteTarget(trimmed.slice(trimmed.indexOf(':') + 1).trim()); + if (trimmed === '/') return normalizeRouteTarget(trimmed); if (trimmed.startsWith('/')) { const absolute = path.resolve(trimmed); const relativeToProject = path.relative(projectRoot, absolute); const isProjectFile = relativeToProject && !relativeToProject.startsWith('..') && !path.isAbsolute(relativeToProject); - if (!isProjectFile && !fs.existsSync(absolute) && !trimmed.includes('..')) { - const normalizedRoute = trimmed.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; - return `route:${normalizedRoute}`; - } + if (!isProjectFile && !fs.existsSync(absolute)) return normalizeRouteTarget(trimmed); } const abs = path.isAbsolute(trimmed) ? trimmed : path.resolve(projectRoot, trimmed); const rel = path.relative(projectRoot, abs); diff --git a/.claude/skills/impeccable/scripts/lib/surface-briefs.mjs b/.claude/skills/impeccable/scripts/lib/surface-briefs.mjs index f83416f69..83783517f 100644 --- a/.claude/skills/impeccable/scripts/lib/surface-briefs.mjs +++ b/.claude/skills/impeccable/scripts/lib/surface-briefs.mjs @@ -8,6 +8,12 @@ export function getSurfaceBriefDir(projectRoot) { return path.join(projectRoot, '.impeccable', 'surfaces'); } +function normalizeRouteTarget(route) { + if (!route.startsWith('/') || route.includes('..')) return null; + const normalized = route.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; + return `route:${normalized}`; +} + export function normalizeSurfaceTarget(target, { projectRoot = process.cwd() } = {}) { if (!target || typeof target !== 'string' || !target.trim()) return null; const trimmed = target.trim(); @@ -21,21 +27,13 @@ export function normalizeSurfaceTarget(target, { projectRoot = process.cwd() } = return null; } } - if (/^route:/i.test(trimmed)) { - const route = trimmed.slice(trimmed.indexOf(':') + 1).trim(); - if (!route.startsWith('/') || route.includes('..')) return null; - const normalizedRoute = route.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; - return `route:${normalizedRoute}`; - } - if (trimmed === '/') return 'route:/'; + if (/^route:/i.test(trimmed)) return normalizeRouteTarget(trimmed.slice(trimmed.indexOf(':') + 1).trim()); + if (trimmed === '/') return normalizeRouteTarget(trimmed); if (trimmed.startsWith('/')) { const absolute = path.resolve(trimmed); const relativeToProject = path.relative(projectRoot, absolute); const isProjectFile = relativeToProject && !relativeToProject.startsWith('..') && !path.isAbsolute(relativeToProject); - if (!isProjectFile && !fs.existsSync(absolute) && !trimmed.includes('..')) { - const normalizedRoute = trimmed.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; - return `route:${normalizedRoute}`; - } + if (!isProjectFile && !fs.existsSync(absolute)) return normalizeRouteTarget(trimmed); } const abs = path.isAbsolute(trimmed) ? trimmed : path.resolve(projectRoot, trimmed); const rel = path.relative(projectRoot, abs); diff --git a/.cursor/skills/impeccable/scripts/lib/surface-briefs.mjs b/.cursor/skills/impeccable/scripts/lib/surface-briefs.mjs index f83416f69..83783517f 100644 --- a/.cursor/skills/impeccable/scripts/lib/surface-briefs.mjs +++ b/.cursor/skills/impeccable/scripts/lib/surface-briefs.mjs @@ -8,6 +8,12 @@ export function getSurfaceBriefDir(projectRoot) { return path.join(projectRoot, '.impeccable', 'surfaces'); } +function normalizeRouteTarget(route) { + if (!route.startsWith('/') || route.includes('..')) return null; + const normalized = route.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; + return `route:${normalized}`; +} + export function normalizeSurfaceTarget(target, { projectRoot = process.cwd() } = {}) { if (!target || typeof target !== 'string' || !target.trim()) return null; const trimmed = target.trim(); @@ -21,21 +27,13 @@ export function normalizeSurfaceTarget(target, { projectRoot = process.cwd() } = return null; } } - if (/^route:/i.test(trimmed)) { - const route = trimmed.slice(trimmed.indexOf(':') + 1).trim(); - if (!route.startsWith('/') || route.includes('..')) return null; - const normalizedRoute = route.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; - return `route:${normalizedRoute}`; - } - if (trimmed === '/') return 'route:/'; + if (/^route:/i.test(trimmed)) return normalizeRouteTarget(trimmed.slice(trimmed.indexOf(':') + 1).trim()); + if (trimmed === '/') return normalizeRouteTarget(trimmed); if (trimmed.startsWith('/')) { const absolute = path.resolve(trimmed); const relativeToProject = path.relative(projectRoot, absolute); const isProjectFile = relativeToProject && !relativeToProject.startsWith('..') && !path.isAbsolute(relativeToProject); - if (!isProjectFile && !fs.existsSync(absolute) && !trimmed.includes('..')) { - const normalizedRoute = trimmed.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; - return `route:${normalizedRoute}`; - } + if (!isProjectFile && !fs.existsSync(absolute)) return normalizeRouteTarget(trimmed); } const abs = path.isAbsolute(trimmed) ? trimmed : path.resolve(projectRoot, trimmed); const rel = path.relative(projectRoot, abs); diff --git a/.gemini/skills/impeccable/scripts/lib/surface-briefs.mjs b/.gemini/skills/impeccable/scripts/lib/surface-briefs.mjs index f83416f69..83783517f 100644 --- a/.gemini/skills/impeccable/scripts/lib/surface-briefs.mjs +++ b/.gemini/skills/impeccable/scripts/lib/surface-briefs.mjs @@ -8,6 +8,12 @@ export function getSurfaceBriefDir(projectRoot) { return path.join(projectRoot, '.impeccable', 'surfaces'); } +function normalizeRouteTarget(route) { + if (!route.startsWith('/') || route.includes('..')) return null; + const normalized = route.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; + return `route:${normalized}`; +} + export function normalizeSurfaceTarget(target, { projectRoot = process.cwd() } = {}) { if (!target || typeof target !== 'string' || !target.trim()) return null; const trimmed = target.trim(); @@ -21,21 +27,13 @@ export function normalizeSurfaceTarget(target, { projectRoot = process.cwd() } = return null; } } - if (/^route:/i.test(trimmed)) { - const route = trimmed.slice(trimmed.indexOf(':') + 1).trim(); - if (!route.startsWith('/') || route.includes('..')) return null; - const normalizedRoute = route.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; - return `route:${normalizedRoute}`; - } - if (trimmed === '/') return 'route:/'; + if (/^route:/i.test(trimmed)) return normalizeRouteTarget(trimmed.slice(trimmed.indexOf(':') + 1).trim()); + if (trimmed === '/') return normalizeRouteTarget(trimmed); if (trimmed.startsWith('/')) { const absolute = path.resolve(trimmed); const relativeToProject = path.relative(projectRoot, absolute); const isProjectFile = relativeToProject && !relativeToProject.startsWith('..') && !path.isAbsolute(relativeToProject); - if (!isProjectFile && !fs.existsSync(absolute) && !trimmed.includes('..')) { - const normalizedRoute = trimmed.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; - return `route:${normalizedRoute}`; - } + if (!isProjectFile && !fs.existsSync(absolute)) return normalizeRouteTarget(trimmed); } const abs = path.isAbsolute(trimmed) ? trimmed : path.resolve(projectRoot, trimmed); const rel = path.relative(projectRoot, abs); diff --git a/.github/skills/impeccable/scripts/lib/surface-briefs.mjs b/.github/skills/impeccable/scripts/lib/surface-briefs.mjs index f83416f69..83783517f 100644 --- a/.github/skills/impeccable/scripts/lib/surface-briefs.mjs +++ b/.github/skills/impeccable/scripts/lib/surface-briefs.mjs @@ -8,6 +8,12 @@ export function getSurfaceBriefDir(projectRoot) { return path.join(projectRoot, '.impeccable', 'surfaces'); } +function normalizeRouteTarget(route) { + if (!route.startsWith('/') || route.includes('..')) return null; + const normalized = route.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; + return `route:${normalized}`; +} + export function normalizeSurfaceTarget(target, { projectRoot = process.cwd() } = {}) { if (!target || typeof target !== 'string' || !target.trim()) return null; const trimmed = target.trim(); @@ -21,21 +27,13 @@ export function normalizeSurfaceTarget(target, { projectRoot = process.cwd() } = return null; } } - if (/^route:/i.test(trimmed)) { - const route = trimmed.slice(trimmed.indexOf(':') + 1).trim(); - if (!route.startsWith('/') || route.includes('..')) return null; - const normalizedRoute = route.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; - return `route:${normalizedRoute}`; - } - if (trimmed === '/') return 'route:/'; + if (/^route:/i.test(trimmed)) return normalizeRouteTarget(trimmed.slice(trimmed.indexOf(':') + 1).trim()); + if (trimmed === '/') return normalizeRouteTarget(trimmed); if (trimmed.startsWith('/')) { const absolute = path.resolve(trimmed); const relativeToProject = path.relative(projectRoot, absolute); const isProjectFile = relativeToProject && !relativeToProject.startsWith('..') && !path.isAbsolute(relativeToProject); - if (!isProjectFile && !fs.existsSync(absolute) && !trimmed.includes('..')) { - const normalizedRoute = trimmed.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; - return `route:${normalizedRoute}`; - } + if (!isProjectFile && !fs.existsSync(absolute)) return normalizeRouteTarget(trimmed); } const abs = path.isAbsolute(trimmed) ? trimmed : path.resolve(projectRoot, trimmed); const rel = path.relative(projectRoot, abs); diff --git a/.grok/skills/impeccable/scripts/lib/surface-briefs.mjs b/.grok/skills/impeccable/scripts/lib/surface-briefs.mjs index f83416f69..83783517f 100644 --- a/.grok/skills/impeccable/scripts/lib/surface-briefs.mjs +++ b/.grok/skills/impeccable/scripts/lib/surface-briefs.mjs @@ -8,6 +8,12 @@ export function getSurfaceBriefDir(projectRoot) { return path.join(projectRoot, '.impeccable', 'surfaces'); } +function normalizeRouteTarget(route) { + if (!route.startsWith('/') || route.includes('..')) return null; + const normalized = route.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; + return `route:${normalized}`; +} + export function normalizeSurfaceTarget(target, { projectRoot = process.cwd() } = {}) { if (!target || typeof target !== 'string' || !target.trim()) return null; const trimmed = target.trim(); @@ -21,21 +27,13 @@ export function normalizeSurfaceTarget(target, { projectRoot = process.cwd() } = return null; } } - if (/^route:/i.test(trimmed)) { - const route = trimmed.slice(trimmed.indexOf(':') + 1).trim(); - if (!route.startsWith('/') || route.includes('..')) return null; - const normalizedRoute = route.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; - return `route:${normalizedRoute}`; - } - if (trimmed === '/') return 'route:/'; + if (/^route:/i.test(trimmed)) return normalizeRouteTarget(trimmed.slice(trimmed.indexOf(':') + 1).trim()); + if (trimmed === '/') return normalizeRouteTarget(trimmed); if (trimmed.startsWith('/')) { const absolute = path.resolve(trimmed); const relativeToProject = path.relative(projectRoot, absolute); const isProjectFile = relativeToProject && !relativeToProject.startsWith('..') && !path.isAbsolute(relativeToProject); - if (!isProjectFile && !fs.existsSync(absolute) && !trimmed.includes('..')) { - const normalizedRoute = trimmed.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; - return `route:${normalizedRoute}`; - } + if (!isProjectFile && !fs.existsSync(absolute)) return normalizeRouteTarget(trimmed); } const abs = path.isAbsolute(trimmed) ? trimmed : path.resolve(projectRoot, trimmed); const rel = path.relative(projectRoot, abs); diff --git a/.hermes/skills/impeccable/scripts/lib/surface-briefs.mjs b/.hermes/skills/impeccable/scripts/lib/surface-briefs.mjs index f83416f69..83783517f 100644 --- a/.hermes/skills/impeccable/scripts/lib/surface-briefs.mjs +++ b/.hermes/skills/impeccable/scripts/lib/surface-briefs.mjs @@ -8,6 +8,12 @@ export function getSurfaceBriefDir(projectRoot) { return path.join(projectRoot, '.impeccable', 'surfaces'); } +function normalizeRouteTarget(route) { + if (!route.startsWith('/') || route.includes('..')) return null; + const normalized = route.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; + return `route:${normalized}`; +} + export function normalizeSurfaceTarget(target, { projectRoot = process.cwd() } = {}) { if (!target || typeof target !== 'string' || !target.trim()) return null; const trimmed = target.trim(); @@ -21,21 +27,13 @@ export function normalizeSurfaceTarget(target, { projectRoot = process.cwd() } = return null; } } - if (/^route:/i.test(trimmed)) { - const route = trimmed.slice(trimmed.indexOf(':') + 1).trim(); - if (!route.startsWith('/') || route.includes('..')) return null; - const normalizedRoute = route.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; - return `route:${normalizedRoute}`; - } - if (trimmed === '/') return 'route:/'; + if (/^route:/i.test(trimmed)) return normalizeRouteTarget(trimmed.slice(trimmed.indexOf(':') + 1).trim()); + if (trimmed === '/') return normalizeRouteTarget(trimmed); if (trimmed.startsWith('/')) { const absolute = path.resolve(trimmed); const relativeToProject = path.relative(projectRoot, absolute); const isProjectFile = relativeToProject && !relativeToProject.startsWith('..') && !path.isAbsolute(relativeToProject); - if (!isProjectFile && !fs.existsSync(absolute) && !trimmed.includes('..')) { - const normalizedRoute = trimmed.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; - return `route:${normalizedRoute}`; - } + if (!isProjectFile && !fs.existsSync(absolute)) return normalizeRouteTarget(trimmed); } const abs = path.isAbsolute(trimmed) ? trimmed : path.resolve(projectRoot, trimmed); const rel = path.relative(projectRoot, abs); diff --git a/.kiro/skills/impeccable/scripts/lib/surface-briefs.mjs b/.kiro/skills/impeccable/scripts/lib/surface-briefs.mjs index f83416f69..83783517f 100644 --- a/.kiro/skills/impeccable/scripts/lib/surface-briefs.mjs +++ b/.kiro/skills/impeccable/scripts/lib/surface-briefs.mjs @@ -8,6 +8,12 @@ export function getSurfaceBriefDir(projectRoot) { return path.join(projectRoot, '.impeccable', 'surfaces'); } +function normalizeRouteTarget(route) { + if (!route.startsWith('/') || route.includes('..')) return null; + const normalized = route.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; + return `route:${normalized}`; +} + export function normalizeSurfaceTarget(target, { projectRoot = process.cwd() } = {}) { if (!target || typeof target !== 'string' || !target.trim()) return null; const trimmed = target.trim(); @@ -21,21 +27,13 @@ export function normalizeSurfaceTarget(target, { projectRoot = process.cwd() } = return null; } } - if (/^route:/i.test(trimmed)) { - const route = trimmed.slice(trimmed.indexOf(':') + 1).trim(); - if (!route.startsWith('/') || route.includes('..')) return null; - const normalizedRoute = route.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; - return `route:${normalizedRoute}`; - } - if (trimmed === '/') return 'route:/'; + if (/^route:/i.test(trimmed)) return normalizeRouteTarget(trimmed.slice(trimmed.indexOf(':') + 1).trim()); + if (trimmed === '/') return normalizeRouteTarget(trimmed); if (trimmed.startsWith('/')) { const absolute = path.resolve(trimmed); const relativeToProject = path.relative(projectRoot, absolute); const isProjectFile = relativeToProject && !relativeToProject.startsWith('..') && !path.isAbsolute(relativeToProject); - if (!isProjectFile && !fs.existsSync(absolute) && !trimmed.includes('..')) { - const normalizedRoute = trimmed.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; - return `route:${normalizedRoute}`; - } + if (!isProjectFile && !fs.existsSync(absolute)) return normalizeRouteTarget(trimmed); } const abs = path.isAbsolute(trimmed) ? trimmed : path.resolve(projectRoot, trimmed); const rel = path.relative(projectRoot, abs); diff --git a/.opencode/skills/impeccable/scripts/lib/surface-briefs.mjs b/.opencode/skills/impeccable/scripts/lib/surface-briefs.mjs index f83416f69..83783517f 100644 --- a/.opencode/skills/impeccable/scripts/lib/surface-briefs.mjs +++ b/.opencode/skills/impeccable/scripts/lib/surface-briefs.mjs @@ -8,6 +8,12 @@ export function getSurfaceBriefDir(projectRoot) { return path.join(projectRoot, '.impeccable', 'surfaces'); } +function normalizeRouteTarget(route) { + if (!route.startsWith('/') || route.includes('..')) return null; + const normalized = route.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; + return `route:${normalized}`; +} + export function normalizeSurfaceTarget(target, { projectRoot = process.cwd() } = {}) { if (!target || typeof target !== 'string' || !target.trim()) return null; const trimmed = target.trim(); @@ -21,21 +27,13 @@ export function normalizeSurfaceTarget(target, { projectRoot = process.cwd() } = return null; } } - if (/^route:/i.test(trimmed)) { - const route = trimmed.slice(trimmed.indexOf(':') + 1).trim(); - if (!route.startsWith('/') || route.includes('..')) return null; - const normalizedRoute = route.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; - return `route:${normalizedRoute}`; - } - if (trimmed === '/') return 'route:/'; + if (/^route:/i.test(trimmed)) return normalizeRouteTarget(trimmed.slice(trimmed.indexOf(':') + 1).trim()); + if (trimmed === '/') return normalizeRouteTarget(trimmed); if (trimmed.startsWith('/')) { const absolute = path.resolve(trimmed); const relativeToProject = path.relative(projectRoot, absolute); const isProjectFile = relativeToProject && !relativeToProject.startsWith('..') && !path.isAbsolute(relativeToProject); - if (!isProjectFile && !fs.existsSync(absolute) && !trimmed.includes('..')) { - const normalizedRoute = trimmed.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; - return `route:${normalizedRoute}`; - } + if (!isProjectFile && !fs.existsSync(absolute)) return normalizeRouteTarget(trimmed); } const abs = path.isAbsolute(trimmed) ? trimmed : path.resolve(projectRoot, trimmed); const rel = path.relative(projectRoot, abs); diff --git a/.pi/skills/impeccable/scripts/lib/surface-briefs.mjs b/.pi/skills/impeccable/scripts/lib/surface-briefs.mjs index f83416f69..83783517f 100644 --- a/.pi/skills/impeccable/scripts/lib/surface-briefs.mjs +++ b/.pi/skills/impeccable/scripts/lib/surface-briefs.mjs @@ -8,6 +8,12 @@ export function getSurfaceBriefDir(projectRoot) { return path.join(projectRoot, '.impeccable', 'surfaces'); } +function normalizeRouteTarget(route) { + if (!route.startsWith('/') || route.includes('..')) return null; + const normalized = route.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; + return `route:${normalized}`; +} + export function normalizeSurfaceTarget(target, { projectRoot = process.cwd() } = {}) { if (!target || typeof target !== 'string' || !target.trim()) return null; const trimmed = target.trim(); @@ -21,21 +27,13 @@ export function normalizeSurfaceTarget(target, { projectRoot = process.cwd() } = return null; } } - if (/^route:/i.test(trimmed)) { - const route = trimmed.slice(trimmed.indexOf(':') + 1).trim(); - if (!route.startsWith('/') || route.includes('..')) return null; - const normalizedRoute = route.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; - return `route:${normalizedRoute}`; - } - if (trimmed === '/') return 'route:/'; + if (/^route:/i.test(trimmed)) return normalizeRouteTarget(trimmed.slice(trimmed.indexOf(':') + 1).trim()); + if (trimmed === '/') return normalizeRouteTarget(trimmed); if (trimmed.startsWith('/')) { const absolute = path.resolve(trimmed); const relativeToProject = path.relative(projectRoot, absolute); const isProjectFile = relativeToProject && !relativeToProject.startsWith('..') && !path.isAbsolute(relativeToProject); - if (!isProjectFile && !fs.existsSync(absolute) && !trimmed.includes('..')) { - const normalizedRoute = trimmed.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; - return `route:${normalizedRoute}`; - } + if (!isProjectFile && !fs.existsSync(absolute)) return normalizeRouteTarget(trimmed); } const abs = path.isAbsolute(trimmed) ? trimmed : path.resolve(projectRoot, trimmed); const rel = path.relative(projectRoot, abs); diff --git a/.qoder/skills/impeccable/scripts/lib/surface-briefs.mjs b/.qoder/skills/impeccable/scripts/lib/surface-briefs.mjs index f83416f69..83783517f 100644 --- a/.qoder/skills/impeccable/scripts/lib/surface-briefs.mjs +++ b/.qoder/skills/impeccable/scripts/lib/surface-briefs.mjs @@ -8,6 +8,12 @@ export function getSurfaceBriefDir(projectRoot) { return path.join(projectRoot, '.impeccable', 'surfaces'); } +function normalizeRouteTarget(route) { + if (!route.startsWith('/') || route.includes('..')) return null; + const normalized = route.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; + return `route:${normalized}`; +} + export function normalizeSurfaceTarget(target, { projectRoot = process.cwd() } = {}) { if (!target || typeof target !== 'string' || !target.trim()) return null; const trimmed = target.trim(); @@ -21,21 +27,13 @@ export function normalizeSurfaceTarget(target, { projectRoot = process.cwd() } = return null; } } - if (/^route:/i.test(trimmed)) { - const route = trimmed.slice(trimmed.indexOf(':') + 1).trim(); - if (!route.startsWith('/') || route.includes('..')) return null; - const normalizedRoute = route.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; - return `route:${normalizedRoute}`; - } - if (trimmed === '/') return 'route:/'; + if (/^route:/i.test(trimmed)) return normalizeRouteTarget(trimmed.slice(trimmed.indexOf(':') + 1).trim()); + if (trimmed === '/') return normalizeRouteTarget(trimmed); if (trimmed.startsWith('/')) { const absolute = path.resolve(trimmed); const relativeToProject = path.relative(projectRoot, absolute); const isProjectFile = relativeToProject && !relativeToProject.startsWith('..') && !path.isAbsolute(relativeToProject); - if (!isProjectFile && !fs.existsSync(absolute) && !trimmed.includes('..')) { - const normalizedRoute = trimmed.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; - return `route:${normalizedRoute}`; - } + if (!isProjectFile && !fs.existsSync(absolute)) return normalizeRouteTarget(trimmed); } const abs = path.isAbsolute(trimmed) ? trimmed : path.resolve(projectRoot, trimmed); const rel = path.relative(projectRoot, abs); diff --git a/.rovodev/skills/impeccable/scripts/lib/surface-briefs.mjs b/.rovodev/skills/impeccable/scripts/lib/surface-briefs.mjs index f83416f69..83783517f 100644 --- a/.rovodev/skills/impeccable/scripts/lib/surface-briefs.mjs +++ b/.rovodev/skills/impeccable/scripts/lib/surface-briefs.mjs @@ -8,6 +8,12 @@ export function getSurfaceBriefDir(projectRoot) { return path.join(projectRoot, '.impeccable', 'surfaces'); } +function normalizeRouteTarget(route) { + if (!route.startsWith('/') || route.includes('..')) return null; + const normalized = route.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; + return `route:${normalized}`; +} + export function normalizeSurfaceTarget(target, { projectRoot = process.cwd() } = {}) { if (!target || typeof target !== 'string' || !target.trim()) return null; const trimmed = target.trim(); @@ -21,21 +27,13 @@ export function normalizeSurfaceTarget(target, { projectRoot = process.cwd() } = return null; } } - if (/^route:/i.test(trimmed)) { - const route = trimmed.slice(trimmed.indexOf(':') + 1).trim(); - if (!route.startsWith('/') || route.includes('..')) return null; - const normalizedRoute = route.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; - return `route:${normalizedRoute}`; - } - if (trimmed === '/') return 'route:/'; + if (/^route:/i.test(trimmed)) return normalizeRouteTarget(trimmed.slice(trimmed.indexOf(':') + 1).trim()); + if (trimmed === '/') return normalizeRouteTarget(trimmed); if (trimmed.startsWith('/')) { const absolute = path.resolve(trimmed); const relativeToProject = path.relative(projectRoot, absolute); const isProjectFile = relativeToProject && !relativeToProject.startsWith('..') && !path.isAbsolute(relativeToProject); - if (!isProjectFile && !fs.existsSync(absolute) && !trimmed.includes('..')) { - const normalizedRoute = trimmed.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; - return `route:${normalizedRoute}`; - } + if (!isProjectFile && !fs.existsSync(absolute)) return normalizeRouteTarget(trimmed); } const abs = path.isAbsolute(trimmed) ? trimmed : path.resolve(projectRoot, trimmed); const rel = path.relative(projectRoot, abs); diff --git a/.trae-cn/skills/impeccable/scripts/lib/surface-briefs.mjs b/.trae-cn/skills/impeccable/scripts/lib/surface-briefs.mjs index f83416f69..83783517f 100644 --- a/.trae-cn/skills/impeccable/scripts/lib/surface-briefs.mjs +++ b/.trae-cn/skills/impeccable/scripts/lib/surface-briefs.mjs @@ -8,6 +8,12 @@ export function getSurfaceBriefDir(projectRoot) { return path.join(projectRoot, '.impeccable', 'surfaces'); } +function normalizeRouteTarget(route) { + if (!route.startsWith('/') || route.includes('..')) return null; + const normalized = route.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; + return `route:${normalized}`; +} + export function normalizeSurfaceTarget(target, { projectRoot = process.cwd() } = {}) { if (!target || typeof target !== 'string' || !target.trim()) return null; const trimmed = target.trim(); @@ -21,21 +27,13 @@ export function normalizeSurfaceTarget(target, { projectRoot = process.cwd() } = return null; } } - if (/^route:/i.test(trimmed)) { - const route = trimmed.slice(trimmed.indexOf(':') + 1).trim(); - if (!route.startsWith('/') || route.includes('..')) return null; - const normalizedRoute = route.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; - return `route:${normalizedRoute}`; - } - if (trimmed === '/') return 'route:/'; + if (/^route:/i.test(trimmed)) return normalizeRouteTarget(trimmed.slice(trimmed.indexOf(':') + 1).trim()); + if (trimmed === '/') return normalizeRouteTarget(trimmed); if (trimmed.startsWith('/')) { const absolute = path.resolve(trimmed); const relativeToProject = path.relative(projectRoot, absolute); const isProjectFile = relativeToProject && !relativeToProject.startsWith('..') && !path.isAbsolute(relativeToProject); - if (!isProjectFile && !fs.existsSync(absolute) && !trimmed.includes('..')) { - const normalizedRoute = trimmed.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; - return `route:${normalizedRoute}`; - } + if (!isProjectFile && !fs.existsSync(absolute)) return normalizeRouteTarget(trimmed); } const abs = path.isAbsolute(trimmed) ? trimmed : path.resolve(projectRoot, trimmed); const rel = path.relative(projectRoot, abs); diff --git a/.trae/skills/impeccable/scripts/lib/surface-briefs.mjs b/.trae/skills/impeccable/scripts/lib/surface-briefs.mjs index f83416f69..83783517f 100644 --- a/.trae/skills/impeccable/scripts/lib/surface-briefs.mjs +++ b/.trae/skills/impeccable/scripts/lib/surface-briefs.mjs @@ -8,6 +8,12 @@ export function getSurfaceBriefDir(projectRoot) { return path.join(projectRoot, '.impeccable', 'surfaces'); } +function normalizeRouteTarget(route) { + if (!route.startsWith('/') || route.includes('..')) return null; + const normalized = route.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; + return `route:${normalized}`; +} + export function normalizeSurfaceTarget(target, { projectRoot = process.cwd() } = {}) { if (!target || typeof target !== 'string' || !target.trim()) return null; const trimmed = target.trim(); @@ -21,21 +27,13 @@ export function normalizeSurfaceTarget(target, { projectRoot = process.cwd() } = return null; } } - if (/^route:/i.test(trimmed)) { - const route = trimmed.slice(trimmed.indexOf(':') + 1).trim(); - if (!route.startsWith('/') || route.includes('..')) return null; - const normalizedRoute = route.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; - return `route:${normalizedRoute}`; - } - if (trimmed === '/') return 'route:/'; + if (/^route:/i.test(trimmed)) return normalizeRouteTarget(trimmed.slice(trimmed.indexOf(':') + 1).trim()); + if (trimmed === '/') return normalizeRouteTarget(trimmed); if (trimmed.startsWith('/')) { const absolute = path.resolve(trimmed); const relativeToProject = path.relative(projectRoot, absolute); const isProjectFile = relativeToProject && !relativeToProject.startsWith('..') && !path.isAbsolute(relativeToProject); - if (!isProjectFile && !fs.existsSync(absolute) && !trimmed.includes('..')) { - const normalizedRoute = trimmed.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; - return `route:${normalizedRoute}`; - } + if (!isProjectFile && !fs.existsSync(absolute)) return normalizeRouteTarget(trimmed); } const abs = path.isAbsolute(trimmed) ? trimmed : path.resolve(projectRoot, trimmed); const rel = path.relative(projectRoot, abs); diff --git a/.vibe/skills/impeccable/scripts/lib/surface-briefs.mjs b/.vibe/skills/impeccable/scripts/lib/surface-briefs.mjs index f83416f69..83783517f 100644 --- a/.vibe/skills/impeccable/scripts/lib/surface-briefs.mjs +++ b/.vibe/skills/impeccable/scripts/lib/surface-briefs.mjs @@ -8,6 +8,12 @@ export function getSurfaceBriefDir(projectRoot) { return path.join(projectRoot, '.impeccable', 'surfaces'); } +function normalizeRouteTarget(route) { + if (!route.startsWith('/') || route.includes('..')) return null; + const normalized = route.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; + return `route:${normalized}`; +} + export function normalizeSurfaceTarget(target, { projectRoot = process.cwd() } = {}) { if (!target || typeof target !== 'string' || !target.trim()) return null; const trimmed = target.trim(); @@ -21,21 +27,13 @@ export function normalizeSurfaceTarget(target, { projectRoot = process.cwd() } = return null; } } - if (/^route:/i.test(trimmed)) { - const route = trimmed.slice(trimmed.indexOf(':') + 1).trim(); - if (!route.startsWith('/') || route.includes('..')) return null; - const normalizedRoute = route.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; - return `route:${normalizedRoute}`; - } - if (trimmed === '/') return 'route:/'; + if (/^route:/i.test(trimmed)) return normalizeRouteTarget(trimmed.slice(trimmed.indexOf(':') + 1).trim()); + if (trimmed === '/') return normalizeRouteTarget(trimmed); if (trimmed.startsWith('/')) { const absolute = path.resolve(trimmed); const relativeToProject = path.relative(projectRoot, absolute); const isProjectFile = relativeToProject && !relativeToProject.startsWith('..') && !path.isAbsolute(relativeToProject); - if (!isProjectFile && !fs.existsSync(absolute) && !trimmed.includes('..')) { - const normalizedRoute = trimmed.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; - return `route:${normalizedRoute}`; - } + if (!isProjectFile && !fs.existsSync(absolute)) return normalizeRouteTarget(trimmed); } const abs = path.isAbsolute(trimmed) ? trimmed : path.resolve(projectRoot, trimmed); const rel = path.relative(projectRoot, abs); diff --git a/plugin/skills/impeccable/scripts/lib/surface-briefs.mjs b/plugin/skills/impeccable/scripts/lib/surface-briefs.mjs index f83416f69..83783517f 100644 --- a/plugin/skills/impeccable/scripts/lib/surface-briefs.mjs +++ b/plugin/skills/impeccable/scripts/lib/surface-briefs.mjs @@ -8,6 +8,12 @@ export function getSurfaceBriefDir(projectRoot) { return path.join(projectRoot, '.impeccable', 'surfaces'); } +function normalizeRouteTarget(route) { + if (!route.startsWith('/') || route.includes('..')) return null; + const normalized = route.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; + return `route:${normalized}`; +} + export function normalizeSurfaceTarget(target, { projectRoot = process.cwd() } = {}) { if (!target || typeof target !== 'string' || !target.trim()) return null; const trimmed = target.trim(); @@ -21,21 +27,13 @@ export function normalizeSurfaceTarget(target, { projectRoot = process.cwd() } = return null; } } - if (/^route:/i.test(trimmed)) { - const route = trimmed.slice(trimmed.indexOf(':') + 1).trim(); - if (!route.startsWith('/') || route.includes('..')) return null; - const normalizedRoute = route.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; - return `route:${normalizedRoute}`; - } - if (trimmed === '/') return 'route:/'; + if (/^route:/i.test(trimmed)) return normalizeRouteTarget(trimmed.slice(trimmed.indexOf(':') + 1).trim()); + if (trimmed === '/') return normalizeRouteTarget(trimmed); if (trimmed.startsWith('/')) { const absolute = path.resolve(trimmed); const relativeToProject = path.relative(projectRoot, absolute); const isProjectFile = relativeToProject && !relativeToProject.startsWith('..') && !path.isAbsolute(relativeToProject); - if (!isProjectFile && !fs.existsSync(absolute) && !trimmed.includes('..')) { - const normalizedRoute = trimmed.split(/[?#]/, 1)[0].replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/'; - return `route:${normalizedRoute}`; - } + if (!isProjectFile && !fs.existsSync(absolute)) return normalizeRouteTarget(trimmed); } const abs = path.isAbsolute(trimmed) ? trimmed : path.resolve(projectRoot, trimmed); const rel = path.relative(projectRoot, abs);