@inspecto-dev/plugin 0.3.7 → 0.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/README.md +2 -1
  2. package/dist/astro.cjs +2687 -0
  3. package/dist/astro.cjs.map +1 -0
  4. package/dist/astro.d.cts +17 -0
  5. package/dist/astro.d.ts +17 -0
  6. package/dist/astro.js +2656 -0
  7. package/dist/astro.js.map +1 -0
  8. package/dist/index.cjs +932 -87
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.d.cts +22 -1
  11. package/dist/index.d.ts +22 -1
  12. package/dist/index.js +930 -87
  13. package/dist/index.js.map +1 -1
  14. package/dist/legacy/rspack/index.cjs +530 -89
  15. package/dist/legacy/rspack/index.cjs.map +1 -1
  16. package/dist/legacy/rspack/index.js +530 -89
  17. package/dist/legacy/rspack/index.js.map +1 -1
  18. package/dist/legacy/rspack/loader.cjs +407 -3
  19. package/dist/legacy/rspack/loader.cjs.map +1 -1
  20. package/dist/legacy/rspack/loader.js +403 -3
  21. package/dist/legacy/rspack/loader.js.map +1 -1
  22. package/dist/legacy/webpack4/index.cjs +519 -78
  23. package/dist/legacy/webpack4/index.cjs.map +1 -1
  24. package/dist/legacy/webpack4/index.js +519 -78
  25. package/dist/legacy/webpack4/index.js.map +1 -1
  26. package/dist/legacy/webpack4/loader.cjs +407 -3
  27. package/dist/legacy/webpack4/loader.cjs.map +1 -1
  28. package/dist/legacy/webpack4/loader.js +403 -3
  29. package/dist/legacy/webpack4/loader.js.map +1 -1
  30. package/dist/rollup.cjs +932 -87
  31. package/dist/rollup.cjs.map +1 -1
  32. package/dist/rollup.d.cts +1 -1
  33. package/dist/rollup.d.ts +1 -1
  34. package/dist/rollup.js +930 -87
  35. package/dist/rollup.js.map +1 -1
  36. package/dist/rspack.cjs +932 -87
  37. package/dist/rspack.cjs.map +1 -1
  38. package/dist/rspack.d.cts +1 -1
  39. package/dist/rspack.d.ts +1 -1
  40. package/dist/rspack.js +930 -87
  41. package/dist/rspack.js.map +1 -1
  42. package/dist/vite.cjs +932 -87
  43. package/dist/vite.cjs.map +1 -1
  44. package/dist/vite.d.cts +1 -1
  45. package/dist/vite.d.ts +1 -1
  46. package/dist/vite.js +930 -87
  47. package/dist/vite.js.map +1 -1
  48. package/dist/webpack.cjs +932 -87
  49. package/dist/webpack.cjs.map +1 -1
  50. package/dist/webpack.d.cts +1 -1
  51. package/dist/webpack.d.ts +1 -1
  52. package/dist/webpack.js +930 -87
  53. package/dist/webpack.js.map +1 -1
  54. package/package.json +13 -10
package/dist/webpack.cjs CHANGED
@@ -34,14 +34,16 @@ __export(src_exports, {
34
34
  esbuildPlugin: () => esbuildPlugin,
35
35
  rollupPlugin: () => rollupPlugin,
36
36
  rspackPlugin: () => rspackPlugin,
37
+ transformAstro: () => transformAstro,
37
38
  transformJsx: () => transformJsx,
39
+ transformRouter: () => transformRouter,
38
40
  unplugin: () => unplugin,
39
41
  vitePlugin: () => vitePlugin,
40
42
  webpackPlugin: () => webpackPlugin
41
43
  });
42
44
  module.exports = __toCommonJS(src_exports);
43
45
 
44
- // ../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.9_typescript@5.9.3_yaml@2.8.3/node_modules/tsup/assets/cjs_shims.js
46
+ // ../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.10_typescript@5.9.3_yaml@2.8.3/node_modules/tsup/assets/cjs_shims.js
45
47
  var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.tagName.toUpperCase() === "SCRIPT" ? document.currentScript.src : new URL("main.js", document.baseURI).href;
46
48
  var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
47
49
 
@@ -120,14 +122,14 @@ function extractTransformFilePath(requestId) {
120
122
  wrapped: filePath !== requestId
121
123
  };
122
124
  }
123
- function shouldTransform(filePath, options) {
125
+ function shouldTransform(filePath, _options) {
124
126
  const resolvedFilePath = extractTransformFilePath(filePath).filePath;
125
127
  if (process.env["NODE_ENV"] === "production") return false;
126
128
  if (resolvedFilePath.includes("node_modules")) return false;
127
129
  if (resolvedFilePath.startsWith("\0")) return false;
128
130
  if (/[/\\](dist|build|\.next|\.nuxt)[/\\]/.test(resolvedFilePath)) return false;
129
131
  const ext = resolvedFilePath.split(".").pop()?.toLowerCase();
130
- if (ext && !["js", "jsx", "ts", "tsx", "mjs", "mts", "vue"].includes(ext)) {
132
+ if (ext && !["js", "jsx", "ts", "tsx", "mjs", "mts", "vue", "svelte", "astro"].includes(ext)) {
131
133
  return false;
132
134
  }
133
135
  return true;
@@ -288,7 +290,7 @@ function transformVue(options) {
288
290
  if (escapeTagsSet.has(tagName)) return;
289
291
  if (tagName === "template" && node === ast.children[0]) return;
290
292
  const alreadyHasAttr = node.props.some(
291
- (p) => p.type === import_compiler_core.NodeTypes.ATTRIBUTE && p.name === attributeName
293
+ (p2) => p2.type === import_compiler_core.NodeTypes.ATTRIBUTE && p2.name === attributeName
292
294
  );
293
295
  if (alreadyHasAttr) return;
294
296
  const loc = node.loc;
@@ -325,6 +327,387 @@ function walkElement(node, visitor) {
325
327
  }
326
328
  }
327
329
 
330
+ // src/transform/transform-svelte.ts
331
+ var import_magic_string3 = __toESM(require("magic-string"), 1);
332
+ var import_compiler = require("svelte/compiler");
333
+ function walk(node, visitor) {
334
+ if (!node || typeof node !== "object") return;
335
+ visitor.enter(node);
336
+ for (const key in node) {
337
+ if (key === "parent" || key === "prev" || key === "next") continue;
338
+ const value = node[key];
339
+ if (Array.isArray(value)) {
340
+ value.forEach((child) => {
341
+ if (child && typeof child === "object") walk(child, visitor);
342
+ });
343
+ } else if (value && typeof value === "object") {
344
+ walk(value, visitor);
345
+ }
346
+ }
347
+ }
348
+ function transformSvelte(options) {
349
+ const { filePath, source, escapeTags, attributeName = "data-inspecto" } = options;
350
+ const escapeTagsSet = buildEscapeTagsSet(escapeTags);
351
+ let replacedContent = source;
352
+ const scriptRegex = /<script(?:\s+[a-zA-Z-]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^>\s]*))?)?>[\s\S]*?<\/script>/gi;
353
+ const styleRegex = /<style(?:\s+[a-zA-Z-]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^>\s]*))?)?>[\s\S]*?<\/style>/gi;
354
+ const scriptMatches = source.match(scriptRegex) || [];
355
+ const styleMatches = source.match(styleRegex) || [];
356
+ [...scriptMatches, ...styleMatches].forEach((match) => {
357
+ replacedContent = replacedContent.replace(match, " ".repeat(match.length));
358
+ });
359
+ let ast;
360
+ try {
361
+ ast = (0, import_compiler.parse)(replacedContent);
362
+ } catch {
363
+ return { code: source, map: null, changed: false };
364
+ }
365
+ const s2 = new import_magic_string3.default(source);
366
+ let changed = false;
367
+ function countLines(text, position) {
368
+ let lines = 0;
369
+ for (let i2 = 0; i2 < position; i2++) {
370
+ if (text[i2] === "\n") lines++;
371
+ }
372
+ return lines;
373
+ }
374
+ const root = ast.html || ast.fragment || ast;
375
+ walk(root, {
376
+ enter(node) {
377
+ if (node.type === "Element" || node.type === "RegularElement" || node.type === "InlineComponent" || node.type === "Component") {
378
+ const tagName = node.name || "";
379
+ if (tagName && !escapeTagsSet.has(tagName.toLowerCase()) && !node.attributes?.some((attr) => attr.name === attributeName)) {
380
+ const insertPosition = node.start + tagName.length + 1;
381
+ const line = countLines(source, node.start) + 1;
382
+ const lastNewLine = source.lastIndexOf("\n", node.start - 1);
383
+ const column = lastNewLine === -1 ? node.start + 1 : node.start - lastNewLine;
384
+ const attrValue = formatAttrValue(filePath, line, column);
385
+ const addition = ` ${attributeName}="${attrValue}"`;
386
+ s2.appendLeft(insertPosition, addition);
387
+ changed = true;
388
+ }
389
+ }
390
+ }
391
+ });
392
+ return {
393
+ code: s2.toString(),
394
+ map: changed ? s2.generateMap({ source: filePath, includeContent: true }) : null,
395
+ changed
396
+ };
397
+ }
398
+
399
+ // src/transform/transform-astro.ts
400
+ var import_magic_string4 = __toESM(require("magic-string"), 1);
401
+
402
+ // ../../node_modules/.pnpm/@astrojs+compiler@3.0.1/node_modules/@astrojs/compiler/dist/chunk-W5DTLHV4.js
403
+ var import_crypto = __toESM(require("crypto"), 1);
404
+ var import_fs = __toESM(require("fs"), 1);
405
+ var import_util = require("util");
406
+ globalThis.fs || Object.defineProperty(globalThis, "fs", { value: import_fs.default });
407
+ globalThis.process || Object.defineProperties(globalThis, "process", { value: process });
408
+ globalThis.crypto || Object.defineProperty(globalThis, "crypto", { value: import_crypto.default.webcrypto ? import_crypto.default.webcrypto : { getRandomValues(m2) {
409
+ return import_crypto.default.randomFillSync(m2);
410
+ } } });
411
+ globalThis.performance || Object.defineProperty(globalThis, "performance", { value: { now() {
412
+ let [m2, o] = process.hrtime();
413
+ return m2 * 1e3 + o / 1e6;
414
+ } } });
415
+ var y = new import_util.TextEncoder("utf-8");
416
+ var w = new import_util.TextDecoder("utf-8");
417
+ var d = class {
418
+ constructor() {
419
+ this.argv = ["js"], this.env = {}, this.exit = (t) => {
420
+ t !== 0 && console.warn("exit code:", t);
421
+ }, this._exitPromise = new Promise((t) => {
422
+ this._resolveExitPromise = t;
423
+ }), this._pendingEvent = null, this._scheduledTimeouts = /* @__PURE__ */ new Map(), this._nextCallbackTimeoutID = 1;
424
+ let o = (t, e) => {
425
+ this.mem.setUint32(t + 0, e, true), this.mem.setUint32(t + 4, Math.floor(e / 4294967296), true);
426
+ }, n = (t) => {
427
+ let e = this.mem.getUint32(t + 0, true), s2 = this.mem.getInt32(t + 4, true);
428
+ return e + s2 * 4294967296;
429
+ }, r = (t) => {
430
+ let e = this.mem.getFloat64(t, true);
431
+ if (e === 0) return;
432
+ if (!isNaN(e)) return e;
433
+ let s2 = this.mem.getUint32(t, true);
434
+ return this._values[s2];
435
+ }, l = (t, e) => {
436
+ if (typeof e == "number" && e !== 0) {
437
+ if (isNaN(e)) {
438
+ this.mem.setUint32(t + 4, 2146959360, true), this.mem.setUint32(t, 0, true);
439
+ return;
440
+ }
441
+ this.mem.setFloat64(t, e, true);
442
+ return;
443
+ }
444
+ if (e === void 0) {
445
+ this.mem.setFloat64(t, 0, true);
446
+ return;
447
+ }
448
+ let i2 = this._ids.get(e);
449
+ i2 === void 0 && (i2 = this._idPool.pop(), i2 === void 0 && (i2 = this._values.length), this._values[i2] = e, this._goRefCounts[i2] = 0, this._ids.set(e, i2)), this._goRefCounts[i2]++;
450
+ let a = 0;
451
+ switch (typeof e) {
452
+ case "object":
453
+ e !== null && (a = 1);
454
+ break;
455
+ case "string":
456
+ a = 2;
457
+ break;
458
+ case "symbol":
459
+ a = 3;
460
+ break;
461
+ case "function":
462
+ a = 4;
463
+ break;
464
+ }
465
+ this.mem.setUint32(t + 4, 2146959360 | a, true), this.mem.setUint32(t, i2, true);
466
+ }, c = (t) => {
467
+ let e = n(t + 0), s2 = n(t + 8);
468
+ return new Uint8Array(this._inst.exports.mem.buffer, e, s2);
469
+ }, f2 = (t) => {
470
+ let e = n(t + 0), s2 = n(t + 8), i2 = new Array(s2);
471
+ for (let a = 0; a < s2; a++) i2[a] = r(e + a * 8);
472
+ return i2;
473
+ }, u = (t) => {
474
+ let e = n(t + 0), s2 = n(t + 8);
475
+ return w.decode(new DataView(this._inst.exports.mem.buffer, e, s2));
476
+ }, h = Date.now() - performance.now();
477
+ this.importObject = { gojs: { "runtime.wasmExit": (t) => {
478
+ t >>>= 0;
479
+ let e = this.mem.getInt32(t + 8, true);
480
+ this.exited = true, delete this._inst, delete this._values, delete this._goRefCounts, delete this._ids, delete this._idPool, this.exit(e);
481
+ }, "runtime.wasmWrite": (t) => {
482
+ t >>>= 0;
483
+ let e = n(t + 8), s2 = n(t + 16), i2 = this.mem.getInt32(t + 24, true);
484
+ import_fs.default.writeSync(e, new Uint8Array(this._inst.exports.mem.buffer, s2, i2));
485
+ }, "runtime.resetMemoryDataView": (t) => {
486
+ t >>>= 0, this.mem = new DataView(this._inst.exports.mem.buffer);
487
+ }, "runtime.nanotime1": (t) => {
488
+ t >>>= 0, o(t + 8, (h + performance.now()) * 1e6);
489
+ }, "runtime.walltime": (t) => {
490
+ t >>>= 0;
491
+ let e = (/* @__PURE__ */ new Date()).getTime();
492
+ o(t + 8, e / 1e3), this.mem.setInt32(t + 16, e % 1e3 * 1e6, true);
493
+ }, "runtime.scheduleTimeoutEvent": (t) => {
494
+ t >>>= 0;
495
+ let e = this._nextCallbackTimeoutID;
496
+ this._nextCallbackTimeoutID++, this._scheduledTimeouts.set(e, setTimeout(() => {
497
+ for (this._resume(); this._scheduledTimeouts.has(e); ) console.warn("scheduleTimeoutEvent: missed timeout event"), this._resume();
498
+ }, n(t + 8) + 1)), this.mem.setInt32(t + 16, e, true);
499
+ }, "runtime.clearTimeoutEvent": (t) => {
500
+ t >>>= 0;
501
+ let e = this.mem.getInt32(t + 8, true);
502
+ clearTimeout(this._scheduledTimeouts.get(e)), this._scheduledTimeouts.delete(e);
503
+ }, "runtime.getRandomData": (t) => {
504
+ t >>>= 0, globalThis.crypto.getRandomValues(c(t + 8));
505
+ }, "syscall/js.finalizeRef": (t) => {
506
+ t >>>= 0;
507
+ let e = this.mem.getUint32(t + 8, true);
508
+ if (this._goRefCounts[e]--, this._goRefCounts[e] === 0) {
509
+ let s2 = this._values[e];
510
+ this._values[e] = null, this._ids.delete(s2), this._idPool.push(e);
511
+ }
512
+ }, "syscall/js.stringVal": (t) => {
513
+ t >>>= 0, l(t + 24, u(t + 8));
514
+ }, "syscall/js.valueGet": (t) => {
515
+ t >>>= 0;
516
+ let e = Reflect.get(r(t + 8), u(t + 16));
517
+ t = this._inst.exports.getsp() >>> 0, l(t + 32, e);
518
+ }, "syscall/js.valueSet": (t) => {
519
+ t >>>= 0, Reflect.set(r(t + 8), u(t + 16), r(t + 32));
520
+ }, "syscall/js.valueDelete": (t) => {
521
+ t >>>= 0, Reflect.deleteProperty(r(t + 8), u(t + 16));
522
+ }, "syscall/js.valueIndex": (t) => {
523
+ t >>>= 0, l(t + 24, Reflect.get(r(t + 8), n(t + 16)));
524
+ }, "syscall/js.valueSetIndex": (t) => {
525
+ t >>>= 0, Reflect.set(r(t + 8), n(t + 16), r(t + 24));
526
+ }, "syscall/js.valueCall": (t) => {
527
+ t >>>= 0;
528
+ try {
529
+ let e = r(t + 8), s2 = Reflect.get(e, u(t + 16)), i2 = f2(t + 32), a = Reflect.apply(s2, e, i2);
530
+ t = this._inst.exports.getsp() >>> 0, l(t + 56, a), this.mem.setUint8(t + 64, 1);
531
+ } catch (e) {
532
+ t = this._inst.exports.getsp() >>> 0, l(t + 56, e), this.mem.setUint8(t + 64, 0);
533
+ }
534
+ }, "syscall/js.valueInvoke": (t) => {
535
+ t >>>= 0;
536
+ try {
537
+ let e = r(t + 8), s2 = f2(t + 16), i2 = Reflect.apply(e, void 0, s2);
538
+ t = this._inst.exports.getsp() >>> 0, l(t + 40, i2), this.mem.setUint8(t + 48, 1);
539
+ } catch (e) {
540
+ t = this._inst.exports.getsp() >>> 0, l(t + 40, e), this.mem.setUint8(t + 48, 0);
541
+ }
542
+ }, "syscall/js.valueNew": (t) => {
543
+ t >>>= 0;
544
+ try {
545
+ let e = r(t + 8), s2 = f2(t + 16), i2 = Reflect.construct(e, s2);
546
+ t = this._inst.exports.getsp() >>> 0, l(t + 40, i2), this.mem.setUint8(t + 48, 1);
547
+ } catch (e) {
548
+ t = this._inst.exports.getsp() >>> 0, l(t + 40, e), this.mem.setUint8(t + 48, 0);
549
+ }
550
+ }, "syscall/js.valueLength": (t) => {
551
+ t >>>= 0, o(t + 16, Number.parseInt(r(t + 8).length));
552
+ }, "syscall/js.valuePrepareString": (t) => {
553
+ t >>>= 0;
554
+ let e = y.encode(String(r(t + 8)));
555
+ l(t + 16, e), o(t + 24, e.length);
556
+ }, "syscall/js.valueLoadString": (t) => {
557
+ t >>>= 0;
558
+ let e = r(t + 8);
559
+ c(t + 16).set(e);
560
+ }, "syscall/js.valueInstanceOf": (t) => {
561
+ t >>>= 0, this.mem.setUint8(t + 24, r(t + 8) instanceof r(t + 16) ? 1 : 0);
562
+ }, "syscall/js.copyBytesToGo": (t) => {
563
+ t >>>= 0;
564
+ let e = c(t + 8), s2 = r(t + 32);
565
+ if (!(s2 instanceof Uint8Array || s2 instanceof Uint8ClampedArray)) {
566
+ this.mem.setUint8(t + 48, 0);
567
+ return;
568
+ }
569
+ let i2 = s2.subarray(0, e.length);
570
+ e.set(i2), o(t + 40, i2.length), this.mem.setUint8(t + 48, 1);
571
+ }, "syscall/js.copyBytesToJS": (t) => {
572
+ t >>>= 0;
573
+ let e = r(t + 8), s2 = c(t + 16);
574
+ if (!(e instanceof Uint8Array || e instanceof Uint8ClampedArray)) {
575
+ this.mem.setUint8(t + 48, 0);
576
+ return;
577
+ }
578
+ let i2 = s2.subarray(0, e.length);
579
+ e.set(i2), o(t + 40, i2.length), this.mem.setUint8(t + 48, 1);
580
+ }, debug: (t) => {
581
+ console.log(t);
582
+ } } };
583
+ }
584
+ async run(o) {
585
+ if (!(o instanceof WebAssembly.Instance)) throw new Error("Go.run: WebAssembly.Instance expected");
586
+ this._inst = o, this.mem = new DataView(this._inst.exports.mem.buffer), this._values = [Number.NaN, 0, null, true, false, globalThis, this], this._goRefCounts = new Array(this._values.length).fill(Number.POSITIVE_INFINITY), this._ids = /* @__PURE__ */ new Map([[0, 1], [null, 2], [true, 3], [false, 4], [globalThis, 5], [this, 6]]), this._idPool = [], this.exited = false;
587
+ let n = 4096, r = (h) => {
588
+ let t = n, e = y.encode(`${h}\0`);
589
+ return new Uint8Array(this.mem.buffer, n, e.length).set(e), n += e.length, n % 8 !== 0 && (n += 8 - n % 8), t;
590
+ }, l = this.argv.length, c = [];
591
+ this.argv.forEach((h) => {
592
+ c.push(r(h));
593
+ }), c.push(0), Object.keys(this.env).sort().forEach((h) => {
594
+ c.push(r(`${h}=${this.env[h]}`));
595
+ }), c.push(0);
596
+ let u = n;
597
+ c.forEach((h) => {
598
+ this.mem.setUint32(n, h, true), this.mem.setUint32(n + 4, 0, true), n += 8;
599
+ }), this._inst.exports.run(l, u), this.exited && this._resolveExitPromise(), await this._exitPromise;
600
+ }
601
+ _resume() {
602
+ if (this.exited) throw new Error("Go program has already exited");
603
+ this._inst.exports.resume(), this.exited && this._resolveExitPromise();
604
+ }
605
+ _makeFuncWrapper(o) {
606
+ let n = this;
607
+ return function() {
608
+ let r = { id: o, this: this, args: arguments };
609
+ return n._pendingEvent = r, n._resume(), r.result;
610
+ };
611
+ }
612
+ };
613
+
614
+ // ../../node_modules/.pnpm/@astrojs+compiler@3.0.1/node_modules/@astrojs/compiler/dist/node/sync.js
615
+ var import_fs2 = require("fs");
616
+ var import_url = require("url");
617
+ function i() {
618
+ return s || (s = f()), s;
619
+ }
620
+ var s;
621
+ var w2 = (e, t) => i().parse(e, t);
622
+ function f() {
623
+ let e = new d(), t = v2((0, import_url.fileURLToPath)(new URL("../astro.wasm", importMetaUrl)), e.importObject);
624
+ e.run(t);
625
+ let o = globalThis["@astrojs/compiler"];
626
+ return { transform: (n, a) => {
627
+ try {
628
+ return o.transform(n, a || {});
629
+ } catch (r) {
630
+ throw s = void 0, r;
631
+ }
632
+ }, parse: (n, a) => {
633
+ try {
634
+ let r = o.parse(n, a || {});
635
+ return { ...r, ast: JSON.parse(r.ast) };
636
+ } catch (r) {
637
+ throw s = void 0, r;
638
+ }
639
+ }, convertToTSX: (n, a) => {
640
+ try {
641
+ let r = o.convertToTSX(n, a || {});
642
+ return { ...r, map: JSON.parse(r.map) };
643
+ } catch (r) {
644
+ throw s = void 0, r;
645
+ }
646
+ } };
647
+ }
648
+ function v2(e, t) {
649
+ let o = (0, import_fs2.readFileSync)(e);
650
+ return new WebAssembly.Instance(new WebAssembly.Module(o), t);
651
+ }
652
+
653
+ // src/transform/transform-astro.ts
654
+ function walk2(node, visitor) {
655
+ if (!node || typeof node !== "object") return;
656
+ visitor.enter(node);
657
+ if (Array.isArray(node.children)) {
658
+ for (const child of node.children) {
659
+ walk2(child, visitor);
660
+ }
661
+ }
662
+ }
663
+ function transformAstro(options) {
664
+ const { filePath, source, escapeTags, attributeName = "data-inspecto" } = options;
665
+ const escapeTagsSet = buildEscapeTagsSet(escapeTags);
666
+ let ast;
667
+ try {
668
+ ast = w2(source, { position: true }).ast;
669
+ } catch (_err) {
670
+ return { code: source, map: null, changed: false };
671
+ }
672
+ const s2 = new import_magic_string4.default(source);
673
+ let changed = false;
674
+ walk2(ast, {
675
+ enter(node) {
676
+ if (node.type === "element" || node.type === "component") {
677
+ const tagName = node.name;
678
+ if (tagName && !escapeTagsSet.has(tagName) && !node.attributes?.some((attr) => attr.name === attributeName)) {
679
+ const startOffset = node.position?.start?.offset ?? -1;
680
+ if (startOffset === -1) return;
681
+ let tagStartIndex = startOffset;
682
+ while (tagStartIndex >= 0 && source[tagStartIndex] !== "<") {
683
+ tagStartIndex--;
684
+ }
685
+ if (tagStartIndex >= 0) {
686
+ const substringAfterTag = source.substring(tagStartIndex);
687
+ const escapedTagName = tagName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
688
+ const strictRegex = new RegExp(`^<\\s*${escapedTagName}(?=\\s|/|>)`, "i");
689
+ const strictMatch = substringAfterTag.match(strictRegex);
690
+ if (strictMatch) {
691
+ const insertPosition = tagStartIndex + strictMatch[0].length;
692
+ const line = node.position.start.line;
693
+ const column = node.position.start.column;
694
+ const attrValue = formatAttrValue(filePath, line, column);
695
+ const addition = ` ${attributeName}="${attrValue}"`;
696
+ s2.appendLeft(insertPosition, addition);
697
+ changed = true;
698
+ }
699
+ }
700
+ }
701
+ }
702
+ }
703
+ });
704
+ return {
705
+ code: s2.toString(),
706
+ map: changed ? s2.generateMap({ source: filePath, includeContent: true }) : null,
707
+ changed
708
+ };
709
+ }
710
+
328
711
  // src/transform/index.ts
329
712
  function transformRouter(options) {
330
713
  const { filePath, source, projectRoot, pluginOptions } = options;
@@ -349,6 +732,25 @@ function transformRouter(options) {
349
732
  attributeName: pluginOptions.attributeName
350
733
  });
351
734
  }
735
+ if (ext === ".svelte") {
736
+ return transformSvelte({
737
+ filePath,
738
+ source,
739
+ projectRoot,
740
+ escapeTags: pluginOptions.escapeTags,
741
+ pathType: pluginOptions.pathType,
742
+ attributeName: pluginOptions.attributeName
743
+ });
744
+ }
745
+ if (ext === ".astro") {
746
+ return transformAstro({
747
+ filePath,
748
+ source,
749
+ escapeTags: pluginOptions.escapeTags,
750
+ pathType: pluginOptions.pathType,
751
+ attributeName: pluginOptions.attributeName
752
+ });
753
+ }
352
754
  return null;
353
755
  }
354
756
 
@@ -487,7 +889,7 @@ function isDebugEnabled(namespace) {
487
889
  if (typeof process === "undefined" || !process.env) return false;
488
890
  const debugEnv = process.env.DEBUG;
489
891
  if (!debugEnv) return false;
490
- const namespaces = debugEnv.split(",").map((s) => s.trim());
892
+ const namespaces = debugEnv.split(",").map((s2) => s2.trim());
491
893
  for (const ns of namespaces) {
492
894
  if (ns === "*") return true;
493
895
  if (ns.endsWith("*")) {
@@ -643,7 +1045,7 @@ function readJsonSafely(filePath) {
643
1045
  }
644
1046
  return null;
645
1047
  }
646
- function resolveTargetTool(config, ide = "vscode") {
1048
+ function resolveTargetTool(config, _ide = "vscode") {
647
1049
  const defaultProvider = config["provider.default"];
648
1050
  if (defaultProvider) {
649
1051
  const tool = defaultProvider.split(".")[0];
@@ -751,7 +1153,7 @@ function resolveIntents(serverPrompts) {
751
1153
  configLogger.warn(`Intent "${item.id}" is missing required "aiIntent".`);
752
1154
  continue;
753
1155
  }
754
- const existingIdx = merged.findIndex((i) => i.id === item.id);
1156
+ const existingIdx = merged.findIndex((i2) => i2.id === item.id);
755
1157
  if (existingIdx !== -1) {
756
1158
  if (item.enabled === false) {
757
1159
  merged.splice(existingIdx, 1);
@@ -795,7 +1197,7 @@ function watchConfig(onReload, cwd = process.cwd(), gitRoot) {
795
1197
  });
796
1198
  watcher.unref();
797
1199
  watchers.push(watcher);
798
- } catch (e) {
1200
+ } catch (_e) {
799
1201
  }
800
1202
  }
801
1203
  }
@@ -863,7 +1265,6 @@ function dispatchPromptThroughIde(runtime, payload) {
863
1265
  line: payload.line,
864
1266
  column: payload.column,
865
1267
  snippet: payload.snippet,
866
- ...payload.screenshotContext ? { screenshotContext: payload.screenshotContext } : {},
867
1268
  overrides: runtime.overrides,
868
1269
  autoSend: runtime.autoSend
869
1270
  });
@@ -997,6 +1398,188 @@ function assertPathWithinIdeOpenScope(file, projectRoot) {
997
1398
  }
998
1399
  }
999
1400
 
1401
+ // src/server/session-store.ts
1402
+ var DEFAULT_STATUS = "pending";
1403
+ function createAnnotationSessionStore(options = {}) {
1404
+ const sessions = /* @__PURE__ */ new Map();
1405
+ const listeners = /* @__PURE__ */ new Set();
1406
+ const now = options.now ?? (() => Date.now());
1407
+ const createId = options.createId ?? createRandomId;
1408
+ function findNewestMatchingSession(statuses) {
1409
+ return [...sessions.values()].filter((session) => statuses ? statuses.has(session.status) : true).sort((left, right) => right.updatedAt - left.updatedAt)[0] ?? null;
1410
+ }
1411
+ function updateSessionStatus(id, status) {
1412
+ const session = sessions.get(id);
1413
+ if (!session) return null;
1414
+ const timestamp = now();
1415
+ session.status = status;
1416
+ session.updatedAt = timestamp;
1417
+ if (status === "acknowledged") {
1418
+ session.acknowledgedAt = timestamp;
1419
+ }
1420
+ if (status === "resolved") {
1421
+ session.resolvedAt = timestamp;
1422
+ }
1423
+ emit({ type: "session-status-updated", session });
1424
+ return cloneSession(session);
1425
+ }
1426
+ function claimSession(id, statuses) {
1427
+ const session = sessions.get(id);
1428
+ if (!session || statuses && !statuses.has(session.status)) return null;
1429
+ if (session.status === "acknowledged") return cloneSession(session);
1430
+ return updateSessionStatus(id, "acknowledged");
1431
+ }
1432
+ function emit(event) {
1433
+ const snapshot = cloneSession(event.session);
1434
+ for (const listener of listeners) {
1435
+ listener({ type: event.type, session: snapshot });
1436
+ }
1437
+ }
1438
+ const store = {
1439
+ createSession(input) {
1440
+ const timestamp = now();
1441
+ const session = {
1442
+ id: createId(),
1443
+ instruction: input.instruction?.trim() ?? "",
1444
+ annotations: cloneArray(input.annotations),
1445
+ ...input.deliveryMode ? { deliveryMode: input.deliveryMode } : {},
1446
+ status: DEFAULT_STATUS,
1447
+ messages: cloneArray(input.messages ?? []),
1448
+ createdAt: timestamp,
1449
+ updatedAt: timestamp,
1450
+ ...input.runtimeContext ? { runtimeContext: cloneValue(input.runtimeContext) } : {},
1451
+ ...input.cssContextPrompt?.trim() ? { cssContextPrompt: input.cssContextPrompt.trim() } : {},
1452
+ ...input.pageUrl ? { pageUrl: input.pageUrl } : {},
1453
+ ...input.route ? { route: input.route } : {}
1454
+ };
1455
+ sessions.set(session.id, session);
1456
+ emit({ type: "session-created", session });
1457
+ return cloneSession(session);
1458
+ },
1459
+ getSession(id) {
1460
+ const session = sessions.get(id);
1461
+ return session ? cloneSession(session) : null;
1462
+ },
1463
+ listSessions(options2 = {}) {
1464
+ const statuses = normalizeStatuses(options2.status);
1465
+ return [...sessions.values()].filter((session) => statuses ? statuses.has(session.status) : true).sort((left, right) => right.updatedAt - left.updatedAt).map((session) => cloneSession(session));
1466
+ },
1467
+ async claimNextSession(options2 = {}) {
1468
+ const statuses = normalizeStatuses(DEFAULT_STATUS);
1469
+ const existingSession = findNewestMatchingSession(statuses);
1470
+ if (existingSession) {
1471
+ return {
1472
+ session: claimSession(existingSession.id, statuses),
1473
+ timedOut: false,
1474
+ matchedExisting: true
1475
+ };
1476
+ }
1477
+ const timeoutMs = normalizeTimeoutMs(options2.timeoutMs);
1478
+ if (timeoutMs === 0) {
1479
+ return {
1480
+ session: null,
1481
+ timedOut: true,
1482
+ matchedExisting: false
1483
+ };
1484
+ }
1485
+ return await new Promise((resolve2) => {
1486
+ let settled = false;
1487
+ let timeout = null;
1488
+ const finish = (result) => {
1489
+ if (settled) return;
1490
+ settled = true;
1491
+ unsubscribe();
1492
+ if (timeout) {
1493
+ clearTimeout(timeout);
1494
+ }
1495
+ resolve2(result);
1496
+ };
1497
+ const unsubscribe = this.subscribe((event) => {
1498
+ const session = claimSession(event.session.id, statuses);
1499
+ if (!session) return;
1500
+ finish({
1501
+ session,
1502
+ timedOut: false,
1503
+ matchedExisting: false,
1504
+ event: event.type
1505
+ });
1506
+ });
1507
+ if (timeoutMs !== null) {
1508
+ timeout = setTimeout(() => {
1509
+ finish({
1510
+ session: null,
1511
+ timedOut: true,
1512
+ matchedExisting: false
1513
+ });
1514
+ }, timeoutMs);
1515
+ }
1516
+ });
1517
+ },
1518
+ appendMessage(id, input) {
1519
+ const session = sessions.get(id);
1520
+ if (!session) return null;
1521
+ const timestamp = now();
1522
+ session.messages.push({
1523
+ id: createId(),
1524
+ role: input.role,
1525
+ text: input.text,
1526
+ createdAt: timestamp
1527
+ });
1528
+ session.updatedAt = timestamp;
1529
+ if (input.role === "agent" && isPendingLikeStatus(session.status)) {
1530
+ session.status = "in_progress";
1531
+ }
1532
+ emit({ type: "session-message-appended", session });
1533
+ return cloneSession(session);
1534
+ },
1535
+ updateStatus(id, status) {
1536
+ return updateSessionStatus(id, status);
1537
+ },
1538
+ subscribe(listener) {
1539
+ listeners.add(listener);
1540
+ return () => {
1541
+ listeners.delete(listener);
1542
+ };
1543
+ },
1544
+ clear() {
1545
+ sessions.clear();
1546
+ listeners.clear();
1547
+ }
1548
+ };
1549
+ return store;
1550
+ }
1551
+ var annotationSessionStore = createAnnotationSessionStore();
1552
+ function normalizeStatuses(status) {
1553
+ if (!status) return null;
1554
+ return new Set(Array.isArray(status) ? status : [status]);
1555
+ }
1556
+ function normalizeTimeoutMs(value) {
1557
+ if (value === void 0) return null;
1558
+ if (!Number.isFinite(value)) return 0;
1559
+ return Math.max(0, Math.floor(value));
1560
+ }
1561
+ function isPendingLikeStatus(status) {
1562
+ return status === "pending" || status === "acknowledged";
1563
+ }
1564
+ function hasAgentReply(session) {
1565
+ return session.messages.some((message) => message.role === "agent" && Boolean(message.text?.trim()));
1566
+ }
1567
+ function createRandomId() {
1568
+ return `annotation-session-${Math.random().toString(36).slice(2, 10)}`;
1569
+ }
1570
+ function cloneSession(session) {
1571
+ return cloneValue(session);
1572
+ }
1573
+ function cloneArray(value) {
1574
+ return cloneValue(value);
1575
+ }
1576
+ function cloneValue(value) {
1577
+ if (typeof structuredClone === "function") {
1578
+ return structuredClone(value);
1579
+ }
1580
+ return JSON.parse(JSON.stringify(value));
1581
+ }
1582
+
1000
1583
  // src/server/annotation-dispatch.ts
1001
1584
  var AnnotationDispatchError = class extends Error {
1002
1585
  constructor(message, errorCode) {
@@ -1005,20 +1588,30 @@ var AnnotationDispatchError = class extends Error {
1005
1588
  this.errorCode = errorCode;
1006
1589
  }
1007
1590
  };
1008
- async function dispatchAnnotationsToAi(req, state) {
1591
+ async function dispatchAnnotationsToAi(req, state, store = annotationSessionStore) {
1009
1592
  try {
1010
1593
  validateAnnotationDispatchRequest(req, state);
1011
1594
  const batch = normalizeAnnotationBatch(req);
1012
1595
  const prompt = buildAnnotationBatchPrompt(batch);
1596
+ const deliveryMode = normalizeDeliveryMode(req.deliveryMode);
1597
+ const session = store.createSession({
1598
+ instruction: batch.instruction,
1599
+ annotations: toSessionAnnotations(batch.annotations),
1600
+ deliveryMode,
1601
+ ...batch.runtimeContext ? { runtimeContext: batch.runtimeContext } : {},
1602
+ ...batch.cssContextPrompt ? { cssContextPrompt: batch.cssContextPrompt } : {}
1603
+ });
1013
1604
  const representativeTarget = batch.annotations[0]?.targets[0];
1014
- const runtime = resolvePromptDispatchRuntime(state);
1015
- return dispatchPromptThroughIde(runtime, {
1605
+ const dispatchResult = deliveryMode === "ide" ? dispatchPromptThroughIde(resolvePromptDispatchRuntime(state), {
1016
1606
  prompt,
1017
1607
  ...representativeTarget?.file ? { filePath: representativeTarget.file } : {},
1018
1608
  ...representativeTarget?.line ? { line: representativeTarget.line } : {},
1019
- ...representativeTarget?.column ? { column: representativeTarget.column } : {},
1020
- ...batch.screenshotContext ? { screenshotContext: batch.screenshotContext } : {}
1021
- });
1609
+ ...representativeTarget?.column ? { column: representativeTarget.column } : {}
1610
+ }) : { success: true };
1611
+ return {
1612
+ ...dispatchResult,
1613
+ session: toSessionSummary(session)
1614
+ };
1022
1615
  } catch (error) {
1023
1616
  return {
1024
1617
  success: false,
@@ -1027,6 +1620,41 @@ async function dispatchAnnotationsToAi(req, state) {
1027
1620
  };
1028
1621
  }
1029
1622
  }
1623
+ function normalizeDeliveryMode(input) {
1624
+ return input === "agent" ? "agent" : "ide";
1625
+ }
1626
+ function toSessionAnnotations(annotations) {
1627
+ return annotations.map((annotation) => ({
1628
+ id: `annotation-${annotation.index}`,
1629
+ note: annotation.note,
1630
+ intent: annotation.intent,
1631
+ targets: annotation.targets.map((target, targetIndex) => ({
1632
+ id: `annotation-${annotation.index}-target-${targetIndex + 1}`,
1633
+ label: target.label ?? "Unknown target",
1634
+ location: {
1635
+ file: target.file,
1636
+ line: target.line,
1637
+ column: target.column
1638
+ },
1639
+ ...target.selector ? { selector: target.selector } : {},
1640
+ ...target.snippet ? { snippet: target.snippet } : {},
1641
+ rect: {
1642
+ x: 0,
1643
+ y: 0,
1644
+ width: 0,
1645
+ height: 0
1646
+ }
1647
+ }))
1648
+ }));
1649
+ }
1650
+ function toSessionSummary(session) {
1651
+ return {
1652
+ id: session.id,
1653
+ status: session.status,
1654
+ createdAt: session.createdAt,
1655
+ updatedAt: session.updatedAt
1656
+ };
1657
+ }
1030
1658
  function validateAnnotationDispatchRequest(req, state) {
1031
1659
  if (!req.annotations.length) {
1032
1660
  throw new AnnotationDispatchError("At least one annotation is required.", "INVALID_REQUEST");
@@ -1047,9 +1675,7 @@ function validateAnnotationDispatchRequest(req, state) {
1047
1675
  function normalizeAnnotationBatch(req) {
1048
1676
  return {
1049
1677
  instruction: req.instruction?.trim() ?? "",
1050
- responseMode: req.responseMode ?? "unified",
1051
1678
  ...req.runtimeContext ? { runtimeContext: req.runtimeContext } : {},
1052
- ...req.screenshotContext ? { screenshotContext: req.screenshotContext } : {},
1053
1679
  ...req.cssContextPrompt?.trim() ? { cssContextPrompt: req.cssContextPrompt.trim() } : {},
1054
1680
  annotations: req.annotations.map((annotation, index) => ({
1055
1681
  index: index + 1,
@@ -1071,12 +1697,9 @@ function buildAnnotationBatchPrompt(batch) {
1071
1697
  const prompt = batch.instruction ? `${batch.instruction}
1072
1698
 
1073
1699
  ${body}` : body;
1074
- return appendScreenshotContextSection(
1075
- appendCssContextSection(
1076
- appendRuntimeContextSection(prompt, batch.runtimeContext),
1077
- batch.cssContextPrompt
1078
- ),
1079
- batch.screenshotContext
1700
+ return appendCssContextSection(
1701
+ appendRuntimeContextSection(prompt, batch.runtimeContext),
1702
+ batch.cssContextPrompt
1080
1703
  );
1081
1704
  }
1082
1705
  function appendCssContextSection(prompt, cssContextPrompt) {
@@ -1103,20 +1726,6 @@ function buildSelectedElementsPrompt(annotations) {
1103
1726
  }
1104
1727
  return lines.join("\n");
1105
1728
  }
1106
- function appendScreenshotContextSection(prompt, screenshotContext) {
1107
- if (!screenshotContext || !screenshotContext.imageDataUrl && !screenshotContext.imageAssetId) {
1108
- return prompt;
1109
- }
1110
- const lines = [
1111
- "Visual screenshot context attached:",
1112
- `- capturedAt=${screenshotContext.capturedAt}`,
1113
- `- mimeType=${screenshotContext.mimeType}`,
1114
- ...screenshotContext.imageAssetId ? [`- imageAssetId=${screenshotContext.imageAssetId}`] : []
1115
- ];
1116
- return `${prompt}
1117
-
1118
- ${lines.join("\n")}`;
1119
- }
1120
1729
  function appendRuntimeContextSection(prompt, runtimeContext) {
1121
1730
  if (!runtimeContext?.records.length) {
1122
1731
  return prompt;
@@ -1164,7 +1773,7 @@ async function buildClientConfig(serverState2) {
1164
1773
  ...info,
1165
1774
  prompts: resolveIntents(promptsConfig),
1166
1775
  hotKeys: userConfig["inspector.hotKey"] ?? "alt",
1167
- theme: userConfig["inspector.theme"] ?? "auto",
1776
+ annotateDeliveryMode: userConfig["annotate.deliveryMode"] ?? "both",
1168
1777
  includeSnippet: userConfig["prompt.includeSnippet"] ?? false,
1169
1778
  runtimeContext: {
1170
1779
  enabled: true,
@@ -1172,10 +1781,6 @@ async function buildClientConfig(serverState2) {
1172
1781
  maxRuntimeErrors: 3,
1173
1782
  maxFailedRequests: 2
1174
1783
  },
1175
- screenshotContext: {
1176
- enabled: false
1177
- },
1178
- annotationResponseMode: userConfig["prompt.annotationResponseMode"] ?? "unified",
1179
1784
  autoSend: userConfig["prompt.autoSend"] ?? false
1180
1785
  };
1181
1786
  }
@@ -1220,7 +1825,7 @@ function handleOpenFileRequest(body, serverState2) {
1220
1825
  else if (rawEditorHint === "vscodium") editorHint = "codium";
1221
1826
  else if (rawEditorHint === "trae-cn" || rawEditorHint === "trae") editorHint = "trae";
1222
1827
  serverLogger2.debug(
1223
- `IDE_OPEN: activeIde=${activeIde}, activeIdeScheme=${activeIdeScheme}, configuredIde=${configuredIde} -> rawEditorHint=${rawEditorHint}, finalEditorHint=${editorHint}`
1828
+ `SOURCE_OPEN: activeIde=${activeIde}, activeIdeScheme=${activeIdeScheme}, configuredIde=${configuredIde} -> rawEditorHint=${rawEditorHint}, finalEditorHint=${editorHint}`
1224
1829
  );
1225
1830
  if (VSCODE_FAMILY_SCHEMES.includes(rawEditorHint)) {
1226
1831
  let normalizedPath = absolutePath.replace(/\\/g, "/");
@@ -1229,7 +1834,7 @@ function handleOpenFileRequest(body, serverState2) {
1229
1834
  }
1230
1835
  const encodedPath = encodeURI(normalizedPath);
1231
1836
  const uri = `${rawEditorHint}://file${encodedPath}:${body.line}:${body.column}`;
1232
- serverLogger2.debug(`IDE_OPEN: Bypassing launchIDE, using URI scheme directly: ${uri}`);
1837
+ serverLogger2.debug(`SOURCE_OPEN: Bypassing launchIDE, using URI scheme directly: ${uri}`);
1233
1838
  try {
1234
1839
  if (process.platform === "darwin") {
1235
1840
  (0, import_node_child_process2.execFileSync)("open", [uri]);
@@ -1239,7 +1844,7 @@ function handleOpenFileRequest(body, serverState2) {
1239
1844
  (0, import_node_child_process2.execFileSync)("xdg-open", [uri]);
1240
1845
  }
1241
1846
  } catch (e) {
1242
- serverLogger2.error(`Failed to launch URI for IDE_OPEN (${uri}):`, e);
1847
+ serverLogger2.error(`Failed to launch URI for SOURCE_OPEN (${uri}):`, e);
1243
1848
  (0, import_launch_ide2.launchIDE)({
1244
1849
  file: absolutePath,
1245
1850
  line: body.line,
@@ -1296,6 +1901,7 @@ function resolveProjectRoot() {
1296
1901
 
1297
1902
  // src/server/index.ts
1298
1903
  var serverLogger4 = createLogger("inspecto:server", { logLevel: getGlobalLogLevel() });
1904
+ var PORT_FILE_NAME = "inspecto.port.json";
1299
1905
  var serverState = {
1300
1906
  port: null,
1301
1907
  running: false,
@@ -1304,6 +1910,42 @@ var serverState = {
1304
1910
  cwd: process.cwd()
1305
1911
  };
1306
1912
  var serverInstance = null;
1913
+ function getPortFilePath() {
1914
+ return import_node_path7.default.join(import_node_os2.default.tmpdir(), PORT_FILE_NAME);
1915
+ }
1916
+ function getProjectRootHash() {
1917
+ if (!serverState.projectRoot) return null;
1918
+ return import_node_crypto2.default.createHash("md5").update(serverState.projectRoot).digest("hex");
1919
+ }
1920
+ function readPortData(portFile) {
1921
+ if (!import_node_fs4.default.existsSync(portFile)) return {};
1922
+ try {
1923
+ return JSON.parse(import_node_fs4.default.readFileSync(portFile, "utf-8"));
1924
+ } catch {
1925
+ return {};
1926
+ }
1927
+ }
1928
+ function writeProjectPort(port) {
1929
+ const rootHash = getProjectRootHash();
1930
+ if (!rootHash) return;
1931
+ const portFile = getPortFilePath();
1932
+ const portData = readPortData(portFile);
1933
+ portData[rootHash] = port;
1934
+ import_node_fs4.default.writeFileSync(portFile, JSON.stringify(portData, null, 2), "utf-8");
1935
+ }
1936
+ function removeProjectPort() {
1937
+ const rootHash = getProjectRootHash();
1938
+ if (!rootHash) return;
1939
+ const portFile = getPortFilePath();
1940
+ if (!import_node_fs4.default.existsSync(portFile)) return;
1941
+ const portData = readPortData(portFile);
1942
+ delete portData[rootHash];
1943
+ if (Object.keys(portData).length === 0) {
1944
+ import_node_fs4.default.unlinkSync(portFile);
1945
+ } else {
1946
+ import_node_fs4.default.writeFileSync(portFile, JSON.stringify(portData, null, 2), "utf-8");
1947
+ }
1948
+ }
1307
1949
  async function startServer() {
1308
1950
  if (serverState.running && serverState.port !== null) {
1309
1951
  return serverState.port;
@@ -1337,7 +1979,7 @@ async function startServer() {
1337
1979
  });
1338
1980
  });
1339
1981
  await new Promise((resolve2, reject) => {
1340
- serverInstance.listen(port, "127.0.0.1", () => {
1982
+ serverInstance.listen(port, "0.0.0.0", () => {
1341
1983
  serverInstance.unref();
1342
1984
  resolve2();
1343
1985
  });
@@ -1348,37 +1990,18 @@ async function startServer() {
1348
1990
  });
1349
1991
  serverState.port = port;
1350
1992
  serverState.running = true;
1351
- const portFile = import_node_path7.default.join(import_node_os2.default.tmpdir(), "inspecto.port.json");
1352
1993
  try {
1353
- let portData = {};
1354
- if (import_node_fs4.default.existsSync(portFile)) {
1355
- try {
1356
- portData = JSON.parse(import_node_fs4.default.readFileSync(portFile, "utf-8"));
1357
- } catch (e) {
1358
- }
1359
- }
1360
- const rootHash = import_node_crypto2.default.createHash("md5").update(serverState.projectRoot).digest("hex");
1361
- portData[rootHash] = port;
1362
- import_node_fs4.default.writeFileSync(portFile, JSON.stringify(portData, null, 2), "utf-8");
1363
- } catch (e) {
1364
- serverLogger4.warn("Failed to write port file:", e);
1994
+ writeProjectPort(port);
1995
+ } catch (_e) {
1996
+ serverLogger4.warn("Failed to write port file:", _e);
1365
1997
  }
1366
1998
  process.once("exit", () => {
1367
1999
  try {
1368
- if (import_node_fs4.default.existsSync(portFile)) {
1369
- const portData = JSON.parse(import_node_fs4.default.readFileSync(portFile, "utf-8"));
1370
- const rootHash = import_node_crypto2.default.createHash("md5").update(serverState.projectRoot).digest("hex");
1371
- delete portData[rootHash];
1372
- if (Object.keys(portData).length === 0) {
1373
- import_node_fs4.default.unlinkSync(portFile);
1374
- } else {
1375
- import_node_fs4.default.writeFileSync(portFile, JSON.stringify(portData, null, 2), "utf-8");
1376
- }
1377
- }
2000
+ removeProjectPort();
1378
2001
  } catch {
1379
2002
  }
1380
2003
  });
1381
- serverLogger4.info(`server running at http://127.0.0.1:${port}`);
2004
+ serverLogger4.info(`server running at http://0.0.0.0:${port}`);
1382
2005
  return port;
1383
2006
  }
1384
2007
  async function readBody(req) {
@@ -1430,11 +2053,11 @@ async function handleRequest(url, req, res) {
1430
2053
  }
1431
2054
  return;
1432
2055
  }
1433
- if (pathname === import_types2.INSPECTO_API_PATHS.IDE_OPEN && req.method === "POST") {
2056
+ if ((pathname === import_types2.INSPECTO_API_PATHS.SOURCE_OPEN || pathname === import_types2.INSPECTO_API_PATHS.IDE_OPEN) && req.method === "POST") {
1434
2057
  let body;
1435
2058
  try {
1436
2059
  body = JSON.parse(await readBody(req));
1437
- } catch (e) {
2060
+ } catch (_e) {
1438
2061
  res.writeHead(400, { "Content-Type": "application/json" });
1439
2062
  res.end(JSON.stringify({ error: "Invalid JSON body" }));
1440
2063
  return;
@@ -1443,7 +2066,7 @@ async function handleRequest(url, req, res) {
1443
2066
  handleOpenFileRequest(body, serverState);
1444
2067
  } catch (err) {
1445
2068
  serverLogger4.warn(
1446
- `Security: Blocked path traversal attempt in IDE_OPEN: ${body.file}. Reason: ${err.message}`
2069
+ `Security: Blocked path traversal attempt in SOURCE_OPEN: ${body.file}. Reason: ${err.message}`
1447
2070
  );
1448
2071
  res.writeHead(403, { "Content-Type": "application/json" });
1449
2072
  res.end(JSON.stringify({ error: "Access denied: File is outside of project workspace" }));
@@ -1517,6 +2140,212 @@ async function handleRequest(url, req, res) {
1517
2140
  }
1518
2141
  return;
1519
2142
  }
2143
+ if (pathname === import_types2.INSPECTO_API_PATHS.SESSION_CLAIM_NEXT && req.method === "POST") {
2144
+ try {
2145
+ const rawBody = await readBody(req);
2146
+ const body = rawBody ? JSON.parse(rawBody) : {};
2147
+ const timeoutMs = normalizeSessionClaimTimeout(
2148
+ body.timeoutMs === void 0 ? null : String(body.timeoutMs)
2149
+ );
2150
+ const result = await annotationSessionStore.claimNextSession({
2151
+ ...timeoutMs !== void 0 ? { timeoutMs } : {}
2152
+ });
2153
+ res.writeHead(200, { "Content-Type": "application/json" });
2154
+ res.end(
2155
+ JSON.stringify({
2156
+ success: true,
2157
+ timedOut: result.timedOut,
2158
+ matchedExisting: result.matchedExisting,
2159
+ ...result.event ? { event: result.event } : {},
2160
+ ...result.session ? { session: result.session } : {}
2161
+ })
2162
+ );
2163
+ } catch (e) {
2164
+ serverLogger4.error(`Error parsing session claim request:`, e);
2165
+ res.writeHead(400, { "Content-Type": "application/json" });
2166
+ res.end(JSON.stringify({ success: false, error: "Invalid JSON body" }));
2167
+ }
2168
+ return;
2169
+ }
2170
+ if (pathname === import_types2.INSPECTO_API_PATHS.SESSION_EVENTS && req.method === "GET") {
2171
+ const statusParam = url.searchParams.getAll("status");
2172
+ const statuses = statusParam.length ? new Set(statusParam) : null;
2173
+ const sessionId = url.searchParams.get("sessionId")?.trim() || null;
2174
+ res.writeHead(200, {
2175
+ "Content-Type": "text/event-stream",
2176
+ "Cache-Control": "no-cache",
2177
+ Connection: "keep-alive"
2178
+ });
2179
+ res.write(`event: ready
2180
+ data: ${JSON.stringify({ ok: true })}
2181
+
2182
+ `);
2183
+ const unsubscribe = annotationSessionStore.subscribe((event) => {
2184
+ if (sessionId && event.session.id !== sessionId) {
2185
+ return;
2186
+ }
2187
+ if (statuses && !statuses.has(event.session.status)) {
2188
+ return;
2189
+ }
2190
+ res.write(formatSessionSseEvent(event));
2191
+ });
2192
+ req.on("close", () => {
2193
+ unsubscribe();
2194
+ res.end();
2195
+ });
2196
+ return;
2197
+ }
2198
+ if (pathname === import_types2.INSPECTO_API_PATHS.SESSIONS && req.method === "GET") {
2199
+ const statusParam = url.searchParams.getAll("status");
2200
+ const sessions = annotationSessionStore.listSessions(
2201
+ statusParam.length ? {
2202
+ status: statusParam
2203
+ } : void 0
2204
+ );
2205
+ res.writeHead(200, { "Content-Type": "application/json" });
2206
+ res.end(JSON.stringify({ success: true, sessions }));
2207
+ return;
2208
+ }
2209
+ if (pathname.startsWith(`${import_types2.INSPECTO_API_PATHS.SESSIONS}/`) && req.method === "GET") {
2210
+ const sessionId = pathname.substring(import_types2.INSPECTO_API_PATHS.SESSIONS.length + 1);
2211
+ const session = annotationSessionStore.getSession(sessionId);
2212
+ if (!session) {
2213
+ res.writeHead(404, { "Content-Type": "application/json" });
2214
+ res.end(JSON.stringify({ success: false, error: "Session not found" }));
2215
+ return;
2216
+ }
2217
+ res.writeHead(200, { "Content-Type": "application/json" });
2218
+ res.end(JSON.stringify({ success: true, session }));
2219
+ return;
2220
+ }
2221
+ if (pathname.startsWith(`${import_types2.INSPECTO_API_PATHS.SESSIONS}/`) && pathname.endsWith(import_types2.INSPECTO_API_PATHS.SESSION_REPLY_SUFFIX) && req.method === "POST") {
2222
+ const sessionId = pathname.slice(
2223
+ import_types2.INSPECTO_API_PATHS.SESSIONS.length + 1,
2224
+ -import_types2.INSPECTO_API_PATHS.SESSION_REPLY_SUFFIX.length
2225
+ );
2226
+ try {
2227
+ const rawBody = await readBody(req);
2228
+ const body = JSON.parse(rawBody);
2229
+ if (!isAnnotationThreadRole(body.role)) {
2230
+ res.writeHead(400, { "Content-Type": "application/json" });
2231
+ res.end(JSON.stringify({ success: false, error: "Reply role is invalid." }));
2232
+ return;
2233
+ }
2234
+ if (!body.text?.trim()) {
2235
+ res.writeHead(400, { "Content-Type": "application/json" });
2236
+ res.end(JSON.stringify({ success: false, error: "Reply text is required." }));
2237
+ return;
2238
+ }
2239
+ const session = annotationSessionStore.appendMessage(sessionId, {
2240
+ role: body.role,
2241
+ text: body.text.trim()
2242
+ });
2243
+ if (!session) {
2244
+ res.writeHead(404, { "Content-Type": "application/json" });
2245
+ res.end(JSON.stringify({ success: false, error: "Session not found" }));
2246
+ return;
2247
+ }
2248
+ res.writeHead(200, { "Content-Type": "application/json" });
2249
+ res.end(JSON.stringify({ success: true, session }));
2250
+ } catch (e) {
2251
+ serverLogger4.error(`Error parsing session reply request:`, e);
2252
+ res.writeHead(400, { "Content-Type": "application/json" });
2253
+ res.end(JSON.stringify({ success: false, error: "Invalid JSON body" }));
2254
+ }
2255
+ return;
2256
+ }
2257
+ if (pathname.startsWith(`${import_types2.INSPECTO_API_PATHS.SESSIONS}/`) && pathname.endsWith(import_types2.INSPECTO_API_PATHS.SESSION_RESOLVE_SUFFIX) && req.method === "POST") {
2258
+ const sessionId = pathname.slice(
2259
+ import_types2.INSPECTO_API_PATHS.SESSIONS.length + 1,
2260
+ -import_types2.INSPECTO_API_PATHS.SESSION_RESOLVE_SUFFIX.length
2261
+ );
2262
+ try {
2263
+ const rawBody = await readBody(req);
2264
+ const body = rawBody ? JSON.parse(rawBody) : {};
2265
+ const message = body.message?.trim();
2266
+ const existingSession = annotationSessionStore.getSession(sessionId);
2267
+ if (!existingSession) {
2268
+ res.writeHead(404, { "Content-Type": "application/json" });
2269
+ res.end(JSON.stringify({ success: false, error: "Session not found" }));
2270
+ return;
2271
+ }
2272
+ if (!message && !hasAgentReply(existingSession)) {
2273
+ res.writeHead(400, { "Content-Type": "application/json" });
2274
+ res.end(
2275
+ JSON.stringify({
2276
+ success: false,
2277
+ error: "Resolve message is required until an agent reply is recorded."
2278
+ })
2279
+ );
2280
+ return;
2281
+ }
2282
+ if (message) {
2283
+ const repliedSession = annotationSessionStore.appendMessage(sessionId, {
2284
+ role: "agent",
2285
+ text: message
2286
+ });
2287
+ if (!repliedSession) {
2288
+ res.writeHead(404, { "Content-Type": "application/json" });
2289
+ res.end(JSON.stringify({ success: false, error: "Session not found" }));
2290
+ return;
2291
+ }
2292
+ }
2293
+ const session = annotationSessionStore.updateStatus(sessionId, "resolved");
2294
+ if (!session) {
2295
+ res.writeHead(404, { "Content-Type": "application/json" });
2296
+ res.end(JSON.stringify({ success: false, error: "Session not found" }));
2297
+ return;
2298
+ }
2299
+ res.writeHead(200, { "Content-Type": "application/json" });
2300
+ res.end(JSON.stringify({ success: true, session }));
2301
+ } catch (e) {
2302
+ serverLogger4.error(`Error parsing session resolve request:`, e);
2303
+ res.writeHead(400, { "Content-Type": "application/json" });
2304
+ res.end(JSON.stringify({ success: false, error: "Invalid JSON body" }));
2305
+ }
2306
+ return;
2307
+ }
2308
+ if (pathname.startsWith(`${import_types2.INSPECTO_API_PATHS.SESSIONS}/`) && pathname.endsWith(import_types2.INSPECTO_API_PATHS.SESSION_DISMISS_SUFFIX) && req.method === "POST") {
2309
+ const sessionId = pathname.slice(
2310
+ import_types2.INSPECTO_API_PATHS.SESSIONS.length + 1,
2311
+ -import_types2.INSPECTO_API_PATHS.SESSION_DISMISS_SUFFIX.length
2312
+ );
2313
+ try {
2314
+ const rawBody = await readBody(req);
2315
+ const body = rawBody ? JSON.parse(rawBody) : {};
2316
+ const message = body.message?.trim();
2317
+ const existingSession = annotationSessionStore.getSession(sessionId);
2318
+ if (!existingSession) {
2319
+ res.writeHead(404, { "Content-Type": "application/json" });
2320
+ res.end(JSON.stringify({ success: false, error: "Session not found" }));
2321
+ return;
2322
+ }
2323
+ if (message) {
2324
+ const repliedSession = annotationSessionStore.appendMessage(sessionId, {
2325
+ role: "agent",
2326
+ text: message
2327
+ });
2328
+ if (!repliedSession) {
2329
+ res.writeHead(404, { "Content-Type": "application/json" });
2330
+ res.end(JSON.stringify({ success: false, error: "Session not found" }));
2331
+ return;
2332
+ }
2333
+ }
2334
+ const session = annotationSessionStore.updateStatus(sessionId, "dismissed");
2335
+ if (!session) {
2336
+ res.writeHead(404, { "Content-Type": "application/json" });
2337
+ res.end(JSON.stringify({ success: false, error: "Session not found" }));
2338
+ return;
2339
+ }
2340
+ res.writeHead(200, { "Content-Type": "application/json" });
2341
+ res.end(JSON.stringify({ success: true, session }));
2342
+ } catch (e) {
2343
+ serverLogger4.error(`Error parsing session dismiss request:`, e);
2344
+ res.writeHead(400, { "Content-Type": "application/json" });
2345
+ res.end(JSON.stringify({ success: false, error: "Invalid JSON body" }));
2346
+ }
2347
+ return;
2348
+ }
1520
2349
  if (pathname.startsWith(`${import_types2.INSPECTO_API_PATHS.AI_TICKET}/`) && req.method === "GET") {
1521
2350
  const ticketId = pathname.substring(import_types2.INSPECTO_API_PATHS.AI_TICKET.length + 1);
1522
2351
  const payloadStr = readTicket(ticketId);
@@ -1533,7 +2362,7 @@ async function handleRequest(url, req, res) {
1533
2362
  res.end(JSON.stringify({ error: "not found" }));
1534
2363
  }
1535
2364
  async function dispatchToAi(req) {
1536
- const { location, snippet, prompt, screenshotContext } = req;
2365
+ const { location, snippet, prompt } = req;
1537
2366
  const formattedPrompt = prompt ?? `Please help me with this code from \`${location.file}\` (line ${location.line}):
1538
2367
 
1539
2368
  \`\`\`
@@ -1546,8 +2375,7 @@ ${snippet}
1546
2375
  filePath: location.file,
1547
2376
  line: location.line,
1548
2377
  column: location.column,
1549
- snippet,
1550
- ...screenshotContext ? { screenshotContext } : {}
2378
+ snippet
1551
2379
  });
1552
2380
  }
1553
2381
  function getBatchDispatchStatusCode(errorCode, success) {
@@ -1556,6 +2384,21 @@ function getBatchDispatchStatusCode(errorCode, success) {
1556
2384
  if (errorCode === "FORBIDDEN_PATH") return 403;
1557
2385
  return 500;
1558
2386
  }
2387
+ function isAnnotationThreadRole(value) {
2388
+ return value === "user" || value === "agent" || value === "system";
2389
+ }
2390
+ function formatSessionSseEvent(event) {
2391
+ return `event: ${event.type}
2392
+ data: ${JSON.stringify(event)}
2393
+
2394
+ `;
2395
+ }
2396
+ function normalizeSessionClaimTimeout(value) {
2397
+ if (!value?.trim()) return 3e4;
2398
+ const parsed = Number.parseInt(value, 10);
2399
+ if (!Number.isFinite(parsed)) return 3e4;
2400
+ return Math.max(0, Math.min(parsed, 3e5));
2401
+ }
1559
2402
 
1560
2403
  // src/injectors/utils.ts
1561
2404
  var import_node_module = require("module");
@@ -1578,13 +2421,13 @@ var resolveClientModule = () => {
1578
2421
  function getWebpackHtmlScript(serverPort) {
1579
2422
  return `
1580
2423
  window.__AI_INSPECTOR_PORT__ = ${serverPort};
1581
- window.addEventListener('load', () => {
1582
- if (window.InspectoClient) {
1583
- window.InspectoClient.mountInspector({
1584
- serverUrl: 'http://127.0.0.1:' + window.__AI_INSPECTOR_PORT__,
1585
- });
1586
- }
1587
- });
2424
+ window.addEventListener('load', () => {
2425
+ if (window.InspectoClient) {
2426
+ window.InspectoClient.mountInspector({
2427
+ serverUrl: 'http://0.0.0.0:' + window.__AI_INSPECTOR_PORT__,
2428
+ });
2429
+ }
2430
+ });
1588
2431
  `;
1589
2432
  }
1590
2433
  function getWebpackAssetScript(serverPort) {
@@ -1594,7 +2437,7 @@ if (typeof window !== 'undefined') {
1594
2437
  const _initInspecto = () => {
1595
2438
  if (window.InspectoClient) {
1596
2439
  window.InspectoClient.mountInspector({
1597
- serverUrl: 'http://127.0.0.1:' + window.__AI_INSPECTOR_PORT__,
2440
+ serverUrl: 'http://0.0.0.0:' + window.__AI_INSPECTOR_PORT__,
1598
2441
  });
1599
2442
  } else {
1600
2443
  setTimeout(_initInspecto, 100);
@@ -1617,7 +2460,7 @@ function injectWebpack(compiler, serverPortFn, resolveClientModule2) {
1617
2460
  }
1618
2461
  compiler.hooks.compilation.tap("inspecto-overlay", (compilation) => {
1619
2462
  const HtmlWebpackPlugin = compiler.options.plugins.find(
1620
- (p) => p && p.constructor && p.constructor.name === "HtmlWebpackPlugin"
2463
+ (p2) => p2 && p2.constructor && p2.constructor.name === "HtmlWebpackPlugin"
1621
2464
  );
1622
2465
  if (HtmlWebpackPlugin) {
1623
2466
  const hooks = HtmlWebpackPlugin.constructor.getHooks(compilation);
@@ -1661,7 +2504,7 @@ function injectRspack(compiler, serverPortFn, resolveClientModule2) {
1661
2504
  new compiler.webpack.EntryPlugin(compiler.context, inspectoClientPath, {}).apply(compiler);
1662
2505
  compiler.hooks.compilation.tap("inspecto-overlay", (compilation) => {
1663
2506
  const HtmlRspackPlugin = compiler.options.plugins.find(
1664
- (p) => p && p.constructor && p.constructor.name === "HtmlRspackPlugin"
2507
+ (p2) => p2 && p2.constructor && p2.constructor.name === "HtmlRspackPlugin"
1665
2508
  );
1666
2509
  if (HtmlRspackPlugin) {
1667
2510
  const hooks = HtmlRspackPlugin.constructor.getHooks(compilation);
@@ -1685,7 +2528,7 @@ function getViteVirtualModuleScript(serverPort) {
1685
2528
  import { mountInspector } from '@inspecto-dev/core';
1686
2529
  window.__AI_INSPECTOR_PORT__ = ${serverPort};
1687
2530
  mountInspector({
1688
- serverUrl: 'http://127.0.0.1:' + window.__AI_INSPECTOR_PORT__,
2531
+ serverUrl: 'http://0.0.0.0:' + window.__AI_INSPECTOR_PORT__,
1689
2532
  });
1690
2533
  `;
1691
2534
  }
@@ -1819,7 +2662,9 @@ var src_default = InspectoPlugin;
1819
2662
  esbuildPlugin,
1820
2663
  rollupPlugin,
1821
2664
  rspackPlugin,
2665
+ transformAstro,
1822
2666
  transformJsx,
2667
+ transformRouter,
1823
2668
  unplugin,
1824
2669
  vitePlugin,
1825
2670
  webpackPlugin