@inspecto-dev/plugin 0.2.0-alpha.0 → 0.2.0-alpha.1
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.
- package/dist/index.cjs +3 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/legacy/rspack/index.cjs +3 -1
- package/dist/legacy/rspack/index.cjs.map +1 -1
- package/dist/legacy/rspack/index.js +3 -1
- package/dist/legacy/rspack/index.js.map +1 -1
- package/dist/rollup.cjs +3 -1
- package/dist/rollup.cjs.map +1 -1
- package/dist/rollup.js +3 -1
- package/dist/rollup.js.map +1 -1
- package/dist/rspack.cjs +3 -1
- package/dist/rspack.cjs.map +1 -1
- package/dist/rspack.js +3 -1
- package/dist/rspack.js.map +1 -1
- package/dist/vite.cjs +3 -1
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.js +3 -1
- package/dist/vite.js.map +1 -1
- package/dist/webpack.cjs +3 -1
- package/dist/webpack.cjs.map +1 -1
- package/dist/webpack.js +3 -1
- package/dist/webpack.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -844,7 +844,9 @@ var resolveClientModule = () => {
|
|
|
844
844
|
try {
|
|
845
845
|
return require.resolve("@inspecto-dev/core");
|
|
846
846
|
} catch {
|
|
847
|
-
console.warn(
|
|
847
|
+
console.warn(
|
|
848
|
+
"[inspecto] Could not resolve @inspecto-dev/core \u2014 falling back to bare specifier"
|
|
849
|
+
);
|
|
848
850
|
return "@inspecto-dev/core";
|
|
849
851
|
}
|
|
850
852
|
}
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_typescript@5.9.3_yaml@2.8.3/node_modules/tsup/assets/cjs_shims.js","../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/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 {\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}\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 // 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(console.error)\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 = InspectoPlugin.webpack\nexport const rspackPlugin = InspectoPlugin.rspack\nexport const rollupPlugin = InspectoPlugin.rollup\nexport const esbuildPlugin = InspectoPlugin.esbuild\nexport { transformJsx }\nexport default InspectoPlugin\n","// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\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 // 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 // @vue/compiler-dom uses 1-based line, 0-based column\n const attrValue = formatAttrValue(normalizedPath, line, column + 1)\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 { execSync, execFileSync } from 'node:child_process'\nimport portfinder from 'portfinder'\nimport { launchIDE } from 'launch-ide'\nimport type {\n ServerState,\n OpenFileRequest,\n SendToAiRequest,\n SendToAiResponse,\n IdeType,\n AiTool,\n} from '@inspecto-dev/types'\nimport { extractSnippet } from './snippet.js'\nimport {\n loadUserConfigSync,\n loadPromptsConfig,\n resolveToolMode,\n extractToolOverrides,\n watchConfig,\n unwatchConfig,\n resolveTargetTool,\n} from '../config.js'\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\n// Remove unused detectTraeScheme function\n\nfunction resolveProjectRoot(): string {\n let gitRoot: string\n try {\n gitRoot = execSync('git rev-parse --show-toplevel', { encoding: 'utf-8' }).trim()\n } catch {\n gitRoot = process.cwd()\n }\n\n // Walk upward from gitRoot looking for the nearest ancestor that contains .inspecto/.\n // This handles nested-git-repo playgrounds (e.g. playground/nextjs has its own .git\n // but the real config lives in the monorepo root two levels up).\n let current = gitRoot\n while (true) {\n if (fs.existsSync(path.join(current, '.inspecto'))) return current\n const parent = path.dirname(current)\n if (parent === current) break\n current = parent\n }\n\n // No .inspecto/ found anywhere — fall back to the git root (or cwd)\n return gitRoot\n}\n\n// Function to safely launch a URI to avoid launch-ide swallow bugs on macOS\nfunction 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 console.error('[inspecto] Failed to launch URI via execFileSync, falling back to launchIDE:', e)\n launchIDE({ file: uri })\n }\n}\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 console.log('[inspecto] 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 console.error('[inspecto] 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 console.error('[inspecto] 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')\n try {\n fs.writeFileSync(portFile, String(port), 'utf-8')\n } catch {\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 fs.unlinkSync(portFile)\n } catch {\n /* ignore */\n }\n })\n\n console.log(`[inspecto] 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\nasync function handleRequest(\n url: URL,\n req: http.IncomingMessage,\n res: http.ServerResponse,\n): Promise<void> {\n const pathname = url.pathname\n\n if (pathname === '/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 if (pathname === '/config' && req.method === 'GET') {\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 // Extension hasn't registered yet — derive available targets from user config\n const fallbackTargets = userConfig.providers\n ? (Object.keys(userConfig.providers) as AiTool[])\n : ['claude-code', 'gemini', 'coco', 'codex']\n\n info = {\n ide: effectiveIde,\n providers: fallbackTargets.reduce(\n (acc, target) => {\n acc[target] = {\n mode: resolveToolMode(target as AiTool, effectiveIde, userConfig),\n installed: false,\n }\n return acc\n },\n {} as Record<string, { mode: string; installed: boolean }>,\n ),\n }\n } else {\n const { scheme: _scheme, ...rest } = serverState.ideInfo as any\n info = rest\n }\n\n // Ensure provider modes are correct even if provided by IDE\n const resolvedProviders = { ...info.providers }\n for (const tool in resolvedProviders) {\n resolvedProviders[tool].mode = resolveToolMode(tool as AiTool, info.ide, userConfig)\n }\n\n const config = {\n ...info,\n providers: resolvedProviders,\n providerOverrides: extractToolOverrides(info.ide, userConfig),\n prompts: promptsConfig,\n hotKeys: userConfig.hotKeys,\n includeSnippet: userConfig.includeSnippet,\n }\n\n res.writeHead(200, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify(config))\n return\n }\n\n if (pathname === '/config' && req.method === 'POST') {\n try {\n const body = JSON.parse(await readBody(req))\n serverState.ideInfo = body\n console.log(`[inspecto] Received IDE info from extension:`, body)\n res.writeHead(200, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ success: true }))\n } catch (e) {\n console.error('[inspecto] Error parsing /config 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 === '/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 const absolutePath = path.isAbsolute(body.file)\n ? body.file\n : path.resolve(serverState.cwd, body.file)\n\n const userConfig = loadUserConfigSync(false, serverState.cwd, serverState.configRoot)\n const ide = (userConfig.ide ?? 'vscode') as IdeType\n const editorHint = 'code'\n launchIDE({\n file: absolutePath,\n line: body.line,\n column: body.column,\n editor: editorHint,\n type: process.platform === 'darwin' ? 'open' : 'exec',\n })\n\n res.writeHead(200, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ success: true }))\n return\n }\n\n if (pathname === '/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 = path.isAbsolute(file) ? file : path.resolve(serverState.cwd, file)\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 === '/send-to-ai' && 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 console.error('[inspecto] Error parsing /send-to-ai 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 res.writeHead(404, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ error: 'not found' }))\n}\n\nasync function dispatchToAi(req: SendToAiRequest): Promise<SendToAiResponse> {\n const { location, snippet, prompt } = req\n\n const userConfig = loadUserConfigSync(false, serverState.cwd, serverState.configRoot)\n // userConfig.ide allows the user to declare their IDE explicitly in settings.\n // It takes priority over the runtime-detected IDE so that a dev server started\n // from VS Code can still dispatch to Trae/Cursor when the user says so.\n const ide = (userConfig.ide ?? 'vscode') as IdeType\n\n // Resolve preferred target based on phase-target-mode-unification.md strategy\n const resolvedTarget = resolveTargetTool(userConfig)\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\n const params = new URLSearchParams()\n params.set('target', resolvedTarget)\n\n const overrides = extractToolOverrides(ide, userConfig)[resolvedTarget]\n if (overrides) {\n params.set('overrides', JSON.stringify(overrides))\n }\n\n params.set('prompt', formattedPrompt)\n params.set('file', location.file)\n params.set('line', String(location.line))\n params.set('col', String(location.column))\n params.set('snippet', snippet)\n\n // Use the exact scheme reported by the extension if available\n const scheme = serverState.ideInfo?.scheme || 'vscode'\n\n const uri = `${scheme}://inspecto.inspecto/send?${params.toString()}`\n\n console.log(`[inspecto] dispatchToAi: Generated URI: ${uri}`)\n\n launchURI(uri)\n return { success: true }\n}\n","import * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport * as parser from '@babel/parser'\n// @ts-expect-error ignore - Default export issue with some bundlers\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 AiTool,\n ToolMode,\n ToolOverrides,\n IdeType,\n} from '@inspecto-dev/types'\nimport { DEFAULT_TOOL_MODE, VALID_MODES } from '@inspecto-dev/types'\n\nlet loadedConfig: InspectoSettings | null = null\nlet loadedPrompts: InspectoPromptsConfig | null = null\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\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({ providers: {} })\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 console.warn(`[inspecto] Failed to parse config at ${filePath}: Invalid JSON`)\n } else {\n console.warn(`[inspecto] 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): AiTool {\n if (config.prefer) {\n return config.prefer as AiTool\n }\n if (config.providers && Object.keys(config.providers).length > 0) {\n return Object.keys(config.providers)[0] as AiTool\n }\n return 'github-copilot'\n}\n\n/**\n * Resolve the effective mode/type for a tool in the context of an IDE.\n */\nexport function resolveToolMode(tool: AiTool, ide: IdeType, config: InspectoSettings): ToolMode {\n let requestedType: ToolMode | undefined = undefined\n\n // Check providers config\n if (config.providers && config.providers[tool] && config.providers[tool].type) {\n const type = config.providers[tool].type\n if (type === 'plugin' || type === 'cli') {\n requestedType = type\n }\n }\n\n requestedType = requestedType ?? DEFAULT_TOOL_MODE[tool]\n const valid = VALID_MODES[tool] || [DEFAULT_TOOL_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<AiTool, ToolOverrides>> {\n const result: Partial<Record<AiTool, ToolOverrides>> = {}\n\n if (!config.providers) return result\n\n for (const [tool, cfg] of Object.entries(config.providers)) {\n if (!cfg) continue\n\n const overrides: ToolOverrides = {\n type: cfg.type || DEFAULT_TOOL_MODE[tool as AiTool] || 'plugin',\n }\n if (cfg.bin) overrides.binaryPath = cfg.bin\n if (cfg.args) overrides.args = cfg.args\n if (cfg.cwd) overrides.cwd = cfg.cwd\n if (cfg.autoSend !== undefined) overrides.autoSend = cfg.autoSend\n\n result[tool as AiTool] = overrides\n }\n\n return result\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 { 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 // @ts-expect-error ignore\n return require.resolve('@inspecto-dev/core')\n } catch {\n console.warn('[inspecto] Could not resolve @inspecto-dev/core — falling back to bare specifier')\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 new compiler.webpack.EntryPlugin(compiler.context, inspectoClientPath, { name: undefined }).apply(\n 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":["import_node_path","traverse_","path","MagicString","import_magic_string","import_node_path","path","parseSFC","MagicString","path","import_node_fs","import_node_path","import_node_os","path","parser","import_traverse","traverse","traverse_","import_node_path","path","fs","os","fs","path","portfinder","http","resolve","os","resolve","path","resolveClientModule","resolveClientModule"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_typescript@5.9.3_yaml@2.8.3/node_modules/tsup/assets/cjs_shims.js","../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/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 {\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}\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 // 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(console.error)\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 = InspectoPlugin.webpack\nexport const rspackPlugin = InspectoPlugin.rspack\nexport const rollupPlugin = InspectoPlugin.rollup\nexport const esbuildPlugin = InspectoPlugin.esbuild\nexport { transformJsx }\nexport default InspectoPlugin\n","// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\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 // 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 // @vue/compiler-dom uses 1-based line, 0-based column\n const attrValue = formatAttrValue(normalizedPath, line, column + 1)\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 { execSync, execFileSync } from 'node:child_process'\nimport portfinder from 'portfinder'\nimport { launchIDE } from 'launch-ide'\nimport type {\n ServerState,\n OpenFileRequest,\n SendToAiRequest,\n SendToAiResponse,\n IdeType,\n AiTool,\n} from '@inspecto-dev/types'\nimport { extractSnippet } from './snippet.js'\nimport {\n loadUserConfigSync,\n loadPromptsConfig,\n resolveToolMode,\n extractToolOverrides,\n watchConfig,\n unwatchConfig,\n resolveTargetTool,\n} from '../config.js'\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\n// Remove unused detectTraeScheme function\n\nfunction resolveProjectRoot(): string {\n let gitRoot: string\n try {\n gitRoot = execSync('git rev-parse --show-toplevel', { encoding: 'utf-8' }).trim()\n } catch {\n gitRoot = process.cwd()\n }\n\n // Walk upward from gitRoot looking for the nearest ancestor that contains .inspecto/.\n // This handles nested-git-repo playgrounds (e.g. playground/nextjs has its own .git\n // but the real config lives in the monorepo root two levels up).\n let current = gitRoot\n while (true) {\n if (fs.existsSync(path.join(current, '.inspecto'))) return current\n const parent = path.dirname(current)\n if (parent === current) break\n current = parent\n }\n\n // No .inspecto/ found anywhere — fall back to the git root (or cwd)\n return gitRoot\n}\n\n// Function to safely launch a URI to avoid launch-ide swallow bugs on macOS\nfunction 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 console.error('[inspecto] Failed to launch URI via execFileSync, falling back to launchIDE:', e)\n launchIDE({ file: uri })\n }\n}\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 console.log('[inspecto] 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 console.error('[inspecto] 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 console.error('[inspecto] 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')\n try {\n fs.writeFileSync(portFile, String(port), 'utf-8')\n } catch {\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 fs.unlinkSync(portFile)\n } catch {\n /* ignore */\n }\n })\n\n console.log(`[inspecto] 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\nasync function handleRequest(\n url: URL,\n req: http.IncomingMessage,\n res: http.ServerResponse,\n): Promise<void> {\n const pathname = url.pathname\n\n if (pathname === '/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 if (pathname === '/config' && req.method === 'GET') {\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 // Extension hasn't registered yet — derive available targets from user config\n const fallbackTargets = userConfig.providers\n ? (Object.keys(userConfig.providers) as AiTool[])\n : ['claude-code', 'gemini', 'coco', 'codex']\n\n info = {\n ide: effectiveIde,\n providers: fallbackTargets.reduce(\n (acc, target) => {\n acc[target] = {\n mode: resolveToolMode(target as AiTool, effectiveIde, userConfig),\n installed: false,\n }\n return acc\n },\n {} as Record<string, { mode: string; installed: boolean }>,\n ),\n }\n } else {\n const { scheme: _scheme, ...rest } = serverState.ideInfo as any\n info = rest\n }\n\n // Ensure provider modes are correct even if provided by IDE\n const resolvedProviders = { ...info.providers }\n for (const tool in resolvedProviders) {\n resolvedProviders[tool].mode = resolveToolMode(tool as AiTool, info.ide, userConfig)\n }\n\n const config = {\n ...info,\n providers: resolvedProviders,\n providerOverrides: extractToolOverrides(info.ide, userConfig),\n prompts: promptsConfig,\n hotKeys: userConfig.hotKeys,\n includeSnippet: userConfig.includeSnippet,\n }\n\n res.writeHead(200, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify(config))\n return\n }\n\n if (pathname === '/config' && req.method === 'POST') {\n try {\n const body = JSON.parse(await readBody(req))\n serverState.ideInfo = body\n console.log(`[inspecto] Received IDE info from extension:`, body)\n res.writeHead(200, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ success: true }))\n } catch (e) {\n console.error('[inspecto] Error parsing /config 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 === '/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 const absolutePath = path.isAbsolute(body.file)\n ? body.file\n : path.resolve(serverState.cwd, body.file)\n\n const userConfig = loadUserConfigSync(false, serverState.cwd, serverState.configRoot)\n const ide = (userConfig.ide ?? 'vscode') as IdeType\n const editorHint = 'code'\n launchIDE({\n file: absolutePath,\n line: body.line,\n column: body.column,\n editor: editorHint,\n type: process.platform === 'darwin' ? 'open' : 'exec',\n })\n\n res.writeHead(200, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ success: true }))\n return\n }\n\n if (pathname === '/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 = path.isAbsolute(file) ? file : path.resolve(serverState.cwd, file)\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 === '/send-to-ai' && 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 console.error('[inspecto] Error parsing /send-to-ai 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 res.writeHead(404, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ error: 'not found' }))\n}\n\nasync function dispatchToAi(req: SendToAiRequest): Promise<SendToAiResponse> {\n const { location, snippet, prompt } = req\n\n const userConfig = loadUserConfigSync(false, serverState.cwd, serverState.configRoot)\n // userConfig.ide allows the user to declare their IDE explicitly in settings.\n // It takes priority over the runtime-detected IDE so that a dev server started\n // from VS Code can still dispatch to Trae/Cursor when the user says so.\n const ide = (userConfig.ide ?? 'vscode') as IdeType\n\n // Resolve preferred target based on phase-target-mode-unification.md strategy\n const resolvedTarget = resolveTargetTool(userConfig)\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\n const params = new URLSearchParams()\n params.set('target', resolvedTarget)\n\n const overrides = extractToolOverrides(ide, userConfig)[resolvedTarget]\n if (overrides) {\n params.set('overrides', JSON.stringify(overrides))\n }\n\n params.set('prompt', formattedPrompt)\n params.set('file', location.file)\n params.set('line', String(location.line))\n params.set('col', String(location.column))\n params.set('snippet', snippet)\n\n // Use the exact scheme reported by the extension if available\n const scheme = serverState.ideInfo?.scheme || 'vscode'\n\n const uri = `${scheme}://inspecto.inspecto/send?${params.toString()}`\n\n console.log(`[inspecto] dispatchToAi: Generated URI: ${uri}`)\n\n launchURI(uri)\n return { success: true }\n}\n","import * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport * as parser from '@babel/parser'\n// @ts-expect-error ignore - Default export issue with some bundlers\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 AiTool,\n ToolMode,\n ToolOverrides,\n IdeType,\n} from '@inspecto-dev/types'\nimport { DEFAULT_TOOL_MODE, VALID_MODES } from '@inspecto-dev/types'\n\nlet loadedConfig: InspectoSettings | null = null\nlet loadedPrompts: InspectoPromptsConfig | null = null\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\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({ providers: {} })\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 console.warn(`[inspecto] Failed to parse config at ${filePath}: Invalid JSON`)\n } else {\n console.warn(`[inspecto] 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): AiTool {\n if (config.prefer) {\n return config.prefer as AiTool\n }\n if (config.providers && Object.keys(config.providers).length > 0) {\n return Object.keys(config.providers)[0] as AiTool\n }\n return 'github-copilot'\n}\n\n/**\n * Resolve the effective mode/type for a tool in the context of an IDE.\n */\nexport function resolveToolMode(tool: AiTool, ide: IdeType, config: InspectoSettings): ToolMode {\n let requestedType: ToolMode | undefined = undefined\n\n // Check providers config\n if (config.providers && config.providers[tool] && config.providers[tool].type) {\n const type = config.providers[tool].type\n if (type === 'plugin' || type === 'cli') {\n requestedType = type\n }\n }\n\n requestedType = requestedType ?? DEFAULT_TOOL_MODE[tool]\n const valid = VALID_MODES[tool] || [DEFAULT_TOOL_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<AiTool, ToolOverrides>> {\n const result: Partial<Record<AiTool, ToolOverrides>> = {}\n\n if (!config.providers) return result\n\n for (const [tool, cfg] of Object.entries(config.providers)) {\n if (!cfg) continue\n\n const overrides: ToolOverrides = {\n type: cfg.type || DEFAULT_TOOL_MODE[tool as AiTool] || 'plugin',\n }\n if (cfg.bin) overrides.binaryPath = cfg.bin\n if (cfg.args) overrides.args = cfg.args\n if (cfg.cwd) overrides.cwd = cfg.cwd\n if (cfg.autoSend !== undefined) overrides.autoSend = cfg.autoSend\n\n result[tool as AiTool] = overrides\n }\n\n return result\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 { 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 // @ts-expect-error ignore\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 new compiler.webpack.EntryPlugin(compiler.context, inspectoClientPath, { name: undefined }).apply(\n 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":["import_node_path","traverse_","path","MagicString","import_magic_string","import_node_path","path","parseSFC","MagicString","path","import_node_fs","import_node_path","import_node_os","path","parser","import_traverse","traverse","traverse_","import_node_path","path","fs","os","fs","path","portfinder","http","resolve","os","resolve","path","resolveClientModule","resolveClientModule"]}
|
package/dist/index.js
CHANGED
|
@@ -804,7 +804,9 @@ var resolveClientModule = () => {
|
|
|
804
804
|
try {
|
|
805
805
|
return __require.resolve("@inspecto-dev/core");
|
|
806
806
|
} catch {
|
|
807
|
-
console.warn(
|
|
807
|
+
console.warn(
|
|
808
|
+
"[inspecto] Could not resolve @inspecto-dev/core \u2014 falling back to bare specifier"
|
|
809
|
+
);
|
|
808
810
|
return "@inspecto-dev/core";
|
|
809
811
|
}
|
|
810
812
|
}
|