@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
|
@@ -14,13 +14,11 @@ var __dirname = /* @__PURE__ */ getDirname();
|
|
|
14
14
|
|
|
15
15
|
// src/server/index.ts
|
|
16
16
|
import http from "http";
|
|
17
|
-
import
|
|
18
|
-
import
|
|
17
|
+
import fs4 from "fs";
|
|
18
|
+
import path6 from "path";
|
|
19
19
|
import os2 from "os";
|
|
20
|
-
import
|
|
21
|
-
import { execSync, execFileSync } from "child_process";
|
|
20
|
+
import crypto2 from "crypto";
|
|
22
21
|
import portfinder from "portfinder";
|
|
23
|
-
import { launchIDE } from "launch-ide";
|
|
24
22
|
import { INSPECTO_API_PATHS } from "@inspecto-dev/types";
|
|
25
23
|
|
|
26
24
|
// src/server/snippet.ts
|
|
@@ -344,9 +342,9 @@ function extractToolOverrides(ide, config) {
|
|
|
344
342
|
function resolveIntents(serverPrompts) {
|
|
345
343
|
const baseMap = /* @__PURE__ */ new Map();
|
|
346
344
|
for (const intent of DEFAULT_INTENTS) {
|
|
347
|
-
|
|
345
|
+
baseMap.set(intent.id, { ...intent });
|
|
348
346
|
}
|
|
349
|
-
const defaults = () =>
|
|
347
|
+
const defaults = () => Array.from(baseMap.values());
|
|
350
348
|
if (!serverPrompts) return defaults();
|
|
351
349
|
const isReplace = !Array.isArray(serverPrompts) && typeof serverPrompts === "object" && serverPrompts.$replace === true;
|
|
352
350
|
const promptsArray = Array.isArray(serverPrompts) ? serverPrompts : isReplace ? serverPrompts.items : [];
|
|
@@ -373,16 +371,18 @@ function resolveIntents(serverPrompts) {
|
|
|
373
371
|
);
|
|
374
372
|
continue;
|
|
375
373
|
}
|
|
376
|
-
if (item.
|
|
374
|
+
if (!item.aiIntent) {
|
|
377
375
|
configLogger.warn(
|
|
378
|
-
`
|
|
376
|
+
`Intent "${item.id}" is missing required "aiIntent".`
|
|
379
377
|
);
|
|
380
378
|
continue;
|
|
381
379
|
}
|
|
382
|
-
result.push(
|
|
380
|
+
result.push(
|
|
381
|
+
baseMap.has(item.id) ? { ...baseMap.get(item.id), ...item } : item
|
|
382
|
+
);
|
|
383
383
|
}
|
|
384
384
|
}
|
|
385
|
-
return
|
|
385
|
+
return result;
|
|
386
386
|
}
|
|
387
387
|
const merged = Array.from(baseMap.values());
|
|
388
388
|
for (const item of promptsArray) {
|
|
@@ -399,9 +399,9 @@ function resolveIntents(serverPrompts) {
|
|
|
399
399
|
configLogger.warn('Intent object missing required "id" field, skipping.');
|
|
400
400
|
continue;
|
|
401
401
|
}
|
|
402
|
-
if (item.
|
|
402
|
+
if (!item.aiIntent) {
|
|
403
403
|
configLogger.warn(
|
|
404
|
-
`
|
|
404
|
+
`Intent "${item.id}" is missing required "aiIntent".`
|
|
405
405
|
);
|
|
406
406
|
continue;
|
|
407
407
|
}
|
|
@@ -419,15 +419,7 @@ function resolveIntents(serverPrompts) {
|
|
|
419
419
|
}
|
|
420
420
|
}
|
|
421
421
|
}
|
|
422
|
-
return
|
|
423
|
-
}
|
|
424
|
-
function ensureOpenInEditorLast(intents) {
|
|
425
|
-
const idx = intents.findIndex((i) => i.id === "open-in-editor");
|
|
426
|
-
if (idx === -1 || idx === intents.length - 1) return intents;
|
|
427
|
-
const result = [...intents];
|
|
428
|
-
const item = result.splice(idx, 1)[0];
|
|
429
|
-
result.push(item);
|
|
430
|
-
return result;
|
|
422
|
+
return merged;
|
|
431
423
|
}
|
|
432
424
|
var watchers = [];
|
|
433
425
|
function watchConfig(onReload, cwd = process.cwd(), gitRoot) {
|
|
@@ -462,7 +454,10 @@ function watchConfig(onReload, cwd = process.cwd(), gitRoot) {
|
|
|
462
454
|
}
|
|
463
455
|
}
|
|
464
456
|
|
|
465
|
-
// src/server/
|
|
457
|
+
// src/server/dispatch-transport.ts
|
|
458
|
+
import crypto from "crypto";
|
|
459
|
+
import { execFileSync } from "child_process";
|
|
460
|
+
import { launchIDE } from "launch-ide";
|
|
466
461
|
var serverLogger = createLogger("inspecto:server", { logLevel: getGlobalLogLevel() });
|
|
467
462
|
var payloadTickets = /* @__PURE__ */ new Map();
|
|
468
463
|
function createTicket(payload) {
|
|
@@ -476,32 +471,8 @@ function createTicket(payload) {
|
|
|
476
471
|
);
|
|
477
472
|
return ticketId;
|
|
478
473
|
}
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
running: false,
|
|
482
|
-
projectRoot: "",
|
|
483
|
-
configRoot: "",
|
|
484
|
-
cwd: process.cwd()
|
|
485
|
-
};
|
|
486
|
-
var serverInstance = null;
|
|
487
|
-
function resolveProjectRoot() {
|
|
488
|
-
let gitRoot;
|
|
489
|
-
try {
|
|
490
|
-
serverLogger.info("Resolving project root...");
|
|
491
|
-
gitRoot = execSync("git rev-parse --show-toplevel", { encoding: "utf-8" }).trim();
|
|
492
|
-
serverLogger.info("Resolved project root: " + gitRoot);
|
|
493
|
-
} catch (e) {
|
|
494
|
-
serverLogger.error("Failed to resolve project root:", e);
|
|
495
|
-
gitRoot = process.cwd();
|
|
496
|
-
}
|
|
497
|
-
let current = gitRoot;
|
|
498
|
-
while (true) {
|
|
499
|
-
if (fs3.existsSync(path4.join(current, ".inspecto"))) return current;
|
|
500
|
-
const parent = path4.dirname(current);
|
|
501
|
-
if (parent === current) break;
|
|
502
|
-
current = parent;
|
|
503
|
-
}
|
|
504
|
-
return gitRoot;
|
|
474
|
+
function readTicket(ticketId) {
|
|
475
|
+
return payloadTickets.get(ticketId);
|
|
505
476
|
}
|
|
506
477
|
function launchURI(uri) {
|
|
507
478
|
try {
|
|
@@ -517,6 +488,378 @@ function launchURI(uri) {
|
|
|
517
488
|
launchIDE({ file: uri });
|
|
518
489
|
}
|
|
519
490
|
}
|
|
491
|
+
|
|
492
|
+
// src/server/dispatch-runtime.ts
|
|
493
|
+
function resolvePromptDispatchRuntime(state) {
|
|
494
|
+
const userConfig = loadUserConfigSync(false, state.cwd, state.projectRoot);
|
|
495
|
+
const resolvedTarget = resolveTargetTool(userConfig);
|
|
496
|
+
const finalIde = resolveFinalIde(userConfig.ide, state.ideInfo?.ide, state.ideInfo?.scheme);
|
|
497
|
+
const mode = resolveProviderMode(resolvedTarget, finalIde, userConfig);
|
|
498
|
+
const overrides = extractToolOverrides(finalIde, userConfig)[resolvedTarget] || void 0;
|
|
499
|
+
return {
|
|
500
|
+
resolvedTarget,
|
|
501
|
+
finalIde,
|
|
502
|
+
mode,
|
|
503
|
+
...hasOverrides(overrides) ? { overrides } : {},
|
|
504
|
+
...userConfig["prompt.autoSend"] !== void 0 ? { autoSend: Boolean(userConfig["prompt.autoSend"]) } : {}
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
function dispatchPromptThroughIde(runtime, payload) {
|
|
508
|
+
const ticketId = createTicket({
|
|
509
|
+
ide: runtime.finalIde,
|
|
510
|
+
target: runtime.resolvedTarget,
|
|
511
|
+
targetType: runtime.mode,
|
|
512
|
+
prompt: payload.prompt,
|
|
513
|
+
filePath: payload.filePath,
|
|
514
|
+
line: payload.line,
|
|
515
|
+
column: payload.column,
|
|
516
|
+
snippet: payload.snippet,
|
|
517
|
+
...payload.screenshotContext ? { screenshotContext: payload.screenshotContext } : {},
|
|
518
|
+
overrides: runtime.overrides,
|
|
519
|
+
autoSend: runtime.autoSend
|
|
520
|
+
});
|
|
521
|
+
const params = new URLSearchParams();
|
|
522
|
+
params.set("ticket", ticketId);
|
|
523
|
+
params.set("target", runtime.resolvedTarget);
|
|
524
|
+
launchURI(`${runtime.finalIde}://inspecto.inspecto/send?${params.toString()}`);
|
|
525
|
+
return {
|
|
526
|
+
success: true,
|
|
527
|
+
fallbackPayload: {
|
|
528
|
+
prompt: payload.prompt,
|
|
529
|
+
...payload.filePath ? { file: payload.filePath } : {}
|
|
530
|
+
}
|
|
531
|
+
};
|
|
532
|
+
}
|
|
533
|
+
function resolveFinalIde(configuredIde, activeIde, activeIdeScheme) {
|
|
534
|
+
if (configuredIde && activeIdeScheme && !activeIdeScheme.includes(configuredIde)) {
|
|
535
|
+
return configuredIde;
|
|
536
|
+
}
|
|
537
|
+
return configuredIde || activeIdeScheme || activeIde || "vscode";
|
|
538
|
+
}
|
|
539
|
+
function hasOverrides(overrides) {
|
|
540
|
+
return Boolean(overrides && Object.keys(overrides).length > 0);
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
// src/server/path-guards.ts
|
|
544
|
+
import path4 from "path";
|
|
545
|
+
function isWindowsAbsolutePath(file) {
|
|
546
|
+
return /^[a-zA-Z]:[\\/]/.test(file) || /^\\\\[^\\]+\\[^\\]+/.test(file);
|
|
547
|
+
}
|
|
548
|
+
function resolveWorkspacePath(file, cwd) {
|
|
549
|
+
if (isWindowsAbsolutePath(file)) {
|
|
550
|
+
return path4.win32.normalize(file);
|
|
551
|
+
}
|
|
552
|
+
return path4.isAbsolute(file) ? path4.resolve(file) : path4.resolve(cwd, file);
|
|
553
|
+
}
|
|
554
|
+
function assertPathWithinProject(file, projectRoot) {
|
|
555
|
+
const relativeToRoot = isWindowsAbsolutePath(file) || isWindowsAbsolutePath(projectRoot) ? path4.win32.relative(path4.win32.normalize(projectRoot), path4.win32.normalize(file)) : path4.relative(projectRoot, file);
|
|
556
|
+
if (relativeToRoot.startsWith("..") || path4.isAbsolute(relativeToRoot)) {
|
|
557
|
+
throw new Error("Access denied: File is outside of project workspace");
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
// src/server/annotation-dispatch.ts
|
|
562
|
+
var AnnotationDispatchError = class extends Error {
|
|
563
|
+
constructor(message, errorCode) {
|
|
564
|
+
super(message);
|
|
565
|
+
this.name = "AnnotationDispatchError";
|
|
566
|
+
this.errorCode = errorCode;
|
|
567
|
+
}
|
|
568
|
+
};
|
|
569
|
+
async function dispatchAnnotationsToAi(req, state) {
|
|
570
|
+
try {
|
|
571
|
+
validateAnnotationDispatchRequest(req, state);
|
|
572
|
+
const batch = normalizeAnnotationBatch(req);
|
|
573
|
+
const prompt = buildAnnotationBatchPrompt(batch);
|
|
574
|
+
const representativeTarget = batch.annotations[0]?.targets[0];
|
|
575
|
+
const runtime = resolvePromptDispatchRuntime(state);
|
|
576
|
+
return dispatchPromptThroughIde(runtime, {
|
|
577
|
+
prompt,
|
|
578
|
+
...representativeTarget?.file ? { filePath: representativeTarget.file } : {},
|
|
579
|
+
...representativeTarget?.line ? { line: representativeTarget.line } : {},
|
|
580
|
+
...representativeTarget?.column ? { column: representativeTarget.column } : {},
|
|
581
|
+
...batch.screenshotContext ? { screenshotContext: batch.screenshotContext } : {}
|
|
582
|
+
});
|
|
583
|
+
} catch (error) {
|
|
584
|
+
return {
|
|
585
|
+
success: false,
|
|
586
|
+
error: error instanceof Error ? error.message : String(error),
|
|
587
|
+
errorCode: getAnnotationDispatchErrorCode(error)
|
|
588
|
+
};
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
function validateAnnotationDispatchRequest(req, state) {
|
|
592
|
+
if (!req.annotations.length) {
|
|
593
|
+
throw new AnnotationDispatchError("At least one annotation is required.", "INVALID_REQUEST");
|
|
594
|
+
}
|
|
595
|
+
for (const annotation of req.annotations) {
|
|
596
|
+
if (!annotation.targets.length) {
|
|
597
|
+
throw new AnnotationDispatchError(
|
|
598
|
+
"Each annotation must include at least one target.",
|
|
599
|
+
"INVALID_REQUEST"
|
|
600
|
+
);
|
|
601
|
+
}
|
|
602
|
+
for (const target of annotation.targets) {
|
|
603
|
+
const absolutePath = resolveWorkspacePath(target.location.file, state.cwd);
|
|
604
|
+
assertPathWithinProject(absolutePath, state.projectRoot);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
function normalizeAnnotationBatch(req) {
|
|
609
|
+
return {
|
|
610
|
+
instruction: req.instruction?.trim() ?? "",
|
|
611
|
+
responseMode: req.responseMode ?? "unified",
|
|
612
|
+
...req.runtimeContext ? { runtimeContext: req.runtimeContext } : {},
|
|
613
|
+
...req.screenshotContext ? { screenshotContext: req.screenshotContext } : {},
|
|
614
|
+
...req.cssContextPrompt?.trim() ? { cssContextPrompt: req.cssContextPrompt.trim() } : {},
|
|
615
|
+
annotations: req.annotations.map((annotation, index) => ({
|
|
616
|
+
index: index + 1,
|
|
617
|
+
note: annotation.note.trim(),
|
|
618
|
+
intent: annotation.intent,
|
|
619
|
+
targets: annotation.targets.map((target) => ({
|
|
620
|
+
file: target.location.file,
|
|
621
|
+
line: target.location.line,
|
|
622
|
+
column: target.location.column,
|
|
623
|
+
...target.label ? { label: target.label } : {},
|
|
624
|
+
...target.selector ? { selector: target.selector } : {},
|
|
625
|
+
...target.snippet ? { snippet: target.snippet } : {}
|
|
626
|
+
}))
|
|
627
|
+
}))
|
|
628
|
+
};
|
|
629
|
+
}
|
|
630
|
+
function buildAnnotationBatchPrompt(batch) {
|
|
631
|
+
const body = buildSelectedElementsPrompt(batch.annotations);
|
|
632
|
+
const prompt = batch.instruction ? `${batch.instruction}
|
|
633
|
+
|
|
634
|
+
${body}` : body;
|
|
635
|
+
return appendScreenshotContextSection(
|
|
636
|
+
appendCssContextSection(
|
|
637
|
+
appendRuntimeContextSection(prompt, batch.runtimeContext),
|
|
638
|
+
batch.cssContextPrompt
|
|
639
|
+
),
|
|
640
|
+
batch.screenshotContext
|
|
641
|
+
);
|
|
642
|
+
}
|
|
643
|
+
function appendCssContextSection(prompt, cssContextPrompt) {
|
|
644
|
+
if (!cssContextPrompt) return prompt;
|
|
645
|
+
return `${prompt}
|
|
646
|
+
|
|
647
|
+
${cssContextPrompt}`;
|
|
648
|
+
}
|
|
649
|
+
function buildSelectedElementsPrompt(annotations) {
|
|
650
|
+
const lines = ["Selected elements:"];
|
|
651
|
+
for (const annotation of annotations) {
|
|
652
|
+
const trimmedNote = annotation.note.trim();
|
|
653
|
+
for (const target of annotation.targets) {
|
|
654
|
+
const targetLabel = (target.label || "Unknown target").trim() || "Unknown target";
|
|
655
|
+
lines.push(`- ${targetLabel}`);
|
|
656
|
+
lines.push(`file=${target.file}:${target.line}:${target.column}`);
|
|
657
|
+
if (trimmedNote) {
|
|
658
|
+
lines.push(`note=${trimmedNote}`);
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
if (lines.length === 1) {
|
|
663
|
+
lines.push("- None");
|
|
664
|
+
}
|
|
665
|
+
return lines.join("\n");
|
|
666
|
+
}
|
|
667
|
+
function appendScreenshotContextSection(prompt, screenshotContext) {
|
|
668
|
+
if (!screenshotContext || !screenshotContext.imageDataUrl && !screenshotContext.imageAssetId) {
|
|
669
|
+
return prompt;
|
|
670
|
+
}
|
|
671
|
+
const lines = [
|
|
672
|
+
"Visual screenshot context attached:",
|
|
673
|
+
`- capturedAt=${screenshotContext.capturedAt}`,
|
|
674
|
+
`- mimeType=${screenshotContext.mimeType}`,
|
|
675
|
+
...screenshotContext.imageAssetId ? [`- imageAssetId=${screenshotContext.imageAssetId}`] : []
|
|
676
|
+
];
|
|
677
|
+
return `${prompt}
|
|
678
|
+
|
|
679
|
+
${lines.join("\n")}`;
|
|
680
|
+
}
|
|
681
|
+
function appendRuntimeContextSection(prompt, runtimeContext) {
|
|
682
|
+
if (!runtimeContext?.records.length) {
|
|
683
|
+
return prompt;
|
|
684
|
+
}
|
|
685
|
+
return `${prompt}
|
|
686
|
+
|
|
687
|
+
${buildRuntimeContextSection(runtimeContext.records)}`;
|
|
688
|
+
}
|
|
689
|
+
function buildRuntimeContextSection(records) {
|
|
690
|
+
return ["Relevant runtime context:", ...records.map(formatRuntimeRecord)].join("\n");
|
|
691
|
+
}
|
|
692
|
+
function formatRuntimeRecord(record) {
|
|
693
|
+
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}`;
|
|
694
|
+
const reasonSummary = record.relevanceReasons.length ? record.relevanceReasons.join("; ") : "timing-based";
|
|
695
|
+
const stackSummary = record.stack ? `
|
|
696
|
+
stack=${record.stack.split("\n").slice(0, 5).join(" | ")}` : "";
|
|
697
|
+
return [
|
|
698
|
+
`- [${record.kind}] ${record.message}`,
|
|
699
|
+
` relevance=${record.relevanceLevel} (${reasonSummary})`,
|
|
700
|
+
` ${requestSummary}`,
|
|
701
|
+
stackSummary
|
|
702
|
+
].filter(Boolean).join("\n");
|
|
703
|
+
}
|
|
704
|
+
function getAnnotationDispatchErrorCode(error) {
|
|
705
|
+
if (error instanceof AnnotationDispatchError) return error.errorCode;
|
|
706
|
+
if (error instanceof Error && error.message.includes("outside of project workspace")) {
|
|
707
|
+
return "FORBIDDEN_PATH";
|
|
708
|
+
}
|
|
709
|
+
return "UNKNOWN";
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
// src/server/client-config.ts
|
|
713
|
+
async function buildClientConfig(serverState3) {
|
|
714
|
+
const userConfig = loadUserConfigSync(false, serverState3.cwd, serverState3.configRoot);
|
|
715
|
+
const promptsConfig = await loadPromptsConfig(false, serverState3.cwd, serverState3.configRoot);
|
|
716
|
+
const effectiveIde = userConfig.ide ?? "vscode";
|
|
717
|
+
let info;
|
|
718
|
+
if (!serverState3.ideInfo) {
|
|
719
|
+
info = { ide: effectiveIde };
|
|
720
|
+
} else {
|
|
721
|
+
const { scheme: _scheme, ...rest } = serverState3.ideInfo;
|
|
722
|
+
info = rest;
|
|
723
|
+
}
|
|
724
|
+
return {
|
|
725
|
+
...info,
|
|
726
|
+
prompts: resolveIntents(promptsConfig),
|
|
727
|
+
hotKeys: userConfig["inspector.hotKey"] ?? "alt",
|
|
728
|
+
theme: userConfig["inspector.theme"] ?? "auto",
|
|
729
|
+
includeSnippet: userConfig["prompt.includeSnippet"] ?? false,
|
|
730
|
+
runtimeContext: {
|
|
731
|
+
enabled: true,
|
|
732
|
+
preview: true,
|
|
733
|
+
maxRuntimeErrors: 3,
|
|
734
|
+
maxFailedRequests: 2
|
|
735
|
+
},
|
|
736
|
+
screenshotContext: {
|
|
737
|
+
enabled: false
|
|
738
|
+
},
|
|
739
|
+
annotationResponseMode: userConfig["prompt.annotationResponseMode"] ?? "unified",
|
|
740
|
+
autoSend: userConfig["prompt.autoSend"] ?? false
|
|
741
|
+
};
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
// src/server/open-file.ts
|
|
745
|
+
import { execFileSync as execFileSync2 } from "child_process";
|
|
746
|
+
import { launchIDE as launchIDE2 } from "launch-ide";
|
|
747
|
+
var serverLogger2 = createLogger("inspecto:server", { logLevel: getGlobalLogLevel() });
|
|
748
|
+
var VSCODE_FAMILY_SCHEMES = [
|
|
749
|
+
"vscode",
|
|
750
|
+
"vscode-insiders",
|
|
751
|
+
"cursor",
|
|
752
|
+
"windsurf",
|
|
753
|
+
"trae",
|
|
754
|
+
"trae-cn",
|
|
755
|
+
"vscodium",
|
|
756
|
+
"codebuddy",
|
|
757
|
+
"codebuddy-cn",
|
|
758
|
+
"antigravity"
|
|
759
|
+
];
|
|
760
|
+
function handleOpenFileRequest(body, serverState3) {
|
|
761
|
+
const absolutePath = resolveWorkspacePath(body.file, serverState3.cwd);
|
|
762
|
+
assertPathWithinProject(absolutePath, serverState3.projectRoot);
|
|
763
|
+
const userConfig = loadUserConfigSync(false, serverState3.cwd, serverState3.configRoot);
|
|
764
|
+
const configuredIde = userConfig.ide;
|
|
765
|
+
const activeIde = serverState3.ideInfo?.ide;
|
|
766
|
+
const activeIdeScheme = serverState3.ideInfo?.scheme;
|
|
767
|
+
const rawEditorHint = configuredIde || activeIde || activeIdeScheme || "code";
|
|
768
|
+
if (configuredIde && activeIdeScheme && !activeIdeScheme.includes(configuredIde)) {
|
|
769
|
+
serverLogger2.warn(
|
|
770
|
+
`Active IDE is ${activeIdeScheme}, but config forces ${configuredIde}. Using configured IDE.`
|
|
771
|
+
);
|
|
772
|
+
}
|
|
773
|
+
let editorHint = rawEditorHint;
|
|
774
|
+
if (rawEditorHint === "vscode") editorHint = "code";
|
|
775
|
+
else if (rawEditorHint === "vscode-insiders") editorHint = "code-insiders";
|
|
776
|
+
else if (rawEditorHint === "vscodium") editorHint = "codium";
|
|
777
|
+
else if (rawEditorHint === "trae-cn" || rawEditorHint === "trae") editorHint = "trae";
|
|
778
|
+
serverLogger2.debug(
|
|
779
|
+
`IDE_OPEN: activeIde=${activeIde}, activeIdeScheme=${activeIdeScheme}, configuredIde=${configuredIde} -> rawEditorHint=${rawEditorHint}, finalEditorHint=${editorHint}`
|
|
780
|
+
);
|
|
781
|
+
if (VSCODE_FAMILY_SCHEMES.includes(rawEditorHint)) {
|
|
782
|
+
let normalizedPath = absolutePath.replace(/\\/g, "/");
|
|
783
|
+
if (!normalizedPath.startsWith("/")) {
|
|
784
|
+
normalizedPath = "/" + normalizedPath;
|
|
785
|
+
}
|
|
786
|
+
const encodedPath = encodeURI(normalizedPath);
|
|
787
|
+
const uri = `${rawEditorHint}://file${encodedPath}:${body.line}:${body.column}`;
|
|
788
|
+
serverLogger2.debug(`IDE_OPEN: Bypassing launchIDE, using URI scheme directly: ${uri}`);
|
|
789
|
+
try {
|
|
790
|
+
if (process.platform === "darwin") {
|
|
791
|
+
execFileSync2("open", [uri]);
|
|
792
|
+
} else if (process.platform === "win32") {
|
|
793
|
+
execFileSync2("cmd", ["/c", "start", '""', uri]);
|
|
794
|
+
} else {
|
|
795
|
+
execFileSync2("xdg-open", [uri]);
|
|
796
|
+
}
|
|
797
|
+
} catch (e) {
|
|
798
|
+
serverLogger2.error(`Failed to launch URI for IDE_OPEN (${uri}):`, e);
|
|
799
|
+
launchIDE2({
|
|
800
|
+
file: absolutePath,
|
|
801
|
+
line: body.line,
|
|
802
|
+
column: body.column,
|
|
803
|
+
editor: editorHint,
|
|
804
|
+
type: process.platform === "darwin" ? "open" : "exec"
|
|
805
|
+
});
|
|
806
|
+
}
|
|
807
|
+
} else {
|
|
808
|
+
launchIDE2({
|
|
809
|
+
file: absolutePath,
|
|
810
|
+
line: body.line,
|
|
811
|
+
column: body.column,
|
|
812
|
+
editor: editorHint,
|
|
813
|
+
type: process.platform === "darwin" ? "open" : "exec"
|
|
814
|
+
});
|
|
815
|
+
}
|
|
816
|
+
return { success: true };
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
// src/server/project-root.ts
|
|
820
|
+
import fs3 from "fs";
|
|
821
|
+
import path5 from "path";
|
|
822
|
+
import { execSync } from "child_process";
|
|
823
|
+
var serverLogger3 = createLogger("inspecto:server", { logLevel: getGlobalLogLevel() });
|
|
824
|
+
function resolveProjectRoot() {
|
|
825
|
+
const cwd = process.cwd();
|
|
826
|
+
let gitRoot;
|
|
827
|
+
try {
|
|
828
|
+
gitRoot = execSync("git rev-parse --show-toplevel", { encoding: "utf-8" }).trim();
|
|
829
|
+
} catch (e) {
|
|
830
|
+
serverLogger3.warn("Failed to resolve git root via git rev-parse:", e);
|
|
831
|
+
gitRoot = cwd;
|
|
832
|
+
}
|
|
833
|
+
const visited = /* @__PURE__ */ new Set();
|
|
834
|
+
const search = (start, stop) => {
|
|
835
|
+
let current = start;
|
|
836
|
+
while (!visited.has(current)) {
|
|
837
|
+
visited.add(current);
|
|
838
|
+
if (fs3.existsSync(path5.join(current, ".inspecto"))) return current;
|
|
839
|
+
if (current === stop) break;
|
|
840
|
+
const parent = path5.dirname(current);
|
|
841
|
+
if (parent === current) break;
|
|
842
|
+
current = parent;
|
|
843
|
+
}
|
|
844
|
+
return null;
|
|
845
|
+
};
|
|
846
|
+
const cwdMatch = search(cwd, path5.parse(cwd).root);
|
|
847
|
+
if (cwdMatch) return cwdMatch;
|
|
848
|
+
const repoMatch = search(gitRoot, path5.parse(gitRoot).root);
|
|
849
|
+
if (repoMatch) return repoMatch;
|
|
850
|
+
return gitRoot;
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
// src/server/index.ts
|
|
854
|
+
var serverLogger4 = createLogger("inspecto:server", { logLevel: getGlobalLogLevel() });
|
|
855
|
+
var serverState = {
|
|
856
|
+
port: null,
|
|
857
|
+
running: false,
|
|
858
|
+
projectRoot: "",
|
|
859
|
+
configRoot: "",
|
|
860
|
+
cwd: process.cwd()
|
|
861
|
+
};
|
|
862
|
+
var serverInstance = null;
|
|
520
863
|
async function startServer() {
|
|
521
864
|
if (serverState.running && serverState.port !== null) {
|
|
522
865
|
return serverState.port;
|
|
@@ -528,7 +871,7 @@ async function startServer() {
|
|
|
528
871
|
const port = await portfinder.getPortPromise();
|
|
529
872
|
watchConfig(
|
|
530
873
|
() => {
|
|
531
|
-
|
|
874
|
+
serverLogger4.info("user config reloaded.");
|
|
532
875
|
},
|
|
533
876
|
serverState.cwd,
|
|
534
877
|
serverState.configRoot
|
|
@@ -544,7 +887,7 @@ async function startServer() {
|
|
|
544
887
|
}
|
|
545
888
|
const url = new URL(req.url ?? "/", `http://localhost:${port}`);
|
|
546
889
|
handleRequest(url, req, res).catch((err) => {
|
|
547
|
-
|
|
890
|
+
serverLogger4.error("server error:", err);
|
|
548
891
|
res.writeHead(500, { "Content-Type": "application/json" });
|
|
549
892
|
res.end(JSON.stringify({ success: false, error: String(err) }));
|
|
550
893
|
});
|
|
@@ -557,41 +900,41 @@ async function startServer() {
|
|
|
557
900
|
serverInstance.once("error", reject);
|
|
558
901
|
});
|
|
559
902
|
serverInstance.on("error", (err) => {
|
|
560
|
-
|
|
903
|
+
serverLogger4.error("persistent server error:", err);
|
|
561
904
|
});
|
|
562
905
|
serverState.port = port;
|
|
563
906
|
serverState.running = true;
|
|
564
|
-
const portFile =
|
|
907
|
+
const portFile = path6.join(os2.tmpdir(), "inspecto.port.json");
|
|
565
908
|
try {
|
|
566
909
|
let portData = {};
|
|
567
|
-
if (
|
|
910
|
+
if (fs4.existsSync(portFile)) {
|
|
568
911
|
try {
|
|
569
|
-
portData = JSON.parse(
|
|
912
|
+
portData = JSON.parse(fs4.readFileSync(portFile, "utf-8"));
|
|
570
913
|
} catch (e) {
|
|
571
914
|
}
|
|
572
915
|
}
|
|
573
|
-
const rootHash =
|
|
916
|
+
const rootHash = crypto2.createHash("md5").update(serverState.projectRoot).digest("hex");
|
|
574
917
|
portData[rootHash] = port;
|
|
575
|
-
|
|
918
|
+
fs4.writeFileSync(portFile, JSON.stringify(portData, null, 2), "utf-8");
|
|
576
919
|
} catch (e) {
|
|
577
|
-
|
|
920
|
+
serverLogger4.warn("Failed to write port file:", e);
|
|
578
921
|
}
|
|
579
922
|
process.once("exit", () => {
|
|
580
923
|
try {
|
|
581
|
-
if (
|
|
582
|
-
const portData = JSON.parse(
|
|
583
|
-
const rootHash =
|
|
924
|
+
if (fs4.existsSync(portFile)) {
|
|
925
|
+
const portData = JSON.parse(fs4.readFileSync(portFile, "utf-8"));
|
|
926
|
+
const rootHash = crypto2.createHash("md5").update(serverState.projectRoot).digest("hex");
|
|
584
927
|
delete portData[rootHash];
|
|
585
928
|
if (Object.keys(portData).length === 0) {
|
|
586
|
-
|
|
929
|
+
fs4.unlinkSync(portFile);
|
|
587
930
|
} else {
|
|
588
|
-
|
|
931
|
+
fs4.writeFileSync(portFile, JSON.stringify(portData, null, 2), "utf-8");
|
|
589
932
|
}
|
|
590
933
|
}
|
|
591
934
|
} catch {
|
|
592
935
|
}
|
|
593
936
|
});
|
|
594
|
-
|
|
937
|
+
serverLogger4.info(`server running at http://127.0.0.1:${port}`);
|
|
595
938
|
return port;
|
|
596
939
|
}
|
|
597
940
|
async function readBody(req) {
|
|
@@ -610,26 +953,7 @@ async function handleRequest(url, req, res) {
|
|
|
610
953
|
return;
|
|
611
954
|
}
|
|
612
955
|
if (pathname === INSPECTO_API_PATHS.CLIENT_CONFIG && req.method === "GET") {
|
|
613
|
-
const
|
|
614
|
-
const promptsConfig = await loadPromptsConfig(false, serverState.cwd, serverState.configRoot);
|
|
615
|
-
const effectiveIde = userConfig.ide ?? "vscode";
|
|
616
|
-
let info;
|
|
617
|
-
if (!serverState.ideInfo) {
|
|
618
|
-
info = {
|
|
619
|
-
ide: effectiveIde
|
|
620
|
-
};
|
|
621
|
-
} else {
|
|
622
|
-
const { scheme: _scheme, ...rest } = serverState.ideInfo;
|
|
623
|
-
info = rest;
|
|
624
|
-
}
|
|
625
|
-
const config = {
|
|
626
|
-
...info,
|
|
627
|
-
prompts: resolveIntents(promptsConfig),
|
|
628
|
-
hotKeys: userConfig["inspector.hotKey"] ?? "alt",
|
|
629
|
-
theme: userConfig["inspector.theme"] ?? "auto",
|
|
630
|
-
includeSnippet: userConfig["prompt.includeSnippet"] ?? false,
|
|
631
|
-
autoSend: userConfig["prompt.autoSend"] ?? false
|
|
632
|
-
};
|
|
956
|
+
const config = await buildClientConfig(serverState);
|
|
633
957
|
delete config.providers;
|
|
634
958
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
635
959
|
res.end(JSON.stringify(config));
|
|
@@ -640,21 +964,23 @@ async function handleRequest(url, req, res) {
|
|
|
640
964
|
const body = JSON.parse(await readBody(req));
|
|
641
965
|
const ideWorkspace = body.workspaceRoot || "";
|
|
642
966
|
const serverProjectRoot = serverState.projectRoot || "";
|
|
643
|
-
const
|
|
967
|
+
const normalizedIdeRoot = ideWorkspace ? path6.resolve(ideWorkspace) : "";
|
|
968
|
+
const normalizedServerRoot = serverProjectRoot ? path6.resolve(serverProjectRoot) : "";
|
|
969
|
+
const isSameProject = !normalizedIdeRoot || !normalizedServerRoot || normalizedIdeRoot === normalizedServerRoot || normalizedServerRoot.startsWith(normalizedIdeRoot + path6.sep) || normalizedIdeRoot.startsWith(normalizedServerRoot + path6.sep);
|
|
644
970
|
if (isSameProject) {
|
|
645
971
|
serverState.ideInfo = body;
|
|
646
|
-
|
|
972
|
+
serverLogger4.debug(
|
|
647
973
|
`Accepted IDE info from matched workspace (ide-${body.ide} / schema-${body.scheme})`
|
|
648
974
|
);
|
|
649
975
|
} else {
|
|
650
|
-
|
|
976
|
+
serverLogger4.debug(
|
|
651
977
|
`Ignored IDE info from unrelated workspace (IDE Workspace: ${ideWorkspace}, Server: ${serverProjectRoot}, Scheme: ${body.scheme}, IDE: ${body.ide})`
|
|
652
978
|
);
|
|
653
979
|
}
|
|
654
980
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
655
981
|
res.end(JSON.stringify({ success: true }));
|
|
656
982
|
} catch (e) {
|
|
657
|
-
|
|
983
|
+
serverLogger4.error(`Error parsing ${INSPECTO_API_PATHS.IDE_INFO} POST request:`, e);
|
|
658
984
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
659
985
|
res.end(JSON.stringify({ error: "Invalid JSON body" }));
|
|
660
986
|
}
|
|
@@ -669,74 +995,14 @@ async function handleRequest(url, req, res) {
|
|
|
669
995
|
res.end(JSON.stringify({ error: "Invalid JSON body" }));
|
|
670
996
|
return;
|
|
671
997
|
}
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
998
|
+
try {
|
|
999
|
+
handleOpenFileRequest(body, serverState);
|
|
1000
|
+
} catch {
|
|
1001
|
+
serverLogger4.warn(`Security: Blocked path traversal attempt in IDE_OPEN: ${body.file}`);
|
|
676
1002
|
res.writeHead(403, { "Content-Type": "application/json" });
|
|
677
1003
|
res.end(JSON.stringify({ error: "Access denied: File is outside of project workspace" }));
|
|
678
1004
|
return;
|
|
679
1005
|
}
|
|
680
|
-
const userConfig = loadUserConfigSync(false, serverState.cwd, serverState.configRoot);
|
|
681
|
-
const configuredIde = userConfig.ide;
|
|
682
|
-
const activeIde = serverState.ideInfo?.ide;
|
|
683
|
-
const activeIdeScheme = serverState.ideInfo?.scheme;
|
|
684
|
-
const rawEditorHint = configuredIde || activeIde || activeIdeScheme || "code";
|
|
685
|
-
if (configuredIde && activeIdeScheme && !activeIdeScheme.includes(configuredIde)) {
|
|
686
|
-
serverLogger.warn(
|
|
687
|
-
`Active IDE is ${activeIdeScheme}, but config forces ${configuredIde}. Using configured IDE.`
|
|
688
|
-
);
|
|
689
|
-
}
|
|
690
|
-
let editorHint = rawEditorHint;
|
|
691
|
-
if (rawEditorHint === "vscode") editorHint = "code";
|
|
692
|
-
else if (rawEditorHint === "vscode-insiders") editorHint = "code-insiders";
|
|
693
|
-
else if (rawEditorHint === "vscodium") editorHint = "codium";
|
|
694
|
-
else if (rawEditorHint === "trae-cn" || rawEditorHint === "trae") editorHint = "trae";
|
|
695
|
-
serverLogger.debug(
|
|
696
|
-
`IDE_OPEN: activeIde=${activeIde}, activeIdeScheme=${activeIdeScheme}, configuredIde=${configuredIde} -> rawEditorHint=${rawEditorHint}, finalEditorHint=${editorHint}`
|
|
697
|
-
);
|
|
698
|
-
const VSCODE_FAMILY_SCHEMES = [
|
|
699
|
-
"vscode",
|
|
700
|
-
"vscode-insiders",
|
|
701
|
-
"cursor",
|
|
702
|
-
"windsurf",
|
|
703
|
-
"trae",
|
|
704
|
-
"trae-cn",
|
|
705
|
-
"vscodium",
|
|
706
|
-
"codebuddy",
|
|
707
|
-
"codebuddy-cn",
|
|
708
|
-
"antigravity"
|
|
709
|
-
];
|
|
710
|
-
if (VSCODE_FAMILY_SCHEMES.includes(rawEditorHint)) {
|
|
711
|
-
const uri = `${rawEditorHint}://file${absolutePath}:${body.line}:${body.column}`;
|
|
712
|
-
serverLogger.debug(`IDE_OPEN: Bypassing launchIDE, using URI scheme directly: ${uri}`);
|
|
713
|
-
try {
|
|
714
|
-
if (process.platform === "darwin") {
|
|
715
|
-
execFileSync("open", [uri]);
|
|
716
|
-
} else if (process.platform === "win32") {
|
|
717
|
-
execFileSync("cmd", ["/c", "start", '""', uri]);
|
|
718
|
-
} else {
|
|
719
|
-
execFileSync("xdg-open", [uri]);
|
|
720
|
-
}
|
|
721
|
-
} catch (e) {
|
|
722
|
-
serverLogger.error(`Failed to launch URI for IDE_OPEN (${uri}):`, e);
|
|
723
|
-
launchIDE({
|
|
724
|
-
file: absolutePath,
|
|
725
|
-
line: body.line,
|
|
726
|
-
column: body.column,
|
|
727
|
-
editor: editorHint,
|
|
728
|
-
type: process.platform === "darwin" ? "open" : "exec"
|
|
729
|
-
});
|
|
730
|
-
}
|
|
731
|
-
} else {
|
|
732
|
-
launchIDE({
|
|
733
|
-
file: absolutePath,
|
|
734
|
-
line: body.line,
|
|
735
|
-
column: body.column,
|
|
736
|
-
editor: editorHint,
|
|
737
|
-
type: process.platform === "darwin" ? "open" : "exec"
|
|
738
|
-
});
|
|
739
|
-
}
|
|
740
1006
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
741
1007
|
res.end(JSON.stringify({ success: true }));
|
|
742
1008
|
return;
|
|
@@ -747,10 +1013,11 @@ async function handleRequest(url, req, res) {
|
|
|
747
1013
|
const column = parseInt(url.searchParams.get("column") ?? "1", 10);
|
|
748
1014
|
const maxLines = parseInt(url.searchParams.get("maxLines") ?? "100", 10);
|
|
749
1015
|
try {
|
|
750
|
-
const absolutePath =
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
1016
|
+
const absolutePath = resolveWorkspacePath(file, serverState.cwd);
|
|
1017
|
+
try {
|
|
1018
|
+
assertPathWithinProject(absolutePath, serverState.projectRoot);
|
|
1019
|
+
} catch {
|
|
1020
|
+
serverLogger4.warn(`Security: Blocked path traversal attempt in PROJECT_SNIPPET: ${file}`);
|
|
754
1021
|
res.writeHead(403, { "Content-Type": "application/json" });
|
|
755
1022
|
res.end(
|
|
756
1023
|
JSON.stringify({
|
|
@@ -780,7 +1047,23 @@ async function handleRequest(url, req, res) {
|
|
|
780
1047
|
res.writeHead(result.success ? 200 : 500, { "Content-Type": "application/json" });
|
|
781
1048
|
res.end(JSON.stringify(result));
|
|
782
1049
|
} catch (e) {
|
|
783
|
-
|
|
1050
|
+
serverLogger4.error(`Error parsing ${INSPECTO_API_PATHS.AI_DISPATCH} request:`, e);
|
|
1051
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
1052
|
+
res.end(JSON.stringify({ success: false, error: String(e), errorCode: "INTERNAL_ERROR" }));
|
|
1053
|
+
}
|
|
1054
|
+
return;
|
|
1055
|
+
}
|
|
1056
|
+
if (pathname === INSPECTO_API_PATHS.AI_BATCH_DISPATCH && req.method === "POST") {
|
|
1057
|
+
try {
|
|
1058
|
+
const rawBody = await readBody(req);
|
|
1059
|
+
const body = JSON.parse(rawBody);
|
|
1060
|
+
const result = await dispatchAnnotationsToAi(body, serverState);
|
|
1061
|
+
res.writeHead(getBatchDispatchStatusCode(result.errorCode, result.success), {
|
|
1062
|
+
"Content-Type": "application/json"
|
|
1063
|
+
});
|
|
1064
|
+
res.end(JSON.stringify(result));
|
|
1065
|
+
} catch (e) {
|
|
1066
|
+
serverLogger4.error(`Error parsing ${INSPECTO_API_PATHS.AI_BATCH_DISPATCH} request:`, e);
|
|
784
1067
|
res.writeHead(500, { "Content-Type": "application/json" });
|
|
785
1068
|
res.end(JSON.stringify({ success: false, error: String(e), errorCode: "INTERNAL_ERROR" }));
|
|
786
1069
|
}
|
|
@@ -788,7 +1071,7 @@ async function handleRequest(url, req, res) {
|
|
|
788
1071
|
}
|
|
789
1072
|
if (pathname.startsWith(`${INSPECTO_API_PATHS.AI_TICKET}/`) && req.method === "GET") {
|
|
790
1073
|
const ticketId = pathname.substring(INSPECTO_API_PATHS.AI_TICKET.length + 1);
|
|
791
|
-
const payloadStr =
|
|
1074
|
+
const payloadStr = readTicket(ticketId);
|
|
792
1075
|
if (!payloadStr) {
|
|
793
1076
|
res.writeHead(404, { "Content-Type": "application/json" });
|
|
794
1077
|
res.end(JSON.stringify({ success: false, error: "Ticket not found or expired" }));
|
|
@@ -802,54 +1085,28 @@ async function handleRequest(url, req, res) {
|
|
|
802
1085
|
res.end(JSON.stringify({ error: "not found" }));
|
|
803
1086
|
}
|
|
804
1087
|
async function dispatchToAi(req) {
|
|
805
|
-
const { location, snippet, prompt } = req;
|
|
806
|
-
const userConfig = loadUserConfigSync(false, serverState.cwd, serverState.configRoot);
|
|
807
|
-
const resolvedTarget = resolveTargetTool(userConfig);
|
|
1088
|
+
const { location, snippet, prompt, screenshotContext } = req;
|
|
808
1089
|
const formattedPrompt = prompt ?? `Please help me with this code from \`${location.file}\` (line ${location.line}):
|
|
809
1090
|
|
|
810
1091
|
\`\`\`
|
|
811
1092
|
${snippet}
|
|
812
1093
|
\`\`\`
|
|
813
1094
|
`;
|
|
814
|
-
const
|
|
815
|
-
|
|
816
|
-
const activeIde = serverState.ideInfo?.ide;
|
|
817
|
-
const activeIdeScheme = serverState.ideInfo?.scheme;
|
|
818
|
-
const finalIde = configuredIde || activeIdeScheme || activeIde || "vscode";
|
|
819
|
-
if (configuredIde && activeIdeScheme && !activeIdeScheme.includes(configuredIde)) {
|
|
820
|
-
serverLogger.warn(
|
|
821
|
-
`dispatchToAi: Active IDE is ${activeIdeScheme}, but config forces ${configuredIde}. Using configured IDE.`
|
|
822
|
-
);
|
|
823
|
-
}
|
|
824
|
-
const mode = resolveProviderMode(resolvedTarget, finalIde, userConfig);
|
|
825
|
-
const overrides = extractToolOverrides(finalIde, userConfig)[resolvedTarget] || {};
|
|
826
|
-
overrides.type = mode;
|
|
827
|
-
const fullPayload = {
|
|
828
|
-
ide: finalIde,
|
|
829
|
-
target: resolvedTarget,
|
|
830
|
-
targetType: mode,
|
|
1095
|
+
const runtime = resolvePromptDispatchRuntime(serverState);
|
|
1096
|
+
return dispatchPromptThroughIde(runtime, {
|
|
831
1097
|
prompt: formattedPrompt,
|
|
832
1098
|
filePath: location.file,
|
|
833
1099
|
line: location.line,
|
|
834
1100
|
column: location.column,
|
|
835
1101
|
snippet,
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
serverLogger.debug(`dispatchToAi: Generated URI: ${uri}`);
|
|
845
|
-
launchURI(uri);
|
|
846
|
-
return {
|
|
847
|
-
success: true,
|
|
848
|
-
fallbackPayload: {
|
|
849
|
-
prompt: formattedPrompt,
|
|
850
|
-
file: location.file
|
|
851
|
-
}
|
|
852
|
-
};
|
|
1102
|
+
...screenshotContext ? { screenshotContext } : {}
|
|
1103
|
+
});
|
|
1104
|
+
}
|
|
1105
|
+
function getBatchDispatchStatusCode(errorCode, success) {
|
|
1106
|
+
if (success) return 200;
|
|
1107
|
+
if (errorCode === "INVALID_REQUEST") return 400;
|
|
1108
|
+
if (errorCode === "FORBIDDEN_PATH") return 403;
|
|
1109
|
+
return 500;
|
|
853
1110
|
}
|
|
854
1111
|
|
|
855
1112
|
// src/injectors/utils.ts
|
|
@@ -884,7 +1141,7 @@ window.addEventListener('load', () => {
|
|
|
884
1141
|
}
|
|
885
1142
|
|
|
886
1143
|
// src/legacy/rspack/index.ts
|
|
887
|
-
import
|
|
1144
|
+
import path7 from "path";
|
|
888
1145
|
var _dirname = typeof __dirname !== "undefined" ? __dirname : __dirname;
|
|
889
1146
|
var DEFAULT_OPTIONS = {
|
|
890
1147
|
include: [],
|
|
@@ -954,7 +1211,7 @@ var InspectoRspackLegacyPlugin = class {
|
|
|
954
1211
|
);
|
|
955
1212
|
}
|
|
956
1213
|
});
|
|
957
|
-
const loaderPath =
|
|
1214
|
+
const loaderPath = path7.resolve(_dirname, "./loader.cjs");
|
|
958
1215
|
compiler.options.module.rules.push({
|
|
959
1216
|
test: /\.[jt]sx?$/,
|
|
960
1217
|
use: [
|