@inspecto-dev/plugin 0.3.3 → 0.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/index.cjs +180 -45
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.js +179 -44
  4. package/dist/index.js.map +1 -1
  5. package/dist/legacy/rspack/index.cjs +109 -19
  6. package/dist/legacy/rspack/index.cjs.map +1 -1
  7. package/dist/legacy/rspack/index.js +109 -19
  8. package/dist/legacy/rspack/index.js.map +1 -1
  9. package/dist/legacy/rspack/loader.cjs +49 -4
  10. package/dist/legacy/rspack/loader.cjs.map +1 -1
  11. package/dist/legacy/rspack/loader.js +49 -4
  12. package/dist/legacy/rspack/loader.js.map +1 -1
  13. package/dist/legacy/webpack4/index.cjs +121 -21
  14. package/dist/legacy/webpack4/index.cjs.map +1 -1
  15. package/dist/legacy/webpack4/index.d.cts +2 -0
  16. package/dist/legacy/webpack4/index.d.ts +2 -0
  17. package/dist/legacy/webpack4/index.js +121 -21
  18. package/dist/legacy/webpack4/index.js.map +1 -1
  19. package/dist/legacy/webpack4/loader.cjs +49 -4
  20. package/dist/legacy/webpack4/loader.cjs.map +1 -1
  21. package/dist/legacy/webpack4/loader.js +49 -4
  22. package/dist/legacy/webpack4/loader.js.map +1 -1
  23. package/dist/rollup.cjs +180 -45
  24. package/dist/rollup.cjs.map +1 -1
  25. package/dist/rollup.js +179 -44
  26. package/dist/rollup.js.map +1 -1
  27. package/dist/rspack.cjs +180 -45
  28. package/dist/rspack.cjs.map +1 -1
  29. package/dist/rspack.js +179 -44
  30. package/dist/rspack.js.map +1 -1
  31. package/dist/vite.cjs +180 -45
  32. package/dist/vite.cjs.map +1 -1
  33. package/dist/vite.js +179 -44
  34. package/dist/vite.js.map +1 -1
  35. package/dist/webpack.cjs +180 -45
  36. package/dist/webpack.cjs.map +1 -1
  37. package/dist/webpack.js +179 -44
  38. package/dist/webpack.js.map +1 -1
  39. package/package.json +6 -6
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/transform/utils.ts","../src/transform/index.ts","../src/transform/transform-jsx.ts","../src/transform/transform-vue.ts","../src/server/index.ts","../src/server/snippet.ts","../src/config.ts","../src/utils/logger.ts","../src/server/dispatch-transport.ts","../src/server/dispatch-runtime.ts","../src/server/path-guards.ts","../src/server/annotation-dispatch.ts","../src/server/client-config.ts","../src/server/open-file.ts","../src/server/project-root.ts","../src/injectors/utils.ts","../src/injectors/webpack.ts","../src/injectors/rspack.ts","../src/injectors/vite.ts"],"sourcesContent":["import { createUnplugin } from 'unplugin'\nimport type { UnpluginOptions } from '@inspecto-dev/types'\nimport { shouldTransform } from './transform/utils.js'\nimport { transformRouter, transformJsx } from './transform/index.js'\nimport { startServer, serverState } from './server/index.js'\nimport { resolveClientModule } from './injectors/utils.js'\nimport { injectWebpack } from './injectors/webpack.js'\nimport { injectRspack } from './injectors/rspack.js'\nimport { setGlobalLogLevel } from './config.js'\nimport { createLogger } from './utils/logger.js'\nimport {\n getViteVirtualModuleScript,\n VITE_VIRTUAL_MODULE_ID,\n VITE_VIRTUAL_IMPORT_ID,\n} from './injectors/vite.js'\n\nimport type { ViteDevServer } from 'vite'\n\nexport type { UnpluginOptions }\n\nconst DEFAULT_OPTIONS: Required<UnpluginOptions> = {\n include: [],\n exclude: [],\n escapeTags: [],\n pathType: 'absolute',\n attributeName: 'data-inspecto',\n logLevel: 'warn',\n}\n\nconst DEFAULT_PORT = 5678\n\nconst getCleanId = (id: string) => id.split('?')[0]!\n\nconst InspectoPlugin = createUnplugin<UnpluginOptions | undefined>((userOptions = {}) => {\n const options: Required<UnpluginOptions> = {\n ...DEFAULT_OPTIONS,\n ...userOptions,\n }\n\n // Sync global log level based on user config\n setGlobalLogLevel(options.logLevel)\n const pluginLogger = createLogger('inspecto:plugin', { logLevel: options.logLevel })\n\n // Skip everything in production\n const isProduction = process.env['NODE_ENV'] === 'production'\n\n let projectRoot = process.cwd()\n let serverPort: number | null = null\n\n // Helper to ensure server is started\n const ensureServer = async () => {\n if (serverPort === null) {\n serverPort = await startServer()\n }\n return serverPort\n }\n\n return {\n name: 'inspecto-overlay',\n enforce: 'pre',\n\n buildStart() {\n if (isProduction) return\n projectRoot = serverState.cwd || process.cwd()\n\n // For pure bundlers (Rollup, Esbuild) that don't have devServer hooks\n // we need to ensure the server starts early enough.\n ensureServer().catch(err => pluginLogger.error('Failed to start server:', err))\n },\n\n buildEnd() {\n // Server cleanup is handled by process exit (server is unref'd, port file\n // removed via process.once('exit')). Calling stopServer() here would break\n // esbuild watch mode (which fires buildEnd after every incremental rebuild)\n // and is unnecessary for Vite/Rspack which manage their own lifecycles.\n },\n\n webpack: compiler => {\n if (isProduction) return\n injectWebpack(compiler, ensureServer, resolveClientModule)\n },\n\n rspack: compiler => {\n if (isProduction) return\n injectRspack(compiler, ensureServer, resolveClientModule)\n },\n\n vite: {\n config(config) {\n if (isProduction) return config\n return {\n ...config,\n define: {\n ...config.define,\n __AI_INSPECTOR_PORT__: JSON.stringify(DEFAULT_PORT), // Placeholder, rewritten in configureServer\n },\n }\n },\n\n resolveId(id) {\n if (id === 'virtual:inspecto-client') {\n return VITE_VIRTUAL_MODULE_ID\n }\n return null\n },\n\n load(id) {\n if (id === VITE_VIRTUAL_MODULE_ID) {\n // serverPort is guaranteed to be set by the time Vite requests this module\n // (configureServer awaits ensureServer before the dev server accepts requests)\n return getViteVirtualModuleScript(serverPort ?? DEFAULT_PORT)\n }\n return null\n },\n\n async configureServer(server: ViteDevServer) {\n if (isProduction) return\n const port = await ensureServer()\n if (!server.config.define) {\n ;(server.config as any).define = {}\n }\n ;(server.config as any).define['__AI_INSPECTOR_PORT__'] = JSON.stringify(port)\n // Invalidate the virtual module so load() re-runs with the correct port\n // (guards against the race where load() was called before configureServer resolved)\n const mod = server.moduleGraph.getModuleById(VITE_VIRTUAL_MODULE_ID)\n if (mod) server.moduleGraph.invalidateModule(mod)\n },\n\n transformIndexHtml(html) {\n if (isProduction || !serverPort) return html\n return {\n html,\n tags: [\n {\n tag: 'script',\n attrs: { type: 'module' },\n children: `import '${VITE_VIRTUAL_IMPORT_ID}';`,\n },\n ],\n }\n },\n },\n\n transformInclude(id) {\n if (isProduction || !id) return false\n const cleanId = getCleanId(id)\n return shouldTransform(cleanId, options)\n },\n\n transform(code, id) {\n if (isProduction || !id) return null\n\n const cleanId = getCleanId(id)\n\n const result = transformRouter({\n filePath: cleanId,\n source: code,\n projectRoot,\n pluginOptions: options,\n })\n\n if (!result || !result.changed) return null\n\n return {\n code: result.code,\n map: result.map,\n }\n },\n }\n})\n\nexport const unplugin = InspectoPlugin\nexport const vitePlugin = InspectoPlugin.vite\nexport const webpackPlugin: (options?: UnpluginOptions) => any = InspectoPlugin.webpack\nexport const rspackPlugin = InspectoPlugin.rspack\nexport const rollupPlugin = InspectoPlugin.rollup\nexport const esbuildPlugin = InspectoPlugin.esbuild\nexport { transformJsx }\nexport default InspectoPlugin\n","import type { UnpluginOptions } from '@inspecto-dev/types'\nimport type MagicString from 'magic-string'\n\nexport interface TransformResult {\n code: string\n map: ReturnType<MagicString['generateMap']> | null\n changed: boolean\n}\n\n/** Default tags whose JSX elements should NOT receive data-inspecto attributes */\nexport const DEFAULT_ESCAPE_TAGS = new Set([\n 'template',\n 'script',\n 'style',\n // React special elements\n 'Fragment',\n 'React.Fragment',\n 'StrictMode',\n 'React.StrictMode',\n 'Suspense',\n 'React.Suspense',\n 'Profiler',\n 'React.Profiler',\n // React transitions\n 'Transition',\n 'TransitionGroup',\n // Vue built-in components\n 'KeepAlive',\n 'Teleport',\n 'Suspense',\n // Vue router built-ins\n 'RouterView',\n 'RouterLink',\n 'NuxtPage',\n 'NuxtLink',\n])\n\n/** File extensions that contain JSX/TSX syntax */\nexport const JSX_EXTENSIONS = new Set(['.jsx', '.tsx', '.js', '.ts', '.mjs', '.mts'])\n\n/**\n * Determine if a file should be transformed.\n * Always skips node_modules and dist directories.\n */\nexport function shouldTransform(filePath: string, options: Required<UnpluginOptions>): boolean {\n // Never transform in production\n if (process.env['NODE_ENV'] === 'production') return false\n\n // Skip node_modules always\n if (filePath.includes('node_modules')) return false\n\n // Skip virtual modules\n if (filePath.startsWith('\\x00')) return false\n\n // Skip dist/build directories\n if (/[/\\\\](dist|build|\\.next|\\.nuxt)[/\\\\]/.test(filePath)) return false\n\n // Skip non-code files (like .html, .css)\n const ext = filePath.split('.').pop()?.toLowerCase()\n if (ext && !['js', 'jsx', 'ts', 'tsx', 'mjs', 'mts', 'vue'].includes(ext)) {\n return false\n }\n\n // Check user-defined exclude patterns\n // (picomatch integration — see index.ts for how options.exclude is applied)\n\n return true\n}\n\n/**\n * Build the escape tags set from user options merged with defaults.\n */\nexport function buildEscapeTagsSet(escapeTags?: string[]): Set<string> {\n const merged = new Set(DEFAULT_ESCAPE_TAGS)\n if (escapeTags) {\n for (const tag of escapeTags) {\n merged.add(tag)\n }\n }\n return merged\n}\n\n/**\n * Format a source location value for the data-inspecto attribute.\n * Format: \"filepath:line:column\"\n */\nexport function formatAttrValue(file: string, line: number, column: number): string {\n return `${file}:${line}:${column}`\n}\n","import path from 'node:path'\nimport type { UnpluginOptions } from '@inspecto-dev/types'\nimport { transformJsx } from './transform-jsx.js'\nimport { transformVue } from './transform-vue.js'\nimport { JSX_EXTENSIONS, type TransformResult } from './utils.js'\n\nexport interface RouterOptions {\n filePath: string\n source: string\n projectRoot: string\n pluginOptions: Required<UnpluginOptions>\n}\n\n/**\n * Route a file to the appropriate transform based on extension.\n * Returns null if no transform applies.\n */\nexport function transformRouter(options: RouterOptions): TransformResult | null {\n const { filePath, source, projectRoot, pluginOptions } = options\n const ext = path.extname(filePath).toLowerCase()\n\n if (JSX_EXTENSIONS.has(ext)) {\n return transformJsx({\n filePath,\n source,\n projectRoot,\n escapeTags: pluginOptions.escapeTags,\n pathType: pluginOptions.pathType,\n attributeName: pluginOptions.attributeName,\n })\n }\n\n // ── Vue SFC ──────────────────────────────────────────────────────────────\n if (ext === '.vue') {\n return transformVue({\n filePath,\n source,\n projectRoot,\n escapeTags: pluginOptions.escapeTags,\n pathType: pluginOptions.pathType,\n attributeName: pluginOptions.attributeName,\n })\n }\n\n return null\n}\n// Export transforms for testing\nexport { transformJsx, transformVue }\n","import * as parser from '@babel/parser'\nimport traverse_ from '@babel/traverse'\n// Support both ESM default and CommonJS module.exports\nconst traverse =\n typeof traverse_ === 'function' ? traverse_ : (traverse_ as any).default || traverse_\nimport type { NodePath } from '@babel/traverse'\nimport type { JSXOpeningElement } from '@babel/types'\nimport MagicString from 'magic-string'\nimport path from 'node:path'\nimport type { UnpluginOptions, PathType } from '@inspecto-dev/types'\nimport { buildEscapeTagsSet, formatAttrValue, type TransformResult } from './utils.js'\n\nexport interface TransformJsxOptions {\n filePath: string\n source: string\n projectRoot: string\n escapeTags?: string[]\n pathType?: PathType\n attributeName?: string\n}\n\n/**\n * Transform JSX/TSX source code by injecting data-inspecto attributes.\n */\nexport function transformJsx(options: TransformJsxOptions): TransformResult {\n const {\n filePath,\n source,\n projectRoot,\n escapeTags,\n pathType = 'absolute',\n attributeName = 'data-inspecto',\n } = options\n\n const escapeTagsSet = buildEscapeTagsSet(escapeTags)\n\n // Resolve the file path based on pathType config\n const resolvedPath =\n pathType === 'absolute'\n ? path.resolve(filePath)\n : path.relative(projectRoot, path.resolve(filePath))\n\n // Normalize path separators on Windows\n const normalizedPath = resolvedPath.replace(/\\\\/g, '/')\n\n let ast: ReturnType<typeof parser.parse>\n try {\n ast = parser.parse(source, {\n sourceType: 'module',\n plugins: [\n 'jsx',\n 'typescript',\n 'decorators-legacy',\n 'classProperties',\n 'optionalChaining',\n 'nullishCoalescingOperator',\n 'importMeta',\n ],\n errorRecovery: true,\n })\n } catch {\n // If parsing fails, return source unchanged\n return { code: source, map: null, changed: false }\n }\n\n const ms = new MagicString(source)\n let changed = false\n\n traverse(ast, {\n JSXOpeningElement(nodePath: NodePath<JSXOpeningElement>) {\n const node = nodePath.node\n\n // Skip elements that already have the attribute\n const alreadyHasAttr = node.attributes.some(\n attr =>\n attr.type === 'JSXAttribute' &&\n attr.name.type === 'JSXIdentifier' &&\n attr.name.name === attributeName,\n )\n if (alreadyHasAttr) return\n\n // Get element tag name\n const nameNode = node.name\n let tagName: string\n if (nameNode.type === 'JSXIdentifier') {\n tagName = nameNode.name\n } else if (nameNode.type === 'JSXMemberExpression') {\n const objName = nameNode.object.type === 'JSXIdentifier' ? nameNode.object.name : ''\n const propName = nameNode.property.type === 'JSXIdentifier' ? nameNode.property.name : ''\n tagName = objName && propName ? `${objName}.${propName}` : objName\n } else {\n tagName = ''\n }\n\n // Skip escaped tags\n if (escapeTagsSet.has(tagName)) return\n\n // Get position from AST location\n const loc = node.loc\n if (!loc) return\n\n const { line, column } = loc.start\n // Babel uses 0-based columns, convert to 1-based\n const attrValue = formatAttrValue(normalizedPath, line, column + 1)\n\n // Determine the best insertion position for the attribute\n // When a JSX element has type arguments (e.g. <Component<string> />),\n // inserting after `node.name.end` might inject inside the generic bracket `<`.\n // The safest place to insert is right before the first attribute,\n // or right before the closing slash/bracket if there are no attributes.\n let insertPos: number | null | undefined = null\n if (node.attributes && node.attributes.length > 0) {\n const firstAttr = node.attributes[0]\n if (firstAttr && firstAttr.start != null) {\n insertPos = firstAttr.start\n }\n }\n\n if (insertPos == null) {\n // Find the start of the closing bracket or self-closing slash\n // We know node.end is the index right after the '>'\n // So we look backwards. But Babel AST doesn't give us exact token positions\n // for the closing tag easily.\n // For a safe fallback, we use node.typeParameters?.end || node.name.end\n if (node.typeParameters && node.typeParameters.end != null) {\n insertPos = node.typeParameters.end\n } else if (node.name.end != null) {\n insertPos = node.name.end\n }\n }\n\n if (insertPos == null) return\n\n ms.appendLeft(\n insertPos,\n ` ${attributeName}=\"${attrValue}\"${node.attributes && node.attributes.length > 0 ? '' : ' '}`,\n )\n changed = true\n },\n })\n\n if (!changed) {\n return { code: source, map: null, changed: false }\n }\n\n return {\n code: ms.toString(),\n map: ms.generateMap({ hires: true, source: filePath }),\n changed: true,\n }\n}\n","import * as vueCompiler from '@vue/compiler-dom'\nimport { parse as parseSFC } from '@vue/compiler-sfc'\nimport type { ElementNode, AttributeNode } from '@vue/compiler-core'\nimport { NodeTypes } from '@vue/compiler-core'\nimport MagicString from 'magic-string'\nimport path from 'node:path'\nimport type { PathType } from '@inspecto-dev/types'\nimport { buildEscapeTagsSet, formatAttrValue, type TransformResult } from './utils.js'\n\nexport interface TransformVueOptions {\n filePath: string\n source: string\n projectRoot: string\n escapeTags?: string[]\n pathType?: PathType\n attributeName?: string\n}\n\n/**\n * Transform Vue SFC source by injecting data-inspecto attributes\n * into template elements.\n *\n * Strategy:\n * 1. Locate the <template> block in the SFC source\n * 2. Parse only the template block with @vue/compiler-dom\n * 3. Walk ElementNode nodes in the AST\n * 4. For each eligible element, inject the attribute using MagicString\n * at the exact offset within the original source\n */\nexport function transformVue(options: TransformVueOptions): TransformResult {\n const {\n filePath,\n source,\n projectRoot,\n escapeTags,\n pathType = 'absolute',\n attributeName = 'data-inspecto',\n } = options\n\n const escapeTagsSet = buildEscapeTagsSet(escapeTags)\n\n // Resolve path\n const resolvedPath =\n pathType === 'absolute'\n ? path.resolve(filePath)\n : path.relative(projectRoot, path.resolve(filePath))\n\n const normalizedPath = resolvedPath.replace(/\\\\/g, '/')\n\n // ── Find <template> block boundaries ──────────────────────────────────────\n // Use @vue/compiler-sfc to parse the file and extract the template block.\n // This is much safer than regex for handling nested templates.\n const { descriptor, errors } = parseSFC(source, {\n filename: filePath,\n sourceMap: false,\n ignoreEmpty: true,\n })\n\n if (errors.length > 0 || !descriptor.template) {\n return { code: source, map: null, changed: false }\n }\n\n const templateContent = descriptor.template.content\n const templateBlockStart = descriptor.template.loc.start.offset\n\n // ── Parse template block ───────────────────────────────────────────────────\n let ast: vueCompiler.RootNode\n try {\n ast = vueCompiler.parse(templateContent, {\n parseMode: 'html',\n // Preserve source locations relative to templateContent\n onError: () => {\n /* ignore non-fatal parse errors */\n },\n })\n } catch {\n return { code: source, map: null, changed: false }\n }\n\n const ms = new MagicString(source)\n let changed = false\n\n // ── Walk AST ───────────────────────────────────────────────────────────────\n walkElement(ast, node => {\n // Skip non-element nodes\n if (node.type !== NodeTypes.ELEMENT) return\n\n const tagName = node.tag\n\n // Skip escaped tags\n if (escapeTagsSet.has(tagName)) return\n\n // Skip <template> wrapper itself (it's the root, not a real element)\n if (tagName === 'template' && node === ast.children[0]) return\n\n // Skip elements that already have the attribute (idempotency)\n const alreadyHasAttr = node.props.some(\n (p): p is AttributeNode => p.type === NodeTypes.ATTRIBUTE && p.name === attributeName,\n )\n if (alreadyHasAttr) return\n\n // node.loc is relative to templateContent — add templateBlockStart offset\n const loc = node.loc\n if (!loc) return\n\n const { line, column } = loc.start\n\n // Calculate absolute line and column in the original source\n // @vue/compiler-dom uses 1-based line and 1-based column\n const templateStartLoc = descriptor.template!.loc.start\n const absoluteLine = templateStartLoc.line + line - 1\n const absoluteColumn = line === 1 ? templateStartLoc.column + column - 1 : column\n\n const attrValue = formatAttrValue(normalizedPath, absoluteLine, absoluteColumn)\n\n // Find insert position: right after the tag name in the original source\n // node.loc.start.offset is 0-based offset within templateContent\n const tagNameEnd = loc.start.offset + tagName.length + 1 // +1 for '<'\n const absoluteOffset = templateBlockStart + tagNameEnd\n\n ms.appendLeft(absoluteOffset, ` ${attributeName}=\"${attrValue}\"`)\n changed = true\n })\n\n if (!changed) {\n return { code: source, map: null, changed: false }\n }\n\n return {\n code: ms.toString(),\n map: ms.generateMap({ hires: true, source: filePath }),\n changed: true,\n }\n}\n\n// ── AST walker ────────────────────────────────────────────────────────────────\n\ntype AnyNode = vueCompiler.RootNode | vueCompiler.TemplateChildNode\n\nfunction walkElement(node: AnyNode, visitor: (node: ElementNode) => void): void {\n if (node.type === NodeTypes.ELEMENT) {\n visitor(node)\n for (const child of node.children) {\n walkElement(child as AnyNode, visitor)\n }\n } else if ('children' in node && Array.isArray(node.children)) {\n for (const child of node.children) {\n walkElement(child as AnyNode, visitor)\n }\n }\n}\n","import http from 'node:http'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport os from 'node:os'\nimport crypto from 'node:crypto'\nimport portfinder from 'portfinder'\nimport type {\n ServerState,\n OpenFileRequest,\n SendToAiRequest,\n SendToAiResponse,\n SendAnnotationsToAiRequest,\n SendAnnotationsToAiResponse,\n} from '@inspecto-dev/types'\nimport { INSPECTO_API_PATHS } from '@inspecto-dev/types'\nimport { extractSnippet } from './snippet.js'\nimport { dispatchAnnotationsToAi } from './annotation-dispatch.js'\nimport { readTicket } from './dispatch-transport.js'\nimport { dispatchPromptThroughIde, resolvePromptDispatchRuntime } from './dispatch-runtime.js'\nimport { assertPathWithinProject, resolveWorkspacePath } from './path-guards.js'\nimport { buildClientConfig } from './client-config.js'\nimport { handleOpenFileRequest } from './open-file.js'\nimport { resolveProjectRoot } from './project-root.js'\nimport { watchConfig, unwatchConfig, getGlobalLogLevel } from '../config.js'\nimport { createLogger } from '../utils/logger.js'\n\nconst serverLogger = createLogger('inspecto:server', { logLevel: getGlobalLogLevel() })\n\nexport const serverState: ServerState = {\n port: null,\n running: false,\n projectRoot: '',\n configRoot: '',\n cwd: process.cwd(),\n}\n\nlet serverInstance: http.Server | null = null\n\nexport async function startServer(): Promise<number> {\n if (serverState.running && serverState.port !== null) {\n return serverState.port\n }\n\n // Resolve project root at server start time so process.cwd() reflects the\n // actual project directory, not the module load-time cwd.\n serverState.projectRoot = resolveProjectRoot()\n serverState.configRoot = serverState.projectRoot\n serverState.cwd = process.cwd()\n\n portfinder.basePort = 5678\n const port = await portfinder.getPortPromise()\n\n // Watch for user config changes to trigger hot-reloads internally if needed\n watchConfig(\n () => {\n serverLogger.info('user config reloaded.')\n },\n serverState.cwd,\n serverState.configRoot,\n )\n\n serverInstance = http.createServer((req, res) => {\n res.setHeader('Access-Control-Allow-Origin', '*')\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type')\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204)\n res.end()\n return\n }\n\n const url = new URL(req.url ?? '/', `http://localhost:${port}`)\n handleRequest(url, req, res).catch(err => {\n serverLogger.error('server error:', err)\n res.writeHead(500, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ success: false, error: String(err) }))\n })\n })\n\n await new Promise<void>((resolve, reject) => {\n serverInstance!.listen(port, '127.0.0.1', () => {\n serverInstance!.unref() // Allow process to exit\n resolve()\n })\n serverInstance!.once('error', reject)\n })\n\n // Add persistent error handler after successful startup\n serverInstance!.on('error', err => {\n serverLogger.error('persistent server error:', err)\n })\n\n serverState.port = port\n serverState.running = true\n\n // Write port file so the IDE extension can discover the server without scanning ports\n const portFile = path.join(os.tmpdir(), 'inspecto.port.json')\n try {\n let portData: Record<string, number> = {}\n if (fs.existsSync(portFile)) {\n try {\n portData = JSON.parse(fs.readFileSync(portFile, 'utf-8'))\n } catch (e) {\n // Invalid JSON, start fresh\n }\n }\n // Hash the project root to avoid invalid keys or paths in JSON\n const rootHash = crypto.createHash('md5').update(serverState.projectRoot).digest('hex')\n portData[rootHash] = port\n fs.writeFileSync(portFile, JSON.stringify(portData, null, 2), 'utf-8')\n } catch (e) {\n serverLogger.warn('Failed to write port file:', e)\n /* non-fatal — extension will fall back to scanning */\n }\n // Clean up on process exit (Vite terminates the process, not stopServer)\n process.once('exit', () => {\n try {\n if (fs.existsSync(portFile)) {\n const portData = JSON.parse(fs.readFileSync(portFile, 'utf-8'))\n const rootHash = crypto.createHash('md5').update(serverState.projectRoot).digest('hex')\n delete portData[rootHash]\n if (Object.keys(portData).length === 0) {\n fs.unlinkSync(portFile)\n } else {\n fs.writeFileSync(portFile, JSON.stringify(portData, null, 2), 'utf-8')\n }\n }\n } catch {\n /* ignore */\n }\n })\n\n serverLogger.info(`server running at http://127.0.0.1:${port}`)\n\n return port\n}\n\nexport function stopServer(): void {\n if (serverInstance) {\n serverInstance.close()\n serverInstance = null\n }\n unwatchConfig()\n serverState.running = false\n serverState.port = null\n try {\n fs.unlinkSync(path.join(os.tmpdir(), 'inspecto.port'))\n } catch {\n /* ignore */\n }\n}\n\nasync function readBody(req: http.IncomingMessage): Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = []\n req.on('data', (chunk: Buffer) => chunks.push(chunk))\n req.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')))\n req.on('error', reject)\n })\n}\n\nexport async function handleRequest(\n url: URL,\n req: http.IncomingMessage,\n res: http.ServerResponse,\n): Promise<void> {\n const pathname = url.pathname\n\n // Health check - root or /inspecto/api/v1/health\n if ((pathname === '/health' || pathname === INSPECTO_API_PATHS.HEALTH) && req.method === 'GET') {\n res.writeHead(200, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ ok: true, port: serverState.port }))\n return\n }\n\n // Browser Client requests\n if (pathname === INSPECTO_API_PATHS.CLIENT_CONFIG && req.method === 'GET') {\n const config = await buildClientConfig(serverState)\n\n // Omit providers from the response sent to the client\n delete config.providers\n\n res.writeHead(200, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify(config))\n return\n }\n\n if (pathname === INSPECTO_API_PATHS.IDE_INFO && req.method === 'POST') {\n try {\n const body = JSON.parse(await readBody(req))\n\n // Workspace matching defense mechanism against multiple IDE connections\n const ideWorkspace = body.workspaceRoot || ''\n const serverProjectRoot = serverState.projectRoot || ''\n\n const normalizedIdeRoot = ideWorkspace ? path.resolve(ideWorkspace) : ''\n const normalizedServerRoot = serverProjectRoot ? path.resolve(serverProjectRoot) : ''\n\n const isSameProject =\n !normalizedIdeRoot ||\n !normalizedServerRoot ||\n normalizedIdeRoot === normalizedServerRoot ||\n normalizedServerRoot.startsWith(normalizedIdeRoot + path.sep) ||\n normalizedIdeRoot.startsWith(normalizedServerRoot + path.sep)\n\n if (isSameProject) {\n serverState.ideInfo = body\n serverLogger.debug(\n `Accepted IDE info from matched workspace (ide-${body.ide} / schema-${body.scheme})`,\n )\n } else {\n serverLogger.debug(\n `Ignored IDE info from unrelated workspace (IDE Workspace: ${ideWorkspace}, Server: ${serverProjectRoot}, Scheme: ${body.scheme}, IDE: ${body.ide})`,\n )\n }\n\n res.writeHead(200, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ success: true }))\n } catch (e) {\n serverLogger.error(`Error parsing ${INSPECTO_API_PATHS.IDE_INFO} POST request:`, e)\n res.writeHead(400, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ error: 'Invalid JSON body' }))\n }\n return\n }\n\n if (pathname === INSPECTO_API_PATHS.IDE_OPEN && req.method === 'POST') {\n let body: OpenFileRequest\n try {\n body = JSON.parse(await readBody(req)) as OpenFileRequest\n } catch (e) {\n res.writeHead(400, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ error: 'Invalid JSON body' }))\n return\n }\n\n try {\n handleOpenFileRequest(body, serverState)\n } catch {\n serverLogger.warn(`Security: Blocked path traversal attempt in IDE_OPEN: ${body.file}`)\n res.writeHead(403, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ error: 'Access denied: File is outside of project workspace' }))\n return\n }\n\n res.writeHead(200, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ success: true }))\n return\n }\n\n if (pathname === INSPECTO_API_PATHS.PROJECT_SNIPPET && req.method === 'GET') {\n const file = url.searchParams.get('file') ?? ''\n const line = parseInt(url.searchParams.get('line') ?? '1', 10)\n const column = parseInt(url.searchParams.get('column') ?? '1', 10)\n const maxLines = parseInt(url.searchParams.get('maxLines') ?? '100', 10)\n\n try {\n const absolutePath = resolveWorkspacePath(file, serverState.cwd)\n\n // Security: Prevent path traversal attacks\n try {\n assertPathWithinProject(absolutePath, serverState.projectRoot)\n } catch {\n serverLogger.warn(`Security: Blocked path traversal attempt in PROJECT_SNIPPET: ${file}`)\n res.writeHead(403, { 'Content-Type': 'application/json' })\n res.end(\n JSON.stringify({\n success: false,\n error: 'Access denied: File is outside of project workspace',\n errorCode: 'FORBIDDEN',\n }),\n )\n return\n }\n\n const result = await extractSnippet({ file: absolutePath, line, column, maxLines })\n res.writeHead(200, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify(result))\n } catch (err: any) {\n const message = String(err.message || err)\n const errorCode = message.startsWith('FILE_NOT_FOUND') ? 'FILE_NOT_FOUND' : 'UNKNOWN'\n res.writeHead(404, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ success: false, error: message, errorCode }))\n }\n return\n }\n\n if (pathname === INSPECTO_API_PATHS.AI_DISPATCH && req.method === 'POST') {\n try {\n const rawBody = await readBody(req)\n const body = JSON.parse(rawBody) as SendToAiRequest\n const result = await dispatchToAi(body)\n res.writeHead(result.success ? 200 : 500, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify(result))\n } catch (e) {\n serverLogger.error(`Error parsing ${INSPECTO_API_PATHS.AI_DISPATCH} request:`, e)\n res.writeHead(500, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ success: false, error: String(e), errorCode: 'INTERNAL_ERROR' }))\n }\n return\n }\n\n if (pathname === INSPECTO_API_PATHS.AI_BATCH_DISPATCH && req.method === 'POST') {\n try {\n const rawBody = await readBody(req)\n const body = JSON.parse(rawBody) as SendAnnotationsToAiRequest\n const result = await dispatchAnnotationsToAi(body, serverState)\n res.writeHead(getBatchDispatchStatusCode(result.errorCode, result.success), {\n 'Content-Type': 'application/json',\n })\n res.end(JSON.stringify(result))\n } catch (e) {\n serverLogger.error(`Error parsing ${INSPECTO_API_PATHS.AI_BATCH_DISPATCH} request:`, e)\n res.writeHead(500, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ success: false, error: String(e), errorCode: 'INTERNAL_ERROR' }))\n }\n return\n }\n\n // Handle IDE payload ticket retrieval\n if (pathname.startsWith(`${INSPECTO_API_PATHS.AI_TICKET}/`) && req.method === 'GET') {\n const ticketId = pathname.substring(INSPECTO_API_PATHS.AI_TICKET.length + 1)\n const payloadStr = readTicket(ticketId)\n\n if (!payloadStr) {\n res.writeHead(404, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ success: false, error: 'Ticket not found or expired' }))\n return\n }\n\n res.writeHead(200, { 'Content-Type': 'application/json' })\n res.end(payloadStr)\n return\n }\n\n res.writeHead(404, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ error: 'not found' }))\n}\n\nasync function dispatchToAi(\n req: SendToAiRequest,\n): Promise<SendToAiResponse & { fallbackPayload?: { prompt: string; file: string } }> {\n const { location, snippet, prompt, screenshotContext } = req\n\n const formattedPrompt =\n prompt ??\n `Please help me with this code from \\`${location.file}\\` (line ${location.line}):\\n\\n\\`\\`\\`\\n${snippet}\\n\\`\\`\\`\\n`\n const runtime = resolvePromptDispatchRuntime(serverState)\n return dispatchPromptThroughIde(runtime, {\n prompt: formattedPrompt,\n filePath: location.file,\n line: location.line,\n column: location.column,\n snippet,\n ...(screenshotContext ? { screenshotContext } : {}),\n }) as SendToAiResponse & { fallbackPayload?: { prompt: string; file: string } }\n}\n\nfunction getBatchDispatchStatusCode(\n errorCode: SendAnnotationsToAiResponse['errorCode'],\n success: boolean,\n): number {\n if (success) return 200\n if (errorCode === 'INVALID_REQUEST') return 400\n if (errorCode === 'FORBIDDEN_PATH') return 403\n return 500\n}\n","import * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport * as parser from '@babel/parser'\nimport traverse_ from '@babel/traverse'\n// Support both ESM default and CommonJS module.exports\nconst traverse =\n typeof traverse_ === 'function' ? traverse_ : (traverse_ as any).default || traverse_\nimport type { NodePath } from '@babel/traverse'\nimport type { Node } from '@babel/types'\nimport type { SnippetRequest, SnippetResponse } from '@inspecto-dev/types'\n\ninterface CacheEntry {\n mtime: number\n /** The full parsed source lines */\n lines: string[]\n}\n\n/** In-memory cache keyed by absolute file path */\nconst snippetCache = new Map<string, CacheEntry>()\n\nconst DEFAULT_MAX_LINES = 100\nconst DEFAULT_CONTEXT_LINES_BEFORE = 5\n\nexport async function extractSnippet(req: SnippetRequest): Promise<SnippetResponse> {\n const { file, line, column, maxLines = DEFAULT_MAX_LINES } = req\n\n const absolutePath = path.resolve(file)\n\n let stat: fs.Stats\n try {\n stat = await fs.promises.stat(absolutePath)\n } catch {\n throw new Error(`FILE_NOT_FOUND: ${absolutePath}`)\n }\n\n const mtime = stat.mtimeMs\n\n let lines: string[]\n const cached = snippetCache.get(absolutePath)\n if (cached && cached.mtime === mtime) {\n lines = cached.lines\n } else {\n const source = await fs.promises.readFile(absolutePath, 'utf-8')\n lines = source.split('\\n')\n snippetCache.set(absolutePath, { mtime, lines })\n }\n\n let snippetLines: string[]\n let startLine: number\n let componentName: string | undefined\n\n try {\n const result = extractComponentBoundary(lines.join('\\n'), line, column, maxLines)\n snippetLines = result.lines\n startLine = result.startLine\n componentName = result.name\n } catch {\n const before = Math.max(0, line - 1 - DEFAULT_CONTEXT_LINES_BEFORE)\n const after = Math.min(lines.length, before + maxLines)\n snippetLines = lines.slice(before, after)\n startLine = before + 1\n }\n\n if (snippetLines.length > maxLines) {\n snippetLines = snippetLines.slice(0, maxLines)\n }\n\n return {\n snippet: snippetLines.join('\\n'),\n startLine,\n file: absolutePath,\n ...(componentName ? { name: componentName } : {}),\n }\n}\n\ninterface BoundaryResult {\n lines: string[]\n startLine: number\n name?: string\n}\n\nfunction extractComponentBoundary(\n source: string,\n targetLine: number,\n _targetColumn: number,\n maxLines: number,\n): BoundaryResult {\n const ast = parser.parse(source, {\n sourceType: 'module',\n plugins: ['jsx', 'typescript', 'decorators-legacy', 'classProperties'],\n errorRecovery: true,\n })\n\n const allLines = source.split('\\n')\n\n let bestStart = 0\n let bestEnd = allLines.length - 1\n let bestName: string | undefined\n\n traverse(ast, {\n 'FunctionDeclaration|FunctionExpression|ArrowFunctionExpression|ClassMethod'(\n nodePath: NodePath<Node>,\n ) {\n const node = nodePath.node\n if (!node.loc) return\n\n const nodeStart = node.loc.start.line\n const nodeEnd = node.loc.end.line\n\n if (targetLine < nodeStart || targetLine > nodeEnd) return\n\n if (nodeEnd - nodeStart < bestEnd - bestStart) {\n bestStart = nodeStart - 1\n bestEnd = nodeEnd - 1\n bestName = extractFunctionName(nodePath)\n }\n },\n })\n\n let sliceStart = bestStart\n let sliceEnd = bestEnd + 1\n\n if (sliceEnd - sliceStart > maxLines) {\n const targetIdx = targetLine - 1\n sliceStart = Math.max(bestStart, targetIdx - Math.floor(maxLines / 3))\n sliceEnd = sliceStart + maxLines\n if (sliceEnd > bestEnd + 1) {\n sliceEnd = bestEnd + 1\n sliceStart = Math.max(0, sliceEnd - maxLines)\n }\n }\n\n return {\n lines: allLines.slice(sliceStart, sliceEnd),\n startLine: sliceStart + 1,\n ...(bestName ? { name: bestName } : {}),\n }\n}\n\nfunction extractFunctionName(nodePath: NodePath<Node>): string | undefined {\n const node = nodePath.node\n\n if (node.type === 'FunctionDeclaration' && node.id) {\n return node.id.name\n }\n\n const parent = nodePath.parent\n if (\n (node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression') &&\n parent.type === 'VariableDeclarator' &&\n parent.id.type === 'Identifier'\n ) {\n return parent.id.name\n }\n\n if (node.type === 'ClassMethod' && node.key.type === 'Identifier') {\n return node.key.name\n }\n\n return undefined\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport os from 'node:os'\nimport { createDefu } from 'defu'\nimport type {\n InspectoSettings,\n InspectoPromptsConfig,\n Provider,\n ProviderMode,\n ToolOverrides,\n IdeType,\n LogLevel,\n} from '@inspecto-dev/types'\nimport {\n DEFAULT_PROVIDER_MODE,\n VALID_MODES,\n DEFAULT_INTENTS,\n IntentConfig,\n} from '@inspecto-dev/types'\nimport { createLogger, setLoggerGlobalLevel } from './utils/logger.js'\n\nconst configLogger = createLogger('inspecto:config')\n\nlet loadedConfig: InspectoSettings | null = null\nlet loadedPrompts: InspectoPromptsConfig | null = null\nlet globalLogLevel: LogLevel = 'warn'\nlet isWatching = false\n\n// Custom array merge behavior for defu: overwrite arrays instead of concatenating them\nconst arrayReplaceMerge = createDefu((obj, key, val) => {\n if (Array.isArray(val)) {\n obj[key] = val\n return true\n }\n})\n\nexport function setGlobalLogLevel(level?: LogLevel) {\n if (level) {\n globalLogLevel = level\n setLoggerGlobalLevel(level)\n }\n}\n\nexport function getGlobalLogLevel() {\n return globalLogLevel\n}\n\n/**\n * Walk from cwd up to gitRoot (inclusive), collecting directories that contain\n * a .inspecto/ subdirectory. Returns them ordered highest-priority first\n * (closest to cwd first).\n *\n * If cwd is not under gitRoot, only cwd itself is checked.\n */\nexport function resolveConfigRoots(cwd: string, gitRoot: string): string[] {\n const roots: string[] = []\n let current = cwd\n\n // Ensure we don't walk past gitRoot (handles cwd above gitRoot case)\n const isUnderOrEqual = current === gitRoot || current.startsWith(gitRoot + path.sep)\n if (!isUnderOrEqual) {\n // cwd is not under gitRoot — only check cwd\n if (fs.existsSync(path.join(cwd, '.inspecto'))) roots.push(cwd)\n return roots\n }\n\n while (true) {\n if (fs.existsSync(path.join(current, '.inspecto'))) {\n roots.push(current)\n }\n if (current === gitRoot) break\n const parent = path.dirname(current)\n if (parent === current) break // filesystem root guard\n current = parent\n }\n\n return roots\n}\n\n/**\n * Load and merge user config from all discovered .inspecto/ layers:\n *\n * Priority (highest → lowest):\n * <cwd>/.inspecto/settings.local.json\n * <cwd>/.inspecto/settings.json\n * ...intermediate dirs...\n * <gitRoot>/.inspecto/settings.local.json\n * <gitRoot>/.inspecto/settings.json\n * ~/.inspecto/settings.json\n *\n * @param force Bust cache and re-read from disk\n * @param cwd Working directory to start resolution from (default: process.cwd())\n * @param gitRoot Git repository root — upward traversal stops here (optional)\n */\nexport function loadUserConfigSync(\n force = false,\n cwd = process.cwd(),\n gitRoot?: string,\n): InspectoSettings {\n if (loadedConfig && !force) return loadedConfig\n loadedConfig = null // force clear\n\n const layers: Partial<InspectoSettings>[] = []\n const roots = resolveConfigRoots(cwd, gitRoot ?? cwd)\n\n for (const root of roots) {\n layers.push(readJsonSafely(path.join(root, '.inspecto', 'settings.local.json')))\n layers.push(readJsonSafely(path.join(root, '.inspecto', 'settings.json')))\n }\n\n layers.push(readJsonSafely(path.join(os.homedir(), '.inspecto', 'settings.json')))\n layers.push({})\n\n const validLayers = layers.filter(l => l !== null)\n loadedConfig = arrayReplaceMerge(...(validLayers as [object, ...object[]])) as InspectoSettings\n return loadedConfig\n}\n\n/**\n * Load and merge prompts config from all discovered .inspecto/ layers:\n *\n * Priority (highest → lowest):\n * <cwd>/.inspecto/prompts.local.json\n * <cwd>/.inspecto/prompts.json\n * ...intermediate dirs...\n * <gitRoot>/.inspecto/prompts.local.json\n * <gitRoot>/.inspecto/prompts.json\n * ~/.inspecto/prompts.json\n *\n * Arrays in custom configurations are replaced instead of merged.\n */\nexport async function loadPromptsConfig(\n force = false,\n cwd = process.cwd(),\n gitRoot?: string,\n): Promise<InspectoPromptsConfig> {\n if (loadedPrompts && !force) return loadedPrompts\n\n const layers: any[] = []\n\n const roots = resolveConfigRoots(cwd, gitRoot ?? cwd)\n for (const root of roots) {\n const localPath = path.join(root, '.inspecto', 'prompts.local.json')\n const jsonPath = path.join(root, '.inspecto', 'prompts.json')\n layers.push(readJsonSafely(localPath))\n layers.push(readJsonSafely(jsonPath))\n }\n\n layers.push(readJsonSafely(path.join(os.homedir(), '.inspecto', 'prompts.json')))\n\n // Find the first layer that contains a valid prompts config (array or $replace object).\n // Highest-priority layer wins — no merging across layers for prompts.\n let finalPrompts: any = []\n for (const layer of layers) {\n if (Array.isArray(layer) && layer.length > 0) {\n finalPrompts = layer\n break\n }\n if (\n layer &&\n typeof layer === 'object' &&\n layer.$replace === true &&\n Array.isArray(layer.items)\n ) {\n finalPrompts = layer\n break\n }\n }\n\n loadedPrompts = finalPrompts as InspectoPromptsConfig\n return loadedPrompts\n}\n\nfunction readJsonSafely(filePath: string): any {\n try {\n if (fs.existsSync(filePath)) {\n const content = fs.readFileSync(filePath, 'utf-8').trim()\n if (!content) return null // Return null instead of [] so we know it's empty\n const parsed = JSON.parse(content)\n // Transition helper: if user still has {\"prompts\": [...]}, extract it\n if (!Array.isArray(parsed) && parsed.prompts && Array.isArray(parsed.prompts)) {\n return parsed.prompts\n }\n return parsed\n }\n } catch (e) {\n // Ignore JSON parsing errors for empty or malformed files during watch\n if (e instanceof SyntaxError) {\n configLogger.warn(`Failed to parse config at ${filePath}: Invalid JSON`)\n } else {\n configLogger.warn(`Failed to read config at ${filePath}:`, e)\n }\n }\n return null\n}\n\n/**\n * Resolve the exact target tool to dispatch to based on user config.\n */\nexport function resolveTargetTool(config: InspectoSettings, ide: IdeType = 'vscode'): Provider {\n // Support \"provider.default\" (e.g., \"claude-code.extension\")\n const defaultProvider = config['provider.default'] as string | undefined\n if (defaultProvider) {\n const tool = defaultProvider.split('.')[0]\n return tool as Provider\n }\n\n // Fallback\n return 'copilot'\n}\n\n/**\n * Resolve the effective mode/type for a tool in the context of an IDE.\n */\nexport function resolveProviderMode(\n tool: Provider,\n ide: IdeType,\n config: InspectoSettings,\n): ProviderMode {\n let requestedType: ProviderMode | undefined = undefined\n\n // V2 format: check provider.default for \"tool.mode\"\n const defaultProvider = config['provider.default'] as string | undefined\n if (defaultProvider && defaultProvider.startsWith(`${tool}.`)) {\n const mode = defaultProvider.split('.')[1]\n if (mode === 'extension') requestedType = 'extension'\n if (mode === 'cli') requestedType = 'cli'\n }\n\n requestedType = requestedType ?? DEFAULT_PROVIDER_MODE[tool]\n const valid = VALID_MODES[tool] || [DEFAULT_PROVIDER_MODE[tool]]\n return requestedType && valid.includes(requestedType) ? requestedType : valid[0]!\n}\n\n/**\n * Extract ToolOverrides (binaryPath, args, etc) for Extension consumption.\n */\nexport function extractToolOverrides(\n ide: IdeType,\n config: InspectoSettings,\n): Partial<Record<Provider, ToolOverrides>> {\n const result: Partial<Record<Provider, ToolOverrides>> = {}\n\n if (!config) return result\n\n // Parse new flat `provider.*` format\n for (const [key, value] of Object.entries(config)) {\n if (!key.startsWith('provider.')) continue\n\n // We only process tool specific overrides, ignore `.default`\n if (key === 'provider.default') continue\n\n // Handle `provider.[tool].[mode]`\n const toolIndex = 1\n const modeIndex = 2\n const propIndex = 3\n\n const parts = key.split('.')\n\n if (parts.length >= propIndex + 1) {\n const tool = parts[toolIndex] as Provider\n const mode = parts[modeIndex] as ProviderMode\n const prop = parts[propIndex]\n\n if (!result[tool]) {\n result[tool] = { type: mode }\n }\n\n const overrides = result[tool]!\n\n // If we see config for a mode that differs from what we've initialized,\n // it means both modes have config. In v2, mode is determined by provider.default.\n // We will just accumulate the settings for now and let resolveProviderMode decide the active type.\n\n if (prop === 'bin') overrides.binaryPath = value as string\n if (prop === 'args') overrides.args = value as string[]\n if (prop === 'cwd') overrides.cwd = value as string\n if (prop === 'coldStartDelay') overrides.coldStartDelay = value as number\n }\n }\n\n return result\n}\n\nexport function resolveIntents(serverPrompts?: InspectoPromptsConfig): IntentConfig[] {\n // Start with DEFAULT_INTENTS as base\n const baseMap = new Map<string, IntentConfig>()\n for (const intent of DEFAULT_INTENTS) {\n baseMap.set(intent.id, { ...intent } as IntentConfig)\n }\n\n const defaults = () => Array.from(baseMap.values())\n\n if (!serverPrompts) return defaults()\n\n const isReplace =\n !Array.isArray(serverPrompts) &&\n typeof serverPrompts === 'object' &&\n serverPrompts.$replace === true\n const promptsArray = Array.isArray(serverPrompts)\n ? serverPrompts\n : isReplace\n ? serverPrompts.items\n : []\n\n if (!promptsArray || promptsArray.length === 0) return defaults()\n\n if (isReplace) {\n // $replace: true — exact list, user controls everything\n const result: IntentConfig[] = []\n for (const item of promptsArray) {\n if (typeof item === 'string') {\n if (baseMap.has(item)) {\n result.push(baseMap.get(item)!)\n } else {\n configLogger.warn(\n `Unknown built-in intent id: \"${item}\". Available: ${[...baseMap.keys()].join(', ')}`,\n )\n }\n } else if (typeof item === 'object') {\n if (!item.id) {\n configLogger.warn('Intent object missing required \"id\" field, skipping.')\n continue\n }\n if (item.enabled === false) {\n configLogger.warn(\n `Intent \"${item.id}\" is listed in $replace but has enabled:false — it will be excluded.`,\n )\n continue\n }\n if (!item.aiIntent) {\n configLogger.warn(`Intent \"${item.id}\" is missing required \"aiIntent\".`)\n continue\n }\n result.push(\n (baseMap.has(item.id) ? { ...baseMap.get(item.id)!, ...item } : item) as IntentConfig,\n )\n }\n }\n return result\n }\n\n // Default: append / override mode.\n // - Objects with known id: merge over built-in (or remove if enabled:false)\n // - Objects with unknown id: append as new intent\n // - Strings: not meaningful in append mode (order is fixed to built-in order + appended)\n const merged = Array.from(baseMap.values())\n\n for (const item of promptsArray) {\n if (typeof item === 'string') {\n if (!baseMap.has(item)) {\n configLogger.warn(\n `Unknown built-in intent id: \"${item}\". In append mode, strings have no effect on ordering — use $replace to control order.`,\n )\n }\n // Known string ids are already in merged — nothing to do\n continue\n }\n\n if (typeof item === 'object') {\n if (!item.id) {\n configLogger.warn('Intent object missing required \"id\" field, skipping.')\n continue\n }\n if (!item.aiIntent) {\n configLogger.warn(`Intent \"${item.id}\" is missing required \"aiIntent\".`)\n continue\n }\n const existingIdx = merged.findIndex(i => i.id === item.id)\n if (existingIdx !== -1) {\n if (item.enabled === false) {\n merged.splice(existingIdx, 1)\n } else {\n merged[existingIdx] = { ...merged[existingIdx], ...item } as IntentConfig\n }\n } else {\n if (item.enabled !== false) {\n merged.push(item as IntentConfig)\n }\n }\n }\n }\n\n return merged\n}\n\nlet watchers: fs.FSWatcher[] = []\n\nexport function watchConfig(onReload: () => void, cwd = process.cwd(), gitRoot?: string): void {\n if (isWatching) return\n isWatching = true\n\n // Watch .inspecto/ directories rather than individual files so that newly\n // created files (e.g. prompts.local.json added after server start) are picked up.\n const watchDirs: string[] = [path.join(os.homedir(), '.inspecto')]\n const roots = resolveConfigRoots(cwd, gitRoot ?? cwd)\n for (const root of roots) {\n watchDirs.push(path.join(root, '.inspecto'))\n }\n\n const CONFIG_FILES = new Set([\n 'settings.json',\n 'settings.local.json',\n 'prompts.json',\n 'prompts.local.json',\n ])\n\n for (const dir of watchDirs) {\n if (!fs.existsSync(dir)) continue\n try {\n const watcher = fs.watch(dir, async (eventType, filename) => {\n if (!filename || !CONFIG_FILES.has(filename)) return\n loadedConfig = null\n loadedPrompts = null\n loadUserConfigSync(true, cwd, gitRoot)\n await loadPromptsConfig(true, cwd, gitRoot)\n onReload()\n })\n watcher.unref()\n watchers.push(watcher)\n } catch (e) {\n // ignore watch errors (e.g. unsupported fs)\n }\n }\n}\n\nexport function unwatchConfig(): void {\n for (const watcher of watchers) {\n watcher.close()\n }\n watchers = []\n isWatching = false\n}\n","import type { LogLevel } from '@inspecto-dev/types'\n\nexport interface Logger {\n info(msg: string, ...args: any[]): void\n warn(msg: string, ...args: any[]): void\n error(msg: string, ...args: any[]): void\n debug(msg: string, ...args: any[]): void\n setLevel?(level: LogLevel): void\n}\n\nconst LOG_LEVELS: Record<LogLevel, number> = {\n silent: 0,\n error: 1,\n warn: 2,\n info: 3,\n}\n\n// Very simple implementation of a DEBUG matching string.\n// Supports `DEBUG=inspecto:*` or `DEBUG=inspecto:server,inspecto:ast`\nfunction isDebugEnabled(namespace: string): boolean {\n if (typeof process === 'undefined' || !process.env) return false\n const debugEnv = process.env.DEBUG\n if (!debugEnv) return false\n\n const namespaces = debugEnv.split(',').map(s => s.trim())\n for (const ns of namespaces) {\n if (ns === '*') return true\n if (ns.endsWith('*')) {\n const prefix = ns.slice(0, -1)\n if (namespace.startsWith(prefix)) return true\n } else if (ns === namespace) {\n return true\n }\n }\n return false\n}\n\n// Store global level locally to avoid circular dependency with config.ts\nlet globalLevel: LogLevel = 'warn'\nconst registeredLoggers: Set<Logger> = new Set()\n\nexport function setLoggerGlobalLevel(level: LogLevel) {\n globalLevel = level\n for (const logger of registeredLoggers) {\n if (logger.setLevel) {\n logger.setLevel(level)\n }\n }\n}\n\nexport function createLogger(namespace: string, options?: { logLevel?: LogLevel }): Logger {\n let currentLevel = options?.logLevel ?? globalLevel\n let numericLevel = LOG_LEVELS[currentLevel] ?? 2\n const debugEnabled = isDebugEnabled(namespace)\n\n const logger: Logger = {\n setLevel(level: LogLevel) {\n currentLevel = level\n numericLevel = LOG_LEVELS[level] ?? 2\n },\n info(msg: string, ...args: any[]) {\n if (numericLevel >= LOG_LEVELS.info) {\n console.log(`\\x1b[36m[inspecto]\\x1b[0m ${msg}`, ...args)\n }\n },\n warn(msg: string, ...args: any[]) {\n if (numericLevel >= LOG_LEVELS.warn) {\n console.warn(`\\x1b[33m[inspecto] WARN:\\x1b[0m ${msg}`, ...args)\n }\n },\n error(msg: string, ...args: any[]) {\n if (numericLevel >= LOG_LEVELS.error) {\n console.error(`\\x1b[31m[inspecto] ERROR:\\x1b[0m ${msg}`, ...args)\n }\n },\n debug(msg: string, ...args: any[]) {\n if (debugEnabled) {\n console.log(`\\x1b[90m[${namespace}]\\x1b[0m ${msg}`, ...args)\n }\n },\n }\n\n registeredLoggers.add(logger)\n\n return logger\n}\n","import crypto from 'node:crypto'\nimport { execFileSync } from 'node:child_process'\nimport { launchIDE } from 'launch-ide'\nimport { createLogger } from '../utils/logger.js'\nimport { getGlobalLogLevel } from '../config.js'\n\nconst serverLogger = createLogger('inspecto:server', { logLevel: getGlobalLogLevel() })\n\nconst payloadTickets = new Map<string, string>()\n\nexport function createTicket(payload: unknown): string {\n const ticketId = crypto.randomUUID()\n payloadTickets.set(ticketId, JSON.stringify(payload))\n\n setTimeout(\n () => {\n payloadTickets.delete(ticketId)\n },\n 5 * 60 * 1000,\n )\n\n return ticketId\n}\n\nexport function readTicket(ticketId: string): string | undefined {\n return payloadTickets.get(ticketId)\n}\n\nexport function launchURI(uri: string): void {\n try {\n if (process.platform === 'darwin') {\n execFileSync('open', [uri])\n } else if (process.platform === 'win32') {\n execFileSync('cmd', ['/c', 'start', '\"\"', uri])\n } else {\n execFileSync('xdg-open', [uri])\n }\n } catch (e) {\n serverLogger.error('Failed to launch URI via execFileSync, falling back to launchIDE:', e)\n launchIDE({ file: uri })\n }\n}\n","import type {\n IdeType,\n Provider,\n ProviderMode,\n ScreenshotContext,\n ServerState,\n ToolOverrides,\n} from '@inspecto-dev/types'\nimport {\n extractToolOverrides,\n loadUserConfigSync,\n resolveProviderMode,\n resolveTargetTool,\n} from '../config.js'\nimport { createTicket, launchURI } from './dispatch-transport.js'\n\nexport interface PromptDispatchRuntime {\n resolvedTarget: Provider\n finalIde: string\n mode: ProviderMode\n overrides?: ToolOverrides\n autoSend?: boolean\n}\n\nexport interface PromptDispatchPayload {\n prompt: string\n filePath?: string\n line?: number\n column?: number\n snippet?: string\n screenshotContext?: ScreenshotContext\n}\n\nexport interface PromptDispatchResult {\n success: true\n fallbackPayload: {\n prompt: string\n file?: string\n }\n}\n\nexport function resolvePromptDispatchRuntime(\n state: Pick<ServerState, 'projectRoot' | 'cwd' | 'ideInfo'>,\n): PromptDispatchRuntime {\n const userConfig = loadUserConfigSync(false, state.cwd, state.projectRoot)\n const resolvedTarget = resolveTargetTool(userConfig)\n const finalIde = resolveFinalIde(userConfig.ide, state.ideInfo?.ide, state.ideInfo?.scheme)\n const mode = resolveProviderMode(resolvedTarget, finalIde as IdeType, userConfig)\n const overrides =\n extractToolOverrides(finalIde as IdeType, userConfig)[resolvedTarget] || undefined\n\n return {\n resolvedTarget,\n finalIde,\n mode,\n ...(hasOverrides(overrides) ? { overrides } : {}),\n ...(userConfig['prompt.autoSend'] !== undefined\n ? { autoSend: Boolean(userConfig['prompt.autoSend']) }\n : {}),\n }\n}\n\nexport function dispatchPromptThroughIde(\n runtime: PromptDispatchRuntime,\n payload: PromptDispatchPayload,\n): PromptDispatchResult {\n const ticketId = createTicket({\n ide: runtime.finalIde,\n target: runtime.resolvedTarget,\n targetType: runtime.mode,\n prompt: payload.prompt,\n filePath: payload.filePath,\n line: payload.line,\n column: payload.column,\n snippet: payload.snippet,\n ...(payload.screenshotContext ? { screenshotContext: payload.screenshotContext } : {}),\n overrides: runtime.overrides,\n autoSend: runtime.autoSend,\n })\n\n const params = new URLSearchParams()\n params.set('ticket', ticketId)\n params.set('target', runtime.resolvedTarget)\n\n launchURI(`${runtime.finalIde}://inspecto.inspecto/send?${params.toString()}`)\n\n return {\n success: true,\n fallbackPayload: {\n prompt: payload.prompt,\n ...(payload.filePath ? { file: payload.filePath } : {}),\n },\n }\n}\n\nfunction resolveFinalIde(\n configuredIde: string | undefined,\n activeIde: string | undefined,\n activeIdeScheme: string | undefined,\n): string {\n if (configuredIde && activeIdeScheme && !activeIdeScheme.includes(configuredIde)) {\n return configuredIde\n }\n\n return configuredIde || activeIdeScheme || activeIde || 'vscode'\n}\n\nfunction hasOverrides(overrides: ToolOverrides | undefined): overrides is ToolOverrides {\n return Boolean(overrides && Object.keys(overrides).length > 0)\n}\n","import path from 'node:path'\n\nfunction isWindowsAbsolutePath(file: string): boolean {\n return /^[a-zA-Z]:[\\\\/]/.test(file) || /^\\\\\\\\[^\\\\]+\\\\[^\\\\]+/.test(file)\n}\n\nexport function resolveWorkspacePath(file: string, cwd: string): string {\n if (isWindowsAbsolutePath(file)) {\n return path.win32.normalize(file)\n }\n return path.isAbsolute(file) ? path.resolve(file) : path.resolve(cwd, file)\n}\n\nexport function assertPathWithinProject(file: string, projectRoot: string): void {\n const relativeToRoot =\n isWindowsAbsolutePath(file) || isWindowsAbsolutePath(projectRoot)\n ? path.win32.relative(path.win32.normalize(projectRoot), path.win32.normalize(file))\n : path.relative(projectRoot, file)\n if (relativeToRoot.startsWith('..') || path.isAbsolute(relativeToRoot)) {\n throw new Error('Access denied: File is outside of project workspace')\n }\n}\n","import type {\n AnnotationIntent,\n AiErrorCode,\n RuntimeContextEnvelope,\n RuntimeEvidenceRecord,\n ScreenshotContext,\n SendAnnotationsToAiRequest,\n SendAnnotationsToAiResponse,\n ServerState,\n} from '@inspecto-dev/types'\nimport { dispatchPromptThroughIde, resolvePromptDispatchRuntime } from './dispatch-runtime.js'\nimport { assertPathWithinProject, resolveWorkspacePath } from './path-guards.js'\n\nexport interface NormalizedAnnotationTarget {\n file: string\n line: number\n column: number\n label?: string\n selector?: string\n snippet?: string\n}\n\nexport interface NormalizedAnnotation {\n index: number\n note: string\n intent: AnnotationIntent\n targets: NormalizedAnnotationTarget[]\n}\n\nexport interface NormalizedAnnotationBatch {\n instruction: string\n responseMode: 'unified' | 'per-annotation'\n annotations: NormalizedAnnotation[]\n runtimeContext?: RuntimeContextEnvelope\n screenshotContext?: ScreenshotContext\n cssContextPrompt?: string\n}\n\nclass AnnotationDispatchError extends Error {\n readonly errorCode: AiErrorCode\n\n constructor(message: string, errorCode: AiErrorCode) {\n super(message)\n this.name = 'AnnotationDispatchError'\n this.errorCode = errorCode\n }\n}\n\nexport async function dispatchAnnotationsToAi(\n req: SendAnnotationsToAiRequest,\n state: Pick<ServerState, 'projectRoot' | 'cwd' | 'ideInfo'>,\n): Promise<SendAnnotationsToAiResponse> {\n try {\n validateAnnotationDispatchRequest(req, state)\n const batch = normalizeAnnotationBatch(req)\n const prompt = buildAnnotationBatchPrompt(batch)\n const representativeTarget = batch.annotations[0]?.targets[0]\n const runtime = resolvePromptDispatchRuntime(state)\n\n return dispatchPromptThroughIde(runtime, {\n prompt,\n ...(representativeTarget?.file ? { filePath: representativeTarget.file } : {}),\n ...(representativeTarget?.line ? { line: representativeTarget.line } : {}),\n ...(representativeTarget?.column ? { column: representativeTarget.column } : {}),\n ...(batch.screenshotContext ? { screenshotContext: batch.screenshotContext } : {}),\n })\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n errorCode: getAnnotationDispatchErrorCode(error),\n }\n }\n}\n\nexport function validateAnnotationDispatchRequest(\n req: SendAnnotationsToAiRequest,\n state: Pick<ServerState, 'projectRoot' | 'cwd'>,\n): void {\n if (!req.annotations.length) {\n throw new AnnotationDispatchError('At least one annotation is required.', 'INVALID_REQUEST')\n }\n\n for (const annotation of req.annotations) {\n if (!annotation.targets.length) {\n throw new AnnotationDispatchError(\n 'Each annotation must include at least one target.',\n 'INVALID_REQUEST',\n )\n }\n\n for (const target of annotation.targets) {\n const absolutePath = resolveWorkspacePath(target.location.file, state.cwd)\n assertPathWithinProject(absolutePath, state.projectRoot)\n }\n }\n}\n\nexport function normalizeAnnotationBatch(\n req: SendAnnotationsToAiRequest,\n): NormalizedAnnotationBatch {\n return {\n instruction: req.instruction?.trim() ?? '',\n responseMode: req.responseMode ?? 'unified',\n ...(req.runtimeContext ? { runtimeContext: req.runtimeContext } : {}),\n ...(req.screenshotContext ? { screenshotContext: req.screenshotContext } : {}),\n ...(req.cssContextPrompt?.trim() ? { cssContextPrompt: req.cssContextPrompt.trim() } : {}),\n annotations: req.annotations.map((annotation, index) => ({\n index: index + 1,\n note: annotation.note.trim(),\n intent: annotation.intent,\n targets: annotation.targets.map(target => ({\n file: target.location.file,\n line: target.location.line,\n column: target.location.column,\n ...(target.label ? { label: target.label } : {}),\n ...(target.selector ? { selector: target.selector } : {}),\n ...(target.snippet ? { snippet: target.snippet } : {}),\n })),\n })),\n }\n}\n\nexport function buildAnnotationBatchPrompt(batch: NormalizedAnnotationBatch): string {\n const body = buildSelectedElementsPrompt(batch.annotations)\n const prompt = batch.instruction ? `${batch.instruction}\\n\\n${body}` : body\n\n return appendScreenshotContextSection(\n appendCssContextSection(\n appendRuntimeContextSection(prompt, batch.runtimeContext),\n batch.cssContextPrompt,\n ),\n batch.screenshotContext,\n )\n}\n\nfunction appendCssContextSection(prompt: string, cssContextPrompt: string | undefined): string {\n if (!cssContextPrompt) return prompt\n return `${prompt}\\n\\n${cssContextPrompt}`\n}\n\nfunction buildSelectedElementsPrompt(annotations: NormalizedAnnotation[]): string {\n const lines = ['Selected elements:']\n\n for (const annotation of annotations) {\n const trimmedNote = annotation.note.trim()\n for (const target of annotation.targets) {\n const targetLabel = (target.label || 'Unknown target').trim() || 'Unknown target'\n lines.push(`- ${targetLabel}`)\n lines.push(`file=${target.file}:${target.line}:${target.column}`)\n if (trimmedNote) {\n lines.push(`note=${trimmedNote}`)\n }\n }\n }\n\n if (lines.length === 1) {\n lines.push('- None')\n }\n\n return lines.join('\\n')\n}\n\nfunction appendScreenshotContextSection(\n prompt: string,\n screenshotContext: ScreenshotContext | undefined,\n): string {\n if (!screenshotContext || (!screenshotContext.imageDataUrl && !screenshotContext.imageAssetId)) {\n return prompt\n }\n\n const lines = [\n 'Visual screenshot context attached:',\n `- capturedAt=${screenshotContext.capturedAt}`,\n `- mimeType=${screenshotContext.mimeType}`,\n ...(screenshotContext.imageAssetId ? [`- imageAssetId=${screenshotContext.imageAssetId}`] : []),\n ]\n\n return `${prompt}\\n\\n${lines.join('\\n')}`\n}\n\nfunction appendRuntimeContextSection(\n prompt: string,\n runtimeContext: RuntimeContextEnvelope | undefined,\n): string {\n if (!runtimeContext?.records.length) {\n return prompt\n }\n\n return `${prompt}\\n\\n${buildRuntimeContextSection(runtimeContext.records)}`\n}\n\nfunction buildRuntimeContextSection(records: RuntimeEvidenceRecord[]): string {\n return ['Relevant runtime context:', ...records.map(formatRuntimeRecord)].join('\\n')\n}\n\nfunction formatRuntimeRecord(record: RuntimeEvidenceRecord): string {\n const requestSummary =\n record.kind === 'failed-request'\n ? `request=${record.request?.method ?? 'GET'} ${record.request?.pathname ?? record.request?.url ?? 'unknown'} status=${record.request?.status ?? 'unknown'}`\n : `occurrences=${record.occurrenceCount}`\n const reasonSummary = record.relevanceReasons.length\n ? record.relevanceReasons.join('; ')\n : 'timing-based'\n const stackSummary = record.stack\n ? `\\n stack=${record.stack.split('\\n').slice(0, 5).join(' | ')}`\n : ''\n\n return [\n `- [${record.kind}] ${record.message}`,\n ` relevance=${record.relevanceLevel} (${reasonSummary})`,\n ` ${requestSummary}`,\n stackSummary,\n ]\n .filter(Boolean)\n .join('\\n')\n}\n\nfunction getAnnotationDispatchErrorCode(error: unknown): AiErrorCode {\n if (error instanceof AnnotationDispatchError) return error.errorCode\n if (error instanceof Error && error.message.includes('outside of project workspace')) {\n return 'FORBIDDEN_PATH'\n }\n return 'UNKNOWN'\n}\n","import type { IdeType, InspectoConfig, ServerState } from '@inspecto-dev/types'\nimport { loadPromptsConfig, loadUserConfigSync, resolveIntents } from '../config.js'\n\nexport async function buildClientConfig(\n serverState: ServerState,\n): Promise<InspectoConfig & { autoSend: boolean }> {\n const userConfig = loadUserConfigSync(false, serverState.cwd, serverState.configRoot)\n const promptsConfig = await loadPromptsConfig(false, serverState.cwd, serverState.configRoot)\n const effectiveIde = (userConfig.ide ?? 'vscode') as IdeType\n\n let info: any\n if (!serverState.ideInfo) {\n info = { ide: effectiveIde }\n } else {\n const { scheme: _scheme, ...rest } = serverState.ideInfo as any\n info = rest\n }\n\n return {\n ...info,\n prompts: resolveIntents(promptsConfig),\n hotKeys: userConfig['inspector.hotKey'] ?? 'alt',\n theme: userConfig['inspector.theme'] ?? 'auto',\n includeSnippet: userConfig['prompt.includeSnippet'] ?? false,\n runtimeContext: {\n enabled: true,\n preview: true,\n maxRuntimeErrors: 3,\n maxFailedRequests: 2,\n },\n screenshotContext: {\n enabled: false,\n },\n annotationResponseMode: userConfig['prompt.annotationResponseMode'] ?? 'unified',\n autoSend: userConfig['prompt.autoSend'] ?? false,\n }\n}\n","import { execFileSync } from 'node:child_process'\nimport { Editor, launchIDE } from 'launch-ide'\nimport type { OpenFileRequest, ServerState } from '@inspecto-dev/types'\nimport { loadUserConfigSync } from '../config.js'\nimport { createLogger } from '../utils/logger.js'\nimport { getGlobalLogLevel } from '../config.js'\nimport { assertPathWithinProject, resolveWorkspacePath } from './path-guards.js'\n\nconst serverLogger = createLogger('inspecto:server', { logLevel: getGlobalLogLevel() })\n\nconst VSCODE_FAMILY_SCHEMES = [\n 'vscode',\n 'vscode-insiders',\n 'cursor',\n 'windsurf',\n 'trae',\n 'trae-cn',\n 'vscodium',\n 'codebuddy',\n 'codebuddy-cn',\n 'antigravity',\n]\n\nexport function handleOpenFileRequest(\n body: OpenFileRequest,\n serverState: ServerState,\n): { success: true } {\n const absolutePath = resolveWorkspacePath(body.file, serverState.cwd)\n\n assertPathWithinProject(absolutePath, serverState.projectRoot)\n\n const userConfig = loadUserConfigSync(false, serverState.cwd, serverState.configRoot)\n const configuredIde = userConfig.ide\n const activeIde = serverState.ideInfo?.ide\n const activeIdeScheme = serverState.ideInfo?.scheme\n\n const rawEditorHint = configuredIde || activeIde || activeIdeScheme || 'code'\n\n if (configuredIde && activeIdeScheme && !activeIdeScheme.includes(configuredIde)) {\n serverLogger.warn(\n `Active IDE is ${activeIdeScheme}, but config forces ${configuredIde}. Using configured IDE.`,\n )\n }\n\n let editorHint = rawEditorHint\n if (rawEditorHint === 'vscode') editorHint = 'code'\n else if (rawEditorHint === 'vscode-insiders') editorHint = 'code-insiders'\n else if (rawEditorHint === 'vscodium') editorHint = 'codium'\n else if (rawEditorHint === 'trae-cn' || rawEditorHint === 'trae') editorHint = 'trae'\n\n serverLogger.debug(\n `IDE_OPEN: activeIde=${activeIde}, activeIdeScheme=${activeIdeScheme}, configuredIde=${configuredIde} -> rawEditorHint=${rawEditorHint}, finalEditorHint=${editorHint}`,\n )\n\n if (VSCODE_FAMILY_SCHEMES.includes(rawEditorHint)) {\n let normalizedPath = absolutePath.replace(/\\\\/g, '/')\n if (!normalizedPath.startsWith('/')) {\n normalizedPath = '/' + normalizedPath\n }\n const encodedPath = encodeURI(normalizedPath)\n const uri = `${rawEditorHint}://file${encodedPath}:${body.line}:${body.column}`\n serverLogger.debug(`IDE_OPEN: Bypassing launchIDE, using URI scheme directly: ${uri}`)\n\n try {\n if (process.platform === 'darwin') {\n execFileSync('open', [uri])\n } else if (process.platform === 'win32') {\n execFileSync('cmd', ['/c', 'start', '\"\"', uri])\n } else {\n execFileSync('xdg-open', [uri])\n }\n } catch (e) {\n serverLogger.error(`Failed to launch URI for IDE_OPEN (${uri}):`, e)\n launchIDE({\n file: absolutePath,\n line: body.line,\n column: body.column,\n editor: editorHint as Editor,\n type: process.platform === 'darwin' ? 'open' : 'exec',\n })\n }\n } else {\n launchIDE({\n file: absolutePath,\n line: body.line,\n column: body.column,\n editor: editorHint as Editor,\n type: process.platform === 'darwin' ? 'open' : 'exec',\n })\n }\n\n return { success: true }\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport { execSync } from 'node:child_process'\nimport { createLogger } from '../utils/logger.js'\nimport { getGlobalLogLevel } from '../config.js'\n\nconst serverLogger = createLogger('inspecto:server', { logLevel: getGlobalLogLevel() })\n\nexport function resolveProjectRoot(): string {\n const cwd = process.cwd()\n let gitRoot: string\n try {\n gitRoot = execSync('git rev-parse --show-toplevel', { encoding: 'utf-8' }).trim()\n } catch (e) {\n serverLogger.warn('Failed to resolve git root via git rev-parse:', e)\n gitRoot = cwd\n }\n\n const visited = new Set<string>()\n const search = (start: string, stop: string) => {\n let current = start\n while (!visited.has(current)) {\n visited.add(current)\n if (fs.existsSync(path.join(current, '.inspecto'))) return current\n if (current === stop) break\n const parent = path.dirname(current)\n if (parent === current) break\n current = parent\n }\n return null\n }\n\n const cwdMatch = search(cwd, path.parse(cwd).root)\n if (cwdMatch) return cwdMatch\n\n const repoMatch = search(gitRoot, path.parse(gitRoot).root)\n if (repoMatch) return repoMatch\n\n return gitRoot\n}\n","import { createRequire } from 'node:module'\n\n// Safely resolve the client module without breaking ESM/CJS or bundling\nexport const resolveClientModule = () => {\n try {\n return createRequire(import.meta.url).resolve('@inspecto-dev/core')\n } catch {\n try {\n return require.resolve('@inspecto-dev/core')\n } catch {\n console.warn(\n '[inspecto] Could not resolve @inspecto-dev/core — falling back to bare specifier',\n )\n return '@inspecto-dev/core'\n }\n }\n}\n","export function getWebpackHtmlScript(serverPort: number) {\n return `\nwindow.__AI_INSPECTOR_PORT__ = ${serverPort};\nwindow.addEventListener('load', () => {\n if (window.InspectoClient) {\n window.InspectoClient.mountInspector({\n serverUrl: 'http://127.0.0.1:' + window.__AI_INSPECTOR_PORT__,\n });\n }\n});\n`\n}\n\nexport function getWebpackAssetScript(serverPort: number) {\n return `\nif (typeof window !== 'undefined') {\n window.__AI_INSPECTOR_PORT__ = ${serverPort};\n const _initInspecto = () => {\n if (window.InspectoClient) {\n window.InspectoClient.mountInspector({\n serverUrl: 'http://127.0.0.1:' + window.__AI_INSPECTOR_PORT__,\n });\n } else {\n setTimeout(_initInspecto, 100);\n }\n };\n if (document.readyState === 'complete') {\n _initInspecto();\n } else {\n window.addEventListener('load', _initInspecto);\n }\n}\n`\n}\n\nexport function injectWebpack(\n compiler: any,\n serverPortFn: () => Promise<number>,\n resolveClientModule: () => string,\n) {\n const inspectoClientPath = resolveClientModule()\n\n // Inject the client logic directly using the absolute path\n if (compiler.webpack && compiler.webpack.EntryPlugin) {\n // Webpack 5+\n new compiler.webpack.EntryPlugin(compiler.context, inspectoClientPath, {\n name: undefined,\n }).apply(compiler)\n }\n\n compiler.hooks.compilation.tap('inspecto-overlay', (compilation: any) => {\n // Find HtmlWebpackPlugin (standard Webpack)\n const HtmlWebpackPlugin = compiler.options.plugins.find(\n (p: any) => p && p.constructor && p.constructor.name === 'HtmlWebpackPlugin',\n )\n if (HtmlWebpackPlugin) {\n const hooks = (HtmlWebpackPlugin.constructor as any).getHooks(compilation)\n hooks.alterAssetTagGroups.tapPromise('inspecto-overlay', async (data: any) => {\n const port = await serverPortFn()\n data.headTags.unshift({\n tagName: 'script',\n voidTag: false,\n meta: { plugin: 'inspecto-overlay' },\n innerHTML: getWebpackHtmlScript(port),\n })\n return data\n })\n } else {\n // Fallback for frameworks like Next.js that don't use HtmlWebpackPlugin\n compilation.hooks.processAssets.tapPromise(\n {\n name: 'inspecto-overlay',\n stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONS,\n },\n async (assets: any) => {\n const port = await serverPortFn()\n\n // Only inject into the main client entry chunks (e.g. main-app or main.js)\n const mainAssetKey = Object.keys(assets).find(\n key => key.endsWith('.js') && (key.includes('main') || key.includes('app')),\n )\n if (!mainAssetKey) return\n\n const originalSource = assets[mainAssetKey].source()\n assets[mainAssetKey] = new compiler.webpack.sources.RawSource(\n getWebpackAssetScript(port) + '\\n' + originalSource,\n )\n },\n )\n }\n })\n}\n","import { getWebpackHtmlScript } from './webpack.js'\n\nexport function injectRspack(\n compiler: any,\n serverPortFn: () => Promise<number>,\n resolveClientModule: () => string,\n) {\n const inspectoClientPath = resolveClientModule()\n\n // Use the exact same entry injection strategy as Webpack\n new compiler.webpack.EntryPlugin(compiler.context, inspectoClientPath, {}).apply(compiler)\n\n compiler.hooks.compilation.tap('inspecto-overlay', (compilation: any) => {\n const HtmlRspackPlugin = compiler.options.plugins.find(\n (p: any) => p && p.constructor && p.constructor.name === 'HtmlRspackPlugin',\n )\n if (HtmlRspackPlugin) {\n const hooks = (HtmlRspackPlugin.constructor as any).getHooks(compilation)\n hooks.alterAssetTagGroups.tapPromise('inspecto-overlay', async (data: any) => {\n const port = await serverPortFn()\n\n data.headTags.unshift({\n tagName: 'script',\n voidTag: false,\n meta: { plugin: 'inspecto-overlay' },\n innerHTML: getWebpackHtmlScript(port),\n })\n return data\n })\n }\n })\n}\n","export function getViteVirtualModuleScript(serverPort: number) {\n return `\nimport { mountInspector } from '@inspecto-dev/core';\nwindow.__AI_INSPECTOR_PORT__ = ${serverPort};\nmountInspector({\n serverUrl: 'http://127.0.0.1:' + window.__AI_INSPECTOR_PORT__,\n});\n`\n}\n\nexport const VITE_VIRTUAL_MODULE_ID = '\\0virtual:inspecto-client'\nexport const VITE_VIRTUAL_IMPORT_ID = '/@id/__x00__virtual:inspecto-client'\n"],"mappings":"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","names":["path","MagicString","path","path","MagicString","path","fs","path","os","crypto","path","parser","traverse_","traverse","fs","path","path","fs","path","serverState","execFileSync","launchIDE","serverLogger","serverState","execFileSync","launchIDE","fs","path","serverLogger","fs","path","serverLogger","resolve","path","os","fs","crypto","resolve","path","serverLogger","resolveClientModule","resolveClientModule"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/transform/utils.ts","../src/transform/index.ts","../src/transform/transform-jsx.ts","../src/transform/transform-vue.ts","../src/server/index.ts","../src/server/snippet.ts","../src/config.ts","../src/utils/logger.ts","../src/server/dispatch-transport.ts","../src/server/dispatch-runtime.ts","../src/server/path-guards.ts","../src/server/annotation-dispatch.ts","../src/server/client-config.ts","../src/server/open-file.ts","../src/server/project-root.ts","../src/injectors/utils.ts","../src/injectors/webpack.ts","../src/injectors/rspack.ts","../src/injectors/vite.ts"],"sourcesContent":["import { createUnplugin } from 'unplugin'\nimport type { UnpluginOptions } from '@inspecto-dev/types'\nimport { extractTransformFilePath, shouldTransform } from './transform/utils.js'\nimport { transformRouter, transformJsx } from './transform/index.js'\nimport { startServer, serverState } from './server/index.js'\nimport { resolveClientModule } from './injectors/utils.js'\nimport { injectWebpack } from './injectors/webpack.js'\nimport { injectRspack } from './injectors/rspack.js'\nimport { setGlobalLogLevel } from './config.js'\nimport { createLogger } from './utils/logger.js'\nimport {\n getViteVirtualModuleScript,\n VITE_VIRTUAL_MODULE_ID,\n VITE_VIRTUAL_IMPORT_ID,\n} from './injectors/vite.js'\n\nimport type { ViteDevServer } from 'vite'\n\nexport type { UnpluginOptions }\n\nconst DEFAULT_OPTIONS: Required<UnpluginOptions> = {\n include: [],\n exclude: [],\n escapeTags: [],\n pathType: 'absolute',\n attributeName: 'data-inspecto',\n logLevel: 'warn',\n}\n\nconst DEFAULT_PORT = 5678\n\nconst InspectoPlugin = createUnplugin<UnpluginOptions | undefined>((userOptions = {}) => {\n const options: Required<UnpluginOptions> = {\n ...DEFAULT_OPTIONS,\n ...userOptions,\n }\n\n // Sync global log level based on user config\n setGlobalLogLevel(options.logLevel)\n const pluginLogger = createLogger('inspecto:plugin', { logLevel: options.logLevel })\n\n // Skip everything in production\n const isProduction = process.env['NODE_ENV'] === 'production'\n\n let projectRoot = process.cwd()\n let serverPort: number | null = null\n\n // Helper to ensure server is started\n const ensureServer = async () => {\n if (serverPort === null) {\n serverPort = await startServer()\n }\n return serverPort\n }\n\n return {\n name: 'inspecto-overlay',\n enforce: 'pre',\n\n buildStart() {\n if (isProduction) return\n projectRoot = serverState.cwd || process.cwd()\n\n // For pure bundlers (Rollup, Esbuild) that don't have devServer hooks\n // we need to ensure the server starts early enough.\n ensureServer().catch(err => pluginLogger.error('Failed to start server:', err))\n },\n\n buildEnd() {\n // Server cleanup is handled by process exit (server is unref'd, port file\n // removed via process.once('exit')). Calling stopServer() here would break\n // esbuild watch mode (which fires buildEnd after every incremental rebuild)\n // and is unnecessary for Vite/Rspack which manage their own lifecycles.\n },\n\n webpack: compiler => {\n if (isProduction) return\n injectWebpack(compiler, ensureServer, resolveClientModule)\n },\n\n rspack: compiler => {\n if (isProduction) return\n injectRspack(compiler, ensureServer, resolveClientModule)\n },\n\n vite: {\n config(config) {\n if (isProduction) return config\n return {\n ...config,\n define: {\n ...config.define,\n __AI_INSPECTOR_PORT__: JSON.stringify(DEFAULT_PORT), // Placeholder, rewritten in configureServer\n },\n }\n },\n\n resolveId(id) {\n if (id === 'virtual:inspecto-client') {\n return VITE_VIRTUAL_MODULE_ID\n }\n return null\n },\n\n load(id) {\n if (id === VITE_VIRTUAL_MODULE_ID) {\n // serverPort is guaranteed to be set by the time Vite requests this module\n // (configureServer awaits ensureServer before the dev server accepts requests)\n return getViteVirtualModuleScript(serverPort ?? DEFAULT_PORT)\n }\n return null\n },\n\n async configureServer(server: ViteDevServer) {\n if (isProduction) return\n const port = await ensureServer()\n if (!server.config.define) {\n ;(server.config as any).define = {}\n }\n ;(server.config as any).define['__AI_INSPECTOR_PORT__'] = JSON.stringify(port)\n // Invalidate the virtual module so load() re-runs with the correct port\n // (guards against the race where load() was called before configureServer resolved)\n const mod = server.moduleGraph.getModuleById(VITE_VIRTUAL_MODULE_ID)\n if (mod) server.moduleGraph.invalidateModule(mod)\n },\n\n transformIndexHtml(html) {\n if (isProduction || !serverPort) return html\n return {\n html,\n tags: [\n {\n tag: 'script',\n attrs: { type: 'module' },\n children: `import '${VITE_VIRTUAL_IMPORT_ID}';`,\n },\n ],\n }\n },\n },\n\n transformInclude(id) {\n if (isProduction || !id) return false\n return shouldTransform(id, options)\n },\n\n transform(code, id) {\n if (isProduction || !id) return null\n\n const { filePath } = extractTransformFilePath(id)\n\n const result = transformRouter({\n filePath,\n source: code,\n projectRoot,\n pluginOptions: options,\n })\n\n if (!result || !result.changed) return null\n\n return {\n code: result.code,\n map: result.map,\n }\n },\n }\n})\n\nexport const unplugin = InspectoPlugin\nexport const vitePlugin = InspectoPlugin.vite\nexport const webpackPlugin: (options?: UnpluginOptions) => any = InspectoPlugin.webpack\nexport const rspackPlugin = InspectoPlugin.rspack\nexport const rollupPlugin = InspectoPlugin.rollup\nexport const esbuildPlugin = InspectoPlugin.esbuild\nexport { transformJsx }\nexport default InspectoPlugin\n","import type { UnpluginOptions } from '@inspecto-dev/types'\nimport type MagicString from 'magic-string'\n\nexport interface TransformResult {\n code: string\n map: ReturnType<MagicString['generateMap']> | null\n changed: boolean\n}\n\nexport interface NormalizedTransformTarget {\n requestId: string\n filePath: string\n wrapped: boolean\n}\n\n/** Default tags whose JSX elements should NOT receive data-inspecto attributes */\nexport const DEFAULT_ESCAPE_TAGS = new Set([\n 'template',\n 'script',\n 'style',\n // React special elements\n 'Fragment',\n 'React.Fragment',\n 'StrictMode',\n 'React.StrictMode',\n 'Suspense',\n 'React.Suspense',\n 'Profiler',\n 'React.Profiler',\n // React transitions\n 'Transition',\n 'TransitionGroup',\n // Vue built-in components\n 'KeepAlive',\n 'Teleport',\n 'Suspense',\n // Vue router built-ins\n 'RouterView',\n 'RouterLink',\n 'NuxtPage',\n 'NuxtLink',\n])\n\n/** File extensions that contain JSX/TSX syntax */\nexport const JSX_EXTENSIONS = new Set(['.jsx', '.tsx', '.js', '.ts', '.mjs', '.mts'])\n\nfunction normalizeWebpackModuleRequest(id: string): string {\n return id.replace(/!+$/, '').replace(/^\\((?:app-pages-browser|rsc|ssr)\\)\\/\\.\\//, '')\n}\n\nfunction extractNextModuleRequest(id: string): string | undefined {\n if (!id.includes('next-flight-client-entry-loader.js?')) {\n return undefined\n }\n\n const queryIndex = id.indexOf('?')\n if (queryIndex === -1) {\n return undefined\n }\n\n const params = new URLSearchParams(id.slice(queryIndex + 1).replace(/!+$/, ''))\n for (const entry of params.getAll('modules')) {\n try {\n const parsed = JSON.parse(entry) as { request?: unknown }\n if (typeof parsed.request === 'string' && parsed.request.length > 0) {\n return parsed.request\n }\n } catch {\n continue\n }\n }\n\n return undefined\n}\n\nexport function extractTransformFilePath(requestId: string): NormalizedTransformTarget {\n const normalizedRequestId = normalizeWebpackModuleRequest(requestId)\n const nextModuleRequest = extractNextModuleRequest(normalizedRequestId)\n if (nextModuleRequest) {\n return {\n requestId,\n filePath: nextModuleRequest,\n wrapped: true,\n }\n }\n\n const lastLoaderSeparator = normalizedRequestId.lastIndexOf('!')\n const resourceRequest =\n lastLoaderSeparator >= 0\n ? normalizedRequestId.slice(lastLoaderSeparator + 1)\n : normalizedRequestId\n const queryIndex = resourceRequest.indexOf('?')\n const filePath = queryIndex >= 0 ? resourceRequest.slice(0, queryIndex) : resourceRequest\n\n return {\n requestId,\n filePath,\n wrapped: filePath !== requestId,\n }\n}\n\n/**\n * Determine if a file should be transformed.\n * Always skips node_modules and dist directories.\n */\nexport function shouldTransform(filePath: string, options: Required<UnpluginOptions>): boolean {\n const resolvedFilePath = extractTransformFilePath(filePath).filePath\n\n // Never transform in production\n if (process.env['NODE_ENV'] === 'production') return false\n\n // Skip node_modules always\n if (resolvedFilePath.includes('node_modules')) return false\n\n // Skip virtual modules\n if (resolvedFilePath.startsWith('\\x00')) return false\n\n // Skip dist/build directories\n if (/[/\\\\](dist|build|\\.next|\\.nuxt)[/\\\\]/.test(resolvedFilePath)) return false\n\n // Skip non-code files (like .html, .css)\n const ext = resolvedFilePath.split('.').pop()?.toLowerCase()\n if (ext && !['js', 'jsx', 'ts', 'tsx', 'mjs', 'mts', 'vue'].includes(ext)) {\n return false\n }\n\n // Check user-defined exclude patterns\n // (picomatch integration — see index.ts for how options.exclude is applied)\n\n return true\n}\n\n/**\n * Build the escape tags set from user options merged with defaults.\n */\nexport function buildEscapeTagsSet(escapeTags?: string[]): Set<string> {\n const merged = new Set(DEFAULT_ESCAPE_TAGS)\n if (escapeTags) {\n for (const tag of escapeTags) {\n merged.add(tag)\n }\n }\n return merged\n}\n\n/**\n * Format a source location value for the data-inspecto attribute.\n * Format: \"filepath:line:column\"\n */\nexport function formatAttrValue(file: string, line: number, column: number): string {\n return `${file}:${line}:${column}`\n}\n","import path from 'node:path'\nimport type { UnpluginOptions } from '@inspecto-dev/types'\nimport { transformJsx } from './transform-jsx.js'\nimport { transformVue } from './transform-vue.js'\nimport { JSX_EXTENSIONS, type TransformResult } from './utils.js'\n\nexport interface RouterOptions {\n filePath: string\n source: string\n projectRoot: string\n pluginOptions: Required<UnpluginOptions>\n}\n\n/**\n * Route a file to the appropriate transform based on extension.\n * Returns null if no transform applies.\n */\nexport function transformRouter(options: RouterOptions): TransformResult | null {\n const { filePath, source, projectRoot, pluginOptions } = options\n const ext = path.extname(filePath).toLowerCase()\n\n if (JSX_EXTENSIONS.has(ext)) {\n return transformJsx({\n filePath,\n source,\n projectRoot,\n escapeTags: pluginOptions.escapeTags,\n pathType: pluginOptions.pathType,\n attributeName: pluginOptions.attributeName,\n })\n }\n\n // ── Vue SFC ──────────────────────────────────────────────────────────────\n if (ext === '.vue') {\n return transformVue({\n filePath,\n source,\n projectRoot,\n escapeTags: pluginOptions.escapeTags,\n pathType: pluginOptions.pathType,\n attributeName: pluginOptions.attributeName,\n })\n }\n\n return null\n}\n// Export transforms for testing\nexport { transformJsx, transformVue }\n","import * as parser from '@babel/parser'\nimport traverse_ from '@babel/traverse'\n// Support both ESM default and CommonJS module.exports\nconst traverse =\n typeof traverse_ === 'function' ? traverse_ : (traverse_ as any).default || traverse_\nimport type { NodePath } from '@babel/traverse'\nimport type { JSXOpeningElement } from '@babel/types'\nimport MagicString from 'magic-string'\nimport path from 'node:path'\nimport type { UnpluginOptions, PathType } from '@inspecto-dev/types'\nimport { buildEscapeTagsSet, formatAttrValue, type TransformResult } from './utils.js'\n\nexport interface TransformJsxOptions {\n filePath: string\n source: string\n projectRoot: string\n escapeTags?: string[]\n pathType?: PathType\n attributeName?: string\n}\n\n/**\n * Transform JSX/TSX source code by injecting data-inspecto attributes.\n */\nexport function transformJsx(options: TransformJsxOptions): TransformResult {\n const {\n filePath,\n source,\n projectRoot,\n escapeTags,\n pathType = 'absolute',\n attributeName = 'data-inspecto',\n } = options\n\n const escapeTagsSet = buildEscapeTagsSet(escapeTags)\n\n // Resolve the file path based on pathType config\n const resolvedPath =\n pathType === 'absolute'\n ? path.resolve(filePath)\n : path.relative(projectRoot, path.resolve(filePath))\n\n // Normalize path separators on Windows\n const normalizedPath = resolvedPath.replace(/\\\\/g, '/')\n\n let ast: ReturnType<typeof parser.parse>\n try {\n ast = parser.parse(source, {\n sourceType: 'module',\n plugins: [\n 'jsx',\n 'typescript',\n 'decorators-legacy',\n 'classProperties',\n 'optionalChaining',\n 'nullishCoalescingOperator',\n 'importMeta',\n ],\n errorRecovery: true,\n })\n } catch {\n // If parsing fails, return source unchanged\n return { code: source, map: null, changed: false }\n }\n\n const ms = new MagicString(source)\n let changed = false\n\n traverse(ast, {\n JSXOpeningElement(nodePath: NodePath<JSXOpeningElement>) {\n const node = nodePath.node\n\n // Skip elements that already have the attribute\n const alreadyHasAttr = node.attributes.some(\n attr =>\n attr.type === 'JSXAttribute' &&\n attr.name.type === 'JSXIdentifier' &&\n attr.name.name === attributeName,\n )\n if (alreadyHasAttr) return\n\n // Get element tag name\n const nameNode = node.name\n let tagName: string\n if (nameNode.type === 'JSXIdentifier') {\n tagName = nameNode.name\n } else if (nameNode.type === 'JSXMemberExpression') {\n const objName = nameNode.object.type === 'JSXIdentifier' ? nameNode.object.name : ''\n const propName = nameNode.property.type === 'JSXIdentifier' ? nameNode.property.name : ''\n tagName = objName && propName ? `${objName}.${propName}` : objName\n } else {\n tagName = ''\n }\n\n // Skip escaped tags\n if (escapeTagsSet.has(tagName)) return\n\n // Get position from AST location\n const loc = node.loc\n if (!loc) return\n\n const { line, column } = loc.start\n // Babel uses 0-based columns, convert to 1-based\n const attrValue = formatAttrValue(normalizedPath, line, column + 1)\n\n // Determine the best insertion position for the attribute\n // When a JSX element has type arguments (e.g. <Component<string> />),\n // inserting after `node.name.end` might inject inside the generic bracket `<`.\n // The safest place to insert is right before the first attribute,\n // or right before the closing slash/bracket if there are no attributes.\n let insertPos: number | null | undefined = null\n if (node.attributes && node.attributes.length > 0) {\n const firstAttr = node.attributes[0]\n if (firstAttr && firstAttr.start != null) {\n insertPos = firstAttr.start\n }\n }\n\n if (insertPos == null) {\n // Find the start of the closing bracket or self-closing slash\n // We know node.end is the index right after the '>'\n // So we look backwards. But Babel AST doesn't give us exact token positions\n // for the closing tag easily.\n // For a safe fallback, we use node.typeParameters?.end || node.name.end\n if (node.typeParameters && node.typeParameters.end != null) {\n insertPos = node.typeParameters.end\n } else if (node.name.end != null) {\n insertPos = node.name.end\n }\n }\n\n if (insertPos == null) return\n\n ms.appendLeft(\n insertPos,\n ` ${attributeName}=\"${attrValue}\"${node.attributes && node.attributes.length > 0 ? '' : ' '}`,\n )\n changed = true\n },\n })\n\n if (!changed) {\n return { code: source, map: null, changed: false }\n }\n\n return {\n code: ms.toString(),\n map: ms.generateMap({ hires: true, source: filePath }),\n changed: true,\n }\n}\n","import * as vueCompiler from '@vue/compiler-dom'\nimport { parse as parseSFC } from '@vue/compiler-sfc'\nimport type { ElementNode, AttributeNode } from '@vue/compiler-core'\nimport { NodeTypes } from '@vue/compiler-core'\nimport MagicString from 'magic-string'\nimport path from 'node:path'\nimport type { PathType } from '@inspecto-dev/types'\nimport { buildEscapeTagsSet, formatAttrValue, type TransformResult } from './utils.js'\n\nexport interface TransformVueOptions {\n filePath: string\n source: string\n projectRoot: string\n escapeTags?: string[]\n pathType?: PathType\n attributeName?: string\n}\n\n/**\n * Transform Vue SFC source by injecting data-inspecto attributes\n * into template elements.\n *\n * Strategy:\n * 1. Locate the <template> block in the SFC source\n * 2. Parse only the template block with @vue/compiler-dom\n * 3. Walk ElementNode nodes in the AST\n * 4. For each eligible element, inject the attribute using MagicString\n * at the exact offset within the original source\n */\nexport function transformVue(options: TransformVueOptions): TransformResult {\n const {\n filePath,\n source,\n projectRoot,\n escapeTags,\n pathType = 'absolute',\n attributeName = 'data-inspecto',\n } = options\n\n const escapeTagsSet = buildEscapeTagsSet(escapeTags)\n\n // Resolve path\n const resolvedPath =\n pathType === 'absolute'\n ? path.resolve(filePath)\n : path.relative(projectRoot, path.resolve(filePath))\n\n const normalizedPath = resolvedPath.replace(/\\\\/g, '/')\n\n // ── Find <template> block boundaries ──────────────────────────────────────\n // Use @vue/compiler-sfc to parse the file and extract the template block.\n // This is much safer than regex for handling nested templates.\n const { descriptor, errors } = parseSFC(source, {\n filename: filePath,\n sourceMap: false,\n ignoreEmpty: true,\n })\n\n if (errors.length > 0 || !descriptor.template) {\n return { code: source, map: null, changed: false }\n }\n\n const templateContent = descriptor.template.content\n const templateBlockStart = descriptor.template.loc.start.offset\n\n // ── Parse template block ───────────────────────────────────────────────────\n let ast: vueCompiler.RootNode\n try {\n ast = vueCompiler.parse(templateContent, {\n parseMode: 'html',\n // Preserve source locations relative to templateContent\n onError: () => {\n /* ignore non-fatal parse errors */\n },\n })\n } catch {\n return { code: source, map: null, changed: false }\n }\n\n const ms = new MagicString(source)\n let changed = false\n\n // ── Walk AST ───────────────────────────────────────────────────────────────\n walkElement(ast, node => {\n // Skip non-element nodes\n if (node.type !== NodeTypes.ELEMENT) return\n\n const tagName = node.tag\n\n // Skip escaped tags\n if (escapeTagsSet.has(tagName)) return\n\n // Skip <template> wrapper itself (it's the root, not a real element)\n if (tagName === 'template' && node === ast.children[0]) return\n\n // Skip elements that already have the attribute (idempotency)\n const alreadyHasAttr = node.props.some(\n (p): p is AttributeNode => p.type === NodeTypes.ATTRIBUTE && p.name === attributeName,\n )\n if (alreadyHasAttr) return\n\n // node.loc is relative to templateContent — add templateBlockStart offset\n const loc = node.loc\n if (!loc) return\n\n const { line, column } = loc.start\n\n // Calculate absolute line and column in the original source\n // @vue/compiler-dom uses 1-based line and 1-based column\n const templateStartLoc = descriptor.template!.loc.start\n const absoluteLine = templateStartLoc.line + line - 1\n const absoluteColumn = line === 1 ? templateStartLoc.column + column - 1 : column\n\n const attrValue = formatAttrValue(normalizedPath, absoluteLine, absoluteColumn)\n\n // Find insert position: right after the tag name in the original source\n // node.loc.start.offset is 0-based offset within templateContent\n const tagNameEnd = loc.start.offset + tagName.length + 1 // +1 for '<'\n const absoluteOffset = templateBlockStart + tagNameEnd\n\n ms.appendLeft(absoluteOffset, ` ${attributeName}=\"${attrValue}\"`)\n changed = true\n })\n\n if (!changed) {\n return { code: source, map: null, changed: false }\n }\n\n return {\n code: ms.toString(),\n map: ms.generateMap({ hires: true, source: filePath }),\n changed: true,\n }\n}\n\n// ── AST walker ────────────────────────────────────────────────────────────────\n\ntype AnyNode = vueCompiler.RootNode | vueCompiler.TemplateChildNode\n\nfunction walkElement(node: AnyNode, visitor: (node: ElementNode) => void): void {\n if (node.type === NodeTypes.ELEMENT) {\n visitor(node)\n for (const child of node.children) {\n walkElement(child as AnyNode, visitor)\n }\n } else if ('children' in node && Array.isArray(node.children)) {\n for (const child of node.children) {\n walkElement(child as AnyNode, visitor)\n }\n }\n}\n","import http from 'node:http'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport os from 'node:os'\nimport crypto from 'node:crypto'\nimport portfinder from 'portfinder'\nimport type {\n ServerState,\n OpenFileRequest,\n SendToAiRequest,\n SendToAiResponse,\n SendAnnotationsToAiRequest,\n SendAnnotationsToAiResponse,\n} from '@inspecto-dev/types'\nimport { INSPECTO_API_PATHS } from '@inspecto-dev/types'\nimport { extractSnippet } from './snippet.js'\nimport { dispatchAnnotationsToAi } from './annotation-dispatch.js'\nimport { readTicket } from './dispatch-transport.js'\nimport { dispatchPromptThroughIde, resolvePromptDispatchRuntime } from './dispatch-runtime.js'\nimport { assertPathWithinProject, resolveWorkspacePath } from './path-guards.js'\nimport { buildClientConfig } from './client-config.js'\nimport { handleOpenFileRequest } from './open-file.js'\nimport { resolveProjectRoot } from './project-root.js'\nimport { watchConfig, unwatchConfig, getGlobalLogLevel } from '../config.js'\nimport { createLogger } from '../utils/logger.js'\n\nconst serverLogger = createLogger('inspecto:server', { logLevel: getGlobalLogLevel() })\n\nexport const serverState: ServerState = {\n port: null,\n running: false,\n projectRoot: '',\n configRoot: '',\n cwd: process.cwd(),\n}\n\nlet serverInstance: http.Server | null = null\n\nexport async function startServer(): Promise<number> {\n if (serverState.running && serverState.port !== null) {\n return serverState.port\n }\n\n // Resolve project root at server start time so process.cwd() reflects the\n // actual project directory, not the module load-time cwd.\n serverState.projectRoot = resolveProjectRoot()\n serverState.configRoot = serverState.projectRoot\n serverState.cwd = process.cwd()\n\n portfinder.basePort = 5678\n const port = await portfinder.getPortPromise()\n\n // Watch for user config changes to trigger hot-reloads internally if needed\n watchConfig(\n () => {\n serverLogger.info('user config reloaded.')\n },\n serverState.cwd,\n serverState.configRoot,\n )\n\n serverInstance = http.createServer((req, res) => {\n res.setHeader('Access-Control-Allow-Origin', '*')\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type')\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204)\n res.end()\n return\n }\n\n const url = new URL(req.url ?? '/', `http://localhost:${port}`)\n handleRequest(url, req, res).catch(err => {\n serverLogger.error('server error:', err)\n res.writeHead(500, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ success: false, error: String(err) }))\n })\n })\n\n await new Promise<void>((resolve, reject) => {\n serverInstance!.listen(port, '127.0.0.1', () => {\n serverInstance!.unref() // Allow process to exit\n resolve()\n })\n serverInstance!.once('error', reject)\n })\n\n // Add persistent error handler after successful startup\n serverInstance!.on('error', err => {\n serverLogger.error('persistent server error:', err)\n })\n\n serverState.port = port\n serverState.running = true\n\n // Write port file so the IDE extension can discover the server without scanning ports\n const portFile = path.join(os.tmpdir(), 'inspecto.port.json')\n try {\n let portData: Record<string, number> = {}\n if (fs.existsSync(portFile)) {\n try {\n portData = JSON.parse(fs.readFileSync(portFile, 'utf-8'))\n } catch (e) {\n // Invalid JSON, start fresh\n }\n }\n // Hash the project root to avoid invalid keys or paths in JSON\n const rootHash = crypto.createHash('md5').update(serverState.projectRoot).digest('hex')\n portData[rootHash] = port\n fs.writeFileSync(portFile, JSON.stringify(portData, null, 2), 'utf-8')\n } catch (e) {\n serverLogger.warn('Failed to write port file:', e)\n /* non-fatal — extension will fall back to scanning */\n }\n // Clean up on process exit (Vite terminates the process, not stopServer)\n process.once('exit', () => {\n try {\n if (fs.existsSync(portFile)) {\n const portData = JSON.parse(fs.readFileSync(portFile, 'utf-8'))\n const rootHash = crypto.createHash('md5').update(serverState.projectRoot).digest('hex')\n delete portData[rootHash]\n if (Object.keys(portData).length === 0) {\n fs.unlinkSync(portFile)\n } else {\n fs.writeFileSync(portFile, JSON.stringify(portData, null, 2), 'utf-8')\n }\n }\n } catch {\n /* ignore */\n }\n })\n\n serverLogger.info(`server running at http://127.0.0.1:${port}`)\n\n return port\n}\n\nexport function stopServer(): void {\n if (serverInstance) {\n serverInstance.close()\n serverInstance = null\n }\n unwatchConfig()\n serverState.running = false\n serverState.port = null\n try {\n fs.unlinkSync(path.join(os.tmpdir(), 'inspecto.port'))\n } catch {\n /* ignore */\n }\n}\n\nasync function readBody(req: http.IncomingMessage): Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = []\n req.on('data', (chunk: Buffer) => chunks.push(chunk))\n req.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')))\n req.on('error', reject)\n })\n}\n\nexport async function handleRequest(\n url: URL,\n req: http.IncomingMessage,\n res: http.ServerResponse,\n): Promise<void> {\n const pathname = url.pathname\n\n // Health check - root or /inspecto/api/v1/health\n if ((pathname === '/health' || pathname === INSPECTO_API_PATHS.HEALTH) && req.method === 'GET') {\n res.writeHead(200, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ ok: true, port: serverState.port }))\n return\n }\n\n // Browser Client requests\n if (pathname === INSPECTO_API_PATHS.CLIENT_CONFIG && req.method === 'GET') {\n const config = await buildClientConfig(serverState)\n\n // Omit providers from the response sent to the client\n delete config.providers\n\n res.writeHead(200, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify(config))\n return\n }\n\n if (pathname === INSPECTO_API_PATHS.IDE_INFO && req.method === 'POST') {\n try {\n const body = JSON.parse(await readBody(req))\n\n // Workspace matching defense mechanism against multiple IDE connections\n const ideWorkspace = body.workspaceRoot || ''\n const serverProjectRoot = serverState.projectRoot || ''\n\n const normalizedIdeRoot = ideWorkspace ? path.resolve(ideWorkspace) : ''\n const normalizedServerRoot = serverProjectRoot ? path.resolve(serverProjectRoot) : ''\n\n const isSameProject =\n !normalizedIdeRoot ||\n !normalizedServerRoot ||\n normalizedIdeRoot === normalizedServerRoot ||\n normalizedServerRoot.startsWith(normalizedIdeRoot + path.sep) ||\n normalizedIdeRoot.startsWith(normalizedServerRoot + path.sep)\n\n if (isSameProject) {\n serverState.ideInfo = body\n serverLogger.debug(\n `Accepted IDE info from matched workspace (ide-${body.ide} / schema-${body.scheme})`,\n )\n } else {\n serverLogger.debug(\n `Ignored IDE info from unrelated workspace (IDE Workspace: ${ideWorkspace}, Server: ${serverProjectRoot}, Scheme: ${body.scheme}, IDE: ${body.ide})`,\n )\n }\n\n res.writeHead(200, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ success: true }))\n } catch (e) {\n serverLogger.error(`Error parsing ${INSPECTO_API_PATHS.IDE_INFO} POST request:`, e)\n res.writeHead(400, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ error: 'Invalid JSON body' }))\n }\n return\n }\n\n if (pathname === INSPECTO_API_PATHS.IDE_OPEN && req.method === 'POST') {\n let body: OpenFileRequest\n try {\n body = JSON.parse(await readBody(req)) as OpenFileRequest\n } catch (e) {\n res.writeHead(400, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ error: 'Invalid JSON body' }))\n return\n }\n\n try {\n handleOpenFileRequest(body, serverState)\n } catch (err: any) {\n serverLogger.warn(\n `Security: Blocked path traversal attempt in IDE_OPEN: ${body.file}. Reason: ${err.message}`,\n )\n res.writeHead(403, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ error: 'Access denied: File is outside of project workspace' }))\n return\n }\n\n res.writeHead(200, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ success: true }))\n return\n }\n\n if (pathname === INSPECTO_API_PATHS.PROJECT_SNIPPET && req.method === 'GET') {\n const file = url.searchParams.get('file') ?? ''\n const line = parseInt(url.searchParams.get('line') ?? '1', 10)\n const column = parseInt(url.searchParams.get('column') ?? '1', 10)\n const maxLines = parseInt(url.searchParams.get('maxLines') ?? '100', 10)\n\n try {\n const absolutePath = resolveWorkspacePath(file, serverState.cwd)\n\n // Security: Prevent path traversal attacks\n try {\n assertPathWithinProject(absolutePath, serverState.projectRoot)\n } catch (err: any) {\n serverLogger.warn(\n `Security: Blocked path traversal attempt in PROJECT_SNIPPET: ${file}. Reason: ${err.message}`,\n )\n res.writeHead(403, { 'Content-Type': 'application/json' })\n res.end(\n JSON.stringify({\n success: false,\n error: 'Access denied: File is outside of project workspace',\n errorCode: 'FORBIDDEN',\n }),\n )\n return\n }\n\n const result = await extractSnippet({ file: absolutePath, line, column, maxLines })\n res.writeHead(200, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify(result))\n } catch (err: any) {\n const message = String(err.message || err)\n const errorCode = message.startsWith('FILE_NOT_FOUND') ? 'FILE_NOT_FOUND' : 'UNKNOWN'\n res.writeHead(404, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ success: false, error: message, errorCode }))\n }\n return\n }\n\n if (pathname === INSPECTO_API_PATHS.AI_DISPATCH && req.method === 'POST') {\n try {\n const rawBody = await readBody(req)\n const body = JSON.parse(rawBody) as SendToAiRequest\n const result = await dispatchToAi(body)\n res.writeHead(result.success ? 200 : 500, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify(result))\n } catch (e) {\n serverLogger.error(`Error parsing ${INSPECTO_API_PATHS.AI_DISPATCH} request:`, e)\n res.writeHead(500, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ success: false, error: String(e), errorCode: 'INTERNAL_ERROR' }))\n }\n return\n }\n\n if (pathname === INSPECTO_API_PATHS.AI_BATCH_DISPATCH && req.method === 'POST') {\n try {\n const rawBody = await readBody(req)\n const body = JSON.parse(rawBody) as SendAnnotationsToAiRequest\n const result = await dispatchAnnotationsToAi(body, serverState)\n res.writeHead(getBatchDispatchStatusCode(result.errorCode, result.success), {\n 'Content-Type': 'application/json',\n })\n res.end(JSON.stringify(result))\n } catch (e) {\n serverLogger.error(`Error parsing ${INSPECTO_API_PATHS.AI_BATCH_DISPATCH} request:`, e)\n res.writeHead(500, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ success: false, error: String(e), errorCode: 'INTERNAL_ERROR' }))\n }\n return\n }\n\n // Handle IDE payload ticket retrieval\n if (pathname.startsWith(`${INSPECTO_API_PATHS.AI_TICKET}/`) && req.method === 'GET') {\n const ticketId = pathname.substring(INSPECTO_API_PATHS.AI_TICKET.length + 1)\n const payloadStr = readTicket(ticketId)\n\n if (!payloadStr) {\n res.writeHead(404, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ success: false, error: 'Ticket not found or expired' }))\n return\n }\n\n res.writeHead(200, { 'Content-Type': 'application/json' })\n res.end(payloadStr)\n return\n }\n\n res.writeHead(404, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ error: 'not found' }))\n}\n\nasync function dispatchToAi(\n req: SendToAiRequest,\n): Promise<SendToAiResponse & { fallbackPayload?: { prompt: string; file: string } }> {\n const { location, snippet, prompt, screenshotContext } = req\n\n const formattedPrompt =\n prompt ??\n `Please help me with this code from \\`${location.file}\\` (line ${location.line}):\\n\\n\\`\\`\\`\\n${snippet}\\n\\`\\`\\`\\n`\n const runtime = resolvePromptDispatchRuntime(serverState)\n return dispatchPromptThroughIde(runtime, {\n prompt: formattedPrompt,\n filePath: location.file,\n line: location.line,\n column: location.column,\n snippet,\n ...(screenshotContext ? { screenshotContext } : {}),\n }) as SendToAiResponse & { fallbackPayload?: { prompt: string; file: string } }\n}\n\nfunction getBatchDispatchStatusCode(\n errorCode: SendAnnotationsToAiResponse['errorCode'],\n success: boolean,\n): number {\n if (success) return 200\n if (errorCode === 'INVALID_REQUEST') return 400\n if (errorCode === 'FORBIDDEN_PATH') return 403\n return 500\n}\n","import * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport * as parser from '@babel/parser'\nimport traverse_ from '@babel/traverse'\n// Support both ESM default and CommonJS module.exports\nconst traverse =\n typeof traverse_ === 'function' ? traverse_ : (traverse_ as any).default || traverse_\nimport type { NodePath } from '@babel/traverse'\nimport type { Node } from '@babel/types'\nimport type { SnippetRequest, SnippetResponse } from '@inspecto-dev/types'\n\ninterface CacheEntry {\n mtime: number\n /** The full parsed source lines */\n lines: string[]\n}\n\n/** In-memory cache keyed by absolute file path */\nconst snippetCache = new Map<string, CacheEntry>()\n\nconst DEFAULT_MAX_LINES = 100\nconst DEFAULT_CONTEXT_LINES_BEFORE = 5\n\nexport async function extractSnippet(req: SnippetRequest): Promise<SnippetResponse> {\n const { file, line, column, maxLines = DEFAULT_MAX_LINES } = req\n\n const absolutePath = path.resolve(file)\n\n let stat: fs.Stats\n try {\n stat = await fs.promises.stat(absolutePath)\n } catch {\n throw new Error(`FILE_NOT_FOUND: ${absolutePath}`)\n }\n\n const mtime = stat.mtimeMs\n\n let lines: string[]\n const cached = snippetCache.get(absolutePath)\n if (cached && cached.mtime === mtime) {\n lines = cached.lines\n } else {\n const source = await fs.promises.readFile(absolutePath, 'utf-8')\n lines = source.split('\\n')\n snippetCache.set(absolutePath, { mtime, lines })\n }\n\n let snippetLines: string[]\n let startLine: number\n let componentName: string | undefined\n\n try {\n const result = extractComponentBoundary(lines.join('\\n'), line, column, maxLines)\n snippetLines = result.lines\n startLine = result.startLine\n componentName = result.name\n } catch {\n const before = Math.max(0, line - 1 - DEFAULT_CONTEXT_LINES_BEFORE)\n const after = Math.min(lines.length, before + maxLines)\n snippetLines = lines.slice(before, after)\n startLine = before + 1\n }\n\n if (snippetLines.length > maxLines) {\n snippetLines = snippetLines.slice(0, maxLines)\n }\n\n return {\n snippet: snippetLines.join('\\n'),\n startLine,\n file: absolutePath,\n ...(componentName ? { name: componentName } : {}),\n }\n}\n\ninterface BoundaryResult {\n lines: string[]\n startLine: number\n name?: string\n}\n\nfunction extractComponentBoundary(\n source: string,\n targetLine: number,\n _targetColumn: number,\n maxLines: number,\n): BoundaryResult {\n const ast = parser.parse(source, {\n sourceType: 'module',\n plugins: ['jsx', 'typescript', 'decorators-legacy', 'classProperties'],\n errorRecovery: true,\n })\n\n const allLines = source.split('\\n')\n\n let bestStart = 0\n let bestEnd = allLines.length - 1\n let bestName: string | undefined\n\n traverse(ast, {\n 'FunctionDeclaration|FunctionExpression|ArrowFunctionExpression|ClassMethod'(\n nodePath: NodePath<Node>,\n ) {\n const node = nodePath.node\n if (!node.loc) return\n\n const nodeStart = node.loc.start.line\n const nodeEnd = node.loc.end.line\n\n if (targetLine < nodeStart || targetLine > nodeEnd) return\n\n if (nodeEnd - nodeStart < bestEnd - bestStart) {\n bestStart = nodeStart - 1\n bestEnd = nodeEnd - 1\n bestName = extractFunctionName(nodePath)\n }\n },\n })\n\n let sliceStart = bestStart\n let sliceEnd = bestEnd + 1\n\n if (sliceEnd - sliceStart > maxLines) {\n const targetIdx = targetLine - 1\n sliceStart = Math.max(bestStart, targetIdx - Math.floor(maxLines / 3))\n sliceEnd = sliceStart + maxLines\n if (sliceEnd > bestEnd + 1) {\n sliceEnd = bestEnd + 1\n sliceStart = Math.max(0, sliceEnd - maxLines)\n }\n }\n\n return {\n lines: allLines.slice(sliceStart, sliceEnd),\n startLine: sliceStart + 1,\n ...(bestName ? { name: bestName } : {}),\n }\n}\n\nfunction extractFunctionName(nodePath: NodePath<Node>): string | undefined {\n const node = nodePath.node\n\n if (node.type === 'FunctionDeclaration' && node.id) {\n return node.id.name\n }\n\n const parent = nodePath.parent\n if (\n (node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression') &&\n parent.type === 'VariableDeclarator' &&\n parent.id.type === 'Identifier'\n ) {\n return parent.id.name\n }\n\n if (node.type === 'ClassMethod' && node.key.type === 'Identifier') {\n return node.key.name\n }\n\n return undefined\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport os from 'node:os'\nimport { createDefu } from 'defu'\nimport type {\n InspectoSettings,\n InspectoPromptsConfig,\n Provider,\n ProviderMode,\n ToolOverrides,\n IdeType,\n LogLevel,\n} from '@inspecto-dev/types'\nimport {\n DEFAULT_PROVIDER_MODE,\n VALID_MODES,\n DEFAULT_INTENTS,\n IntentConfig,\n} from '@inspecto-dev/types'\nimport { createLogger, setLoggerGlobalLevel } from './utils/logger.js'\n\nconst configLogger = createLogger('inspecto:config')\n\nlet loadedConfig: InspectoSettings | null = null\nlet loadedPrompts: InspectoPromptsConfig | null = null\nlet globalLogLevel: LogLevel = 'warn'\nlet isWatching = false\n\n// Custom array merge behavior for defu: overwrite arrays instead of concatenating them\nconst arrayReplaceMerge = createDefu((obj, key, val) => {\n if (Array.isArray(val)) {\n obj[key] = val\n return true\n }\n})\n\nexport function setGlobalLogLevel(level?: LogLevel) {\n if (level) {\n globalLogLevel = level\n setLoggerGlobalLevel(level)\n }\n}\n\nexport function getGlobalLogLevel() {\n return globalLogLevel\n}\n\n/**\n * Walk from cwd up to gitRoot (inclusive), collecting directories that contain\n * a .inspecto/ subdirectory. Returns them ordered highest-priority first\n * (closest to cwd first).\n *\n * If cwd is not under gitRoot, only cwd itself is checked.\n */\nexport function resolveConfigRoots(cwd: string, gitRoot: string): string[] {\n const roots: string[] = []\n let current = cwd\n\n // Ensure we don't walk past gitRoot (handles cwd above gitRoot case)\n const isUnderOrEqual = current === gitRoot || current.startsWith(gitRoot + path.sep)\n if (!isUnderOrEqual) {\n // cwd is not under gitRoot — only check cwd\n if (fs.existsSync(path.join(cwd, '.inspecto'))) roots.push(cwd)\n return roots\n }\n\n while (true) {\n if (fs.existsSync(path.join(current, '.inspecto'))) {\n roots.push(current)\n }\n if (current === gitRoot) break\n const parent = path.dirname(current)\n if (parent === current) break // filesystem root guard\n current = parent\n }\n\n return roots\n}\n\n/**\n * Load and merge user config from all discovered .inspecto/ layers:\n *\n * Priority (highest → lowest):\n * <cwd>/.inspecto/settings.local.json\n * <cwd>/.inspecto/settings.json\n * ...intermediate dirs...\n * <gitRoot>/.inspecto/settings.local.json\n * <gitRoot>/.inspecto/settings.json\n * ~/.inspecto/settings.json\n *\n * @param force Bust cache and re-read from disk\n * @param cwd Working directory to start resolution from (default: process.cwd())\n * @param gitRoot Git repository root — upward traversal stops here (optional)\n */\nexport function loadUserConfigSync(\n force = false,\n cwd = process.cwd(),\n gitRoot?: string,\n): InspectoSettings {\n if (loadedConfig && !force) return loadedConfig\n loadedConfig = null // force clear\n\n const layers: Partial<InspectoSettings>[] = []\n const roots = resolveConfigRoots(cwd, gitRoot ?? cwd)\n\n for (const root of roots) {\n layers.push(readJsonSafely(path.join(root, '.inspecto', 'settings.local.json')))\n layers.push(readJsonSafely(path.join(root, '.inspecto', 'settings.json')))\n }\n\n layers.push(readJsonSafely(path.join(os.homedir(), '.inspecto', 'settings.json')))\n layers.push({})\n\n const validLayers = layers.filter(l => l !== null)\n loadedConfig = arrayReplaceMerge(...(validLayers as [object, ...object[]])) as InspectoSettings\n return loadedConfig\n}\n\n/**\n * Load and merge prompts config from all discovered .inspecto/ layers:\n *\n * Priority (highest → lowest):\n * <cwd>/.inspecto/prompts.local.json\n * <cwd>/.inspecto/prompts.json\n * ...intermediate dirs...\n * <gitRoot>/.inspecto/prompts.local.json\n * <gitRoot>/.inspecto/prompts.json\n * ~/.inspecto/prompts.json\n *\n * Arrays in custom configurations are replaced instead of merged.\n */\nexport async function loadPromptsConfig(\n force = false,\n cwd = process.cwd(),\n gitRoot?: string,\n): Promise<InspectoPromptsConfig> {\n if (loadedPrompts && !force) return loadedPrompts\n\n const layers: any[] = []\n\n const roots = resolveConfigRoots(cwd, gitRoot ?? cwd)\n for (const root of roots) {\n const localPath = path.join(root, '.inspecto', 'prompts.local.json')\n const jsonPath = path.join(root, '.inspecto', 'prompts.json')\n layers.push(readJsonSafely(localPath))\n layers.push(readJsonSafely(jsonPath))\n }\n\n layers.push(readJsonSafely(path.join(os.homedir(), '.inspecto', 'prompts.json')))\n\n // Find the first layer that contains a valid prompts config (array or $replace object).\n // Highest-priority layer wins — no merging across layers for prompts.\n let finalPrompts: any = []\n for (const layer of layers) {\n if (Array.isArray(layer) && layer.length > 0) {\n finalPrompts = layer\n break\n }\n if (\n layer &&\n typeof layer === 'object' &&\n layer.$replace === true &&\n Array.isArray(layer.items)\n ) {\n finalPrompts = layer\n break\n }\n }\n\n loadedPrompts = finalPrompts as InspectoPromptsConfig\n return loadedPrompts\n}\n\nfunction readJsonSafely(filePath: string): any {\n try {\n if (fs.existsSync(filePath)) {\n const content = fs.readFileSync(filePath, 'utf-8').trim()\n if (!content) return null // Return null instead of [] so we know it's empty\n const parsed = JSON.parse(content)\n // Transition helper: if user still has {\"prompts\": [...]}, extract it\n if (!Array.isArray(parsed) && parsed.prompts && Array.isArray(parsed.prompts)) {\n return parsed.prompts\n }\n return parsed\n }\n } catch (e) {\n // Ignore JSON parsing errors for empty or malformed files during watch\n if (e instanceof SyntaxError) {\n configLogger.warn(`Failed to parse config at ${filePath}: Invalid JSON`)\n } else {\n configLogger.warn(`Failed to read config at ${filePath}:`, e)\n }\n }\n return null\n}\n\n/**\n * Resolve the exact target tool to dispatch to based on user config.\n */\nexport function resolveTargetTool(config: InspectoSettings, ide: IdeType = 'vscode'): Provider {\n // Support \"provider.default\" (e.g., \"claude-code.extension\")\n const defaultProvider = config['provider.default'] as string | undefined\n if (defaultProvider) {\n const tool = defaultProvider.split('.')[0]\n return tool as Provider\n }\n\n // Fallback\n return 'copilot'\n}\n\n/**\n * Resolve the effective mode/type for a tool in the context of an IDE.\n */\nexport function resolveProviderMode(\n tool: Provider,\n ide: IdeType,\n config: InspectoSettings,\n): ProviderMode {\n let requestedType: ProviderMode | undefined = undefined\n\n // V2 format: check provider.default for \"tool.mode\"\n const defaultProvider = config['provider.default'] as string | undefined\n if (defaultProvider && defaultProvider.startsWith(`${tool}.`)) {\n const mode = defaultProvider.split('.')[1]\n if (mode === 'extension') requestedType = 'extension'\n if (mode === 'cli') requestedType = 'cli'\n }\n\n requestedType = requestedType ?? DEFAULT_PROVIDER_MODE[tool]\n const valid = VALID_MODES[tool] || [DEFAULT_PROVIDER_MODE[tool]]\n return requestedType && valid.includes(requestedType) ? requestedType : valid[0]!\n}\n\n/**\n * Extract ToolOverrides (binaryPath, args, etc) for Extension consumption.\n */\nexport function extractToolOverrides(\n ide: IdeType,\n config: InspectoSettings,\n): Partial<Record<Provider, ToolOverrides>> {\n const result: Partial<Record<Provider, ToolOverrides>> = {}\n\n if (!config) return result\n\n // Parse new flat `provider.*` format\n for (const [key, value] of Object.entries(config)) {\n if (!key.startsWith('provider.')) continue\n\n // We only process tool specific overrides, ignore `.default`\n if (key === 'provider.default') continue\n\n // Handle `provider.[tool].[mode]`\n const toolIndex = 1\n const modeIndex = 2\n const propIndex = 3\n\n const parts = key.split('.')\n\n if (parts.length >= propIndex + 1) {\n const tool = parts[toolIndex] as Provider\n const mode = parts[modeIndex] as ProviderMode\n const prop = parts[propIndex]\n\n if (!result[tool]) {\n result[tool] = { type: mode }\n }\n\n const overrides = result[tool]!\n\n // If we see config for a mode that differs from what we've initialized,\n // it means both modes have config. In v2, mode is determined by provider.default.\n // We will just accumulate the settings for now and let resolveProviderMode decide the active type.\n\n if (prop === 'bin') overrides.binaryPath = value as string\n if (prop === 'args') overrides.args = value as string[]\n if (prop === 'cwd') overrides.cwd = value as string\n if (prop === 'coldStartDelay') overrides.coldStartDelay = value as number\n }\n }\n\n return result\n}\n\nexport function resolveIntents(serverPrompts?: InspectoPromptsConfig): IntentConfig[] {\n // Start with DEFAULT_INTENTS as base\n const baseMap = new Map<string, IntentConfig>()\n for (const intent of DEFAULT_INTENTS) {\n baseMap.set(intent.id, { ...intent } as IntentConfig)\n }\n\n const defaults = () => Array.from(baseMap.values())\n\n if (!serverPrompts) return defaults()\n\n const isReplace =\n !Array.isArray(serverPrompts) &&\n typeof serverPrompts === 'object' &&\n serverPrompts.$replace === true\n const promptsArray = Array.isArray(serverPrompts)\n ? serverPrompts\n : isReplace\n ? serverPrompts.items\n : []\n\n if (!promptsArray || promptsArray.length === 0) return defaults()\n\n if (isReplace) {\n // $replace: true — exact list, user controls everything\n const result: IntentConfig[] = []\n for (const item of promptsArray) {\n if (typeof item === 'string') {\n if (baseMap.has(item)) {\n result.push(baseMap.get(item)!)\n } else {\n configLogger.warn(\n `Unknown built-in intent id: \"${item}\". Available: ${[...baseMap.keys()].join(', ')}`,\n )\n }\n } else if (typeof item === 'object') {\n if (!item.id) {\n configLogger.warn('Intent object missing required \"id\" field, skipping.')\n continue\n }\n if (item.enabled === false) {\n configLogger.warn(\n `Intent \"${item.id}\" is listed in $replace but has enabled:false — it will be excluded.`,\n )\n continue\n }\n if (!item.aiIntent) {\n configLogger.warn(`Intent \"${item.id}\" is missing required \"aiIntent\".`)\n continue\n }\n result.push(\n (baseMap.has(item.id) ? { ...baseMap.get(item.id)!, ...item } : item) as IntentConfig,\n )\n }\n }\n return result\n }\n\n // Default: append / override mode.\n // - Objects with known id: merge over built-in (or remove if enabled:false)\n // - Objects with unknown id: append as new intent\n // - Strings: not meaningful in append mode (order is fixed to built-in order + appended)\n const merged = Array.from(baseMap.values())\n\n for (const item of promptsArray) {\n if (typeof item === 'string') {\n if (!baseMap.has(item)) {\n configLogger.warn(\n `Unknown built-in intent id: \"${item}\". In append mode, strings have no effect on ordering — use $replace to control order.`,\n )\n }\n // Known string ids are already in merged — nothing to do\n continue\n }\n\n if (typeof item === 'object') {\n if (!item.id) {\n configLogger.warn('Intent object missing required \"id\" field, skipping.')\n continue\n }\n if (!item.aiIntent) {\n configLogger.warn(`Intent \"${item.id}\" is missing required \"aiIntent\".`)\n continue\n }\n const existingIdx = merged.findIndex(i => i.id === item.id)\n if (existingIdx !== -1) {\n if (item.enabled === false) {\n merged.splice(existingIdx, 1)\n } else {\n merged[existingIdx] = { ...merged[existingIdx], ...item } as IntentConfig\n }\n } else {\n if (item.enabled !== false) {\n merged.push(item as IntentConfig)\n }\n }\n }\n }\n\n return merged\n}\n\nlet watchers: fs.FSWatcher[] = []\n\nexport function watchConfig(onReload: () => void, cwd = process.cwd(), gitRoot?: string): void {\n if (isWatching) return\n isWatching = true\n\n // Watch .inspecto/ directories rather than individual files so that newly\n // created files (e.g. prompts.local.json added after server start) are picked up.\n const watchDirs: string[] = [path.join(os.homedir(), '.inspecto')]\n const roots = resolveConfigRoots(cwd, gitRoot ?? cwd)\n for (const root of roots) {\n watchDirs.push(path.join(root, '.inspecto'))\n }\n\n const CONFIG_FILES = new Set([\n 'settings.json',\n 'settings.local.json',\n 'prompts.json',\n 'prompts.local.json',\n ])\n\n for (const dir of watchDirs) {\n if (!fs.existsSync(dir)) continue\n try {\n const watcher = fs.watch(dir, async (eventType, filename) => {\n if (!filename || !CONFIG_FILES.has(filename)) return\n loadedConfig = null\n loadedPrompts = null\n loadUserConfigSync(true, cwd, gitRoot)\n await loadPromptsConfig(true, cwd, gitRoot)\n onReload()\n })\n watcher.unref()\n watchers.push(watcher)\n } catch (e) {\n // ignore watch errors (e.g. unsupported fs)\n }\n }\n}\n\nexport function unwatchConfig(): void {\n for (const watcher of watchers) {\n watcher.close()\n }\n watchers = []\n isWatching = false\n}\n","import type { LogLevel } from '@inspecto-dev/types'\n\nexport interface Logger {\n info(msg: string, ...args: any[]): void\n warn(msg: string, ...args: any[]): void\n error(msg: string, ...args: any[]): void\n debug(msg: string, ...args: any[]): void\n setLevel?(level: LogLevel): void\n}\n\nconst LOG_LEVELS: Record<LogLevel, number> = {\n silent: 0,\n error: 1,\n warn: 2,\n info: 3,\n}\n\n// Very simple implementation of a DEBUG matching string.\n// Supports `DEBUG=inspecto:*` or `DEBUG=inspecto:server,inspecto:ast`\nfunction isDebugEnabled(namespace: string): boolean {\n if (typeof process === 'undefined' || !process.env) return false\n const debugEnv = process.env.DEBUG\n if (!debugEnv) return false\n\n const namespaces = debugEnv.split(',').map(s => s.trim())\n for (const ns of namespaces) {\n if (ns === '*') return true\n if (ns.endsWith('*')) {\n const prefix = ns.slice(0, -1)\n if (namespace.startsWith(prefix)) return true\n } else if (ns === namespace) {\n return true\n }\n }\n return false\n}\n\n// Store global level locally to avoid circular dependency with config.ts\nlet globalLevel: LogLevel = 'warn'\nconst registeredLoggers: Set<Logger> = new Set()\n\nexport function setLoggerGlobalLevel(level: LogLevel) {\n globalLevel = level\n for (const logger of registeredLoggers) {\n if (logger.setLevel) {\n logger.setLevel(level)\n }\n }\n}\n\nexport function createLogger(namespace: string, options?: { logLevel?: LogLevel }): Logger {\n let currentLevel = options?.logLevel ?? globalLevel\n let numericLevel = LOG_LEVELS[currentLevel] ?? 2\n const debugEnabled = isDebugEnabled(namespace)\n\n const logger: Logger = {\n setLevel(level: LogLevel) {\n currentLevel = level\n numericLevel = LOG_LEVELS[level] ?? 2\n },\n info(msg: string, ...args: any[]) {\n if (numericLevel >= LOG_LEVELS.info) {\n console.log(`\\x1b[36m[inspecto]\\x1b[0m ${msg}`, ...args)\n }\n },\n warn(msg: string, ...args: any[]) {\n if (numericLevel >= LOG_LEVELS.warn) {\n console.warn(`\\x1b[33m[inspecto] WARN:\\x1b[0m ${msg}`, ...args)\n }\n },\n error(msg: string, ...args: any[]) {\n if (numericLevel >= LOG_LEVELS.error) {\n console.error(`\\x1b[31m[inspecto] ERROR:\\x1b[0m ${msg}`, ...args)\n }\n },\n debug(msg: string, ...args: any[]) {\n if (debugEnabled) {\n console.log(`\\x1b[90m[${namespace}]\\x1b[0m ${msg}`, ...args)\n }\n },\n }\n\n registeredLoggers.add(logger)\n\n return logger\n}\n","import crypto from 'node:crypto'\nimport { execFileSync } from 'node:child_process'\nimport { launchIDE } from 'launch-ide'\nimport { createLogger } from '../utils/logger.js'\nimport { getGlobalLogLevel } from '../config.js'\n\nconst serverLogger = createLogger('inspecto:server', { logLevel: getGlobalLogLevel() })\n\nconst payloadTickets = new Map<string, string>()\n\nexport function createTicket(payload: unknown): string {\n const ticketId = crypto.randomUUID()\n payloadTickets.set(ticketId, JSON.stringify(payload))\n\n setTimeout(\n () => {\n payloadTickets.delete(ticketId)\n },\n 5 * 60 * 1000,\n )\n\n return ticketId\n}\n\nexport function readTicket(ticketId: string): string | undefined {\n return payloadTickets.get(ticketId)\n}\n\nexport function launchURI(uri: string): void {\n try {\n if (process.platform === 'darwin') {\n execFileSync('open', [uri])\n } else if (process.platform === 'win32') {\n execFileSync('cmd', ['/c', 'start', '\"\"', uri])\n } else {\n execFileSync('xdg-open', [uri])\n }\n } catch (e) {\n serverLogger.error('Failed to launch URI via execFileSync, falling back to launchIDE:', e)\n launchIDE({ file: uri })\n }\n}\n","import type {\n IdeType,\n Provider,\n ProviderMode,\n ScreenshotContext,\n ServerState,\n ToolOverrides,\n} from '@inspecto-dev/types'\nimport {\n extractToolOverrides,\n loadUserConfigSync,\n resolveProviderMode,\n resolveTargetTool,\n} from '../config.js'\nimport { createTicket, launchURI } from './dispatch-transport.js'\n\nexport interface PromptDispatchRuntime {\n resolvedTarget: Provider\n finalIde: string\n mode: ProviderMode\n overrides?: ToolOverrides\n autoSend?: boolean\n}\n\nexport interface PromptDispatchPayload {\n prompt: string\n filePath?: string\n line?: number\n column?: number\n snippet?: string\n screenshotContext?: ScreenshotContext\n}\n\nexport interface PromptDispatchResult {\n success: true\n fallbackPayload: {\n prompt: string\n file?: string\n }\n}\n\nexport function resolvePromptDispatchRuntime(\n state: Pick<ServerState, 'projectRoot' | 'cwd' | 'ideInfo'>,\n): PromptDispatchRuntime {\n const userConfig = loadUserConfigSync(false, state.cwd, state.projectRoot)\n const resolvedTarget = resolveTargetTool(userConfig)\n const finalIde = resolveFinalIde(userConfig.ide, state.ideInfo?.ide, state.ideInfo?.scheme)\n const mode = resolveProviderMode(resolvedTarget, finalIde as IdeType, userConfig)\n const overrides =\n extractToolOverrides(finalIde as IdeType, userConfig)[resolvedTarget] || undefined\n\n return {\n resolvedTarget,\n finalIde,\n mode,\n ...(hasOverrides(overrides) ? { overrides } : {}),\n ...(userConfig['prompt.autoSend'] !== undefined\n ? { autoSend: Boolean(userConfig['prompt.autoSend']) }\n : {}),\n }\n}\n\nexport function dispatchPromptThroughIde(\n runtime: PromptDispatchRuntime,\n payload: PromptDispatchPayload,\n): PromptDispatchResult {\n const ticketId = createTicket({\n ide: runtime.finalIde,\n target: runtime.resolvedTarget,\n targetType: runtime.mode,\n prompt: payload.prompt,\n filePath: payload.filePath,\n line: payload.line,\n column: payload.column,\n snippet: payload.snippet,\n ...(payload.screenshotContext ? { screenshotContext: payload.screenshotContext } : {}),\n overrides: runtime.overrides,\n autoSend: runtime.autoSend,\n })\n\n const params = new URLSearchParams()\n params.set('ticket', ticketId)\n params.set('target', runtime.resolvedTarget)\n\n launchURI(`${runtime.finalIde}://inspecto.inspecto/send?${params.toString()}`)\n\n return {\n success: true,\n fallbackPayload: {\n prompt: payload.prompt,\n ...(payload.filePath ? { file: payload.filePath } : {}),\n },\n }\n}\n\nfunction resolveFinalIde(\n configuredIde: string | undefined,\n activeIde: string | undefined,\n activeIdeScheme: string | undefined,\n): string {\n if (configuredIde && activeIdeScheme && !activeIdeScheme.includes(configuredIde)) {\n return configuredIde\n }\n\n return configuredIde || activeIdeScheme || activeIde || 'vscode'\n}\n\nfunction hasOverrides(overrides: ToolOverrides | undefined): overrides is ToolOverrides {\n return Boolean(overrides && Object.keys(overrides).length > 0)\n}\n","import path from 'node:path'\nimport fs from 'node:fs'\n\nfunction isWindowsAbsolutePath(file: string): boolean {\n return /^[a-zA-Z]:[\\\\/]/.test(file) || /^\\\\\\\\[^\\\\]+\\\\[^\\\\]+/.test(file)\n}\n\nexport function resolveWorkspacePath(file: string, cwd: string): string {\n if (isWindowsAbsolutePath(file)) {\n return path.win32.normalize(file)\n }\n return path.isAbsolute(file) ? path.resolve(file) : path.resolve(cwd, file)\n}\n\nexport function assertPathWithinProject(file: string, projectRoot: string): void {\n let realFile = file\n let realProjectRoot = projectRoot\n try {\n if (fs.existsSync(file)) {\n realFile = fs.realpathSync(file)\n }\n } catch {\n // ignore\n }\n\n try {\n if (fs.existsSync(projectRoot)) {\n realProjectRoot = fs.realpathSync(projectRoot)\n }\n } catch {\n // ignore\n }\n\n if (isWithinPath(file, projectRoot) || isWithinPath(realFile, realProjectRoot)) {\n return\n }\n\n throw new Error(\n `Access denied: File ${normalizeForComparison(realFile)} is outside of project workspace ${normalizeForComparison(realProjectRoot)}`,\n )\n}\n\nfunction tryReadPackageName(packageRoot: string): string | undefined {\n try {\n const packageJsonPath = path.join(packageRoot, 'package.json')\n if (!fs.existsSync(packageJsonPath)) return undefined\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')) as { name?: string }\n return typeof packageJson.name === 'string' ? packageJson.name : undefined\n } catch {\n return undefined\n }\n}\n\nfunction findNearestPackageRoot(file: string): string | undefined {\n let current = path.dirname(file)\n\n while (true) {\n if (fs.existsSync(path.join(current, 'package.json'))) {\n return current\n }\n const parent = path.dirname(current)\n if (parent === current) {\n return undefined\n }\n current = parent\n }\n}\n\nfunction normalizeForComparison(file: string): string {\n return isWindowsAbsolutePath(file) ? path.win32.normalize(file) : path.normalize(file)\n}\n\nfunction pathSeparatorFor(file: string): string {\n return isWindowsAbsolutePath(file) ? path.win32.sep : path.sep\n}\n\nfunction isWithinPath(file: string, root: string): boolean {\n const normalizedFile = normalizeForComparison(file)\n const normalizedRoot = normalizeForComparison(root)\n const separator = pathSeparatorFor(normalizedRoot)\n const rootWithSep = normalizedRoot.endsWith(separator)\n ? normalizedRoot\n : normalizedRoot + separator\n return normalizedFile === normalizedRoot || normalizedFile.startsWith(rootWithSep)\n}\n\nfunction resolveLinkedDependencyEntry(\n projectRoot: string,\n packageName: string,\n): string | undefined {\n const packageSegments = packageName.split('/')\n const dependencyPath = path.join(projectRoot, 'node_modules', ...packageSegments)\n if (!fs.existsSync(dependencyPath)) return undefined\n\n try {\n return fs.realpathSync(dependencyPath)\n } catch {\n return dependencyPath\n }\n}\n\nfunction isLinkedDependencyPath(file: string, projectRoot: string, packageName: string): boolean {\n const linkedDependencyRoot = resolveLinkedDependencyEntry(projectRoot, packageName)\n if (!linkedDependencyRoot) return false\n\n return isWithinPath(file, linkedDependencyRoot)\n}\n\nfunction isLinkedDependencySourcePath(file: string, projectRoot: string): boolean {\n const packageRoot = findNearestPackageRoot(file)\n if (!packageRoot) return false\n\n const packageName = tryReadPackageName(packageRoot)\n if (!packageName) return false\n\n return isLinkedDependencyPath(file, projectRoot, packageName)\n}\n\nexport function assertPathWithinIdeOpenScope(file: string, projectRoot: string): void {\n try {\n assertPathWithinProject(file, projectRoot)\n return\n } catch {\n if (isLinkedDependencySourcePath(file, projectRoot)) {\n return\n }\n throw new Error(`Access denied: File is outside of project workspace`)\n }\n}\n","import type {\n AnnotationIntent,\n AiErrorCode,\n RuntimeContextEnvelope,\n RuntimeEvidenceRecord,\n ScreenshotContext,\n SendAnnotationsToAiRequest,\n SendAnnotationsToAiResponse,\n ServerState,\n} from '@inspecto-dev/types'\nimport { dispatchPromptThroughIde, resolvePromptDispatchRuntime } from './dispatch-runtime.js'\nimport { assertPathWithinProject, resolveWorkspacePath } from './path-guards.js'\n\nexport interface NormalizedAnnotationTarget {\n file: string\n line: number\n column: number\n label?: string\n selector?: string\n snippet?: string\n}\n\nexport interface NormalizedAnnotation {\n index: number\n note: string\n intent: AnnotationIntent\n targets: NormalizedAnnotationTarget[]\n}\n\nexport interface NormalizedAnnotationBatch {\n instruction: string\n responseMode: 'unified' | 'per-annotation'\n annotations: NormalizedAnnotation[]\n runtimeContext?: RuntimeContextEnvelope\n screenshotContext?: ScreenshotContext\n cssContextPrompt?: string\n}\n\nclass AnnotationDispatchError extends Error {\n readonly errorCode: AiErrorCode\n\n constructor(message: string, errorCode: AiErrorCode) {\n super(message)\n this.name = 'AnnotationDispatchError'\n this.errorCode = errorCode\n }\n}\n\nexport async function dispatchAnnotationsToAi(\n req: SendAnnotationsToAiRequest,\n state: Pick<ServerState, 'projectRoot' | 'cwd' | 'ideInfo'>,\n): Promise<SendAnnotationsToAiResponse> {\n try {\n validateAnnotationDispatchRequest(req, state)\n const batch = normalizeAnnotationBatch(req)\n const prompt = buildAnnotationBatchPrompt(batch)\n const representativeTarget = batch.annotations[0]?.targets[0]\n const runtime = resolvePromptDispatchRuntime(state)\n\n return dispatchPromptThroughIde(runtime, {\n prompt,\n ...(representativeTarget?.file ? { filePath: representativeTarget.file } : {}),\n ...(representativeTarget?.line ? { line: representativeTarget.line } : {}),\n ...(representativeTarget?.column ? { column: representativeTarget.column } : {}),\n ...(batch.screenshotContext ? { screenshotContext: batch.screenshotContext } : {}),\n })\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n errorCode: getAnnotationDispatchErrorCode(error),\n }\n }\n}\n\nexport function validateAnnotationDispatchRequest(\n req: SendAnnotationsToAiRequest,\n state: Pick<ServerState, 'projectRoot' | 'cwd'>,\n): void {\n if (!req.annotations.length) {\n throw new AnnotationDispatchError('At least one annotation is required.', 'INVALID_REQUEST')\n }\n\n for (const annotation of req.annotations) {\n if (!annotation.targets.length) {\n throw new AnnotationDispatchError(\n 'Each annotation must include at least one target.',\n 'INVALID_REQUEST',\n )\n }\n\n for (const target of annotation.targets) {\n const absolutePath = resolveWorkspacePath(target.location.file, state.cwd)\n assertPathWithinProject(absolutePath, state.projectRoot)\n }\n }\n}\n\nexport function normalizeAnnotationBatch(\n req: SendAnnotationsToAiRequest,\n): NormalizedAnnotationBatch {\n return {\n instruction: req.instruction?.trim() ?? '',\n responseMode: req.responseMode ?? 'unified',\n ...(req.runtimeContext ? { runtimeContext: req.runtimeContext } : {}),\n ...(req.screenshotContext ? { screenshotContext: req.screenshotContext } : {}),\n ...(req.cssContextPrompt?.trim() ? { cssContextPrompt: req.cssContextPrompt.trim() } : {}),\n annotations: req.annotations.map((annotation, index) => ({\n index: index + 1,\n note: annotation.note.trim(),\n intent: annotation.intent,\n targets: annotation.targets.map(target => ({\n file: target.location.file,\n line: target.location.line,\n column: target.location.column,\n ...(target.label ? { label: target.label } : {}),\n ...(target.selector ? { selector: target.selector } : {}),\n ...(target.snippet ? { snippet: target.snippet } : {}),\n })),\n })),\n }\n}\n\nexport function buildAnnotationBatchPrompt(batch: NormalizedAnnotationBatch): string {\n const body = buildSelectedElementsPrompt(batch.annotations)\n const prompt = batch.instruction ? `${batch.instruction}\\n\\n${body}` : body\n\n return appendScreenshotContextSection(\n appendCssContextSection(\n appendRuntimeContextSection(prompt, batch.runtimeContext),\n batch.cssContextPrompt,\n ),\n batch.screenshotContext,\n )\n}\n\nfunction appendCssContextSection(prompt: string, cssContextPrompt: string | undefined): string {\n if (!cssContextPrompt) return prompt\n return `${prompt}\\n\\n${cssContextPrompt}`\n}\n\nfunction buildSelectedElementsPrompt(annotations: NormalizedAnnotation[]): string {\n const lines = ['Selected elements:']\n\n for (const annotation of annotations) {\n const trimmedNote = annotation.note.trim()\n for (const target of annotation.targets) {\n const targetLabel = (target.label || 'Unknown target').trim() || 'Unknown target'\n lines.push(`- ${targetLabel}`)\n lines.push(`file=${target.file}:${target.line}:${target.column}`)\n if (trimmedNote) {\n lines.push(`note=${trimmedNote}`)\n }\n }\n }\n\n if (lines.length === 1) {\n lines.push('- None')\n }\n\n return lines.join('\\n')\n}\n\nfunction appendScreenshotContextSection(\n prompt: string,\n screenshotContext: ScreenshotContext | undefined,\n): string {\n if (!screenshotContext || (!screenshotContext.imageDataUrl && !screenshotContext.imageAssetId)) {\n return prompt\n }\n\n const lines = [\n 'Visual screenshot context attached:',\n `- capturedAt=${screenshotContext.capturedAt}`,\n `- mimeType=${screenshotContext.mimeType}`,\n ...(screenshotContext.imageAssetId ? [`- imageAssetId=${screenshotContext.imageAssetId}`] : []),\n ]\n\n return `${prompt}\\n\\n${lines.join('\\n')}`\n}\n\nfunction appendRuntimeContextSection(\n prompt: string,\n runtimeContext: RuntimeContextEnvelope | undefined,\n): string {\n if (!runtimeContext?.records.length) {\n return prompt\n }\n\n return `${prompt}\\n\\n${buildRuntimeContextSection(runtimeContext.records)}`\n}\n\nfunction buildRuntimeContextSection(records: RuntimeEvidenceRecord[]): string {\n return ['Relevant runtime context:', ...records.map(formatRuntimeRecord)].join('\\n')\n}\n\nfunction formatRuntimeRecord(record: RuntimeEvidenceRecord): string {\n const requestSummary =\n record.kind === 'failed-request'\n ? `request=${record.request?.method ?? 'GET'} ${record.request?.pathname ?? record.request?.url ?? 'unknown'} status=${record.request?.status ?? 'unknown'}`\n : `occurrences=${record.occurrenceCount}`\n const reasonSummary = record.relevanceReasons.length\n ? record.relevanceReasons.join('; ')\n : 'timing-based'\n const stackSummary = record.stack\n ? `\\n stack=${record.stack.split('\\n').slice(0, 5).join(' | ')}`\n : ''\n\n return [\n `- [${record.kind}] ${record.message}`,\n ` relevance=${record.relevanceLevel} (${reasonSummary})`,\n ` ${requestSummary}`,\n stackSummary,\n ]\n .filter(Boolean)\n .join('\\n')\n}\n\nfunction getAnnotationDispatchErrorCode(error: unknown): AiErrorCode {\n if (error instanceof AnnotationDispatchError) return error.errorCode\n if (error instanceof Error && error.message.includes('outside of project workspace')) {\n return 'FORBIDDEN_PATH'\n }\n return 'UNKNOWN'\n}\n","import type { IdeType, InspectoConfig, ServerState } from '@inspecto-dev/types'\nimport { loadPromptsConfig, loadUserConfigSync, resolveIntents } from '../config.js'\n\nexport async function buildClientConfig(\n serverState: ServerState,\n): Promise<InspectoConfig & { autoSend: boolean }> {\n const userConfig = loadUserConfigSync(false, serverState.cwd, serverState.configRoot)\n const promptsConfig = await loadPromptsConfig(false, serverState.cwd, serverState.configRoot)\n const effectiveIde = (userConfig.ide ?? 'vscode') as IdeType\n\n let info: any\n if (!serverState.ideInfo) {\n info = { ide: effectiveIde }\n } else {\n const { scheme: _scheme, ...rest } = serverState.ideInfo as any\n info = rest\n }\n\n return {\n ...info,\n prompts: resolveIntents(promptsConfig),\n hotKeys: userConfig['inspector.hotKey'] ?? 'alt',\n theme: userConfig['inspector.theme'] ?? 'auto',\n includeSnippet: userConfig['prompt.includeSnippet'] ?? false,\n runtimeContext: {\n enabled: true,\n preview: true,\n maxRuntimeErrors: 3,\n maxFailedRequests: 2,\n },\n screenshotContext: {\n enabled: false,\n },\n annotationResponseMode: userConfig['prompt.annotationResponseMode'] ?? 'unified',\n autoSend: userConfig['prompt.autoSend'] ?? false,\n }\n}\n","import { execFileSync } from 'node:child_process'\nimport { Editor, launchIDE } from 'launch-ide'\nimport type { OpenFileRequest, ServerState } from '@inspecto-dev/types'\nimport { loadUserConfigSync } from '../config.js'\nimport { createLogger } from '../utils/logger.js'\nimport { getGlobalLogLevel } from '../config.js'\nimport { assertPathWithinIdeOpenScope, resolveWorkspacePath } from './path-guards.js'\n\nconst serverLogger = createLogger('inspecto:server', { logLevel: getGlobalLogLevel() })\n\nconst VSCODE_FAMILY_SCHEMES = [\n 'vscode',\n 'vscode-insiders',\n 'cursor',\n 'windsurf',\n 'trae',\n 'trae-cn',\n 'vscodium',\n 'codebuddy',\n 'codebuddy-cn',\n 'antigravity',\n]\n\nexport function handleOpenFileRequest(\n body: OpenFileRequest,\n serverState: ServerState,\n): { success: true } {\n const absolutePath = resolveWorkspacePath(body.file, serverState.cwd)\n\n assertPathWithinIdeOpenScope(absolutePath, serverState.projectRoot)\n\n const userConfig = loadUserConfigSync(false, serverState.cwd, serverState.configRoot)\n const configuredIde = userConfig.ide\n const activeIde = serverState.ideInfo?.ide\n const activeIdeScheme = serverState.ideInfo?.scheme\n\n const rawEditorHint = configuredIde || activeIde || activeIdeScheme || 'code'\n\n if (configuredIde && activeIdeScheme && !activeIdeScheme.includes(configuredIde)) {\n serverLogger.warn(\n `Active IDE is ${activeIdeScheme}, but config forces ${configuredIde}. Using configured IDE.`,\n )\n }\n\n let editorHint = rawEditorHint\n if (rawEditorHint === 'vscode') editorHint = 'code'\n else if (rawEditorHint === 'vscode-insiders') editorHint = 'code-insiders'\n else if (rawEditorHint === 'vscodium') editorHint = 'codium'\n else if (rawEditorHint === 'trae-cn' || rawEditorHint === 'trae') editorHint = 'trae'\n\n serverLogger.debug(\n `IDE_OPEN: activeIde=${activeIde}, activeIdeScheme=${activeIdeScheme}, configuredIde=${configuredIde} -> rawEditorHint=${rawEditorHint}, finalEditorHint=${editorHint}`,\n )\n\n if (VSCODE_FAMILY_SCHEMES.includes(rawEditorHint)) {\n let normalizedPath = absolutePath.replace(/\\\\/g, '/')\n if (!normalizedPath.startsWith('/')) {\n normalizedPath = '/' + normalizedPath\n }\n const encodedPath = encodeURI(normalizedPath)\n const uri = `${rawEditorHint}://file${encodedPath}:${body.line}:${body.column}`\n serverLogger.debug(`IDE_OPEN: Bypassing launchIDE, using URI scheme directly: ${uri}`)\n\n try {\n if (process.platform === 'darwin') {\n execFileSync('open', [uri])\n } else if (process.platform === 'win32') {\n execFileSync('cmd', ['/c', 'start', '\"\"', uri])\n } else {\n execFileSync('xdg-open', [uri])\n }\n } catch (e) {\n serverLogger.error(`Failed to launch URI for IDE_OPEN (${uri}):`, e)\n launchIDE({\n file: absolutePath,\n line: body.line,\n column: body.column,\n editor: editorHint as Editor,\n type: process.platform === 'darwin' ? 'open' : 'exec',\n })\n }\n } else {\n launchIDE({\n file: absolutePath,\n line: body.line,\n column: body.column,\n editor: editorHint as Editor,\n type: process.platform === 'darwin' ? 'open' : 'exec',\n })\n }\n\n return { success: true }\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport { execSync } from 'node:child_process'\nimport { createLogger } from '../utils/logger.js'\nimport { getGlobalLogLevel } from '../config.js'\n\nconst serverLogger = createLogger('inspecto:server', { logLevel: getGlobalLogLevel() })\n\nexport function resolveProjectRoot(): string {\n const cwd = process.cwd()\n let gitRoot: string\n try {\n gitRoot = execSync('git rev-parse --show-toplevel', { encoding: 'utf-8' }).trim()\n } catch (e) {\n serverLogger.warn('Failed to resolve git root via git rev-parse:', e)\n gitRoot = cwd\n }\n\n const visited = new Set<string>()\n const search = (start: string, stop: string) => {\n let current = start\n while (!visited.has(current)) {\n visited.add(current)\n if (fs.existsSync(path.join(current, '.inspecto'))) return current\n if (current === stop) break\n const parent = path.dirname(current)\n if (parent === current) break\n current = parent\n }\n return null\n }\n\n const cwdMatch = search(cwd, path.parse(cwd).root)\n if (cwdMatch) return cwdMatch\n\n const repoMatch = search(gitRoot, path.parse(gitRoot).root)\n if (repoMatch) return repoMatch\n\n return gitRoot\n}\n","import { createRequire } from 'node:module'\n\n// Safely resolve the client module without breaking ESM/CJS or bundling\nexport const resolveClientModule = () => {\n try {\n return createRequire(import.meta.url).resolve('@inspecto-dev/core')\n } catch {\n try {\n return require.resolve('@inspecto-dev/core')\n } catch {\n console.warn(\n '[inspecto] Could not resolve @inspecto-dev/core — falling back to bare specifier',\n )\n return '@inspecto-dev/core'\n }\n }\n}\n","export function getWebpackHtmlScript(serverPort: number) {\n return `\nwindow.__AI_INSPECTOR_PORT__ = ${serverPort};\nwindow.addEventListener('load', () => {\n if (window.InspectoClient) {\n window.InspectoClient.mountInspector({\n serverUrl: 'http://127.0.0.1:' + window.__AI_INSPECTOR_PORT__,\n });\n }\n});\n`\n}\n\nexport function getWebpackAssetScript(serverPort: number) {\n return `\nif (typeof window !== 'undefined') {\n window.__AI_INSPECTOR_PORT__ = ${serverPort};\n const _initInspecto = () => {\n if (window.InspectoClient) {\n window.InspectoClient.mountInspector({\n serverUrl: 'http://127.0.0.1:' + window.__AI_INSPECTOR_PORT__,\n });\n } else {\n setTimeout(_initInspecto, 100);\n }\n };\n if (document.readyState === 'complete') {\n _initInspecto();\n } else {\n window.addEventListener('load', _initInspecto);\n }\n}\n`\n}\n\nexport function injectWebpack(\n compiler: any,\n serverPortFn: () => Promise<number>,\n resolveClientModule: () => string,\n) {\n const inspectoClientPath = resolveClientModule()\n\n // Inject the client logic directly using the absolute path\n if (compiler.webpack && compiler.webpack.EntryPlugin) {\n // Webpack 5+\n new compiler.webpack.EntryPlugin(compiler.context, inspectoClientPath, {\n name: undefined,\n }).apply(compiler)\n }\n\n compiler.hooks.compilation.tap('inspecto-overlay', (compilation: any) => {\n // Find HtmlWebpackPlugin (standard Webpack)\n const HtmlWebpackPlugin = compiler.options.plugins.find(\n (p: any) => p && p.constructor && p.constructor.name === 'HtmlWebpackPlugin',\n )\n if (HtmlWebpackPlugin) {\n const hooks = (HtmlWebpackPlugin.constructor as any).getHooks(compilation)\n hooks.alterAssetTagGroups.tapPromise('inspecto-overlay', async (data: any) => {\n const port = await serverPortFn()\n data.headTags.unshift({\n tagName: 'script',\n voidTag: false,\n meta: { plugin: 'inspecto-overlay' },\n innerHTML: getWebpackHtmlScript(port),\n })\n return data\n })\n } else {\n // Fallback for frameworks like Next.js that don't use HtmlWebpackPlugin\n if (compilation.hooks.processAssets) {\n // Webpack 5+\n compilation.hooks.processAssets.tapPromise(\n {\n name: 'inspecto-overlay',\n stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONS,\n },\n async (assets: any) => {\n const port = await serverPortFn()\n\n // Only inject into the main client entry chunks (e.g. main-app, main.js, umi.js)\n const mainAssetKey = Object.keys(assets).find(\n key =>\n key.endsWith('.js') &&\n (key.includes('main') || key.includes('app') || key.includes('umi')),\n )\n if (!mainAssetKey) return\n\n const originalSource = assets[mainAssetKey].source()\n assets[mainAssetKey] = new compiler.webpack.sources.RawSource(\n getWebpackAssetScript(port) + '\\n' + originalSource,\n )\n },\n )\n }\n }\n })\n}\n","import { getWebpackHtmlScript } from './webpack.js'\n\nexport function injectRspack(\n compiler: any,\n serverPortFn: () => Promise<number>,\n resolveClientModule: () => string,\n) {\n const inspectoClientPath = resolveClientModule()\n\n // Use the exact same entry injection strategy as Webpack\n new compiler.webpack.EntryPlugin(compiler.context, inspectoClientPath, {}).apply(compiler)\n\n compiler.hooks.compilation.tap('inspecto-overlay', (compilation: any) => {\n const HtmlRspackPlugin = compiler.options.plugins.find(\n (p: any) => p && p.constructor && p.constructor.name === 'HtmlRspackPlugin',\n )\n if (HtmlRspackPlugin) {\n const hooks = (HtmlRspackPlugin.constructor as any).getHooks(compilation)\n hooks.alterAssetTagGroups.tapPromise('inspecto-overlay', async (data: any) => {\n const port = await serverPortFn()\n\n data.headTags.unshift({\n tagName: 'script',\n voidTag: false,\n meta: { plugin: 'inspecto-overlay' },\n innerHTML: getWebpackHtmlScript(port),\n })\n return data\n })\n }\n })\n}\n","export function getViteVirtualModuleScript(serverPort: number) {\n return `\nimport { mountInspector } from '@inspecto-dev/core';\nwindow.__AI_INSPECTOR_PORT__ = ${serverPort};\nmountInspector({\n serverUrl: 'http://127.0.0.1:' + window.__AI_INSPECTOR_PORT__,\n});\n`\n}\n\nexport const VITE_VIRTUAL_MODULE_ID = '\\0virtual:inspecto-client'\nexport const VITE_VIRTUAL_IMPORT_ID = '/@id/__x00__virtual:inspecto-client'\n"],"mappings":"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","names":["path","MagicString","path","path","MagicString","path","fs","path","os","crypto","path","parser","traverse_","traverse","fs","path","path","fs","path","fs","serverState","execFileSync","launchIDE","serverLogger","serverState","execFileSync","launchIDE","fs","path","serverLogger","fs","path","serverLogger","resolve","path","os","fs","crypto","resolve","path","serverLogger","resolveClientModule","resolveClientModule"]}