@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
|
@@ -36,7 +36,7 @@ __export(rspack_exports, {
|
|
|
36
36
|
});
|
|
37
37
|
module.exports = __toCommonJS(rspack_exports);
|
|
38
38
|
|
|
39
|
-
// ../../node_modules/.pnpm/tsup@8.5.1_jiti@2.
|
|
39
|
+
// ../../node_modules/.pnpm/tsup@8.5.1_jiti@2.7.0_postcss@8.5.14_typescript@5.9.3_yaml@2.8.4/node_modules/tsup/assets/cjs_shims.js
|
|
40
40
|
var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.tagName.toUpperCase() === "SCRIPT" ? document.currentScript.src : new URL("main.js", document.baseURI).href;
|
|
41
41
|
var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
|
|
42
42
|
|
|
@@ -537,7 +537,6 @@ function dispatchPromptThroughIde(runtime, payload) {
|
|
|
537
537
|
line: payload.line,
|
|
538
538
|
column: payload.column,
|
|
539
539
|
snippet: payload.snippet,
|
|
540
|
-
...payload.screenshotContext ? { screenshotContext: payload.screenshotContext } : {},
|
|
541
540
|
overrides: runtime.overrides,
|
|
542
541
|
autoSend: runtime.autoSend
|
|
543
542
|
});
|
|
@@ -671,6 +670,188 @@ function assertPathWithinIdeOpenScope(file, projectRoot) {
|
|
|
671
670
|
}
|
|
672
671
|
}
|
|
673
672
|
|
|
673
|
+
// src/server/session-store.ts
|
|
674
|
+
var DEFAULT_STATUS = "pending";
|
|
675
|
+
function createAnnotationSessionStore(options = {}) {
|
|
676
|
+
const sessions = /* @__PURE__ */ new Map();
|
|
677
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
678
|
+
const now = options.now ?? (() => Date.now());
|
|
679
|
+
const createId = options.createId ?? createRandomId;
|
|
680
|
+
function findNewestMatchingSession(statuses) {
|
|
681
|
+
return [...sessions.values()].filter((session) => statuses ? statuses.has(session.status) : true).sort((left, right) => right.updatedAt - left.updatedAt)[0] ?? null;
|
|
682
|
+
}
|
|
683
|
+
function updateSessionStatus(id, status) {
|
|
684
|
+
const session = sessions.get(id);
|
|
685
|
+
if (!session) return null;
|
|
686
|
+
const timestamp = now();
|
|
687
|
+
session.status = status;
|
|
688
|
+
session.updatedAt = timestamp;
|
|
689
|
+
if (status === "acknowledged") {
|
|
690
|
+
session.acknowledgedAt = timestamp;
|
|
691
|
+
}
|
|
692
|
+
if (status === "resolved") {
|
|
693
|
+
session.resolvedAt = timestamp;
|
|
694
|
+
}
|
|
695
|
+
emit({ type: "session-status-updated", session });
|
|
696
|
+
return cloneSession(session);
|
|
697
|
+
}
|
|
698
|
+
function claimSession(id, statuses) {
|
|
699
|
+
const session = sessions.get(id);
|
|
700
|
+
if (!session || statuses && !statuses.has(session.status)) return null;
|
|
701
|
+
if (session.status === "acknowledged") return cloneSession(session);
|
|
702
|
+
return updateSessionStatus(id, "acknowledged");
|
|
703
|
+
}
|
|
704
|
+
function emit(event) {
|
|
705
|
+
const snapshot = cloneSession(event.session);
|
|
706
|
+
for (const listener of listeners) {
|
|
707
|
+
listener({ type: event.type, session: snapshot });
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
const store = {
|
|
711
|
+
createSession(input) {
|
|
712
|
+
const timestamp = now();
|
|
713
|
+
const session = {
|
|
714
|
+
id: createId(),
|
|
715
|
+
instruction: input.instruction?.trim() ?? "",
|
|
716
|
+
annotations: cloneArray(input.annotations),
|
|
717
|
+
...input.deliveryMode ? { deliveryMode: input.deliveryMode } : {},
|
|
718
|
+
status: DEFAULT_STATUS,
|
|
719
|
+
messages: cloneArray(input.messages ?? []),
|
|
720
|
+
createdAt: timestamp,
|
|
721
|
+
updatedAt: timestamp,
|
|
722
|
+
...input.runtimeContext ? { runtimeContext: cloneValue(input.runtimeContext) } : {},
|
|
723
|
+
...input.cssContextPrompt?.trim() ? { cssContextPrompt: input.cssContextPrompt.trim() } : {},
|
|
724
|
+
...input.pageUrl ? { pageUrl: input.pageUrl } : {},
|
|
725
|
+
...input.route ? { route: input.route } : {}
|
|
726
|
+
};
|
|
727
|
+
sessions.set(session.id, session);
|
|
728
|
+
emit({ type: "session-created", session });
|
|
729
|
+
return cloneSession(session);
|
|
730
|
+
},
|
|
731
|
+
getSession(id) {
|
|
732
|
+
const session = sessions.get(id);
|
|
733
|
+
return session ? cloneSession(session) : null;
|
|
734
|
+
},
|
|
735
|
+
listSessions(options2 = {}) {
|
|
736
|
+
const statuses = normalizeStatuses(options2.status);
|
|
737
|
+
return [...sessions.values()].filter((session) => statuses ? statuses.has(session.status) : true).sort((left, right) => right.updatedAt - left.updatedAt).map((session) => cloneSession(session));
|
|
738
|
+
},
|
|
739
|
+
async claimNextSession(options2 = {}) {
|
|
740
|
+
const statuses = normalizeStatuses(DEFAULT_STATUS);
|
|
741
|
+
const existingSession = findNewestMatchingSession(statuses);
|
|
742
|
+
if (existingSession) {
|
|
743
|
+
return {
|
|
744
|
+
session: claimSession(existingSession.id, statuses),
|
|
745
|
+
timedOut: false,
|
|
746
|
+
matchedExisting: true
|
|
747
|
+
};
|
|
748
|
+
}
|
|
749
|
+
const timeoutMs = normalizeTimeoutMs(options2.timeoutMs);
|
|
750
|
+
if (timeoutMs === 0) {
|
|
751
|
+
return {
|
|
752
|
+
session: null,
|
|
753
|
+
timedOut: true,
|
|
754
|
+
matchedExisting: false
|
|
755
|
+
};
|
|
756
|
+
}
|
|
757
|
+
return await new Promise((resolve2) => {
|
|
758
|
+
let settled = false;
|
|
759
|
+
let timeout = null;
|
|
760
|
+
const finish = (result) => {
|
|
761
|
+
if (settled) return;
|
|
762
|
+
settled = true;
|
|
763
|
+
unsubscribe();
|
|
764
|
+
if (timeout) {
|
|
765
|
+
clearTimeout(timeout);
|
|
766
|
+
}
|
|
767
|
+
resolve2(result);
|
|
768
|
+
};
|
|
769
|
+
const unsubscribe = this.subscribe((event) => {
|
|
770
|
+
const session = claimSession(event.session.id, statuses);
|
|
771
|
+
if (!session) return;
|
|
772
|
+
finish({
|
|
773
|
+
session,
|
|
774
|
+
timedOut: false,
|
|
775
|
+
matchedExisting: false,
|
|
776
|
+
event: event.type
|
|
777
|
+
});
|
|
778
|
+
});
|
|
779
|
+
if (timeoutMs !== null) {
|
|
780
|
+
timeout = setTimeout(() => {
|
|
781
|
+
finish({
|
|
782
|
+
session: null,
|
|
783
|
+
timedOut: true,
|
|
784
|
+
matchedExisting: false
|
|
785
|
+
});
|
|
786
|
+
}, timeoutMs);
|
|
787
|
+
}
|
|
788
|
+
});
|
|
789
|
+
},
|
|
790
|
+
appendMessage(id, input) {
|
|
791
|
+
const session = sessions.get(id);
|
|
792
|
+
if (!session) return null;
|
|
793
|
+
const timestamp = now();
|
|
794
|
+
session.messages.push({
|
|
795
|
+
id: createId(),
|
|
796
|
+
role: input.role,
|
|
797
|
+
text: input.text,
|
|
798
|
+
createdAt: timestamp
|
|
799
|
+
});
|
|
800
|
+
session.updatedAt = timestamp;
|
|
801
|
+
if (input.role === "agent" && isPendingLikeStatus(session.status)) {
|
|
802
|
+
session.status = "in_progress";
|
|
803
|
+
}
|
|
804
|
+
emit({ type: "session-message-appended", session });
|
|
805
|
+
return cloneSession(session);
|
|
806
|
+
},
|
|
807
|
+
updateStatus(id, status) {
|
|
808
|
+
return updateSessionStatus(id, status);
|
|
809
|
+
},
|
|
810
|
+
subscribe(listener) {
|
|
811
|
+
listeners.add(listener);
|
|
812
|
+
return () => {
|
|
813
|
+
listeners.delete(listener);
|
|
814
|
+
};
|
|
815
|
+
},
|
|
816
|
+
clear() {
|
|
817
|
+
sessions.clear();
|
|
818
|
+
listeners.clear();
|
|
819
|
+
}
|
|
820
|
+
};
|
|
821
|
+
return store;
|
|
822
|
+
}
|
|
823
|
+
var annotationSessionStore = createAnnotationSessionStore();
|
|
824
|
+
function normalizeStatuses(status) {
|
|
825
|
+
if (!status) return null;
|
|
826
|
+
return new Set(Array.isArray(status) ? status : [status]);
|
|
827
|
+
}
|
|
828
|
+
function normalizeTimeoutMs(value) {
|
|
829
|
+
if (value === void 0) return null;
|
|
830
|
+
if (!Number.isFinite(value)) return 0;
|
|
831
|
+
return Math.max(0, Math.floor(value));
|
|
832
|
+
}
|
|
833
|
+
function isPendingLikeStatus(status) {
|
|
834
|
+
return status === "pending" || status === "acknowledged";
|
|
835
|
+
}
|
|
836
|
+
function hasAgentReply(session) {
|
|
837
|
+
return session.messages.some((message) => message.role === "agent" && Boolean(message.text?.trim()));
|
|
838
|
+
}
|
|
839
|
+
function createRandomId() {
|
|
840
|
+
return `annotation-session-${Math.random().toString(36).slice(2, 10)}`;
|
|
841
|
+
}
|
|
842
|
+
function cloneSession(session) {
|
|
843
|
+
return cloneValue(session);
|
|
844
|
+
}
|
|
845
|
+
function cloneArray(value) {
|
|
846
|
+
return cloneValue(value);
|
|
847
|
+
}
|
|
848
|
+
function cloneValue(value) {
|
|
849
|
+
if (typeof structuredClone === "function") {
|
|
850
|
+
return structuredClone(value);
|
|
851
|
+
}
|
|
852
|
+
return JSON.parse(JSON.stringify(value));
|
|
853
|
+
}
|
|
854
|
+
|
|
674
855
|
// src/server/annotation-dispatch.ts
|
|
675
856
|
var AnnotationDispatchError = class extends Error {
|
|
676
857
|
constructor(message, errorCode) {
|
|
@@ -679,20 +860,30 @@ var AnnotationDispatchError = class extends Error {
|
|
|
679
860
|
this.errorCode = errorCode;
|
|
680
861
|
}
|
|
681
862
|
};
|
|
682
|
-
async function dispatchAnnotationsToAi(req, state) {
|
|
863
|
+
async function dispatchAnnotationsToAi(req, state, store = annotationSessionStore) {
|
|
683
864
|
try {
|
|
684
865
|
validateAnnotationDispatchRequest(req, state);
|
|
685
866
|
const batch = normalizeAnnotationBatch(req);
|
|
686
867
|
const prompt = buildAnnotationBatchPrompt(batch);
|
|
868
|
+
const deliveryMode = normalizeDeliveryMode(req.deliveryMode);
|
|
869
|
+
const session = store.createSession({
|
|
870
|
+
instruction: batch.instruction,
|
|
871
|
+
annotations: toSessionAnnotations(batch.annotations),
|
|
872
|
+
deliveryMode,
|
|
873
|
+
...batch.runtimeContext ? { runtimeContext: batch.runtimeContext } : {},
|
|
874
|
+
...batch.cssContextPrompt ? { cssContextPrompt: batch.cssContextPrompt } : {}
|
|
875
|
+
});
|
|
687
876
|
const representativeTarget = batch.annotations[0]?.targets[0];
|
|
688
|
-
const
|
|
689
|
-
return dispatchPromptThroughIde(runtime, {
|
|
877
|
+
const dispatchResult = deliveryMode === "ide" ? dispatchPromptThroughIde(resolvePromptDispatchRuntime(state), {
|
|
690
878
|
prompt,
|
|
691
879
|
...representativeTarget?.file ? { filePath: representativeTarget.file } : {},
|
|
692
880
|
...representativeTarget?.line ? { line: representativeTarget.line } : {},
|
|
693
|
-
...representativeTarget?.column ? { column: representativeTarget.column } : {}
|
|
694
|
-
|
|
695
|
-
|
|
881
|
+
...representativeTarget?.column ? { column: representativeTarget.column } : {}
|
|
882
|
+
}) : { success: true };
|
|
883
|
+
return {
|
|
884
|
+
...dispatchResult,
|
|
885
|
+
session: toSessionSummary(session)
|
|
886
|
+
};
|
|
696
887
|
} catch (error) {
|
|
697
888
|
return {
|
|
698
889
|
success: false,
|
|
@@ -701,6 +892,41 @@ async function dispatchAnnotationsToAi(req, state) {
|
|
|
701
892
|
};
|
|
702
893
|
}
|
|
703
894
|
}
|
|
895
|
+
function normalizeDeliveryMode(input) {
|
|
896
|
+
return input === "agent" ? "agent" : "ide";
|
|
897
|
+
}
|
|
898
|
+
function toSessionAnnotations(annotations) {
|
|
899
|
+
return annotations.map((annotation) => ({
|
|
900
|
+
id: `annotation-${annotation.index}`,
|
|
901
|
+
note: annotation.note,
|
|
902
|
+
intent: annotation.intent,
|
|
903
|
+
targets: annotation.targets.map((target, targetIndex) => ({
|
|
904
|
+
id: `annotation-${annotation.index}-target-${targetIndex + 1}`,
|
|
905
|
+
label: target.label ?? "Unknown target",
|
|
906
|
+
location: {
|
|
907
|
+
file: target.file,
|
|
908
|
+
line: target.line,
|
|
909
|
+
column: target.column
|
|
910
|
+
},
|
|
911
|
+
...target.selector ? { selector: target.selector } : {},
|
|
912
|
+
...target.snippet ? { snippet: target.snippet } : {},
|
|
913
|
+
rect: {
|
|
914
|
+
x: 0,
|
|
915
|
+
y: 0,
|
|
916
|
+
width: 0,
|
|
917
|
+
height: 0
|
|
918
|
+
}
|
|
919
|
+
}))
|
|
920
|
+
}));
|
|
921
|
+
}
|
|
922
|
+
function toSessionSummary(session) {
|
|
923
|
+
return {
|
|
924
|
+
id: session.id,
|
|
925
|
+
status: session.status,
|
|
926
|
+
createdAt: session.createdAt,
|
|
927
|
+
updatedAt: session.updatedAt
|
|
928
|
+
};
|
|
929
|
+
}
|
|
704
930
|
function validateAnnotationDispatchRequest(req, state) {
|
|
705
931
|
if (!req.annotations.length) {
|
|
706
932
|
throw new AnnotationDispatchError("At least one annotation is required.", "INVALID_REQUEST");
|
|
@@ -721,9 +947,7 @@ function validateAnnotationDispatchRequest(req, state) {
|
|
|
721
947
|
function normalizeAnnotationBatch(req) {
|
|
722
948
|
return {
|
|
723
949
|
instruction: req.instruction?.trim() ?? "",
|
|
724
|
-
responseMode: req.responseMode ?? "unified",
|
|
725
950
|
...req.runtimeContext ? { runtimeContext: req.runtimeContext } : {},
|
|
726
|
-
...req.screenshotContext ? { screenshotContext: req.screenshotContext } : {},
|
|
727
951
|
...req.cssContextPrompt?.trim() ? { cssContextPrompt: req.cssContextPrompt.trim() } : {},
|
|
728
952
|
annotations: req.annotations.map((annotation, index) => ({
|
|
729
953
|
index: index + 1,
|
|
@@ -745,12 +969,9 @@ function buildAnnotationBatchPrompt(batch) {
|
|
|
745
969
|
const prompt = batch.instruction ? `${batch.instruction}
|
|
746
970
|
|
|
747
971
|
${body}` : body;
|
|
748
|
-
return
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
batch.cssContextPrompt
|
|
752
|
-
),
|
|
753
|
-
batch.screenshotContext
|
|
972
|
+
return appendCssContextSection(
|
|
973
|
+
appendRuntimeContextSection(prompt, batch.runtimeContext),
|
|
974
|
+
batch.cssContextPrompt
|
|
754
975
|
);
|
|
755
976
|
}
|
|
756
977
|
function appendCssContextSection(prompt, cssContextPrompt) {
|
|
@@ -777,20 +998,6 @@ function buildSelectedElementsPrompt(annotations) {
|
|
|
777
998
|
}
|
|
778
999
|
return lines.join("\n");
|
|
779
1000
|
}
|
|
780
|
-
function appendScreenshotContextSection(prompt, screenshotContext) {
|
|
781
|
-
if (!screenshotContext || !screenshotContext.imageDataUrl && !screenshotContext.imageAssetId) {
|
|
782
|
-
return prompt;
|
|
783
|
-
}
|
|
784
|
-
const lines = [
|
|
785
|
-
"Visual screenshot context attached:",
|
|
786
|
-
`- capturedAt=${screenshotContext.capturedAt}`,
|
|
787
|
-
`- mimeType=${screenshotContext.mimeType}`,
|
|
788
|
-
...screenshotContext.imageAssetId ? [`- imageAssetId=${screenshotContext.imageAssetId}`] : []
|
|
789
|
-
];
|
|
790
|
-
return `${prompt}
|
|
791
|
-
|
|
792
|
-
${lines.join("\n")}`;
|
|
793
|
-
}
|
|
794
1001
|
function appendRuntimeContextSection(prompt, runtimeContext) {
|
|
795
1002
|
if (!runtimeContext?.records.length) {
|
|
796
1003
|
return prompt;
|
|
@@ -838,7 +1045,7 @@ async function buildClientConfig(serverState2) {
|
|
|
838
1045
|
...info,
|
|
839
1046
|
prompts: resolveIntents(promptsConfig),
|
|
840
1047
|
hotKeys: userConfig["inspector.hotKey"] ?? "alt",
|
|
841
|
-
|
|
1048
|
+
annotateDeliveryMode: userConfig["annotate.deliveryMode"] ?? "both",
|
|
842
1049
|
includeSnippet: userConfig["prompt.includeSnippet"] ?? false,
|
|
843
1050
|
runtimeContext: {
|
|
844
1051
|
enabled: true,
|
|
@@ -846,10 +1053,6 @@ async function buildClientConfig(serverState2) {
|
|
|
846
1053
|
maxRuntimeErrors: 3,
|
|
847
1054
|
maxFailedRequests: 2
|
|
848
1055
|
},
|
|
849
|
-
screenshotContext: {
|
|
850
|
-
enabled: false
|
|
851
|
-
},
|
|
852
|
-
annotationResponseMode: userConfig["prompt.annotationResponseMode"] ?? "unified",
|
|
853
1056
|
autoSend: userConfig["prompt.autoSend"] ?? false
|
|
854
1057
|
};
|
|
855
1058
|
}
|
|
@@ -894,7 +1097,7 @@ function handleOpenFileRequest(body, serverState2) {
|
|
|
894
1097
|
else if (rawEditorHint === "vscodium") editorHint = "codium";
|
|
895
1098
|
else if (rawEditorHint === "trae-cn" || rawEditorHint === "trae") editorHint = "trae";
|
|
896
1099
|
serverLogger2.debug(
|
|
897
|
-
`
|
|
1100
|
+
`SOURCE_OPEN: activeIde=${activeIde}, activeIdeScheme=${activeIdeScheme}, configuredIde=${configuredIde} -> rawEditorHint=${rawEditorHint}, finalEditorHint=${editorHint}`
|
|
898
1101
|
);
|
|
899
1102
|
if (VSCODE_FAMILY_SCHEMES.includes(rawEditorHint)) {
|
|
900
1103
|
let normalizedPath = absolutePath.replace(/\\/g, "/");
|
|
@@ -903,7 +1106,7 @@ function handleOpenFileRequest(body, serverState2) {
|
|
|
903
1106
|
}
|
|
904
1107
|
const encodedPath = encodeURI(normalizedPath);
|
|
905
1108
|
const uri = `${rawEditorHint}://file${encodedPath}:${body.line}:${body.column}`;
|
|
906
|
-
serverLogger2.debug(`
|
|
1109
|
+
serverLogger2.debug(`SOURCE_OPEN: Bypassing launchIDE, using URI scheme directly: ${uri}`);
|
|
907
1110
|
try {
|
|
908
1111
|
if (process.platform === "darwin") {
|
|
909
1112
|
(0, import_node_child_process2.execFileSync)("open", [uri]);
|
|
@@ -913,7 +1116,7 @@ function handleOpenFileRequest(body, serverState2) {
|
|
|
913
1116
|
(0, import_node_child_process2.execFileSync)("xdg-open", [uri]);
|
|
914
1117
|
}
|
|
915
1118
|
} catch (e) {
|
|
916
|
-
serverLogger2.error(`Failed to launch URI for
|
|
1119
|
+
serverLogger2.error(`Failed to launch URI for SOURCE_OPEN (${uri}):`, e);
|
|
917
1120
|
(0, import_launch_ide2.launchIDE)({
|
|
918
1121
|
file: absolutePath,
|
|
919
1122
|
line: body.line,
|
|
@@ -968,8 +1171,18 @@ function resolveProjectRoot() {
|
|
|
968
1171
|
return gitRoot;
|
|
969
1172
|
}
|
|
970
1173
|
|
|
1174
|
+
// src/server/server-url.ts
|
|
1175
|
+
function resolveServerHost(cwd, configRoot) {
|
|
1176
|
+
const userConfig = loadUserConfigSync(false, cwd, configRoot);
|
|
1177
|
+
const configuredHost = userConfig["server.host"]?.trim();
|
|
1178
|
+
if (configuredHost) return configuredHost;
|
|
1179
|
+
if (process.env["VITEST"]) return "127.0.0.1";
|
|
1180
|
+
return "127.0.0.1";
|
|
1181
|
+
}
|
|
1182
|
+
|
|
971
1183
|
// src/server/index.ts
|
|
972
1184
|
var serverLogger4 = createLogger("inspecto:server", { logLevel: getGlobalLogLevel() });
|
|
1185
|
+
var PORT_FILE_NAME = "inspecto.port.json";
|
|
973
1186
|
var serverState = {
|
|
974
1187
|
port: null,
|
|
975
1188
|
running: false,
|
|
@@ -978,6 +1191,42 @@ var serverState = {
|
|
|
978
1191
|
cwd: process.cwd()
|
|
979
1192
|
};
|
|
980
1193
|
var serverInstance = null;
|
|
1194
|
+
function getPortFilePath() {
|
|
1195
|
+
return import_node_path4.default.join(import_node_os2.default.tmpdir(), PORT_FILE_NAME);
|
|
1196
|
+
}
|
|
1197
|
+
function getProjectRootHash() {
|
|
1198
|
+
if (!serverState.projectRoot) return null;
|
|
1199
|
+
return import_node_crypto2.default.createHash("md5").update(serverState.projectRoot).digest("hex");
|
|
1200
|
+
}
|
|
1201
|
+
function readPortData(portFile) {
|
|
1202
|
+
if (!import_node_fs4.default.existsSync(portFile)) return {};
|
|
1203
|
+
try {
|
|
1204
|
+
return JSON.parse(import_node_fs4.default.readFileSync(portFile, "utf-8"));
|
|
1205
|
+
} catch {
|
|
1206
|
+
return {};
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
function writeProjectPort(port) {
|
|
1210
|
+
const rootHash = getProjectRootHash();
|
|
1211
|
+
if (!rootHash) return;
|
|
1212
|
+
const portFile = getPortFilePath();
|
|
1213
|
+
const portData = readPortData(portFile);
|
|
1214
|
+
portData[rootHash] = port;
|
|
1215
|
+
import_node_fs4.default.writeFileSync(portFile, JSON.stringify(portData, null, 2), "utf-8");
|
|
1216
|
+
}
|
|
1217
|
+
function removeProjectPort() {
|
|
1218
|
+
const rootHash = getProjectRootHash();
|
|
1219
|
+
if (!rootHash) return;
|
|
1220
|
+
const portFile = getPortFilePath();
|
|
1221
|
+
if (!import_node_fs4.default.existsSync(portFile)) return;
|
|
1222
|
+
const portData = readPortData(portFile);
|
|
1223
|
+
delete portData[rootHash];
|
|
1224
|
+
if (Object.keys(portData).length === 0) {
|
|
1225
|
+
import_node_fs4.default.unlinkSync(portFile);
|
|
1226
|
+
} else {
|
|
1227
|
+
import_node_fs4.default.writeFileSync(portFile, JSON.stringify(portData, null, 2), "utf-8");
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
981
1230
|
async function startServer() {
|
|
982
1231
|
if (serverState.running && serverState.port !== null) {
|
|
983
1232
|
return serverState.port;
|
|
@@ -985,6 +1234,7 @@ async function startServer() {
|
|
|
985
1234
|
serverState.projectRoot = resolveProjectRoot();
|
|
986
1235
|
serverState.configRoot = serverState.projectRoot;
|
|
987
1236
|
serverState.cwd = process.cwd();
|
|
1237
|
+
const serverHost = resolveServerHost(serverState.cwd, serverState.configRoot);
|
|
988
1238
|
import_portfinder.default.basePort = 5678;
|
|
989
1239
|
const port = await import_portfinder.default.getPortPromise();
|
|
990
1240
|
watchConfig(
|
|
@@ -1011,7 +1261,7 @@ async function startServer() {
|
|
|
1011
1261
|
});
|
|
1012
1262
|
});
|
|
1013
1263
|
await new Promise((resolve2, reject) => {
|
|
1014
|
-
serverInstance.listen(port,
|
|
1264
|
+
serverInstance.listen(port, serverHost, () => {
|
|
1015
1265
|
serverInstance.unref();
|
|
1016
1266
|
resolve2();
|
|
1017
1267
|
});
|
|
@@ -1022,37 +1272,18 @@ async function startServer() {
|
|
|
1022
1272
|
});
|
|
1023
1273
|
serverState.port = port;
|
|
1024
1274
|
serverState.running = true;
|
|
1025
|
-
const portFile = import_node_path4.default.join(import_node_os2.default.tmpdir(), "inspecto.port.json");
|
|
1026
1275
|
try {
|
|
1027
|
-
|
|
1028
|
-
if (import_node_fs4.default.existsSync(portFile)) {
|
|
1029
|
-
try {
|
|
1030
|
-
portData = JSON.parse(import_node_fs4.default.readFileSync(portFile, "utf-8"));
|
|
1031
|
-
} catch (_e) {
|
|
1032
|
-
}
|
|
1033
|
-
}
|
|
1034
|
-
const rootHash = import_node_crypto2.default.createHash("md5").update(serverState.projectRoot).digest("hex");
|
|
1035
|
-
portData[rootHash] = port;
|
|
1036
|
-
import_node_fs4.default.writeFileSync(portFile, JSON.stringify(portData, null, 2), "utf-8");
|
|
1276
|
+
writeProjectPort(port);
|
|
1037
1277
|
} catch (_e) {
|
|
1038
1278
|
serverLogger4.warn("Failed to write port file:", _e);
|
|
1039
1279
|
}
|
|
1040
1280
|
process.once("exit", () => {
|
|
1041
1281
|
try {
|
|
1042
|
-
|
|
1043
|
-
const portData = JSON.parse(import_node_fs4.default.readFileSync(portFile, "utf-8"));
|
|
1044
|
-
const rootHash = import_node_crypto2.default.createHash("md5").update(serverState.projectRoot).digest("hex");
|
|
1045
|
-
delete portData[rootHash];
|
|
1046
|
-
if (Object.keys(portData).length === 0) {
|
|
1047
|
-
import_node_fs4.default.unlinkSync(portFile);
|
|
1048
|
-
} else {
|
|
1049
|
-
import_node_fs4.default.writeFileSync(portFile, JSON.stringify(portData, null, 2), "utf-8");
|
|
1050
|
-
}
|
|
1051
|
-
}
|
|
1282
|
+
removeProjectPort();
|
|
1052
1283
|
} catch {
|
|
1053
1284
|
}
|
|
1054
1285
|
});
|
|
1055
|
-
serverLogger4.info(`server running at http
|
|
1286
|
+
serverLogger4.info(`server running at http://${serverHost}:${port}`);
|
|
1056
1287
|
return port;
|
|
1057
1288
|
}
|
|
1058
1289
|
async function readBody(req) {
|
|
@@ -1104,7 +1335,7 @@ async function handleRequest(url, req, res) {
|
|
|
1104
1335
|
}
|
|
1105
1336
|
return;
|
|
1106
1337
|
}
|
|
1107
|
-
if (pathname === import_types2.INSPECTO_API_PATHS.IDE_OPEN && req.method === "POST") {
|
|
1338
|
+
if ((pathname === import_types2.INSPECTO_API_PATHS.SOURCE_OPEN || pathname === import_types2.INSPECTO_API_PATHS.IDE_OPEN) && req.method === "POST") {
|
|
1108
1339
|
let body;
|
|
1109
1340
|
try {
|
|
1110
1341
|
body = JSON.parse(await readBody(req));
|
|
@@ -1117,7 +1348,7 @@ async function handleRequest(url, req, res) {
|
|
|
1117
1348
|
handleOpenFileRequest(body, serverState);
|
|
1118
1349
|
} catch (err) {
|
|
1119
1350
|
serverLogger4.warn(
|
|
1120
|
-
`Security: Blocked path traversal attempt in
|
|
1351
|
+
`Security: Blocked path traversal attempt in SOURCE_OPEN: ${body.file}. Reason: ${err.message}`
|
|
1121
1352
|
);
|
|
1122
1353
|
res.writeHead(403, { "Content-Type": "application/json" });
|
|
1123
1354
|
res.end(JSON.stringify({ error: "Access denied: File is outside of project workspace" }));
|
|
@@ -1191,6 +1422,212 @@ async function handleRequest(url, req, res) {
|
|
|
1191
1422
|
}
|
|
1192
1423
|
return;
|
|
1193
1424
|
}
|
|
1425
|
+
if (pathname === import_types2.INSPECTO_API_PATHS.SESSION_CLAIM_NEXT && req.method === "POST") {
|
|
1426
|
+
try {
|
|
1427
|
+
const rawBody = await readBody(req);
|
|
1428
|
+
const body = rawBody ? JSON.parse(rawBody) : {};
|
|
1429
|
+
const timeoutMs = normalizeSessionClaimTimeout(
|
|
1430
|
+
body.timeoutMs === void 0 ? null : String(body.timeoutMs)
|
|
1431
|
+
);
|
|
1432
|
+
const result = await annotationSessionStore.claimNextSession({
|
|
1433
|
+
...timeoutMs !== void 0 ? { timeoutMs } : {}
|
|
1434
|
+
});
|
|
1435
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
1436
|
+
res.end(
|
|
1437
|
+
JSON.stringify({
|
|
1438
|
+
success: true,
|
|
1439
|
+
timedOut: result.timedOut,
|
|
1440
|
+
matchedExisting: result.matchedExisting,
|
|
1441
|
+
...result.event ? { event: result.event } : {},
|
|
1442
|
+
...result.session ? { session: result.session } : {}
|
|
1443
|
+
})
|
|
1444
|
+
);
|
|
1445
|
+
} catch (e) {
|
|
1446
|
+
serverLogger4.error(`Error parsing session claim request:`, e);
|
|
1447
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
1448
|
+
res.end(JSON.stringify({ success: false, error: "Invalid JSON body" }));
|
|
1449
|
+
}
|
|
1450
|
+
return;
|
|
1451
|
+
}
|
|
1452
|
+
if (pathname === import_types2.INSPECTO_API_PATHS.SESSION_EVENTS && req.method === "GET") {
|
|
1453
|
+
const statusParam = url.searchParams.getAll("status");
|
|
1454
|
+
const statuses = statusParam.length ? new Set(statusParam) : null;
|
|
1455
|
+
const sessionId = url.searchParams.get("sessionId")?.trim() || null;
|
|
1456
|
+
res.writeHead(200, {
|
|
1457
|
+
"Content-Type": "text/event-stream",
|
|
1458
|
+
"Cache-Control": "no-cache",
|
|
1459
|
+
Connection: "keep-alive"
|
|
1460
|
+
});
|
|
1461
|
+
res.write(`event: ready
|
|
1462
|
+
data: ${JSON.stringify({ ok: true })}
|
|
1463
|
+
|
|
1464
|
+
`);
|
|
1465
|
+
const unsubscribe = annotationSessionStore.subscribe((event) => {
|
|
1466
|
+
if (sessionId && event.session.id !== sessionId) {
|
|
1467
|
+
return;
|
|
1468
|
+
}
|
|
1469
|
+
if (statuses && !statuses.has(event.session.status)) {
|
|
1470
|
+
return;
|
|
1471
|
+
}
|
|
1472
|
+
res.write(formatSessionSseEvent(event));
|
|
1473
|
+
});
|
|
1474
|
+
req.on("close", () => {
|
|
1475
|
+
unsubscribe();
|
|
1476
|
+
res.end();
|
|
1477
|
+
});
|
|
1478
|
+
return;
|
|
1479
|
+
}
|
|
1480
|
+
if (pathname === import_types2.INSPECTO_API_PATHS.SESSIONS && req.method === "GET") {
|
|
1481
|
+
const statusParam = url.searchParams.getAll("status");
|
|
1482
|
+
const sessions = annotationSessionStore.listSessions(
|
|
1483
|
+
statusParam.length ? {
|
|
1484
|
+
status: statusParam
|
|
1485
|
+
} : void 0
|
|
1486
|
+
);
|
|
1487
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
1488
|
+
res.end(JSON.stringify({ success: true, sessions }));
|
|
1489
|
+
return;
|
|
1490
|
+
}
|
|
1491
|
+
if (pathname.startsWith(`${import_types2.INSPECTO_API_PATHS.SESSIONS}/`) && req.method === "GET") {
|
|
1492
|
+
const sessionId = pathname.substring(import_types2.INSPECTO_API_PATHS.SESSIONS.length + 1);
|
|
1493
|
+
const session = annotationSessionStore.getSession(sessionId);
|
|
1494
|
+
if (!session) {
|
|
1495
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
1496
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
1497
|
+
return;
|
|
1498
|
+
}
|
|
1499
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
1500
|
+
res.end(JSON.stringify({ success: true, session }));
|
|
1501
|
+
return;
|
|
1502
|
+
}
|
|
1503
|
+
if (pathname.startsWith(`${import_types2.INSPECTO_API_PATHS.SESSIONS}/`) && pathname.endsWith(import_types2.INSPECTO_API_PATHS.SESSION_REPLY_SUFFIX) && req.method === "POST") {
|
|
1504
|
+
const sessionId = pathname.slice(
|
|
1505
|
+
import_types2.INSPECTO_API_PATHS.SESSIONS.length + 1,
|
|
1506
|
+
-import_types2.INSPECTO_API_PATHS.SESSION_REPLY_SUFFIX.length
|
|
1507
|
+
);
|
|
1508
|
+
try {
|
|
1509
|
+
const rawBody = await readBody(req);
|
|
1510
|
+
const body = JSON.parse(rawBody);
|
|
1511
|
+
if (!isAnnotationThreadRole(body.role)) {
|
|
1512
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
1513
|
+
res.end(JSON.stringify({ success: false, error: "Reply role is invalid." }));
|
|
1514
|
+
return;
|
|
1515
|
+
}
|
|
1516
|
+
if (!body.text?.trim()) {
|
|
1517
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
1518
|
+
res.end(JSON.stringify({ success: false, error: "Reply text is required." }));
|
|
1519
|
+
return;
|
|
1520
|
+
}
|
|
1521
|
+
const session = annotationSessionStore.appendMessage(sessionId, {
|
|
1522
|
+
role: body.role,
|
|
1523
|
+
text: body.text.trim()
|
|
1524
|
+
});
|
|
1525
|
+
if (!session) {
|
|
1526
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
1527
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
1528
|
+
return;
|
|
1529
|
+
}
|
|
1530
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
1531
|
+
res.end(JSON.stringify({ success: true, session }));
|
|
1532
|
+
} catch (e) {
|
|
1533
|
+
serverLogger4.error(`Error parsing session reply request:`, e);
|
|
1534
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
1535
|
+
res.end(JSON.stringify({ success: false, error: "Invalid JSON body" }));
|
|
1536
|
+
}
|
|
1537
|
+
return;
|
|
1538
|
+
}
|
|
1539
|
+
if (pathname.startsWith(`${import_types2.INSPECTO_API_PATHS.SESSIONS}/`) && pathname.endsWith(import_types2.INSPECTO_API_PATHS.SESSION_RESOLVE_SUFFIX) && req.method === "POST") {
|
|
1540
|
+
const sessionId = pathname.slice(
|
|
1541
|
+
import_types2.INSPECTO_API_PATHS.SESSIONS.length + 1,
|
|
1542
|
+
-import_types2.INSPECTO_API_PATHS.SESSION_RESOLVE_SUFFIX.length
|
|
1543
|
+
);
|
|
1544
|
+
try {
|
|
1545
|
+
const rawBody = await readBody(req);
|
|
1546
|
+
const body = rawBody ? JSON.parse(rawBody) : {};
|
|
1547
|
+
const message = body.message?.trim();
|
|
1548
|
+
const existingSession = annotationSessionStore.getSession(sessionId);
|
|
1549
|
+
if (!existingSession) {
|
|
1550
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
1551
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
1552
|
+
return;
|
|
1553
|
+
}
|
|
1554
|
+
if (!message && !hasAgentReply(existingSession)) {
|
|
1555
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
1556
|
+
res.end(
|
|
1557
|
+
JSON.stringify({
|
|
1558
|
+
success: false,
|
|
1559
|
+
error: "Resolve message is required until an agent reply is recorded."
|
|
1560
|
+
})
|
|
1561
|
+
);
|
|
1562
|
+
return;
|
|
1563
|
+
}
|
|
1564
|
+
if (message) {
|
|
1565
|
+
const repliedSession = annotationSessionStore.appendMessage(sessionId, {
|
|
1566
|
+
role: "agent",
|
|
1567
|
+
text: message
|
|
1568
|
+
});
|
|
1569
|
+
if (!repliedSession) {
|
|
1570
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
1571
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
1572
|
+
return;
|
|
1573
|
+
}
|
|
1574
|
+
}
|
|
1575
|
+
const session = annotationSessionStore.updateStatus(sessionId, "resolved");
|
|
1576
|
+
if (!session) {
|
|
1577
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
1578
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
1579
|
+
return;
|
|
1580
|
+
}
|
|
1581
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
1582
|
+
res.end(JSON.stringify({ success: true, session }));
|
|
1583
|
+
} catch (e) {
|
|
1584
|
+
serverLogger4.error(`Error parsing session resolve request:`, e);
|
|
1585
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
1586
|
+
res.end(JSON.stringify({ success: false, error: "Invalid JSON body" }));
|
|
1587
|
+
}
|
|
1588
|
+
return;
|
|
1589
|
+
}
|
|
1590
|
+
if (pathname.startsWith(`${import_types2.INSPECTO_API_PATHS.SESSIONS}/`) && pathname.endsWith(import_types2.INSPECTO_API_PATHS.SESSION_DISMISS_SUFFIX) && req.method === "POST") {
|
|
1591
|
+
const sessionId = pathname.slice(
|
|
1592
|
+
import_types2.INSPECTO_API_PATHS.SESSIONS.length + 1,
|
|
1593
|
+
-import_types2.INSPECTO_API_PATHS.SESSION_DISMISS_SUFFIX.length
|
|
1594
|
+
);
|
|
1595
|
+
try {
|
|
1596
|
+
const rawBody = await readBody(req);
|
|
1597
|
+
const body = rawBody ? JSON.parse(rawBody) : {};
|
|
1598
|
+
const message = body.message?.trim();
|
|
1599
|
+
const existingSession = annotationSessionStore.getSession(sessionId);
|
|
1600
|
+
if (!existingSession) {
|
|
1601
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
1602
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
1603
|
+
return;
|
|
1604
|
+
}
|
|
1605
|
+
if (message) {
|
|
1606
|
+
const repliedSession = annotationSessionStore.appendMessage(sessionId, {
|
|
1607
|
+
role: "agent",
|
|
1608
|
+
text: message
|
|
1609
|
+
});
|
|
1610
|
+
if (!repliedSession) {
|
|
1611
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
1612
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
1613
|
+
return;
|
|
1614
|
+
}
|
|
1615
|
+
}
|
|
1616
|
+
const session = annotationSessionStore.updateStatus(sessionId, "dismissed");
|
|
1617
|
+
if (!session) {
|
|
1618
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
1619
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
1620
|
+
return;
|
|
1621
|
+
}
|
|
1622
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
1623
|
+
res.end(JSON.stringify({ success: true, session }));
|
|
1624
|
+
} catch (e) {
|
|
1625
|
+
serverLogger4.error(`Error parsing session dismiss request:`, e);
|
|
1626
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
1627
|
+
res.end(JSON.stringify({ success: false, error: "Invalid JSON body" }));
|
|
1628
|
+
}
|
|
1629
|
+
return;
|
|
1630
|
+
}
|
|
1194
1631
|
if (pathname.startsWith(`${import_types2.INSPECTO_API_PATHS.AI_TICKET}/`) && req.method === "GET") {
|
|
1195
1632
|
const ticketId = pathname.substring(import_types2.INSPECTO_API_PATHS.AI_TICKET.length + 1);
|
|
1196
1633
|
const payloadStr = readTicket(ticketId);
|
|
@@ -1207,7 +1644,7 @@ async function handleRequest(url, req, res) {
|
|
|
1207
1644
|
res.end(JSON.stringify({ error: "not found" }));
|
|
1208
1645
|
}
|
|
1209
1646
|
async function dispatchToAi(req) {
|
|
1210
|
-
const { location, snippet, prompt
|
|
1647
|
+
const { location, snippet, prompt } = req;
|
|
1211
1648
|
const formattedPrompt = prompt ?? `Please help me with this code from \`${location.file}\` (line ${location.line}):
|
|
1212
1649
|
|
|
1213
1650
|
\`\`\`
|
|
@@ -1220,8 +1657,7 @@ ${snippet}
|
|
|
1220
1657
|
filePath: location.file,
|
|
1221
1658
|
line: location.line,
|
|
1222
1659
|
column: location.column,
|
|
1223
|
-
snippet
|
|
1224
|
-
...screenshotContext ? { screenshotContext } : {}
|
|
1660
|
+
snippet
|
|
1225
1661
|
});
|
|
1226
1662
|
}
|
|
1227
1663
|
function getBatchDispatchStatusCode(errorCode, success) {
|
|
@@ -1230,6 +1666,21 @@ function getBatchDispatchStatusCode(errorCode, success) {
|
|
|
1230
1666
|
if (errorCode === "FORBIDDEN_PATH") return 403;
|
|
1231
1667
|
return 500;
|
|
1232
1668
|
}
|
|
1669
|
+
function isAnnotationThreadRole(value) {
|
|
1670
|
+
return value === "user" || value === "agent" || value === "system";
|
|
1671
|
+
}
|
|
1672
|
+
function formatSessionSseEvent(event) {
|
|
1673
|
+
return `event: ${event.type}
|
|
1674
|
+
data: ${JSON.stringify(event)}
|
|
1675
|
+
|
|
1676
|
+
`;
|
|
1677
|
+
}
|
|
1678
|
+
function normalizeSessionClaimTimeout(value) {
|
|
1679
|
+
if (!value?.trim()) return 3e4;
|
|
1680
|
+
const parsed = Number.parseInt(value, 10);
|
|
1681
|
+
if (!Number.isFinite(parsed)) return 3e4;
|
|
1682
|
+
return Math.max(0, Math.min(parsed, 3e5));
|
|
1683
|
+
}
|
|
1233
1684
|
|
|
1234
1685
|
// src/injectors/utils.ts
|
|
1235
1686
|
var import_node_module = require("module");
|
|
@@ -1249,16 +1700,17 @@ var resolveClientModule = () => {
|
|
|
1249
1700
|
};
|
|
1250
1701
|
|
|
1251
1702
|
// src/injectors/webpack.ts
|
|
1252
|
-
function getWebpackHtmlScript(serverPort2) {
|
|
1703
|
+
function getWebpackHtmlScript(serverPort2, publicServerUrl) {
|
|
1253
1704
|
return `
|
|
1254
1705
|
window.__AI_INSPECTOR_PORT__ = ${serverPort2};
|
|
1255
|
-
window.
|
|
1256
|
-
|
|
1257
|
-
window.InspectoClient
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
}
|
|
1706
|
+
window.__AI_INSPECTOR_SERVER_URL__ = '${publicServerUrl ?? `http://127.0.0.1:${serverPort2}`}';
|
|
1707
|
+
window.addEventListener('load', () => {
|
|
1708
|
+
if (window.InspectoClient) {
|
|
1709
|
+
window.InspectoClient.mountInspector({
|
|
1710
|
+
serverUrl: window.__AI_INSPECTOR_SERVER_URL__,
|
|
1711
|
+
});
|
|
1712
|
+
}
|
|
1713
|
+
});
|
|
1262
1714
|
`;
|
|
1263
1715
|
}
|
|
1264
1716
|
|