@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/astro.js
CHANGED
|
@@ -520,7 +520,6 @@ function dispatchPromptThroughIde(runtime, payload) {
|
|
|
520
520
|
line: payload.line,
|
|
521
521
|
column: payload.column,
|
|
522
522
|
snippet: payload.snippet,
|
|
523
|
-
...payload.screenshotContext ? { screenshotContext: payload.screenshotContext } : {},
|
|
524
523
|
overrides: runtime.overrides,
|
|
525
524
|
autoSend: runtime.autoSend
|
|
526
525
|
});
|
|
@@ -654,6 +653,188 @@ function assertPathWithinIdeOpenScope(file, projectRoot) {
|
|
|
654
653
|
}
|
|
655
654
|
}
|
|
656
655
|
|
|
656
|
+
// src/server/session-store.ts
|
|
657
|
+
var DEFAULT_STATUS = "pending";
|
|
658
|
+
function createAnnotationSessionStore(options = {}) {
|
|
659
|
+
const sessions = /* @__PURE__ */ new Map();
|
|
660
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
661
|
+
const now = options.now ?? (() => Date.now());
|
|
662
|
+
const createId = options.createId ?? createRandomId;
|
|
663
|
+
function findNewestMatchingSession(statuses) {
|
|
664
|
+
return [...sessions.values()].filter((session) => statuses ? statuses.has(session.status) : true).sort((left, right) => right.updatedAt - left.updatedAt)[0] ?? null;
|
|
665
|
+
}
|
|
666
|
+
function updateSessionStatus(id, status) {
|
|
667
|
+
const session = sessions.get(id);
|
|
668
|
+
if (!session) return null;
|
|
669
|
+
const timestamp = now();
|
|
670
|
+
session.status = status;
|
|
671
|
+
session.updatedAt = timestamp;
|
|
672
|
+
if (status === "acknowledged") {
|
|
673
|
+
session.acknowledgedAt = timestamp;
|
|
674
|
+
}
|
|
675
|
+
if (status === "resolved") {
|
|
676
|
+
session.resolvedAt = timestamp;
|
|
677
|
+
}
|
|
678
|
+
emit({ type: "session-status-updated", session });
|
|
679
|
+
return cloneSession(session);
|
|
680
|
+
}
|
|
681
|
+
function claimSession(id, statuses) {
|
|
682
|
+
const session = sessions.get(id);
|
|
683
|
+
if (!session || statuses && !statuses.has(session.status)) return null;
|
|
684
|
+
if (session.status === "acknowledged") return cloneSession(session);
|
|
685
|
+
return updateSessionStatus(id, "acknowledged");
|
|
686
|
+
}
|
|
687
|
+
function emit(event) {
|
|
688
|
+
const snapshot = cloneSession(event.session);
|
|
689
|
+
for (const listener of listeners) {
|
|
690
|
+
listener({ type: event.type, session: snapshot });
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
const store = {
|
|
694
|
+
createSession(input) {
|
|
695
|
+
const timestamp = now();
|
|
696
|
+
const session = {
|
|
697
|
+
id: createId(),
|
|
698
|
+
instruction: input.instruction?.trim() ?? "",
|
|
699
|
+
annotations: cloneArray(input.annotations),
|
|
700
|
+
...input.deliveryMode ? { deliveryMode: input.deliveryMode } : {},
|
|
701
|
+
status: DEFAULT_STATUS,
|
|
702
|
+
messages: cloneArray(input.messages ?? []),
|
|
703
|
+
createdAt: timestamp,
|
|
704
|
+
updatedAt: timestamp,
|
|
705
|
+
...input.runtimeContext ? { runtimeContext: cloneValue(input.runtimeContext) } : {},
|
|
706
|
+
...input.cssContextPrompt?.trim() ? { cssContextPrompt: input.cssContextPrompt.trim() } : {},
|
|
707
|
+
...input.pageUrl ? { pageUrl: input.pageUrl } : {},
|
|
708
|
+
...input.route ? { route: input.route } : {}
|
|
709
|
+
};
|
|
710
|
+
sessions.set(session.id, session);
|
|
711
|
+
emit({ type: "session-created", session });
|
|
712
|
+
return cloneSession(session);
|
|
713
|
+
},
|
|
714
|
+
getSession(id) {
|
|
715
|
+
const session = sessions.get(id);
|
|
716
|
+
return session ? cloneSession(session) : null;
|
|
717
|
+
},
|
|
718
|
+
listSessions(options2 = {}) {
|
|
719
|
+
const statuses = normalizeStatuses(options2.status);
|
|
720
|
+
return [...sessions.values()].filter((session) => statuses ? statuses.has(session.status) : true).sort((left, right) => right.updatedAt - left.updatedAt).map((session) => cloneSession(session));
|
|
721
|
+
},
|
|
722
|
+
async claimNextSession(options2 = {}) {
|
|
723
|
+
const statuses = normalizeStatuses(DEFAULT_STATUS);
|
|
724
|
+
const existingSession = findNewestMatchingSession(statuses);
|
|
725
|
+
if (existingSession) {
|
|
726
|
+
return {
|
|
727
|
+
session: claimSession(existingSession.id, statuses),
|
|
728
|
+
timedOut: false,
|
|
729
|
+
matchedExisting: true
|
|
730
|
+
};
|
|
731
|
+
}
|
|
732
|
+
const timeoutMs = normalizeTimeoutMs(options2.timeoutMs);
|
|
733
|
+
if (timeoutMs === 0) {
|
|
734
|
+
return {
|
|
735
|
+
session: null,
|
|
736
|
+
timedOut: true,
|
|
737
|
+
matchedExisting: false
|
|
738
|
+
};
|
|
739
|
+
}
|
|
740
|
+
return await new Promise((resolve2) => {
|
|
741
|
+
let settled = false;
|
|
742
|
+
let timeout = null;
|
|
743
|
+
const finish = (result) => {
|
|
744
|
+
if (settled) return;
|
|
745
|
+
settled = true;
|
|
746
|
+
unsubscribe();
|
|
747
|
+
if (timeout) {
|
|
748
|
+
clearTimeout(timeout);
|
|
749
|
+
}
|
|
750
|
+
resolve2(result);
|
|
751
|
+
};
|
|
752
|
+
const unsubscribe = this.subscribe((event) => {
|
|
753
|
+
const session = claimSession(event.session.id, statuses);
|
|
754
|
+
if (!session) return;
|
|
755
|
+
finish({
|
|
756
|
+
session,
|
|
757
|
+
timedOut: false,
|
|
758
|
+
matchedExisting: false,
|
|
759
|
+
event: event.type
|
|
760
|
+
});
|
|
761
|
+
});
|
|
762
|
+
if (timeoutMs !== null) {
|
|
763
|
+
timeout = setTimeout(() => {
|
|
764
|
+
finish({
|
|
765
|
+
session: null,
|
|
766
|
+
timedOut: true,
|
|
767
|
+
matchedExisting: false
|
|
768
|
+
});
|
|
769
|
+
}, timeoutMs);
|
|
770
|
+
}
|
|
771
|
+
});
|
|
772
|
+
},
|
|
773
|
+
appendMessage(id, input) {
|
|
774
|
+
const session = sessions.get(id);
|
|
775
|
+
if (!session) return null;
|
|
776
|
+
const timestamp = now();
|
|
777
|
+
session.messages.push({
|
|
778
|
+
id: createId(),
|
|
779
|
+
role: input.role,
|
|
780
|
+
text: input.text,
|
|
781
|
+
createdAt: timestamp
|
|
782
|
+
});
|
|
783
|
+
session.updatedAt = timestamp;
|
|
784
|
+
if (input.role === "agent" && isPendingLikeStatus(session.status)) {
|
|
785
|
+
session.status = "in_progress";
|
|
786
|
+
}
|
|
787
|
+
emit({ type: "session-message-appended", session });
|
|
788
|
+
return cloneSession(session);
|
|
789
|
+
},
|
|
790
|
+
updateStatus(id, status) {
|
|
791
|
+
return updateSessionStatus(id, status);
|
|
792
|
+
},
|
|
793
|
+
subscribe(listener) {
|
|
794
|
+
listeners.add(listener);
|
|
795
|
+
return () => {
|
|
796
|
+
listeners.delete(listener);
|
|
797
|
+
};
|
|
798
|
+
},
|
|
799
|
+
clear() {
|
|
800
|
+
sessions.clear();
|
|
801
|
+
listeners.clear();
|
|
802
|
+
}
|
|
803
|
+
};
|
|
804
|
+
return store;
|
|
805
|
+
}
|
|
806
|
+
var annotationSessionStore = createAnnotationSessionStore();
|
|
807
|
+
function normalizeStatuses(status) {
|
|
808
|
+
if (!status) return null;
|
|
809
|
+
return new Set(Array.isArray(status) ? status : [status]);
|
|
810
|
+
}
|
|
811
|
+
function normalizeTimeoutMs(value) {
|
|
812
|
+
if (value === void 0) return null;
|
|
813
|
+
if (!Number.isFinite(value)) return 0;
|
|
814
|
+
return Math.max(0, Math.floor(value));
|
|
815
|
+
}
|
|
816
|
+
function isPendingLikeStatus(status) {
|
|
817
|
+
return status === "pending" || status === "acknowledged";
|
|
818
|
+
}
|
|
819
|
+
function hasAgentReply(session) {
|
|
820
|
+
return session.messages.some((message) => message.role === "agent" && Boolean(message.text?.trim()));
|
|
821
|
+
}
|
|
822
|
+
function createRandomId() {
|
|
823
|
+
return `annotation-session-${Math.random().toString(36).slice(2, 10)}`;
|
|
824
|
+
}
|
|
825
|
+
function cloneSession(session) {
|
|
826
|
+
return cloneValue(session);
|
|
827
|
+
}
|
|
828
|
+
function cloneArray(value) {
|
|
829
|
+
return cloneValue(value);
|
|
830
|
+
}
|
|
831
|
+
function cloneValue(value) {
|
|
832
|
+
if (typeof structuredClone === "function") {
|
|
833
|
+
return structuredClone(value);
|
|
834
|
+
}
|
|
835
|
+
return JSON.parse(JSON.stringify(value));
|
|
836
|
+
}
|
|
837
|
+
|
|
657
838
|
// src/server/annotation-dispatch.ts
|
|
658
839
|
var AnnotationDispatchError = class extends Error {
|
|
659
840
|
constructor(message, errorCode) {
|
|
@@ -662,20 +843,30 @@ var AnnotationDispatchError = class extends Error {
|
|
|
662
843
|
this.errorCode = errorCode;
|
|
663
844
|
}
|
|
664
845
|
};
|
|
665
|
-
async function dispatchAnnotationsToAi(req, state) {
|
|
846
|
+
async function dispatchAnnotationsToAi(req, state, store = annotationSessionStore) {
|
|
666
847
|
try {
|
|
667
848
|
validateAnnotationDispatchRequest(req, state);
|
|
668
849
|
const batch = normalizeAnnotationBatch(req);
|
|
669
850
|
const prompt = buildAnnotationBatchPrompt(batch);
|
|
851
|
+
const deliveryMode = normalizeDeliveryMode(req.deliveryMode);
|
|
852
|
+
const session = store.createSession({
|
|
853
|
+
instruction: batch.instruction,
|
|
854
|
+
annotations: toSessionAnnotations(batch.annotations),
|
|
855
|
+
deliveryMode,
|
|
856
|
+
...batch.runtimeContext ? { runtimeContext: batch.runtimeContext } : {},
|
|
857
|
+
...batch.cssContextPrompt ? { cssContextPrompt: batch.cssContextPrompt } : {}
|
|
858
|
+
});
|
|
670
859
|
const representativeTarget = batch.annotations[0]?.targets[0];
|
|
671
|
-
const
|
|
672
|
-
return dispatchPromptThroughIde(runtime, {
|
|
860
|
+
const dispatchResult = deliveryMode === "ide" ? dispatchPromptThroughIde(resolvePromptDispatchRuntime(state), {
|
|
673
861
|
prompt,
|
|
674
862
|
...representativeTarget?.file ? { filePath: representativeTarget.file } : {},
|
|
675
863
|
...representativeTarget?.line ? { line: representativeTarget.line } : {},
|
|
676
|
-
...representativeTarget?.column ? { column: representativeTarget.column } : {}
|
|
677
|
-
|
|
678
|
-
|
|
864
|
+
...representativeTarget?.column ? { column: representativeTarget.column } : {}
|
|
865
|
+
}) : { success: true };
|
|
866
|
+
return {
|
|
867
|
+
...dispatchResult,
|
|
868
|
+
session: toSessionSummary(session)
|
|
869
|
+
};
|
|
679
870
|
} catch (error) {
|
|
680
871
|
return {
|
|
681
872
|
success: false,
|
|
@@ -684,6 +875,41 @@ async function dispatchAnnotationsToAi(req, state) {
|
|
|
684
875
|
};
|
|
685
876
|
}
|
|
686
877
|
}
|
|
878
|
+
function normalizeDeliveryMode(input) {
|
|
879
|
+
return input === "agent" ? "agent" : "ide";
|
|
880
|
+
}
|
|
881
|
+
function toSessionAnnotations(annotations) {
|
|
882
|
+
return annotations.map((annotation) => ({
|
|
883
|
+
id: `annotation-${annotation.index}`,
|
|
884
|
+
note: annotation.note,
|
|
885
|
+
intent: annotation.intent,
|
|
886
|
+
targets: annotation.targets.map((target, targetIndex) => ({
|
|
887
|
+
id: `annotation-${annotation.index}-target-${targetIndex + 1}`,
|
|
888
|
+
label: target.label ?? "Unknown target",
|
|
889
|
+
location: {
|
|
890
|
+
file: target.file,
|
|
891
|
+
line: target.line,
|
|
892
|
+
column: target.column
|
|
893
|
+
},
|
|
894
|
+
...target.selector ? { selector: target.selector } : {},
|
|
895
|
+
...target.snippet ? { snippet: target.snippet } : {},
|
|
896
|
+
rect: {
|
|
897
|
+
x: 0,
|
|
898
|
+
y: 0,
|
|
899
|
+
width: 0,
|
|
900
|
+
height: 0
|
|
901
|
+
}
|
|
902
|
+
}))
|
|
903
|
+
}));
|
|
904
|
+
}
|
|
905
|
+
function toSessionSummary(session) {
|
|
906
|
+
return {
|
|
907
|
+
id: session.id,
|
|
908
|
+
status: session.status,
|
|
909
|
+
createdAt: session.createdAt,
|
|
910
|
+
updatedAt: session.updatedAt
|
|
911
|
+
};
|
|
912
|
+
}
|
|
687
913
|
function validateAnnotationDispatchRequest(req, state) {
|
|
688
914
|
if (!req.annotations.length) {
|
|
689
915
|
throw new AnnotationDispatchError("At least one annotation is required.", "INVALID_REQUEST");
|
|
@@ -704,9 +930,7 @@ function validateAnnotationDispatchRequest(req, state) {
|
|
|
704
930
|
function normalizeAnnotationBatch(req) {
|
|
705
931
|
return {
|
|
706
932
|
instruction: req.instruction?.trim() ?? "",
|
|
707
|
-
responseMode: req.responseMode ?? "unified",
|
|
708
933
|
...req.runtimeContext ? { runtimeContext: req.runtimeContext } : {},
|
|
709
|
-
...req.screenshotContext ? { screenshotContext: req.screenshotContext } : {},
|
|
710
934
|
...req.cssContextPrompt?.trim() ? { cssContextPrompt: req.cssContextPrompt.trim() } : {},
|
|
711
935
|
annotations: req.annotations.map((annotation, index) => ({
|
|
712
936
|
index: index + 1,
|
|
@@ -728,12 +952,9 @@ function buildAnnotationBatchPrompt(batch) {
|
|
|
728
952
|
const prompt = batch.instruction ? `${batch.instruction}
|
|
729
953
|
|
|
730
954
|
${body}` : body;
|
|
731
|
-
return
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
batch.cssContextPrompt
|
|
735
|
-
),
|
|
736
|
-
batch.screenshotContext
|
|
955
|
+
return appendCssContextSection(
|
|
956
|
+
appendRuntimeContextSection(prompt, batch.runtimeContext),
|
|
957
|
+
batch.cssContextPrompt
|
|
737
958
|
);
|
|
738
959
|
}
|
|
739
960
|
function appendCssContextSection(prompt, cssContextPrompt) {
|
|
@@ -760,20 +981,6 @@ function buildSelectedElementsPrompt(annotations) {
|
|
|
760
981
|
}
|
|
761
982
|
return lines.join("\n");
|
|
762
983
|
}
|
|
763
|
-
function appendScreenshotContextSection(prompt, screenshotContext) {
|
|
764
|
-
if (!screenshotContext || !screenshotContext.imageDataUrl && !screenshotContext.imageAssetId) {
|
|
765
|
-
return prompt;
|
|
766
|
-
}
|
|
767
|
-
const lines = [
|
|
768
|
-
"Visual screenshot context attached:",
|
|
769
|
-
`- capturedAt=${screenshotContext.capturedAt}`,
|
|
770
|
-
`- mimeType=${screenshotContext.mimeType}`,
|
|
771
|
-
...screenshotContext.imageAssetId ? [`- imageAssetId=${screenshotContext.imageAssetId}`] : []
|
|
772
|
-
];
|
|
773
|
-
return `${prompt}
|
|
774
|
-
|
|
775
|
-
${lines.join("\n")}`;
|
|
776
|
-
}
|
|
777
984
|
function appendRuntimeContextSection(prompt, runtimeContext) {
|
|
778
985
|
if (!runtimeContext?.records.length) {
|
|
779
986
|
return prompt;
|
|
@@ -821,7 +1028,7 @@ async function buildClientConfig(serverState2) {
|
|
|
821
1028
|
...info,
|
|
822
1029
|
prompts: resolveIntents(promptsConfig),
|
|
823
1030
|
hotKeys: userConfig["inspector.hotKey"] ?? "alt",
|
|
824
|
-
|
|
1031
|
+
annotateDeliveryMode: userConfig["annotate.deliveryMode"] ?? "both",
|
|
825
1032
|
includeSnippet: userConfig["prompt.includeSnippet"] ?? false,
|
|
826
1033
|
runtimeContext: {
|
|
827
1034
|
enabled: true,
|
|
@@ -829,10 +1036,6 @@ async function buildClientConfig(serverState2) {
|
|
|
829
1036
|
maxRuntimeErrors: 3,
|
|
830
1037
|
maxFailedRequests: 2
|
|
831
1038
|
},
|
|
832
|
-
screenshotContext: {
|
|
833
|
-
enabled: false
|
|
834
|
-
},
|
|
835
|
-
annotationResponseMode: userConfig["prompt.annotationResponseMode"] ?? "unified",
|
|
836
1039
|
autoSend: userConfig["prompt.autoSend"] ?? false
|
|
837
1040
|
};
|
|
838
1041
|
}
|
|
@@ -877,7 +1080,7 @@ function handleOpenFileRequest(body, serverState2) {
|
|
|
877
1080
|
else if (rawEditorHint === "vscodium") editorHint = "codium";
|
|
878
1081
|
else if (rawEditorHint === "trae-cn" || rawEditorHint === "trae") editorHint = "trae";
|
|
879
1082
|
serverLogger2.debug(
|
|
880
|
-
`
|
|
1083
|
+
`SOURCE_OPEN: activeIde=${activeIde}, activeIdeScheme=${activeIdeScheme}, configuredIde=${configuredIde} -> rawEditorHint=${rawEditorHint}, finalEditorHint=${editorHint}`
|
|
881
1084
|
);
|
|
882
1085
|
if (VSCODE_FAMILY_SCHEMES.includes(rawEditorHint)) {
|
|
883
1086
|
let normalizedPath = absolutePath.replace(/\\/g, "/");
|
|
@@ -886,7 +1089,7 @@ function handleOpenFileRequest(body, serverState2) {
|
|
|
886
1089
|
}
|
|
887
1090
|
const encodedPath = encodeURI(normalizedPath);
|
|
888
1091
|
const uri = `${rawEditorHint}://file${encodedPath}:${body.line}:${body.column}`;
|
|
889
|
-
serverLogger2.debug(`
|
|
1092
|
+
serverLogger2.debug(`SOURCE_OPEN: Bypassing launchIDE, using URI scheme directly: ${uri}`);
|
|
890
1093
|
try {
|
|
891
1094
|
if (process.platform === "darwin") {
|
|
892
1095
|
execFileSync2("open", [uri]);
|
|
@@ -896,7 +1099,7 @@ function handleOpenFileRequest(body, serverState2) {
|
|
|
896
1099
|
execFileSync2("xdg-open", [uri]);
|
|
897
1100
|
}
|
|
898
1101
|
} catch (e) {
|
|
899
|
-
serverLogger2.error(`Failed to launch URI for
|
|
1102
|
+
serverLogger2.error(`Failed to launch URI for SOURCE_OPEN (${uri}):`, e);
|
|
900
1103
|
launchIDE2({
|
|
901
1104
|
file: absolutePath,
|
|
902
1105
|
line: body.line,
|
|
@@ -951,8 +1154,27 @@ function resolveProjectRoot() {
|
|
|
951
1154
|
return gitRoot;
|
|
952
1155
|
}
|
|
953
1156
|
|
|
1157
|
+
// src/server/server-url.ts
|
|
1158
|
+
function resolveServerHost(cwd, configRoot) {
|
|
1159
|
+
const userConfig = loadUserConfigSync(false, cwd, configRoot);
|
|
1160
|
+
const configuredHost = userConfig["server.host"]?.trim();
|
|
1161
|
+
if (configuredHost) return configuredHost;
|
|
1162
|
+
if (process.env["VITEST"]) return "127.0.0.1";
|
|
1163
|
+
return "127.0.0.1";
|
|
1164
|
+
}
|
|
1165
|
+
function resolvePublicServerUrl(args) {
|
|
1166
|
+
const userConfig = loadUserConfigSync(false, args.cwd, args.configRoot);
|
|
1167
|
+
const configuredPublicUrl = userConfig["server.publicUrl"]?.trim();
|
|
1168
|
+
if (configuredPublicUrl) {
|
|
1169
|
+
return configuredPublicUrl.replace(/\/$/, "");
|
|
1170
|
+
}
|
|
1171
|
+
const host = resolveServerHost(args.cwd, args.configRoot);
|
|
1172
|
+
return `http://${host}:${args.port}`;
|
|
1173
|
+
}
|
|
1174
|
+
|
|
954
1175
|
// src/server/index.ts
|
|
955
1176
|
var serverLogger4 = createLogger("inspecto:server", { logLevel: getGlobalLogLevel() });
|
|
1177
|
+
var PORT_FILE_NAME = "inspecto.port.json";
|
|
956
1178
|
var serverState = {
|
|
957
1179
|
port: null,
|
|
958
1180
|
running: false,
|
|
@@ -961,6 +1183,42 @@ var serverState = {
|
|
|
961
1183
|
cwd: process.cwd()
|
|
962
1184
|
};
|
|
963
1185
|
var serverInstance = null;
|
|
1186
|
+
function getPortFilePath() {
|
|
1187
|
+
return path5.join(os2.tmpdir(), PORT_FILE_NAME);
|
|
1188
|
+
}
|
|
1189
|
+
function getProjectRootHash() {
|
|
1190
|
+
if (!serverState.projectRoot) return null;
|
|
1191
|
+
return crypto2.createHash("md5").update(serverState.projectRoot).digest("hex");
|
|
1192
|
+
}
|
|
1193
|
+
function readPortData(portFile) {
|
|
1194
|
+
if (!fs5.existsSync(portFile)) return {};
|
|
1195
|
+
try {
|
|
1196
|
+
return JSON.parse(fs5.readFileSync(portFile, "utf-8"));
|
|
1197
|
+
} catch {
|
|
1198
|
+
return {};
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
function writeProjectPort(port) {
|
|
1202
|
+
const rootHash = getProjectRootHash();
|
|
1203
|
+
if (!rootHash) return;
|
|
1204
|
+
const portFile = getPortFilePath();
|
|
1205
|
+
const portData = readPortData(portFile);
|
|
1206
|
+
portData[rootHash] = port;
|
|
1207
|
+
fs5.writeFileSync(portFile, JSON.stringify(portData, null, 2), "utf-8");
|
|
1208
|
+
}
|
|
1209
|
+
function removeProjectPort() {
|
|
1210
|
+
const rootHash = getProjectRootHash();
|
|
1211
|
+
if (!rootHash) return;
|
|
1212
|
+
const portFile = getPortFilePath();
|
|
1213
|
+
if (!fs5.existsSync(portFile)) return;
|
|
1214
|
+
const portData = readPortData(portFile);
|
|
1215
|
+
delete portData[rootHash];
|
|
1216
|
+
if (Object.keys(portData).length === 0) {
|
|
1217
|
+
fs5.unlinkSync(portFile);
|
|
1218
|
+
} else {
|
|
1219
|
+
fs5.writeFileSync(portFile, JSON.stringify(portData, null, 2), "utf-8");
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
964
1222
|
async function startServer() {
|
|
965
1223
|
if (serverState.running && serverState.port !== null) {
|
|
966
1224
|
return serverState.port;
|
|
@@ -968,6 +1226,7 @@ async function startServer() {
|
|
|
968
1226
|
serverState.projectRoot = resolveProjectRoot();
|
|
969
1227
|
serverState.configRoot = serverState.projectRoot;
|
|
970
1228
|
serverState.cwd = process.cwd();
|
|
1229
|
+
const serverHost = resolveServerHost(serverState.cwd, serverState.configRoot);
|
|
971
1230
|
portfinder.basePort = 5678;
|
|
972
1231
|
const port = await portfinder.getPortPromise();
|
|
973
1232
|
watchConfig(
|
|
@@ -994,7 +1253,7 @@ async function startServer() {
|
|
|
994
1253
|
});
|
|
995
1254
|
});
|
|
996
1255
|
await new Promise((resolve2, reject) => {
|
|
997
|
-
serverInstance.listen(port,
|
|
1256
|
+
serverInstance.listen(port, serverHost, () => {
|
|
998
1257
|
serverInstance.unref();
|
|
999
1258
|
resolve2();
|
|
1000
1259
|
});
|
|
@@ -1005,37 +1264,18 @@ async function startServer() {
|
|
|
1005
1264
|
});
|
|
1006
1265
|
serverState.port = port;
|
|
1007
1266
|
serverState.running = true;
|
|
1008
|
-
const portFile = path5.join(os2.tmpdir(), "inspecto.port.json");
|
|
1009
1267
|
try {
|
|
1010
|
-
|
|
1011
|
-
if (fs5.existsSync(portFile)) {
|
|
1012
|
-
try {
|
|
1013
|
-
portData = JSON.parse(fs5.readFileSync(portFile, "utf-8"));
|
|
1014
|
-
} catch (_e) {
|
|
1015
|
-
}
|
|
1016
|
-
}
|
|
1017
|
-
const rootHash = crypto2.createHash("md5").update(serverState.projectRoot).digest("hex");
|
|
1018
|
-
portData[rootHash] = port;
|
|
1019
|
-
fs5.writeFileSync(portFile, JSON.stringify(portData, null, 2), "utf-8");
|
|
1268
|
+
writeProjectPort(port);
|
|
1020
1269
|
} catch (_e) {
|
|
1021
1270
|
serverLogger4.warn("Failed to write port file:", _e);
|
|
1022
1271
|
}
|
|
1023
1272
|
process.once("exit", () => {
|
|
1024
1273
|
try {
|
|
1025
|
-
|
|
1026
|
-
const portData = JSON.parse(fs5.readFileSync(portFile, "utf-8"));
|
|
1027
|
-
const rootHash = crypto2.createHash("md5").update(serverState.projectRoot).digest("hex");
|
|
1028
|
-
delete portData[rootHash];
|
|
1029
|
-
if (Object.keys(portData).length === 0) {
|
|
1030
|
-
fs5.unlinkSync(portFile);
|
|
1031
|
-
} else {
|
|
1032
|
-
fs5.writeFileSync(portFile, JSON.stringify(portData, null, 2), "utf-8");
|
|
1033
|
-
}
|
|
1034
|
-
}
|
|
1274
|
+
removeProjectPort();
|
|
1035
1275
|
} catch {
|
|
1036
1276
|
}
|
|
1037
1277
|
});
|
|
1038
|
-
serverLogger4.info(`server running at http
|
|
1278
|
+
serverLogger4.info(`server running at http://${serverHost}:${port}`);
|
|
1039
1279
|
return port;
|
|
1040
1280
|
}
|
|
1041
1281
|
async function readBody(req) {
|
|
@@ -1087,7 +1327,7 @@ async function handleRequest(url, req, res) {
|
|
|
1087
1327
|
}
|
|
1088
1328
|
return;
|
|
1089
1329
|
}
|
|
1090
|
-
if (pathname === INSPECTO_API_PATHS.IDE_OPEN && req.method === "POST") {
|
|
1330
|
+
if ((pathname === INSPECTO_API_PATHS.SOURCE_OPEN || pathname === INSPECTO_API_PATHS.IDE_OPEN) && req.method === "POST") {
|
|
1091
1331
|
let body;
|
|
1092
1332
|
try {
|
|
1093
1333
|
body = JSON.parse(await readBody(req));
|
|
@@ -1100,7 +1340,7 @@ async function handleRequest(url, req, res) {
|
|
|
1100
1340
|
handleOpenFileRequest(body, serverState);
|
|
1101
1341
|
} catch (err) {
|
|
1102
1342
|
serverLogger4.warn(
|
|
1103
|
-
`Security: Blocked path traversal attempt in
|
|
1343
|
+
`Security: Blocked path traversal attempt in SOURCE_OPEN: ${body.file}. Reason: ${err.message}`
|
|
1104
1344
|
);
|
|
1105
1345
|
res.writeHead(403, { "Content-Type": "application/json" });
|
|
1106
1346
|
res.end(JSON.stringify({ error: "Access denied: File is outside of project workspace" }));
|
|
@@ -1174,6 +1414,212 @@ async function handleRequest(url, req, res) {
|
|
|
1174
1414
|
}
|
|
1175
1415
|
return;
|
|
1176
1416
|
}
|
|
1417
|
+
if (pathname === INSPECTO_API_PATHS.SESSION_CLAIM_NEXT && req.method === "POST") {
|
|
1418
|
+
try {
|
|
1419
|
+
const rawBody = await readBody(req);
|
|
1420
|
+
const body = rawBody ? JSON.parse(rawBody) : {};
|
|
1421
|
+
const timeoutMs = normalizeSessionClaimTimeout(
|
|
1422
|
+
body.timeoutMs === void 0 ? null : String(body.timeoutMs)
|
|
1423
|
+
);
|
|
1424
|
+
const result = await annotationSessionStore.claimNextSession({
|
|
1425
|
+
...timeoutMs !== void 0 ? { timeoutMs } : {}
|
|
1426
|
+
});
|
|
1427
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
1428
|
+
res.end(
|
|
1429
|
+
JSON.stringify({
|
|
1430
|
+
success: true,
|
|
1431
|
+
timedOut: result.timedOut,
|
|
1432
|
+
matchedExisting: result.matchedExisting,
|
|
1433
|
+
...result.event ? { event: result.event } : {},
|
|
1434
|
+
...result.session ? { session: result.session } : {}
|
|
1435
|
+
})
|
|
1436
|
+
);
|
|
1437
|
+
} catch (e) {
|
|
1438
|
+
serverLogger4.error(`Error parsing session claim request:`, e);
|
|
1439
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
1440
|
+
res.end(JSON.stringify({ success: false, error: "Invalid JSON body" }));
|
|
1441
|
+
}
|
|
1442
|
+
return;
|
|
1443
|
+
}
|
|
1444
|
+
if (pathname === INSPECTO_API_PATHS.SESSION_EVENTS && req.method === "GET") {
|
|
1445
|
+
const statusParam = url.searchParams.getAll("status");
|
|
1446
|
+
const statuses = statusParam.length ? new Set(statusParam) : null;
|
|
1447
|
+
const sessionId = url.searchParams.get("sessionId")?.trim() || null;
|
|
1448
|
+
res.writeHead(200, {
|
|
1449
|
+
"Content-Type": "text/event-stream",
|
|
1450
|
+
"Cache-Control": "no-cache",
|
|
1451
|
+
Connection: "keep-alive"
|
|
1452
|
+
});
|
|
1453
|
+
res.write(`event: ready
|
|
1454
|
+
data: ${JSON.stringify({ ok: true })}
|
|
1455
|
+
|
|
1456
|
+
`);
|
|
1457
|
+
const unsubscribe = annotationSessionStore.subscribe((event) => {
|
|
1458
|
+
if (sessionId && event.session.id !== sessionId) {
|
|
1459
|
+
return;
|
|
1460
|
+
}
|
|
1461
|
+
if (statuses && !statuses.has(event.session.status)) {
|
|
1462
|
+
return;
|
|
1463
|
+
}
|
|
1464
|
+
res.write(formatSessionSseEvent(event));
|
|
1465
|
+
});
|
|
1466
|
+
req.on("close", () => {
|
|
1467
|
+
unsubscribe();
|
|
1468
|
+
res.end();
|
|
1469
|
+
});
|
|
1470
|
+
return;
|
|
1471
|
+
}
|
|
1472
|
+
if (pathname === INSPECTO_API_PATHS.SESSIONS && req.method === "GET") {
|
|
1473
|
+
const statusParam = url.searchParams.getAll("status");
|
|
1474
|
+
const sessions = annotationSessionStore.listSessions(
|
|
1475
|
+
statusParam.length ? {
|
|
1476
|
+
status: statusParam
|
|
1477
|
+
} : void 0
|
|
1478
|
+
);
|
|
1479
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
1480
|
+
res.end(JSON.stringify({ success: true, sessions }));
|
|
1481
|
+
return;
|
|
1482
|
+
}
|
|
1483
|
+
if (pathname.startsWith(`${INSPECTO_API_PATHS.SESSIONS}/`) && req.method === "GET") {
|
|
1484
|
+
const sessionId = pathname.substring(INSPECTO_API_PATHS.SESSIONS.length + 1);
|
|
1485
|
+
const session = annotationSessionStore.getSession(sessionId);
|
|
1486
|
+
if (!session) {
|
|
1487
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
1488
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
1489
|
+
return;
|
|
1490
|
+
}
|
|
1491
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
1492
|
+
res.end(JSON.stringify({ success: true, session }));
|
|
1493
|
+
return;
|
|
1494
|
+
}
|
|
1495
|
+
if (pathname.startsWith(`${INSPECTO_API_PATHS.SESSIONS}/`) && pathname.endsWith(INSPECTO_API_PATHS.SESSION_REPLY_SUFFIX) && req.method === "POST") {
|
|
1496
|
+
const sessionId = pathname.slice(
|
|
1497
|
+
INSPECTO_API_PATHS.SESSIONS.length + 1,
|
|
1498
|
+
-INSPECTO_API_PATHS.SESSION_REPLY_SUFFIX.length
|
|
1499
|
+
);
|
|
1500
|
+
try {
|
|
1501
|
+
const rawBody = await readBody(req);
|
|
1502
|
+
const body = JSON.parse(rawBody);
|
|
1503
|
+
if (!isAnnotationThreadRole(body.role)) {
|
|
1504
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
1505
|
+
res.end(JSON.stringify({ success: false, error: "Reply role is invalid." }));
|
|
1506
|
+
return;
|
|
1507
|
+
}
|
|
1508
|
+
if (!body.text?.trim()) {
|
|
1509
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
1510
|
+
res.end(JSON.stringify({ success: false, error: "Reply text is required." }));
|
|
1511
|
+
return;
|
|
1512
|
+
}
|
|
1513
|
+
const session = annotationSessionStore.appendMessage(sessionId, {
|
|
1514
|
+
role: body.role,
|
|
1515
|
+
text: body.text.trim()
|
|
1516
|
+
});
|
|
1517
|
+
if (!session) {
|
|
1518
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
1519
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
1520
|
+
return;
|
|
1521
|
+
}
|
|
1522
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
1523
|
+
res.end(JSON.stringify({ success: true, session }));
|
|
1524
|
+
} catch (e) {
|
|
1525
|
+
serverLogger4.error(`Error parsing session reply request:`, e);
|
|
1526
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
1527
|
+
res.end(JSON.stringify({ success: false, error: "Invalid JSON body" }));
|
|
1528
|
+
}
|
|
1529
|
+
return;
|
|
1530
|
+
}
|
|
1531
|
+
if (pathname.startsWith(`${INSPECTO_API_PATHS.SESSIONS}/`) && pathname.endsWith(INSPECTO_API_PATHS.SESSION_RESOLVE_SUFFIX) && req.method === "POST") {
|
|
1532
|
+
const sessionId = pathname.slice(
|
|
1533
|
+
INSPECTO_API_PATHS.SESSIONS.length + 1,
|
|
1534
|
+
-INSPECTO_API_PATHS.SESSION_RESOLVE_SUFFIX.length
|
|
1535
|
+
);
|
|
1536
|
+
try {
|
|
1537
|
+
const rawBody = await readBody(req);
|
|
1538
|
+
const body = rawBody ? JSON.parse(rawBody) : {};
|
|
1539
|
+
const message = body.message?.trim();
|
|
1540
|
+
const existingSession = annotationSessionStore.getSession(sessionId);
|
|
1541
|
+
if (!existingSession) {
|
|
1542
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
1543
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
1544
|
+
return;
|
|
1545
|
+
}
|
|
1546
|
+
if (!message && !hasAgentReply(existingSession)) {
|
|
1547
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
1548
|
+
res.end(
|
|
1549
|
+
JSON.stringify({
|
|
1550
|
+
success: false,
|
|
1551
|
+
error: "Resolve message is required until an agent reply is recorded."
|
|
1552
|
+
})
|
|
1553
|
+
);
|
|
1554
|
+
return;
|
|
1555
|
+
}
|
|
1556
|
+
if (message) {
|
|
1557
|
+
const repliedSession = annotationSessionStore.appendMessage(sessionId, {
|
|
1558
|
+
role: "agent",
|
|
1559
|
+
text: message
|
|
1560
|
+
});
|
|
1561
|
+
if (!repliedSession) {
|
|
1562
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
1563
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
1564
|
+
return;
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1567
|
+
const session = annotationSessionStore.updateStatus(sessionId, "resolved");
|
|
1568
|
+
if (!session) {
|
|
1569
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
1570
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
1571
|
+
return;
|
|
1572
|
+
}
|
|
1573
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
1574
|
+
res.end(JSON.stringify({ success: true, session }));
|
|
1575
|
+
} catch (e) {
|
|
1576
|
+
serverLogger4.error(`Error parsing session resolve request:`, e);
|
|
1577
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
1578
|
+
res.end(JSON.stringify({ success: false, error: "Invalid JSON body" }));
|
|
1579
|
+
}
|
|
1580
|
+
return;
|
|
1581
|
+
}
|
|
1582
|
+
if (pathname.startsWith(`${INSPECTO_API_PATHS.SESSIONS}/`) && pathname.endsWith(INSPECTO_API_PATHS.SESSION_DISMISS_SUFFIX) && req.method === "POST") {
|
|
1583
|
+
const sessionId = pathname.slice(
|
|
1584
|
+
INSPECTO_API_PATHS.SESSIONS.length + 1,
|
|
1585
|
+
-INSPECTO_API_PATHS.SESSION_DISMISS_SUFFIX.length
|
|
1586
|
+
);
|
|
1587
|
+
try {
|
|
1588
|
+
const rawBody = await readBody(req);
|
|
1589
|
+
const body = rawBody ? JSON.parse(rawBody) : {};
|
|
1590
|
+
const message = body.message?.trim();
|
|
1591
|
+
const existingSession = annotationSessionStore.getSession(sessionId);
|
|
1592
|
+
if (!existingSession) {
|
|
1593
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
1594
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
1595
|
+
return;
|
|
1596
|
+
}
|
|
1597
|
+
if (message) {
|
|
1598
|
+
const repliedSession = annotationSessionStore.appendMessage(sessionId, {
|
|
1599
|
+
role: "agent",
|
|
1600
|
+
text: message
|
|
1601
|
+
});
|
|
1602
|
+
if (!repliedSession) {
|
|
1603
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
1604
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
1605
|
+
return;
|
|
1606
|
+
}
|
|
1607
|
+
}
|
|
1608
|
+
const session = annotationSessionStore.updateStatus(sessionId, "dismissed");
|
|
1609
|
+
if (!session) {
|
|
1610
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
1611
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
1612
|
+
return;
|
|
1613
|
+
}
|
|
1614
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
1615
|
+
res.end(JSON.stringify({ success: true, session }));
|
|
1616
|
+
} catch (e) {
|
|
1617
|
+
serverLogger4.error(`Error parsing session dismiss request:`, e);
|
|
1618
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
1619
|
+
res.end(JSON.stringify({ success: false, error: "Invalid JSON body" }));
|
|
1620
|
+
}
|
|
1621
|
+
return;
|
|
1622
|
+
}
|
|
1177
1623
|
if (pathname.startsWith(`${INSPECTO_API_PATHS.AI_TICKET}/`) && req.method === "GET") {
|
|
1178
1624
|
const ticketId = pathname.substring(INSPECTO_API_PATHS.AI_TICKET.length + 1);
|
|
1179
1625
|
const payloadStr = readTicket(ticketId);
|
|
@@ -1190,7 +1636,7 @@ async function handleRequest(url, req, res) {
|
|
|
1190
1636
|
res.end(JSON.stringify({ error: "not found" }));
|
|
1191
1637
|
}
|
|
1192
1638
|
async function dispatchToAi(req) {
|
|
1193
|
-
const { location, snippet, prompt
|
|
1639
|
+
const { location, snippet, prompt } = req;
|
|
1194
1640
|
const formattedPrompt = prompt ?? `Please help me with this code from \`${location.file}\` (line ${location.line}):
|
|
1195
1641
|
|
|
1196
1642
|
\`\`\`
|
|
@@ -1203,8 +1649,7 @@ ${snippet}
|
|
|
1203
1649
|
filePath: location.file,
|
|
1204
1650
|
line: location.line,
|
|
1205
1651
|
column: location.column,
|
|
1206
|
-
snippet
|
|
1207
|
-
...screenshotContext ? { screenshotContext } : {}
|
|
1652
|
+
snippet
|
|
1208
1653
|
});
|
|
1209
1654
|
}
|
|
1210
1655
|
function getBatchDispatchStatusCode(errorCode, success) {
|
|
@@ -1213,6 +1658,21 @@ function getBatchDispatchStatusCode(errorCode, success) {
|
|
|
1213
1658
|
if (errorCode === "FORBIDDEN_PATH") return 403;
|
|
1214
1659
|
return 500;
|
|
1215
1660
|
}
|
|
1661
|
+
function isAnnotationThreadRole(value) {
|
|
1662
|
+
return value === "user" || value === "agent" || value === "system";
|
|
1663
|
+
}
|
|
1664
|
+
function formatSessionSseEvent(event) {
|
|
1665
|
+
return `event: ${event.type}
|
|
1666
|
+
data: ${JSON.stringify(event)}
|
|
1667
|
+
|
|
1668
|
+
`;
|
|
1669
|
+
}
|
|
1670
|
+
function normalizeSessionClaimTimeout(value) {
|
|
1671
|
+
if (!value?.trim()) return 3e4;
|
|
1672
|
+
const parsed = Number.parseInt(value, 10);
|
|
1673
|
+
if (!Number.isFinite(parsed)) return 3e4;
|
|
1674
|
+
return Math.max(0, Math.min(parsed, 3e5));
|
|
1675
|
+
}
|
|
1216
1676
|
|
|
1217
1677
|
// src/index.ts
|
|
1218
1678
|
import { createUnplugin } from "unplugin";
|
|
@@ -1903,7 +2363,9 @@ function transformRouter(options) {
|
|
|
1903
2363
|
return transformSvelte({
|
|
1904
2364
|
filePath,
|
|
1905
2365
|
source,
|
|
2366
|
+
projectRoot,
|
|
1906
2367
|
escapeTags: pluginOptions.escapeTags,
|
|
2368
|
+
pathType: pluginOptions.pathType,
|
|
1907
2369
|
attributeName: pluginOptions.attributeName
|
|
1908
2370
|
});
|
|
1909
2371
|
}
|
|
@@ -1912,6 +2374,7 @@ function transformRouter(options) {
|
|
|
1912
2374
|
filePath,
|
|
1913
2375
|
source,
|
|
1914
2376
|
escapeTags: pluginOptions.escapeTags,
|
|
2377
|
+
pathType: pluginOptions.pathType,
|
|
1915
2378
|
attributeName: pluginOptions.attributeName
|
|
1916
2379
|
});
|
|
1917
2380
|
}
|
|
@@ -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
|
},
|
|
@@ -2175,10 +2651,10 @@ var rollupPlugin = InspectoPlugin.rollup;
|
|
|
2175
2651
|
var esbuildPlugin = InspectoPlugin.esbuild;
|
|
2176
2652
|
|
|
2177
2653
|
// src/astro.ts
|
|
2178
|
-
function getAstroInjectedScript(serverPort) {
|
|
2654
|
+
function getAstroInjectedScript(serverPort, publicServerUrl) {
|
|
2179
2655
|
return `
|
|
2180
2656
|
import { mountInspector } from '@inspecto-dev/core';
|
|
2181
|
-
window.__AI_INSPECTOR_SERVER_URL__ = 'http://127.0.0.1:${serverPort}';
|
|
2657
|
+
window.__AI_INSPECTOR_SERVER_URL__ = '${publicServerUrl ?? `http://127.0.0.1:${serverPort}`}';
|
|
2182
2658
|
mountInspector({
|
|
2183
2659
|
serverUrl: window.__AI_INSPECTOR_SERVER_URL__,
|
|
2184
2660
|
});
|
|
@@ -2198,7 +2674,17 @@ function astroIntegration(options) {
|
|
|
2198
2674
|
return;
|
|
2199
2675
|
}
|
|
2200
2676
|
const serverPort = await startServer();
|
|
2201
|
-
injectScript(
|
|
2677
|
+
injectScript(
|
|
2678
|
+
"page",
|
|
2679
|
+
getAstroInjectedScript(
|
|
2680
|
+
serverPort,
|
|
2681
|
+
resolvePublicServerUrl({
|
|
2682
|
+
cwd: serverState.cwd || process.cwd(),
|
|
2683
|
+
configRoot: serverState.configRoot || process.cwd(),
|
|
2684
|
+
port: serverPort
|
|
2685
|
+
})
|
|
2686
|
+
)
|
|
2687
|
+
);
|
|
2202
2688
|
}
|
|
2203
2689
|
}
|
|
2204
2690
|
};
|