@inspecto-dev/plugin 0.2.0-alpha.3 → 0.3.0-alpha.1
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 +1 -1
- package/dist/index.cjs +452 -195
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +452 -195
- package/dist/index.js.map +1 -1
- package/dist/legacy/rspack/index.cjs +454 -197
- package/dist/legacy/rspack/index.cjs.map +1 -1
- package/dist/legacy/rspack/index.js +454 -197
- package/dist/legacy/rspack/index.js.map +1 -1
- package/dist/legacy/webpack4/index.cjs +454 -197
- package/dist/legacy/webpack4/index.cjs.map +1 -1
- package/dist/legacy/webpack4/index.js +454 -197
- package/dist/legacy/webpack4/index.js.map +1 -1
- package/dist/rollup.cjs +452 -195
- package/dist/rollup.cjs.map +1 -1
- package/dist/rollup.js +452 -195
- package/dist/rollup.js.map +1 -1
- package/dist/rspack.cjs +452 -195
- package/dist/rspack.cjs.map +1 -1
- package/dist/rspack.js +452 -195
- package/dist/rspack.js.map +1 -1
- package/dist/vite.cjs +452 -195
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.js +452 -195
- package/dist/vite.js.map +1 -1
- package/dist/webpack.cjs +452 -195
- package/dist/webpack.cjs.map +1 -1
- package/dist/webpack.js +452 -195
- package/dist/webpack.js.map +1 -1
- package/package.json +2 -2
|
@@ -45,13 +45,11 @@ var resolveClientModule = () => {
|
|
|
45
45
|
|
|
46
46
|
// src/server/index.ts
|
|
47
47
|
import http from "http";
|
|
48
|
-
import
|
|
49
|
-
import
|
|
48
|
+
import fs4 from "fs";
|
|
49
|
+
import path6 from "path";
|
|
50
50
|
import os2 from "os";
|
|
51
|
-
import
|
|
52
|
-
import { execSync, execFileSync } from "child_process";
|
|
51
|
+
import crypto2 from "crypto";
|
|
53
52
|
import portfinder from "portfinder";
|
|
54
|
-
import { launchIDE } from "launch-ide";
|
|
55
53
|
import { INSPECTO_API_PATHS } from "@inspecto-dev/types";
|
|
56
54
|
|
|
57
55
|
// src/server/snippet.ts
|
|
@@ -375,9 +373,9 @@ function extractToolOverrides(ide, config) {
|
|
|
375
373
|
function resolveIntents(serverPrompts) {
|
|
376
374
|
const baseMap = /* @__PURE__ */ new Map();
|
|
377
375
|
for (const intent of DEFAULT_INTENTS) {
|
|
378
|
-
|
|
376
|
+
baseMap.set(intent.id, { ...intent });
|
|
379
377
|
}
|
|
380
|
-
const defaults = () =>
|
|
378
|
+
const defaults = () => Array.from(baseMap.values());
|
|
381
379
|
if (!serverPrompts) return defaults();
|
|
382
380
|
const isReplace = !Array.isArray(serverPrompts) && typeof serverPrompts === "object" && serverPrompts.$replace === true;
|
|
383
381
|
const promptsArray = Array.isArray(serverPrompts) ? serverPrompts : isReplace ? serverPrompts.items : [];
|
|
@@ -404,16 +402,18 @@ function resolveIntents(serverPrompts) {
|
|
|
404
402
|
);
|
|
405
403
|
continue;
|
|
406
404
|
}
|
|
407
|
-
if (item.
|
|
405
|
+
if (!item.aiIntent) {
|
|
408
406
|
configLogger.warn(
|
|
409
|
-
`
|
|
407
|
+
`Intent "${item.id}" is missing required "aiIntent".`
|
|
410
408
|
);
|
|
411
409
|
continue;
|
|
412
410
|
}
|
|
413
|
-
result.push(
|
|
411
|
+
result.push(
|
|
412
|
+
baseMap.has(item.id) ? { ...baseMap.get(item.id), ...item } : item
|
|
413
|
+
);
|
|
414
414
|
}
|
|
415
415
|
}
|
|
416
|
-
return
|
|
416
|
+
return result;
|
|
417
417
|
}
|
|
418
418
|
const merged = Array.from(baseMap.values());
|
|
419
419
|
for (const item of promptsArray) {
|
|
@@ -430,9 +430,9 @@ function resolveIntents(serverPrompts) {
|
|
|
430
430
|
configLogger.warn('Intent object missing required "id" field, skipping.');
|
|
431
431
|
continue;
|
|
432
432
|
}
|
|
433
|
-
if (item.
|
|
433
|
+
if (!item.aiIntent) {
|
|
434
434
|
configLogger.warn(
|
|
435
|
-
`
|
|
435
|
+
`Intent "${item.id}" is missing required "aiIntent".`
|
|
436
436
|
);
|
|
437
437
|
continue;
|
|
438
438
|
}
|
|
@@ -450,15 +450,7 @@ function resolveIntents(serverPrompts) {
|
|
|
450
450
|
}
|
|
451
451
|
}
|
|
452
452
|
}
|
|
453
|
-
return
|
|
454
|
-
}
|
|
455
|
-
function ensureOpenInEditorLast(intents) {
|
|
456
|
-
const idx = intents.findIndex((i) => i.id === "open-in-editor");
|
|
457
|
-
if (idx === -1 || idx === intents.length - 1) return intents;
|
|
458
|
-
const result = [...intents];
|
|
459
|
-
const item = result.splice(idx, 1)[0];
|
|
460
|
-
result.push(item);
|
|
461
|
-
return result;
|
|
453
|
+
return merged;
|
|
462
454
|
}
|
|
463
455
|
var watchers = [];
|
|
464
456
|
function watchConfig(onReload, cwd = process.cwd(), gitRoot) {
|
|
@@ -493,7 +485,10 @@ function watchConfig(onReload, cwd = process.cwd(), gitRoot) {
|
|
|
493
485
|
}
|
|
494
486
|
}
|
|
495
487
|
|
|
496
|
-
// src/server/
|
|
488
|
+
// src/server/dispatch-transport.ts
|
|
489
|
+
import crypto from "crypto";
|
|
490
|
+
import { execFileSync } from "child_process";
|
|
491
|
+
import { launchIDE } from "launch-ide";
|
|
497
492
|
var serverLogger = createLogger("inspecto:server", { logLevel: getGlobalLogLevel() });
|
|
498
493
|
var payloadTickets = /* @__PURE__ */ new Map();
|
|
499
494
|
function createTicket(payload) {
|
|
@@ -507,32 +502,8 @@ function createTicket(payload) {
|
|
|
507
502
|
);
|
|
508
503
|
return ticketId;
|
|
509
504
|
}
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
running: false,
|
|
513
|
-
projectRoot: "",
|
|
514
|
-
configRoot: "",
|
|
515
|
-
cwd: process.cwd()
|
|
516
|
-
};
|
|
517
|
-
var serverInstance = null;
|
|
518
|
-
function resolveProjectRoot() {
|
|
519
|
-
let gitRoot;
|
|
520
|
-
try {
|
|
521
|
-
serverLogger.info("Resolving project root...");
|
|
522
|
-
gitRoot = execSync("git rev-parse --show-toplevel", { encoding: "utf-8" }).trim();
|
|
523
|
-
serverLogger.info("Resolved project root: " + gitRoot);
|
|
524
|
-
} catch (e) {
|
|
525
|
-
serverLogger.error("Failed to resolve project root:", e);
|
|
526
|
-
gitRoot = process.cwd();
|
|
527
|
-
}
|
|
528
|
-
let current = gitRoot;
|
|
529
|
-
while (true) {
|
|
530
|
-
if (fs3.existsSync(path4.join(current, ".inspecto"))) return current;
|
|
531
|
-
const parent = path4.dirname(current);
|
|
532
|
-
if (parent === current) break;
|
|
533
|
-
current = parent;
|
|
534
|
-
}
|
|
535
|
-
return gitRoot;
|
|
505
|
+
function readTicket(ticketId) {
|
|
506
|
+
return payloadTickets.get(ticketId);
|
|
536
507
|
}
|
|
537
508
|
function launchURI(uri) {
|
|
538
509
|
try {
|
|
@@ -548,6 +519,378 @@ function launchURI(uri) {
|
|
|
548
519
|
launchIDE({ file: uri });
|
|
549
520
|
}
|
|
550
521
|
}
|
|
522
|
+
|
|
523
|
+
// src/server/dispatch-runtime.ts
|
|
524
|
+
function resolvePromptDispatchRuntime(state) {
|
|
525
|
+
const userConfig = loadUserConfigSync(false, state.cwd, state.projectRoot);
|
|
526
|
+
const resolvedTarget = resolveTargetTool(userConfig);
|
|
527
|
+
const finalIde = resolveFinalIde(userConfig.ide, state.ideInfo?.ide, state.ideInfo?.scheme);
|
|
528
|
+
const mode = resolveProviderMode(resolvedTarget, finalIde, userConfig);
|
|
529
|
+
const overrides = extractToolOverrides(finalIde, userConfig)[resolvedTarget] || void 0;
|
|
530
|
+
return {
|
|
531
|
+
resolvedTarget,
|
|
532
|
+
finalIde,
|
|
533
|
+
mode,
|
|
534
|
+
...hasOverrides(overrides) ? { overrides } : {},
|
|
535
|
+
...userConfig["prompt.autoSend"] !== void 0 ? { autoSend: Boolean(userConfig["prompt.autoSend"]) } : {}
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
function dispatchPromptThroughIde(runtime, payload) {
|
|
539
|
+
const ticketId = createTicket({
|
|
540
|
+
ide: runtime.finalIde,
|
|
541
|
+
target: runtime.resolvedTarget,
|
|
542
|
+
targetType: runtime.mode,
|
|
543
|
+
prompt: payload.prompt,
|
|
544
|
+
filePath: payload.filePath,
|
|
545
|
+
line: payload.line,
|
|
546
|
+
column: payload.column,
|
|
547
|
+
snippet: payload.snippet,
|
|
548
|
+
...payload.screenshotContext ? { screenshotContext: payload.screenshotContext } : {},
|
|
549
|
+
overrides: runtime.overrides,
|
|
550
|
+
autoSend: runtime.autoSend
|
|
551
|
+
});
|
|
552
|
+
const params = new URLSearchParams();
|
|
553
|
+
params.set("ticket", ticketId);
|
|
554
|
+
params.set("target", runtime.resolvedTarget);
|
|
555
|
+
launchURI(`${runtime.finalIde}://inspecto.inspecto/send?${params.toString()}`);
|
|
556
|
+
return {
|
|
557
|
+
success: true,
|
|
558
|
+
fallbackPayload: {
|
|
559
|
+
prompt: payload.prompt,
|
|
560
|
+
...payload.filePath ? { file: payload.filePath } : {}
|
|
561
|
+
}
|
|
562
|
+
};
|
|
563
|
+
}
|
|
564
|
+
function resolveFinalIde(configuredIde, activeIde, activeIdeScheme) {
|
|
565
|
+
if (configuredIde && activeIdeScheme && !activeIdeScheme.includes(configuredIde)) {
|
|
566
|
+
return configuredIde;
|
|
567
|
+
}
|
|
568
|
+
return configuredIde || activeIdeScheme || activeIde || "vscode";
|
|
569
|
+
}
|
|
570
|
+
function hasOverrides(overrides) {
|
|
571
|
+
return Boolean(overrides && Object.keys(overrides).length > 0);
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
// src/server/path-guards.ts
|
|
575
|
+
import path4 from "path";
|
|
576
|
+
function isWindowsAbsolutePath(file) {
|
|
577
|
+
return /^[a-zA-Z]:[\\/]/.test(file) || /^\\\\[^\\]+\\[^\\]+/.test(file);
|
|
578
|
+
}
|
|
579
|
+
function resolveWorkspacePath(file, cwd) {
|
|
580
|
+
if (isWindowsAbsolutePath(file)) {
|
|
581
|
+
return path4.win32.normalize(file);
|
|
582
|
+
}
|
|
583
|
+
return path4.isAbsolute(file) ? path4.resolve(file) : path4.resolve(cwd, file);
|
|
584
|
+
}
|
|
585
|
+
function assertPathWithinProject(file, projectRoot) {
|
|
586
|
+
const relativeToRoot = isWindowsAbsolutePath(file) || isWindowsAbsolutePath(projectRoot) ? path4.win32.relative(path4.win32.normalize(projectRoot), path4.win32.normalize(file)) : path4.relative(projectRoot, file);
|
|
587
|
+
if (relativeToRoot.startsWith("..") || path4.isAbsolute(relativeToRoot)) {
|
|
588
|
+
throw new Error("Access denied: File is outside of project workspace");
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
// src/server/annotation-dispatch.ts
|
|
593
|
+
var AnnotationDispatchError = class extends Error {
|
|
594
|
+
constructor(message, errorCode) {
|
|
595
|
+
super(message);
|
|
596
|
+
this.name = "AnnotationDispatchError";
|
|
597
|
+
this.errorCode = errorCode;
|
|
598
|
+
}
|
|
599
|
+
};
|
|
600
|
+
async function dispatchAnnotationsToAi(req, state) {
|
|
601
|
+
try {
|
|
602
|
+
validateAnnotationDispatchRequest(req, state);
|
|
603
|
+
const batch = normalizeAnnotationBatch(req);
|
|
604
|
+
const prompt = buildAnnotationBatchPrompt(batch);
|
|
605
|
+
const representativeTarget = batch.annotations[0]?.targets[0];
|
|
606
|
+
const runtime = resolvePromptDispatchRuntime(state);
|
|
607
|
+
return dispatchPromptThroughIde(runtime, {
|
|
608
|
+
prompt,
|
|
609
|
+
...representativeTarget?.file ? { filePath: representativeTarget.file } : {},
|
|
610
|
+
...representativeTarget?.line ? { line: representativeTarget.line } : {},
|
|
611
|
+
...representativeTarget?.column ? { column: representativeTarget.column } : {},
|
|
612
|
+
...batch.screenshotContext ? { screenshotContext: batch.screenshotContext } : {}
|
|
613
|
+
});
|
|
614
|
+
} catch (error) {
|
|
615
|
+
return {
|
|
616
|
+
success: false,
|
|
617
|
+
error: error instanceof Error ? error.message : String(error),
|
|
618
|
+
errorCode: getAnnotationDispatchErrorCode(error)
|
|
619
|
+
};
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
function validateAnnotationDispatchRequest(req, state) {
|
|
623
|
+
if (!req.annotations.length) {
|
|
624
|
+
throw new AnnotationDispatchError("At least one annotation is required.", "INVALID_REQUEST");
|
|
625
|
+
}
|
|
626
|
+
for (const annotation of req.annotations) {
|
|
627
|
+
if (!annotation.targets.length) {
|
|
628
|
+
throw new AnnotationDispatchError(
|
|
629
|
+
"Each annotation must include at least one target.",
|
|
630
|
+
"INVALID_REQUEST"
|
|
631
|
+
);
|
|
632
|
+
}
|
|
633
|
+
for (const target of annotation.targets) {
|
|
634
|
+
const absolutePath = resolveWorkspacePath(target.location.file, state.cwd);
|
|
635
|
+
assertPathWithinProject(absolutePath, state.projectRoot);
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
function normalizeAnnotationBatch(req) {
|
|
640
|
+
return {
|
|
641
|
+
instruction: req.instruction?.trim() ?? "",
|
|
642
|
+
responseMode: req.responseMode ?? "unified",
|
|
643
|
+
...req.runtimeContext ? { runtimeContext: req.runtimeContext } : {},
|
|
644
|
+
...req.screenshotContext ? { screenshotContext: req.screenshotContext } : {},
|
|
645
|
+
...req.cssContextPrompt?.trim() ? { cssContextPrompt: req.cssContextPrompt.trim() } : {},
|
|
646
|
+
annotations: req.annotations.map((annotation, index) => ({
|
|
647
|
+
index: index + 1,
|
|
648
|
+
note: annotation.note.trim(),
|
|
649
|
+
intent: annotation.intent,
|
|
650
|
+
targets: annotation.targets.map((target) => ({
|
|
651
|
+
file: target.location.file,
|
|
652
|
+
line: target.location.line,
|
|
653
|
+
column: target.location.column,
|
|
654
|
+
...target.label ? { label: target.label } : {},
|
|
655
|
+
...target.selector ? { selector: target.selector } : {},
|
|
656
|
+
...target.snippet ? { snippet: target.snippet } : {}
|
|
657
|
+
}))
|
|
658
|
+
}))
|
|
659
|
+
};
|
|
660
|
+
}
|
|
661
|
+
function buildAnnotationBatchPrompt(batch) {
|
|
662
|
+
const body = buildSelectedElementsPrompt(batch.annotations);
|
|
663
|
+
const prompt = batch.instruction ? `${batch.instruction}
|
|
664
|
+
|
|
665
|
+
${body}` : body;
|
|
666
|
+
return appendScreenshotContextSection(
|
|
667
|
+
appendCssContextSection(
|
|
668
|
+
appendRuntimeContextSection(prompt, batch.runtimeContext),
|
|
669
|
+
batch.cssContextPrompt
|
|
670
|
+
),
|
|
671
|
+
batch.screenshotContext
|
|
672
|
+
);
|
|
673
|
+
}
|
|
674
|
+
function appendCssContextSection(prompt, cssContextPrompt) {
|
|
675
|
+
if (!cssContextPrompt) return prompt;
|
|
676
|
+
return `${prompt}
|
|
677
|
+
|
|
678
|
+
${cssContextPrompt}`;
|
|
679
|
+
}
|
|
680
|
+
function buildSelectedElementsPrompt(annotations) {
|
|
681
|
+
const lines = ["Selected elements:"];
|
|
682
|
+
for (const annotation of annotations) {
|
|
683
|
+
const trimmedNote = annotation.note.trim();
|
|
684
|
+
for (const target of annotation.targets) {
|
|
685
|
+
const targetLabel = (target.label || "Unknown target").trim() || "Unknown target";
|
|
686
|
+
lines.push(`- ${targetLabel}`);
|
|
687
|
+
lines.push(`file=${target.file}:${target.line}:${target.column}`);
|
|
688
|
+
if (trimmedNote) {
|
|
689
|
+
lines.push(`note=${trimmedNote}`);
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
if (lines.length === 1) {
|
|
694
|
+
lines.push("- None");
|
|
695
|
+
}
|
|
696
|
+
return lines.join("\n");
|
|
697
|
+
}
|
|
698
|
+
function appendScreenshotContextSection(prompt, screenshotContext) {
|
|
699
|
+
if (!screenshotContext || !screenshotContext.imageDataUrl && !screenshotContext.imageAssetId) {
|
|
700
|
+
return prompt;
|
|
701
|
+
}
|
|
702
|
+
const lines = [
|
|
703
|
+
"Visual screenshot context attached:",
|
|
704
|
+
`- capturedAt=${screenshotContext.capturedAt}`,
|
|
705
|
+
`- mimeType=${screenshotContext.mimeType}`,
|
|
706
|
+
...screenshotContext.imageAssetId ? [`- imageAssetId=${screenshotContext.imageAssetId}`] : []
|
|
707
|
+
];
|
|
708
|
+
return `${prompt}
|
|
709
|
+
|
|
710
|
+
${lines.join("\n")}`;
|
|
711
|
+
}
|
|
712
|
+
function appendRuntimeContextSection(prompt, runtimeContext) {
|
|
713
|
+
if (!runtimeContext?.records.length) {
|
|
714
|
+
return prompt;
|
|
715
|
+
}
|
|
716
|
+
return `${prompt}
|
|
717
|
+
|
|
718
|
+
${buildRuntimeContextSection(runtimeContext.records)}`;
|
|
719
|
+
}
|
|
720
|
+
function buildRuntimeContextSection(records) {
|
|
721
|
+
return ["Relevant runtime context:", ...records.map(formatRuntimeRecord)].join("\n");
|
|
722
|
+
}
|
|
723
|
+
function formatRuntimeRecord(record) {
|
|
724
|
+
const requestSummary = record.kind === "failed-request" ? `request=${record.request?.method ?? "GET"} ${record.request?.pathname ?? record.request?.url ?? "unknown"} status=${record.request?.status ?? "unknown"}` : `occurrences=${record.occurrenceCount}`;
|
|
725
|
+
const reasonSummary = record.relevanceReasons.length ? record.relevanceReasons.join("; ") : "timing-based";
|
|
726
|
+
const stackSummary = record.stack ? `
|
|
727
|
+
stack=${record.stack.split("\n").slice(0, 5).join(" | ")}` : "";
|
|
728
|
+
return [
|
|
729
|
+
`- [${record.kind}] ${record.message}`,
|
|
730
|
+
` relevance=${record.relevanceLevel} (${reasonSummary})`,
|
|
731
|
+
` ${requestSummary}`,
|
|
732
|
+
stackSummary
|
|
733
|
+
].filter(Boolean).join("\n");
|
|
734
|
+
}
|
|
735
|
+
function getAnnotationDispatchErrorCode(error) {
|
|
736
|
+
if (error instanceof AnnotationDispatchError) return error.errorCode;
|
|
737
|
+
if (error instanceof Error && error.message.includes("outside of project workspace")) {
|
|
738
|
+
return "FORBIDDEN_PATH";
|
|
739
|
+
}
|
|
740
|
+
return "UNKNOWN";
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
// src/server/client-config.ts
|
|
744
|
+
async function buildClientConfig(serverState2) {
|
|
745
|
+
const userConfig = loadUserConfigSync(false, serverState2.cwd, serverState2.configRoot);
|
|
746
|
+
const promptsConfig = await loadPromptsConfig(false, serverState2.cwd, serverState2.configRoot);
|
|
747
|
+
const effectiveIde = userConfig.ide ?? "vscode";
|
|
748
|
+
let info;
|
|
749
|
+
if (!serverState2.ideInfo) {
|
|
750
|
+
info = { ide: effectiveIde };
|
|
751
|
+
} else {
|
|
752
|
+
const { scheme: _scheme, ...rest } = serverState2.ideInfo;
|
|
753
|
+
info = rest;
|
|
754
|
+
}
|
|
755
|
+
return {
|
|
756
|
+
...info,
|
|
757
|
+
prompts: resolveIntents(promptsConfig),
|
|
758
|
+
hotKeys: userConfig["inspector.hotKey"] ?? "alt",
|
|
759
|
+
theme: userConfig["inspector.theme"] ?? "auto",
|
|
760
|
+
includeSnippet: userConfig["prompt.includeSnippet"] ?? false,
|
|
761
|
+
runtimeContext: {
|
|
762
|
+
enabled: true,
|
|
763
|
+
preview: true,
|
|
764
|
+
maxRuntimeErrors: 3,
|
|
765
|
+
maxFailedRequests: 2
|
|
766
|
+
},
|
|
767
|
+
screenshotContext: {
|
|
768
|
+
enabled: false
|
|
769
|
+
},
|
|
770
|
+
annotationResponseMode: userConfig["prompt.annotationResponseMode"] ?? "unified",
|
|
771
|
+
autoSend: userConfig["prompt.autoSend"] ?? false
|
|
772
|
+
};
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
// src/server/open-file.ts
|
|
776
|
+
import { execFileSync as execFileSync2 } from "child_process";
|
|
777
|
+
import { launchIDE as launchIDE2 } from "launch-ide";
|
|
778
|
+
var serverLogger2 = createLogger("inspecto:server", { logLevel: getGlobalLogLevel() });
|
|
779
|
+
var VSCODE_FAMILY_SCHEMES = [
|
|
780
|
+
"vscode",
|
|
781
|
+
"vscode-insiders",
|
|
782
|
+
"cursor",
|
|
783
|
+
"windsurf",
|
|
784
|
+
"trae",
|
|
785
|
+
"trae-cn",
|
|
786
|
+
"vscodium",
|
|
787
|
+
"codebuddy",
|
|
788
|
+
"codebuddy-cn",
|
|
789
|
+
"antigravity"
|
|
790
|
+
];
|
|
791
|
+
function handleOpenFileRequest(body, serverState2) {
|
|
792
|
+
const absolutePath = resolveWorkspacePath(body.file, serverState2.cwd);
|
|
793
|
+
assertPathWithinProject(absolutePath, serverState2.projectRoot);
|
|
794
|
+
const userConfig = loadUserConfigSync(false, serverState2.cwd, serverState2.configRoot);
|
|
795
|
+
const configuredIde = userConfig.ide;
|
|
796
|
+
const activeIde = serverState2.ideInfo?.ide;
|
|
797
|
+
const activeIdeScheme = serverState2.ideInfo?.scheme;
|
|
798
|
+
const rawEditorHint = configuredIde || activeIde || activeIdeScheme || "code";
|
|
799
|
+
if (configuredIde && activeIdeScheme && !activeIdeScheme.includes(configuredIde)) {
|
|
800
|
+
serverLogger2.warn(
|
|
801
|
+
`Active IDE is ${activeIdeScheme}, but config forces ${configuredIde}. Using configured IDE.`
|
|
802
|
+
);
|
|
803
|
+
}
|
|
804
|
+
let editorHint = rawEditorHint;
|
|
805
|
+
if (rawEditorHint === "vscode") editorHint = "code";
|
|
806
|
+
else if (rawEditorHint === "vscode-insiders") editorHint = "code-insiders";
|
|
807
|
+
else if (rawEditorHint === "vscodium") editorHint = "codium";
|
|
808
|
+
else if (rawEditorHint === "trae-cn" || rawEditorHint === "trae") editorHint = "trae";
|
|
809
|
+
serverLogger2.debug(
|
|
810
|
+
`IDE_OPEN: activeIde=${activeIde}, activeIdeScheme=${activeIdeScheme}, configuredIde=${configuredIde} -> rawEditorHint=${rawEditorHint}, finalEditorHint=${editorHint}`
|
|
811
|
+
);
|
|
812
|
+
if (VSCODE_FAMILY_SCHEMES.includes(rawEditorHint)) {
|
|
813
|
+
let normalizedPath = absolutePath.replace(/\\/g, "/");
|
|
814
|
+
if (!normalizedPath.startsWith("/")) {
|
|
815
|
+
normalizedPath = "/" + normalizedPath;
|
|
816
|
+
}
|
|
817
|
+
const encodedPath = encodeURI(normalizedPath);
|
|
818
|
+
const uri = `${rawEditorHint}://file${encodedPath}:${body.line}:${body.column}`;
|
|
819
|
+
serverLogger2.debug(`IDE_OPEN: Bypassing launchIDE, using URI scheme directly: ${uri}`);
|
|
820
|
+
try {
|
|
821
|
+
if (process.platform === "darwin") {
|
|
822
|
+
execFileSync2("open", [uri]);
|
|
823
|
+
} else if (process.platform === "win32") {
|
|
824
|
+
execFileSync2("cmd", ["/c", "start", '""', uri]);
|
|
825
|
+
} else {
|
|
826
|
+
execFileSync2("xdg-open", [uri]);
|
|
827
|
+
}
|
|
828
|
+
} catch (e) {
|
|
829
|
+
serverLogger2.error(`Failed to launch URI for IDE_OPEN (${uri}):`, e);
|
|
830
|
+
launchIDE2({
|
|
831
|
+
file: absolutePath,
|
|
832
|
+
line: body.line,
|
|
833
|
+
column: body.column,
|
|
834
|
+
editor: editorHint,
|
|
835
|
+
type: process.platform === "darwin" ? "open" : "exec"
|
|
836
|
+
});
|
|
837
|
+
}
|
|
838
|
+
} else {
|
|
839
|
+
launchIDE2({
|
|
840
|
+
file: absolutePath,
|
|
841
|
+
line: body.line,
|
|
842
|
+
column: body.column,
|
|
843
|
+
editor: editorHint,
|
|
844
|
+
type: process.platform === "darwin" ? "open" : "exec"
|
|
845
|
+
});
|
|
846
|
+
}
|
|
847
|
+
return { success: true };
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
// src/server/project-root.ts
|
|
851
|
+
import fs3 from "fs";
|
|
852
|
+
import path5 from "path";
|
|
853
|
+
import { execSync } from "child_process";
|
|
854
|
+
var serverLogger3 = createLogger("inspecto:server", { logLevel: getGlobalLogLevel() });
|
|
855
|
+
function resolveProjectRoot() {
|
|
856
|
+
const cwd = process.cwd();
|
|
857
|
+
let gitRoot;
|
|
858
|
+
try {
|
|
859
|
+
gitRoot = execSync("git rev-parse --show-toplevel", { encoding: "utf-8" }).trim();
|
|
860
|
+
} catch (e) {
|
|
861
|
+
serverLogger3.warn("Failed to resolve git root via git rev-parse:", e);
|
|
862
|
+
gitRoot = cwd;
|
|
863
|
+
}
|
|
864
|
+
const visited = /* @__PURE__ */ new Set();
|
|
865
|
+
const search = (start, stop) => {
|
|
866
|
+
let current = start;
|
|
867
|
+
while (!visited.has(current)) {
|
|
868
|
+
visited.add(current);
|
|
869
|
+
if (fs3.existsSync(path5.join(current, ".inspecto"))) return current;
|
|
870
|
+
if (current === stop) break;
|
|
871
|
+
const parent = path5.dirname(current);
|
|
872
|
+
if (parent === current) break;
|
|
873
|
+
current = parent;
|
|
874
|
+
}
|
|
875
|
+
return null;
|
|
876
|
+
};
|
|
877
|
+
const cwdMatch = search(cwd, path5.parse(cwd).root);
|
|
878
|
+
if (cwdMatch) return cwdMatch;
|
|
879
|
+
const repoMatch = search(gitRoot, path5.parse(gitRoot).root);
|
|
880
|
+
if (repoMatch) return repoMatch;
|
|
881
|
+
return gitRoot;
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
// src/server/index.ts
|
|
885
|
+
var serverLogger4 = createLogger("inspecto:server", { logLevel: getGlobalLogLevel() });
|
|
886
|
+
var serverState = {
|
|
887
|
+
port: null,
|
|
888
|
+
running: false,
|
|
889
|
+
projectRoot: "",
|
|
890
|
+
configRoot: "",
|
|
891
|
+
cwd: process.cwd()
|
|
892
|
+
};
|
|
893
|
+
var serverInstance = null;
|
|
551
894
|
async function startServer() {
|
|
552
895
|
if (serverState.running && serverState.port !== null) {
|
|
553
896
|
return serverState.port;
|
|
@@ -559,7 +902,7 @@ async function startServer() {
|
|
|
559
902
|
const port = await portfinder.getPortPromise();
|
|
560
903
|
watchConfig(
|
|
561
904
|
() => {
|
|
562
|
-
|
|
905
|
+
serverLogger4.info("user config reloaded.");
|
|
563
906
|
},
|
|
564
907
|
serverState.cwd,
|
|
565
908
|
serverState.configRoot
|
|
@@ -575,7 +918,7 @@ async function startServer() {
|
|
|
575
918
|
}
|
|
576
919
|
const url = new URL(req.url ?? "/", `http://localhost:${port}`);
|
|
577
920
|
handleRequest(url, req, res).catch((err) => {
|
|
578
|
-
|
|
921
|
+
serverLogger4.error("server error:", err);
|
|
579
922
|
res.writeHead(500, { "Content-Type": "application/json" });
|
|
580
923
|
res.end(JSON.stringify({ success: false, error: String(err) }));
|
|
581
924
|
});
|
|
@@ -588,41 +931,41 @@ async function startServer() {
|
|
|
588
931
|
serverInstance.once("error", reject);
|
|
589
932
|
});
|
|
590
933
|
serverInstance.on("error", (err) => {
|
|
591
|
-
|
|
934
|
+
serverLogger4.error("persistent server error:", err);
|
|
592
935
|
});
|
|
593
936
|
serverState.port = port;
|
|
594
937
|
serverState.running = true;
|
|
595
|
-
const portFile =
|
|
938
|
+
const portFile = path6.join(os2.tmpdir(), "inspecto.port.json");
|
|
596
939
|
try {
|
|
597
940
|
let portData = {};
|
|
598
|
-
if (
|
|
941
|
+
if (fs4.existsSync(portFile)) {
|
|
599
942
|
try {
|
|
600
|
-
portData = JSON.parse(
|
|
943
|
+
portData = JSON.parse(fs4.readFileSync(portFile, "utf-8"));
|
|
601
944
|
} catch (e) {
|
|
602
945
|
}
|
|
603
946
|
}
|
|
604
|
-
const rootHash =
|
|
947
|
+
const rootHash = crypto2.createHash("md5").update(serverState.projectRoot).digest("hex");
|
|
605
948
|
portData[rootHash] = port;
|
|
606
|
-
|
|
949
|
+
fs4.writeFileSync(portFile, JSON.stringify(portData, null, 2), "utf-8");
|
|
607
950
|
} catch (e) {
|
|
608
|
-
|
|
951
|
+
serverLogger4.warn("Failed to write port file:", e);
|
|
609
952
|
}
|
|
610
953
|
process.once("exit", () => {
|
|
611
954
|
try {
|
|
612
|
-
if (
|
|
613
|
-
const portData = JSON.parse(
|
|
614
|
-
const rootHash =
|
|
955
|
+
if (fs4.existsSync(portFile)) {
|
|
956
|
+
const portData = JSON.parse(fs4.readFileSync(portFile, "utf-8"));
|
|
957
|
+
const rootHash = crypto2.createHash("md5").update(serverState.projectRoot).digest("hex");
|
|
615
958
|
delete portData[rootHash];
|
|
616
959
|
if (Object.keys(portData).length === 0) {
|
|
617
|
-
|
|
960
|
+
fs4.unlinkSync(portFile);
|
|
618
961
|
} else {
|
|
619
|
-
|
|
962
|
+
fs4.writeFileSync(portFile, JSON.stringify(portData, null, 2), "utf-8");
|
|
620
963
|
}
|
|
621
964
|
}
|
|
622
965
|
} catch {
|
|
623
966
|
}
|
|
624
967
|
});
|
|
625
|
-
|
|
968
|
+
serverLogger4.info(`server running at http://127.0.0.1:${port}`);
|
|
626
969
|
return port;
|
|
627
970
|
}
|
|
628
971
|
async function readBody(req) {
|
|
@@ -641,26 +984,7 @@ async function handleRequest(url, req, res) {
|
|
|
641
984
|
return;
|
|
642
985
|
}
|
|
643
986
|
if (pathname === INSPECTO_API_PATHS.CLIENT_CONFIG && req.method === "GET") {
|
|
644
|
-
const
|
|
645
|
-
const promptsConfig = await loadPromptsConfig(false, serverState.cwd, serverState.configRoot);
|
|
646
|
-
const effectiveIde = userConfig.ide ?? "vscode";
|
|
647
|
-
let info;
|
|
648
|
-
if (!serverState.ideInfo) {
|
|
649
|
-
info = {
|
|
650
|
-
ide: effectiveIde
|
|
651
|
-
};
|
|
652
|
-
} else {
|
|
653
|
-
const { scheme: _scheme, ...rest } = serverState.ideInfo;
|
|
654
|
-
info = rest;
|
|
655
|
-
}
|
|
656
|
-
const config = {
|
|
657
|
-
...info,
|
|
658
|
-
prompts: resolveIntents(promptsConfig),
|
|
659
|
-
hotKeys: userConfig["inspector.hotKey"] ?? "alt",
|
|
660
|
-
theme: userConfig["inspector.theme"] ?? "auto",
|
|
661
|
-
includeSnippet: userConfig["prompt.includeSnippet"] ?? false,
|
|
662
|
-
autoSend: userConfig["prompt.autoSend"] ?? false
|
|
663
|
-
};
|
|
987
|
+
const config = await buildClientConfig(serverState);
|
|
664
988
|
delete config.providers;
|
|
665
989
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
666
990
|
res.end(JSON.stringify(config));
|
|
@@ -671,21 +995,23 @@ async function handleRequest(url, req, res) {
|
|
|
671
995
|
const body = JSON.parse(await readBody(req));
|
|
672
996
|
const ideWorkspace = body.workspaceRoot || "";
|
|
673
997
|
const serverProjectRoot = serverState.projectRoot || "";
|
|
674
|
-
const
|
|
998
|
+
const normalizedIdeRoot = ideWorkspace ? path6.resolve(ideWorkspace) : "";
|
|
999
|
+
const normalizedServerRoot = serverProjectRoot ? path6.resolve(serverProjectRoot) : "";
|
|
1000
|
+
const isSameProject = !normalizedIdeRoot || !normalizedServerRoot || normalizedIdeRoot === normalizedServerRoot || normalizedServerRoot.startsWith(normalizedIdeRoot + path6.sep) || normalizedIdeRoot.startsWith(normalizedServerRoot + path6.sep);
|
|
675
1001
|
if (isSameProject) {
|
|
676
1002
|
serverState.ideInfo = body;
|
|
677
|
-
|
|
1003
|
+
serverLogger4.debug(
|
|
678
1004
|
`Accepted IDE info from matched workspace (ide-${body.ide} / schema-${body.scheme})`
|
|
679
1005
|
);
|
|
680
1006
|
} else {
|
|
681
|
-
|
|
1007
|
+
serverLogger4.debug(
|
|
682
1008
|
`Ignored IDE info from unrelated workspace (IDE Workspace: ${ideWorkspace}, Server: ${serverProjectRoot}, Scheme: ${body.scheme}, IDE: ${body.ide})`
|
|
683
1009
|
);
|
|
684
1010
|
}
|
|
685
1011
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
686
1012
|
res.end(JSON.stringify({ success: true }));
|
|
687
1013
|
} catch (e) {
|
|
688
|
-
|
|
1014
|
+
serverLogger4.error(`Error parsing ${INSPECTO_API_PATHS.IDE_INFO} POST request:`, e);
|
|
689
1015
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
690
1016
|
res.end(JSON.stringify({ error: "Invalid JSON body" }));
|
|
691
1017
|
}
|
|
@@ -700,74 +1026,14 @@ async function handleRequest(url, req, res) {
|
|
|
700
1026
|
res.end(JSON.stringify({ error: "Invalid JSON body" }));
|
|
701
1027
|
return;
|
|
702
1028
|
}
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
1029
|
+
try {
|
|
1030
|
+
handleOpenFileRequest(body, serverState);
|
|
1031
|
+
} catch {
|
|
1032
|
+
serverLogger4.warn(`Security: Blocked path traversal attempt in IDE_OPEN: ${body.file}`);
|
|
707
1033
|
res.writeHead(403, { "Content-Type": "application/json" });
|
|
708
1034
|
res.end(JSON.stringify({ error: "Access denied: File is outside of project workspace" }));
|
|
709
1035
|
return;
|
|
710
1036
|
}
|
|
711
|
-
const userConfig = loadUserConfigSync(false, serverState.cwd, serverState.configRoot);
|
|
712
|
-
const configuredIde = userConfig.ide;
|
|
713
|
-
const activeIde = serverState.ideInfo?.ide;
|
|
714
|
-
const activeIdeScheme = serverState.ideInfo?.scheme;
|
|
715
|
-
const rawEditorHint = configuredIde || activeIde || activeIdeScheme || "code";
|
|
716
|
-
if (configuredIde && activeIdeScheme && !activeIdeScheme.includes(configuredIde)) {
|
|
717
|
-
serverLogger.warn(
|
|
718
|
-
`Active IDE is ${activeIdeScheme}, but config forces ${configuredIde}. Using configured IDE.`
|
|
719
|
-
);
|
|
720
|
-
}
|
|
721
|
-
let editorHint = rawEditorHint;
|
|
722
|
-
if (rawEditorHint === "vscode") editorHint = "code";
|
|
723
|
-
else if (rawEditorHint === "vscode-insiders") editorHint = "code-insiders";
|
|
724
|
-
else if (rawEditorHint === "vscodium") editorHint = "codium";
|
|
725
|
-
else if (rawEditorHint === "trae-cn" || rawEditorHint === "trae") editorHint = "trae";
|
|
726
|
-
serverLogger.debug(
|
|
727
|
-
`IDE_OPEN: activeIde=${activeIde}, activeIdeScheme=${activeIdeScheme}, configuredIde=${configuredIde} -> rawEditorHint=${rawEditorHint}, finalEditorHint=${editorHint}`
|
|
728
|
-
);
|
|
729
|
-
const VSCODE_FAMILY_SCHEMES = [
|
|
730
|
-
"vscode",
|
|
731
|
-
"vscode-insiders",
|
|
732
|
-
"cursor",
|
|
733
|
-
"windsurf",
|
|
734
|
-
"trae",
|
|
735
|
-
"trae-cn",
|
|
736
|
-
"vscodium",
|
|
737
|
-
"codebuddy",
|
|
738
|
-
"codebuddy-cn",
|
|
739
|
-
"antigravity"
|
|
740
|
-
];
|
|
741
|
-
if (VSCODE_FAMILY_SCHEMES.includes(rawEditorHint)) {
|
|
742
|
-
const uri = `${rawEditorHint}://file${absolutePath}:${body.line}:${body.column}`;
|
|
743
|
-
serverLogger.debug(`IDE_OPEN: Bypassing launchIDE, using URI scheme directly: ${uri}`);
|
|
744
|
-
try {
|
|
745
|
-
if (process.platform === "darwin") {
|
|
746
|
-
execFileSync("open", [uri]);
|
|
747
|
-
} else if (process.platform === "win32") {
|
|
748
|
-
execFileSync("cmd", ["/c", "start", '""', uri]);
|
|
749
|
-
} else {
|
|
750
|
-
execFileSync("xdg-open", [uri]);
|
|
751
|
-
}
|
|
752
|
-
} catch (e) {
|
|
753
|
-
serverLogger.error(`Failed to launch URI for IDE_OPEN (${uri}):`, e);
|
|
754
|
-
launchIDE({
|
|
755
|
-
file: absolutePath,
|
|
756
|
-
line: body.line,
|
|
757
|
-
column: body.column,
|
|
758
|
-
editor: editorHint,
|
|
759
|
-
type: process.platform === "darwin" ? "open" : "exec"
|
|
760
|
-
});
|
|
761
|
-
}
|
|
762
|
-
} else {
|
|
763
|
-
launchIDE({
|
|
764
|
-
file: absolutePath,
|
|
765
|
-
line: body.line,
|
|
766
|
-
column: body.column,
|
|
767
|
-
editor: editorHint,
|
|
768
|
-
type: process.platform === "darwin" ? "open" : "exec"
|
|
769
|
-
});
|
|
770
|
-
}
|
|
771
1037
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
772
1038
|
res.end(JSON.stringify({ success: true }));
|
|
773
1039
|
return;
|
|
@@ -778,10 +1044,11 @@ async function handleRequest(url, req, res) {
|
|
|
778
1044
|
const column = parseInt(url.searchParams.get("column") ?? "1", 10);
|
|
779
1045
|
const maxLines = parseInt(url.searchParams.get("maxLines") ?? "100", 10);
|
|
780
1046
|
try {
|
|
781
|
-
const absolutePath =
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
1047
|
+
const absolutePath = resolveWorkspacePath(file, serverState.cwd);
|
|
1048
|
+
try {
|
|
1049
|
+
assertPathWithinProject(absolutePath, serverState.projectRoot);
|
|
1050
|
+
} catch {
|
|
1051
|
+
serverLogger4.warn(`Security: Blocked path traversal attempt in PROJECT_SNIPPET: ${file}`);
|
|
785
1052
|
res.writeHead(403, { "Content-Type": "application/json" });
|
|
786
1053
|
res.end(
|
|
787
1054
|
JSON.stringify({
|
|
@@ -811,7 +1078,23 @@ async function handleRequest(url, req, res) {
|
|
|
811
1078
|
res.writeHead(result.success ? 200 : 500, { "Content-Type": "application/json" });
|
|
812
1079
|
res.end(JSON.stringify(result));
|
|
813
1080
|
} catch (e) {
|
|
814
|
-
|
|
1081
|
+
serverLogger4.error(`Error parsing ${INSPECTO_API_PATHS.AI_DISPATCH} request:`, e);
|
|
1082
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
1083
|
+
res.end(JSON.stringify({ success: false, error: String(e), errorCode: "INTERNAL_ERROR" }));
|
|
1084
|
+
}
|
|
1085
|
+
return;
|
|
1086
|
+
}
|
|
1087
|
+
if (pathname === INSPECTO_API_PATHS.AI_BATCH_DISPATCH && req.method === "POST") {
|
|
1088
|
+
try {
|
|
1089
|
+
const rawBody = await readBody(req);
|
|
1090
|
+
const body = JSON.parse(rawBody);
|
|
1091
|
+
const result = await dispatchAnnotationsToAi(body, serverState);
|
|
1092
|
+
res.writeHead(getBatchDispatchStatusCode(result.errorCode, result.success), {
|
|
1093
|
+
"Content-Type": "application/json"
|
|
1094
|
+
});
|
|
1095
|
+
res.end(JSON.stringify(result));
|
|
1096
|
+
} catch (e) {
|
|
1097
|
+
serverLogger4.error(`Error parsing ${INSPECTO_API_PATHS.AI_BATCH_DISPATCH} request:`, e);
|
|
815
1098
|
res.writeHead(500, { "Content-Type": "application/json" });
|
|
816
1099
|
res.end(JSON.stringify({ success: false, error: String(e), errorCode: "INTERNAL_ERROR" }));
|
|
817
1100
|
}
|
|
@@ -819,7 +1102,7 @@ async function handleRequest(url, req, res) {
|
|
|
819
1102
|
}
|
|
820
1103
|
if (pathname.startsWith(`${INSPECTO_API_PATHS.AI_TICKET}/`) && req.method === "GET") {
|
|
821
1104
|
const ticketId = pathname.substring(INSPECTO_API_PATHS.AI_TICKET.length + 1);
|
|
822
|
-
const payloadStr =
|
|
1105
|
+
const payloadStr = readTicket(ticketId);
|
|
823
1106
|
if (!payloadStr) {
|
|
824
1107
|
res.writeHead(404, { "Content-Type": "application/json" });
|
|
825
1108
|
res.end(JSON.stringify({ success: false, error: "Ticket not found or expired" }));
|
|
@@ -833,58 +1116,32 @@ async function handleRequest(url, req, res) {
|
|
|
833
1116
|
res.end(JSON.stringify({ error: "not found" }));
|
|
834
1117
|
}
|
|
835
1118
|
async function dispatchToAi(req) {
|
|
836
|
-
const { location, snippet, prompt } = req;
|
|
837
|
-
const userConfig = loadUserConfigSync(false, serverState.cwd, serverState.configRoot);
|
|
838
|
-
const resolvedTarget = resolveTargetTool(userConfig);
|
|
1119
|
+
const { location, snippet, prompt, screenshotContext } = req;
|
|
839
1120
|
const formattedPrompt = prompt ?? `Please help me with this code from \`${location.file}\` (line ${location.line}):
|
|
840
1121
|
|
|
841
1122
|
\`\`\`
|
|
842
1123
|
${snippet}
|
|
843
1124
|
\`\`\`
|
|
844
1125
|
`;
|
|
845
|
-
const
|
|
846
|
-
|
|
847
|
-
const activeIde = serverState.ideInfo?.ide;
|
|
848
|
-
const activeIdeScheme = serverState.ideInfo?.scheme;
|
|
849
|
-
const finalIde = configuredIde || activeIdeScheme || activeIde || "vscode";
|
|
850
|
-
if (configuredIde && activeIdeScheme && !activeIdeScheme.includes(configuredIde)) {
|
|
851
|
-
serverLogger.warn(
|
|
852
|
-
`dispatchToAi: Active IDE is ${activeIdeScheme}, but config forces ${configuredIde}. Using configured IDE.`
|
|
853
|
-
);
|
|
854
|
-
}
|
|
855
|
-
const mode = resolveProviderMode(resolvedTarget, finalIde, userConfig);
|
|
856
|
-
const overrides = extractToolOverrides(finalIde, userConfig)[resolvedTarget] || {};
|
|
857
|
-
overrides.type = mode;
|
|
858
|
-
const fullPayload = {
|
|
859
|
-
ide: finalIde,
|
|
860
|
-
target: resolvedTarget,
|
|
861
|
-
targetType: mode,
|
|
1126
|
+
const runtime = resolvePromptDispatchRuntime(serverState);
|
|
1127
|
+
return dispatchPromptThroughIde(runtime, {
|
|
862
1128
|
prompt: formattedPrompt,
|
|
863
1129
|
filePath: location.file,
|
|
864
1130
|
line: location.line,
|
|
865
1131
|
column: location.column,
|
|
866
1132
|
snippet,
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
serverLogger.debug(`dispatchToAi: Generated URI: ${uri}`);
|
|
876
|
-
launchURI(uri);
|
|
877
|
-
return {
|
|
878
|
-
success: true,
|
|
879
|
-
fallbackPayload: {
|
|
880
|
-
prompt: formattedPrompt,
|
|
881
|
-
file: location.file
|
|
882
|
-
}
|
|
883
|
-
};
|
|
1133
|
+
...screenshotContext ? { screenshotContext } : {}
|
|
1134
|
+
});
|
|
1135
|
+
}
|
|
1136
|
+
function getBatchDispatchStatusCode(errorCode, success) {
|
|
1137
|
+
if (success) return 200;
|
|
1138
|
+
if (errorCode === "INVALID_REQUEST") return 400;
|
|
1139
|
+
if (errorCode === "FORBIDDEN_PATH") return 403;
|
|
1140
|
+
return 500;
|
|
884
1141
|
}
|
|
885
1142
|
|
|
886
1143
|
// src/legacy/webpack4/index.ts
|
|
887
|
-
import
|
|
1144
|
+
import path7 from "path";
|
|
888
1145
|
var InspectoWebpack4Plugin = class {
|
|
889
1146
|
constructor(options = {}) {
|
|
890
1147
|
this.options = options;
|
|
@@ -892,7 +1149,7 @@ var InspectoWebpack4Plugin = class {
|
|
|
892
1149
|
apply(compiler) {
|
|
893
1150
|
const clientPath = resolveClientModule();
|
|
894
1151
|
compiler.hooks.afterEnvironment.tap("InspectoWebpack4Plugin", () => {
|
|
895
|
-
const inspectoLoader =
|
|
1152
|
+
const inspectoLoader = path7.resolve(__dirname, "loader.cjs");
|
|
896
1153
|
compiler.options.module.rules.push({
|
|
897
1154
|
test: /\.[jt]sx?$/,
|
|
898
1155
|
enforce: "pre",
|