@inspecto-dev/plugin 0.3.7 → 0.3.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/astro.cjs +2687 -0
- package/dist/astro.cjs.map +1 -0
- package/dist/astro.d.cts +17 -0
- package/dist/astro.d.ts +17 -0
- package/dist/astro.js +2656 -0
- package/dist/astro.js.map +1 -0
- package/dist/index.cjs +932 -87
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +22 -1
- package/dist/index.d.ts +22 -1
- package/dist/index.js +930 -87
- package/dist/index.js.map +1 -1
- package/dist/legacy/rspack/index.cjs +530 -89
- package/dist/legacy/rspack/index.cjs.map +1 -1
- package/dist/legacy/rspack/index.js +530 -89
- package/dist/legacy/rspack/index.js.map +1 -1
- package/dist/legacy/rspack/loader.cjs +407 -3
- package/dist/legacy/rspack/loader.cjs.map +1 -1
- package/dist/legacy/rspack/loader.js +403 -3
- package/dist/legacy/rspack/loader.js.map +1 -1
- package/dist/legacy/webpack4/index.cjs +519 -78
- package/dist/legacy/webpack4/index.cjs.map +1 -1
- package/dist/legacy/webpack4/index.js +519 -78
- package/dist/legacy/webpack4/index.js.map +1 -1
- package/dist/legacy/webpack4/loader.cjs +407 -3
- package/dist/legacy/webpack4/loader.cjs.map +1 -1
- package/dist/legacy/webpack4/loader.js +403 -3
- package/dist/legacy/webpack4/loader.js.map +1 -1
- package/dist/rollup.cjs +932 -87
- package/dist/rollup.cjs.map +1 -1
- package/dist/rollup.d.cts +1 -1
- package/dist/rollup.d.ts +1 -1
- package/dist/rollup.js +930 -87
- package/dist/rollup.js.map +1 -1
- package/dist/rspack.cjs +932 -87
- package/dist/rspack.cjs.map +1 -1
- package/dist/rspack.d.cts +1 -1
- package/dist/rspack.d.ts +1 -1
- package/dist/rspack.js +930 -87
- package/dist/rspack.js.map +1 -1
- package/dist/vite.cjs +932 -87
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.d.cts +1 -1
- package/dist/vite.d.ts +1 -1
- package/dist/vite.js +930 -87
- package/dist/vite.js.map +1 -1
- package/dist/webpack.cjs +932 -87
- package/dist/webpack.cjs.map +1 -1
- package/dist/webpack.d.cts +1 -1
- package/dist/webpack.d.ts +1 -1
- package/dist/webpack.js +930 -87
- package/dist/webpack.js.map +1 -1
- package/package.json +13 -10
|
@@ -5,7 +5,7 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
5
5
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
6
|
});
|
|
7
7
|
|
|
8
|
-
// ../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.
|
|
8
|
+
// ../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.10_typescript@5.9.3_yaml@2.8.3/node_modules/tsup/assets/esm_shims.js
|
|
9
9
|
import path from "path";
|
|
10
10
|
import { fileURLToPath } from "url";
|
|
11
11
|
var getFilename = () => fileURLToPath(import.meta.url);
|
|
@@ -16,13 +16,13 @@ var __dirname = /* @__PURE__ */ getDirname();
|
|
|
16
16
|
function getWebpackHtmlScript(serverPort) {
|
|
17
17
|
return `
|
|
18
18
|
window.__AI_INSPECTOR_PORT__ = ${serverPort};
|
|
19
|
-
window.addEventListener('load', () => {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
});
|
|
19
|
+
window.addEventListener('load', () => {
|
|
20
|
+
if (window.InspectoClient) {
|
|
21
|
+
window.InspectoClient.mountInspector({
|
|
22
|
+
serverUrl: 'http://0.0.0.0:' + window.__AI_INSPECTOR_PORT__,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
26
|
`;
|
|
27
27
|
}
|
|
28
28
|
|
|
@@ -324,7 +324,7 @@ function readJsonSafely(filePath) {
|
|
|
324
324
|
}
|
|
325
325
|
return null;
|
|
326
326
|
}
|
|
327
|
-
function resolveTargetTool(config,
|
|
327
|
+
function resolveTargetTool(config, _ide = "vscode") {
|
|
328
328
|
const defaultProvider = config["provider.default"];
|
|
329
329
|
if (defaultProvider) {
|
|
330
330
|
const tool = defaultProvider.split(".")[0];
|
|
@@ -476,7 +476,7 @@ function watchConfig(onReload, cwd = process.cwd(), gitRoot) {
|
|
|
476
476
|
});
|
|
477
477
|
watcher.unref();
|
|
478
478
|
watchers.push(watcher);
|
|
479
|
-
} catch (
|
|
479
|
+
} catch (_e) {
|
|
480
480
|
}
|
|
481
481
|
}
|
|
482
482
|
}
|
|
@@ -544,7 +544,6 @@ function dispatchPromptThroughIde(runtime, payload) {
|
|
|
544
544
|
line: payload.line,
|
|
545
545
|
column: payload.column,
|
|
546
546
|
snippet: payload.snippet,
|
|
547
|
-
...payload.screenshotContext ? { screenshotContext: payload.screenshotContext } : {},
|
|
548
547
|
overrides: runtime.overrides,
|
|
549
548
|
autoSend: runtime.autoSend
|
|
550
549
|
});
|
|
@@ -678,6 +677,188 @@ function assertPathWithinIdeOpenScope(file, projectRoot) {
|
|
|
678
677
|
}
|
|
679
678
|
}
|
|
680
679
|
|
|
680
|
+
// src/server/session-store.ts
|
|
681
|
+
var DEFAULT_STATUS = "pending";
|
|
682
|
+
function createAnnotationSessionStore(options = {}) {
|
|
683
|
+
const sessions = /* @__PURE__ */ new Map();
|
|
684
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
685
|
+
const now = options.now ?? (() => Date.now());
|
|
686
|
+
const createId = options.createId ?? createRandomId;
|
|
687
|
+
function findNewestMatchingSession(statuses) {
|
|
688
|
+
return [...sessions.values()].filter((session) => statuses ? statuses.has(session.status) : true).sort((left, right) => right.updatedAt - left.updatedAt)[0] ?? null;
|
|
689
|
+
}
|
|
690
|
+
function updateSessionStatus(id, status) {
|
|
691
|
+
const session = sessions.get(id);
|
|
692
|
+
if (!session) return null;
|
|
693
|
+
const timestamp = now();
|
|
694
|
+
session.status = status;
|
|
695
|
+
session.updatedAt = timestamp;
|
|
696
|
+
if (status === "acknowledged") {
|
|
697
|
+
session.acknowledgedAt = timestamp;
|
|
698
|
+
}
|
|
699
|
+
if (status === "resolved") {
|
|
700
|
+
session.resolvedAt = timestamp;
|
|
701
|
+
}
|
|
702
|
+
emit({ type: "session-status-updated", session });
|
|
703
|
+
return cloneSession(session);
|
|
704
|
+
}
|
|
705
|
+
function claimSession(id, statuses) {
|
|
706
|
+
const session = sessions.get(id);
|
|
707
|
+
if (!session || statuses && !statuses.has(session.status)) return null;
|
|
708
|
+
if (session.status === "acknowledged") return cloneSession(session);
|
|
709
|
+
return updateSessionStatus(id, "acknowledged");
|
|
710
|
+
}
|
|
711
|
+
function emit(event) {
|
|
712
|
+
const snapshot = cloneSession(event.session);
|
|
713
|
+
for (const listener of listeners) {
|
|
714
|
+
listener({ type: event.type, session: snapshot });
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
const store = {
|
|
718
|
+
createSession(input) {
|
|
719
|
+
const timestamp = now();
|
|
720
|
+
const session = {
|
|
721
|
+
id: createId(),
|
|
722
|
+
instruction: input.instruction?.trim() ?? "",
|
|
723
|
+
annotations: cloneArray(input.annotations),
|
|
724
|
+
...input.deliveryMode ? { deliveryMode: input.deliveryMode } : {},
|
|
725
|
+
status: DEFAULT_STATUS,
|
|
726
|
+
messages: cloneArray(input.messages ?? []),
|
|
727
|
+
createdAt: timestamp,
|
|
728
|
+
updatedAt: timestamp,
|
|
729
|
+
...input.runtimeContext ? { runtimeContext: cloneValue(input.runtimeContext) } : {},
|
|
730
|
+
...input.cssContextPrompt?.trim() ? { cssContextPrompt: input.cssContextPrompt.trim() } : {},
|
|
731
|
+
...input.pageUrl ? { pageUrl: input.pageUrl } : {},
|
|
732
|
+
...input.route ? { route: input.route } : {}
|
|
733
|
+
};
|
|
734
|
+
sessions.set(session.id, session);
|
|
735
|
+
emit({ type: "session-created", session });
|
|
736
|
+
return cloneSession(session);
|
|
737
|
+
},
|
|
738
|
+
getSession(id) {
|
|
739
|
+
const session = sessions.get(id);
|
|
740
|
+
return session ? cloneSession(session) : null;
|
|
741
|
+
},
|
|
742
|
+
listSessions(options2 = {}) {
|
|
743
|
+
const statuses = normalizeStatuses(options2.status);
|
|
744
|
+
return [...sessions.values()].filter((session) => statuses ? statuses.has(session.status) : true).sort((left, right) => right.updatedAt - left.updatedAt).map((session) => cloneSession(session));
|
|
745
|
+
},
|
|
746
|
+
async claimNextSession(options2 = {}) {
|
|
747
|
+
const statuses = normalizeStatuses(DEFAULT_STATUS);
|
|
748
|
+
const existingSession = findNewestMatchingSession(statuses);
|
|
749
|
+
if (existingSession) {
|
|
750
|
+
return {
|
|
751
|
+
session: claimSession(existingSession.id, statuses),
|
|
752
|
+
timedOut: false,
|
|
753
|
+
matchedExisting: true
|
|
754
|
+
};
|
|
755
|
+
}
|
|
756
|
+
const timeoutMs = normalizeTimeoutMs(options2.timeoutMs);
|
|
757
|
+
if (timeoutMs === 0) {
|
|
758
|
+
return {
|
|
759
|
+
session: null,
|
|
760
|
+
timedOut: true,
|
|
761
|
+
matchedExisting: false
|
|
762
|
+
};
|
|
763
|
+
}
|
|
764
|
+
return await new Promise((resolve2) => {
|
|
765
|
+
let settled = false;
|
|
766
|
+
let timeout = null;
|
|
767
|
+
const finish = (result) => {
|
|
768
|
+
if (settled) return;
|
|
769
|
+
settled = true;
|
|
770
|
+
unsubscribe();
|
|
771
|
+
if (timeout) {
|
|
772
|
+
clearTimeout(timeout);
|
|
773
|
+
}
|
|
774
|
+
resolve2(result);
|
|
775
|
+
};
|
|
776
|
+
const unsubscribe = this.subscribe((event) => {
|
|
777
|
+
const session = claimSession(event.session.id, statuses);
|
|
778
|
+
if (!session) return;
|
|
779
|
+
finish({
|
|
780
|
+
session,
|
|
781
|
+
timedOut: false,
|
|
782
|
+
matchedExisting: false,
|
|
783
|
+
event: event.type
|
|
784
|
+
});
|
|
785
|
+
});
|
|
786
|
+
if (timeoutMs !== null) {
|
|
787
|
+
timeout = setTimeout(() => {
|
|
788
|
+
finish({
|
|
789
|
+
session: null,
|
|
790
|
+
timedOut: true,
|
|
791
|
+
matchedExisting: false
|
|
792
|
+
});
|
|
793
|
+
}, timeoutMs);
|
|
794
|
+
}
|
|
795
|
+
});
|
|
796
|
+
},
|
|
797
|
+
appendMessage(id, input) {
|
|
798
|
+
const session = sessions.get(id);
|
|
799
|
+
if (!session) return null;
|
|
800
|
+
const timestamp = now();
|
|
801
|
+
session.messages.push({
|
|
802
|
+
id: createId(),
|
|
803
|
+
role: input.role,
|
|
804
|
+
text: input.text,
|
|
805
|
+
createdAt: timestamp
|
|
806
|
+
});
|
|
807
|
+
session.updatedAt = timestamp;
|
|
808
|
+
if (input.role === "agent" && isPendingLikeStatus(session.status)) {
|
|
809
|
+
session.status = "in_progress";
|
|
810
|
+
}
|
|
811
|
+
emit({ type: "session-message-appended", session });
|
|
812
|
+
return cloneSession(session);
|
|
813
|
+
},
|
|
814
|
+
updateStatus(id, status) {
|
|
815
|
+
return updateSessionStatus(id, status);
|
|
816
|
+
},
|
|
817
|
+
subscribe(listener) {
|
|
818
|
+
listeners.add(listener);
|
|
819
|
+
return () => {
|
|
820
|
+
listeners.delete(listener);
|
|
821
|
+
};
|
|
822
|
+
},
|
|
823
|
+
clear() {
|
|
824
|
+
sessions.clear();
|
|
825
|
+
listeners.clear();
|
|
826
|
+
}
|
|
827
|
+
};
|
|
828
|
+
return store;
|
|
829
|
+
}
|
|
830
|
+
var annotationSessionStore = createAnnotationSessionStore();
|
|
831
|
+
function normalizeStatuses(status) {
|
|
832
|
+
if (!status) return null;
|
|
833
|
+
return new Set(Array.isArray(status) ? status : [status]);
|
|
834
|
+
}
|
|
835
|
+
function normalizeTimeoutMs(value) {
|
|
836
|
+
if (value === void 0) return null;
|
|
837
|
+
if (!Number.isFinite(value)) return 0;
|
|
838
|
+
return Math.max(0, Math.floor(value));
|
|
839
|
+
}
|
|
840
|
+
function isPendingLikeStatus(status) {
|
|
841
|
+
return status === "pending" || status === "acknowledged";
|
|
842
|
+
}
|
|
843
|
+
function hasAgentReply(session) {
|
|
844
|
+
return session.messages.some((message) => message.role === "agent" && Boolean(message.text?.trim()));
|
|
845
|
+
}
|
|
846
|
+
function createRandomId() {
|
|
847
|
+
return `annotation-session-${Math.random().toString(36).slice(2, 10)}`;
|
|
848
|
+
}
|
|
849
|
+
function cloneSession(session) {
|
|
850
|
+
return cloneValue(session);
|
|
851
|
+
}
|
|
852
|
+
function cloneArray(value) {
|
|
853
|
+
return cloneValue(value);
|
|
854
|
+
}
|
|
855
|
+
function cloneValue(value) {
|
|
856
|
+
if (typeof structuredClone === "function") {
|
|
857
|
+
return structuredClone(value);
|
|
858
|
+
}
|
|
859
|
+
return JSON.parse(JSON.stringify(value));
|
|
860
|
+
}
|
|
861
|
+
|
|
681
862
|
// src/server/annotation-dispatch.ts
|
|
682
863
|
var AnnotationDispatchError = class extends Error {
|
|
683
864
|
constructor(message, errorCode) {
|
|
@@ -686,20 +867,30 @@ var AnnotationDispatchError = class extends Error {
|
|
|
686
867
|
this.errorCode = errorCode;
|
|
687
868
|
}
|
|
688
869
|
};
|
|
689
|
-
async function dispatchAnnotationsToAi(req, state) {
|
|
870
|
+
async function dispatchAnnotationsToAi(req, state, store = annotationSessionStore) {
|
|
690
871
|
try {
|
|
691
872
|
validateAnnotationDispatchRequest(req, state);
|
|
692
873
|
const batch = normalizeAnnotationBatch(req);
|
|
693
874
|
const prompt = buildAnnotationBatchPrompt(batch);
|
|
875
|
+
const deliveryMode = normalizeDeliveryMode(req.deliveryMode);
|
|
876
|
+
const session = store.createSession({
|
|
877
|
+
instruction: batch.instruction,
|
|
878
|
+
annotations: toSessionAnnotations(batch.annotations),
|
|
879
|
+
deliveryMode,
|
|
880
|
+
...batch.runtimeContext ? { runtimeContext: batch.runtimeContext } : {},
|
|
881
|
+
...batch.cssContextPrompt ? { cssContextPrompt: batch.cssContextPrompt } : {}
|
|
882
|
+
});
|
|
694
883
|
const representativeTarget = batch.annotations[0]?.targets[0];
|
|
695
|
-
const
|
|
696
|
-
return dispatchPromptThroughIde(runtime, {
|
|
884
|
+
const dispatchResult = deliveryMode === "ide" ? dispatchPromptThroughIde(resolvePromptDispatchRuntime(state), {
|
|
697
885
|
prompt,
|
|
698
886
|
...representativeTarget?.file ? { filePath: representativeTarget.file } : {},
|
|
699
887
|
...representativeTarget?.line ? { line: representativeTarget.line } : {},
|
|
700
|
-
...representativeTarget?.column ? { column: representativeTarget.column } : {}
|
|
701
|
-
|
|
702
|
-
|
|
888
|
+
...representativeTarget?.column ? { column: representativeTarget.column } : {}
|
|
889
|
+
}) : { success: true };
|
|
890
|
+
return {
|
|
891
|
+
...dispatchResult,
|
|
892
|
+
session: toSessionSummary(session)
|
|
893
|
+
};
|
|
703
894
|
} catch (error) {
|
|
704
895
|
return {
|
|
705
896
|
success: false,
|
|
@@ -708,6 +899,41 @@ async function dispatchAnnotationsToAi(req, state) {
|
|
|
708
899
|
};
|
|
709
900
|
}
|
|
710
901
|
}
|
|
902
|
+
function normalizeDeliveryMode(input) {
|
|
903
|
+
return input === "agent" ? "agent" : "ide";
|
|
904
|
+
}
|
|
905
|
+
function toSessionAnnotations(annotations) {
|
|
906
|
+
return annotations.map((annotation) => ({
|
|
907
|
+
id: `annotation-${annotation.index}`,
|
|
908
|
+
note: annotation.note,
|
|
909
|
+
intent: annotation.intent,
|
|
910
|
+
targets: annotation.targets.map((target, targetIndex) => ({
|
|
911
|
+
id: `annotation-${annotation.index}-target-${targetIndex + 1}`,
|
|
912
|
+
label: target.label ?? "Unknown target",
|
|
913
|
+
location: {
|
|
914
|
+
file: target.file,
|
|
915
|
+
line: target.line,
|
|
916
|
+
column: target.column
|
|
917
|
+
},
|
|
918
|
+
...target.selector ? { selector: target.selector } : {},
|
|
919
|
+
...target.snippet ? { snippet: target.snippet } : {},
|
|
920
|
+
rect: {
|
|
921
|
+
x: 0,
|
|
922
|
+
y: 0,
|
|
923
|
+
width: 0,
|
|
924
|
+
height: 0
|
|
925
|
+
}
|
|
926
|
+
}))
|
|
927
|
+
}));
|
|
928
|
+
}
|
|
929
|
+
function toSessionSummary(session) {
|
|
930
|
+
return {
|
|
931
|
+
id: session.id,
|
|
932
|
+
status: session.status,
|
|
933
|
+
createdAt: session.createdAt,
|
|
934
|
+
updatedAt: session.updatedAt
|
|
935
|
+
};
|
|
936
|
+
}
|
|
711
937
|
function validateAnnotationDispatchRequest(req, state) {
|
|
712
938
|
if (!req.annotations.length) {
|
|
713
939
|
throw new AnnotationDispatchError("At least one annotation is required.", "INVALID_REQUEST");
|
|
@@ -728,9 +954,7 @@ function validateAnnotationDispatchRequest(req, state) {
|
|
|
728
954
|
function normalizeAnnotationBatch(req) {
|
|
729
955
|
return {
|
|
730
956
|
instruction: req.instruction?.trim() ?? "",
|
|
731
|
-
responseMode: req.responseMode ?? "unified",
|
|
732
957
|
...req.runtimeContext ? { runtimeContext: req.runtimeContext } : {},
|
|
733
|
-
...req.screenshotContext ? { screenshotContext: req.screenshotContext } : {},
|
|
734
958
|
...req.cssContextPrompt?.trim() ? { cssContextPrompt: req.cssContextPrompt.trim() } : {},
|
|
735
959
|
annotations: req.annotations.map((annotation, index) => ({
|
|
736
960
|
index: index + 1,
|
|
@@ -752,12 +976,9 @@ function buildAnnotationBatchPrompt(batch) {
|
|
|
752
976
|
const prompt = batch.instruction ? `${batch.instruction}
|
|
753
977
|
|
|
754
978
|
${body}` : body;
|
|
755
|
-
return
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
batch.cssContextPrompt
|
|
759
|
-
),
|
|
760
|
-
batch.screenshotContext
|
|
979
|
+
return appendCssContextSection(
|
|
980
|
+
appendRuntimeContextSection(prompt, batch.runtimeContext),
|
|
981
|
+
batch.cssContextPrompt
|
|
761
982
|
);
|
|
762
983
|
}
|
|
763
984
|
function appendCssContextSection(prompt, cssContextPrompt) {
|
|
@@ -784,20 +1005,6 @@ function buildSelectedElementsPrompt(annotations) {
|
|
|
784
1005
|
}
|
|
785
1006
|
return lines.join("\n");
|
|
786
1007
|
}
|
|
787
|
-
function appendScreenshotContextSection(prompt, screenshotContext) {
|
|
788
|
-
if (!screenshotContext || !screenshotContext.imageDataUrl && !screenshotContext.imageAssetId) {
|
|
789
|
-
return prompt;
|
|
790
|
-
}
|
|
791
|
-
const lines = [
|
|
792
|
-
"Visual screenshot context attached:",
|
|
793
|
-
`- capturedAt=${screenshotContext.capturedAt}`,
|
|
794
|
-
`- mimeType=${screenshotContext.mimeType}`,
|
|
795
|
-
...screenshotContext.imageAssetId ? [`- imageAssetId=${screenshotContext.imageAssetId}`] : []
|
|
796
|
-
];
|
|
797
|
-
return `${prompt}
|
|
798
|
-
|
|
799
|
-
${lines.join("\n")}`;
|
|
800
|
-
}
|
|
801
1008
|
function appendRuntimeContextSection(prompt, runtimeContext) {
|
|
802
1009
|
if (!runtimeContext?.records.length) {
|
|
803
1010
|
return prompt;
|
|
@@ -845,7 +1052,7 @@ async function buildClientConfig(serverState2) {
|
|
|
845
1052
|
...info,
|
|
846
1053
|
prompts: resolveIntents(promptsConfig),
|
|
847
1054
|
hotKeys: userConfig["inspector.hotKey"] ?? "alt",
|
|
848
|
-
|
|
1055
|
+
annotateDeliveryMode: userConfig["annotate.deliveryMode"] ?? "both",
|
|
849
1056
|
includeSnippet: userConfig["prompt.includeSnippet"] ?? false,
|
|
850
1057
|
runtimeContext: {
|
|
851
1058
|
enabled: true,
|
|
@@ -853,10 +1060,6 @@ async function buildClientConfig(serverState2) {
|
|
|
853
1060
|
maxRuntimeErrors: 3,
|
|
854
1061
|
maxFailedRequests: 2
|
|
855
1062
|
},
|
|
856
|
-
screenshotContext: {
|
|
857
|
-
enabled: false
|
|
858
|
-
},
|
|
859
|
-
annotationResponseMode: userConfig["prompt.annotationResponseMode"] ?? "unified",
|
|
860
1063
|
autoSend: userConfig["prompt.autoSend"] ?? false
|
|
861
1064
|
};
|
|
862
1065
|
}
|
|
@@ -901,7 +1104,7 @@ function handleOpenFileRequest(body, serverState2) {
|
|
|
901
1104
|
else if (rawEditorHint === "vscodium") editorHint = "codium";
|
|
902
1105
|
else if (rawEditorHint === "trae-cn" || rawEditorHint === "trae") editorHint = "trae";
|
|
903
1106
|
serverLogger2.debug(
|
|
904
|
-
`
|
|
1107
|
+
`SOURCE_OPEN: activeIde=${activeIde}, activeIdeScheme=${activeIdeScheme}, configuredIde=${configuredIde} -> rawEditorHint=${rawEditorHint}, finalEditorHint=${editorHint}`
|
|
905
1108
|
);
|
|
906
1109
|
if (VSCODE_FAMILY_SCHEMES.includes(rawEditorHint)) {
|
|
907
1110
|
let normalizedPath = absolutePath.replace(/\\/g, "/");
|
|
@@ -910,7 +1113,7 @@ function handleOpenFileRequest(body, serverState2) {
|
|
|
910
1113
|
}
|
|
911
1114
|
const encodedPath = encodeURI(normalizedPath);
|
|
912
1115
|
const uri = `${rawEditorHint}://file${encodedPath}:${body.line}:${body.column}`;
|
|
913
|
-
serverLogger2.debug(`
|
|
1116
|
+
serverLogger2.debug(`SOURCE_OPEN: Bypassing launchIDE, using URI scheme directly: ${uri}`);
|
|
914
1117
|
try {
|
|
915
1118
|
if (process.platform === "darwin") {
|
|
916
1119
|
execFileSync2("open", [uri]);
|
|
@@ -920,7 +1123,7 @@ function handleOpenFileRequest(body, serverState2) {
|
|
|
920
1123
|
execFileSync2("xdg-open", [uri]);
|
|
921
1124
|
}
|
|
922
1125
|
} catch (e) {
|
|
923
|
-
serverLogger2.error(`Failed to launch URI for
|
|
1126
|
+
serverLogger2.error(`Failed to launch URI for SOURCE_OPEN (${uri}):`, e);
|
|
924
1127
|
launchIDE2({
|
|
925
1128
|
file: absolutePath,
|
|
926
1129
|
line: body.line,
|
|
@@ -977,6 +1180,7 @@ function resolveProjectRoot() {
|
|
|
977
1180
|
|
|
978
1181
|
// src/server/index.ts
|
|
979
1182
|
var serverLogger4 = createLogger("inspecto:server", { logLevel: getGlobalLogLevel() });
|
|
1183
|
+
var PORT_FILE_NAME = "inspecto.port.json";
|
|
980
1184
|
var serverState = {
|
|
981
1185
|
port: null,
|
|
982
1186
|
running: false,
|
|
@@ -985,6 +1189,42 @@ var serverState = {
|
|
|
985
1189
|
cwd: process.cwd()
|
|
986
1190
|
};
|
|
987
1191
|
var serverInstance = null;
|
|
1192
|
+
function getPortFilePath() {
|
|
1193
|
+
return path6.join(os2.tmpdir(), PORT_FILE_NAME);
|
|
1194
|
+
}
|
|
1195
|
+
function getProjectRootHash() {
|
|
1196
|
+
if (!serverState.projectRoot) return null;
|
|
1197
|
+
return crypto2.createHash("md5").update(serverState.projectRoot).digest("hex");
|
|
1198
|
+
}
|
|
1199
|
+
function readPortData(portFile) {
|
|
1200
|
+
if (!fs5.existsSync(portFile)) return {};
|
|
1201
|
+
try {
|
|
1202
|
+
return JSON.parse(fs5.readFileSync(portFile, "utf-8"));
|
|
1203
|
+
} catch {
|
|
1204
|
+
return {};
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
function writeProjectPort(port) {
|
|
1208
|
+
const rootHash = getProjectRootHash();
|
|
1209
|
+
if (!rootHash) return;
|
|
1210
|
+
const portFile = getPortFilePath();
|
|
1211
|
+
const portData = readPortData(portFile);
|
|
1212
|
+
portData[rootHash] = port;
|
|
1213
|
+
fs5.writeFileSync(portFile, JSON.stringify(portData, null, 2), "utf-8");
|
|
1214
|
+
}
|
|
1215
|
+
function removeProjectPort() {
|
|
1216
|
+
const rootHash = getProjectRootHash();
|
|
1217
|
+
if (!rootHash) return;
|
|
1218
|
+
const portFile = getPortFilePath();
|
|
1219
|
+
if (!fs5.existsSync(portFile)) return;
|
|
1220
|
+
const portData = readPortData(portFile);
|
|
1221
|
+
delete portData[rootHash];
|
|
1222
|
+
if (Object.keys(portData).length === 0) {
|
|
1223
|
+
fs5.unlinkSync(portFile);
|
|
1224
|
+
} else {
|
|
1225
|
+
fs5.writeFileSync(portFile, JSON.stringify(portData, null, 2), "utf-8");
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
988
1228
|
async function startServer() {
|
|
989
1229
|
if (serverState.running && serverState.port !== null) {
|
|
990
1230
|
return serverState.port;
|
|
@@ -1018,7 +1258,7 @@ async function startServer() {
|
|
|
1018
1258
|
});
|
|
1019
1259
|
});
|
|
1020
1260
|
await new Promise((resolve2, reject) => {
|
|
1021
|
-
serverInstance.listen(port, "
|
|
1261
|
+
serverInstance.listen(port, "0.0.0.0", () => {
|
|
1022
1262
|
serverInstance.unref();
|
|
1023
1263
|
resolve2();
|
|
1024
1264
|
});
|
|
@@ -1029,37 +1269,18 @@ async function startServer() {
|
|
|
1029
1269
|
});
|
|
1030
1270
|
serverState.port = port;
|
|
1031
1271
|
serverState.running = true;
|
|
1032
|
-
const portFile = path6.join(os2.tmpdir(), "inspecto.port.json");
|
|
1033
1272
|
try {
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
portData = JSON.parse(fs5.readFileSync(portFile, "utf-8"));
|
|
1038
|
-
} catch (e) {
|
|
1039
|
-
}
|
|
1040
|
-
}
|
|
1041
|
-
const rootHash = crypto2.createHash("md5").update(serverState.projectRoot).digest("hex");
|
|
1042
|
-
portData[rootHash] = port;
|
|
1043
|
-
fs5.writeFileSync(portFile, JSON.stringify(portData, null, 2), "utf-8");
|
|
1044
|
-
} catch (e) {
|
|
1045
|
-
serverLogger4.warn("Failed to write port file:", e);
|
|
1273
|
+
writeProjectPort(port);
|
|
1274
|
+
} catch (_e) {
|
|
1275
|
+
serverLogger4.warn("Failed to write port file:", _e);
|
|
1046
1276
|
}
|
|
1047
1277
|
process.once("exit", () => {
|
|
1048
1278
|
try {
|
|
1049
|
-
|
|
1050
|
-
const portData = JSON.parse(fs5.readFileSync(portFile, "utf-8"));
|
|
1051
|
-
const rootHash = crypto2.createHash("md5").update(serverState.projectRoot).digest("hex");
|
|
1052
|
-
delete portData[rootHash];
|
|
1053
|
-
if (Object.keys(portData).length === 0) {
|
|
1054
|
-
fs5.unlinkSync(portFile);
|
|
1055
|
-
} else {
|
|
1056
|
-
fs5.writeFileSync(portFile, JSON.stringify(portData, null, 2), "utf-8");
|
|
1057
|
-
}
|
|
1058
|
-
}
|
|
1279
|
+
removeProjectPort();
|
|
1059
1280
|
} catch {
|
|
1060
1281
|
}
|
|
1061
1282
|
});
|
|
1062
|
-
serverLogger4.info(`server running at http://
|
|
1283
|
+
serverLogger4.info(`server running at http://0.0.0.0:${port}`);
|
|
1063
1284
|
return port;
|
|
1064
1285
|
}
|
|
1065
1286
|
async function readBody(req) {
|
|
@@ -1111,11 +1332,11 @@ async function handleRequest(url, req, res) {
|
|
|
1111
1332
|
}
|
|
1112
1333
|
return;
|
|
1113
1334
|
}
|
|
1114
|
-
if (pathname === INSPECTO_API_PATHS.IDE_OPEN && req.method === "POST") {
|
|
1335
|
+
if ((pathname === INSPECTO_API_PATHS.SOURCE_OPEN || pathname === INSPECTO_API_PATHS.IDE_OPEN) && req.method === "POST") {
|
|
1115
1336
|
let body;
|
|
1116
1337
|
try {
|
|
1117
1338
|
body = JSON.parse(await readBody(req));
|
|
1118
|
-
} catch (
|
|
1339
|
+
} catch (_e) {
|
|
1119
1340
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
1120
1341
|
res.end(JSON.stringify({ error: "Invalid JSON body" }));
|
|
1121
1342
|
return;
|
|
@@ -1124,7 +1345,7 @@ async function handleRequest(url, req, res) {
|
|
|
1124
1345
|
handleOpenFileRequest(body, serverState);
|
|
1125
1346
|
} catch (err) {
|
|
1126
1347
|
serverLogger4.warn(
|
|
1127
|
-
`Security: Blocked path traversal attempt in
|
|
1348
|
+
`Security: Blocked path traversal attempt in SOURCE_OPEN: ${body.file}. Reason: ${err.message}`
|
|
1128
1349
|
);
|
|
1129
1350
|
res.writeHead(403, { "Content-Type": "application/json" });
|
|
1130
1351
|
res.end(JSON.stringify({ error: "Access denied: File is outside of project workspace" }));
|
|
@@ -1198,6 +1419,212 @@ async function handleRequest(url, req, res) {
|
|
|
1198
1419
|
}
|
|
1199
1420
|
return;
|
|
1200
1421
|
}
|
|
1422
|
+
if (pathname === INSPECTO_API_PATHS.SESSION_CLAIM_NEXT && req.method === "POST") {
|
|
1423
|
+
try {
|
|
1424
|
+
const rawBody = await readBody(req);
|
|
1425
|
+
const body = rawBody ? JSON.parse(rawBody) : {};
|
|
1426
|
+
const timeoutMs = normalizeSessionClaimTimeout(
|
|
1427
|
+
body.timeoutMs === void 0 ? null : String(body.timeoutMs)
|
|
1428
|
+
);
|
|
1429
|
+
const result = await annotationSessionStore.claimNextSession({
|
|
1430
|
+
...timeoutMs !== void 0 ? { timeoutMs } : {}
|
|
1431
|
+
});
|
|
1432
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
1433
|
+
res.end(
|
|
1434
|
+
JSON.stringify({
|
|
1435
|
+
success: true,
|
|
1436
|
+
timedOut: result.timedOut,
|
|
1437
|
+
matchedExisting: result.matchedExisting,
|
|
1438
|
+
...result.event ? { event: result.event } : {},
|
|
1439
|
+
...result.session ? { session: result.session } : {}
|
|
1440
|
+
})
|
|
1441
|
+
);
|
|
1442
|
+
} catch (e) {
|
|
1443
|
+
serverLogger4.error(`Error parsing session claim request:`, e);
|
|
1444
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
1445
|
+
res.end(JSON.stringify({ success: false, error: "Invalid JSON body" }));
|
|
1446
|
+
}
|
|
1447
|
+
return;
|
|
1448
|
+
}
|
|
1449
|
+
if (pathname === INSPECTO_API_PATHS.SESSION_EVENTS && req.method === "GET") {
|
|
1450
|
+
const statusParam = url.searchParams.getAll("status");
|
|
1451
|
+
const statuses = statusParam.length ? new Set(statusParam) : null;
|
|
1452
|
+
const sessionId = url.searchParams.get("sessionId")?.trim() || null;
|
|
1453
|
+
res.writeHead(200, {
|
|
1454
|
+
"Content-Type": "text/event-stream",
|
|
1455
|
+
"Cache-Control": "no-cache",
|
|
1456
|
+
Connection: "keep-alive"
|
|
1457
|
+
});
|
|
1458
|
+
res.write(`event: ready
|
|
1459
|
+
data: ${JSON.stringify({ ok: true })}
|
|
1460
|
+
|
|
1461
|
+
`);
|
|
1462
|
+
const unsubscribe = annotationSessionStore.subscribe((event) => {
|
|
1463
|
+
if (sessionId && event.session.id !== sessionId) {
|
|
1464
|
+
return;
|
|
1465
|
+
}
|
|
1466
|
+
if (statuses && !statuses.has(event.session.status)) {
|
|
1467
|
+
return;
|
|
1468
|
+
}
|
|
1469
|
+
res.write(formatSessionSseEvent(event));
|
|
1470
|
+
});
|
|
1471
|
+
req.on("close", () => {
|
|
1472
|
+
unsubscribe();
|
|
1473
|
+
res.end();
|
|
1474
|
+
});
|
|
1475
|
+
return;
|
|
1476
|
+
}
|
|
1477
|
+
if (pathname === INSPECTO_API_PATHS.SESSIONS && req.method === "GET") {
|
|
1478
|
+
const statusParam = url.searchParams.getAll("status");
|
|
1479
|
+
const sessions = annotationSessionStore.listSessions(
|
|
1480
|
+
statusParam.length ? {
|
|
1481
|
+
status: statusParam
|
|
1482
|
+
} : void 0
|
|
1483
|
+
);
|
|
1484
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
1485
|
+
res.end(JSON.stringify({ success: true, sessions }));
|
|
1486
|
+
return;
|
|
1487
|
+
}
|
|
1488
|
+
if (pathname.startsWith(`${INSPECTO_API_PATHS.SESSIONS}/`) && req.method === "GET") {
|
|
1489
|
+
const sessionId = pathname.substring(INSPECTO_API_PATHS.SESSIONS.length + 1);
|
|
1490
|
+
const session = annotationSessionStore.getSession(sessionId);
|
|
1491
|
+
if (!session) {
|
|
1492
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
1493
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
1494
|
+
return;
|
|
1495
|
+
}
|
|
1496
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
1497
|
+
res.end(JSON.stringify({ success: true, session }));
|
|
1498
|
+
return;
|
|
1499
|
+
}
|
|
1500
|
+
if (pathname.startsWith(`${INSPECTO_API_PATHS.SESSIONS}/`) && pathname.endsWith(INSPECTO_API_PATHS.SESSION_REPLY_SUFFIX) && req.method === "POST") {
|
|
1501
|
+
const sessionId = pathname.slice(
|
|
1502
|
+
INSPECTO_API_PATHS.SESSIONS.length + 1,
|
|
1503
|
+
-INSPECTO_API_PATHS.SESSION_REPLY_SUFFIX.length
|
|
1504
|
+
);
|
|
1505
|
+
try {
|
|
1506
|
+
const rawBody = await readBody(req);
|
|
1507
|
+
const body = JSON.parse(rawBody);
|
|
1508
|
+
if (!isAnnotationThreadRole(body.role)) {
|
|
1509
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
1510
|
+
res.end(JSON.stringify({ success: false, error: "Reply role is invalid." }));
|
|
1511
|
+
return;
|
|
1512
|
+
}
|
|
1513
|
+
if (!body.text?.trim()) {
|
|
1514
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
1515
|
+
res.end(JSON.stringify({ success: false, error: "Reply text is required." }));
|
|
1516
|
+
return;
|
|
1517
|
+
}
|
|
1518
|
+
const session = annotationSessionStore.appendMessage(sessionId, {
|
|
1519
|
+
role: body.role,
|
|
1520
|
+
text: body.text.trim()
|
|
1521
|
+
});
|
|
1522
|
+
if (!session) {
|
|
1523
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
1524
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
1525
|
+
return;
|
|
1526
|
+
}
|
|
1527
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
1528
|
+
res.end(JSON.stringify({ success: true, session }));
|
|
1529
|
+
} catch (e) {
|
|
1530
|
+
serverLogger4.error(`Error parsing session reply request:`, e);
|
|
1531
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
1532
|
+
res.end(JSON.stringify({ success: false, error: "Invalid JSON body" }));
|
|
1533
|
+
}
|
|
1534
|
+
return;
|
|
1535
|
+
}
|
|
1536
|
+
if (pathname.startsWith(`${INSPECTO_API_PATHS.SESSIONS}/`) && pathname.endsWith(INSPECTO_API_PATHS.SESSION_RESOLVE_SUFFIX) && req.method === "POST") {
|
|
1537
|
+
const sessionId = pathname.slice(
|
|
1538
|
+
INSPECTO_API_PATHS.SESSIONS.length + 1,
|
|
1539
|
+
-INSPECTO_API_PATHS.SESSION_RESOLVE_SUFFIX.length
|
|
1540
|
+
);
|
|
1541
|
+
try {
|
|
1542
|
+
const rawBody = await readBody(req);
|
|
1543
|
+
const body = rawBody ? JSON.parse(rawBody) : {};
|
|
1544
|
+
const message = body.message?.trim();
|
|
1545
|
+
const existingSession = annotationSessionStore.getSession(sessionId);
|
|
1546
|
+
if (!existingSession) {
|
|
1547
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
1548
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
1549
|
+
return;
|
|
1550
|
+
}
|
|
1551
|
+
if (!message && !hasAgentReply(existingSession)) {
|
|
1552
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
1553
|
+
res.end(
|
|
1554
|
+
JSON.stringify({
|
|
1555
|
+
success: false,
|
|
1556
|
+
error: "Resolve message is required until an agent reply is recorded."
|
|
1557
|
+
})
|
|
1558
|
+
);
|
|
1559
|
+
return;
|
|
1560
|
+
}
|
|
1561
|
+
if (message) {
|
|
1562
|
+
const repliedSession = annotationSessionStore.appendMessage(sessionId, {
|
|
1563
|
+
role: "agent",
|
|
1564
|
+
text: message
|
|
1565
|
+
});
|
|
1566
|
+
if (!repliedSession) {
|
|
1567
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
1568
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
1569
|
+
return;
|
|
1570
|
+
}
|
|
1571
|
+
}
|
|
1572
|
+
const session = annotationSessionStore.updateStatus(sessionId, "resolved");
|
|
1573
|
+
if (!session) {
|
|
1574
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
1575
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
1576
|
+
return;
|
|
1577
|
+
}
|
|
1578
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
1579
|
+
res.end(JSON.stringify({ success: true, session }));
|
|
1580
|
+
} catch (e) {
|
|
1581
|
+
serverLogger4.error(`Error parsing session resolve request:`, e);
|
|
1582
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
1583
|
+
res.end(JSON.stringify({ success: false, error: "Invalid JSON body" }));
|
|
1584
|
+
}
|
|
1585
|
+
return;
|
|
1586
|
+
}
|
|
1587
|
+
if (pathname.startsWith(`${INSPECTO_API_PATHS.SESSIONS}/`) && pathname.endsWith(INSPECTO_API_PATHS.SESSION_DISMISS_SUFFIX) && req.method === "POST") {
|
|
1588
|
+
const sessionId = pathname.slice(
|
|
1589
|
+
INSPECTO_API_PATHS.SESSIONS.length + 1,
|
|
1590
|
+
-INSPECTO_API_PATHS.SESSION_DISMISS_SUFFIX.length
|
|
1591
|
+
);
|
|
1592
|
+
try {
|
|
1593
|
+
const rawBody = await readBody(req);
|
|
1594
|
+
const body = rawBody ? JSON.parse(rawBody) : {};
|
|
1595
|
+
const message = body.message?.trim();
|
|
1596
|
+
const existingSession = annotationSessionStore.getSession(sessionId);
|
|
1597
|
+
if (!existingSession) {
|
|
1598
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
1599
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
1600
|
+
return;
|
|
1601
|
+
}
|
|
1602
|
+
if (message) {
|
|
1603
|
+
const repliedSession = annotationSessionStore.appendMessage(sessionId, {
|
|
1604
|
+
role: "agent",
|
|
1605
|
+
text: message
|
|
1606
|
+
});
|
|
1607
|
+
if (!repliedSession) {
|
|
1608
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
1609
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
1610
|
+
return;
|
|
1611
|
+
}
|
|
1612
|
+
}
|
|
1613
|
+
const session = annotationSessionStore.updateStatus(sessionId, "dismissed");
|
|
1614
|
+
if (!session) {
|
|
1615
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
1616
|
+
res.end(JSON.stringify({ success: false, error: "Session not found" }));
|
|
1617
|
+
return;
|
|
1618
|
+
}
|
|
1619
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
1620
|
+
res.end(JSON.stringify({ success: true, session }));
|
|
1621
|
+
} catch (e) {
|
|
1622
|
+
serverLogger4.error(`Error parsing session dismiss request:`, e);
|
|
1623
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
1624
|
+
res.end(JSON.stringify({ success: false, error: "Invalid JSON body" }));
|
|
1625
|
+
}
|
|
1626
|
+
return;
|
|
1627
|
+
}
|
|
1201
1628
|
if (pathname.startsWith(`${INSPECTO_API_PATHS.AI_TICKET}/`) && req.method === "GET") {
|
|
1202
1629
|
const ticketId = pathname.substring(INSPECTO_API_PATHS.AI_TICKET.length + 1);
|
|
1203
1630
|
const payloadStr = readTicket(ticketId);
|
|
@@ -1214,7 +1641,7 @@ async function handleRequest(url, req, res) {
|
|
|
1214
1641
|
res.end(JSON.stringify({ error: "not found" }));
|
|
1215
1642
|
}
|
|
1216
1643
|
async function dispatchToAi(req) {
|
|
1217
|
-
const { location, snippet, prompt
|
|
1644
|
+
const { location, snippet, prompt } = req;
|
|
1218
1645
|
const formattedPrompt = prompt ?? `Please help me with this code from \`${location.file}\` (line ${location.line}):
|
|
1219
1646
|
|
|
1220
1647
|
\`\`\`
|
|
@@ -1227,8 +1654,7 @@ ${snippet}
|
|
|
1227
1654
|
filePath: location.file,
|
|
1228
1655
|
line: location.line,
|
|
1229
1656
|
column: location.column,
|
|
1230
|
-
snippet
|
|
1231
|
-
...screenshotContext ? { screenshotContext } : {}
|
|
1657
|
+
snippet
|
|
1232
1658
|
});
|
|
1233
1659
|
}
|
|
1234
1660
|
function getBatchDispatchStatusCode(errorCode, success) {
|
|
@@ -1237,6 +1663,21 @@ function getBatchDispatchStatusCode(errorCode, success) {
|
|
|
1237
1663
|
if (errorCode === "FORBIDDEN_PATH") return 403;
|
|
1238
1664
|
return 500;
|
|
1239
1665
|
}
|
|
1666
|
+
function isAnnotationThreadRole(value) {
|
|
1667
|
+
return value === "user" || value === "agent" || value === "system";
|
|
1668
|
+
}
|
|
1669
|
+
function formatSessionSseEvent(event) {
|
|
1670
|
+
return `event: ${event.type}
|
|
1671
|
+
data: ${JSON.stringify(event)}
|
|
1672
|
+
|
|
1673
|
+
`;
|
|
1674
|
+
}
|
|
1675
|
+
function normalizeSessionClaimTimeout(value) {
|
|
1676
|
+
if (!value?.trim()) return 3e4;
|
|
1677
|
+
const parsed = Number.parseInt(value, 10);
|
|
1678
|
+
if (!Number.isFinite(parsed)) return 3e4;
|
|
1679
|
+
return Math.max(0, Math.min(parsed, 3e5));
|
|
1680
|
+
}
|
|
1240
1681
|
|
|
1241
1682
|
// src/legacy/webpack4/index.ts
|
|
1242
1683
|
import path7 from "path";
|