cobro-mcp 0.9.0 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/dist/overlay.js +68 -22
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,10 @@ All notable changes to this project are documented here. The format follows [Kee
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.9.1] — 2026-09-21
|
|
8
|
+
### Added
|
|
9
|
+
- Working indicator: while the agent is editing (from Send until done), the elements and regions you sent get a blue scanning outline and the toolbar shows a flowing line; respects prefers-reduced-motion.
|
|
10
|
+
|
|
7
11
|
## [0.9.0] — 2026-09-21
|
|
8
12
|
### Added
|
|
9
13
|
- Drag groups: dragging over two or more elements picks them as one group — the band becomes a region (ref "1") and the elements inside get "1a", "1b"…; the row is collapsed by default and expands to show or remove them. A band over one element picks just that element. Every element and region now carries a stable `ref` that does not change when other rows are removed.
|
package/dist/overlay.js
CHANGED
|
@@ -81,6 +81,17 @@
|
|
|
81
81
|
.status-in.enter{animation:cobroin .15s ease-out}
|
|
82
82
|
@keyframes cobroin{from{opacity:.4;transform:translateX(-6px)}to{opacity:1;transform:translateX(0)}}
|
|
83
83
|
@media (prefers-reduced-motion: reduce){.status-in{transition:none}.status-in.enter{animation:none}}
|
|
84
|
+
.wbox{position:fixed;border:1.5px solid var(--info);border-radius:2px;pointer-events:none;box-sizing:border-box;animation:cobrobreathe 2.4s ease-in-out infinite}
|
|
85
|
+
.wbox.region{border-style:dashed;background:color-mix(in srgb, var(--info) 6%, transparent)}
|
|
86
|
+
.wbox .clip{position:absolute;inset:0;overflow:hidden;border-radius:inherit}
|
|
87
|
+
.wbox .sweep{position:absolute;top:0;bottom:0;left:0;width:55%;background:linear-gradient(90deg,transparent,color-mix(in srgb, var(--info) 55%, transparent),transparent);animation:cobrosweep 2.2s cubic-bezier(.4,0,.2,1) infinite}
|
|
88
|
+
/* \uBC30\uC9C0 \uBC30\uACBD \uD1A0\uD070\uC744 \uAE00\uC790\uC0C9\uC73C\uB85C \u2014 --info \uC704 \uB300\uBE44\uAC00 \uC138 \uD14C\uB9C8 \uBAA8\uB450 \uB9DE\uB294\uB2E4 */
|
|
89
|
+
.wbox .n{position:absolute;left:-2px;top:-2px;transform:translate(-50%,-50%);min-width:18px;height:18px;padding:0 5px;border-radius:9px;background:var(--info);color:var(--badge-bg);font:700 11px/18px ui-monospace,Menlo,Consolas,monospace;text-align:center;box-shadow:0 1px 3px rgba(0,0,0,.4)}
|
|
90
|
+
@keyframes cobrosweep{0%{transform:translateX(-110%)}100%{transform:translateX(300%)}}
|
|
91
|
+
@keyframes cobrobreathe{0%{box-shadow:0 0 0 1px color-mix(in srgb, var(--info) 12%, transparent),0 0 6px color-mix(in srgb, var(--info) 18%, transparent)}50%{box-shadow:0 0 0 3px color-mix(in srgb, var(--info) 16%, transparent),0 0 16px color-mix(in srgb, var(--info) 42%, transparent)}100%{box-shadow:0 0 0 1px color-mix(in srgb, var(--info) 12%, transparent),0 0 6px color-mix(in srgb, var(--info) 18%, transparent)}}
|
|
92
|
+
.toolbar .line{position:absolute;left:20px;right:20px;bottom:0;height:2px;background:linear-gradient(90deg,transparent,var(--info) 30%,var(--accent) 50%,var(--info) 70%,transparent);background-size:200% 100%;background-position:100%;opacity:.9;animation:cobroflow 2.2s linear infinite;pointer-events:none}
|
|
93
|
+
@keyframes cobroflow{from{background-position:100%}to{background-position:-100%}}
|
|
94
|
+
@media (prefers-reduced-motion: reduce){.wbox{animation:none}.wbox .sweep{display:none}.toolbar .line{animation:none}}
|
|
84
95
|
.panel{position:fixed;right:14px;bottom:60px;width:320px;background:var(--bg-2);border:1px solid var(--accent);border-radius:var(--radius);padding:16px 16px 14px;box-shadow:var(--shadow);pointer-events:auto;display:none}
|
|
85
96
|
.panel.show{display:block}
|
|
86
97
|
.panel h4{margin:0 0 12px;color:var(--fg);font-size:12px;font-weight:700;display:flex;align-items:center;gap:6px;cursor:grab;user-select:none}
|
|
@@ -113,15 +124,15 @@ textarea{width:100%;min-height:80px;resize:none;font:inherit;color:var(--fg);bac
|
|
|
113
124
|
.marker{position:fixed;border:2px solid var(--accent);border-radius:2px;pointer-events:none;box-sizing:border-box}
|
|
114
125
|
.marker.region{border-style:dashed;background:color-mix(in srgb, var(--accent) 6%, transparent)}
|
|
115
126
|
.marker .n{position:absolute;left:-2px;top:-2px;transform:translate(-50%,-50%);min-width:18px;height:18px;padding:0 5px;border-radius:9px;background:var(--accent);color:#fff;font:700 11px/18px ui-monospace,Menlo,Consolas,monospace;text-align:center;box-shadow:0 1px 3px rgba(0,0,0,.4)}
|
|
116
|
-
.marker.inside-x .n{transform:translate(4px,-50%)}
|
|
117
|
-
.marker.inside-y .n{transform:translate(-50%,4px)}
|
|
118
|
-
.marker.inside-x.inside-y .n{transform:translate(4px,4px)}
|
|
127
|
+
.marker.inside-x .n,.wbox.inside-x .n{transform:translate(4px,-50%)}
|
|
128
|
+
.marker.inside-y .n,.wbox.inside-y .n{transform:translate(-50%,4px)}
|
|
129
|
+
.marker.inside-x.inside-y .n,.wbox.inside-x.inside-y .n{transform:translate(4px,4px)}
|
|
119
130
|
.marker.child .n{left:auto;right:-2px;transform:translate(50%,-50%)}
|
|
120
131
|
.flash{position:fixed;border:2px solid var(--ok);border-radius:2px;pointer-events:none;animation:cobroflash 1.6s ease-out forwards}
|
|
121
132
|
@keyframes cobroflash{0%{opacity:1}100%{opacity:0}}
|
|
122
133
|
/* shadow root\uC758 \uC790\uC2DD\uC740 \uBAA8\uB450 position:fixed \uD615\uC81C \u2014 picker\uAC00 glass\uB97C toolbar/panel \uB4A4\uC5D0 append\uD558\uBBC0\uB85C \uC313\uC784 \uC21C\uC11C\uB97C \uBA85\uC2DC\uD55C\uB2E4 */
|
|
123
134
|
.glass{z-index:0}
|
|
124
|
-
.hover-box,.hover-badge,.band,.flash,.marker{z-index:1}
|
|
135
|
+
.hover-box,.hover-badge,.band,.flash,.marker,.wbox{z-index:1}
|
|
125
136
|
.toolbar,.pop,.panel{z-index:2}
|
|
126
137
|
.pop{position:fixed;bottom:56px;left:50%;transform:translateX(-50%);display:none;min-width:260px;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);padding:10px 12px;box-shadow:var(--shadow);backdrop-filter:var(--blur);-webkit-backdrop-filter:var(--blur);pointer-events:auto;color:var(--fg-2)}
|
|
127
138
|
.pop.show{display:block}
|
|
@@ -352,6 +363,10 @@ textarea{width:100%;min-height:80px;resize:none;font:inherit;color:var(--fg);bac
|
|
|
352
363
|
const grip = gripParts.btn;
|
|
353
364
|
grip.setAttribute("aria-label", "Move toolbar");
|
|
354
365
|
toolbar.append(grip, selectBtn, chip, chip2, status, gearBtn);
|
|
366
|
+
const line = document.createElement("span");
|
|
367
|
+
line.className = "line";
|
|
368
|
+
line.hidden = true;
|
|
369
|
+
toolbar.append(line);
|
|
355
370
|
makeDraggable(toolbar, grip);
|
|
356
371
|
const pop = document.createElement("div");
|
|
357
372
|
pop.className = "pop";
|
|
@@ -640,8 +655,7 @@ textarea{width:100%;min-height:80px;resize:none;font:inherit;color:var(--fg);bac
|
|
|
640
655
|
cancelAnimationFrame(markerFrame);
|
|
641
656
|
markerFrame = requestAnimationFrame(() => {
|
|
642
657
|
root.querySelectorAll(".marker").forEach((m) => m.remove());
|
|
643
|
-
|
|
644
|
-
if (!cur) return;
|
|
658
|
+
root.querySelectorAll(".wbox").forEach((m) => m.remove());
|
|
645
659
|
const place = (m, left, top, width, height, n) => {
|
|
646
660
|
Object.assign(m.style, { left: left + "px", top: top + "px", width: width + "px", height: height + "px" });
|
|
647
661
|
if (left < 12) m.classList.add("inside-x");
|
|
@@ -649,23 +663,54 @@ textarea{width:100%;min-height:80px;resize:none;font:inherit;color:var(--fg);bac
|
|
|
649
663
|
m.append(el("span", "n", String(n)));
|
|
650
664
|
root.append(m);
|
|
651
665
|
};
|
|
652
|
-
cur.
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
target =
|
|
660
|
-
|
|
666
|
+
const cur = vm.drafts.length ? vm.drafts[vm.drafts.length - 1] : null;
|
|
667
|
+
if (cur) {
|
|
668
|
+
cur.elements.forEach((e) => {
|
|
669
|
+
if (e.missing) return;
|
|
670
|
+
const isChild = /[a-z]$/.test(e.ref ?? "");
|
|
671
|
+
const groupRef = isChild ? e.ref.slice(0, -1) : null;
|
|
672
|
+
if (isChild && vm.expanded !== groupRef) return;
|
|
673
|
+
let target = null;
|
|
674
|
+
try {
|
|
675
|
+
target = document.querySelector(e.selector);
|
|
676
|
+
} catch {
|
|
677
|
+
}
|
|
678
|
+
if (!target) return;
|
|
679
|
+
const r = target.getBoundingClientRect();
|
|
680
|
+
place(el("div", isChild ? "marker child" : "marker"), r.left - 2, r.top - 2, r.width + 4, r.height + 4, e.ref ?? "");
|
|
681
|
+
});
|
|
682
|
+
cur.regions?.forEach((r) => {
|
|
683
|
+
place(el("div", "marker region"), r.rect.x - scrollX, r.rect.y - scrollY, r.rect.w, r.rect.h, r.ref ?? "");
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
const working = vm.locked && vm.connected;
|
|
687
|
+
line.hidden = !working;
|
|
688
|
+
if (working) {
|
|
689
|
+
const wbox = (cls) => {
|
|
690
|
+
const m = el("div", cls);
|
|
691
|
+
const clip = el("div", "clip");
|
|
692
|
+
clip.append(el("span", "sweep"));
|
|
693
|
+
m.append(clip);
|
|
694
|
+
return m;
|
|
695
|
+
};
|
|
696
|
+
for (const b of vm.sent) {
|
|
697
|
+
b.elements.forEach((e) => {
|
|
698
|
+
if (e.missing) return;
|
|
699
|
+
if (/[a-z]$/.test(e.ref ?? "")) return;
|
|
700
|
+
let target = null;
|
|
701
|
+
try {
|
|
702
|
+
target = document.querySelector(e.selector);
|
|
703
|
+
} catch {
|
|
704
|
+
}
|
|
705
|
+
if (!target) return;
|
|
706
|
+
const r = target.getBoundingClientRect();
|
|
707
|
+
place(wbox("wbox"), r.left - 2, r.top - 2, r.width + 4, r.height + 4, e.ref ?? "");
|
|
708
|
+
});
|
|
709
|
+
b.regions?.forEach((r) => {
|
|
710
|
+
place(wbox("wbox region"), r.rect.x - scrollX, r.rect.y - scrollY, r.rect.w, r.rect.h, r.ref ?? "");
|
|
711
|
+
});
|
|
661
712
|
}
|
|
662
|
-
|
|
663
|
-
const r = target.getBoundingClientRect();
|
|
664
|
-
place(el("div", isChild ? "marker child" : "marker"), r.left - 2, r.top - 2, r.width + 4, r.height + 4, e.ref ?? "");
|
|
665
|
-
});
|
|
666
|
-
cur.regions?.forEach((r) => {
|
|
667
|
-
place(el("div", "marker region"), r.rect.x - scrollX, r.rect.y - scrollY, r.rect.w, r.rect.h, r.ref ?? "");
|
|
668
|
-
});
|
|
713
|
+
}
|
|
669
714
|
});
|
|
670
715
|
}
|
|
671
716
|
function flash(selectors) {
|
|
@@ -1125,6 +1170,7 @@ ${Math.round(r.width)}\xD7${Math.round(r.height)}`;
|
|
|
1125
1170
|
agent: session?.agent ?? { status: "idle", text: "" },
|
|
1126
1171
|
strategy: session ? session.strategy ?? session.detected : null,
|
|
1127
1172
|
drafts: drafts ?? [],
|
|
1173
|
+
sent: session?.batches.filter((b) => b.status === "sent") ?? [],
|
|
1128
1174
|
locked: session?.agent.status === "sent" || session?.agent.status === "working",
|
|
1129
1175
|
prefs,
|
|
1130
1176
|
expanded: expandedGroup
|
package/package.json
CHANGED