@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.
- package/README.md +2 -1
- package/dist/astro.cjs +2687 -0
- package/dist/astro.cjs.map +1 -0
- package/dist/astro.d.cts +17 -0
- package/dist/astro.d.ts +17 -0
- package/dist/astro.js +2656 -0
- package/dist/astro.js.map +1 -0
- package/dist/index.cjs +932 -87
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +22 -1
- package/dist/index.d.ts +22 -1
- package/dist/index.js +930 -87
- package/dist/index.js.map +1 -1
- package/dist/legacy/rspack/index.cjs +530 -89
- package/dist/legacy/rspack/index.cjs.map +1 -1
- package/dist/legacy/rspack/index.js +530 -89
- package/dist/legacy/rspack/index.js.map +1 -1
- package/dist/legacy/rspack/loader.cjs +407 -3
- package/dist/legacy/rspack/loader.cjs.map +1 -1
- package/dist/legacy/rspack/loader.js +403 -3
- package/dist/legacy/rspack/loader.js.map +1 -1
- package/dist/legacy/webpack4/index.cjs +519 -78
- package/dist/legacy/webpack4/index.cjs.map +1 -1
- package/dist/legacy/webpack4/index.js +519 -78
- package/dist/legacy/webpack4/index.js.map +1 -1
- package/dist/legacy/webpack4/loader.cjs +407 -3
- package/dist/legacy/webpack4/loader.cjs.map +1 -1
- package/dist/legacy/webpack4/loader.js +403 -3
- package/dist/legacy/webpack4/loader.js.map +1 -1
- package/dist/rollup.cjs +932 -87
- package/dist/rollup.cjs.map +1 -1
- package/dist/rollup.d.cts +1 -1
- package/dist/rollup.d.ts +1 -1
- package/dist/rollup.js +930 -87
- package/dist/rollup.js.map +1 -1
- package/dist/rspack.cjs +932 -87
- package/dist/rspack.cjs.map +1 -1
- package/dist/rspack.d.cts +1 -1
- package/dist/rspack.d.ts +1 -1
- package/dist/rspack.js +930 -87
- package/dist/rspack.js.map +1 -1
- package/dist/vite.cjs +932 -87
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.d.cts +1 -1
- package/dist/vite.d.ts +1 -1
- package/dist/vite.js +930 -87
- package/dist/vite.js.map +1 -1
- package/dist/webpack.cjs +932 -87
- package/dist/webpack.cjs.map +1 -1
- package/dist/webpack.d.cts +1 -1
- package/dist/webpack.d.ts +1 -1
- package/dist/webpack.js +930 -87
- package/dist/webpack.js.map +1 -1
- package/package.json +13 -10
package/dist/vite.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
-
get: (a,
|
|
2
|
+
get: (a, b2) => (typeof require !== "undefined" ? require : a)[b2]
|
|
3
3
|
}) : x)(function(x) {
|
|
4
4
|
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
5
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
@@ -80,14 +80,14 @@ function extractTransformFilePath(requestId) {
|
|
|
80
80
|
wrapped: filePath !== requestId
|
|
81
81
|
};
|
|
82
82
|
}
|
|
83
|
-
function shouldTransform(filePath,
|
|
83
|
+
function shouldTransform(filePath, _options) {
|
|
84
84
|
const resolvedFilePath = extractTransformFilePath(filePath).filePath;
|
|
85
85
|
if (process.env["NODE_ENV"] === "production") return false;
|
|
86
86
|
if (resolvedFilePath.includes("node_modules")) return false;
|
|
87
87
|
if (resolvedFilePath.startsWith("\0")) return false;
|
|
88
88
|
if (/[/\\](dist|build|\.next|\.nuxt)[/\\]/.test(resolvedFilePath)) return false;
|
|
89
89
|
const ext = resolvedFilePath.split(".").pop()?.toLowerCase();
|
|
90
|
-
if (ext && !["js", "jsx", "ts", "tsx", "mjs", "mts", "vue"].includes(ext)) {
|
|
90
|
+
if (ext && !["js", "jsx", "ts", "tsx", "mjs", "mts", "vue", "svelte", "astro"].includes(ext)) {
|
|
91
91
|
return false;
|
|
92
92
|
}
|
|
93
93
|
return true;
|
|
@@ -248,7 +248,7 @@ function transformVue(options) {
|
|
|
248
248
|
if (escapeTagsSet.has(tagName)) return;
|
|
249
249
|
if (tagName === "template" && node === ast.children[0]) return;
|
|
250
250
|
const alreadyHasAttr = node.props.some(
|
|
251
|
-
(
|
|
251
|
+
(p2) => p2.type === NodeTypes.ATTRIBUTE && p2.name === attributeName
|
|
252
252
|
);
|
|
253
253
|
if (alreadyHasAttr) return;
|
|
254
254
|
const loc = node.loc;
|
|
@@ -285,6 +285,387 @@ function walkElement(node, visitor) {
|
|
|
285
285
|
}
|
|
286
286
|
}
|
|
287
287
|
|
|
288
|
+
// src/transform/transform-svelte.ts
|
|
289
|
+
import MagicString3 from "magic-string";
|
|
290
|
+
import { parse as parseSvelte } from "svelte/compiler";
|
|
291
|
+
function walk(node, visitor) {
|
|
292
|
+
if (!node || typeof node !== "object") return;
|
|
293
|
+
visitor.enter(node);
|
|
294
|
+
for (const key in node) {
|
|
295
|
+
if (key === "parent" || key === "prev" || key === "next") continue;
|
|
296
|
+
const value = node[key];
|
|
297
|
+
if (Array.isArray(value)) {
|
|
298
|
+
value.forEach((child) => {
|
|
299
|
+
if (child && typeof child === "object") walk(child, visitor);
|
|
300
|
+
});
|
|
301
|
+
} else if (value && typeof value === "object") {
|
|
302
|
+
walk(value, visitor);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
function transformSvelte(options) {
|
|
307
|
+
const { filePath, source, escapeTags, attributeName = "data-inspecto" } = options;
|
|
308
|
+
const escapeTagsSet = buildEscapeTagsSet(escapeTags);
|
|
309
|
+
let replacedContent = source;
|
|
310
|
+
const scriptRegex = /<script(?:\s+[a-zA-Z-]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^>\s]*))?)?>[\s\S]*?<\/script>/gi;
|
|
311
|
+
const styleRegex = /<style(?:\s+[a-zA-Z-]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^>\s]*))?)?>[\s\S]*?<\/style>/gi;
|
|
312
|
+
const scriptMatches = source.match(scriptRegex) || [];
|
|
313
|
+
const styleMatches = source.match(styleRegex) || [];
|
|
314
|
+
[...scriptMatches, ...styleMatches].forEach((match) => {
|
|
315
|
+
replacedContent = replacedContent.replace(match, " ".repeat(match.length));
|
|
316
|
+
});
|
|
317
|
+
let ast;
|
|
318
|
+
try {
|
|
319
|
+
ast = parseSvelte(replacedContent);
|
|
320
|
+
} catch {
|
|
321
|
+
return { code: source, map: null, changed: false };
|
|
322
|
+
}
|
|
323
|
+
const s2 = new MagicString3(source);
|
|
324
|
+
let changed = false;
|
|
325
|
+
function countLines(text, position) {
|
|
326
|
+
let lines = 0;
|
|
327
|
+
for (let i2 = 0; i2 < position; i2++) {
|
|
328
|
+
if (text[i2] === "\n") lines++;
|
|
329
|
+
}
|
|
330
|
+
return lines;
|
|
331
|
+
}
|
|
332
|
+
const root = ast.html || ast.fragment || ast;
|
|
333
|
+
walk(root, {
|
|
334
|
+
enter(node) {
|
|
335
|
+
if (node.type === "Element" || node.type === "RegularElement" || node.type === "InlineComponent" || node.type === "Component") {
|
|
336
|
+
const tagName = node.name || "";
|
|
337
|
+
if (tagName && !escapeTagsSet.has(tagName.toLowerCase()) && !node.attributes?.some((attr) => attr.name === attributeName)) {
|
|
338
|
+
const insertPosition = node.start + tagName.length + 1;
|
|
339
|
+
const line = countLines(source, node.start) + 1;
|
|
340
|
+
const lastNewLine = source.lastIndexOf("\n", node.start - 1);
|
|
341
|
+
const column = lastNewLine === -1 ? node.start + 1 : node.start - lastNewLine;
|
|
342
|
+
const attrValue = formatAttrValue(filePath, line, column);
|
|
343
|
+
const addition = ` ${attributeName}="${attrValue}"`;
|
|
344
|
+
s2.appendLeft(insertPosition, addition);
|
|
345
|
+
changed = true;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
});
|
|
350
|
+
return {
|
|
351
|
+
code: s2.toString(),
|
|
352
|
+
map: changed ? s2.generateMap({ source: filePath, includeContent: true }) : null,
|
|
353
|
+
changed
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// src/transform/transform-astro.ts
|
|
358
|
+
import MagicString4 from "magic-string";
|
|
359
|
+
|
|
360
|
+
// ../../node_modules/.pnpm/@astrojs+compiler@3.0.1/node_modules/@astrojs/compiler/dist/chunk-W5DTLHV4.js
|
|
361
|
+
import g from "crypto";
|
|
362
|
+
import _ from "fs";
|
|
363
|
+
import { TextDecoder as b, TextEncoder as v } from "util";
|
|
364
|
+
globalThis.fs || Object.defineProperty(globalThis, "fs", { value: _ });
|
|
365
|
+
globalThis.process || Object.defineProperties(globalThis, "process", { value: process });
|
|
366
|
+
globalThis.crypto || Object.defineProperty(globalThis, "crypto", { value: g.webcrypto ? g.webcrypto : { getRandomValues(m2) {
|
|
367
|
+
return g.randomFillSync(m2);
|
|
368
|
+
} } });
|
|
369
|
+
globalThis.performance || Object.defineProperty(globalThis, "performance", { value: { now() {
|
|
370
|
+
let [m2, o] = process.hrtime();
|
|
371
|
+
return m2 * 1e3 + o / 1e6;
|
|
372
|
+
} } });
|
|
373
|
+
var y = new v("utf-8");
|
|
374
|
+
var w = new b("utf-8");
|
|
375
|
+
var d = class {
|
|
376
|
+
constructor() {
|
|
377
|
+
this.argv = ["js"], this.env = {}, this.exit = (t) => {
|
|
378
|
+
t !== 0 && console.warn("exit code:", t);
|
|
379
|
+
}, this._exitPromise = new Promise((t) => {
|
|
380
|
+
this._resolveExitPromise = t;
|
|
381
|
+
}), this._pendingEvent = null, this._scheduledTimeouts = /* @__PURE__ */ new Map(), this._nextCallbackTimeoutID = 1;
|
|
382
|
+
let o = (t, e) => {
|
|
383
|
+
this.mem.setUint32(t + 0, e, true), this.mem.setUint32(t + 4, Math.floor(e / 4294967296), true);
|
|
384
|
+
}, n = (t) => {
|
|
385
|
+
let e = this.mem.getUint32(t + 0, true), s2 = this.mem.getInt32(t + 4, true);
|
|
386
|
+
return e + s2 * 4294967296;
|
|
387
|
+
}, r = (t) => {
|
|
388
|
+
let e = this.mem.getFloat64(t, true);
|
|
389
|
+
if (e === 0) return;
|
|
390
|
+
if (!isNaN(e)) return e;
|
|
391
|
+
let s2 = this.mem.getUint32(t, true);
|
|
392
|
+
return this._values[s2];
|
|
393
|
+
}, l = (t, e) => {
|
|
394
|
+
if (typeof e == "number" && e !== 0) {
|
|
395
|
+
if (isNaN(e)) {
|
|
396
|
+
this.mem.setUint32(t + 4, 2146959360, true), this.mem.setUint32(t, 0, true);
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
this.mem.setFloat64(t, e, true);
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
if (e === void 0) {
|
|
403
|
+
this.mem.setFloat64(t, 0, true);
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
let i2 = this._ids.get(e);
|
|
407
|
+
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]++;
|
|
408
|
+
let a = 0;
|
|
409
|
+
switch (typeof e) {
|
|
410
|
+
case "object":
|
|
411
|
+
e !== null && (a = 1);
|
|
412
|
+
break;
|
|
413
|
+
case "string":
|
|
414
|
+
a = 2;
|
|
415
|
+
break;
|
|
416
|
+
case "symbol":
|
|
417
|
+
a = 3;
|
|
418
|
+
break;
|
|
419
|
+
case "function":
|
|
420
|
+
a = 4;
|
|
421
|
+
break;
|
|
422
|
+
}
|
|
423
|
+
this.mem.setUint32(t + 4, 2146959360 | a, true), this.mem.setUint32(t, i2, true);
|
|
424
|
+
}, c = (t) => {
|
|
425
|
+
let e = n(t + 0), s2 = n(t + 8);
|
|
426
|
+
return new Uint8Array(this._inst.exports.mem.buffer, e, s2);
|
|
427
|
+
}, f2 = (t) => {
|
|
428
|
+
let e = n(t + 0), s2 = n(t + 8), i2 = new Array(s2);
|
|
429
|
+
for (let a = 0; a < s2; a++) i2[a] = r(e + a * 8);
|
|
430
|
+
return i2;
|
|
431
|
+
}, u = (t) => {
|
|
432
|
+
let e = n(t + 0), s2 = n(t + 8);
|
|
433
|
+
return w.decode(new DataView(this._inst.exports.mem.buffer, e, s2));
|
|
434
|
+
}, h = Date.now() - performance.now();
|
|
435
|
+
this.importObject = { gojs: { "runtime.wasmExit": (t) => {
|
|
436
|
+
t >>>= 0;
|
|
437
|
+
let e = this.mem.getInt32(t + 8, true);
|
|
438
|
+
this.exited = true, delete this._inst, delete this._values, delete this._goRefCounts, delete this._ids, delete this._idPool, this.exit(e);
|
|
439
|
+
}, "runtime.wasmWrite": (t) => {
|
|
440
|
+
t >>>= 0;
|
|
441
|
+
let e = n(t + 8), s2 = n(t + 16), i2 = this.mem.getInt32(t + 24, true);
|
|
442
|
+
_.writeSync(e, new Uint8Array(this._inst.exports.mem.buffer, s2, i2));
|
|
443
|
+
}, "runtime.resetMemoryDataView": (t) => {
|
|
444
|
+
t >>>= 0, this.mem = new DataView(this._inst.exports.mem.buffer);
|
|
445
|
+
}, "runtime.nanotime1": (t) => {
|
|
446
|
+
t >>>= 0, o(t + 8, (h + performance.now()) * 1e6);
|
|
447
|
+
}, "runtime.walltime": (t) => {
|
|
448
|
+
t >>>= 0;
|
|
449
|
+
let e = (/* @__PURE__ */ new Date()).getTime();
|
|
450
|
+
o(t + 8, e / 1e3), this.mem.setInt32(t + 16, e % 1e3 * 1e6, true);
|
|
451
|
+
}, "runtime.scheduleTimeoutEvent": (t) => {
|
|
452
|
+
t >>>= 0;
|
|
453
|
+
let e = this._nextCallbackTimeoutID;
|
|
454
|
+
this._nextCallbackTimeoutID++, this._scheduledTimeouts.set(e, setTimeout(() => {
|
|
455
|
+
for (this._resume(); this._scheduledTimeouts.has(e); ) console.warn("scheduleTimeoutEvent: missed timeout event"), this._resume();
|
|
456
|
+
}, n(t + 8) + 1)), this.mem.setInt32(t + 16, e, true);
|
|
457
|
+
}, "runtime.clearTimeoutEvent": (t) => {
|
|
458
|
+
t >>>= 0;
|
|
459
|
+
let e = this.mem.getInt32(t + 8, true);
|
|
460
|
+
clearTimeout(this._scheduledTimeouts.get(e)), this._scheduledTimeouts.delete(e);
|
|
461
|
+
}, "runtime.getRandomData": (t) => {
|
|
462
|
+
t >>>= 0, globalThis.crypto.getRandomValues(c(t + 8));
|
|
463
|
+
}, "syscall/js.finalizeRef": (t) => {
|
|
464
|
+
t >>>= 0;
|
|
465
|
+
let e = this.mem.getUint32(t + 8, true);
|
|
466
|
+
if (this._goRefCounts[e]--, this._goRefCounts[e] === 0) {
|
|
467
|
+
let s2 = this._values[e];
|
|
468
|
+
this._values[e] = null, this._ids.delete(s2), this._idPool.push(e);
|
|
469
|
+
}
|
|
470
|
+
}, "syscall/js.stringVal": (t) => {
|
|
471
|
+
t >>>= 0, l(t + 24, u(t + 8));
|
|
472
|
+
}, "syscall/js.valueGet": (t) => {
|
|
473
|
+
t >>>= 0;
|
|
474
|
+
let e = Reflect.get(r(t + 8), u(t + 16));
|
|
475
|
+
t = this._inst.exports.getsp() >>> 0, l(t + 32, e);
|
|
476
|
+
}, "syscall/js.valueSet": (t) => {
|
|
477
|
+
t >>>= 0, Reflect.set(r(t + 8), u(t + 16), r(t + 32));
|
|
478
|
+
}, "syscall/js.valueDelete": (t) => {
|
|
479
|
+
t >>>= 0, Reflect.deleteProperty(r(t + 8), u(t + 16));
|
|
480
|
+
}, "syscall/js.valueIndex": (t) => {
|
|
481
|
+
t >>>= 0, l(t + 24, Reflect.get(r(t + 8), n(t + 16)));
|
|
482
|
+
}, "syscall/js.valueSetIndex": (t) => {
|
|
483
|
+
t >>>= 0, Reflect.set(r(t + 8), n(t + 16), r(t + 24));
|
|
484
|
+
}, "syscall/js.valueCall": (t) => {
|
|
485
|
+
t >>>= 0;
|
|
486
|
+
try {
|
|
487
|
+
let e = r(t + 8), s2 = Reflect.get(e, u(t + 16)), i2 = f2(t + 32), a = Reflect.apply(s2, e, i2);
|
|
488
|
+
t = this._inst.exports.getsp() >>> 0, l(t + 56, a), this.mem.setUint8(t + 64, 1);
|
|
489
|
+
} catch (e) {
|
|
490
|
+
t = this._inst.exports.getsp() >>> 0, l(t + 56, e), this.mem.setUint8(t + 64, 0);
|
|
491
|
+
}
|
|
492
|
+
}, "syscall/js.valueInvoke": (t) => {
|
|
493
|
+
t >>>= 0;
|
|
494
|
+
try {
|
|
495
|
+
let e = r(t + 8), s2 = f2(t + 16), i2 = Reflect.apply(e, void 0, s2);
|
|
496
|
+
t = this._inst.exports.getsp() >>> 0, l(t + 40, i2), this.mem.setUint8(t + 48, 1);
|
|
497
|
+
} catch (e) {
|
|
498
|
+
t = this._inst.exports.getsp() >>> 0, l(t + 40, e), this.mem.setUint8(t + 48, 0);
|
|
499
|
+
}
|
|
500
|
+
}, "syscall/js.valueNew": (t) => {
|
|
501
|
+
t >>>= 0;
|
|
502
|
+
try {
|
|
503
|
+
let e = r(t + 8), s2 = f2(t + 16), i2 = Reflect.construct(e, s2);
|
|
504
|
+
t = this._inst.exports.getsp() >>> 0, l(t + 40, i2), this.mem.setUint8(t + 48, 1);
|
|
505
|
+
} catch (e) {
|
|
506
|
+
t = this._inst.exports.getsp() >>> 0, l(t + 40, e), this.mem.setUint8(t + 48, 0);
|
|
507
|
+
}
|
|
508
|
+
}, "syscall/js.valueLength": (t) => {
|
|
509
|
+
t >>>= 0, o(t + 16, Number.parseInt(r(t + 8).length));
|
|
510
|
+
}, "syscall/js.valuePrepareString": (t) => {
|
|
511
|
+
t >>>= 0;
|
|
512
|
+
let e = y.encode(String(r(t + 8)));
|
|
513
|
+
l(t + 16, e), o(t + 24, e.length);
|
|
514
|
+
}, "syscall/js.valueLoadString": (t) => {
|
|
515
|
+
t >>>= 0;
|
|
516
|
+
let e = r(t + 8);
|
|
517
|
+
c(t + 16).set(e);
|
|
518
|
+
}, "syscall/js.valueInstanceOf": (t) => {
|
|
519
|
+
t >>>= 0, this.mem.setUint8(t + 24, r(t + 8) instanceof r(t + 16) ? 1 : 0);
|
|
520
|
+
}, "syscall/js.copyBytesToGo": (t) => {
|
|
521
|
+
t >>>= 0;
|
|
522
|
+
let e = c(t + 8), s2 = r(t + 32);
|
|
523
|
+
if (!(s2 instanceof Uint8Array || s2 instanceof Uint8ClampedArray)) {
|
|
524
|
+
this.mem.setUint8(t + 48, 0);
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
527
|
+
let i2 = s2.subarray(0, e.length);
|
|
528
|
+
e.set(i2), o(t + 40, i2.length), this.mem.setUint8(t + 48, 1);
|
|
529
|
+
}, "syscall/js.copyBytesToJS": (t) => {
|
|
530
|
+
t >>>= 0;
|
|
531
|
+
let e = r(t + 8), s2 = c(t + 16);
|
|
532
|
+
if (!(e instanceof Uint8Array || e instanceof Uint8ClampedArray)) {
|
|
533
|
+
this.mem.setUint8(t + 48, 0);
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
let i2 = s2.subarray(0, e.length);
|
|
537
|
+
e.set(i2), o(t + 40, i2.length), this.mem.setUint8(t + 48, 1);
|
|
538
|
+
}, debug: (t) => {
|
|
539
|
+
console.log(t);
|
|
540
|
+
} } };
|
|
541
|
+
}
|
|
542
|
+
async run(o) {
|
|
543
|
+
if (!(o instanceof WebAssembly.Instance)) throw new Error("Go.run: WebAssembly.Instance expected");
|
|
544
|
+
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;
|
|
545
|
+
let n = 4096, r = (h) => {
|
|
546
|
+
let t = n, e = y.encode(`${h}\0`);
|
|
547
|
+
return new Uint8Array(this.mem.buffer, n, e.length).set(e), n += e.length, n % 8 !== 0 && (n += 8 - n % 8), t;
|
|
548
|
+
}, l = this.argv.length, c = [];
|
|
549
|
+
this.argv.forEach((h) => {
|
|
550
|
+
c.push(r(h));
|
|
551
|
+
}), c.push(0), Object.keys(this.env).sort().forEach((h) => {
|
|
552
|
+
c.push(r(`${h}=${this.env[h]}`));
|
|
553
|
+
}), c.push(0);
|
|
554
|
+
let u = n;
|
|
555
|
+
c.forEach((h) => {
|
|
556
|
+
this.mem.setUint32(n, h, true), this.mem.setUint32(n + 4, 0, true), n += 8;
|
|
557
|
+
}), this._inst.exports.run(l, u), this.exited && this._resolveExitPromise(), await this._exitPromise;
|
|
558
|
+
}
|
|
559
|
+
_resume() {
|
|
560
|
+
if (this.exited) throw new Error("Go program has already exited");
|
|
561
|
+
this._inst.exports.resume(), this.exited && this._resolveExitPromise();
|
|
562
|
+
}
|
|
563
|
+
_makeFuncWrapper(o) {
|
|
564
|
+
let n = this;
|
|
565
|
+
return function() {
|
|
566
|
+
let r = { id: o, this: this, args: arguments };
|
|
567
|
+
return n._pendingEvent = r, n._resume(), r.result;
|
|
568
|
+
};
|
|
569
|
+
}
|
|
570
|
+
};
|
|
571
|
+
|
|
572
|
+
// ../../node_modules/.pnpm/@astrojs+compiler@3.0.1/node_modules/@astrojs/compiler/dist/node/sync.js
|
|
573
|
+
import { readFileSync as p } from "fs";
|
|
574
|
+
import { fileURLToPath as m } from "url";
|
|
575
|
+
function i() {
|
|
576
|
+
return s || (s = f()), s;
|
|
577
|
+
}
|
|
578
|
+
var s;
|
|
579
|
+
var w2 = (e, t) => i().parse(e, t);
|
|
580
|
+
function f() {
|
|
581
|
+
let e = new d(), t = v2(m(new URL("../astro.wasm", import.meta.url)), e.importObject);
|
|
582
|
+
e.run(t);
|
|
583
|
+
let o = globalThis["@astrojs/compiler"];
|
|
584
|
+
return { transform: (n, a) => {
|
|
585
|
+
try {
|
|
586
|
+
return o.transform(n, a || {});
|
|
587
|
+
} catch (r) {
|
|
588
|
+
throw s = void 0, r;
|
|
589
|
+
}
|
|
590
|
+
}, parse: (n, a) => {
|
|
591
|
+
try {
|
|
592
|
+
let r = o.parse(n, a || {});
|
|
593
|
+
return { ...r, ast: JSON.parse(r.ast) };
|
|
594
|
+
} catch (r) {
|
|
595
|
+
throw s = void 0, r;
|
|
596
|
+
}
|
|
597
|
+
}, convertToTSX: (n, a) => {
|
|
598
|
+
try {
|
|
599
|
+
let r = o.convertToTSX(n, a || {});
|
|
600
|
+
return { ...r, map: JSON.parse(r.map) };
|
|
601
|
+
} catch (r) {
|
|
602
|
+
throw s = void 0, r;
|
|
603
|
+
}
|
|
604
|
+
} };
|
|
605
|
+
}
|
|
606
|
+
function v2(e, t) {
|
|
607
|
+
let o = p(e);
|
|
608
|
+
return new WebAssembly.Instance(new WebAssembly.Module(o), t);
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
// src/transform/transform-astro.ts
|
|
612
|
+
function walk2(node, visitor) {
|
|
613
|
+
if (!node || typeof node !== "object") return;
|
|
614
|
+
visitor.enter(node);
|
|
615
|
+
if (Array.isArray(node.children)) {
|
|
616
|
+
for (const child of node.children) {
|
|
617
|
+
walk2(child, visitor);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
function transformAstro(options) {
|
|
622
|
+
const { filePath, source, escapeTags, attributeName = "data-inspecto" } = options;
|
|
623
|
+
const escapeTagsSet = buildEscapeTagsSet(escapeTags);
|
|
624
|
+
let ast;
|
|
625
|
+
try {
|
|
626
|
+
ast = w2(source, { position: true }).ast;
|
|
627
|
+
} catch (_err) {
|
|
628
|
+
return { code: source, map: null, changed: false };
|
|
629
|
+
}
|
|
630
|
+
const s2 = new MagicString4(source);
|
|
631
|
+
let changed = false;
|
|
632
|
+
walk2(ast, {
|
|
633
|
+
enter(node) {
|
|
634
|
+
if (node.type === "element" || node.type === "component") {
|
|
635
|
+
const tagName = node.name;
|
|
636
|
+
if (tagName && !escapeTagsSet.has(tagName) && !node.attributes?.some((attr) => attr.name === attributeName)) {
|
|
637
|
+
const startOffset = node.position?.start?.offset ?? -1;
|
|
638
|
+
if (startOffset === -1) return;
|
|
639
|
+
let tagStartIndex = startOffset;
|
|
640
|
+
while (tagStartIndex >= 0 && source[tagStartIndex] !== "<") {
|
|
641
|
+
tagStartIndex--;
|
|
642
|
+
}
|
|
643
|
+
if (tagStartIndex >= 0) {
|
|
644
|
+
const substringAfterTag = source.substring(tagStartIndex);
|
|
645
|
+
const escapedTagName = tagName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
646
|
+
const strictRegex = new RegExp(`^<\\s*${escapedTagName}(?=\\s|/|>)`, "i");
|
|
647
|
+
const strictMatch = substringAfterTag.match(strictRegex);
|
|
648
|
+
if (strictMatch) {
|
|
649
|
+
const insertPosition = tagStartIndex + strictMatch[0].length;
|
|
650
|
+
const line = node.position.start.line;
|
|
651
|
+
const column = node.position.start.column;
|
|
652
|
+
const attrValue = formatAttrValue(filePath, line, column);
|
|
653
|
+
const addition = ` ${attributeName}="${attrValue}"`;
|
|
654
|
+
s2.appendLeft(insertPosition, addition);
|
|
655
|
+
changed = true;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
});
|
|
662
|
+
return {
|
|
663
|
+
code: s2.toString(),
|
|
664
|
+
map: changed ? s2.generateMap({ source: filePath, includeContent: true }) : null,
|
|
665
|
+
changed
|
|
666
|
+
};
|
|
667
|
+
}
|
|
668
|
+
|
|
288
669
|
// src/transform/index.ts
|
|
289
670
|
function transformRouter(options) {
|
|
290
671
|
const { filePath, source, projectRoot, pluginOptions } = options;
|
|
@@ -309,6 +690,25 @@ function transformRouter(options) {
|
|
|
309
690
|
attributeName: pluginOptions.attributeName
|
|
310
691
|
});
|
|
311
692
|
}
|
|
693
|
+
if (ext === ".svelte") {
|
|
694
|
+
return transformSvelte({
|
|
695
|
+
filePath,
|
|
696
|
+
source,
|
|
697
|
+
projectRoot,
|
|
698
|
+
escapeTags: pluginOptions.escapeTags,
|
|
699
|
+
pathType: pluginOptions.pathType,
|
|
700
|
+
attributeName: pluginOptions.attributeName
|
|
701
|
+
});
|
|
702
|
+
}
|
|
703
|
+
if (ext === ".astro") {
|
|
704
|
+
return transformAstro({
|
|
705
|
+
filePath,
|
|
706
|
+
source,
|
|
707
|
+
escapeTags: pluginOptions.escapeTags,
|
|
708
|
+
pathType: pluginOptions.pathType,
|
|
709
|
+
attributeName: pluginOptions.attributeName
|
|
710
|
+
});
|
|
711
|
+
}
|
|
312
712
|
return null;
|
|
313
713
|
}
|
|
314
714
|
|
|
@@ -451,7 +851,7 @@ function isDebugEnabled(namespace) {
|
|
|
451
851
|
if (typeof process === "undefined" || !process.env) return false;
|
|
452
852
|
const debugEnv = process.env.DEBUG;
|
|
453
853
|
if (!debugEnv) return false;
|
|
454
|
-
const namespaces = debugEnv.split(",").map((
|
|
854
|
+
const namespaces = debugEnv.split(",").map((s2) => s2.trim());
|
|
455
855
|
for (const ns of namespaces) {
|
|
456
856
|
if (ns === "*") return true;
|
|
457
857
|
if (ns.endsWith("*")) {
|
|
@@ -607,7 +1007,7 @@ function readJsonSafely(filePath) {
|
|
|
607
1007
|
}
|
|
608
1008
|
return null;
|
|
609
1009
|
}
|
|
610
|
-
function resolveTargetTool(config,
|
|
1010
|
+
function resolveTargetTool(config, _ide = "vscode") {
|
|
611
1011
|
const defaultProvider = config["provider.default"];
|
|
612
1012
|
if (defaultProvider) {
|
|
613
1013
|
const tool = defaultProvider.split(".")[0];
|
|
@@ -715,7 +1115,7 @@ function resolveIntents(serverPrompts) {
|
|
|
715
1115
|
configLogger.warn(`Intent "${item.id}" is missing required "aiIntent".`);
|
|
716
1116
|
continue;
|
|
717
1117
|
}
|
|
718
|
-
const existingIdx = merged.findIndex((
|
|
1118
|
+
const existingIdx = merged.findIndex((i2) => i2.id === item.id);
|
|
719
1119
|
if (existingIdx !== -1) {
|
|
720
1120
|
if (item.enabled === false) {
|
|
721
1121
|
merged.splice(existingIdx, 1);
|
|
@@ -759,7 +1159,7 @@ function watchConfig(onReload, cwd = process.cwd(), gitRoot) {
|
|
|
759
1159
|
});
|
|
760
1160
|
watcher.unref();
|
|
761
1161
|
watchers.push(watcher);
|
|
762
|
-
} catch (
|
|
1162
|
+
} catch (_e) {
|
|
763
1163
|
}
|
|
764
1164
|
}
|
|
765
1165
|
}
|
|
@@ -827,7 +1227,6 @@ function dispatchPromptThroughIde(runtime, payload) {
|
|
|
827
1227
|
line: payload.line,
|
|
828
1228
|
column: payload.column,
|
|
829
1229
|
snippet: payload.snippet,
|
|
830
|
-
...payload.screenshotContext ? { screenshotContext: payload.screenshotContext } : {},
|
|
831
1230
|
overrides: runtime.overrides,
|
|
832
1231
|
autoSend: runtime.autoSend
|
|
833
1232
|
});
|
|
@@ -961,6 +1360,188 @@ function assertPathWithinIdeOpenScope(file, projectRoot) {
|
|
|
961
1360
|
}
|
|
962
1361
|
}
|
|
963
1362
|
|
|
1363
|
+
// src/server/session-store.ts
|
|
1364
|
+
var DEFAULT_STATUS = "pending";
|
|
1365
|
+
function createAnnotationSessionStore(options = {}) {
|
|
1366
|
+
const sessions = /* @__PURE__ */ new Map();
|
|
1367
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
1368
|
+
const now = options.now ?? (() => Date.now());
|
|
1369
|
+
const createId = options.createId ?? createRandomId;
|
|
1370
|
+
function findNewestMatchingSession(statuses) {
|
|
1371
|
+
return [...sessions.values()].filter((session) => statuses ? statuses.has(session.status) : true).sort((left, right) => right.updatedAt - left.updatedAt)[0] ?? null;
|
|
1372
|
+
}
|
|
1373
|
+
function updateSessionStatus(id, status) {
|
|
1374
|
+
const session = sessions.get(id);
|
|
1375
|
+
if (!session) return null;
|
|
1376
|
+
const timestamp = now();
|
|
1377
|
+
session.status = status;
|
|
1378
|
+
session.updatedAt = timestamp;
|
|
1379
|
+
if (status === "acknowledged") {
|
|
1380
|
+
session.acknowledgedAt = timestamp;
|
|
1381
|
+
}
|
|
1382
|
+
if (status === "resolved") {
|
|
1383
|
+
session.resolvedAt = timestamp;
|
|
1384
|
+
}
|
|
1385
|
+
emit({ type: "session-status-updated", session });
|
|
1386
|
+
return cloneSession(session);
|
|
1387
|
+
}
|
|
1388
|
+
function claimSession(id, statuses) {
|
|
1389
|
+
const session = sessions.get(id);
|
|
1390
|
+
if (!session || statuses && !statuses.has(session.status)) return null;
|
|
1391
|
+
if (session.status === "acknowledged") return cloneSession(session);
|
|
1392
|
+
return updateSessionStatus(id, "acknowledged");
|
|
1393
|
+
}
|
|
1394
|
+
function emit(event) {
|
|
1395
|
+
const snapshot = cloneSession(event.session);
|
|
1396
|
+
for (const listener of listeners) {
|
|
1397
|
+
listener({ type: event.type, session: snapshot });
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
const store = {
|
|
1401
|
+
createSession(input) {
|
|
1402
|
+
const timestamp = now();
|
|
1403
|
+
const session = {
|
|
1404
|
+
id: createId(),
|
|
1405
|
+
instruction: input.instruction?.trim() ?? "",
|
|
1406
|
+
annotations: cloneArray(input.annotations),
|
|
1407
|
+
...input.deliveryMode ? { deliveryMode: input.deliveryMode } : {},
|
|
1408
|
+
status: DEFAULT_STATUS,
|
|
1409
|
+
messages: cloneArray(input.messages ?? []),
|
|
1410
|
+
createdAt: timestamp,
|
|
1411
|
+
updatedAt: timestamp,
|
|
1412
|
+
...input.runtimeContext ? { runtimeContext: cloneValue(input.runtimeContext) } : {},
|
|
1413
|
+
...input.cssContextPrompt?.trim() ? { cssContextPrompt: input.cssContextPrompt.trim() } : {},
|
|
1414
|
+
...input.pageUrl ? { pageUrl: input.pageUrl } : {},
|
|
1415
|
+
...input.route ? { route: input.route } : {}
|
|
1416
|
+
};
|
|
1417
|
+
sessions.set(session.id, session);
|
|
1418
|
+
emit({ type: "session-created", session });
|
|
1419
|
+
return cloneSession(session);
|
|
1420
|
+
},
|
|
1421
|
+
getSession(id) {
|
|
1422
|
+
const session = sessions.get(id);
|
|
1423
|
+
return session ? cloneSession(session) : null;
|
|
1424
|
+
},
|
|
1425
|
+
listSessions(options2 = {}) {
|
|
1426
|
+
const statuses = normalizeStatuses(options2.status);
|
|
1427
|
+
return [...sessions.values()].filter((session) => statuses ? statuses.has(session.status) : true).sort((left, right) => right.updatedAt - left.updatedAt).map((session) => cloneSession(session));
|
|
1428
|
+
},
|
|
1429
|
+
async claimNextSession(options2 = {}) {
|
|
1430
|
+
const statuses = normalizeStatuses(DEFAULT_STATUS);
|
|
1431
|
+
const existingSession = findNewestMatchingSession(statuses);
|
|
1432
|
+
if (existingSession) {
|
|
1433
|
+
return {
|
|
1434
|
+
session: claimSession(existingSession.id, statuses),
|
|
1435
|
+
timedOut: false,
|
|
1436
|
+
matchedExisting: true
|
|
1437
|
+
};
|
|
1438
|
+
}
|
|
1439
|
+
const timeoutMs = normalizeTimeoutMs(options2.timeoutMs);
|
|
1440
|
+
if (timeoutMs === 0) {
|
|
1441
|
+
return {
|
|
1442
|
+
session: null,
|
|
1443
|
+
timedOut: true,
|
|
1444
|
+
matchedExisting: false
|
|
1445
|
+
};
|
|
1446
|
+
}
|
|
1447
|
+
return await new Promise((resolve2) => {
|
|
1448
|
+
let settled = false;
|
|
1449
|
+
let timeout = null;
|
|
1450
|
+
const finish = (result) => {
|
|
1451
|
+
if (settled) return;
|
|
1452
|
+
settled = true;
|
|
1453
|
+
unsubscribe();
|
|
1454
|
+
if (timeout) {
|
|
1455
|
+
clearTimeout(timeout);
|
|
1456
|
+
}
|
|
1457
|
+
resolve2(result);
|
|
1458
|
+
};
|
|
1459
|
+
const unsubscribe = this.subscribe((event) => {
|
|
1460
|
+
const session = claimSession(event.session.id, statuses);
|
|
1461
|
+
if (!session) return;
|
|
1462
|
+
finish({
|
|
1463
|
+
session,
|
|
1464
|
+
timedOut: false,
|
|
1465
|
+
matchedExisting: false,
|
|
1466
|
+
event: event.type
|
|
1467
|
+
});
|
|
1468
|
+
});
|
|
1469
|
+
if (timeoutMs !== null) {
|
|
1470
|
+
timeout = setTimeout(() => {
|
|
1471
|
+
finish({
|
|
1472
|
+
session: null,
|
|
1473
|
+
timedOut: true,
|
|
1474
|
+
matchedExisting: false
|
|
1475
|
+
});
|
|
1476
|
+
}, timeoutMs);
|
|
1477
|
+
}
|
|
1478
|
+
});
|
|
1479
|
+
},
|
|
1480
|
+
appendMessage(id, input) {
|
|
1481
|
+
const session = sessions.get(id);
|
|
1482
|
+
if (!session) return null;
|
|
1483
|
+
const timestamp = now();
|
|
1484
|
+
session.messages.push({
|
|
1485
|
+
id: createId(),
|
|
1486
|
+
role: input.role,
|
|
1487
|
+
text: input.text,
|
|
1488
|
+
createdAt: timestamp
|
|
1489
|
+
});
|
|
1490
|
+
session.updatedAt = timestamp;
|
|
1491
|
+
if (input.role === "agent" && isPendingLikeStatus(session.status)) {
|
|
1492
|
+
session.status = "in_progress";
|
|
1493
|
+
}
|
|
1494
|
+
emit({ type: "session-message-appended", session });
|
|
1495
|
+
return cloneSession(session);
|
|
1496
|
+
},
|
|
1497
|
+
updateStatus(id, status) {
|
|
1498
|
+
return updateSessionStatus(id, status);
|
|
1499
|
+
},
|
|
1500
|
+
subscribe(listener) {
|
|
1501
|
+
listeners.add(listener);
|
|
1502
|
+
return () => {
|
|
1503
|
+
listeners.delete(listener);
|
|
1504
|
+
};
|
|
1505
|
+
},
|
|
1506
|
+
clear() {
|
|
1507
|
+
sessions.clear();
|
|
1508
|
+
listeners.clear();
|
|
1509
|
+
}
|
|
1510
|
+
};
|
|
1511
|
+
return store;
|
|
1512
|
+
}
|
|
1513
|
+
var annotationSessionStore = createAnnotationSessionStore();
|
|
1514
|
+
function normalizeStatuses(status) {
|
|
1515
|
+
if (!status) return null;
|
|
1516
|
+
return new Set(Array.isArray(status) ? status : [status]);
|
|
1517
|
+
}
|
|
1518
|
+
function normalizeTimeoutMs(value) {
|
|
1519
|
+
if (value === void 0) return null;
|
|
1520
|
+
if (!Number.isFinite(value)) return 0;
|
|
1521
|
+
return Math.max(0, Math.floor(value));
|
|
1522
|
+
}
|
|
1523
|
+
function isPendingLikeStatus(status) {
|
|
1524
|
+
return status === "pending" || status === "acknowledged";
|
|
1525
|
+
}
|
|
1526
|
+
function hasAgentReply(session) {
|
|
1527
|
+
return session.messages.some((message) => message.role === "agent" && Boolean(message.text?.trim()));
|
|
1528
|
+
}
|
|
1529
|
+
function createRandomId() {
|
|
1530
|
+
return `annotation-session-${Math.random().toString(36).slice(2, 10)}`;
|
|
1531
|
+
}
|
|
1532
|
+
function cloneSession(session) {
|
|
1533
|
+
return cloneValue(session);
|
|
1534
|
+
}
|
|
1535
|
+
function cloneArray(value) {
|
|
1536
|
+
return cloneValue(value);
|
|
1537
|
+
}
|
|
1538
|
+
function cloneValue(value) {
|
|
1539
|
+
if (typeof structuredClone === "function") {
|
|
1540
|
+
return structuredClone(value);
|
|
1541
|
+
}
|
|
1542
|
+
return JSON.parse(JSON.stringify(value));
|
|
1543
|
+
}
|
|
1544
|
+
|
|
964
1545
|
// src/server/annotation-dispatch.ts
|
|
965
1546
|
var AnnotationDispatchError = class extends Error {
|
|
966
1547
|
constructor(message, errorCode) {
|
|
@@ -969,20 +1550,30 @@ var AnnotationDispatchError = class extends Error {
|
|
|
969
1550
|
this.errorCode = errorCode;
|
|
970
1551
|
}
|
|
971
1552
|
};
|
|
972
|
-
async function dispatchAnnotationsToAi(req, state) {
|
|
1553
|
+
async function dispatchAnnotationsToAi(req, state, store = annotationSessionStore) {
|
|
973
1554
|
try {
|
|
974
1555
|
validateAnnotationDispatchRequest(req, state);
|
|
975
1556
|
const batch = normalizeAnnotationBatch(req);
|
|
976
1557
|
const prompt = buildAnnotationBatchPrompt(batch);
|
|
1558
|
+
const deliveryMode = normalizeDeliveryMode(req.deliveryMode);
|
|
1559
|
+
const session = store.createSession({
|
|
1560
|
+
instruction: batch.instruction,
|
|
1561
|
+
annotations: toSessionAnnotations(batch.annotations),
|
|
1562
|
+
deliveryMode,
|
|
1563
|
+
...batch.runtimeContext ? { runtimeContext: batch.runtimeContext } : {},
|
|
1564
|
+
...batch.cssContextPrompt ? { cssContextPrompt: batch.cssContextPrompt } : {}
|
|
1565
|
+
});
|
|
977
1566
|
const representativeTarget = batch.annotations[0]?.targets[0];
|
|
978
|
-
const
|
|
979
|
-
return dispatchPromptThroughIde(runtime, {
|
|
1567
|
+
const dispatchResult = deliveryMode === "ide" ? dispatchPromptThroughIde(resolvePromptDispatchRuntime(state), {
|
|
980
1568
|
prompt,
|
|
981
1569
|
...representativeTarget?.file ? { filePath: representativeTarget.file } : {},
|
|
982
1570
|
...representativeTarget?.line ? { line: representativeTarget.line } : {},
|
|
983
|
-
...representativeTarget?.column ? { column: representativeTarget.column } : {}
|
|
984
|
-
|
|
985
|
-
|
|
1571
|
+
...representativeTarget?.column ? { column: representativeTarget.column } : {}
|
|
1572
|
+
}) : { success: true };
|
|
1573
|
+
return {
|
|
1574
|
+
...dispatchResult,
|
|
1575
|
+
session: toSessionSummary(session)
|
|
1576
|
+
};
|
|
986
1577
|
} catch (error) {
|
|
987
1578
|
return {
|
|
988
1579
|
success: false,
|
|
@@ -991,6 +1582,41 @@ async function dispatchAnnotationsToAi(req, state) {
|
|
|
991
1582
|
};
|
|
992
1583
|
}
|
|
993
1584
|
}
|
|
1585
|
+
function normalizeDeliveryMode(input) {
|
|
1586
|
+
return input === "agent" ? "agent" : "ide";
|
|
1587
|
+
}
|
|
1588
|
+
function toSessionAnnotations(annotations) {
|
|
1589
|
+
return annotations.map((annotation) => ({
|
|
1590
|
+
id: `annotation-${annotation.index}`,
|
|
1591
|
+
note: annotation.note,
|
|
1592
|
+
intent: annotation.intent,
|
|
1593
|
+
targets: annotation.targets.map((target, targetIndex) => ({
|
|
1594
|
+
id: `annotation-${annotation.index}-target-${targetIndex + 1}`,
|
|
1595
|
+
label: target.label ?? "Unknown target",
|
|
1596
|
+
location: {
|
|
1597
|
+
file: target.file,
|
|
1598
|
+
line: target.line,
|
|
1599
|
+
column: target.column
|
|
1600
|
+
},
|
|
1601
|
+
...target.selector ? { selector: target.selector } : {},
|
|
1602
|
+
...target.snippet ? { snippet: target.snippet } : {},
|
|
1603
|
+
rect: {
|
|
1604
|
+
x: 0,
|
|
1605
|
+
y: 0,
|
|
1606
|
+
width: 0,
|
|
1607
|
+
height: 0
|
|
1608
|
+
}
|
|
1609
|
+
}))
|
|
1610
|
+
}));
|
|
1611
|
+
}
|
|
1612
|
+
function toSessionSummary(session) {
|
|
1613
|
+
return {
|
|
1614
|
+
id: session.id,
|
|
1615
|
+
status: session.status,
|
|
1616
|
+
createdAt: session.createdAt,
|
|
1617
|
+
updatedAt: session.updatedAt
|
|
1618
|
+
};
|
|
1619
|
+
}
|
|
994
1620
|
function validateAnnotationDispatchRequest(req, state) {
|
|
995
1621
|
if (!req.annotations.length) {
|
|
996
1622
|
throw new AnnotationDispatchError("At least one annotation is required.", "INVALID_REQUEST");
|
|
@@ -1011,9 +1637,7 @@ function validateAnnotationDispatchRequest(req, state) {
|
|
|
1011
1637
|
function normalizeAnnotationBatch(req) {
|
|
1012
1638
|
return {
|
|
1013
1639
|
instruction: req.instruction?.trim() ?? "",
|
|
1014
|
-
responseMode: req.responseMode ?? "unified",
|
|
1015
1640
|
...req.runtimeContext ? { runtimeContext: req.runtimeContext } : {},
|
|
1016
|
-
...req.screenshotContext ? { screenshotContext: req.screenshotContext } : {},
|
|
1017
1641
|
...req.cssContextPrompt?.trim() ? { cssContextPrompt: req.cssContextPrompt.trim() } : {},
|
|
1018
1642
|
annotations: req.annotations.map((annotation, index) => ({
|
|
1019
1643
|
index: index + 1,
|
|
@@ -1035,12 +1659,9 @@ function buildAnnotationBatchPrompt(batch) {
|
|
|
1035
1659
|
const prompt = batch.instruction ? `${batch.instruction}
|
|
1036
1660
|
|
|
1037
1661
|
${body}` : body;
|
|
1038
|
-
return
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
batch.cssContextPrompt
|
|
1042
|
-
),
|
|
1043
|
-
batch.screenshotContext
|
|
1662
|
+
return appendCssContextSection(
|
|
1663
|
+
appendRuntimeContextSection(prompt, batch.runtimeContext),
|
|
1664
|
+
batch.cssContextPrompt
|
|
1044
1665
|
);
|
|
1045
1666
|
}
|
|
1046
1667
|
function appendCssContextSection(prompt, cssContextPrompt) {
|
|
@@ -1067,20 +1688,6 @@ function buildSelectedElementsPrompt(annotations) {
|
|
|
1067
1688
|
}
|
|
1068
1689
|
return lines.join("\n");
|
|
1069
1690
|
}
|
|
1070
|
-
function appendScreenshotContextSection(prompt, screenshotContext) {
|
|
1071
|
-
if (!screenshotContext || !screenshotContext.imageDataUrl && !screenshotContext.imageAssetId) {
|
|
1072
|
-
return prompt;
|
|
1073
|
-
}
|
|
1074
|
-
const lines = [
|
|
1075
|
-
"Visual screenshot context attached:",
|
|
1076
|
-
`- capturedAt=${screenshotContext.capturedAt}`,
|
|
1077
|
-
`- mimeType=${screenshotContext.mimeType}`,
|
|
1078
|
-
...screenshotContext.imageAssetId ? [`- imageAssetId=${screenshotContext.imageAssetId}`] : []
|
|
1079
|
-
];
|
|
1080
|
-
return `${prompt}
|
|
1081
|
-
|
|
1082
|
-
${lines.join("\n")}`;
|
|
1083
|
-
}
|
|
1084
1691
|
function appendRuntimeContextSection(prompt, runtimeContext) {
|
|
1085
1692
|
if (!runtimeContext?.records.length) {
|
|
1086
1693
|
return prompt;
|
|
@@ -1128,7 +1735,7 @@ async function buildClientConfig(serverState2) {
|
|
|
1128
1735
|
...info,
|
|
1129
1736
|
prompts: resolveIntents(promptsConfig),
|
|
1130
1737
|
hotKeys: userConfig["inspector.hotKey"] ?? "alt",
|
|
1131
|
-
|
|
1738
|
+
annotateDeliveryMode: userConfig["annotate.deliveryMode"] ?? "both",
|
|
1132
1739
|
includeSnippet: userConfig["prompt.includeSnippet"] ?? false,
|
|
1133
1740
|
runtimeContext: {
|
|
1134
1741
|
enabled: true,
|
|
@@ -1136,10 +1743,6 @@ async function buildClientConfig(serverState2) {
|
|
|
1136
1743
|
maxRuntimeErrors: 3,
|
|
1137
1744
|
maxFailedRequests: 2
|
|
1138
1745
|
},
|
|
1139
|
-
screenshotContext: {
|
|
1140
|
-
enabled: false
|
|
1141
|
-
},
|
|
1142
|
-
annotationResponseMode: userConfig["prompt.annotationResponseMode"] ?? "unified",
|
|
1143
1746
|
autoSend: userConfig["prompt.autoSend"] ?? false
|
|
1144
1747
|
};
|
|
1145
1748
|
}
|
|
@@ -1184,7 +1787,7 @@ function handleOpenFileRequest(body, serverState2) {
|
|
|
1184
1787
|
else if (rawEditorHint === "vscodium") editorHint = "codium";
|
|
1185
1788
|
else if (rawEditorHint === "trae-cn" || rawEditorHint === "trae") editorHint = "trae";
|
|
1186
1789
|
serverLogger2.debug(
|
|
1187
|
-
`
|
|
1790
|
+
`SOURCE_OPEN: activeIde=${activeIde}, activeIdeScheme=${activeIdeScheme}, configuredIde=${configuredIde} -> rawEditorHint=${rawEditorHint}, finalEditorHint=${editorHint}`
|
|
1188
1791
|
);
|
|
1189
1792
|
if (VSCODE_FAMILY_SCHEMES.includes(rawEditorHint)) {
|
|
1190
1793
|
let normalizedPath = absolutePath.replace(/\\/g, "/");
|
|
@@ -1193,7 +1796,7 @@ function handleOpenFileRequest(body, serverState2) {
|
|
|
1193
1796
|
}
|
|
1194
1797
|
const encodedPath = encodeURI(normalizedPath);
|
|
1195
1798
|
const uri = `${rawEditorHint}://file${encodedPath}:${body.line}:${body.column}`;
|
|
1196
|
-
serverLogger2.debug(`
|
|
1799
|
+
serverLogger2.debug(`SOURCE_OPEN: Bypassing launchIDE, using URI scheme directly: ${uri}`);
|
|
1197
1800
|
try {
|
|
1198
1801
|
if (process.platform === "darwin") {
|
|
1199
1802
|
execFileSync2("open", [uri]);
|
|
@@ -1203,7 +1806,7 @@ function handleOpenFileRequest(body, serverState2) {
|
|
|
1203
1806
|
execFileSync2("xdg-open", [uri]);
|
|
1204
1807
|
}
|
|
1205
1808
|
} catch (e) {
|
|
1206
|
-
serverLogger2.error(`Failed to launch URI for
|
|
1809
|
+
serverLogger2.error(`Failed to launch URI for SOURCE_OPEN (${uri}):`, e);
|
|
1207
1810
|
launchIDE2({
|
|
1208
1811
|
file: absolutePath,
|
|
1209
1812
|
line: body.line,
|
|
@@ -1260,6 +1863,7 @@ function resolveProjectRoot() {
|
|
|
1260
1863
|
|
|
1261
1864
|
// src/server/index.ts
|
|
1262
1865
|
var serverLogger4 = createLogger("inspecto:server", { logLevel: getGlobalLogLevel() });
|
|
1866
|
+
var PORT_FILE_NAME = "inspecto.port.json";
|
|
1263
1867
|
var serverState = {
|
|
1264
1868
|
port: null,
|
|
1265
1869
|
running: false,
|
|
@@ -1268,6 +1872,42 @@ var serverState = {
|
|
|
1268
1872
|
cwd: process.cwd()
|
|
1269
1873
|
};
|
|
1270
1874
|
var serverInstance = null;
|
|
1875
|
+
function getPortFilePath() {
|
|
1876
|
+
return path8.join(os2.tmpdir(), PORT_FILE_NAME);
|
|
1877
|
+
}
|
|
1878
|
+
function getProjectRootHash() {
|
|
1879
|
+
if (!serverState.projectRoot) return null;
|
|
1880
|
+
return crypto2.createHash("md5").update(serverState.projectRoot).digest("hex");
|
|
1881
|
+
}
|
|
1882
|
+
function readPortData(portFile) {
|
|
1883
|
+
if (!fs5.existsSync(portFile)) return {};
|
|
1884
|
+
try {
|
|
1885
|
+
return JSON.parse(fs5.readFileSync(portFile, "utf-8"));
|
|
1886
|
+
} catch {
|
|
1887
|
+
return {};
|
|
1888
|
+
}
|
|
1889
|
+
}
|
|
1890
|
+
function writeProjectPort(port) {
|
|
1891
|
+
const rootHash = getProjectRootHash();
|
|
1892
|
+
if (!rootHash) return;
|
|
1893
|
+
const portFile = getPortFilePath();
|
|
1894
|
+
const portData = readPortData(portFile);
|
|
1895
|
+
portData[rootHash] = port;
|
|
1896
|
+
fs5.writeFileSync(portFile, JSON.stringify(portData, null, 2), "utf-8");
|
|
1897
|
+
}
|
|
1898
|
+
function removeProjectPort() {
|
|
1899
|
+
const rootHash = getProjectRootHash();
|
|
1900
|
+
if (!rootHash) return;
|
|
1901
|
+
const portFile = getPortFilePath();
|
|
1902
|
+
if (!fs5.existsSync(portFile)) return;
|
|
1903
|
+
const portData = readPortData(portFile);
|
|
1904
|
+
delete portData[rootHash];
|
|
1905
|
+
if (Object.keys(portData).length === 0) {
|
|
1906
|
+
fs5.unlinkSync(portFile);
|
|
1907
|
+
} else {
|
|
1908
|
+
fs5.writeFileSync(portFile, JSON.stringify(portData, null, 2), "utf-8");
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1271
1911
|
async function startServer() {
|
|
1272
1912
|
if (serverState.running && serverState.port !== null) {
|
|
1273
1913
|
return serverState.port;
|
|
@@ -1301,7 +1941,7 @@ async function startServer() {
|
|
|
1301
1941
|
});
|
|
1302
1942
|
});
|
|
1303
1943
|
await new Promise((resolve2, reject) => {
|
|
1304
|
-
serverInstance.listen(port, "
|
|
1944
|
+
serverInstance.listen(port, "0.0.0.0", () => {
|
|
1305
1945
|
serverInstance.unref();
|
|
1306
1946
|
resolve2();
|
|
1307
1947
|
});
|
|
@@ -1312,37 +1952,18 @@ async function startServer() {
|
|
|
1312
1952
|
});
|
|
1313
1953
|
serverState.port = port;
|
|
1314
1954
|
serverState.running = true;
|
|
1315
|
-
const portFile = path8.join(os2.tmpdir(), "inspecto.port.json");
|
|
1316
1955
|
try {
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
portData = JSON.parse(fs5.readFileSync(portFile, "utf-8"));
|
|
1321
|
-
} catch (e) {
|
|
1322
|
-
}
|
|
1323
|
-
}
|
|
1324
|
-
const rootHash = crypto2.createHash("md5").update(serverState.projectRoot).digest("hex");
|
|
1325
|
-
portData[rootHash] = port;
|
|
1326
|
-
fs5.writeFileSync(portFile, JSON.stringify(portData, null, 2), "utf-8");
|
|
1327
|
-
} catch (e) {
|
|
1328
|
-
serverLogger4.warn("Failed to write port file:", e);
|
|
1956
|
+
writeProjectPort(port);
|
|
1957
|
+
} catch (_e) {
|
|
1958
|
+
serverLogger4.warn("Failed to write port file:", _e);
|
|
1329
1959
|
}
|
|
1330
1960
|
process.once("exit", () => {
|
|
1331
1961
|
try {
|
|
1332
|
-
|
|
1333
|
-
const portData = JSON.parse(fs5.readFileSync(portFile, "utf-8"));
|
|
1334
|
-
const rootHash = crypto2.createHash("md5").update(serverState.projectRoot).digest("hex");
|
|
1335
|
-
delete portData[rootHash];
|
|
1336
|
-
if (Object.keys(portData).length === 0) {
|
|
1337
|
-
fs5.unlinkSync(portFile);
|
|
1338
|
-
} else {
|
|
1339
|
-
fs5.writeFileSync(portFile, JSON.stringify(portData, null, 2), "utf-8");
|
|
1340
|
-
}
|
|
1341
|
-
}
|
|
1962
|
+
removeProjectPort();
|
|
1342
1963
|
} catch {
|
|
1343
1964
|
}
|
|
1344
1965
|
});
|
|
1345
|
-
serverLogger4.info(`server running at http://
|
|
1966
|
+
serverLogger4.info(`server running at http://0.0.0.0:${port}`);
|
|
1346
1967
|
return port;
|
|
1347
1968
|
}
|
|
1348
1969
|
async function readBody(req) {
|
|
@@ -1394,11 +2015,11 @@ async function handleRequest(url, req, res) {
|
|
|
1394
2015
|
}
|
|
1395
2016
|
return;
|
|
1396
2017
|
}
|
|
1397
|
-
if (pathname === INSPECTO_API_PATHS.IDE_OPEN && req.method === "POST") {
|
|
2018
|
+
if ((pathname === INSPECTO_API_PATHS.SOURCE_OPEN || pathname === INSPECTO_API_PATHS.IDE_OPEN) && req.method === "POST") {
|
|
1398
2019
|
let body;
|
|
1399
2020
|
try {
|
|
1400
2021
|
body = JSON.parse(await readBody(req));
|
|
1401
|
-
} catch (
|
|
2022
|
+
} catch (_e) {
|
|
1402
2023
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
1403
2024
|
res.end(JSON.stringify({ error: "Invalid JSON body" }));
|
|
1404
2025
|
return;
|
|
@@ -1407,7 +2028,7 @@ async function handleRequest(url, req, res) {
|
|
|
1407
2028
|
handleOpenFileRequest(body, serverState);
|
|
1408
2029
|
} catch (err) {
|
|
1409
2030
|
serverLogger4.warn(
|
|
1410
|
-
`Security: Blocked path traversal attempt in
|
|
2031
|
+
`Security: Blocked path traversal attempt in SOURCE_OPEN: ${body.file}. Reason: ${err.message}`
|
|
1411
2032
|
);
|
|
1412
2033
|
res.writeHead(403, { "Content-Type": "application/json" });
|
|
1413
2034
|
res.end(JSON.stringify({ error: "Access denied: File is outside of project workspace" }));
|
|
@@ -1481,6 +2102,212 @@ async function handleRequest(url, req, res) {
|
|
|
1481
2102
|
}
|
|
1482
2103
|
return;
|
|
1483
2104
|
}
|
|
2105
|
+
if (pathname === INSPECTO_API_PATHS.SESSION_CLAIM_NEXT && req.method === "POST") {
|
|
2106
|
+
try {
|
|
2107
|
+
const rawBody = await readBody(req);
|
|
2108
|
+
const body = rawBody ? JSON.parse(rawBody) : {};
|
|
2109
|
+
const timeoutMs = normalizeSessionClaimTimeout(
|
|
2110
|
+
body.timeoutMs === void 0 ? null : String(body.timeoutMs)
|
|
2111
|
+
);
|
|
2112
|
+
const result = await annotationSessionStore.claimNextSession({
|
|
2113
|
+
...timeoutMs !== void 0 ? { timeoutMs } : {}
|
|
2114
|
+
});
|
|
2115
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
2116
|
+
res.end(
|
|
2117
|
+
JSON.stringify({
|
|
2118
|
+
success: true,
|
|
2119
|
+
timedOut: result.timedOut,
|
|
2120
|
+
matchedExisting: result.matchedExisting,
|
|
2121
|
+
...result.event ? { event: result.event } : {},
|
|
2122
|
+
...result.session ? { session: result.session } : {}
|
|
2123
|
+
})
|
|
2124
|
+
);
|
|
2125
|
+
} catch (e) {
|
|
2126
|
+
serverLogger4.error(`Error parsing session claim request:`, e);
|
|
2127
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
2128
|
+
res.end(JSON.stringify({ success: false, error: "Invalid JSON body" }));
|
|
2129
|
+
}
|
|
2130
|
+
return;
|
|
2131
|
+
}
|
|
2132
|
+
if (pathname === INSPECTO_API_PATHS.SESSION_EVENTS && req.method === "GET") {
|
|
2133
|
+
const statusParam = url.searchParams.getAll("status");
|
|
2134
|
+
const statuses = statusParam.length ? new Set(statusParam) : null;
|
|
2135
|
+
const sessionId = url.searchParams.get("sessionId")?.trim() || null;
|
|
2136
|
+
res.writeHead(200, {
|
|
2137
|
+
"Content-Type": "text/event-stream",
|
|
2138
|
+
"Cache-Control": "no-cache",
|
|
2139
|
+
Connection: "keep-alive"
|
|
2140
|
+
});
|
|
2141
|
+
res.write(`event: ready
|
|
2142
|
+
data: ${JSON.stringify({ ok: true })}
|
|
2143
|
+
|
|
2144
|
+
`);
|
|
2145
|
+
const unsubscribe = annotationSessionStore.subscribe((event) => {
|
|
2146
|
+
if (sessionId && event.session.id !== sessionId) {
|
|
2147
|
+
return;
|
|
2148
|
+
}
|
|
2149
|
+
if (statuses && !statuses.has(event.session.status)) {
|
|
2150
|
+
return;
|
|
2151
|
+
}
|
|
2152
|
+
res.write(formatSessionSseEvent(event));
|
|
2153
|
+
});
|
|
2154
|
+
req.on("close", () => {
|
|
2155
|
+
unsubscribe();
|
|
2156
|
+
res.end();
|
|
2157
|
+
});
|
|
2158
|
+
return;
|
|
2159
|
+
}
|
|
2160
|
+
if (pathname === INSPECTO_API_PATHS.SESSIONS && req.method === "GET") {
|
|
2161
|
+
const statusParam = url.searchParams.getAll("status");
|
|
2162
|
+
const sessions = annotationSessionStore.listSessions(
|
|
2163
|
+
statusParam.length ? {
|
|
2164
|
+
status: statusParam
|
|
2165
|
+
} : void 0
|
|
2166
|
+
);
|
|
2167
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
2168
|
+
res.end(JSON.stringify({ success: true, sessions }));
|
|
2169
|
+
return;
|
|
2170
|
+
}
|
|
2171
|
+
if (pathname.startsWith(`${INSPECTO_API_PATHS.SESSIONS}/`) && req.method === "GET") {
|
|
2172
|
+
const sessionId = pathname.substring(INSPECTO_API_PATHS.SESSIONS.length + 1);
|
|
2173
|
+
const session = annotationSessionStore.getSession(sessionId);
|
|
2174
|
+
if (!session) {
|
|
2175
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
2176
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
2177
|
+
return;
|
|
2178
|
+
}
|
|
2179
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
2180
|
+
res.end(JSON.stringify({ success: true, session }));
|
|
2181
|
+
return;
|
|
2182
|
+
}
|
|
2183
|
+
if (pathname.startsWith(`${INSPECTO_API_PATHS.SESSIONS}/`) && pathname.endsWith(INSPECTO_API_PATHS.SESSION_REPLY_SUFFIX) && req.method === "POST") {
|
|
2184
|
+
const sessionId = pathname.slice(
|
|
2185
|
+
INSPECTO_API_PATHS.SESSIONS.length + 1,
|
|
2186
|
+
-INSPECTO_API_PATHS.SESSION_REPLY_SUFFIX.length
|
|
2187
|
+
);
|
|
2188
|
+
try {
|
|
2189
|
+
const rawBody = await readBody(req);
|
|
2190
|
+
const body = JSON.parse(rawBody);
|
|
2191
|
+
if (!isAnnotationThreadRole(body.role)) {
|
|
2192
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
2193
|
+
res.end(JSON.stringify({ success: false, error: "Reply role is invalid." }));
|
|
2194
|
+
return;
|
|
2195
|
+
}
|
|
2196
|
+
if (!body.text?.trim()) {
|
|
2197
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
2198
|
+
res.end(JSON.stringify({ success: false, error: "Reply text is required." }));
|
|
2199
|
+
return;
|
|
2200
|
+
}
|
|
2201
|
+
const session = annotationSessionStore.appendMessage(sessionId, {
|
|
2202
|
+
role: body.role,
|
|
2203
|
+
text: body.text.trim()
|
|
2204
|
+
});
|
|
2205
|
+
if (!session) {
|
|
2206
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
2207
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
2208
|
+
return;
|
|
2209
|
+
}
|
|
2210
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
2211
|
+
res.end(JSON.stringify({ success: true, session }));
|
|
2212
|
+
} catch (e) {
|
|
2213
|
+
serverLogger4.error(`Error parsing session reply request:`, e);
|
|
2214
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
2215
|
+
res.end(JSON.stringify({ success: false, error: "Invalid JSON body" }));
|
|
2216
|
+
}
|
|
2217
|
+
return;
|
|
2218
|
+
}
|
|
2219
|
+
if (pathname.startsWith(`${INSPECTO_API_PATHS.SESSIONS}/`) && pathname.endsWith(INSPECTO_API_PATHS.SESSION_RESOLVE_SUFFIX) && req.method === "POST") {
|
|
2220
|
+
const sessionId = pathname.slice(
|
|
2221
|
+
INSPECTO_API_PATHS.SESSIONS.length + 1,
|
|
2222
|
+
-INSPECTO_API_PATHS.SESSION_RESOLVE_SUFFIX.length
|
|
2223
|
+
);
|
|
2224
|
+
try {
|
|
2225
|
+
const rawBody = await readBody(req);
|
|
2226
|
+
const body = rawBody ? JSON.parse(rawBody) : {};
|
|
2227
|
+
const message = body.message?.trim();
|
|
2228
|
+
const existingSession = annotationSessionStore.getSession(sessionId);
|
|
2229
|
+
if (!existingSession) {
|
|
2230
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
2231
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
2232
|
+
return;
|
|
2233
|
+
}
|
|
2234
|
+
if (!message && !hasAgentReply(existingSession)) {
|
|
2235
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
2236
|
+
res.end(
|
|
2237
|
+
JSON.stringify({
|
|
2238
|
+
success: false,
|
|
2239
|
+
error: "Resolve message is required until an agent reply is recorded."
|
|
2240
|
+
})
|
|
2241
|
+
);
|
|
2242
|
+
return;
|
|
2243
|
+
}
|
|
2244
|
+
if (message) {
|
|
2245
|
+
const repliedSession = annotationSessionStore.appendMessage(sessionId, {
|
|
2246
|
+
role: "agent",
|
|
2247
|
+
text: message
|
|
2248
|
+
});
|
|
2249
|
+
if (!repliedSession) {
|
|
2250
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
2251
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
2252
|
+
return;
|
|
2253
|
+
}
|
|
2254
|
+
}
|
|
2255
|
+
const session = annotationSessionStore.updateStatus(sessionId, "resolved");
|
|
2256
|
+
if (!session) {
|
|
2257
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
2258
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
2259
|
+
return;
|
|
2260
|
+
}
|
|
2261
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
2262
|
+
res.end(JSON.stringify({ success: true, session }));
|
|
2263
|
+
} catch (e) {
|
|
2264
|
+
serverLogger4.error(`Error parsing session resolve request:`, e);
|
|
2265
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
2266
|
+
res.end(JSON.stringify({ success: false, error: "Invalid JSON body" }));
|
|
2267
|
+
}
|
|
2268
|
+
return;
|
|
2269
|
+
}
|
|
2270
|
+
if (pathname.startsWith(`${INSPECTO_API_PATHS.SESSIONS}/`) && pathname.endsWith(INSPECTO_API_PATHS.SESSION_DISMISS_SUFFIX) && req.method === "POST") {
|
|
2271
|
+
const sessionId = pathname.slice(
|
|
2272
|
+
INSPECTO_API_PATHS.SESSIONS.length + 1,
|
|
2273
|
+
-INSPECTO_API_PATHS.SESSION_DISMISS_SUFFIX.length
|
|
2274
|
+
);
|
|
2275
|
+
try {
|
|
2276
|
+
const rawBody = await readBody(req);
|
|
2277
|
+
const body = rawBody ? JSON.parse(rawBody) : {};
|
|
2278
|
+
const message = body.message?.trim();
|
|
2279
|
+
const existingSession = annotationSessionStore.getSession(sessionId);
|
|
2280
|
+
if (!existingSession) {
|
|
2281
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
2282
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
2283
|
+
return;
|
|
2284
|
+
}
|
|
2285
|
+
if (message) {
|
|
2286
|
+
const repliedSession = annotationSessionStore.appendMessage(sessionId, {
|
|
2287
|
+
role: "agent",
|
|
2288
|
+
text: message
|
|
2289
|
+
});
|
|
2290
|
+
if (!repliedSession) {
|
|
2291
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
2292
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
2293
|
+
return;
|
|
2294
|
+
}
|
|
2295
|
+
}
|
|
2296
|
+
const session = annotationSessionStore.updateStatus(sessionId, "dismissed");
|
|
2297
|
+
if (!session) {
|
|
2298
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
2299
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
2300
|
+
return;
|
|
2301
|
+
}
|
|
2302
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
2303
|
+
res.end(JSON.stringify({ success: true, session }));
|
|
2304
|
+
} catch (e) {
|
|
2305
|
+
serverLogger4.error(`Error parsing session dismiss request:`, e);
|
|
2306
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
2307
|
+
res.end(JSON.stringify({ success: false, error: "Invalid JSON body" }));
|
|
2308
|
+
}
|
|
2309
|
+
return;
|
|
2310
|
+
}
|
|
1484
2311
|
if (pathname.startsWith(`${INSPECTO_API_PATHS.AI_TICKET}/`) && req.method === "GET") {
|
|
1485
2312
|
const ticketId = pathname.substring(INSPECTO_API_PATHS.AI_TICKET.length + 1);
|
|
1486
2313
|
const payloadStr = readTicket(ticketId);
|
|
@@ -1497,7 +2324,7 @@ async function handleRequest(url, req, res) {
|
|
|
1497
2324
|
res.end(JSON.stringify({ error: "not found" }));
|
|
1498
2325
|
}
|
|
1499
2326
|
async function dispatchToAi(req) {
|
|
1500
|
-
const { location, snippet, prompt
|
|
2327
|
+
const { location, snippet, prompt } = req;
|
|
1501
2328
|
const formattedPrompt = prompt ?? `Please help me with this code from \`${location.file}\` (line ${location.line}):
|
|
1502
2329
|
|
|
1503
2330
|
\`\`\`
|
|
@@ -1510,8 +2337,7 @@ ${snippet}
|
|
|
1510
2337
|
filePath: location.file,
|
|
1511
2338
|
line: location.line,
|
|
1512
2339
|
column: location.column,
|
|
1513
|
-
snippet
|
|
1514
|
-
...screenshotContext ? { screenshotContext } : {}
|
|
2340
|
+
snippet
|
|
1515
2341
|
});
|
|
1516
2342
|
}
|
|
1517
2343
|
function getBatchDispatchStatusCode(errorCode, success) {
|
|
@@ -1520,6 +2346,21 @@ function getBatchDispatchStatusCode(errorCode, success) {
|
|
|
1520
2346
|
if (errorCode === "FORBIDDEN_PATH") return 403;
|
|
1521
2347
|
return 500;
|
|
1522
2348
|
}
|
|
2349
|
+
function isAnnotationThreadRole(value) {
|
|
2350
|
+
return value === "user" || value === "agent" || value === "system";
|
|
2351
|
+
}
|
|
2352
|
+
function formatSessionSseEvent(event) {
|
|
2353
|
+
return `event: ${event.type}
|
|
2354
|
+
data: ${JSON.stringify(event)}
|
|
2355
|
+
|
|
2356
|
+
`;
|
|
2357
|
+
}
|
|
2358
|
+
function normalizeSessionClaimTimeout(value) {
|
|
2359
|
+
if (!value?.trim()) return 3e4;
|
|
2360
|
+
const parsed = Number.parseInt(value, 10);
|
|
2361
|
+
if (!Number.isFinite(parsed)) return 3e4;
|
|
2362
|
+
return Math.max(0, Math.min(parsed, 3e5));
|
|
2363
|
+
}
|
|
1523
2364
|
|
|
1524
2365
|
// src/injectors/utils.ts
|
|
1525
2366
|
import { createRequire } from "module";
|
|
@@ -1542,13 +2383,13 @@ var resolveClientModule = () => {
|
|
|
1542
2383
|
function getWebpackHtmlScript(serverPort) {
|
|
1543
2384
|
return `
|
|
1544
2385
|
window.__AI_INSPECTOR_PORT__ = ${serverPort};
|
|
1545
|
-
window.addEventListener('load', () => {
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
});
|
|
2386
|
+
window.addEventListener('load', () => {
|
|
2387
|
+
if (window.InspectoClient) {
|
|
2388
|
+
window.InspectoClient.mountInspector({
|
|
2389
|
+
serverUrl: 'http://0.0.0.0:' + window.__AI_INSPECTOR_PORT__,
|
|
2390
|
+
});
|
|
2391
|
+
}
|
|
2392
|
+
});
|
|
1552
2393
|
`;
|
|
1553
2394
|
}
|
|
1554
2395
|
function getWebpackAssetScript(serverPort) {
|
|
@@ -1558,7 +2399,7 @@ if (typeof window !== 'undefined') {
|
|
|
1558
2399
|
const _initInspecto = () => {
|
|
1559
2400
|
if (window.InspectoClient) {
|
|
1560
2401
|
window.InspectoClient.mountInspector({
|
|
1561
|
-
serverUrl: 'http://
|
|
2402
|
+
serverUrl: 'http://0.0.0.0:' + window.__AI_INSPECTOR_PORT__,
|
|
1562
2403
|
});
|
|
1563
2404
|
} else {
|
|
1564
2405
|
setTimeout(_initInspecto, 100);
|
|
@@ -1581,7 +2422,7 @@ function injectWebpack(compiler, serverPortFn, resolveClientModule2) {
|
|
|
1581
2422
|
}
|
|
1582
2423
|
compiler.hooks.compilation.tap("inspecto-overlay", (compilation) => {
|
|
1583
2424
|
const HtmlWebpackPlugin = compiler.options.plugins.find(
|
|
1584
|
-
(
|
|
2425
|
+
(p2) => p2 && p2.constructor && p2.constructor.name === "HtmlWebpackPlugin"
|
|
1585
2426
|
);
|
|
1586
2427
|
if (HtmlWebpackPlugin) {
|
|
1587
2428
|
const hooks = HtmlWebpackPlugin.constructor.getHooks(compilation);
|
|
@@ -1625,7 +2466,7 @@ function injectRspack(compiler, serverPortFn, resolveClientModule2) {
|
|
|
1625
2466
|
new compiler.webpack.EntryPlugin(compiler.context, inspectoClientPath, {}).apply(compiler);
|
|
1626
2467
|
compiler.hooks.compilation.tap("inspecto-overlay", (compilation) => {
|
|
1627
2468
|
const HtmlRspackPlugin = compiler.options.plugins.find(
|
|
1628
|
-
(
|
|
2469
|
+
(p2) => p2 && p2.constructor && p2.constructor.name === "HtmlRspackPlugin"
|
|
1629
2470
|
);
|
|
1630
2471
|
if (HtmlRspackPlugin) {
|
|
1631
2472
|
const hooks = HtmlRspackPlugin.constructor.getHooks(compilation);
|
|
@@ -1649,7 +2490,7 @@ function getViteVirtualModuleScript(serverPort) {
|
|
|
1649
2490
|
import { mountInspector } from '@inspecto-dev/core';
|
|
1650
2491
|
window.__AI_INSPECTOR_PORT__ = ${serverPort};
|
|
1651
2492
|
mountInspector({
|
|
1652
|
-
serverUrl: 'http://
|
|
2493
|
+
serverUrl: 'http://0.0.0.0:' + window.__AI_INSPECTOR_PORT__,
|
|
1653
2494
|
});
|
|
1654
2495
|
`;
|
|
1655
2496
|
}
|
|
@@ -1783,7 +2624,9 @@ export {
|
|
|
1783
2624
|
esbuildPlugin,
|
|
1784
2625
|
rollupPlugin,
|
|
1785
2626
|
rspackPlugin,
|
|
2627
|
+
transformAstro,
|
|
1786
2628
|
transformJsx,
|
|
2629
|
+
transformRouter,
|
|
1787
2630
|
unplugin,
|
|
1788
2631
|
vitePlugin,
|
|
1789
2632
|
webpackPlugin
|