@inspecto-dev/plugin 0.3.8 → 0.3.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/astro.cjs +572 -86
- package/dist/astro.cjs.map +1 -1
- package/dist/astro.d.cts +1 -1
- package/dist/astro.d.ts +1 -1
- package/dist/astro.js +571 -85
- package/dist/astro.js.map +1 -1
- package/dist/index.cjs +559 -83
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +558 -82
- package/dist/index.js.map +1 -1
- package/dist/legacy/rspack/index.cjs +526 -74
- package/dist/legacy/rspack/index.cjs.map +1 -1
- package/dist/legacy/rspack/index.js +526 -74
- package/dist/legacy/rspack/index.js.map +1 -1
- package/dist/legacy/rspack/loader.cjs +4 -1
- package/dist/legacy/rspack/loader.cjs.map +1 -1
- package/dist/legacy/rspack/loader.js +3 -0
- package/dist/legacy/rspack/loader.js.map +1 -1
- package/dist/legacy/webpack4/index.cjs +526 -74
- package/dist/legacy/webpack4/index.cjs.map +1 -1
- package/dist/legacy/webpack4/index.js +526 -74
- package/dist/legacy/webpack4/index.js.map +1 -1
- package/dist/legacy/webpack4/loader.cjs +4 -1
- package/dist/legacy/webpack4/loader.cjs.map +1 -1
- package/dist/legacy/webpack4/loader.js +3 -0
- package/dist/legacy/webpack4/loader.js.map +1 -1
- package/dist/rollup.cjs +559 -83
- package/dist/rollup.cjs.map +1 -1
- package/dist/rollup.js +558 -82
- package/dist/rollup.js.map +1 -1
- package/dist/rspack.cjs +559 -83
- package/dist/rspack.cjs.map +1 -1
- package/dist/rspack.js +558 -82
- package/dist/rspack.js.map +1 -1
- package/dist/vite.cjs +559 -83
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.js +558 -82
- package/dist/vite.js.map +1 -1
- package/dist/webpack.cjs +559 -83
- package/dist/webpack.cjs.map +1 -1
- package/dist/webpack.js +558 -82
- package/dist/webpack.js.map +1 -1
- package/package.json +8 -12
package/dist/index.js
CHANGED
|
@@ -694,7 +694,9 @@ function transformRouter(options) {
|
|
|
694
694
|
return transformSvelte({
|
|
695
695
|
filePath,
|
|
696
696
|
source,
|
|
697
|
+
projectRoot,
|
|
697
698
|
escapeTags: pluginOptions.escapeTags,
|
|
699
|
+
pathType: pluginOptions.pathType,
|
|
698
700
|
attributeName: pluginOptions.attributeName
|
|
699
701
|
});
|
|
700
702
|
}
|
|
@@ -703,6 +705,7 @@ function transformRouter(options) {
|
|
|
703
705
|
filePath,
|
|
704
706
|
source,
|
|
705
707
|
escapeTags: pluginOptions.escapeTags,
|
|
708
|
+
pathType: pluginOptions.pathType,
|
|
706
709
|
attributeName: pluginOptions.attributeName
|
|
707
710
|
});
|
|
708
711
|
}
|
|
@@ -1224,7 +1227,6 @@ function dispatchPromptThroughIde(runtime, payload) {
|
|
|
1224
1227
|
line: payload.line,
|
|
1225
1228
|
column: payload.column,
|
|
1226
1229
|
snippet: payload.snippet,
|
|
1227
|
-
...payload.screenshotContext ? { screenshotContext: payload.screenshotContext } : {},
|
|
1228
1230
|
overrides: runtime.overrides,
|
|
1229
1231
|
autoSend: runtime.autoSend
|
|
1230
1232
|
});
|
|
@@ -1358,6 +1360,188 @@ function assertPathWithinIdeOpenScope(file, projectRoot) {
|
|
|
1358
1360
|
}
|
|
1359
1361
|
}
|
|
1360
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
|
+
|
|
1361
1545
|
// src/server/annotation-dispatch.ts
|
|
1362
1546
|
var AnnotationDispatchError = class extends Error {
|
|
1363
1547
|
constructor(message, errorCode) {
|
|
@@ -1366,20 +1550,30 @@ var AnnotationDispatchError = class extends Error {
|
|
|
1366
1550
|
this.errorCode = errorCode;
|
|
1367
1551
|
}
|
|
1368
1552
|
};
|
|
1369
|
-
async function dispatchAnnotationsToAi(req, state) {
|
|
1553
|
+
async function dispatchAnnotationsToAi(req, state, store = annotationSessionStore) {
|
|
1370
1554
|
try {
|
|
1371
1555
|
validateAnnotationDispatchRequest(req, state);
|
|
1372
1556
|
const batch = normalizeAnnotationBatch(req);
|
|
1373
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
|
+
});
|
|
1374
1566
|
const representativeTarget = batch.annotations[0]?.targets[0];
|
|
1375
|
-
const
|
|
1376
|
-
return dispatchPromptThroughIde(runtime, {
|
|
1567
|
+
const dispatchResult = deliveryMode === "ide" ? dispatchPromptThroughIde(resolvePromptDispatchRuntime(state), {
|
|
1377
1568
|
prompt,
|
|
1378
1569
|
...representativeTarget?.file ? { filePath: representativeTarget.file } : {},
|
|
1379
1570
|
...representativeTarget?.line ? { line: representativeTarget.line } : {},
|
|
1380
|
-
...representativeTarget?.column ? { column: representativeTarget.column } : {}
|
|
1381
|
-
|
|
1382
|
-
|
|
1571
|
+
...representativeTarget?.column ? { column: representativeTarget.column } : {}
|
|
1572
|
+
}) : { success: true };
|
|
1573
|
+
return {
|
|
1574
|
+
...dispatchResult,
|
|
1575
|
+
session: toSessionSummary(session)
|
|
1576
|
+
};
|
|
1383
1577
|
} catch (error) {
|
|
1384
1578
|
return {
|
|
1385
1579
|
success: false,
|
|
@@ -1388,6 +1582,41 @@ async function dispatchAnnotationsToAi(req, state) {
|
|
|
1388
1582
|
};
|
|
1389
1583
|
}
|
|
1390
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
|
+
}
|
|
1391
1620
|
function validateAnnotationDispatchRequest(req, state) {
|
|
1392
1621
|
if (!req.annotations.length) {
|
|
1393
1622
|
throw new AnnotationDispatchError("At least one annotation is required.", "INVALID_REQUEST");
|
|
@@ -1408,9 +1637,7 @@ function validateAnnotationDispatchRequest(req, state) {
|
|
|
1408
1637
|
function normalizeAnnotationBatch(req) {
|
|
1409
1638
|
return {
|
|
1410
1639
|
instruction: req.instruction?.trim() ?? "",
|
|
1411
|
-
responseMode: req.responseMode ?? "unified",
|
|
1412
1640
|
...req.runtimeContext ? { runtimeContext: req.runtimeContext } : {},
|
|
1413
|
-
...req.screenshotContext ? { screenshotContext: req.screenshotContext } : {},
|
|
1414
1641
|
...req.cssContextPrompt?.trim() ? { cssContextPrompt: req.cssContextPrompt.trim() } : {},
|
|
1415
1642
|
annotations: req.annotations.map((annotation, index) => ({
|
|
1416
1643
|
index: index + 1,
|
|
@@ -1432,12 +1659,9 @@ function buildAnnotationBatchPrompt(batch) {
|
|
|
1432
1659
|
const prompt = batch.instruction ? `${batch.instruction}
|
|
1433
1660
|
|
|
1434
1661
|
${body}` : body;
|
|
1435
|
-
return
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
batch.cssContextPrompt
|
|
1439
|
-
),
|
|
1440
|
-
batch.screenshotContext
|
|
1662
|
+
return appendCssContextSection(
|
|
1663
|
+
appendRuntimeContextSection(prompt, batch.runtimeContext),
|
|
1664
|
+
batch.cssContextPrompt
|
|
1441
1665
|
);
|
|
1442
1666
|
}
|
|
1443
1667
|
function appendCssContextSection(prompt, cssContextPrompt) {
|
|
@@ -1464,20 +1688,6 @@ function buildSelectedElementsPrompt(annotations) {
|
|
|
1464
1688
|
}
|
|
1465
1689
|
return lines.join("\n");
|
|
1466
1690
|
}
|
|
1467
|
-
function appendScreenshotContextSection(prompt, screenshotContext) {
|
|
1468
|
-
if (!screenshotContext || !screenshotContext.imageDataUrl && !screenshotContext.imageAssetId) {
|
|
1469
|
-
return prompt;
|
|
1470
|
-
}
|
|
1471
|
-
const lines = [
|
|
1472
|
-
"Visual screenshot context attached:",
|
|
1473
|
-
`- capturedAt=${screenshotContext.capturedAt}`,
|
|
1474
|
-
`- mimeType=${screenshotContext.mimeType}`,
|
|
1475
|
-
...screenshotContext.imageAssetId ? [`- imageAssetId=${screenshotContext.imageAssetId}`] : []
|
|
1476
|
-
];
|
|
1477
|
-
return `${prompt}
|
|
1478
|
-
|
|
1479
|
-
${lines.join("\n")}`;
|
|
1480
|
-
}
|
|
1481
1691
|
function appendRuntimeContextSection(prompt, runtimeContext) {
|
|
1482
1692
|
if (!runtimeContext?.records.length) {
|
|
1483
1693
|
return prompt;
|
|
@@ -1525,7 +1735,7 @@ async function buildClientConfig(serverState2) {
|
|
|
1525
1735
|
...info,
|
|
1526
1736
|
prompts: resolveIntents(promptsConfig),
|
|
1527
1737
|
hotKeys: userConfig["inspector.hotKey"] ?? "alt",
|
|
1528
|
-
|
|
1738
|
+
annotateDeliveryMode: userConfig["annotate.deliveryMode"] ?? "both",
|
|
1529
1739
|
includeSnippet: userConfig["prompt.includeSnippet"] ?? false,
|
|
1530
1740
|
runtimeContext: {
|
|
1531
1741
|
enabled: true,
|
|
@@ -1533,10 +1743,6 @@ async function buildClientConfig(serverState2) {
|
|
|
1533
1743
|
maxRuntimeErrors: 3,
|
|
1534
1744
|
maxFailedRequests: 2
|
|
1535
1745
|
},
|
|
1536
|
-
screenshotContext: {
|
|
1537
|
-
enabled: false
|
|
1538
|
-
},
|
|
1539
|
-
annotationResponseMode: userConfig["prompt.annotationResponseMode"] ?? "unified",
|
|
1540
1746
|
autoSend: userConfig["prompt.autoSend"] ?? false
|
|
1541
1747
|
};
|
|
1542
1748
|
}
|
|
@@ -1581,7 +1787,7 @@ function handleOpenFileRequest(body, serverState2) {
|
|
|
1581
1787
|
else if (rawEditorHint === "vscodium") editorHint = "codium";
|
|
1582
1788
|
else if (rawEditorHint === "trae-cn" || rawEditorHint === "trae") editorHint = "trae";
|
|
1583
1789
|
serverLogger2.debug(
|
|
1584
|
-
`
|
|
1790
|
+
`SOURCE_OPEN: activeIde=${activeIde}, activeIdeScheme=${activeIdeScheme}, configuredIde=${configuredIde} -> rawEditorHint=${rawEditorHint}, finalEditorHint=${editorHint}`
|
|
1585
1791
|
);
|
|
1586
1792
|
if (VSCODE_FAMILY_SCHEMES.includes(rawEditorHint)) {
|
|
1587
1793
|
let normalizedPath = absolutePath.replace(/\\/g, "/");
|
|
@@ -1590,7 +1796,7 @@ function handleOpenFileRequest(body, serverState2) {
|
|
|
1590
1796
|
}
|
|
1591
1797
|
const encodedPath = encodeURI(normalizedPath);
|
|
1592
1798
|
const uri = `${rawEditorHint}://file${encodedPath}:${body.line}:${body.column}`;
|
|
1593
|
-
serverLogger2.debug(`
|
|
1799
|
+
serverLogger2.debug(`SOURCE_OPEN: Bypassing launchIDE, using URI scheme directly: ${uri}`);
|
|
1594
1800
|
try {
|
|
1595
1801
|
if (process.platform === "darwin") {
|
|
1596
1802
|
execFileSync2("open", [uri]);
|
|
@@ -1600,7 +1806,7 @@ function handleOpenFileRequest(body, serverState2) {
|
|
|
1600
1806
|
execFileSync2("xdg-open", [uri]);
|
|
1601
1807
|
}
|
|
1602
1808
|
} catch (e) {
|
|
1603
|
-
serverLogger2.error(`Failed to launch URI for
|
|
1809
|
+
serverLogger2.error(`Failed to launch URI for SOURCE_OPEN (${uri}):`, e);
|
|
1604
1810
|
launchIDE2({
|
|
1605
1811
|
file: absolutePath,
|
|
1606
1812
|
line: body.line,
|
|
@@ -1655,8 +1861,27 @@ function resolveProjectRoot() {
|
|
|
1655
1861
|
return gitRoot;
|
|
1656
1862
|
}
|
|
1657
1863
|
|
|
1864
|
+
// src/server/server-url.ts
|
|
1865
|
+
function resolveServerHost(cwd, configRoot) {
|
|
1866
|
+
const userConfig = loadUserConfigSync(false, cwd, configRoot);
|
|
1867
|
+
const configuredHost = userConfig["server.host"]?.trim();
|
|
1868
|
+
if (configuredHost) return configuredHost;
|
|
1869
|
+
if (process.env["VITEST"]) return "127.0.0.1";
|
|
1870
|
+
return "127.0.0.1";
|
|
1871
|
+
}
|
|
1872
|
+
function resolvePublicServerUrl(args) {
|
|
1873
|
+
const userConfig = loadUserConfigSync(false, args.cwd, args.configRoot);
|
|
1874
|
+
const configuredPublicUrl = userConfig["server.publicUrl"]?.trim();
|
|
1875
|
+
if (configuredPublicUrl) {
|
|
1876
|
+
return configuredPublicUrl.replace(/\/$/, "");
|
|
1877
|
+
}
|
|
1878
|
+
const host = resolveServerHost(args.cwd, args.configRoot);
|
|
1879
|
+
return `http://${host}:${args.port}`;
|
|
1880
|
+
}
|
|
1881
|
+
|
|
1658
1882
|
// src/server/index.ts
|
|
1659
1883
|
var serverLogger4 = createLogger("inspecto:server", { logLevel: getGlobalLogLevel() });
|
|
1884
|
+
var PORT_FILE_NAME = "inspecto.port.json";
|
|
1660
1885
|
var serverState = {
|
|
1661
1886
|
port: null,
|
|
1662
1887
|
running: false,
|
|
@@ -1665,6 +1890,42 @@ var serverState = {
|
|
|
1665
1890
|
cwd: process.cwd()
|
|
1666
1891
|
};
|
|
1667
1892
|
var serverInstance = null;
|
|
1893
|
+
function getPortFilePath() {
|
|
1894
|
+
return path8.join(os2.tmpdir(), PORT_FILE_NAME);
|
|
1895
|
+
}
|
|
1896
|
+
function getProjectRootHash() {
|
|
1897
|
+
if (!serverState.projectRoot) return null;
|
|
1898
|
+
return crypto2.createHash("md5").update(serverState.projectRoot).digest("hex");
|
|
1899
|
+
}
|
|
1900
|
+
function readPortData(portFile) {
|
|
1901
|
+
if (!fs5.existsSync(portFile)) return {};
|
|
1902
|
+
try {
|
|
1903
|
+
return JSON.parse(fs5.readFileSync(portFile, "utf-8"));
|
|
1904
|
+
} catch {
|
|
1905
|
+
return {};
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1908
|
+
function writeProjectPort(port) {
|
|
1909
|
+
const rootHash = getProjectRootHash();
|
|
1910
|
+
if (!rootHash) return;
|
|
1911
|
+
const portFile = getPortFilePath();
|
|
1912
|
+
const portData = readPortData(portFile);
|
|
1913
|
+
portData[rootHash] = port;
|
|
1914
|
+
fs5.writeFileSync(portFile, JSON.stringify(portData, null, 2), "utf-8");
|
|
1915
|
+
}
|
|
1916
|
+
function removeProjectPort() {
|
|
1917
|
+
const rootHash = getProjectRootHash();
|
|
1918
|
+
if (!rootHash) return;
|
|
1919
|
+
const portFile = getPortFilePath();
|
|
1920
|
+
if (!fs5.existsSync(portFile)) return;
|
|
1921
|
+
const portData = readPortData(portFile);
|
|
1922
|
+
delete portData[rootHash];
|
|
1923
|
+
if (Object.keys(portData).length === 0) {
|
|
1924
|
+
fs5.unlinkSync(portFile);
|
|
1925
|
+
} else {
|
|
1926
|
+
fs5.writeFileSync(portFile, JSON.stringify(portData, null, 2), "utf-8");
|
|
1927
|
+
}
|
|
1928
|
+
}
|
|
1668
1929
|
async function startServer() {
|
|
1669
1930
|
if (serverState.running && serverState.port !== null) {
|
|
1670
1931
|
return serverState.port;
|
|
@@ -1672,6 +1933,7 @@ async function startServer() {
|
|
|
1672
1933
|
serverState.projectRoot = resolveProjectRoot();
|
|
1673
1934
|
serverState.configRoot = serverState.projectRoot;
|
|
1674
1935
|
serverState.cwd = process.cwd();
|
|
1936
|
+
const serverHost = resolveServerHost(serverState.cwd, serverState.configRoot);
|
|
1675
1937
|
portfinder.basePort = 5678;
|
|
1676
1938
|
const port = await portfinder.getPortPromise();
|
|
1677
1939
|
watchConfig(
|
|
@@ -1698,7 +1960,7 @@ async function startServer() {
|
|
|
1698
1960
|
});
|
|
1699
1961
|
});
|
|
1700
1962
|
await new Promise((resolve2, reject) => {
|
|
1701
|
-
serverInstance.listen(port,
|
|
1963
|
+
serverInstance.listen(port, serverHost, () => {
|
|
1702
1964
|
serverInstance.unref();
|
|
1703
1965
|
resolve2();
|
|
1704
1966
|
});
|
|
@@ -1709,37 +1971,18 @@ async function startServer() {
|
|
|
1709
1971
|
});
|
|
1710
1972
|
serverState.port = port;
|
|
1711
1973
|
serverState.running = true;
|
|
1712
|
-
const portFile = path8.join(os2.tmpdir(), "inspecto.port.json");
|
|
1713
1974
|
try {
|
|
1714
|
-
|
|
1715
|
-
if (fs5.existsSync(portFile)) {
|
|
1716
|
-
try {
|
|
1717
|
-
portData = JSON.parse(fs5.readFileSync(portFile, "utf-8"));
|
|
1718
|
-
} catch (_e) {
|
|
1719
|
-
}
|
|
1720
|
-
}
|
|
1721
|
-
const rootHash = crypto2.createHash("md5").update(serverState.projectRoot).digest("hex");
|
|
1722
|
-
portData[rootHash] = port;
|
|
1723
|
-
fs5.writeFileSync(portFile, JSON.stringify(portData, null, 2), "utf-8");
|
|
1975
|
+
writeProjectPort(port);
|
|
1724
1976
|
} catch (_e) {
|
|
1725
1977
|
serverLogger4.warn("Failed to write port file:", _e);
|
|
1726
1978
|
}
|
|
1727
1979
|
process.once("exit", () => {
|
|
1728
1980
|
try {
|
|
1729
|
-
|
|
1730
|
-
const portData = JSON.parse(fs5.readFileSync(portFile, "utf-8"));
|
|
1731
|
-
const rootHash = crypto2.createHash("md5").update(serverState.projectRoot).digest("hex");
|
|
1732
|
-
delete portData[rootHash];
|
|
1733
|
-
if (Object.keys(portData).length === 0) {
|
|
1734
|
-
fs5.unlinkSync(portFile);
|
|
1735
|
-
} else {
|
|
1736
|
-
fs5.writeFileSync(portFile, JSON.stringify(portData, null, 2), "utf-8");
|
|
1737
|
-
}
|
|
1738
|
-
}
|
|
1981
|
+
removeProjectPort();
|
|
1739
1982
|
} catch {
|
|
1740
1983
|
}
|
|
1741
1984
|
});
|
|
1742
|
-
serverLogger4.info(`server running at http
|
|
1985
|
+
serverLogger4.info(`server running at http://${serverHost}:${port}`);
|
|
1743
1986
|
return port;
|
|
1744
1987
|
}
|
|
1745
1988
|
async function readBody(req) {
|
|
@@ -1791,7 +2034,7 @@ async function handleRequest(url, req, res) {
|
|
|
1791
2034
|
}
|
|
1792
2035
|
return;
|
|
1793
2036
|
}
|
|
1794
|
-
if (pathname === INSPECTO_API_PATHS.IDE_OPEN && req.method === "POST") {
|
|
2037
|
+
if ((pathname === INSPECTO_API_PATHS.SOURCE_OPEN || pathname === INSPECTO_API_PATHS.IDE_OPEN) && req.method === "POST") {
|
|
1795
2038
|
let body;
|
|
1796
2039
|
try {
|
|
1797
2040
|
body = JSON.parse(await readBody(req));
|
|
@@ -1804,7 +2047,7 @@ async function handleRequest(url, req, res) {
|
|
|
1804
2047
|
handleOpenFileRequest(body, serverState);
|
|
1805
2048
|
} catch (err) {
|
|
1806
2049
|
serverLogger4.warn(
|
|
1807
|
-
`Security: Blocked path traversal attempt in
|
|
2050
|
+
`Security: Blocked path traversal attempt in SOURCE_OPEN: ${body.file}. Reason: ${err.message}`
|
|
1808
2051
|
);
|
|
1809
2052
|
res.writeHead(403, { "Content-Type": "application/json" });
|
|
1810
2053
|
res.end(JSON.stringify({ error: "Access denied: File is outside of project workspace" }));
|
|
@@ -1878,6 +2121,212 @@ async function handleRequest(url, req, res) {
|
|
|
1878
2121
|
}
|
|
1879
2122
|
return;
|
|
1880
2123
|
}
|
|
2124
|
+
if (pathname === INSPECTO_API_PATHS.SESSION_CLAIM_NEXT && req.method === "POST") {
|
|
2125
|
+
try {
|
|
2126
|
+
const rawBody = await readBody(req);
|
|
2127
|
+
const body = rawBody ? JSON.parse(rawBody) : {};
|
|
2128
|
+
const timeoutMs = normalizeSessionClaimTimeout(
|
|
2129
|
+
body.timeoutMs === void 0 ? null : String(body.timeoutMs)
|
|
2130
|
+
);
|
|
2131
|
+
const result = await annotationSessionStore.claimNextSession({
|
|
2132
|
+
...timeoutMs !== void 0 ? { timeoutMs } : {}
|
|
2133
|
+
});
|
|
2134
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
2135
|
+
res.end(
|
|
2136
|
+
JSON.stringify({
|
|
2137
|
+
success: true,
|
|
2138
|
+
timedOut: result.timedOut,
|
|
2139
|
+
matchedExisting: result.matchedExisting,
|
|
2140
|
+
...result.event ? { event: result.event } : {},
|
|
2141
|
+
...result.session ? { session: result.session } : {}
|
|
2142
|
+
})
|
|
2143
|
+
);
|
|
2144
|
+
} catch (e) {
|
|
2145
|
+
serverLogger4.error(`Error parsing session claim request:`, e);
|
|
2146
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
2147
|
+
res.end(JSON.stringify({ success: false, error: "Invalid JSON body" }));
|
|
2148
|
+
}
|
|
2149
|
+
return;
|
|
2150
|
+
}
|
|
2151
|
+
if (pathname === INSPECTO_API_PATHS.SESSION_EVENTS && req.method === "GET") {
|
|
2152
|
+
const statusParam = url.searchParams.getAll("status");
|
|
2153
|
+
const statuses = statusParam.length ? new Set(statusParam) : null;
|
|
2154
|
+
const sessionId = url.searchParams.get("sessionId")?.trim() || null;
|
|
2155
|
+
res.writeHead(200, {
|
|
2156
|
+
"Content-Type": "text/event-stream",
|
|
2157
|
+
"Cache-Control": "no-cache",
|
|
2158
|
+
Connection: "keep-alive"
|
|
2159
|
+
});
|
|
2160
|
+
res.write(`event: ready
|
|
2161
|
+
data: ${JSON.stringify({ ok: true })}
|
|
2162
|
+
|
|
2163
|
+
`);
|
|
2164
|
+
const unsubscribe = annotationSessionStore.subscribe((event) => {
|
|
2165
|
+
if (sessionId && event.session.id !== sessionId) {
|
|
2166
|
+
return;
|
|
2167
|
+
}
|
|
2168
|
+
if (statuses && !statuses.has(event.session.status)) {
|
|
2169
|
+
return;
|
|
2170
|
+
}
|
|
2171
|
+
res.write(formatSessionSseEvent(event));
|
|
2172
|
+
});
|
|
2173
|
+
req.on("close", () => {
|
|
2174
|
+
unsubscribe();
|
|
2175
|
+
res.end();
|
|
2176
|
+
});
|
|
2177
|
+
return;
|
|
2178
|
+
}
|
|
2179
|
+
if (pathname === INSPECTO_API_PATHS.SESSIONS && req.method === "GET") {
|
|
2180
|
+
const statusParam = url.searchParams.getAll("status");
|
|
2181
|
+
const sessions = annotationSessionStore.listSessions(
|
|
2182
|
+
statusParam.length ? {
|
|
2183
|
+
status: statusParam
|
|
2184
|
+
} : void 0
|
|
2185
|
+
);
|
|
2186
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
2187
|
+
res.end(JSON.stringify({ success: true, sessions }));
|
|
2188
|
+
return;
|
|
2189
|
+
}
|
|
2190
|
+
if (pathname.startsWith(`${INSPECTO_API_PATHS.SESSIONS}/`) && req.method === "GET") {
|
|
2191
|
+
const sessionId = pathname.substring(INSPECTO_API_PATHS.SESSIONS.length + 1);
|
|
2192
|
+
const session = annotationSessionStore.getSession(sessionId);
|
|
2193
|
+
if (!session) {
|
|
2194
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
2195
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
2196
|
+
return;
|
|
2197
|
+
}
|
|
2198
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
2199
|
+
res.end(JSON.stringify({ success: true, session }));
|
|
2200
|
+
return;
|
|
2201
|
+
}
|
|
2202
|
+
if (pathname.startsWith(`${INSPECTO_API_PATHS.SESSIONS}/`) && pathname.endsWith(INSPECTO_API_PATHS.SESSION_REPLY_SUFFIX) && req.method === "POST") {
|
|
2203
|
+
const sessionId = pathname.slice(
|
|
2204
|
+
INSPECTO_API_PATHS.SESSIONS.length + 1,
|
|
2205
|
+
-INSPECTO_API_PATHS.SESSION_REPLY_SUFFIX.length
|
|
2206
|
+
);
|
|
2207
|
+
try {
|
|
2208
|
+
const rawBody = await readBody(req);
|
|
2209
|
+
const body = JSON.parse(rawBody);
|
|
2210
|
+
if (!isAnnotationThreadRole(body.role)) {
|
|
2211
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
2212
|
+
res.end(JSON.stringify({ success: false, error: "Reply role is invalid." }));
|
|
2213
|
+
return;
|
|
2214
|
+
}
|
|
2215
|
+
if (!body.text?.trim()) {
|
|
2216
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
2217
|
+
res.end(JSON.stringify({ success: false, error: "Reply text is required." }));
|
|
2218
|
+
return;
|
|
2219
|
+
}
|
|
2220
|
+
const session = annotationSessionStore.appendMessage(sessionId, {
|
|
2221
|
+
role: body.role,
|
|
2222
|
+
text: body.text.trim()
|
|
2223
|
+
});
|
|
2224
|
+
if (!session) {
|
|
2225
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
2226
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
2227
|
+
return;
|
|
2228
|
+
}
|
|
2229
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
2230
|
+
res.end(JSON.stringify({ success: true, session }));
|
|
2231
|
+
} catch (e) {
|
|
2232
|
+
serverLogger4.error(`Error parsing session reply request:`, e);
|
|
2233
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
2234
|
+
res.end(JSON.stringify({ success: false, error: "Invalid JSON body" }));
|
|
2235
|
+
}
|
|
2236
|
+
return;
|
|
2237
|
+
}
|
|
2238
|
+
if (pathname.startsWith(`${INSPECTO_API_PATHS.SESSIONS}/`) && pathname.endsWith(INSPECTO_API_PATHS.SESSION_RESOLVE_SUFFIX) && req.method === "POST") {
|
|
2239
|
+
const sessionId = pathname.slice(
|
|
2240
|
+
INSPECTO_API_PATHS.SESSIONS.length + 1,
|
|
2241
|
+
-INSPECTO_API_PATHS.SESSION_RESOLVE_SUFFIX.length
|
|
2242
|
+
);
|
|
2243
|
+
try {
|
|
2244
|
+
const rawBody = await readBody(req);
|
|
2245
|
+
const body = rawBody ? JSON.parse(rawBody) : {};
|
|
2246
|
+
const message = body.message?.trim();
|
|
2247
|
+
const existingSession = annotationSessionStore.getSession(sessionId);
|
|
2248
|
+
if (!existingSession) {
|
|
2249
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
2250
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
2251
|
+
return;
|
|
2252
|
+
}
|
|
2253
|
+
if (!message && !hasAgentReply(existingSession)) {
|
|
2254
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
2255
|
+
res.end(
|
|
2256
|
+
JSON.stringify({
|
|
2257
|
+
success: false,
|
|
2258
|
+
error: "Resolve message is required until an agent reply is recorded."
|
|
2259
|
+
})
|
|
2260
|
+
);
|
|
2261
|
+
return;
|
|
2262
|
+
}
|
|
2263
|
+
if (message) {
|
|
2264
|
+
const repliedSession = annotationSessionStore.appendMessage(sessionId, {
|
|
2265
|
+
role: "agent",
|
|
2266
|
+
text: message
|
|
2267
|
+
});
|
|
2268
|
+
if (!repliedSession) {
|
|
2269
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
2270
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
2271
|
+
return;
|
|
2272
|
+
}
|
|
2273
|
+
}
|
|
2274
|
+
const session = annotationSessionStore.updateStatus(sessionId, "resolved");
|
|
2275
|
+
if (!session) {
|
|
2276
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
2277
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
2278
|
+
return;
|
|
2279
|
+
}
|
|
2280
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
2281
|
+
res.end(JSON.stringify({ success: true, session }));
|
|
2282
|
+
} catch (e) {
|
|
2283
|
+
serverLogger4.error(`Error parsing session resolve request:`, e);
|
|
2284
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
2285
|
+
res.end(JSON.stringify({ success: false, error: "Invalid JSON body" }));
|
|
2286
|
+
}
|
|
2287
|
+
return;
|
|
2288
|
+
}
|
|
2289
|
+
if (pathname.startsWith(`${INSPECTO_API_PATHS.SESSIONS}/`) && pathname.endsWith(INSPECTO_API_PATHS.SESSION_DISMISS_SUFFIX) && req.method === "POST") {
|
|
2290
|
+
const sessionId = pathname.slice(
|
|
2291
|
+
INSPECTO_API_PATHS.SESSIONS.length + 1,
|
|
2292
|
+
-INSPECTO_API_PATHS.SESSION_DISMISS_SUFFIX.length
|
|
2293
|
+
);
|
|
2294
|
+
try {
|
|
2295
|
+
const rawBody = await readBody(req);
|
|
2296
|
+
const body = rawBody ? JSON.parse(rawBody) : {};
|
|
2297
|
+
const message = body.message?.trim();
|
|
2298
|
+
const existingSession = annotationSessionStore.getSession(sessionId);
|
|
2299
|
+
if (!existingSession) {
|
|
2300
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
2301
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
2302
|
+
return;
|
|
2303
|
+
}
|
|
2304
|
+
if (message) {
|
|
2305
|
+
const repliedSession = annotationSessionStore.appendMessage(sessionId, {
|
|
2306
|
+
role: "agent",
|
|
2307
|
+
text: message
|
|
2308
|
+
});
|
|
2309
|
+
if (!repliedSession) {
|
|
2310
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
2311
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
2312
|
+
return;
|
|
2313
|
+
}
|
|
2314
|
+
}
|
|
2315
|
+
const session = annotationSessionStore.updateStatus(sessionId, "dismissed");
|
|
2316
|
+
if (!session) {
|
|
2317
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
2318
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
2319
|
+
return;
|
|
2320
|
+
}
|
|
2321
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
2322
|
+
res.end(JSON.stringify({ success: true, session }));
|
|
2323
|
+
} catch (e) {
|
|
2324
|
+
serverLogger4.error(`Error parsing session dismiss request:`, e);
|
|
2325
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
2326
|
+
res.end(JSON.stringify({ success: false, error: "Invalid JSON body" }));
|
|
2327
|
+
}
|
|
2328
|
+
return;
|
|
2329
|
+
}
|
|
1881
2330
|
if (pathname.startsWith(`${INSPECTO_API_PATHS.AI_TICKET}/`) && req.method === "GET") {
|
|
1882
2331
|
const ticketId = pathname.substring(INSPECTO_API_PATHS.AI_TICKET.length + 1);
|
|
1883
2332
|
const payloadStr = readTicket(ticketId);
|
|
@@ -1894,7 +2343,7 @@ async function handleRequest(url, req, res) {
|
|
|
1894
2343
|
res.end(JSON.stringify({ error: "not found" }));
|
|
1895
2344
|
}
|
|
1896
2345
|
async function dispatchToAi(req) {
|
|
1897
|
-
const { location, snippet, prompt
|
|
2346
|
+
const { location, snippet, prompt } = req;
|
|
1898
2347
|
const formattedPrompt = prompt ?? `Please help me with this code from \`${location.file}\` (line ${location.line}):
|
|
1899
2348
|
|
|
1900
2349
|
\`\`\`
|
|
@@ -1907,8 +2356,7 @@ ${snippet}
|
|
|
1907
2356
|
filePath: location.file,
|
|
1908
2357
|
line: location.line,
|
|
1909
2358
|
column: location.column,
|
|
1910
|
-
snippet
|
|
1911
|
-
...screenshotContext ? { screenshotContext } : {}
|
|
2359
|
+
snippet
|
|
1912
2360
|
});
|
|
1913
2361
|
}
|
|
1914
2362
|
function getBatchDispatchStatusCode(errorCode, success) {
|
|
@@ -1917,6 +2365,21 @@ function getBatchDispatchStatusCode(errorCode, success) {
|
|
|
1917
2365
|
if (errorCode === "FORBIDDEN_PATH") return 403;
|
|
1918
2366
|
return 500;
|
|
1919
2367
|
}
|
|
2368
|
+
function isAnnotationThreadRole(value) {
|
|
2369
|
+
return value === "user" || value === "agent" || value === "system";
|
|
2370
|
+
}
|
|
2371
|
+
function formatSessionSseEvent(event) {
|
|
2372
|
+
return `event: ${event.type}
|
|
2373
|
+
data: ${JSON.stringify(event)}
|
|
2374
|
+
|
|
2375
|
+
`;
|
|
2376
|
+
}
|
|
2377
|
+
function normalizeSessionClaimTimeout(value) {
|
|
2378
|
+
if (!value?.trim()) return 3e4;
|
|
2379
|
+
const parsed = Number.parseInt(value, 10);
|
|
2380
|
+
if (!Number.isFinite(parsed)) return 3e4;
|
|
2381
|
+
return Math.max(0, Math.min(parsed, 3e5));
|
|
2382
|
+
}
|
|
1920
2383
|
|
|
1921
2384
|
// src/injectors/utils.ts
|
|
1922
2385
|
import { createRequire } from "module";
|
|
@@ -1936,26 +2399,28 @@ var resolveClientModule = () => {
|
|
|
1936
2399
|
};
|
|
1937
2400
|
|
|
1938
2401
|
// src/injectors/webpack.ts
|
|
1939
|
-
function getWebpackHtmlScript(serverPort) {
|
|
2402
|
+
function getWebpackHtmlScript(serverPort, publicServerUrl) {
|
|
1940
2403
|
return `
|
|
1941
2404
|
window.__AI_INSPECTOR_PORT__ = ${serverPort};
|
|
1942
|
-
window.
|
|
1943
|
-
|
|
1944
|
-
window.InspectoClient
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
}
|
|
2405
|
+
window.__AI_INSPECTOR_SERVER_URL__ = '${publicServerUrl ?? `http://127.0.0.1:${serverPort}`}';
|
|
2406
|
+
window.addEventListener('load', () => {
|
|
2407
|
+
if (window.InspectoClient) {
|
|
2408
|
+
window.InspectoClient.mountInspector({
|
|
2409
|
+
serverUrl: window.__AI_INSPECTOR_SERVER_URL__,
|
|
2410
|
+
});
|
|
2411
|
+
}
|
|
2412
|
+
});
|
|
1949
2413
|
`;
|
|
1950
2414
|
}
|
|
1951
|
-
function getWebpackAssetScript(serverPort) {
|
|
2415
|
+
function getWebpackAssetScript(serverPort, publicServerUrl) {
|
|
1952
2416
|
return `
|
|
1953
2417
|
if (typeof window !== 'undefined') {
|
|
1954
2418
|
window.__AI_INSPECTOR_PORT__ = ${serverPort};
|
|
2419
|
+
window.__AI_INSPECTOR_SERVER_URL__ = '${publicServerUrl ?? `http://127.0.0.1:${serverPort}`}';
|
|
1955
2420
|
const _initInspecto = () => {
|
|
1956
2421
|
if (window.InspectoClient) {
|
|
1957
2422
|
window.InspectoClient.mountInspector({
|
|
1958
|
-
serverUrl:
|
|
2423
|
+
serverUrl: window.__AI_INSPECTOR_SERVER_URL__,
|
|
1959
2424
|
});
|
|
1960
2425
|
} else {
|
|
1961
2426
|
setTimeout(_initInspecto, 100);
|
|
@@ -1969,7 +2434,7 @@ if (typeof window !== 'undefined') {
|
|
|
1969
2434
|
}
|
|
1970
2435
|
`;
|
|
1971
2436
|
}
|
|
1972
|
-
function injectWebpack(compiler, serverPortFn, resolveClientModule2) {
|
|
2437
|
+
function injectWebpack(compiler, serverPortFn, publicServerUrlFn, resolveClientModule2) {
|
|
1973
2438
|
const inspectoClientPath = resolveClientModule2();
|
|
1974
2439
|
if (compiler.webpack && compiler.webpack.EntryPlugin) {
|
|
1975
2440
|
new compiler.webpack.EntryPlugin(compiler.context, inspectoClientPath, {
|
|
@@ -1984,11 +2449,12 @@ function injectWebpack(compiler, serverPortFn, resolveClientModule2) {
|
|
|
1984
2449
|
const hooks = HtmlWebpackPlugin.constructor.getHooks(compilation);
|
|
1985
2450
|
hooks.alterAssetTagGroups.tapPromise("inspecto-overlay", async (data) => {
|
|
1986
2451
|
const port = await serverPortFn();
|
|
2452
|
+
const publicServerUrl = publicServerUrlFn(port);
|
|
1987
2453
|
data.headTags.unshift({
|
|
1988
2454
|
tagName: "script",
|
|
1989
2455
|
voidTag: false,
|
|
1990
2456
|
meta: { plugin: "inspecto-overlay" },
|
|
1991
|
-
innerHTML: getWebpackHtmlScript(port)
|
|
2457
|
+
innerHTML: getWebpackHtmlScript(port, publicServerUrl)
|
|
1992
2458
|
});
|
|
1993
2459
|
return data;
|
|
1994
2460
|
});
|
|
@@ -2001,13 +2467,14 @@ function injectWebpack(compiler, serverPortFn, resolveClientModule2) {
|
|
|
2001
2467
|
},
|
|
2002
2468
|
async (assets) => {
|
|
2003
2469
|
const port = await serverPortFn();
|
|
2470
|
+
const publicServerUrl = publicServerUrlFn(port);
|
|
2004
2471
|
const mainAssetKey = Object.keys(assets).find(
|
|
2005
2472
|
(key) => key.endsWith(".js") && (key.includes("main") || key.includes("app") || key.includes("umi"))
|
|
2006
2473
|
);
|
|
2007
2474
|
if (!mainAssetKey) return;
|
|
2008
2475
|
const originalSource = assets[mainAssetKey].source();
|
|
2009
2476
|
assets[mainAssetKey] = new compiler.webpack.sources.RawSource(
|
|
2010
|
-
getWebpackAssetScript(port) + "\n" + originalSource
|
|
2477
|
+
getWebpackAssetScript(port, publicServerUrl) + "\n" + originalSource
|
|
2011
2478
|
);
|
|
2012
2479
|
}
|
|
2013
2480
|
);
|
|
@@ -2041,12 +2508,13 @@ function injectRspack(compiler, serverPortFn, resolveClientModule2) {
|
|
|
2041
2508
|
}
|
|
2042
2509
|
|
|
2043
2510
|
// src/injectors/vite.ts
|
|
2044
|
-
function getViteVirtualModuleScript(serverPort) {
|
|
2511
|
+
function getViteVirtualModuleScript(serverPort, publicServerUrl) {
|
|
2045
2512
|
return `
|
|
2046
2513
|
import { mountInspector } from '@inspecto-dev/core';
|
|
2047
2514
|
window.__AI_INSPECTOR_PORT__ = ${serverPort};
|
|
2515
|
+
window.__AI_INSPECTOR_SERVER_URL__ = '${publicServerUrl ?? `http://127.0.0.1:${serverPort}`}';
|
|
2048
2516
|
mountInspector({
|
|
2049
|
-
serverUrl:
|
|
2517
|
+
serverUrl: window.__AI_INSPECTOR_SERVER_URL__,
|
|
2050
2518
|
});
|
|
2051
2519
|
`;
|
|
2052
2520
|
}
|
|
@@ -2079,6 +2547,11 @@ var InspectoPlugin = createUnplugin((userOptions = {}) => {
|
|
|
2079
2547
|
}
|
|
2080
2548
|
return serverPort;
|
|
2081
2549
|
};
|
|
2550
|
+
const getPublicServerUrl = (port) => resolvePublicServerUrl({
|
|
2551
|
+
cwd: serverState.cwd || process.cwd(),
|
|
2552
|
+
configRoot: serverState.configRoot || projectRoot,
|
|
2553
|
+
port
|
|
2554
|
+
});
|
|
2082
2555
|
return {
|
|
2083
2556
|
name: "inspecto-overlay",
|
|
2084
2557
|
enforce: "pre",
|
|
@@ -2091,7 +2564,7 @@ var InspectoPlugin = createUnplugin((userOptions = {}) => {
|
|
|
2091
2564
|
},
|
|
2092
2565
|
webpack: (compiler) => {
|
|
2093
2566
|
if (isProduction) return;
|
|
2094
|
-
injectWebpack(compiler, ensureServer, resolveClientModule);
|
|
2567
|
+
injectWebpack(compiler, ensureServer, getPublicServerUrl, resolveClientModule);
|
|
2095
2568
|
},
|
|
2096
2569
|
rspack: (compiler) => {
|
|
2097
2570
|
if (isProduction) return;
|
|
@@ -2117,7 +2590,10 @@ var InspectoPlugin = createUnplugin((userOptions = {}) => {
|
|
|
2117
2590
|
},
|
|
2118
2591
|
load(id) {
|
|
2119
2592
|
if (id === VITE_VIRTUAL_MODULE_ID) {
|
|
2120
|
-
return getViteVirtualModuleScript(
|
|
2593
|
+
return getViteVirtualModuleScript(
|
|
2594
|
+
serverPort ?? DEFAULT_PORT,
|
|
2595
|
+
getPublicServerUrl(serverPort ?? DEFAULT_PORT)
|
|
2596
|
+
);
|
|
2121
2597
|
}
|
|
2122
2598
|
return null;
|
|
2123
2599
|
},
|