agentation-vue 0.2.6 → 0.2.12

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.
Files changed (33) hide show
  1. package/README.md +94 -0
  2. package/dist/AgentationVue.vue +270 -60
  3. package/dist/components/AgentationToolbar.d.vue.ts +2 -0
  4. package/dist/components/AgentationToolbar.vue +12 -3
  5. package/dist/components/AgentationToolbar.vue.d.ts +2 -0
  6. package/dist/components/AnnotationInput.d.vue.ts +2 -0
  7. package/dist/components/AnnotationInput.vue +88 -16
  8. package/dist/components/AnnotationInput.vue.d.ts +2 -0
  9. package/dist/components/AnnotationMarker.d.vue.ts +1 -0
  10. package/dist/components/AnnotationMarker.vue +12 -3
  11. package/dist/components/AnnotationMarker.vue.d.ts +1 -0
  12. package/dist/components/MentionDropdown.d.vue.ts +16 -0
  13. package/dist/components/MentionDropdown.vue +41 -0
  14. package/dist/components/MentionDropdown.vue.d.ts +16 -0
  15. package/dist/components/SettingsPanel.vue +26 -3
  16. package/dist/components/SettingsPopover.vue +3 -5
  17. package/dist/composables/useAnnotations.d.ts +2 -0
  18. package/dist/composables/useAnnotations.mjs +6 -1
  19. package/dist/composables/useKeyboardShortcuts.mjs +22 -8
  20. package/dist/composables/useMentionDropdown.d.ts +21 -0
  21. package/dist/composables/useMentionDropdown.mjs +162 -0
  22. package/dist/composables/useOutputFormatter.mjs +2 -1
  23. package/dist/composables/usePeekMode.d.ts +14 -0
  24. package/dist/composables/usePeekMode.mjs +119 -0
  25. package/dist/composables/useSettings.d.ts +1 -0
  26. package/dist/composables/useSettings.mjs +2 -1
  27. package/dist/constants.d.ts +2 -0
  28. package/dist/constants.mjs +3 -0
  29. package/dist/styles/agentation.css +1 -1
  30. package/dist/types.d.ts +1 -0
  31. package/dist/utils/mention.d.ts +13 -0
  32. package/dist/utils/mention.mjs +46 -0
  33. package/package.json +2 -2
@@ -0,0 +1,162 @@
1
+ import { computed, ref } from "vue-demi";
2
+ function getSelection(el) {
3
+ const root = el.getRootNode();
4
+ if (root instanceof ShadowRoot && typeof root.getSelection === "function")
5
+ return root.getSelection();
6
+ return window.getSelection();
7
+ }
8
+ function findTrigger(el) {
9
+ const sel = getSelection(el);
10
+ if (!sel || sel.rangeCount === 0)
11
+ return null;
12
+ const range = sel.getRangeAt(0);
13
+ if (!range.collapsed)
14
+ return null;
15
+ const { startContainer, startOffset } = range;
16
+ if (startContainer.nodeType !== Node.TEXT_NODE)
17
+ return null;
18
+ const textNode = startContainer;
19
+ const text = textNode.textContent || "";
20
+ const beforeCursor = text.slice(0, startOffset);
21
+ for (let i = beforeCursor.length - 1; i >= 0; i--) {
22
+ const ch = beforeCursor[i];
23
+ if (ch === " " || ch === "\n")
24
+ return null;
25
+ if (ch === "@") {
26
+ if (i === 0 || beforeCursor[i - 1] === " " || beforeCursor[i - 1] === "\n") {
27
+ return {
28
+ textNode,
29
+ atIndex: i,
30
+ query: beforeCursor.slice(i + 1)
31
+ };
32
+ }
33
+ return null;
34
+ }
35
+ }
36
+ return null;
37
+ }
38
+ export function useMentionDropdown(inputEl, candidates) {
39
+ const isOpen = ref(false);
40
+ const query = ref("");
41
+ const activeIndex = ref(0);
42
+ const dropdownPosition = ref({ x: 0, y: 0 });
43
+ let currentTrigger = null;
44
+ const filteredCandidates = computed(() => {
45
+ if (!isOpen.value)
46
+ return [];
47
+ const q = query.value.toLowerCase();
48
+ return candidates.value.filter((c) => {
49
+ if (!q)
50
+ return true;
51
+ return String(c.displayNumber).startsWith(q) || c.commentPreview.toLowerCase().includes(q);
52
+ });
53
+ });
54
+ function checkForTrigger() {
55
+ const el = inputEl.value;
56
+ if (!el)
57
+ return;
58
+ const trigger = findTrigger(el);
59
+ if (trigger) {
60
+ currentTrigger = trigger;
61
+ query.value = trigger.query;
62
+ activeIndex.value = 0;
63
+ isOpen.value = true;
64
+ updatePosition();
65
+ } else {
66
+ close();
67
+ }
68
+ }
69
+ function updatePosition() {
70
+ const el = inputEl.value;
71
+ if (!el || !currentTrigger)
72
+ return;
73
+ const sel = getSelection(el);
74
+ if (!sel || sel.rangeCount === 0)
75
+ return;
76
+ const range = sel.getRangeAt(0).cloneRange();
77
+ range.setStart(currentTrigger.textNode, currentTrigger.atIndex);
78
+ const rect = range.getBoundingClientRect();
79
+ const containerRect = el.closest(".__va-input")?.getBoundingClientRect();
80
+ if (!containerRect)
81
+ return;
82
+ const x = rect.left - containerRect.left;
83
+ const y = rect.bottom - containerRect.top + 4;
84
+ const viewportBottom = window.innerHeight;
85
+ const estimatedDropdownHeight = Math.min(filteredCandidates.value.length * 36 + 8, 200);
86
+ if (rect.bottom + estimatedDropdownHeight > viewportBottom) {
87
+ dropdownPosition.value = { x, y: rect.top - containerRect.top - estimatedDropdownHeight - 4 };
88
+ } else {
89
+ dropdownPosition.value = { x, y };
90
+ }
91
+ }
92
+ function selectCandidate(candidate) {
93
+ const el = inputEl.value;
94
+ if (!el || !currentTrigger)
95
+ return;
96
+ const sel = getSelection(el);
97
+ if (!sel || sel.rangeCount === 0)
98
+ return;
99
+ const { textNode, atIndex } = currentTrigger;
100
+ const cursorOffset = sel.getRangeAt(0).startOffset;
101
+ const range = document.createRange();
102
+ range.setStart(textNode, atIndex);
103
+ range.setEnd(textNode, cursorOffset);
104
+ range.deleteContents();
105
+ const chip = document.createElement("span");
106
+ chip.contentEditable = "false";
107
+ chip.className = "__va-mention";
108
+ chip.dataset.mentionId = candidate.id;
109
+ chip.textContent = `@${candidate.displayNumber}`;
110
+ range.insertNode(chip);
111
+ const space = document.createTextNode("\xA0");
112
+ chip.after(space);
113
+ const newRange = document.createRange();
114
+ newRange.setStartAfter(space);
115
+ newRange.collapse(true);
116
+ sel.removeAllRanges();
117
+ sel.addRange(newRange);
118
+ close();
119
+ el.dispatchEvent(new Event("input", { bubbles: true }));
120
+ }
121
+ function onKeyDown(e) {
122
+ if (!isOpen.value || filteredCandidates.value.length === 0)
123
+ return false;
124
+ if (e.key === "ArrowDown") {
125
+ e.preventDefault();
126
+ activeIndex.value = (activeIndex.value + 1) % filteredCandidates.value.length;
127
+ return true;
128
+ }
129
+ if (e.key === "ArrowUp") {
130
+ e.preventDefault();
131
+ activeIndex.value = (activeIndex.value - 1 + filteredCandidates.value.length) % filteredCandidates.value.length;
132
+ return true;
133
+ }
134
+ if (e.key === "Enter") {
135
+ e.preventDefault();
136
+ selectCandidate(filteredCandidates.value[activeIndex.value]);
137
+ return true;
138
+ }
139
+ if (e.key === "Escape") {
140
+ e.preventDefault();
141
+ close();
142
+ return true;
143
+ }
144
+ return false;
145
+ }
146
+ function close() {
147
+ isOpen.value = false;
148
+ query.value = "";
149
+ activeIndex.value = 0;
150
+ currentTrigger = null;
151
+ }
152
+ return {
153
+ isOpen,
154
+ filteredCandidates,
155
+ activeIndex,
156
+ dropdownPosition,
157
+ checkForTrigger,
158
+ selectCandidate,
159
+ onKeyDown,
160
+ close
161
+ };
162
+ }
@@ -27,7 +27,8 @@ export function formatAnnotations(annotations, detail, pageUrl) {
27
27
  } else {
28
28
  lines.push(`### ${num}. \`${ann.element}\` \u2014 ${ann.elementPath}`);
29
29
  }
30
- lines.push(`- **Comment:** ${ann.comment}`);
30
+ if (ann.comment)
31
+ lines.push(`- **Comment:** ${ann.comment}`);
31
32
  if (ann.selectedText) {
32
33
  lines.push(`- **In element:** \`${ann.element}\` \u2014 ${ann.elementPath}`);
33
34
  }
@@ -0,0 +1,14 @@
1
+ import type { Ref } from 'vue-demi';
2
+ export interface UsePeekModeOptions {
3
+ peekKey: () => string;
4
+ enabled: () => boolean;
5
+ isInputOpen: () => boolean;
6
+ onActivate: () => void;
7
+ onDeactivate: () => void;
8
+ }
9
+ export declare function usePeekMode(options: UsePeekModeOptions): {
10
+ isCharging: Ref<boolean>;
11
+ isActive: Ref<boolean>;
12
+ deactivate: () => void;
13
+ scheduleExit: () => void;
14
+ };
@@ -0,0 +1,119 @@
1
+ import { onBeforeUnmount, onMounted, ref } from "vue-demi";
2
+ import { PEEK_HOLD_DURATION_MS } from "../constants.mjs";
3
+ export function usePeekMode(options) {
4
+ const isCharging = ref(false);
5
+ const isActive = ref(false);
6
+ let holdTimer = null;
7
+ let exitTimer = null;
8
+ let listenerAttached = false;
9
+ function clearHoldTimer() {
10
+ if (holdTimer) {
11
+ clearTimeout(holdTimer);
12
+ holdTimer = null;
13
+ }
14
+ }
15
+ function clearExitTimer() {
16
+ if (exitTimer) {
17
+ clearTimeout(exitTimer);
18
+ exitTimer = null;
19
+ }
20
+ }
21
+ function clearTimers() {
22
+ clearHoldTimer();
23
+ clearExitTimer();
24
+ }
25
+ function resetAll() {
26
+ clearTimers();
27
+ const wasActive = isActive.value;
28
+ isCharging.value = false;
29
+ isActive.value = false;
30
+ if (wasActive)
31
+ options.onDeactivate();
32
+ }
33
+ function deactivate() {
34
+ clearExitTimer();
35
+ isActive.value = false;
36
+ options.onDeactivate();
37
+ }
38
+ function scheduleExit() {
39
+ clearExitTimer();
40
+ exitTimer = setTimeout(() => {
41
+ exitTimer = null;
42
+ deactivate();
43
+ }, PEEK_HOLD_DURATION_MS);
44
+ }
45
+ function matchesKey(e) {
46
+ const key = options.peekKey();
47
+ if (key === "none")
48
+ return false;
49
+ return e.key === key;
50
+ }
51
+ function onKeyDown(e) {
52
+ if (e.repeat)
53
+ return;
54
+ if (isCharging.value && !matchesKey(e)) {
55
+ clearHoldTimer();
56
+ isCharging.value = false;
57
+ return;
58
+ }
59
+ if (!matchesKey(e))
60
+ return;
61
+ if (isActive.value && exitTimer) {
62
+ clearExitTimer();
63
+ return;
64
+ }
65
+ if (!options.enabled())
66
+ return;
67
+ if (isCharging.value || isActive.value)
68
+ return;
69
+ isCharging.value = true;
70
+ holdTimer = setTimeout(() => {
71
+ holdTimer = null;
72
+ isCharging.value = false;
73
+ isActive.value = true;
74
+ options.onActivate();
75
+ }, PEEK_HOLD_DURATION_MS);
76
+ }
77
+ function onKeyUp(e) {
78
+ if (!matchesKey(e))
79
+ return;
80
+ clearHoldTimer();
81
+ isCharging.value = false;
82
+ if (isActive.value) {
83
+ if (options.isInputOpen()) {
84
+ return;
85
+ }
86
+ deactivate();
87
+ }
88
+ }
89
+ function onBlurOrVisibility() {
90
+ resetAll();
91
+ }
92
+ function attach() {
93
+ if (listenerAttached)
94
+ return;
95
+ listenerAttached = true;
96
+ window.addEventListener("keydown", onKeyDown, true);
97
+ window.addEventListener("keyup", onKeyUp, true);
98
+ window.addEventListener("blur", onBlurOrVisibility);
99
+ document.addEventListener("visibilitychange", onBlurOrVisibility);
100
+ }
101
+ function detach() {
102
+ if (!listenerAttached)
103
+ return;
104
+ listenerAttached = false;
105
+ window.removeEventListener("keydown", onKeyDown, true);
106
+ window.removeEventListener("keyup", onKeyUp, true);
107
+ window.removeEventListener("blur", onBlurOrVisibility);
108
+ document.removeEventListener("visibilitychange", onBlurOrVisibility);
109
+ resetAll();
110
+ }
111
+ onMounted(attach);
112
+ onBeforeUnmount(detach);
113
+ return {
114
+ isCharging,
115
+ isActive,
116
+ deactivate,
117
+ scheduleExit
118
+ };
119
+ }
@@ -12,6 +12,7 @@ export declare function useSettings(): {
12
12
  showComponentTree: boolean;
13
13
  theme: "light" | "dark" | "auto";
14
14
  activationKey: "none" | "Meta" | "Alt" | "Shift";
15
+ peekKey: "none" | "Meta" | "Alt" | "Shift" | "Control";
15
16
  };
16
17
  resetSettings: () => void;
17
18
  };
@@ -18,7 +18,8 @@ const defaults = {
18
18
  clearAfterCopy: false,
19
19
  showComponentTree: true,
20
20
  theme: "auto",
21
- activationKey: "Shift"
21
+ activationKey: "Shift",
22
+ peekKey: "none"
22
23
  };
23
24
  function loadSettings() {
24
25
  try {
@@ -1,2 +1,4 @@
1
1
  export declare const VA_DATA_ATTR = "data-agentation-vue";
2
2
  export declare const VA_DATA_ATTR_SELECTOR = "[data-agentation-vue]";
3
+ export declare const VA_VERSION: any;
4
+ export declare const PEEK_HOLD_DURATION_MS = 1000;
@@ -1,2 +1,5 @@
1
+ import { version } from "../package.json";
1
2
  export const VA_DATA_ATTR = "data-agentation-vue";
2
3
  export const VA_DATA_ATTR_SELECTOR = "[data-agentation-vue]";
4
+ export const VA_VERSION = version;
5
+ export const PEEK_HOLD_DURATION_MS = 1e3;
@@ -1 +1 @@
1
- [data-agentation-vue]{--va-bg:#fff;--va-bg-secondary:#f5f5f5;--va-text:#1a1a1a;--va-text-secondary:#666;--va-border:#e5e5e5}[data-agentation-vue]:not([data-agentation-vue] [data-agentation-vue]){--va-accent:#42b883;--va-accent-rgb:66,184,131}@media (prefers-color-scheme:dark){[data-agentation-vue]:not([data-va-theme=light]){--va-bg:#1a1a1a;--va-bg-secondary:#2a2a2a;--va-text:#f5f5f5;--va-text-secondary:#999;--va-border:#333}}[data-agentation-vue][data-va-theme=dark],[data-agentation-vue][data-va-theme=dark] [data-agentation-vue]{--va-bg:#1a1a1a;--va-bg-secondary:#2a2a2a;--va-text:#f5f5f5;--va-text-secondary:#999;--va-border:#333}[data-agentation-vue][data-va-theme=light],[data-agentation-vue][data-va-theme=light] [data-agentation-vue]{--va-bg:#fff;--va-bg-secondary:#f5f5f5;--va-text:#1a1a1a;--va-text-secondary:#666;--va-border:#e5e5e5}:where([data-agentation-vue],[data-agentation-vue] *){border:none;box-sizing:border-box;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;line-height:1.5;list-style:none;margin:0;padding:0;text-decoration:none}.__va-intercept{background:transparent;cursor:crosshair;inset:0;position:fixed;z-index:2147483646}.__va-intercept--input-open{pointer-events:none}.__va-toolbar{position:fixed;--va-toolbar-base-transform:translate(0);--va-toolbar-auto-hide-transform:translate(0);--va-toolbar-size:42px;--va-toolbar-edge-offset:20px;--va-toolbar-auto-hide-peek:8px;--va-toolbar-auto-hide-corner-peek:16px;--va-toolbar-auto-hide-shift:calc(var(--va-toolbar-edge-offset) + var(--va-toolbar-size) - var(--va-toolbar-auto-hide-peek));--va-toolbar-auto-hide-corner-shift:calc(var(--va-toolbar-edge-offset) + var(--va-toolbar-size) - var(--va-toolbar-auto-hide-corner-peek));display:block;max-width:42px;min-height:42px;z-index:2147483647;--va-toolbar-resize-delay:0ms;background:var(--va-bg);border:1px solid var(--va-border);border-radius:999px;box-shadow:0 4px 12px rgba(0,0,0,.15);padding:0;transform:var(--va-toolbar-base-transform) var(--va-toolbar-auto-hide-transform);transition:border-radius .12s cubic-bezier(.32,.72,0,1),padding .12s cubic-bezier(.32,.72,0,1),max-width .24s cubic-bezier(.22,1,.36,1) var(--va-toolbar-resize-delay),transform .15s ease,opacity .15s ease,box-shadow .15s ease;-webkit-user-select:none;-moz-user-select:none;user-select:none}.__va-toolbar--place-bottom-right{bottom:20px;right:20px}.__va-toolbar--place-bottom-center{bottom:20px;left:50%;--va-toolbar-base-transform:translateX(-50%)}.__va-toolbar--place-bottom-left{bottom:20px;left:20px}.__va-toolbar--place-top-right{right:20px;top:20px}.__va-toolbar--place-top-center{left:50%;top:20px;--va-toolbar-base-transform:translateX(-50%)}.__va-toolbar--place-top-left{left:20px;top:20px}.__va-toolbar--auto-hide.__va-toolbar--collapsed:not(.__va-toolbar--auto-hide-revealed).__va-toolbar--place-top-left{--va-toolbar-auto-hide-transform:translate(calc(var(--va-toolbar-auto-hide-corner-shift)*-1),calc(var(--va-toolbar-auto-hide-corner-shift)*-1))}.__va-toolbar--auto-hide.__va-toolbar--collapsed:not(.__va-toolbar--auto-hide-revealed).__va-toolbar--place-top-center{--va-toolbar-auto-hide-transform:translateY(calc(var(--va-toolbar-auto-hide-shift)*-1))}.__va-toolbar--auto-hide.__va-toolbar--collapsed:not(.__va-toolbar--auto-hide-revealed).__va-toolbar--place-top-right{--va-toolbar-auto-hide-transform:translate(var(--va-toolbar-auto-hide-corner-shift),calc(var(--va-toolbar-auto-hide-corner-shift)*-1))}.__va-toolbar--auto-hide.__va-toolbar--collapsed:not(.__va-toolbar--auto-hide-revealed).__va-toolbar--place-bottom-left{--va-toolbar-auto-hide-transform:translate(calc(var(--va-toolbar-auto-hide-corner-shift)*-1),var(--va-toolbar-auto-hide-corner-shift))}.__va-toolbar--auto-hide.__va-toolbar--collapsed:not(.__va-toolbar--auto-hide-revealed).__va-toolbar--place-bottom-center{--va-toolbar-auto-hide-transform:translateY(var(--va-toolbar-auto-hide-shift))}.__va-toolbar--auto-hide.__va-toolbar--collapsed:not(.__va-toolbar--auto-hide-revealed).__va-toolbar--place-bottom-right{--va-toolbar-auto-hide-transform:translate(var(--va-toolbar-auto-hide-corner-shift),var(--va-toolbar-auto-hide-corner-shift))}.__va-toolbar--collapsed{cursor:pointer;max-width:42px;min-height:42px}.__va-toolbar--expanded{--va-toolbar-resize-delay:110ms;border-radius:10px;max-width:520px;padding:4px}.__va-toolbar--collapsed:not(.__va-toolbar--auto-hide):hover{box-shadow:0 6px 16px rgba(0,0,0,.2)}.__va-toolbar--dragging{bottom:auto;left:0;right:auto;top:0;transform:none;transition:none}.__va-toolbar--dragging.__va-toolbar--collapsed:hover{transform:none}.__va-toolbar-stage{align-items:center;display:flex;gap:4px}.__va-toolbar-stage--toggle{inset:0;justify-content:center;opacity:1;pointer-events:auto;position:absolute;transform:scale(1);transition:opacity .11s ease,transform .18s cubic-bezier(.22,1,.36,1),visibility 0s linear 0s;visibility:visible}.__va-toolbar-stage--menu{--va-toolbar-menu-enter-x:8px;filter:blur(4px);opacity:0;overflow:hidden;pointer-events:none;transform:translateX(var(--va-toolbar-menu-enter-x));transition:opacity .14s ease 0s,transform .22s cubic-bezier(.22,1,.36,1) 0s,visibility 0s linear .14s,filter 80ms ease 0s;visibility:hidden}.__va-toolbar--expanded .__va-toolbar-stage--toggle{opacity:0;pointer-events:none;transform:scale(.94);transition:opacity 90ms ease,transform .12s ease,visibility 0s linear 90ms;visibility:hidden}.__va-toolbar--expanded .__va-toolbar-stage--menu{filter:blur(0);opacity:1;pointer-events:auto;transform:translateX(0);transition:opacity .15s ease .15s,transform .24s cubic-bezier(.22,1,.36,1) .12s,visibility 0s linear 0s,filter .15s ease .2s;visibility:visible}.__va-toolbar--place-bottom-right .__va-toolbar-stage--menu,.__va-toolbar--place-top-right .__va-toolbar-stage--menu{--va-toolbar-menu-enter-x:-8px}.__va-toolbar--place-bottom-center .__va-toolbar-stage--menu,.__va-toolbar--place-top-center .__va-toolbar-stage--menu{--va-toolbar-menu-enter-x:0px}.__va-snap-zones{inset:0;pointer-events:none;position:fixed;z-index:2147483646}.__va-snap-zone{background:rgba(var(--va-accent-rgb),.035);border:1.5px dashed rgba(var(--va-accent-rgb),.18);border-radius:999px;box-shadow:0 0 0 1px rgba(var(--va-accent-rgb),.04);height:42px;position:fixed;transform:translate(-50%,-50%);transition:all .12s ease;width:42px}.__va-snap-zone--active{background:rgba(var(--va-accent-rgb),.09);border-color:rgba(var(--va-accent-rgb),.4)}.__va-snap-zone--rect{border-radius:8px;transform:none}.__va-snap-zone--rect.__va-snap-zone--active{transform:none}.__va-icon-btn{align-items:center;background:transparent;border:none;border-radius:6px;color:var(--va-text-secondary);cursor:pointer;display:flex;flex-shrink:0;height:32px;justify-content:center;outline:none;padding:0;transition:background .15s ease,color .15s ease;width:32px}.__va-icon-btn:hover{background:var(--va-bg-secondary);color:var(--va-text)}.__va-icon-btn--active{background:rgba(var(--va-accent-rgb),.15);color:var(--va-accent)}.__va-icon-btn--active:hover{background:rgba(var(--va-accent-rgb),.25)}.__va-icon-btn:disabled{cursor:not-allowed;opacity:.3}.__va-icon-btn:disabled:hover{background:transparent}.__va-icon-btn svg{height:18px;width:18px}.__va-toolbar-toggle{align-items:center;background:transparent;border:none;color:var(--va-accent);cursor:pointer;display:flex;height:100%;justify-content:center;line-height:0;outline:none;padding:0;position:relative;width:100%}.__va-toolbar-toggle svg{flex-shrink:0;height:22px;width:22px}.__va-toolbar-sep{background:var(--va-border);flex-shrink:0;height:20px;width:1px}.__va-drag-handle{align-items:center;background:transparent;border:none;border-radius:6px;color:var(--va-text-secondary);cursor:grab;display:flex;flex-shrink:0;height:32px;justify-content:center;outline:none;padding:0;transition:all .15s ease;width:24px}.__va-drag-handle:hover{background:var(--va-bg-secondary);color:var(--va-text)}.__va-drag-handle:active{cursor:grabbing}.__va-drag-handle-dots{display:grid;gap:2.5px;grid-template-columns:repeat(2,3px);grid-template-rows:repeat(3,3px)}.__va-drag-handle-dots span{background:currentColor;border-radius:50%;height:3px;opacity:.6;width:3px}.__va-toolbar-badge{align-items:center;background:var(--va-accent);border-radius:9px;color:#fff;display:flex;font-size:11px;font-weight:600;height:18px;justify-content:center;min-width:18px;padding:0 4px;position:absolute;right:-6px;top:-6px}.__va-tooltip{align-items:center;background:#131518;border:1px solid hsla(0,0%,100%,.08);border-radius:10px;box-shadow:0 10px 24px rgba(0,0,0,.32),0 2px 6px rgba(0,0,0,.28);color:#dce1e7;display:inline-flex;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;font-size:11px;font-weight:500;gap:6px;left:0;line-height:1.15;max-width:min(360px,calc(100vw - 16px));opacity:0;padding:6px 9px;pointer-events:none;position:fixed;top:0;transform:translateY(4px) scale(.98);transform-origin:center bottom;transition:opacity .12s ease,transform .12s ease;white-space:nowrap;z-index:2147483647}.__va-tooltip[data-placement=bottom]{transform:translateY(-4px) scale(.98);transform-origin:center top}.__va-tooltip.__va-tooltip--visible{opacity:1}.__va-tooltip.__va-tooltip--visible[data-placement=bottom],.__va-tooltip.__va-tooltip--visible[data-placement=top]{transform:translateY(0) scale(1)}.__va-tooltip-label{overflow:hidden;text-overflow:ellipsis}.__va-tooltip-shortcut{align-items:center;background:hsla(0,0%,100%,.1);border:1px solid hsla(0,0%,100%,.18);border-radius:6px;color:#b5bec8;display:inline-flex;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:11px;font-weight:600;letter-spacing:.03em;line-height:1;min-height:18px;padding:2px 6px}.__va-tooltip-arrow{background:#131518;border:1px solid hsla(0,0%,100%,.08);border-left:none;border-top:none;height:10px;left:50%;position:absolute;transform:translateX(-50%) rotate(45deg);width:10px}.__va-tooltip[data-placement=top] .__va-tooltip-arrow{bottom:-5px}.__va-tooltip[data-placement=bottom] .__va-tooltip-arrow{top:-5px;transform:translateX(-50%) rotate(225deg)}.__va-highlight{background:rgba(var(--va-accent-rgb),.08);border:2px solid var(--va-accent);border-radius:4px;pointer-events:none;position:fixed;transition:all 80ms ease;z-index:2147483645}.__va-highlight-label{background:var(--va-accent);border-radius:4px;color:#fff;font-size:11px;font-weight:500;left:0;max-width:300px;overflow:hidden;padding:2px 8px;position:absolute;text-overflow:ellipsis;top:-28px;white-space:nowrap}.__va-highlight-label--chain{background:#1a1a1a;max-width:500px;overflow:visible;padding:4px 10px}.__va-marker{align-items:center;background:var(--va-accent);border-radius:50%;box-shadow:0 2px 6px rgba(0,0,0,.3);color:#fff;cursor:pointer;display:flex;font-size:12px;font-weight:700;height:24px;justify-content:center;position:absolute;transform:translate(-50%,-50%);transition:all .15s ease;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:24px;z-index:2147483647}.__va-marker:hover{box-shadow:0 3px 10px rgba(0,0,0,.4);transform:translate(-50%,-50%) scale(1.2)}.__va-marker--fixed{position:fixed}.__va-marker--stale{opacity:.5}.__va-marker-plus{height:14px;stroke-width:3;width:14px}.__va-marker-pencil{display:none;height:12px;width:12px}.__va-marker:not(.__va-marker--pending):hover .__va-marker-number{display:none}.__va-marker:not(.__va-marker--pending):hover .__va-marker-pencil{display:block}.__va-marker--pending{animation:__va-pulse 1.5s ease-in-out infinite}.__va-marker--selection{border-radius:6px;height:26px;width:26px}@keyframes __va-pulse{0%,to{box-shadow:0 2px 6px rgba(0,0,0,.3)}50%{box-shadow:0 2px 12px rgba(var(--va-accent-rgb),.5)}}.__va-input{background:var(--va-bg);border:1px solid var(--va-border);border-radius:8px;box-shadow:0 4px 12px rgba(0,0,0,.15);max-width:360px;min-width:280px;padding:12px;position:fixed;z-index:2147483647}.__va-input-label{color:var(--va-text-secondary);display:block;font-size:12px;margin-bottom:8px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.__va-input-chain{margin-bottom:8px}.__va-input-styles{margin-bottom:10px}.__va-input-styles-summary{align-items:center;color:var(--va-text-secondary);cursor:pointer;display:flex;font-size:12px;gap:6px;min-width:0;-webkit-user-select:none;-moz-user-select:none;user-select:none}.__va-input-styles-summary::-webkit-details-marker{display:none}.__va-input-styles-summary:before{content:"▸";flex-shrink:0;font-size:11px;transition:transform .16s ease}.__va-input-styles[open] .__va-input-styles-summary:before{transform:rotate(90deg)}.__va-input-styles-block{background:var(--va-bg-secondary);border:1px solid var(--va-border);border-radius:6px;font-family:ui-monospace,SFMono-Regular,SF Mono,Menlo,monospace;font-size:11px;line-height:1.55;margin-top:8px;padding:8px 10px}.__va-input-styles-element{color:var(--va-text-secondary);display:inline-block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.__va-input-style-line{color:var(--va-text);word-break:break-word}.__va-input-style-prop{color:#a855f7}.__va-input-style-value{color:var(--va-text)}.__va-comp-chain{align-items:center;display:inline-flex;font-family:ui-monospace,SFMono-Regular,SF Mono,Menlo,monospace;font-size:11px;gap:6px}.__va-comp,.__va-comp-chain{white-space:nowrap}.__va-comp-bracket{opacity:.4}.__va-comp-chain--dark{color:#fff}.__va-comp-chain--light{color:var(--va-accent)}.__va-comp-ellipsis{font-size:11px;letter-spacing:1px;opacity:.5}.__va-comp-chain--collapsible{cursor:pointer;flex-wrap:wrap}.__va-comp-toggle{flex-shrink:0;font-size:10px;opacity:.6;text-align:center;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:10px}.__va-input input{background:var(--va-bg);border:1px solid var(--va-border);border-radius:6px;color:var(--va-text);font-size:13px;outline:none;padding:8px 10px;transition:border-color .15s ease;width:100%}.__va-input input:focus{border-color:var(--va-accent)}.__va-input-actions{align-items:center;display:flex;gap:8px;justify-content:space-between;margin-top:8px}.__va-input-actions-right{display:flex;gap:8px;margin-left:auto}.__va-input-delete-btn{align-items:center;background:transparent;border:none;border-radius:6px;color:var(--va-text-secondary);cursor:pointer;display:flex;height:32px;justify-content:center;outline:none;padding:0;transition:all .15s ease;width:32px}.__va-input-delete-btn svg{height:16px;width:16px}.__va-input-delete-btn:hover{background:var(--va-bg-secondary);color:#ef4444}.__va-btn{border:none;border-radius:6px;cursor:pointer;font-size:12px;font-weight:500;outline:none;padding:6px 14px;transition:all .15s ease}.__va-btn--secondary{background:var(--va-bg-secondary);color:var(--va-text-secondary)}.__va-btn--secondary:hover{background:var(--va-border)}.__va-btn--primary{background:var(--va-accent);color:#fff}.__va-btn--primary:hover{opacity:.9}.__va-btn:disabled{cursor:not-allowed;opacity:.4}.__va-settings-popover{position:fixed;z-index:2147483647}.__va-settings{background:var(--va-bg);border:1px solid var(--va-border);border-radius:8px;box-shadow:0 4px 12px rgba(0,0,0,.15);max-width:min(340px,calc(100vw - 16px));min-width:260px;padding:16px;position:relative}.__va-settings-top{border-bottom:1px solid var(--va-border);display:flex;justify-content:flex-end;margin-bottom:12px;padding-bottom:10px}.__va-theme-toggle{align-items:center;background:var(--va-bg-secondary);border:1px solid var(--va-border);border-radius:999px;color:var(--va-text-secondary);cursor:pointer;display:inline-flex;height:28px;justify-content:center;transition:all .15s ease;width:28px}.__va-theme-toggle:hover{border-color:var(--va-text-secondary);color:var(--va-text)}.__va-theme-toggle svg{height:15px;width:15px}.__va-settings-row{align-items:center;display:flex;gap:12px;justify-content:space-between;margin-bottom:10px}.__va-settings-label{color:var(--va-text-secondary);font-size:12px;white-space:nowrap}.__va-settings-row--stack{display:block}.__va-settings-row--stack .__va-settings-label{display:block;margin-bottom:8px}.__va-settings-row:last-child{margin-bottom:0}.__va-settings-divider{background:var(--va-border);height:1px;margin:8px 0 12px}.__va-settings select{background:var(--va-bg);border:1px solid var(--va-border);border-radius:4px;color:var(--va-text);font-size:12px;outline:none;padding:4px 8px}.__va-color-swatches{align-items:center;display:flex;gap:6px}.__va-color-swatch{border:2px solid var(--va-border);border-radius:50%;cursor:pointer;flex-shrink:0;height:22px;outline:none;padding:0;transition:all .15s ease;width:22px}.__va-color-swatch:hover{transform:scale(1.15)}.__va-color-swatch--active{border-color:var(--va-text);transform:scale(1.15)}.__va-toggle{background:var(--va-border);border:none;border-radius:10px;cursor:pointer;flex-shrink:0;height:20px;outline:none;padding:0;position:relative;transition:background .15s ease;width:36px}.__va-toggle--active{background:var(--va-accent)}.__va-toggle:after{background:#fff;border-radius:50%;box-shadow:0 1px 3px rgba(0,0,0,.2);content:"";height:16px;left:2px;position:absolute;top:2px;transition:transform .15s ease;width:16px}.__va-toggle--active:after{transform:translateX(16px)}.__va-selection-rect{background:rgba(var(--va-accent-rgb),.06);border:2px dashed var(--va-accent);border-radius:2px;pointer-events:none;position:fixed;z-index:2147483645}.__va-copy-feedback{animation:__va-fadeIn .15s ease;background:var(--va-accent);border-radius:6px;bottom:72px;box-shadow:0 4px 12px rgba(0,0,0,.15);color:#fff;font-size:13px;font-weight:500;padding:8px 16px;position:fixed;right:20px;z-index:2147483647}@keyframes __va-fadeIn{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}
1
+ [data-agentation-vue]{--va-bg:#fff;--va-bg-secondary:#f5f5f5;--va-text:#1a1a1a;--va-text-secondary:#666;--va-border:#e5e5e5}[data-agentation-vue]:not([data-agentation-vue] [data-agentation-vue]){--va-accent:#42b883;--va-accent-rgb:66,184,131}@media (prefers-color-scheme:dark){[data-agentation-vue]:not([data-va-theme=light]){--va-bg:#1a1a1a;--va-bg-secondary:#2a2a2a;--va-text:#f5f5f5;--va-text-secondary:#999;--va-border:#333}}[data-agentation-vue][data-va-theme=dark],[data-agentation-vue][data-va-theme=dark] [data-agentation-vue]{--va-bg:#1a1a1a;--va-bg-secondary:#2a2a2a;--va-text:#f5f5f5;--va-text-secondary:#999;--va-border:#333}[data-agentation-vue][data-va-theme=light],[data-agentation-vue][data-va-theme=light] [data-agentation-vue]{--va-bg:#fff;--va-bg-secondary:#f5f5f5;--va-text:#1a1a1a;--va-text-secondary:#666;--va-border:#e5e5e5}:where([data-agentation-vue],[data-agentation-vue] *){border:none;box-sizing:border-box;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;line-height:1.5;list-style:none;margin:0;padding:0;text-decoration:none}.__va-intercept{background:transparent;cursor:crosshair;inset:0;position:fixed;z-index:2147483646}.__va-intercept--input-open{pointer-events:none}.__va-toolbar{position:fixed;--va-toolbar-base-transform:translate(0);--va-toolbar-auto-hide-transform:translate(0);--va-toolbar-size:42px;--va-toolbar-edge-offset:20px;--va-toolbar-auto-hide-peek:8px;--va-toolbar-auto-hide-corner-peek:16px;--va-toolbar-auto-hide-shift:calc(var(--va-toolbar-edge-offset) + var(--va-toolbar-size) - var(--va-toolbar-auto-hide-peek));--va-toolbar-auto-hide-corner-shift:calc(var(--va-toolbar-edge-offset) + var(--va-toolbar-size) - var(--va-toolbar-auto-hide-corner-peek));display:block;max-width:42px;min-height:42px;z-index:2147483647;--va-toolbar-resize-delay:0ms;background:var(--va-bg);border:1px solid var(--va-border);border-radius:999px;box-shadow:0 4px 12px rgba(0,0,0,.15);padding:0;transform:var(--va-toolbar-base-transform) var(--va-toolbar-auto-hide-transform);transition:border-radius .12s cubic-bezier(.32,.72,0,1),padding .12s cubic-bezier(.32,.72,0,1),max-width .24s cubic-bezier(.22,1,.36,1) var(--va-toolbar-resize-delay),transform .15s ease,opacity .15s ease,box-shadow .15s ease;-webkit-user-select:none;-moz-user-select:none;user-select:none}.__va-toolbar--place-bottom-right{bottom:20px;right:20px}.__va-toolbar--place-bottom-center{bottom:20px;left:50%;--va-toolbar-base-transform:translateX(-50%)}.__va-toolbar--place-bottom-left{bottom:20px;left:20px}.__va-toolbar--place-top-right{right:20px;top:20px}.__va-toolbar--place-top-center{left:50%;top:20px;--va-toolbar-base-transform:translateX(-50%)}.__va-toolbar--place-top-left{left:20px;top:20px}.__va-toolbar--auto-hide.__va-toolbar--collapsed:not(.__va-toolbar--auto-hide-revealed).__va-toolbar--place-top-left{--va-toolbar-auto-hide-transform:translate(calc(var(--va-toolbar-auto-hide-corner-shift)*-1),calc(var(--va-toolbar-auto-hide-corner-shift)*-1))}.__va-toolbar--auto-hide.__va-toolbar--collapsed:not(.__va-toolbar--auto-hide-revealed).__va-toolbar--place-top-center{--va-toolbar-auto-hide-transform:translateY(calc(var(--va-toolbar-auto-hide-shift)*-1))}.__va-toolbar--auto-hide.__va-toolbar--collapsed:not(.__va-toolbar--auto-hide-revealed).__va-toolbar--place-top-right{--va-toolbar-auto-hide-transform:translate(var(--va-toolbar-auto-hide-corner-shift),calc(var(--va-toolbar-auto-hide-corner-shift)*-1))}.__va-toolbar--auto-hide.__va-toolbar--collapsed:not(.__va-toolbar--auto-hide-revealed).__va-toolbar--place-bottom-left{--va-toolbar-auto-hide-transform:translate(calc(var(--va-toolbar-auto-hide-corner-shift)*-1),var(--va-toolbar-auto-hide-corner-shift))}.__va-toolbar--auto-hide.__va-toolbar--collapsed:not(.__va-toolbar--auto-hide-revealed).__va-toolbar--place-bottom-center{--va-toolbar-auto-hide-transform:translateY(var(--va-toolbar-auto-hide-shift))}.__va-toolbar--auto-hide.__va-toolbar--collapsed:not(.__va-toolbar--auto-hide-revealed).__va-toolbar--place-bottom-right{--va-toolbar-auto-hide-transform:translate(var(--va-toolbar-auto-hide-corner-shift),var(--va-toolbar-auto-hide-corner-shift))}.__va-toolbar--collapsed{cursor:pointer;max-width:42px;min-height:42px}.__va-toolbar--expanded{--va-toolbar-resize-delay:110ms;border-radius:10px;max-width:520px;padding:4px}.__va-toolbar--collapsed:not(.__va-toolbar--auto-hide):hover{box-shadow:0 6px 16px rgba(0,0,0,.2)}.__va-toolbar--dragging{bottom:auto;left:0;right:auto;top:0;transform:none;transition:none}.__va-toolbar--dragging.__va-toolbar--collapsed:hover{transform:none}.__va-toolbar-stage{align-items:center;display:flex;gap:4px}.__va-toolbar-stage--toggle{inset:0;justify-content:center;opacity:1;pointer-events:auto;position:absolute;transform:scale(1);transition:opacity .11s ease,transform .18s cubic-bezier(.22,1,.36,1),visibility 0s linear 0s;visibility:visible}.__va-toolbar-stage--menu{--va-toolbar-menu-enter-x:8px;filter:blur(4px);opacity:0;overflow:hidden;pointer-events:none;transform:translateX(var(--va-toolbar-menu-enter-x));transition:opacity .14s ease 0s,transform .22s cubic-bezier(.22,1,.36,1) 0s,visibility 0s linear .14s,filter 80ms ease 0s;visibility:hidden}.__va-toolbar--expanded .__va-toolbar-stage--toggle{opacity:0;pointer-events:none;transform:scale(.94);transition:opacity 90ms ease,transform .12s ease,visibility 0s linear 90ms;visibility:hidden}.__va-toolbar--expanded .__va-toolbar-stage--menu{filter:blur(0);opacity:1;pointer-events:auto;transform:translateX(0);transition:opacity .15s ease .15s,transform .24s cubic-bezier(.22,1,.36,1) .12s,visibility 0s linear 0s,filter .15s ease .2s;visibility:visible}.__va-toolbar--place-bottom-right .__va-toolbar-stage--menu,.__va-toolbar--place-top-right .__va-toolbar-stage--menu{--va-toolbar-menu-enter-x:-8px}.__va-toolbar--place-bottom-center .__va-toolbar-stage--menu,.__va-toolbar--place-top-center .__va-toolbar-stage--menu{--va-toolbar-menu-enter-x:0px}.__va-snap-zones{inset:0;pointer-events:none;position:fixed;z-index:2147483646}.__va-snap-zone{background:rgba(var(--va-accent-rgb),.035);border:1.5px dashed rgba(var(--va-accent-rgb),.18);border-radius:999px;box-shadow:0 0 0 1px rgba(var(--va-accent-rgb),.04);height:42px;position:fixed;transform:translate(-50%,-50%);transition:all .12s ease;width:42px}.__va-snap-zone--active{background:rgba(var(--va-accent-rgb),.09);border-color:rgba(var(--va-accent-rgb),.4)}.__va-snap-zone--rect{border-radius:8px;transform:none}.__va-snap-zone--rect.__va-snap-zone--active{transform:none}.__va-icon-btn{align-items:center;background:transparent;border:none;border-radius:6px;color:var(--va-text-secondary);cursor:pointer;display:flex;flex-shrink:0;height:32px;justify-content:center;outline:none;padding:0;transition:background .15s ease,color .15s ease;width:32px}.__va-icon-btn:hover{background:var(--va-bg-secondary);color:var(--va-text)}.__va-icon-btn--active{background:rgba(var(--va-accent-rgb),.15);color:var(--va-accent)}.__va-icon-btn--active:hover{background:rgba(var(--va-accent-rgb),.25)}.__va-icon-btn:disabled{cursor:not-allowed;opacity:.3}.__va-icon-btn:disabled:hover{background:transparent}.__va-icon-btn svg{height:18px;width:18px}.__va-toolbar-toggle{align-items:center;background:transparent;border:none;color:var(--va-accent);cursor:pointer;display:flex;height:100%;justify-content:center;line-height:0;outline:none;padding:0;position:relative;width:100%}.__va-toolbar-toggle svg:not(.__va-peek-ring){flex-shrink:0;height:22px;width:22px}.__va-peek-ring{height:calc(100% + 6px);inset:-3px;overflow:visible;pointer-events:none;position:absolute;width:calc(100% + 6px)}.__va-peek-ring circle{animation:va-peek-fill linear forwards;fill:none;stroke:var(--va-accent);stroke-dasharray:131.95;stroke-dashoffset:131.95;stroke-linecap:round;stroke-width:3;transform:rotate(-90deg);transform-origin:center}@keyframes va-peek-fill{to{stroke-dashoffset:0}}.__va-toolbar-sep{background:var(--va-border);flex-shrink:0;height:20px;width:1px}.__va-drag-handle{align-items:center;background:transparent;border:none;border-radius:6px;color:var(--va-text-secondary);cursor:grab;display:flex;flex-shrink:0;height:32px;justify-content:center;outline:none;padding:0;transition:all .15s ease;width:24px}.__va-drag-handle:hover{background:var(--va-bg-secondary);color:var(--va-text)}.__va-drag-handle:active{cursor:grabbing}.__va-drag-handle-dots{display:grid;gap:2.5px;grid-template-columns:repeat(2,3px);grid-template-rows:repeat(3,3px)}.__va-drag-handle-dots span{background:currentColor;border-radius:50%;height:3px;opacity:.6;width:3px}.__va-toolbar-badge{align-items:center;background:var(--va-accent);border-radius:9px;color:#fff;display:flex;font-size:11px;font-weight:600;height:18px;justify-content:center;min-width:18px;padding:0 4px;position:absolute;right:-6px;top:-6px;z-index:1}.__va-tooltip{align-items:center;background:#131518;border:1px solid hsla(0,0%,100%,.08);border-radius:10px;box-shadow:0 10px 24px rgba(0,0,0,.32),0 2px 6px rgba(0,0,0,.28);color:#dce1e7;display:inline-flex;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;font-size:11px;font-weight:500;gap:6px;left:0;line-height:1.15;max-width:min(360px,calc(100vw - 16px));opacity:0;padding:6px 9px;pointer-events:none;position:fixed;top:0;transform:translateY(4px) scale(.98);transform-origin:center bottom;transition:opacity .12s ease,transform .12s ease;white-space:nowrap;z-index:2147483647}.__va-tooltip[data-placement=bottom]{transform:translateY(-4px) scale(.98);transform-origin:center top}.__va-tooltip.__va-tooltip--visible{opacity:1}.__va-tooltip.__va-tooltip--visible[data-placement=bottom],.__va-tooltip.__va-tooltip--visible[data-placement=top]{transform:translateY(0) scale(1)}.__va-tooltip-label{overflow:hidden;text-overflow:ellipsis}.__va-tooltip-shortcut{align-items:center;background:hsla(0,0%,100%,.1);border:1px solid hsla(0,0%,100%,.18);border-radius:6px;color:#b5bec8;display:inline-flex;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:11px;font-weight:600;letter-spacing:.03em;line-height:1;min-height:18px;padding:2px 6px}.__va-tooltip-arrow{background:#131518;border:1px solid hsla(0,0%,100%,.08);border-left:none;border-top:none;height:10px;left:50%;position:absolute;transform:translateX(-50%) rotate(45deg);width:10px}.__va-tooltip[data-placement=top] .__va-tooltip-arrow{bottom:-5px}.__va-tooltip[data-placement=bottom] .__va-tooltip-arrow{top:-5px;transform:translateX(-50%) rotate(225deg)}.__va-highlight{background:rgba(var(--va-accent-rgb),.08);border:2px solid var(--va-accent);border-radius:4px;pointer-events:none;position:fixed;transition:all 80ms ease;z-index:2147483645}.__va-highlight-label{background:var(--va-accent);border-radius:4px;color:#fff;font-size:11px;font-weight:500;left:0;max-width:300px;overflow:hidden;padding:2px 8px;position:absolute;text-overflow:ellipsis;top:-28px;white-space:nowrap}.__va-highlight-label--chain{background:#1a1a1a;max-width:500px;overflow:visible;padding:4px 10px}.__va-marker{align-items:center;background:var(--va-accent);border-radius:50%;box-shadow:0 2px 6px rgba(0,0,0,.3);color:#fff;cursor:pointer;display:flex;font-size:12px;font-weight:700;height:24px;justify-content:center;position:absolute;transform:translate(-50%,-50%) scale(1);transition:transform .25s cubic-bezier(.34,1.56,.64,1),box-shadow .15s ease,opacity .15s ease;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:24px;z-index:2147483647}.__va-marker:hover{box-shadow:0 3px 10px rgba(0,0,0,.4);transform:translate(-50%,-50%) scale(1.2)}.__va-marker--entering,.__va-marker--hidden{pointer-events:none;transform:translate(-50%,-50%) scale(0)!important}.__va-marker--hidden{transition:transform .2s cubic-bezier(.55,0,1,.45),box-shadow .15s ease,opacity .15s ease}.__va-marker--fixed{position:fixed}.__va-marker--stale{opacity:.5}.__va-marker-plus{height:14px;stroke-width:3;width:14px}.__va-marker-pencil{display:none;height:12px;width:12px}.__va-marker:not(.__va-marker--pending):hover .__va-marker-number{display:none}.__va-marker:not(.__va-marker--pending):hover .__va-marker-pencil{display:block}.__va-marker--pending{animation:__va-pulse 1.5s ease-in-out infinite}.__va-marker--selection{border-radius:6px;height:26px;width:26px}@keyframes __va-pulse{0%,to{box-shadow:0 2px 6px rgba(0,0,0,.3)}50%{box-shadow:0 2px 12px rgba(var(--va-accent-rgb),.5)}}.__va-input{background:var(--va-bg);border:1px solid var(--va-border);border-radius:8px;box-shadow:0 4px 12px rgba(0,0,0,.15);max-width:360px;min-width:280px;padding:12px;position:fixed;z-index:2147483647}.__va-input-label{color:var(--va-text-secondary);display:block;font-size:12px;margin-bottom:8px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.__va-input-chain{margin-bottom:8px}.__va-input-styles{margin-bottom:10px}.__va-input-styles-summary{align-items:center;color:var(--va-text-secondary);cursor:pointer;display:flex;font-size:12px;gap:6px;min-width:0;-webkit-user-select:none;-moz-user-select:none;user-select:none}.__va-input-styles-summary::-webkit-details-marker{display:none}.__va-input-styles-summary:before{content:"▸";flex-shrink:0;font-size:11px;transition:transform .16s ease}.__va-input-styles[open] .__va-input-styles-summary:before{transform:rotate(90deg)}.__va-input-styles-block{background:var(--va-bg-secondary);border:1px solid var(--va-border);border-radius:6px;font-family:ui-monospace,SFMono-Regular,SF Mono,Menlo,monospace;font-size:11px;line-height:1.55;margin-top:8px;padding:8px 10px}.__va-input-styles-element{color:var(--va-text-secondary);display:inline-block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.__va-input-style-line{color:var(--va-text);word-break:break-word}.__va-input-style-prop{color:#a855f7}.__va-input-style-value{color:var(--va-text)}.__va-comp-chain{align-items:center;display:inline-flex;font-family:ui-monospace,SFMono-Regular,SF Mono,Menlo,monospace;font-size:11px;gap:6px}.__va-comp,.__va-comp-chain{white-space:nowrap}.__va-comp-bracket{opacity:.4}.__va-comp-chain--dark{color:#fff}.__va-comp-chain--light{color:var(--va-accent)}.__va-comp-ellipsis{font-size:11px;letter-spacing:1px;opacity:.5}.__va-comp-chain--collapsible{cursor:pointer;flex-wrap:wrap}.__va-comp-toggle{flex-shrink:0;font-size:10px;opacity:.6;text-align:center;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:10px}.__va-input-editable{background:var(--va-bg);border:1px solid var(--va-border);border-radius:6px;color:var(--va-text);font-family:inherit;font-size:13px;line-height:1.4;min-height:1.4em;outline:none;overflow:hidden;padding:8px 10px;transition:border-color .15s ease;white-space:pre-wrap;width:100%;word-break:break-word}.__va-input-editable:focus{border-color:var(--va-accent)}.__va-input-editable:empty:before{color:var(--va-text-secondary);content:attr(data-placeholder);pointer-events:none}.__va-mention{background:rgba(var(--va-accent-rgb),.15);border-radius:4px;color:var(--va-accent);cursor:default;display:inline;font-size:12px;font-weight:600;padding:1px 6px;-webkit-user-select:all;-moz-user-select:all;user-select:all;white-space:nowrap}.__va-mention--deleted{opacity:.45;text-decoration:line-through}.__va-mention-dropdown{background:var(--va-bg);border:1px solid var(--va-border);border-radius:6px;box-shadow:0 4px 12px rgba(0,0,0,.15);max-height:200px;max-width:280px;min-width:180px;overflow-y:auto;padding:4px;position:absolute;z-index:1}.__va-mention-option{align-items:center;border-radius:4px;color:var(--va-text);cursor:pointer;display:flex;font-size:12px;gap:8px;padding:6px 8px}.__va-mention-option--active,.__va-mention-option:hover{background:var(--va-bg-secondary)}.__va-mention-option-number{align-items:center;background:var(--va-accent);border-radius:50%;color:#fff;display:inline-flex;flex-shrink:0;font-size:11px;font-weight:700;height:20px;justify-content:center;width:20px}.__va-mention-option-preview{color:var(--va-text-secondary);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.__va-input-actions{align-items:center;display:flex;gap:8px;justify-content:space-between;margin-top:8px}.__va-input-actions-right{display:flex;gap:8px;margin-left:auto}.__va-input-delete-btn{align-items:center;background:transparent;border:none;border-radius:6px;color:var(--va-text-secondary);cursor:pointer;display:flex;height:32px;justify-content:center;outline:none;padding:0;transition:all .15s ease;width:32px}.__va-input-delete-btn svg{height:16px;width:16px}.__va-input-delete-btn:hover{background:var(--va-bg-secondary);color:#ef4444}.__va-btn{border:none;border-radius:6px;cursor:pointer;font-size:12px;font-weight:500;outline:none;padding:6px 14px;transition:all .15s ease}.__va-btn--secondary{background:var(--va-bg-secondary);color:var(--va-text-secondary)}.__va-btn--secondary:hover{background:var(--va-border)}.__va-btn--primary{background:var(--va-accent);color:#fff}.__va-btn--primary:hover{opacity:.9}.__va-btn:disabled{cursor:not-allowed;opacity:.4}.__va-settings-popover{position:fixed;z-index:2147483647}.__va-settings{background:var(--va-bg);border:1px solid var(--va-border);border-radius:8px;box-shadow:0 4px 12px rgba(0,0,0,.15);max-width:min(340px,calc(100vw - 16px));min-width:260px;padding:16px;position:relative}.__va-settings-top{align-items:center;border-bottom:1px solid var(--va-border);display:flex;justify-content:space-between;margin-bottom:12px;padding-bottom:10px}.__va-settings-title{color:var(--va-text);font-size:13px;font-weight:600}.__va-settings-version{color:var(--va-text-secondary);font-size:11px;font-weight:400}.__va-theme-toggle{align-items:center;background:var(--va-bg-secondary);border:1px solid var(--va-border);border-radius:999px;color:var(--va-text-secondary);cursor:pointer;display:inline-flex;height:28px;justify-content:center;transition:all .15s ease;width:28px}.__va-theme-toggle:hover{border-color:var(--va-text-secondary);color:var(--va-text)}.__va-theme-toggle svg{height:15px;width:15px}.__va-settings-row{align-items:center;display:flex;gap:12px;justify-content:space-between;margin-bottom:10px}.__va-settings-label{color:var(--va-text-secondary);font-size:12px;white-space:nowrap}.__va-settings-row--stack{display:block}.__va-settings-row--stack .__va-settings-label{display:block;margin-bottom:8px}.__va-settings-row:last-child{margin-bottom:0}.__va-settings-divider{background:var(--va-border);height:1px;margin:8px 0 12px}.__va-settings select{background:var(--va-bg);border:1px solid var(--va-border);border-radius:4px;color:var(--va-text);font-size:12px;outline:none;padding:4px 8px}.__va-color-swatches{align-items:center;display:flex;gap:6px}.__va-color-swatch{border:2px solid var(--va-border);border-radius:50%;cursor:pointer;flex-shrink:0;height:22px;outline:none;padding:0;transition:all .15s ease;width:22px}.__va-color-swatch:hover{transform:scale(1.15)}.__va-color-swatch--active{border-color:var(--va-text);transform:scale(1.15)}.__va-toggle{background:var(--va-border);border:none;border-radius:10px;cursor:pointer;flex-shrink:0;height:20px;outline:none;padding:0;position:relative;transition:background .15s ease;width:36px}.__va-toggle--active{background:var(--va-accent)}.__va-toggle:after{background:#fff;border-radius:50%;box-shadow:0 1px 3px rgba(0,0,0,.2);content:"";height:16px;left:2px;position:absolute;top:2px;transition:transform .15s ease;width:16px}.__va-toggle--active:after{transform:translateX(16px)}.__va-selection-rect{background:rgba(var(--va-accent-rgb),.06);border:2px dashed var(--va-accent);border-radius:2px;pointer-events:none;position:fixed;z-index:2147483645}.__va-copy-feedback{animation:__va-fadeIn .15s ease;background:var(--va-accent);border-radius:6px;bottom:72px;box-shadow:0 4px 12px rgba(0,0,0,.15);color:#fff;font-size:13px;font-weight:500;padding:8px 16px;position:fixed;right:20px;z-index:2147483647}@keyframes __va-fadeIn{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.__va-undo-feedback{align-items:center;animation:__va-fadeIn .15s ease;background:var(--va-bg);border:1px solid var(--va-border);border-radius:6px;bottom:72px;box-shadow:0 4px 12px rgba(0,0,0,.15);color:var(--va-text);display:flex;font-size:13px;font-weight:500;gap:12px;padding:8px 12px 8px 16px;position:fixed;right:20px;z-index:2147483647}.__va-undo-feedback--shifted{bottom:112px}.__va-undo-btn{background:var(--va-accent);border:none;border-radius:4px;color:#fff;cursor:pointer;font-family:inherit;font-size:12px;font-weight:600;outline:none;padding:4px 10px;transition:opacity .15s ease}.__va-undo-btn:hover{opacity:.85}
package/dist/types.d.ts CHANGED
@@ -68,6 +68,7 @@ export interface Settings {
68
68
  showComponentTree: boolean;
69
69
  theme: 'light' | 'dark' | 'auto';
70
70
  activationKey: 'none' | 'Meta' | 'Alt' | 'Shift';
71
+ peekKey: 'none' | 'Meta' | 'Alt' | 'Shift' | 'Control';
71
72
  }
72
73
  export interface StorageAdapter {
73
74
  getItem: (key: string) => string | null;
@@ -0,0 +1,13 @@
1
+ export interface MentionCandidate {
2
+ id: string;
3
+ displayNumber: number;
4
+ commentPreview: string;
5
+ }
6
+ export declare function createMentionChipHTML(id: string, displayNumber: number): string;
7
+ export declare function createDeletedMentionChipHTML(id: string): string;
8
+ export declare function serializeMentions(el: HTMLElement): string;
9
+ export declare function hydrateMentions(text: string, annotations: {
10
+ id: string;
11
+ displayNumber: number;
12
+ }[]): string;
13
+ export declare function extractMentionIds(text: string): string[];
@@ -0,0 +1,46 @@
1
+ const MENTION_REGEX = /@\[(\d+)\]/g;
2
+ export function createMentionChipHTML(id, displayNumber) {
3
+ return `<span contenteditable="false" class="__va-mention" data-mention-id="${id}">@${displayNumber}</span>`;
4
+ }
5
+ export function createDeletedMentionChipHTML(id) {
6
+ return `<span contenteditable="false" class="__va-mention __va-mention--deleted" data-mention-id="${id}">@?</span>`;
7
+ }
8
+ export function serializeMentions(el) {
9
+ let result = "";
10
+ for (const node of el.childNodes) {
11
+ if (node.nodeType === Node.TEXT_NODE) {
12
+ result += node.textContent || "";
13
+ } else if (node.nodeType === Node.ELEMENT_NODE) {
14
+ const element = node;
15
+ if (element.classList.contains("__va-mention") && element.dataset.mentionId) {
16
+ result += `@[${element.dataset.mentionId}]`;
17
+ } else if (element.tagName === "BR") {
18
+ result += "\n";
19
+ } else {
20
+ const inner = serializeMentions(element);
21
+ if (element.tagName === "DIV" && result.length > 0 && !result.endsWith("\n"))
22
+ result += "\n";
23
+ result += inner;
24
+ }
25
+ }
26
+ }
27
+ return result;
28
+ }
29
+ export function hydrateMentions(text, annotations) {
30
+ const lookup = new Map(annotations.map((a) => [a.id, a.displayNumber]));
31
+ return escapeHTML(text).replace(
32
+ /@\[(\d+)\]/g,
33
+ (_, id) => {
34
+ const displayNumber = lookup.get(id);
35
+ if (displayNumber != null)
36
+ return createMentionChipHTML(id, displayNumber);
37
+ return createDeletedMentionChipHTML(id);
38
+ }
39
+ );
40
+ }
41
+ export function extractMentionIds(text) {
42
+ return [...new Set(Array.from(text.matchAll(MENTION_REGEX), (m) => m[1]))];
43
+ }
44
+ function escapeHTML(str) {
45
+ return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
46
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentation-vue",
3
- "version": "0.2.6",
3
+ "version": "0.2.12",
4
4
  "description": "Visual feedback tool for AI coding agents — Vue 2.7 & 3",
5
5
  "author": "Dorian Becker",
6
6
  "license": "PolyForm-Shield-1.0.0",
@@ -36,7 +36,7 @@
36
36
  ],
37
37
  "scripts": {
38
38
  "build": "unbuild",
39
- "prepack": "pnpm run build",
39
+ "prepack": "pnpm run build && cp ../../README.md .",
40
40
  "dev": "unbuild --stub",
41
41
  "typecheck": "vue-tsc --noEmit"
42
42
  },