@inspecto-dev/core 0.2.0-alpha.1 → 0.2.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-C4KO2HLL.js +25 -0
- package/dist/chunk-C4KO2HLL.js.map +1 -0
- package/dist/component-4WPU23TV.js +1097 -0
- package/dist/component-4WPU23TV.js.map +1 -0
- package/dist/index.cjs +486 -574
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +19 -1261
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -3,6 +3,9 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __esm = (fn, res) => function __init() {
|
|
7
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
8
|
+
};
|
|
6
9
|
var __export = (target, all) => {
|
|
7
10
|
for (var name in all)
|
|
8
11
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -16,37 +19,52 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
16
19
|
return to;
|
|
17
20
|
};
|
|
18
21
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
var
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
|
|
22
|
+
var __async = (__this, __arguments, generator) => {
|
|
23
|
+
return new Promise((resolve, reject) => {
|
|
24
|
+
var fulfilled = (value) => {
|
|
25
|
+
try {
|
|
26
|
+
step(generator.next(value));
|
|
27
|
+
} catch (e) {
|
|
28
|
+
reject(e);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
var rejected = (value) => {
|
|
32
|
+
try {
|
|
33
|
+
step(generator.throw(value));
|
|
34
|
+
} catch (e) {
|
|
35
|
+
reject(e);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
39
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
40
|
+
});
|
|
41
|
+
};
|
|
28
42
|
|
|
29
43
|
// src/styles.ts
|
|
30
|
-
var overlayClass
|
|
31
|
-
var
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
44
|
+
var overlayClass, menuClass, menuItemClass, loadingSpinnerClass, errorMsgClass, badgeClass, menuInputClass, menuInputWrapperClass, menuInputIconClass, tooltipClass, tooltipTopClass, tooltipBottomClass, tagClass, idClass, classClass, dimClass, separatorClass, sourceClass, shortcutIconClass, darkVars, inspectorStyles;
|
|
45
|
+
var init_styles = __esm({
|
|
46
|
+
"src/styles.ts"() {
|
|
47
|
+
"use strict";
|
|
48
|
+
overlayClass = "inspecto-overlay";
|
|
49
|
+
menuClass = "inspecto-menu";
|
|
50
|
+
menuItemClass = "inspecto-menu-item";
|
|
51
|
+
loadingSpinnerClass = "inspecto-spinner";
|
|
52
|
+
errorMsgClass = "inspecto-error";
|
|
53
|
+
badgeClass = "inspecto-badge";
|
|
54
|
+
menuInputClass = "inspecto-menu-input";
|
|
55
|
+
menuInputWrapperClass = "inspecto-menu-input-wrapper";
|
|
56
|
+
menuInputIconClass = "inspecto-menu-input-icon";
|
|
57
|
+
tooltipClass = "inspecto-tooltip";
|
|
58
|
+
tooltipTopClass = "inspecto-tooltip-top";
|
|
59
|
+
tooltipBottomClass = "inspecto-tooltip-bottom";
|
|
60
|
+
tagClass = "inspecto-tag";
|
|
61
|
+
idClass = "inspecto-id";
|
|
62
|
+
classClass = "inspecto-class";
|
|
63
|
+
dimClass = "inspecto-dim";
|
|
64
|
+
separatorClass = "inspecto-separator";
|
|
65
|
+
sourceClass = "inspecto-source";
|
|
66
|
+
shortcutIconClass = "ai-shortcut-icon";
|
|
67
|
+
darkVars = `
|
|
50
68
|
--inspecto-menu-bg: #252526;
|
|
51
69
|
--inspecto-menu-border: #454545;
|
|
52
70
|
--inspecto-menu-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
|
|
@@ -74,7 +92,7 @@ var darkVars = `
|
|
|
74
92
|
--inspecto-dim-color: #858585;
|
|
75
93
|
--inspecto-error-color: #ef4444;
|
|
76
94
|
`;
|
|
77
|
-
|
|
95
|
+
inspectorStyles = `
|
|
78
96
|
:host {
|
|
79
97
|
/* Light theme (default) */
|
|
80
98
|
--inspecto-menu-bg: #ffffff;
|
|
@@ -413,10 +431,10 @@ var inspectorStyles = `
|
|
|
413
431
|
opacity: 1;
|
|
414
432
|
}
|
|
415
433
|
`;
|
|
434
|
+
}
|
|
435
|
+
});
|
|
416
436
|
|
|
417
437
|
// src/overlay.ts
|
|
418
|
-
var GAP = 8;
|
|
419
|
-
var EDGE_MARGIN = 4;
|
|
420
438
|
function createOverlay(shadowRoot) {
|
|
421
439
|
const overlay = document.createElement("div");
|
|
422
440
|
overlay.className = overlayClass;
|
|
@@ -495,138 +513,23 @@ function createOverlay(shadowRoot) {
|
|
|
495
513
|
}
|
|
496
514
|
return { show, hide };
|
|
497
515
|
}
|
|
516
|
+
var GAP, EDGE_MARGIN;
|
|
517
|
+
var init_overlay = __esm({
|
|
518
|
+
"src/overlay.ts"() {
|
|
519
|
+
"use strict";
|
|
520
|
+
init_styles();
|
|
521
|
+
GAP = 8;
|
|
522
|
+
EDGE_MARGIN = 4;
|
|
523
|
+
}
|
|
524
|
+
});
|
|
498
525
|
|
|
499
526
|
// src/intents.ts
|
|
500
527
|
function CUSTOM_PROMPT_TEMPLATE(userPrompt) {
|
|
501
528
|
return userPrompt;
|
|
502
529
|
}
|
|
503
|
-
var DEFAULT_INTENTS = [
|
|
504
|
-
// ── 1. Explain Component ─────────────────────────────────────────────────
|
|
505
|
-
// Frequency: ★★★★★ — Most common action when navigating unfamiliar codebases
|
|
506
|
-
{
|
|
507
|
-
id: "explain",
|
|
508
|
-
label: "Explain Component",
|
|
509
|
-
prompt: `The following is a {{framework}} component from \`{{file}}\` (line {{line}}).
|
|
510
|
-
|
|
511
|
-
Please explain:
|
|
512
|
-
|
|
513
|
-
1. What this component does and its responsibility in the UI
|
|
514
|
-
2. Key props and their purpose
|
|
515
|
-
3. Important state or side effects (if applicable)
|
|
516
|
-
4. Any non-obvious logic or edge cases worth noting`
|
|
517
|
-
},
|
|
518
|
-
// ── 2. Fix Bug ───────────────────────────────────────────────────────────
|
|
519
|
-
// Frequency: ★★★★★ — Debugging is the highest time-cost activity in frontend dev
|
|
520
|
-
{
|
|
521
|
-
id: "fix-bug",
|
|
522
|
-
label: "Fix Bug",
|
|
523
|
-
prompt: `I found a bug in the following {{framework}} component from \`{{file}}\` (line {{line}}).
|
|
524
|
-
|
|
525
|
-
Please:
|
|
526
|
-
|
|
527
|
-
1. Identify potential bugs or issues in this code
|
|
528
|
-
2. Explain the root cause of each issue
|
|
529
|
-
3. Provide a fixed version with minimal changes
|
|
530
|
-
|
|
531
|
-
If you need more context (e.g. parent component, API response shape),
|
|
532
|
-
please ask before suggesting a fix.`
|
|
533
|
-
},
|
|
534
|
-
// ── 3. Fix Styles ────────────────────────────────────────────────────────
|
|
535
|
-
// Frequency: ★★★★ — Styling issues are top-3 daily pain points for frontend devs
|
|
536
|
-
{
|
|
537
|
-
id: "fix-styles",
|
|
538
|
-
label: "Fix Styles",
|
|
539
|
-
prompt: `The following component from \`{{file}}\` (line {{line}}) has a styling issue.
|
|
540
|
-
|
|
541
|
-
Please:
|
|
542
|
-
|
|
543
|
-
1. Review the current styles (className / inline styles / CSS-in-JS / Style blocks)
|
|
544
|
-
2. Identify common issues: layout shifts, overflow, z-index conflicts,
|
|
545
|
-
responsive breakpoints, or visual inconsistencies
|
|
546
|
-
3. Suggest fixes using the same styling approach already in use
|
|
547
|
-
|
|
548
|
-
Note: Maintain the existing styling conventions (e.g. Tailwind, CSS Modules, scoped styles).`
|
|
549
|
-
},
|
|
550
|
-
// ── 4. Refactor Component ────────────────────────────────────────────────
|
|
551
|
-
// Frequency: ★★★★ — Sustained demand after features stabilize; large component splits
|
|
552
|
-
{
|
|
553
|
-
id: "refactor",
|
|
554
|
-
label: "Refactor Component",
|
|
555
|
-
prompt: `Please refactor the following {{framework}} component from \`{{file}}\` (line {{line}}).
|
|
556
|
-
|
|
557
|
-
Refactoring goals (apply as relevant):
|
|
558
|
-
|
|
559
|
-
- Extract reusable sub-components or composables/hooks
|
|
560
|
-
- Improve readability and reduce complexity
|
|
561
|
-
- Remove redundant state or unnecessary re-renders
|
|
562
|
-
- Apply {{framework}} best practices
|
|
563
|
-
- Maintain existing behavior \u2014 no functional changes
|
|
564
|
-
|
|
565
|
-
Please show the refactored version with a brief explanation of each change.`
|
|
566
|
-
},
|
|
567
|
-
// ── 5. Code Review ───────────────────────────────────────────────────────
|
|
568
|
-
// Frequency: ★★★ — Concentrated at PR stage; slightly less frequent than daily fixes
|
|
569
|
-
{
|
|
570
|
-
id: "code-review",
|
|
571
|
-
label: "Code Review",
|
|
572
|
-
prompt: `Please do a code review for the following {{framework}} component from \`{{file}}\` (line {{line}}).
|
|
573
|
-
|
|
574
|
-
Review dimensions:
|
|
575
|
-
|
|
576
|
-
- Correctness: logic errors, edge cases, race conditions
|
|
577
|
-
- {{framework}} best practices: lifecycle usage, key props, reactivity rules
|
|
578
|
-
- Performance: unnecessary renders, missing memoization
|
|
579
|
-
- Accessibility: ARIA attributes, keyboard navigation, semantic HTML
|
|
580
|
-
- Security: XSS risks, unsafe HTML injection, user input handling
|
|
581
|
-
- Maintainability: naming clarity, code duplication, complexity
|
|
582
|
-
|
|
583
|
-
Format your response as a prioritized list: \u{1F534} Critical / \u{1F7E1} Warning / \u{1F7E2} Suggestion.`
|
|
584
|
-
},
|
|
585
|
-
// ── 6. Generate Test ─────────────────────────────────────────────────────
|
|
586
|
-
// Frequency: ★★★ — Common but often deferred; great AI use case
|
|
587
|
-
{
|
|
588
|
-
id: "generate-test",
|
|
589
|
-
label: "Generate Test",
|
|
590
|
-
prompt: `Please generate unit tests for the following {{framework}} component from \`{{file}}\` (line {{line}}).
|
|
591
|
-
|
|
592
|
-
Requirements:
|
|
593
|
-
|
|
594
|
-
- Use Vitest + Testing Library (or Jest if the codebase implies it)
|
|
595
|
-
- Cover: render correctness, user interactions, edge cases, error states
|
|
596
|
-
- Mock external dependencies (API calls, context/providers, router)
|
|
597
|
-
- Use accessible queries (getByRole, getByLabelText) over getByTestId
|
|
598
|
-
|
|
599
|
-
Generate a complete, runnable test file. Include all import statements.`
|
|
600
|
-
},
|
|
601
|
-
// ── 7. Performance Analysis ──────────────────────────────────────────────
|
|
602
|
-
// Frequency: ★★ — Targeted use during perf sprints; not a daily operation
|
|
603
|
-
{
|
|
604
|
-
id: "performance",
|
|
605
|
-
label: "Performance Analysis",
|
|
606
|
-
prompt: `Please analyze the performance of the following {{framework}} component from \`{{file}}\` (line {{line}}).
|
|
607
|
-
|
|
608
|
-
Focus on:
|
|
609
|
-
|
|
610
|
-
1. Unnecessary re-renders or reactive updates
|
|
611
|
-
2. Expensive computations that should be memoized/computed
|
|
612
|
-
3. Heavy operations in the render path
|
|
613
|
-
4. Dependency arrays or watchers \u2014 missing or over-specified
|
|
614
|
-
5. Large bundle impact (heavy imports that could be lazy-loaded)
|
|
615
|
-
|
|
616
|
-
For each issue found, provide: problem description \u2192 recommended fix \u2192 expected impact.`
|
|
617
|
-
},
|
|
618
|
-
// ── 8. Open in Editor ────────────────────────────────────────────────────
|
|
619
|
-
// Type: local action (no AI prompt) — jumps directly to source in IDE
|
|
620
|
-
{
|
|
621
|
-
id: "open-in-editor",
|
|
622
|
-
label: "Open in Editor",
|
|
623
|
-
prompt: "",
|
|
624
|
-
// unused — isAction handles this
|
|
625
|
-
isAction: true
|
|
626
|
-
}
|
|
627
|
-
];
|
|
628
530
|
function detectFramework(fileName) {
|
|
629
|
-
|
|
531
|
+
var _a;
|
|
532
|
+
const ext = ((_a = fileName.split(".").pop()) == null ? void 0 : _a.toLowerCase()) || "";
|
|
630
533
|
switch (ext) {
|
|
631
534
|
case "vue":
|
|
632
535
|
return "Vue";
|
|
@@ -645,12 +548,13 @@ function detectFramework(fileName) {
|
|
|
645
548
|
}
|
|
646
549
|
}
|
|
647
550
|
function buildPrompt(template, location, snippetResult) {
|
|
648
|
-
|
|
649
|
-
const
|
|
551
|
+
var _a, _b, _c;
|
|
552
|
+
const shortFile = (_a = location.file.split("/").pop()) != null ? _a : location.file;
|
|
553
|
+
const ext = ((_b = shortFile.split(".").pop()) == null ? void 0 : _b.toLowerCase()) || "tsx";
|
|
650
554
|
const framework = detectFramework(shortFile);
|
|
651
555
|
let finalPrompt = template.replace(/\{\{file\}\}/g, location.file).replace(/\{\{line\}\}/g, String(location.line)).replace(/\{\{column\}\}/g, String(location.column)).replace(/\{\{ext\}\}/g, ext).replace(/\{\{framework\}\}/g, framework).replace(/\{\{name\}\}/g, shortFile);
|
|
652
556
|
if (snippetResult && snippetResult.snippet) {
|
|
653
|
-
const name = snippetResult.name
|
|
557
|
+
const name = (_c = snippetResult.name) != null ? _c : shortFile;
|
|
654
558
|
finalPrompt = finalPrompt.replace(/\{\{name\}\}/g, name);
|
|
655
559
|
finalPrompt += `
|
|
656
560
|
|
|
@@ -661,72 +565,93 @@ ${snippetResult.snippet}
|
|
|
661
565
|
}
|
|
662
566
|
return finalPrompt;
|
|
663
567
|
}
|
|
568
|
+
var init_intents = __esm({
|
|
569
|
+
"src/intents.ts"() {
|
|
570
|
+
"use strict";
|
|
571
|
+
}
|
|
572
|
+
});
|
|
664
573
|
|
|
665
574
|
// src/http.ts
|
|
666
|
-
var BASE_URL = globalThis.__AI_INSPECTOR_SERVER_URL__ || "http://127.0.0.1:5678";
|
|
667
575
|
function setBaseUrl(url) {
|
|
668
576
|
BASE_URL = url.replace(/\/$/, "");
|
|
669
577
|
}
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
578
|
+
function fetchIdeInfo(force = false) {
|
|
579
|
+
return __async(this, null, function* () {
|
|
580
|
+
if (cachedConfig && !force) return cachedConfig;
|
|
581
|
+
try {
|
|
582
|
+
const res = yield fetch(`${BASE_URL}${import_types.INSPECTO_API_PATHS.CLIENT_CONFIG}`);
|
|
583
|
+
if (!res.ok) return null;
|
|
584
|
+
cachedConfig = yield res.json();
|
|
585
|
+
return cachedConfig;
|
|
586
|
+
} catch (e) {
|
|
587
|
+
return null;
|
|
588
|
+
}
|
|
589
|
+
});
|
|
681
590
|
}
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
591
|
+
function openFile(req) {
|
|
592
|
+
return __async(this, null, function* () {
|
|
593
|
+
try {
|
|
594
|
+
const res = yield fetch(`${BASE_URL}${import_types.INSPECTO_API_PATHS.IDE_OPEN}`, {
|
|
595
|
+
method: "POST",
|
|
596
|
+
headers: { "Content-Type": "application/json" },
|
|
597
|
+
body: JSON.stringify(req)
|
|
598
|
+
});
|
|
599
|
+
return res.ok;
|
|
600
|
+
} catch (e) {
|
|
601
|
+
return false;
|
|
602
|
+
}
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
function fetchSnippet(file, line, column, maxLines = 100) {
|
|
606
|
+
return __async(this, null, function* () {
|
|
607
|
+
const params = new URLSearchParams({
|
|
608
|
+
file,
|
|
609
|
+
line: String(line),
|
|
610
|
+
column: String(column),
|
|
611
|
+
maxLines: String(maxLines)
|
|
612
|
+
});
|
|
613
|
+
const res = yield fetch(`${BASE_URL}${import_types.INSPECTO_API_PATHS.PROJECT_SNIPPET}?${params}`);
|
|
614
|
+
if (!res.ok) {
|
|
615
|
+
const err = yield res.json().catch(() => ({}));
|
|
616
|
+
throw Object.assign(new Error("snippet fetch failed"), { errorCode: err.errorCode });
|
|
617
|
+
}
|
|
618
|
+
return res.json();
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
function sendToAi(req) {
|
|
622
|
+
return __async(this, null, function* () {
|
|
623
|
+
var _a;
|
|
624
|
+
const res = yield fetch(`${BASE_URL}${import_types.INSPECTO_API_PATHS.AI_DISPATCH}`, {
|
|
685
625
|
method: "POST",
|
|
686
626
|
headers: { "Content-Type": "application/json" },
|
|
687
627
|
body: JSON.stringify(req)
|
|
688
628
|
});
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
column: String(column),
|
|
699
|
-
maxLines: String(maxLines)
|
|
629
|
+
if (!res.ok) {
|
|
630
|
+
const err = yield res.json().catch(() => ({}));
|
|
631
|
+
return {
|
|
632
|
+
success: false,
|
|
633
|
+
error: (_a = err.error) != null ? _a : "Request failed",
|
|
634
|
+
errorCode: err.errorCode
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
return res.json();
|
|
700
638
|
});
|
|
701
|
-
const res = await fetch(`${BASE_URL}/snippet?${params}`);
|
|
702
|
-
if (!res.ok) {
|
|
703
|
-
const err = await res.json().catch(() => ({}));
|
|
704
|
-
throw Object.assign(new Error("snippet fetch failed"), { errorCode: err.errorCode });
|
|
705
|
-
}
|
|
706
|
-
return res.json();
|
|
707
639
|
}
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
const err = await res.json().catch(() => ({}));
|
|
716
|
-
return {
|
|
717
|
-
success: false,
|
|
718
|
-
error: err.error ?? "Request failed",
|
|
719
|
-
errorCode: err.errorCode
|
|
720
|
-
};
|
|
640
|
+
var import_types, BASE_URL, cachedConfig;
|
|
641
|
+
var init_http = __esm({
|
|
642
|
+
"src/http.ts"() {
|
|
643
|
+
"use strict";
|
|
644
|
+
import_types = require("@inspecto-dev/types");
|
|
645
|
+
BASE_URL = globalThis.__AI_INSPECTOR_SERVER_URL__ || "http://127.0.0.1:5678";
|
|
646
|
+
cachedConfig = null;
|
|
721
647
|
}
|
|
722
|
-
|
|
723
|
-
}
|
|
648
|
+
});
|
|
724
649
|
|
|
725
650
|
// src/menu.ts
|
|
726
|
-
var MENU_WIDTH = 280;
|
|
727
651
|
function showIntentMenu(shadowRoot, location, clickX, clickY, options, onClose) {
|
|
728
|
-
|
|
729
|
-
const
|
|
652
|
+
var _a, _b;
|
|
653
|
+
const maxSnippetLines = (_a = options.maxSnippetLines) != null ? _a : 100;
|
|
654
|
+
const includeSnippet = (_b = options.includeSnippet) != null ? _b : false;
|
|
730
655
|
const menu = document.createElement("div");
|
|
731
656
|
menu.className = menuClass;
|
|
732
657
|
const { input, inputWrapper, sendIcon } = createAskInput(options.askPlaceholder);
|
|
@@ -761,26 +686,33 @@ function showIntentMenu(shadowRoot, location, clickX, clickY, options, onClose)
|
|
|
761
686
|
menu.remove();
|
|
762
687
|
onClose();
|
|
763
688
|
}
|
|
764
|
-
const handleSend =
|
|
689
|
+
const handleSend = (promptText, snippetText, disable, restore) => __async(null, null, function* () {
|
|
690
|
+
var _a2, _b2;
|
|
765
691
|
disable();
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
const result =
|
|
692
|
+
yield openFile(location);
|
|
693
|
+
yield new Promise((r) => setTimeout(r, 100));
|
|
694
|
+
const result = yield sendToAi({ location, snippet: snippetText, prompt: promptText });
|
|
769
695
|
if (result.success) {
|
|
696
|
+
if ((_a2 = result.fallbackPayload) == null ? void 0 : _a2.prompt) {
|
|
697
|
+
try {
|
|
698
|
+
yield navigator.clipboard.writeText(result.fallbackPayload.prompt);
|
|
699
|
+
} catch (e) {
|
|
700
|
+
}
|
|
701
|
+
}
|
|
770
702
|
cleanup();
|
|
771
703
|
} else {
|
|
772
704
|
restore();
|
|
773
|
-
showError(menu, result.error
|
|
705
|
+
showError(menu, (_b2 = result.error) != null ? _b2 : "Unknown error", result.errorCode);
|
|
774
706
|
}
|
|
775
|
-
};
|
|
776
|
-
const submitAsk =
|
|
707
|
+
});
|
|
708
|
+
const submitAsk = () => __async(null, null, function* () {
|
|
777
709
|
if (!input.value.trim()) return;
|
|
778
710
|
input.disabled = true;
|
|
779
711
|
sendIcon.style.pointerEvents = "none";
|
|
780
712
|
try {
|
|
781
713
|
let snippetResult = null;
|
|
782
714
|
if (includeSnippet) {
|
|
783
|
-
snippetResult =
|
|
715
|
+
snippetResult = yield fetchSnippet(
|
|
784
716
|
location.file,
|
|
785
717
|
location.line,
|
|
786
718
|
location.column,
|
|
@@ -792,9 +724,9 @@ function showIntentMenu(shadowRoot, location, clickX, clickY, options, onClose)
|
|
|
792
724
|
location,
|
|
793
725
|
snippetResult
|
|
794
726
|
);
|
|
795
|
-
|
|
727
|
+
yield handleSend(
|
|
796
728
|
prompt,
|
|
797
|
-
snippetResult
|
|
729
|
+
(snippetResult == null ? void 0 : snippetResult.snippet) || "",
|
|
798
730
|
() => {
|
|
799
731
|
},
|
|
800
732
|
// already disabled
|
|
@@ -808,20 +740,21 @@ function showIntentMenu(shadowRoot, location, clickX, clickY, options, onClose)
|
|
|
808
740
|
sendIcon.style.pointerEvents = "auto";
|
|
809
741
|
showError(menu, err.message, err.errorCode);
|
|
810
742
|
}
|
|
811
|
-
};
|
|
743
|
+
});
|
|
812
744
|
input.addEventListener("keydown", (e) => {
|
|
813
745
|
if (e.key === "Enter") submitAsk();
|
|
814
746
|
});
|
|
815
747
|
sendIcon.addEventListener("click", submitAsk);
|
|
816
748
|
fetchIdeInfo().then((ideInfo) => {
|
|
749
|
+
var _a2, _b2, _c, _d;
|
|
817
750
|
loadingEl.remove();
|
|
818
|
-
const intents =
|
|
751
|
+
const intents = (ideInfo == null ? void 0 : ideInfo.prompts) || [];
|
|
819
752
|
for (const intent of intents) {
|
|
820
753
|
if (intent.isAction && intent.id === "open-in-editor") {
|
|
821
754
|
const btn2 = document.createElement("button");
|
|
822
755
|
btn2.className = menuItemClass;
|
|
823
756
|
const span = document.createElement("span");
|
|
824
|
-
span.textContent = intent.label
|
|
757
|
+
span.textContent = (_a2 = intent.label) != null ? _a2 : "Unknown";
|
|
825
758
|
btn2.appendChild(span);
|
|
826
759
|
const shortcutDiv = document.createElement("div");
|
|
827
760
|
shortcutDiv.className = shortcutIconClass;
|
|
@@ -835,23 +768,23 @@ function showIntentMenu(shadowRoot, location, clickX, clickY, options, onClose)
|
|
|
835
768
|
menu.appendChild(btn2);
|
|
836
769
|
continue;
|
|
837
770
|
}
|
|
838
|
-
let fullPromptTemplate = intent.prompt
|
|
771
|
+
let fullPromptTemplate = (_b2 = intent.prompt) != null ? _b2 : "";
|
|
839
772
|
if (intent.prependPrompt)
|
|
840
773
|
fullPromptTemplate = intent.prependPrompt + "\n\n" + fullPromptTemplate;
|
|
841
774
|
if (intent.appendPrompt)
|
|
842
775
|
fullPromptTemplate = fullPromptTemplate + "\n\n" + intent.appendPrompt;
|
|
843
|
-
const label = intent.label
|
|
776
|
+
const label = (_d = (_c = intent.label) != null ? _c : intent.id) != null ? _d : "Unknown";
|
|
844
777
|
const btn = document.createElement("button");
|
|
845
778
|
btn.className = menuItemClass;
|
|
846
779
|
btn.textContent = label;
|
|
847
|
-
btn.addEventListener("click",
|
|
780
|
+
btn.addEventListener("click", (e) => __async(null, null, function* () {
|
|
848
781
|
e.stopPropagation();
|
|
849
782
|
btn.disabled = true;
|
|
850
783
|
btn.textContent = "Sending...";
|
|
851
784
|
try {
|
|
852
785
|
let snippetResult = null;
|
|
853
786
|
if (includeSnippet) {
|
|
854
|
-
snippetResult =
|
|
787
|
+
snippetResult = yield fetchSnippet(
|
|
855
788
|
location.file,
|
|
856
789
|
location.line,
|
|
857
790
|
location.column,
|
|
@@ -859,9 +792,9 @@ function showIntentMenu(shadowRoot, location, clickX, clickY, options, onClose)
|
|
|
859
792
|
);
|
|
860
793
|
}
|
|
861
794
|
const prompt = buildPrompt(fullPromptTemplate, location, snippetResult);
|
|
862
|
-
|
|
795
|
+
yield handleSend(
|
|
863
796
|
prompt,
|
|
864
|
-
snippetResult
|
|
797
|
+
(snippetResult == null ? void 0 : snippetResult.snippet) || "",
|
|
865
798
|
() => {
|
|
866
799
|
},
|
|
867
800
|
// already disabled
|
|
@@ -875,117 +808,30 @@ function showIntentMenu(shadowRoot, location, clickX, clickY, options, onClose)
|
|
|
875
808
|
btn.textContent = label;
|
|
876
809
|
showError(menu, err.message, err.errorCode);
|
|
877
810
|
}
|
|
878
|
-
});
|
|
811
|
+
}));
|
|
879
812
|
menu.appendChild(btn);
|
|
880
813
|
}
|
|
881
814
|
updatePosition();
|
|
882
815
|
}).catch((err) => {
|
|
816
|
+
var _a2;
|
|
883
817
|
loadingEl.remove();
|
|
884
818
|
const isServerDown = err instanceof TypeError;
|
|
885
819
|
showError(
|
|
886
820
|
menu,
|
|
887
821
|
isServerDown ? "Cannot connect to inspector server. Is the dev server running?" : err.message,
|
|
888
|
-
err.errorCode
|
|
822
|
+
(_a2 = err.errorCode) != null ? _a2 : "UNKNOWN"
|
|
889
823
|
);
|
|
890
824
|
updatePosition();
|
|
891
825
|
});
|
|
892
826
|
return cleanup;
|
|
893
827
|
}
|
|
894
|
-
function resolveIntents(serverPrompts) {
|
|
895
|
-
const baseMap = /* @__PURE__ */ new Map();
|
|
896
|
-
for (const intent of DEFAULT_INTENTS) {
|
|
897
|
-
if (intent.id) baseMap.set(intent.id, { ...intent });
|
|
898
|
-
}
|
|
899
|
-
const defaults = () => ensureOpenInEditorLast(Array.from(baseMap.values()));
|
|
900
|
-
if (!serverPrompts) return defaults();
|
|
901
|
-
const isReplace = !Array.isArray(serverPrompts) && typeof serverPrompts === "object" && serverPrompts.$replace === true;
|
|
902
|
-
const promptsArray = Array.isArray(serverPrompts) ? serverPrompts : isReplace ? serverPrompts.items : [];
|
|
903
|
-
if (!promptsArray || promptsArray.length === 0) return defaults();
|
|
904
|
-
if (isReplace) {
|
|
905
|
-
const result = [];
|
|
906
|
-
for (const item of promptsArray) {
|
|
907
|
-
if (typeof item === "string") {
|
|
908
|
-
if (baseMap.has(item)) {
|
|
909
|
-
result.push(baseMap.get(item));
|
|
910
|
-
} else {
|
|
911
|
-
console.warn(
|
|
912
|
-
`[inspecto] Unknown built-in intent id: "${item}". Available: ${[...baseMap.keys()].join(", ")}`
|
|
913
|
-
);
|
|
914
|
-
}
|
|
915
|
-
} else if (typeof item === "object") {
|
|
916
|
-
if (!item.id) {
|
|
917
|
-
console.warn('[inspecto] Intent object missing required "id" field, skipping.');
|
|
918
|
-
continue;
|
|
919
|
-
}
|
|
920
|
-
if (item.enabled === false) {
|
|
921
|
-
console.warn(
|
|
922
|
-
`[inspecto] Intent "${item.id}" is listed in $replace but has enabled:false \u2014 it will be excluded.`
|
|
923
|
-
);
|
|
924
|
-
continue;
|
|
925
|
-
}
|
|
926
|
-
if (item.isAction && item.id !== "open-in-editor") {
|
|
927
|
-
console.warn(
|
|
928
|
-
`[inspecto] isAction is reserved for built-in actions. Ignoring intent "${item.id}".`
|
|
929
|
-
);
|
|
930
|
-
continue;
|
|
931
|
-
}
|
|
932
|
-
result.push(baseMap.has(item.id) ? { ...baseMap.get(item.id), ...item } : item);
|
|
933
|
-
}
|
|
934
|
-
}
|
|
935
|
-
return ensureOpenInEditorLast(result);
|
|
936
|
-
}
|
|
937
|
-
const merged = Array.from(baseMap.values());
|
|
938
|
-
for (const item of promptsArray) {
|
|
939
|
-
if (typeof item === "string") {
|
|
940
|
-
if (!baseMap.has(item)) {
|
|
941
|
-
console.warn(
|
|
942
|
-
`[inspecto] Unknown built-in intent id: "${item}". In append mode, strings have no effect on ordering \u2014 use $replace to control order.`
|
|
943
|
-
);
|
|
944
|
-
}
|
|
945
|
-
continue;
|
|
946
|
-
}
|
|
947
|
-
if (typeof item === "object") {
|
|
948
|
-
if (!item.id) {
|
|
949
|
-
console.warn('[inspecto] Intent object missing required "id" field, skipping.');
|
|
950
|
-
continue;
|
|
951
|
-
}
|
|
952
|
-
if (item.isAction && item.id !== "open-in-editor") {
|
|
953
|
-
console.warn(
|
|
954
|
-
`[inspecto] isAction is reserved for built-in actions. Ignoring intent "${item.id}".`
|
|
955
|
-
);
|
|
956
|
-
continue;
|
|
957
|
-
}
|
|
958
|
-
const existingIdx = merged.findIndex((i) => i.id === item.id);
|
|
959
|
-
if (existingIdx !== -1) {
|
|
960
|
-
if (item.enabled === false) {
|
|
961
|
-
merged.splice(existingIdx, 1);
|
|
962
|
-
} else {
|
|
963
|
-
merged[existingIdx] = { ...merged[existingIdx], ...item };
|
|
964
|
-
}
|
|
965
|
-
} else {
|
|
966
|
-
if (item.enabled !== false) {
|
|
967
|
-
merged.push(item);
|
|
968
|
-
}
|
|
969
|
-
}
|
|
970
|
-
}
|
|
971
|
-
}
|
|
972
|
-
return ensureOpenInEditorLast(merged);
|
|
973
|
-
}
|
|
974
|
-
function ensureOpenInEditorLast(intents) {
|
|
975
|
-
const idx = intents.findIndex((i) => i.id === "open-in-editor");
|
|
976
|
-
if (idx === -1 || idx === intents.length - 1) return intents;
|
|
977
|
-
const result = [...intents];
|
|
978
|
-
const item = result.splice(idx, 1)[0];
|
|
979
|
-
result.push(item);
|
|
980
|
-
return result;
|
|
981
|
-
}
|
|
982
828
|
function createAskInput(placeholder) {
|
|
983
829
|
const inputWrapper = document.createElement("div");
|
|
984
830
|
inputWrapper.className = menuInputWrapperClass;
|
|
985
831
|
const input = document.createElement("input");
|
|
986
832
|
input.className = menuInputClass;
|
|
987
833
|
input.type = "text";
|
|
988
|
-
input.placeholder = placeholder
|
|
834
|
+
input.placeholder = placeholder != null ? placeholder : "Describe how to change this component...";
|
|
989
835
|
const sendIcon = document.createElement("div");
|
|
990
836
|
sendIcon.className = menuInputIconClass;
|
|
991
837
|
sendIcon.innerHTML = `<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="22" y1="2" x2="11" y2="13"></line><polygon points="22 2 15 22 11 13 2 9 22 2"></polygon></svg>`;
|
|
@@ -995,15 +841,29 @@ function createAskInput(placeholder) {
|
|
|
995
841
|
return { input, inputWrapper, sendIcon };
|
|
996
842
|
}
|
|
997
843
|
function showError(menu, message, errorCode) {
|
|
998
|
-
|
|
844
|
+
var _a;
|
|
845
|
+
(_a = menu.querySelector(`.${errorMsgClass}`)) == null ? void 0 : _a.remove();
|
|
999
846
|
const errEl = document.createElement("div");
|
|
1000
847
|
errEl.className = errorMsgClass;
|
|
1001
848
|
errEl.textContent = errorCode === "FILE_NOT_FOUND" ? "Source file not found. Is the server running?" : `Error: ${message}`;
|
|
1002
849
|
menu.appendChild(errEl);
|
|
1003
850
|
}
|
|
851
|
+
var MENU_WIDTH;
|
|
852
|
+
var init_menu = __esm({
|
|
853
|
+
"src/menu.ts"() {
|
|
854
|
+
"use strict";
|
|
855
|
+
init_intents();
|
|
856
|
+
init_http();
|
|
857
|
+
init_styles();
|
|
858
|
+
MENU_WIDTH = 280;
|
|
859
|
+
}
|
|
860
|
+
});
|
|
1004
861
|
|
|
1005
862
|
// src/component.ts
|
|
1006
|
-
var
|
|
863
|
+
var component_exports = {};
|
|
864
|
+
__export(component_exports, {
|
|
865
|
+
InspectoElement: () => InspectoElement
|
|
866
|
+
});
|
|
1007
867
|
function parseAttrValue(value) {
|
|
1008
868
|
const parts = value.split(":");
|
|
1009
869
|
if (parts.length < 3) return null;
|
|
@@ -1020,277 +880,329 @@ function findInspectable(el) {
|
|
|
1020
880
|
}
|
|
1021
881
|
return null;
|
|
1022
882
|
}
|
|
883
|
+
function parseHotKeyString(hotKey) {
|
|
884
|
+
const keys = hotKey.split("+").map((k) => k.trim().toLowerCase());
|
|
885
|
+
const result = [];
|
|
886
|
+
if (keys.includes("alt") || keys.includes("option")) result.push("altKey");
|
|
887
|
+
if (keys.includes("ctrl") || keys.includes("control")) result.push("ctrlKey");
|
|
888
|
+
if (keys.includes("meta") || keys.includes("cmd") || keys.includes("command") || keys.includes("win"))
|
|
889
|
+
result.push("metaKey");
|
|
890
|
+
if (keys.includes("shift")) result.push("shiftKey");
|
|
891
|
+
return result;
|
|
892
|
+
}
|
|
1023
893
|
function hotKeysHeld(event, hotKeys) {
|
|
1024
|
-
|
|
894
|
+
if (!hotKeys) return false;
|
|
895
|
+
const mappedKeys = parseHotKeyString(hotKeys);
|
|
896
|
+
if (mappedKeys.length === 0) return false;
|
|
897
|
+
return mappedKeys.every((key) => event[key]);
|
|
1025
898
|
}
|
|
1026
|
-
var BaseElement
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
this.hasMoved = false;
|
|
1037
|
-
this.dragStartX = 0;
|
|
1038
|
-
this.dragStartY = 0;
|
|
1039
|
-
this.badgeInitialRight = 16;
|
|
1040
|
-
this.badgeInitialBottom = 16;
|
|
1041
|
-
this.cleanupMenu = null;
|
|
1042
|
-
this.onDragStart = (e) => {
|
|
1043
|
-
if (e.button !== 0) return;
|
|
1044
|
-
if (e.target.classList?.contains(`${badgeClass}-close`)) return;
|
|
1045
|
-
e.preventDefault();
|
|
1046
|
-
this.isDragging = true;
|
|
1047
|
-
this.hasMoved = false;
|
|
1048
|
-
const rect = this.badge.getBoundingClientRect();
|
|
1049
|
-
this.dragStartX = e.clientX - rect.left;
|
|
1050
|
-
this.dragStartY = e.clientY - rect.top;
|
|
1051
|
-
document.addEventListener("mousemove", this.onDragMove);
|
|
1052
|
-
document.addEventListener("mouseup", this.onDragEnd);
|
|
899
|
+
var ATTR_NAME, BaseElement, InspectoElement;
|
|
900
|
+
var init_component = __esm({
|
|
901
|
+
"src/component.ts"() {
|
|
902
|
+
"use strict";
|
|
903
|
+
init_overlay();
|
|
904
|
+
init_menu();
|
|
905
|
+
init_http();
|
|
906
|
+
init_styles();
|
|
907
|
+
ATTR_NAME = "data-inspecto";
|
|
908
|
+
BaseElement = typeof HTMLElement !== "undefined" ? HTMLElement : class {
|
|
1053
909
|
};
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
newLeft = Math.max(0, Math.min(newLeft, window.innerWidth - badgeWidth));
|
|
1062
|
-
newTop = Math.max(0, Math.min(newTop, window.innerHeight - badgeHeight));
|
|
1063
|
-
this.badge.style.transition = "none";
|
|
1064
|
-
this.badge.style.right = "auto";
|
|
1065
|
-
this.badge.style.bottom = "auto";
|
|
1066
|
-
this.badge.style.left = `${newLeft}px`;
|
|
1067
|
-
this.badge.style.top = `${newTop}px`;
|
|
1068
|
-
};
|
|
1069
|
-
this.onDragEnd = () => {
|
|
1070
|
-
document.removeEventListener("mousemove", this.onDragMove);
|
|
1071
|
-
document.removeEventListener("mouseup", this.onDragEnd);
|
|
1072
|
-
this.badge.style.transition = "";
|
|
1073
|
-
setTimeout(() => {
|
|
910
|
+
InspectoElement = class extends BaseElement {
|
|
911
|
+
constructor() {
|
|
912
|
+
super(...arguments);
|
|
913
|
+
this.options = {};
|
|
914
|
+
this.serverHotKeys = null;
|
|
915
|
+
this.active = false;
|
|
916
|
+
this.disabled = false;
|
|
1074
917
|
this.isDragging = false;
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
this.
|
|
1081
|
-
|
|
918
|
+
this.hasMoved = false;
|
|
919
|
+
this.dragStartX = 0;
|
|
920
|
+
this.dragStartY = 0;
|
|
921
|
+
this.badgeInitialRight = 16;
|
|
922
|
+
this.badgeInitialBottom = 16;
|
|
923
|
+
this.cleanupMenu = null;
|
|
924
|
+
this.onDragStart = (e) => {
|
|
925
|
+
var _a;
|
|
926
|
+
if (e.button !== 0) return;
|
|
927
|
+
if ((_a = e.target.classList) == null ? void 0 : _a.contains(`${badgeClass}-close`)) return;
|
|
928
|
+
e.preventDefault();
|
|
929
|
+
this.isDragging = true;
|
|
930
|
+
this.hasMoved = false;
|
|
931
|
+
const rect = this.badge.getBoundingClientRect();
|
|
932
|
+
this.dragStartX = e.clientX - rect.left;
|
|
933
|
+
this.dragStartY = e.clientY - rect.top;
|
|
934
|
+
document.addEventListener("mousemove", this.onDragMove);
|
|
935
|
+
document.addEventListener("mouseup", this.onDragEnd);
|
|
936
|
+
};
|
|
937
|
+
this.onDragMove = (e) => {
|
|
938
|
+
if (!this.isDragging) return;
|
|
939
|
+
this.hasMoved = true;
|
|
940
|
+
let newLeft = e.clientX - this.dragStartX;
|
|
941
|
+
let newTop = e.clientY - this.dragStartY;
|
|
942
|
+
const badgeWidth = this.badge.offsetWidth;
|
|
943
|
+
const badgeHeight = this.badge.offsetHeight;
|
|
944
|
+
newLeft = Math.max(0, Math.min(newLeft, window.innerWidth - badgeWidth));
|
|
945
|
+
newTop = Math.max(0, Math.min(newTop, window.innerHeight - badgeHeight));
|
|
946
|
+
this.badge.style.transition = "none";
|
|
947
|
+
this.badge.style.right = "auto";
|
|
948
|
+
this.badge.style.bottom = "auto";
|
|
949
|
+
this.badge.style.left = `${newLeft}px`;
|
|
950
|
+
this.badge.style.top = `${newTop}px`;
|
|
951
|
+
};
|
|
952
|
+
this.onDragEnd = () => {
|
|
953
|
+
document.removeEventListener("mousemove", this.onDragMove);
|
|
954
|
+
document.removeEventListener("mouseup", this.onDragEnd);
|
|
955
|
+
this.badge.style.transition = "";
|
|
956
|
+
setTimeout(() => {
|
|
957
|
+
this.isDragging = false;
|
|
958
|
+
}, 0);
|
|
959
|
+
};
|
|
960
|
+
this.onMouseMove = (e) => {
|
|
961
|
+
var _a;
|
|
962
|
+
const isActive = this.isInspectorActive(e);
|
|
963
|
+
if (!isActive) {
|
|
964
|
+
this.overlay.hide();
|
|
965
|
+
return;
|
|
966
|
+
}
|
|
967
|
+
const target = findInspectable(e.target);
|
|
968
|
+
if (!target) {
|
|
969
|
+
this.overlay.hide();
|
|
970
|
+
return;
|
|
971
|
+
}
|
|
972
|
+
const attrValue = target.getAttribute(ATTR_NAME);
|
|
973
|
+
const loc = parseAttrValue(attrValue);
|
|
974
|
+
const label = loc ? `${(_a = loc.file.split("/").pop()) != null ? _a : ""}:${loc.line}` : attrValue;
|
|
975
|
+
this.overlay.show(target, label);
|
|
976
|
+
e.stopPropagation();
|
|
977
|
+
};
|
|
978
|
+
this.onClick = (e) => {
|
|
979
|
+
this.handleTrigger(e);
|
|
980
|
+
};
|
|
981
|
+
this.onContextMenu = (e) => {
|
|
982
|
+
if (this.isInspectorActive(e)) {
|
|
983
|
+
this.handleTrigger(e);
|
|
984
|
+
}
|
|
985
|
+
};
|
|
986
|
+
this.onKeyDown = (e) => {
|
|
987
|
+
var _a;
|
|
988
|
+
if (e.key === "Escape") {
|
|
989
|
+
(_a = this.cleanupMenu) == null ? void 0 : _a.call(this);
|
|
990
|
+
this.overlay.hide();
|
|
991
|
+
}
|
|
992
|
+
};
|
|
1082
993
|
}
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
994
|
+
connectedCallback() {
|
|
995
|
+
this.shadowRootEl = this.attachShadow({ mode: "open" });
|
|
996
|
+
const style = document.createElement("style");
|
|
997
|
+
style.textContent = inspectorStyles;
|
|
998
|
+
this.shadowRootEl.appendChild(style);
|
|
999
|
+
this.overlay = createOverlay(this.shadowRootEl);
|
|
1000
|
+
this.badge = this.createBadge();
|
|
1001
|
+
this.setupListeners();
|
|
1002
|
+
if (this.options.defaultActive) {
|
|
1003
|
+
this.setActive(true);
|
|
1004
|
+
}
|
|
1087
1005
|
}
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
const label = loc ? `${loc.file.split("/").pop() ?? ""}:${loc.line}` : attrValue;
|
|
1091
|
-
this.overlay.show(target, label);
|
|
1092
|
-
e.stopPropagation();
|
|
1093
|
-
};
|
|
1094
|
-
this.onClick = (e) => {
|
|
1095
|
-
this.handleTrigger(e);
|
|
1096
|
-
};
|
|
1097
|
-
this.onContextMenu = (e) => {
|
|
1098
|
-
if (this.isInspectorActive(e)) {
|
|
1099
|
-
this.handleTrigger(e);
|
|
1006
|
+
disconnectedCallback() {
|
|
1007
|
+
this.teardownListeners();
|
|
1100
1008
|
}
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1009
|
+
configure(options) {
|
|
1010
|
+
this.options = options;
|
|
1011
|
+
if (options.serverUrl) {
|
|
1012
|
+
setBaseUrl(options.serverUrl);
|
|
1013
|
+
}
|
|
1014
|
+
if (options.theme === "dark") {
|
|
1015
|
+
this.setAttribute("data-theme", "dark");
|
|
1016
|
+
} else if (options.theme === "light") {
|
|
1017
|
+
this.setAttribute("data-theme", "light");
|
|
1018
|
+
} else {
|
|
1019
|
+
this.removeAttribute("data-theme");
|
|
1020
|
+
}
|
|
1021
|
+
fetchIdeInfo(true).then((info) => {
|
|
1022
|
+
if ((info == null ? void 0 : info.hotKeys) !== void 0) {
|
|
1023
|
+
this.serverHotKeys = info.hotKeys;
|
|
1024
|
+
this.updateBadgeContent();
|
|
1025
|
+
}
|
|
1026
|
+
if ((info == null ? void 0 : info.theme) !== void 0) {
|
|
1027
|
+
if (info.theme === "dark") {
|
|
1028
|
+
this.setAttribute("data-theme", "dark");
|
|
1029
|
+
} else if (info.theme === "light") {
|
|
1030
|
+
this.setAttribute("data-theme", "light");
|
|
1031
|
+
} else {
|
|
1032
|
+
this.removeAttribute("data-theme");
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
if ((info == null ? void 0 : info.includeSnippet) !== void 0) {
|
|
1036
|
+
this.options.includeSnippet = info.includeSnippet;
|
|
1037
|
+
}
|
|
1038
|
+
}).catch(() => {
|
|
1039
|
+
});
|
|
1106
1040
|
}
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1041
|
+
createBadge() {
|
|
1042
|
+
const btn = document.createElement("button");
|
|
1043
|
+
btn.className = badgeClass;
|
|
1044
|
+
btn.style.display = "flex";
|
|
1045
|
+
const textSpan = document.createElement("span");
|
|
1046
|
+
textSpan.textContent = "Inspecto Ready";
|
|
1047
|
+
const closeBtn = document.createElement("span");
|
|
1048
|
+
closeBtn.className = `${badgeClass}-close`;
|
|
1049
|
+
closeBtn.innerHTML = "\xD7";
|
|
1050
|
+
closeBtn.title = "Pause Inspector";
|
|
1051
|
+
closeBtn.addEventListener("click", (e) => {
|
|
1052
|
+
e.stopPropagation();
|
|
1053
|
+
this.toggleDisabled();
|
|
1054
|
+
});
|
|
1055
|
+
btn.appendChild(textSpan);
|
|
1056
|
+
btn.appendChild(closeBtn);
|
|
1057
|
+
btn.addEventListener("mousedown", this.onDragStart);
|
|
1058
|
+
btn.addEventListener("click", (e) => {
|
|
1059
|
+
if (this.hasMoved) {
|
|
1060
|
+
this.hasMoved = false;
|
|
1061
|
+
return;
|
|
1062
|
+
}
|
|
1063
|
+
if (this.disabled) {
|
|
1064
|
+
this.toggleDisabled();
|
|
1065
|
+
} else {
|
|
1066
|
+
this.setActive(!this.active);
|
|
1067
|
+
}
|
|
1068
|
+
});
|
|
1069
|
+
this.shadowRootEl.appendChild(btn);
|
|
1070
|
+
return btn;
|
|
1071
|
+
}
|
|
1072
|
+
toggleDisabled() {
|
|
1073
|
+
var _a;
|
|
1074
|
+
this.disabled = !this.disabled;
|
|
1075
|
+
if (this.disabled) {
|
|
1076
|
+
this.active = false;
|
|
1077
|
+
this.overlay.hide();
|
|
1078
|
+
(_a = this.cleanupMenu) == null ? void 0 : _a.call(this);
|
|
1079
|
+
this.cleanupMenu = null;
|
|
1080
|
+
}
|
|
1139
1081
|
this.updateBadgeContent();
|
|
1140
1082
|
}
|
|
1141
|
-
|
|
1142
|
-
this.
|
|
1083
|
+
dismiss() {
|
|
1084
|
+
this.badge.style.display = "none";
|
|
1085
|
+
this.setActive(false);
|
|
1143
1086
|
}
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
closeBtn.addEventListener("click", (e) => {
|
|
1158
|
-
e.stopPropagation();
|
|
1159
|
-
this.toggleDisabled();
|
|
1160
|
-
});
|
|
1161
|
-
btn.appendChild(textSpan);
|
|
1162
|
-
btn.appendChild(closeBtn);
|
|
1163
|
-
btn.addEventListener("mousedown", this.onDragStart);
|
|
1164
|
-
btn.addEventListener("click", (e) => {
|
|
1165
|
-
if (this.hasMoved) {
|
|
1166
|
-
this.hasMoved = false;
|
|
1167
|
-
return;
|
|
1087
|
+
getHotKeyHint() {
|
|
1088
|
+
const hotKeys = this.getEffectiveHotKeys();
|
|
1089
|
+
if (hotKeys === false) return "Inspecto Ready";
|
|
1090
|
+
const isMac = typeof navigator !== "undefined" && /Mac|iPod|iPhone|iPad/.test(navigator.platform);
|
|
1091
|
+
const keys = hotKeys.split("+").map((k) => k.trim().toLowerCase());
|
|
1092
|
+
const displayKeys = keys.map((k) => {
|
|
1093
|
+
if (k === "alt" || k === "option") return isMac ? "\u2325" : "Alt";
|
|
1094
|
+
if (k === "cmd" || k === "meta" || k === "win" || k === "command") return isMac ? "\u2318" : "Win";
|
|
1095
|
+
if (k === "ctrl" || k === "control") return isMac ? "\u2303" : "Ctrl";
|
|
1096
|
+
if (k === "shift") return isMac ? "\u21E7" : "Shift";
|
|
1097
|
+
return k.charAt(0).toUpperCase() + k.slice(1);
|
|
1098
|
+
});
|
|
1099
|
+
return `Hold ${displayKeys.join(" + ")} to Inspect`;
|
|
1168
1100
|
}
|
|
1169
|
-
|
|
1170
|
-
this.
|
|
1171
|
-
|
|
1172
|
-
|
|
1101
|
+
getEffectiveHotKeys() {
|
|
1102
|
+
if (this.options.hotKeys !== void 0) return this.options.hotKeys;
|
|
1103
|
+
if (this.serverHotKeys !== null) return this.serverHotKeys;
|
|
1104
|
+
return "alt";
|
|
1173
1105
|
}
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
this.badge.style.display = "none";
|
|
1190
|
-
this.setActive(false);
|
|
1191
|
-
}
|
|
1192
|
-
getHotKeyHint() {
|
|
1193
|
-
const hotKeys = this.getEffectiveHotKeys();
|
|
1194
|
-
if (hotKeys === false || hotKeys.length === 0) return "Inspecto Ready";
|
|
1195
|
-
const isMac = typeof navigator !== "undefined" && /Mac|iPod|iPhone|iPad/.test(navigator.platform);
|
|
1196
|
-
const keys = hotKeys.map((k) => {
|
|
1197
|
-
if (k === "altKey") return isMac ? "\u2325" : "Alt";
|
|
1198
|
-
if (k === "metaKey") return isMac ? "\u2318" : "Win";
|
|
1199
|
-
if (k === "ctrlKey") return isMac ? "\u2303" : "Ctrl";
|
|
1200
|
-
if (k === "shiftKey") return isMac ? "\u21E7" : "Shift";
|
|
1201
|
-
return k;
|
|
1202
|
-
});
|
|
1203
|
-
return `Hold ${keys.join(" + ")} to Inspect`;
|
|
1204
|
-
}
|
|
1205
|
-
getEffectiveHotKeys() {
|
|
1206
|
-
if (this.options.hotKeys !== void 0) return this.options.hotKeys;
|
|
1207
|
-
if (this.serverHotKeys !== null) return this.serverHotKeys;
|
|
1208
|
-
return ["altKey"];
|
|
1209
|
-
}
|
|
1210
|
-
updateBadgeContent() {
|
|
1211
|
-
const textSpan = this.badge.querySelector("span");
|
|
1212
|
-
if (!textSpan) return;
|
|
1213
|
-
if (this.disabled) {
|
|
1214
|
-
textSpan.textContent = "Inspector Paused";
|
|
1215
|
-
this.badge.classList.remove("active");
|
|
1216
|
-
this.badge.classList.add("disabled");
|
|
1217
|
-
} else if (this.active) {
|
|
1218
|
-
textSpan.textContent = "\u{1F50D} Inspecting...";
|
|
1219
|
-
this.badge.classList.remove("disabled");
|
|
1220
|
-
this.badge.classList.add("active");
|
|
1221
|
-
} else {
|
|
1222
|
-
textSpan.textContent = this.getHotKeyHint();
|
|
1223
|
-
this.badge.classList.remove("active", "disabled");
|
|
1224
|
-
}
|
|
1225
|
-
}
|
|
1226
|
-
setActive(value) {
|
|
1227
|
-
this.active = value;
|
|
1228
|
-
this.updateBadgeContent();
|
|
1229
|
-
if (!value) {
|
|
1230
|
-
this.overlay.hide();
|
|
1231
|
-
this.cleanupMenu?.();
|
|
1232
|
-
this.cleanupMenu = null;
|
|
1233
|
-
}
|
|
1234
|
-
}
|
|
1235
|
-
handleTrigger(e) {
|
|
1236
|
-
if (!this.isInspectorActive(e)) return;
|
|
1237
|
-
const target = findInspectable(e.target);
|
|
1238
|
-
if (!target) return;
|
|
1239
|
-
e.preventDefault();
|
|
1240
|
-
e.stopPropagation();
|
|
1241
|
-
const attrValue = target.getAttribute(ATTR_NAME);
|
|
1242
|
-
const loc = parseAttrValue(attrValue);
|
|
1243
|
-
if (!loc) return;
|
|
1244
|
-
this.cleanupMenu?.();
|
|
1245
|
-
this.cleanupMenu = showIntentMenu(
|
|
1246
|
-
this.shadowRootEl,
|
|
1247
|
-
loc,
|
|
1248
|
-
e.clientX,
|
|
1249
|
-
e.clientY,
|
|
1250
|
-
this.options,
|
|
1251
|
-
() => {
|
|
1252
|
-
this.cleanupMenu = null;
|
|
1106
|
+
updateBadgeContent() {
|
|
1107
|
+
const textSpan = this.badge.querySelector("span");
|
|
1108
|
+
if (!textSpan) return;
|
|
1109
|
+
if (this.disabled) {
|
|
1110
|
+
textSpan.textContent = "Inspector Paused";
|
|
1111
|
+
this.badge.classList.remove("active");
|
|
1112
|
+
this.badge.classList.add("disabled");
|
|
1113
|
+
} else if (this.active) {
|
|
1114
|
+
textSpan.textContent = "\u{1F50D} Inspecting...";
|
|
1115
|
+
this.badge.classList.remove("disabled");
|
|
1116
|
+
this.badge.classList.add("active");
|
|
1117
|
+
} else {
|
|
1118
|
+
textSpan.textContent = this.getHotKeyHint();
|
|
1119
|
+
this.badge.classList.remove("active", "disabled");
|
|
1120
|
+
}
|
|
1253
1121
|
}
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1122
|
+
setActive(value) {
|
|
1123
|
+
var _a;
|
|
1124
|
+
this.active = value;
|
|
1125
|
+
this.updateBadgeContent();
|
|
1126
|
+
if (!value) {
|
|
1127
|
+
this.overlay.hide();
|
|
1128
|
+
(_a = this.cleanupMenu) == null ? void 0 : _a.call(this);
|
|
1129
|
+
this.cleanupMenu = null;
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
handleTrigger(e) {
|
|
1133
|
+
var _a;
|
|
1134
|
+
if (!this.isInspectorActive(e)) return;
|
|
1135
|
+
const target = findInspectable(e.target);
|
|
1136
|
+
if (!target) return;
|
|
1137
|
+
e.preventDefault();
|
|
1138
|
+
e.stopPropagation();
|
|
1139
|
+
const attrValue = target.getAttribute(ATTR_NAME);
|
|
1140
|
+
const loc = parseAttrValue(attrValue);
|
|
1141
|
+
if (!loc) return;
|
|
1142
|
+
(_a = this.cleanupMenu) == null ? void 0 : _a.call(this);
|
|
1143
|
+
this.cleanupMenu = showIntentMenu(
|
|
1144
|
+
this.shadowRootEl,
|
|
1145
|
+
loc,
|
|
1146
|
+
e.clientX,
|
|
1147
|
+
e.clientY,
|
|
1148
|
+
this.options,
|
|
1149
|
+
() => {
|
|
1150
|
+
this.cleanupMenu = null;
|
|
1151
|
+
}
|
|
1152
|
+
);
|
|
1153
|
+
}
|
|
1154
|
+
isInspectorActive(e) {
|
|
1155
|
+
if (this.disabled) return false;
|
|
1156
|
+
if (this.active) return true;
|
|
1157
|
+
const hotKeys = this.getEffectiveHotKeys();
|
|
1158
|
+
if (hotKeys === false) return false;
|
|
1159
|
+
return hotKeysHeld(e, hotKeys);
|
|
1160
|
+
}
|
|
1161
|
+
setupListeners() {
|
|
1162
|
+
document.addEventListener("mousemove", this.onMouseMove, true);
|
|
1163
|
+
document.addEventListener("click", this.onClick, true);
|
|
1164
|
+
document.addEventListener("contextmenu", this.onContextMenu, true);
|
|
1165
|
+
document.addEventListener("keydown", this.onKeyDown, true);
|
|
1166
|
+
}
|
|
1167
|
+
teardownListeners() {
|
|
1168
|
+
document.removeEventListener("mousemove", this.onMouseMove, true);
|
|
1169
|
+
document.removeEventListener("click", this.onClick, true);
|
|
1170
|
+
document.removeEventListener("contextmenu", this.onContextMenu, true);
|
|
1171
|
+
document.removeEventListener("keydown", this.onKeyDown, true);
|
|
1172
|
+
}
|
|
1173
|
+
};
|
|
1174
|
+
if (typeof customElements !== "undefined") {
|
|
1175
|
+
customElements.define("inspecto-overlay", InspectoElement);
|
|
1176
|
+
}
|
|
1274
1177
|
}
|
|
1275
|
-
};
|
|
1276
|
-
if (typeof customElements !== "undefined") {
|
|
1277
|
-
customElements.define("inspecto-overlay", InspectoElement);
|
|
1278
|
-
}
|
|
1178
|
+
});
|
|
1279
1179
|
|
|
1280
1180
|
// src/index.ts
|
|
1181
|
+
var src_exports = {};
|
|
1182
|
+
__export(src_exports, {
|
|
1183
|
+
mountInspector: () => mountInspector,
|
|
1184
|
+
unmountInspector: () => unmountInspector
|
|
1185
|
+
});
|
|
1186
|
+
module.exports = __toCommonJS(src_exports);
|
|
1281
1187
|
var TAG_NAME = "inspecto-overlay";
|
|
1282
|
-
function mountInspector(
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1188
|
+
function mountInspector() {
|
|
1189
|
+
return __async(this, arguments, function* (options = {}) {
|
|
1190
|
+
if (typeof document === "undefined") return null;
|
|
1191
|
+
const { InspectoElement: InspectoElement2 } = yield Promise.resolve().then(() => (init_component(), component_exports));
|
|
1192
|
+
const existing = document.querySelector(TAG_NAME);
|
|
1193
|
+
if (existing) {
|
|
1194
|
+
;
|
|
1195
|
+
existing.configure(options);
|
|
1196
|
+
return existing;
|
|
1197
|
+
}
|
|
1198
|
+
const el = document.createElement(TAG_NAME);
|
|
1199
|
+
el.configure(options);
|
|
1200
|
+
document.body.appendChild(el);
|
|
1201
|
+
return el;
|
|
1202
|
+
});
|
|
1292
1203
|
}
|
|
1293
1204
|
function unmountInspector() {
|
|
1205
|
+
if (typeof document === "undefined") return;
|
|
1294
1206
|
const existing = document.querySelector(TAG_NAME);
|
|
1295
1207
|
if (existing) {
|
|
1296
1208
|
existing.remove();
|