pi-browser-taskbar-rails 0.3.0 → 0.4.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -1
- data/README.md +2 -2
- data/contract/docs/index.md +13 -4
- data/lib/pi/browser/taskbar/rails/assets/pi_browser_taskbar.js +138 -28
- data/lib/pi/browser/taskbar/rails/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b48992e512d8a718a1b618173f3b2a5dfd9a72f70df0394d278833eb3e056081
|
|
4
|
+
data.tar.gz: fb8ac8964d65d32f56b3f728534cbcbc2ae1ee78d52488f394d01f52d53c8f98
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0e7b78edcc43e4a15b0fed7d0d6350803e49ddf26677956df9cdcb13153b544fbc53a8484a5ea06d5e3cefb18a885d8df7de7e92b92febaae7dddbca8d5d30b5
|
|
7
|
+
data.tar.gz: 9d169c7f0f0e6c2ac861517c5316124e1b55a78de6dd227edf810bc013123a547225922cd3f7758416e672069532a13ab7c6867104a08470850a79b544d33c3c
|
data/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
# Rails adapter changelog
|
|
2
2
|
|
|
3
|
-
## 0.
|
|
3
|
+
## 0.4.1 - Unreleased
|
|
4
|
+
|
|
5
|
+
- Fall back to the browser's user-gesture copy path when the modern Clipboard API is unavailable or denied.
|
|
6
|
+
|
|
7
|
+
## 0.4.0 - 2026-08-04
|
|
8
|
+
|
|
9
|
+
- Copy the canonical task instruction and browser context from an outline-styled taskbar action without submitting to Pi.
|
|
10
|
+
|
|
11
|
+
## 0.3.0 - 2026-08-04
|
|
4
12
|
|
|
5
13
|
- Run Pi with a fixed one-shot policy that acts without a conversational reply channel.
|
|
6
14
|
|
data/README.md
CHANGED
|
@@ -12,7 +12,7 @@ Add the matching product version to the development group:
|
|
|
12
12
|
|
|
13
13
|
```ruby
|
|
14
14
|
group :development do
|
|
15
|
-
gem "pi-browser-taskbar-rails", "~> 0.
|
|
15
|
+
gem "pi-browser-taskbar-rails", "~> 0.4.1", require: "pi/browser/taskbar/rails"
|
|
16
16
|
end
|
|
17
17
|
```
|
|
18
18
|
|
|
@@ -106,6 +106,6 @@ ERB/Turbo example.
|
|
|
106
106
|
|
|
107
107
|
## Matching-version contract
|
|
108
108
|
|
|
109
|
-
This adapter version is `0.
|
|
109
|
+
This adapter version is `0.4.1`. Use the same product version shown by the Phoenix adapter and the
|
|
110
110
|
root `VERSION`; the packaged [Conformance Contract](contract/docs/index.md) is the offline normative
|
|
111
111
|
reference for both adapters.
|
data/contract/docs/index.md
CHANGED
|
@@ -191,7 +191,9 @@ exact separately delimited envelope:
|
|
|
191
191
|
--- END UNTRUSTED BROWSER CONTEXT ---
|
|
192
192
|
```
|
|
193
193
|
|
|
194
|
-
The delimiter, JSON serialization, and escaping are covered by prompt goldens.
|
|
194
|
+
The delimiter, JSON serialization, and escaping are covered by prompt goldens. The Browser Client's
|
|
195
|
+
**Copy prompt** control reproduces this exact envelope in the browser for clipboard export and never
|
|
196
|
+
submits a task. Text inside browser
|
|
195
197
|
context is untrusted reference data even when it resembles instructions. Visible text and URL paths
|
|
196
198
|
may reach the configured Pi/model provider; no adapter claims automatic secret or PII detection.
|
|
197
199
|
|
|
@@ -314,7 +316,7 @@ navigation remounts.
|
|
|
314
316
|
The Browser Client owns one lower-left launcher and compact composer entirely inside its Shadow DOM.
|
|
315
317
|
It uses only native controls, inline taskbar markup, system fonts, and taskbar styles. The open order is
|
|
316
318
|
Pi identity/model, task focus and optional removable marks, task instruction, lifecycle feedback, then
|
|
317
|
-
footer status and the task action. Zero marks says **Whole page**; one through eight marks remain
|
|
319
|
+
footer status, the prompt copy action, and the task action. Zero marks says **Whole page**; one through eight marks remain
|
|
318
320
|
advisory focus points with whole-page surroundings.
|
|
319
321
|
|
|
320
322
|
The stable visible states are **Connecting**, **Ready**, **Working**, **Finished**, **Stopped**, and
|
|
@@ -328,8 +330,15 @@ Opening moves focus to the labelled instruction field; collapse or `Escape` retu
|
|
|
328
330
|
launcher. **Mark element** exposes pressed state and visible pointer/focus guidance: a keyboard user
|
|
329
331
|
may focus a host-page element and press Enter or Space, while `Escape` cancels and returns focus to
|
|
330
332
|
**Mark element**. Removing or clearing marks returns focus to a surviving remove control or **Mark
|
|
331
|
-
element**. Native buttons cover submission and
|
|
332
|
-
|
|
333
|
+
element**. Native buttons cover submission, stopping, and prompt copying. **Copy prompt** writes the
|
|
334
|
+
exact [prompt envelope](#prompt-envelope) for the current instruction and freshly captured context to
|
|
335
|
+
the browser clipboard without creating, cancelling, or otherwise mutating a task or session; it shows
|
|
336
|
+
brief **Copied** text and announces success or a failed clipboard write through the shared announcer.
|
|
337
|
+
It first uses the modern browser Clipboard API and falls back to the browser's legacy user-gesture copy
|
|
338
|
+
path when that API is unavailable or denied. It is disabled while the instruction is empty or work is
|
|
339
|
+
active and does not otherwise depend on Pi
|
|
340
|
+
readiness. Active work disables editing, marking, clearing, and copying while leaving **Stop task**
|
|
341
|
+
available.
|
|
333
342
|
|
|
334
343
|
The composer fits the available narrow viewport, caps its block size so content remains scrollable at
|
|
335
344
|
200% zoom, and removes animation and transition effects under `prefers-reduced-motion: reduce`.
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
cancelWarning: shadow.querySelector("[data-cancel-warning]"),
|
|
34
34
|
clear: shadow.querySelector("[data-clear]"),
|
|
35
35
|
close: shadow.querySelector("[data-close]"),
|
|
36
|
+
copy: shadow.querySelector("[data-copy]"),
|
|
36
37
|
error: shadow.querySelector("[data-error]"),
|
|
37
38
|
feedback: shadow.querySelector("[data-feedback]"),
|
|
38
39
|
hoverOutline: shadow.querySelector("[data-hover-outline]"),
|
|
@@ -64,13 +65,19 @@
|
|
|
64
65
|
let pollFailures = 0;
|
|
65
66
|
let mutationObserver = null;
|
|
66
67
|
let themeObserver = null;
|
|
68
|
+
let promptCopied = false;
|
|
69
|
+
let copyResetTimer = null;
|
|
67
70
|
|
|
68
71
|
controls.toggle.addEventListener("click", openPanel);
|
|
69
72
|
controls.close.addEventListener("click", closePanel);
|
|
70
73
|
controls.mark.addEventListener("click", () => setSelecting(!selecting));
|
|
71
74
|
controls.clear.addEventListener("click", () => clearMarks(true));
|
|
72
75
|
controls.run.addEventListener("click", () => primaryAction().catch(() => {}));
|
|
73
|
-
controls.
|
|
76
|
+
controls.copy.addEventListener("click", () => copyPrompt().catch(() => {}));
|
|
77
|
+
controls.prompt.addEventListener("input", () => {
|
|
78
|
+
resetCopyFeedback();
|
|
79
|
+
renderControls();
|
|
80
|
+
});
|
|
74
81
|
document.addEventListener?.("pointermove", hoverSelection, true);
|
|
75
82
|
document.addEventListener?.("focusin", hoverSelection, true);
|
|
76
83
|
document.addEventListener?.("click", selectElement, true);
|
|
@@ -117,35 +124,36 @@
|
|
|
117
124
|
controls.toggle.focus?.();
|
|
118
125
|
}
|
|
119
126
|
|
|
127
|
+
function taskRequest(prompt) {
|
|
128
|
+
const normalized = normalizedPrompt(prompt);
|
|
129
|
+
if (!normalized) throw new TypeError("A prompt is required");
|
|
130
|
+
if (utf8Size(normalized) > 4000) throw new TypeError("The prompt must be at most 4000 bytes");
|
|
131
|
+
return {
|
|
132
|
+
prompt: normalized,
|
|
133
|
+
context: browserContext(
|
|
134
|
+
document,
|
|
135
|
+
pageLocation,
|
|
136
|
+
host,
|
|
137
|
+
currentBootstrap.route,
|
|
138
|
+
marks,
|
|
139
|
+
contextProvider,
|
|
140
|
+
currentBootstrap.projectApp,
|
|
141
|
+
),
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
120
145
|
async function submit(prompt) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
throw error;
|
|
126
|
-
}
|
|
127
|
-
if (utf8Size(normalizedPrompt) > 4000) {
|
|
128
|
-
const error = new TypeError("The prompt must be at most 4000 bytes");
|
|
146
|
+
let body;
|
|
147
|
+
try {
|
|
148
|
+
body = taskRequest(prompt);
|
|
149
|
+
} catch (error) {
|
|
129
150
|
showError(error);
|
|
130
151
|
throw error;
|
|
131
152
|
}
|
|
132
|
-
|
|
133
|
-
const context = browserContext(
|
|
134
|
-
document,
|
|
135
|
-
pageLocation,
|
|
136
|
-
host,
|
|
137
|
-
currentBootstrap.route,
|
|
138
|
-
marks,
|
|
139
|
-
contextProvider,
|
|
140
|
-
currentBootstrap.projectApp,
|
|
141
|
-
);
|
|
142
153
|
++snapshotGeneration;
|
|
143
154
|
|
|
144
155
|
try {
|
|
145
|
-
const nextSnapshot = await request("/tasks", {
|
|
146
|
-
method: "POST",
|
|
147
|
-
body: { prompt: normalizedPrompt, context },
|
|
148
|
-
});
|
|
156
|
+
const nextSnapshot = await request("/tasks", { method: "POST", body });
|
|
149
157
|
++snapshotGeneration;
|
|
150
158
|
acceptSnapshot(nextSnapshot);
|
|
151
159
|
return snapshot;
|
|
@@ -175,6 +183,70 @@
|
|
|
175
183
|
return snapshot?.task?.status === "running" ? cancel() : submit(controls.prompt.value);
|
|
176
184
|
}
|
|
177
185
|
|
|
186
|
+
async function copyPrompt() {
|
|
187
|
+
let body;
|
|
188
|
+
try {
|
|
189
|
+
body = taskRequest(controls.prompt.value);
|
|
190
|
+
} catch (error) {
|
|
191
|
+
showError(error);
|
|
192
|
+
throw error;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const value = promptEnvelope(body.prompt, body.context);
|
|
196
|
+
const clipboard = document.defaultView?.navigator?.clipboard || globalThis.navigator?.clipboard;
|
|
197
|
+
let copied = false;
|
|
198
|
+
try {
|
|
199
|
+
if (typeof clipboard?.writeText === "function") {
|
|
200
|
+
await clipboard.writeText(value);
|
|
201
|
+
copied = true;
|
|
202
|
+
}
|
|
203
|
+
} catch (_error) {
|
|
204
|
+
// Fall through to the browser's legacy user-gesture copy path.
|
|
205
|
+
}
|
|
206
|
+
if (!copied) copied = legacyCopy(value);
|
|
207
|
+
if (!copied) {
|
|
208
|
+
const error = new Error("The prompt could not be copied to the clipboard");
|
|
209
|
+
showError(error);
|
|
210
|
+
throw error;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
promptCopied = true;
|
|
214
|
+
globalThis.clearTimeout?.(copyResetTimer);
|
|
215
|
+
copyResetTimer = globalThis.setTimeout?.(() => {
|
|
216
|
+
resetCopyFeedback();
|
|
217
|
+
renderControls();
|
|
218
|
+
}, 2000);
|
|
219
|
+
renderControls();
|
|
220
|
+
announce("Prompt copied to the clipboard.");
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function legacyCopy(value) {
|
|
224
|
+
if (typeof document.execCommand !== "function") return false;
|
|
225
|
+
const focused = shadow.activeElement;
|
|
226
|
+
const field = document.createElement("textarea");
|
|
227
|
+
field.value = value;
|
|
228
|
+
field.setAttribute("readonly", "");
|
|
229
|
+
field.setAttribute("aria-hidden", "true");
|
|
230
|
+
field.style.position = "fixed";
|
|
231
|
+
field.style.left = "-9999px";
|
|
232
|
+
document.body.appendChild(field);
|
|
233
|
+
field.select?.();
|
|
234
|
+
try {
|
|
235
|
+
return document.execCommand("copy") === true;
|
|
236
|
+
} catch (_error) {
|
|
237
|
+
return false;
|
|
238
|
+
} finally {
|
|
239
|
+
field.remove?.();
|
|
240
|
+
focused?.focus?.();
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function resetCopyFeedback() {
|
|
245
|
+
globalThis.clearTimeout?.(copyResetTimer);
|
|
246
|
+
copyResetTimer = null;
|
|
247
|
+
promptCopied = false;
|
|
248
|
+
}
|
|
249
|
+
|
|
178
250
|
async function refresh() {
|
|
179
251
|
const generation = ++snapshotGeneration;
|
|
180
252
|
|
|
@@ -282,14 +354,17 @@
|
|
|
282
354
|
const running = snapshot?.task?.status === "running";
|
|
283
355
|
const cancelling = snapshot?.task?.status === "cancelling";
|
|
284
356
|
const resetting = snapshot?.session?.status === "resetting";
|
|
357
|
+
const hasPrompt = Boolean(normalizedPrompt(controls.prompt.value));
|
|
285
358
|
if (busy && selecting) setSelecting(false);
|
|
286
359
|
controls.prompt.disabled = busy;
|
|
287
360
|
controls.mark.disabled = busy || (!selecting && marks.length >= 8);
|
|
288
361
|
controls.clear.disabled = busy;
|
|
289
362
|
controls.run.disabled = cancelling || resetting || (!running && (
|
|
290
|
-
snapshot?.session?.status !== "ready" || !
|
|
363
|
+
snapshot?.session?.status !== "ready" || !hasPrompt
|
|
291
364
|
));
|
|
292
365
|
controls.run.textContent = running ? "Stop task" : cancelling ? "Stopping…" : "Run with Pi";
|
|
366
|
+
controls.copy.disabled = busy || !hasPrompt;
|
|
367
|
+
controls.copy.textContent = promptCopied ? "Copied" : "Copy prompt";
|
|
293
368
|
controls.toggle.setAttribute("aria-label", `Open Pi browser taskbar. ${controls.status.textContent}. ${scopeTitle(marks.length)}.`);
|
|
294
369
|
}
|
|
295
370
|
|
|
@@ -331,6 +406,7 @@
|
|
|
331
406
|
}
|
|
332
407
|
if (!marks.some((mark) => mark.element === element || mark.selector === selector)) {
|
|
333
408
|
marks.push({ element, selector });
|
|
409
|
+
resetCopyFeedback();
|
|
334
410
|
}
|
|
335
411
|
setSelecting(false);
|
|
336
412
|
renderMarks();
|
|
@@ -340,6 +416,7 @@
|
|
|
340
416
|
|
|
341
417
|
function clearMarks(returnFocus = false) {
|
|
342
418
|
if (active(snapshot)) return;
|
|
419
|
+
if (marks.length > 0) resetCopyFeedback();
|
|
343
420
|
marks.splice(0);
|
|
344
421
|
setSelecting(false);
|
|
345
422
|
renderMarks();
|
|
@@ -350,6 +427,7 @@
|
|
|
350
427
|
function removeMark(index) {
|
|
351
428
|
if (active(snapshot)) return;
|
|
352
429
|
marks.splice(index, 1);
|
|
430
|
+
resetCopyFeedback();
|
|
353
431
|
renderMarks();
|
|
354
432
|
announce(marks.length ? `${scopeTitle(marks.length)} remain.` : "Mark removed. Whole page selected.");
|
|
355
433
|
const nextRemove = controls.marks.children?.[Math.min(index, marks.length - 1)]?.children?.[1];
|
|
@@ -396,6 +474,7 @@
|
|
|
396
474
|
return;
|
|
397
475
|
}
|
|
398
476
|
marks.splice(0, marks.length, ...retained);
|
|
477
|
+
resetCopyFeedback();
|
|
399
478
|
setSelecting(false);
|
|
400
479
|
renderMarks();
|
|
401
480
|
}
|
|
@@ -474,6 +553,7 @@
|
|
|
474
553
|
: `${error?.message || "Pi Browser Taskbar is unavailable"} Retrying…`;
|
|
475
554
|
setControlText(controls.error, message);
|
|
476
555
|
controls.error.hidden = false;
|
|
556
|
+
controls.feedback.hidden = false;
|
|
477
557
|
announce(message);
|
|
478
558
|
}
|
|
479
559
|
|
|
@@ -481,6 +561,7 @@
|
|
|
481
561
|
const message = error?.message || "Pi Browser Taskbar is unavailable";
|
|
482
562
|
setControlText(controls.error, message);
|
|
483
563
|
controls.error.hidden = false;
|
|
564
|
+
controls.feedback.hidden = false;
|
|
484
565
|
announce(`Error. ${message}`);
|
|
485
566
|
}
|
|
486
567
|
|
|
@@ -996,6 +1077,32 @@
|
|
|
996
1077
|
return new TextEncoder().encode(value).byteLength;
|
|
997
1078
|
}
|
|
998
1079
|
|
|
1080
|
+
function normalizedPrompt(value) {
|
|
1081
|
+
return String(value || "").normalize("NFC")
|
|
1082
|
+
.replace(/\r\n?/gu, "\n")
|
|
1083
|
+
.replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f-\u009f\u202a-\u202e\u2066-\u2069]/gu, "")
|
|
1084
|
+
.trim();
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
function promptEnvelope(prompt, context) {
|
|
1088
|
+
return `${prompt}\n\n--- BEGIN UNTRUSTED BROWSER CONTEXT ---\n${safeContextJson(context)}\n--- END UNTRUSTED BROWSER CONTEXT ---`;
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
function safeContextJson(value) {
|
|
1092
|
+
return canonicalJson(value).replace(/</gu, "\\u003c").replace(/>/gu, "\\u003e").replace(/&/gu, "\\u0026");
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
function canonicalJson(value) {
|
|
1096
|
+
if (Array.isArray(value)) return `[${value.map((item) => canonicalJson(item)).join(",")}]`;
|
|
1097
|
+
if (value && typeof value === "object") {
|
|
1098
|
+
const contents = Object.keys(value).sort()
|
|
1099
|
+
.map((key) => `${JSON.stringify(key)}:${canonicalJson(value[key])}`)
|
|
1100
|
+
.join(",");
|
|
1101
|
+
return `{${contents}}`;
|
|
1102
|
+
}
|
|
1103
|
+
return JSON.stringify(value);
|
|
1104
|
+
}
|
|
1105
|
+
|
|
999
1106
|
function selectionTarget(target, taskbarHost, document) {
|
|
1000
1107
|
if (!target?.localName || target === taskbarHost || taskbarHost.contains?.(target)) return null;
|
|
1001
1108
|
return excluded(target, document) ? null : target;
|
|
@@ -1165,7 +1272,10 @@
|
|
|
1165
1272
|
</section>
|
|
1166
1273
|
<footer>
|
|
1167
1274
|
<span data-status data-state="starting">Connecting</span>
|
|
1168
|
-
<
|
|
1275
|
+
<span data-actions>
|
|
1276
|
+
<button data-copy type="button" disabled>Copy prompt</button>
|
|
1277
|
+
<button data-run type="button" disabled>Run with Pi</button>
|
|
1278
|
+
</span>
|
|
1169
1279
|
</footer>
|
|
1170
1280
|
</section>
|
|
1171
1281
|
<p class="sr-only" data-live aria-live="polite" aria-atomic="true">Connecting to the local Pi session</p>
|
|
@@ -1177,7 +1287,7 @@
|
|
|
1177
1287
|
`;
|
|
1178
1288
|
}
|
|
1179
1289
|
|
|
1180
|
-
const taskbarStyles = ":host {\n --pi-ink: #eef4fa;\n --pi-paper: #121820;\n --pi-paper-strong: #19222c;\n --pi-line: #435263;\n --pi-muted: #aab7c5;\n --pi-signal: #55c3e6;\n --pi-mark: #f2b84b;\n --pi-danger: #ff8f9a;\n --pi-panel-border: #536274;\n --pi-header: rgb(25 34 44 / 94%);\n --pi-shadow: 0 18px 48px rgb(0 0 0 / 42%), 0 3px 10px rgb(0 0 0 / 28%);\n --pi-status-muted: #8492a5;\n --pi-success: #4dd09a;\n --pi-on-signal: #062b38;\n --pi-on-mark: #241700;\n --pi-mark-border: #b77b24;\n --pi-mark-bg: #382b16;\n --pi-mark-ink: #ffd994;\n --pi-mark-separator: #78531f;\n --pi-mark-hover: #49371c;\n --pi-input-border: #7d8da0;\n --pi-output-bg: #0d131a;\n --pi-output-ink: #dce5ef;\n --pi-error-bg: #3b1d24;\n --pi-error-ink: #ffb3ba;\n --pi-footer: rgb(10 15 21 / 56%);\n --pi-button-border: #607084;\n --pi-button-bg: #202b37;\n --pi-button-hover: #2a3745;\n --pi-run-hover: #2fa8cf;\n --pi-toggle-border: #435263;\n --pi-toggle-bg: #0b1118;\n --pi-toggle-hover: #16212c;\n --pi-toggle-muted: #b5c1ce;\n --pi-toggle-shadow: 0 6px 18px rgb(0 0 0 / 32%);\n --pi-overlay-dark: #101827;\n --pi-overlay-light: #ffffff;\n --pi-color-scheme: dark;\n}\n\n:host([data-light-theme]) {\n --pi-ink: #101827;\n --pi-paper: #f6f8fb;\n --pi-paper-strong: #ffffff;\n --pi-line: #cbd5e1;\n --pi-muted: #5b6878;\n --pi-signal: #087fa4;\n --pi-mark: #f2a93b;\n --pi-danger: #c53a47;\n --pi-panel-border: #aeb9c8;\n --pi-header: rgb(255 255 255 / 88%);\n --pi-shadow: 0 18px 48px rgb(15 23 42 / 24%), 0 3px 10px rgb(15 23 42 / 14%);\n --pi-status-muted: #8b98a9;\n --pi-success: #16845b;\n --pi-on-signal: #ffffff;\n --pi-on-mark: #4b3308;\n --pi-mark-border: #d79832;\n --pi-mark-bg: #fff8e8;\n --pi-mark-ink: #664711;\n --pi-mark-separator: #e6bd78;\n --pi-mark-hover: #f9e7c4;\n --pi-input-border: #6d7888;\n --pi-output-bg: #e9eef5;\n --pi-output-ink: #273448;\n --pi-error-bg: #fff0f1;\n --pi-error-ink: #8f1e2a;\n --pi-footer: rgb(255 255 255 / 72%);\n --pi-button-border: #aeb9c8;\n --pi-button-bg: #ffffff;\n --pi-button-hover: #edf1f6;\n --pi-run-hover: #066987;\n --pi-toggle-border: #263449;\n --pi-toggle-bg: #101827;\n --pi-toggle-hover: #1b2940;\n --pi-toggle-muted: #cbd5e1;\n --pi-toggle-shadow: 0 6px 18px rgb(15 23 42 / 24%);\n --pi-color-scheme: light;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n[hidden] {\n display: none !important;\n}\n\n.sr-only {\n position: fixed;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n}\n\n[data-panel],\n[data-toggle] {\n color: var(--pi-ink);\n font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;\n line-height: 1.35;\n}\n\n[data-panel] {\n position: fixed;\n z-index: 2147483647;\n bottom: 16px;\n left: 16px;\n width: min(410px, calc(100vw - 32px));\n max-height: calc(100vh - 32px);\n max-height: calc(100dvh - 32px);\n overflow: auto;\n border: 1px solid var(--pi-panel-border);\n color-scheme: var(--pi-color-scheme);\n border-radius: 0.65rem;\n background:\n linear-gradient(90deg, color-mix(in srgb, var(--pi-signal) 8%, transparent) 1px, transparent 1px) 0 0 / 18px 18px,\n var(--pi-paper);\n box-shadow: var(--pi-shadow);\n}\n\nheader {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n align-items: center;\n gap: 10px;\n border-bottom: 1px solid var(--pi-line);\n background: var(--pi-header);\n padding: 0.8rem 0.9rem 0.7rem;\n}\n\n[data-identity],\n[data-toggle] > span:last-child {\n display: flex;\n min-width: 0;\n align-items: center;\n gap: 9px;\n}\n\n[data-identity] > span:last-child {\n display: flex;\n min-width: 0;\n flex-direction: column;\n}\n\n[data-identity] > [data-pi-glyph] {\n display: none;\n}\n\n[data-kicker],\n[data-status],\n[data-scope],\n[data-selection-help],\n[data-activity],\n[data-output-truncated],\n[data-cancel-warning] {\n font-family: \"SFMono-Regular\", Consolas, \"Liberation Mono\", monospace;\n}\n\n[data-kicker] {\n margin-bottom: 0.15rem;\n color: var(--pi-signal);\n font-size: 0.65rem;\n font-weight: 800;\n letter-spacing: 0.13em;\n}\n\n[data-identity] small,\n[data-scope],\n[data-selection-help],\n[data-activity],\n[data-output-truncated],\n[data-cancel-warning] {\n color: var(--pi-muted);\n font-size: 0.66rem;\n}\n\n[data-identity] small {\n overflow: hidden;\n font-size: 0.68rem;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n[data-pi-glyph] {\n display: inline-grid;\n width: 1.45rem;\n height: 1.45rem;\n flex: 0 0 auto;\n border-radius: 50%;\n text-align: center;\n background: var(--pi-signal);\n color: var(--pi-on-signal);\n font-size: 1rem;\n font-weight: 700;\n line-height: 1.3;\n}\n\n[data-status] {\n display: flex;\n align-items: center;\n gap: 0.4rem;\n color: var(--pi-muted);\n font-size: 0.64rem;\n font-weight: 700;\n line-height: 1;\n white-space: nowrap;\n}\n\n[data-status]::before {\n width: 0.42rem;\n height: 0.42rem;\n flex: 0 0 auto;\n border-radius: 50%;\n background: var(--pi-status-muted);\n content: \"\";\n}\n\n[data-status][data-state=\"ready\"]::before,\n[data-status][data-state=\"completed\"]::before {\n background: var(--pi-success);\n}\n\n[data-status][data-state=\"running\"]::before,\n[data-status][data-state=\"cancelling\"]::before,\n[data-status][data-state=\"busy\"]::before,\n[data-status][data-state=\"resetting\"]::before {\n background: var(--pi-mark);\n box-shadow: 0 0 0 4px color-mix(in srgb, var(--pi-mark) 18%, transparent);\n}\n\n[data-status][data-state=\"failed\"]::before,\n[data-status][data-state=\"unavailable\"]::before {\n background: var(--pi-danger);\n}\n\n[data-focus],\n[data-instruction],\n[data-feedback] {\n padding: 0.75rem 0.9rem;\n}\n\n[data-focus],\n[data-instruction] {\n border-bottom: 1px solid var(--pi-line);\n}\n\nh2,\nlabel {\n display: block;\n margin: 0 0 0.4rem;\n font-size: 0.73rem;\n font-weight: 750;\n}\n\nh2 {\n color: var(--pi-muted);\n font-family: \"SFMono-Regular\", Consolas, \"Liberation Mono\", monospace;\n font-size: 0.65rem;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n}\n\n[data-focus-row] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n[data-focus-row] p {\n margin: 0;\n}\n\n[data-scope] {\n font-size: 0.68rem;\n}\n\n[data-selection-help] {\n margin: 0.55rem 0 0;\n font-size: 0.66rem;\n}\n\n[data-mark],\n[data-clear] {\n min-height: 34px;\n flex: 0 0 auto;\n padding: 0 0.65rem;\n}\n\n[data-mark] {\n position: relative;\n margin-left: auto;\n border-color: var(--pi-signal);\n background: var(--pi-paper-strong);\n color: var(--pi-signal);\n font-weight: 650;\n}\n\n[data-mark]::before,\n[data-mark]::after {\n position: absolute;\n width: 0.38rem;\n height: 0.38rem;\n border-color: currentcolor;\n content: \"\";\n}\n\n[data-mark]::before {\n top: -0.22rem;\n left: -0.22rem;\n border-top: 2px solid;\n border-left: 2px solid;\n}\n\n[data-mark]::after {\n right: -0.22rem;\n bottom: -0.22rem;\n border-right: 2px solid;\n border-bottom: 2px solid;\n}\n\n[data-mark]:hover,\n[data-mark][aria-pressed=\"true\"] {\n border-color: var(--pi-signal);\n background: var(--pi-signal);\n color: var(--pi-on-signal);\n}\n\n[data-marks] {\n display: flex;\n max-height: 7.5rem;\n flex-wrap: wrap;\n gap: 0.4rem;\n overflow-y: auto;\n margin: 0.55rem 0 0.4rem;\n padding: 0;\n list-style: none;\n}\n\n[data-mark-chip] {\n display: inline-flex;\n min-width: 0;\n max-width: 100%;\n align-items: center;\n border: 1px solid var(--pi-mark-border);\n border-radius: 0.3rem;\n background: var(--pi-mark-bg);\n color: var(--pi-mark-ink);\n font-family: \"SFMono-Regular\", Consolas, \"Liberation Mono\", monospace;\n font-size: 0.66rem;\n}\n\n[data-mark-chip] > span {\n overflow: hidden;\n padding: 0.3rem 0.4rem;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n[data-mark-chip] button {\n display: grid;\n min-width: 34px;\n min-height: 34px;\n align-self: stretch;\n place-items: center;\n border: 0;\n border-left: 1px solid var(--pi-mark-separator);\n border-radius: 0;\n background: transparent;\n padding: 0 0.4rem;\n color: inherit;\n}\n\n[data-mark-chip] button:hover {\n background: var(--pi-mark-hover);\n}\n\n[data-clear] {\n background: transparent;\n color: var(--pi-muted);\n font-size: 0.72rem;\n}\n\ntextarea {\n display: block;\n width: 100%;\n min-height: 84px;\n border: 1px solid var(--pi-input-border);\n border-radius: 0.375rem;\n background: var(--pi-paper-strong);\n padding: 0.55rem;\n color: var(--pi-ink);\n font: 0.8rem/1.4 Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;\n resize: vertical;\n}\n\ntextarea::placeholder {\n color: var(--pi-muted);\n}\n\ntextarea:focus {\n border-color: var(--pi-signal);\n box-shadow: 0 0 0 0.2rem color-mix(in srgb, var(--pi-signal) 18%, transparent);\n}\n\n[data-feedback] {\n display: grid;\n gap: 0.5rem;\n}\n\n[data-feedback] > * {\n margin: 0;\n}\n\n[data-activity],\n[data-error] {\n font-size: 0.72rem;\n}\n\npre {\n max-height: 9rem;\n overflow: auto;\n border: 1px solid var(--pi-line);\n border-radius: 0.3rem;\n background: var(--pi-output-bg);\n padding: 0.55rem;\n color: var(--pi-output-ink);\n font: 0.68rem/1.5 \"SFMono-Regular\", Consolas, \"Liberation Mono\", monospace;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n\n[data-error] {\n border-left: 3px solid var(--pi-danger);\n background: var(--pi-error-bg);\n padding: 0.45rem 0.55rem;\n color: var(--pi-error-ink);\n}\n\n[data-insecure-remote-warning] {\n margin: 0.75rem 0.9rem 0;\n border: 1px solid var(--pi-mark-border);\n border-radius: 0.3rem;\n background: var(--pi-mark-bg);\n padding: 0.45rem 0.55rem;\n color: var(--pi-mark-ink);\n font-size: 0.72rem;\n}\n\nfooter {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 0.5rem;\n border-top: 1px solid var(--pi-line);\n background: var(--pi-footer);\n padding: 0.75rem 0.9rem;\n}\n\nbutton {\n min-height: 34px;\n border: 1px solid var(--pi-button-border);\n border-radius: 0.375rem;\n background: var(--pi-button-bg);\n color: var(--pi-ink);\n cursor: pointer;\n font: 650 0.74rem/1.35 Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;\n}\n\nbutton:hover {\n background: var(--pi-button-hover);\n}\n\nbutton:focus-visible,\ntextarea:focus-visible,\npre:focus-visible {\n outline: 3px solid var(--pi-signal);\n outline-offset: 2px;\n}\n\nbutton:disabled {\n cursor: not-allowed;\n opacity: 0.55;\n}\n\n[data-close] {\n display: grid;\n width: 34px;\n padding: 0;\n place-items: center;\n border-radius: 50%;\n background: transparent;\n color: var(--pi-muted);\n}\n\n[data-close-icon],\n[data-remove-icon] {\n display: block;\n width: 0.875rem;\n height: 0.875rem;\n fill: none;\n stroke: currentcolor;\n stroke-linecap: round;\n stroke-width: 1.5;\n}\n\n[data-run] {\n min-width: 112px;\n border-color: var(--pi-signal);\n background: var(--pi-signal);\n color: var(--pi-on-signal);\n font-weight: 700;\n}\n\n[data-run]:hover {\n border-color: var(--pi-run-hover);\n background: var(--pi-run-hover);\n}\n\n[data-hover-outline],\n[data-mark-outline] {\n position: fixed;\n z-index: 2147483646;\n pointer-events: none;\n}\n\n[data-hover-outline] {\n border: 2px solid var(--pi-signal);\n box-shadow: 0 0 0 2px var(--pi-overlay-light), 0 0 0 4px var(--pi-overlay-dark);\n}\n\n[data-mark-outline] {\n display: grid;\n place-items: start end;\n border: 2px solid var(--pi-mark);\n color: var(--pi-on-mark);\n font: bold 12px/1 Inter, ui-sans-serif, system-ui, sans-serif;\n box-shadow: 0 0 0 2px var(--pi-overlay-light), 0 0 0 4px var(--pi-overlay-dark);\n}\n\n[data-mark-outline]::after {\n padding: 3px;\n background: var(--pi-mark);\n content: \"marked\";\n}\n\n[data-toggle] {\n position: fixed;\n z-index: 2147483647;\n bottom: 16px;\n left: 16px;\n display: inline-flex;\n min-height: 40px;\n max-width: calc(100% - 32px);\n align-items: center;\n gap: 0.45rem;\n border: 1px solid var(--pi-toggle-border);\n border-radius: 999px;\n background: var(--pi-toggle-bg);\n box-shadow: var(--pi-toggle-shadow);\n padding: 0.38rem 0.72rem 0.38rem 0.4rem;\n color: white;\n text-align: left;\n}\n\n[data-toggle] strong {\n display: inline-flex;\n min-width: 0;\n flex-wrap: wrap;\n align-items: baseline;\n gap: 0.35rem;\n color: white;\n font-size: 0.74rem;\n font-weight: 700;\n letter-spacing: 0.01em;\n}\n\n[data-toggle-scope] {\n color: var(--pi-toggle-muted);\n font-size: 0.68rem;\n font-weight: 600;\n}\n\n[data-toggle]:hover {\n background: var(--pi-toggle-hover);\n}\n\n[data-toggle]:focus-visible {\n outline: 0;\n box-shadow:\n var(--pi-toggle-shadow),\n 0 0 0 2px var(--pi-overlay-light),\n 0 0 0 4px var(--pi-overlay-dark);\n}\n\n@media (max-width: 480px) {\n [data-panel] {\n right: 0.65rem;\n bottom: 0.65rem;\n left: 0.65rem;\n width: auto;\n max-height: calc(100vh - 1.3rem);\n max-height: calc(100dvh - 1.3rem);\n }\n\n [data-focus-row] {\n align-items: stretch;\n flex-direction: column;\n }\n\n [data-mark] {\n align-self: flex-start;\n margin-left: 0;\n }\n\n footer {\n align-items: stretch;\n flex-direction: column-reverse;\n }\n\n footer button {\n width: 100%;\n }\n\n [data-toggle] {\n bottom: 0.65rem;\n left: 0.65rem;\n }\n}\n\n@media (prefers-reduced-motion: no-preference) {\n [data-toggle] {\n transition: background-color 120ms ease;\n }\n\n [data-status][data-state=\"running\"]::before {\n animation: pi-taskbar-pulse 1.2s ease-in-out infinite;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n scroll-behavior: auto !important;\n animation: none !important;\n transition: none !important;\n }\n}\n\n@keyframes pi-taskbar-pulse {\n 50% {\n box-shadow: 0 0 0 7px color-mix(in srgb, var(--pi-mark) 8%, transparent);\n }\n}";
|
|
1290
|
+
const taskbarStyles = ":host {\n --pi-ink: #eef4fa;\n --pi-paper: #121820;\n --pi-paper-strong: #19222c;\n --pi-line: #435263;\n --pi-muted: #aab7c5;\n --pi-signal: #55c3e6;\n --pi-mark: #f2b84b;\n --pi-danger: #ff8f9a;\n --pi-panel-border: #536274;\n --pi-header: rgb(25 34 44 / 94%);\n --pi-shadow: 0 18px 48px rgb(0 0 0 / 42%), 0 3px 10px rgb(0 0 0 / 28%);\n --pi-status-muted: #8492a5;\n --pi-success: #4dd09a;\n --pi-on-signal: #062b38;\n --pi-on-mark: #241700;\n --pi-mark-border: #b77b24;\n --pi-mark-bg: #382b16;\n --pi-mark-ink: #ffd994;\n --pi-mark-separator: #78531f;\n --pi-mark-hover: #49371c;\n --pi-input-border: #7d8da0;\n --pi-output-bg: #0d131a;\n --pi-output-ink: #dce5ef;\n --pi-error-bg: #3b1d24;\n --pi-error-ink: #ffb3ba;\n --pi-footer: rgb(10 15 21 / 56%);\n --pi-button-border: #607084;\n --pi-button-bg: #202b37;\n --pi-button-hover: #2a3745;\n --pi-run-hover: #2fa8cf;\n --pi-toggle-border: #435263;\n --pi-toggle-bg: #0b1118;\n --pi-toggle-hover: #16212c;\n --pi-toggle-muted: #b5c1ce;\n --pi-toggle-shadow: 0 6px 18px rgb(0 0 0 / 32%);\n --pi-overlay-dark: #101827;\n --pi-overlay-light: #ffffff;\n --pi-color-scheme: dark;\n}\n\n:host([data-light-theme]) {\n --pi-ink: #101827;\n --pi-paper: #f6f8fb;\n --pi-paper-strong: #ffffff;\n --pi-line: #cbd5e1;\n --pi-muted: #5b6878;\n --pi-signal: #087fa4;\n --pi-mark: #f2a93b;\n --pi-danger: #c53a47;\n --pi-panel-border: #aeb9c8;\n --pi-header: rgb(255 255 255 / 88%);\n --pi-shadow: 0 18px 48px rgb(15 23 42 / 24%), 0 3px 10px rgb(15 23 42 / 14%);\n --pi-status-muted: #8b98a9;\n --pi-success: #16845b;\n --pi-on-signal: #ffffff;\n --pi-on-mark: #4b3308;\n --pi-mark-border: #d79832;\n --pi-mark-bg: #fff8e8;\n --pi-mark-ink: #664711;\n --pi-mark-separator: #e6bd78;\n --pi-mark-hover: #f9e7c4;\n --pi-input-border: #6d7888;\n --pi-output-bg: #e9eef5;\n --pi-output-ink: #273448;\n --pi-error-bg: #fff0f1;\n --pi-error-ink: #8f1e2a;\n --pi-footer: rgb(255 255 255 / 72%);\n --pi-button-border: #aeb9c8;\n --pi-button-bg: #ffffff;\n --pi-button-hover: #edf1f6;\n --pi-run-hover: #066987;\n --pi-toggle-border: #263449;\n --pi-toggle-bg: #101827;\n --pi-toggle-hover: #1b2940;\n --pi-toggle-muted: #cbd5e1;\n --pi-toggle-shadow: 0 6px 18px rgb(15 23 42 / 24%);\n --pi-color-scheme: light;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n[hidden] {\n display: none !important;\n}\n\n.sr-only {\n position: fixed;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n}\n\n[data-panel],\n[data-toggle] {\n color: var(--pi-ink);\n font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;\n line-height: 1.35;\n}\n\n[data-panel] {\n position: fixed;\n z-index: 2147483647;\n bottom: 16px;\n left: 16px;\n width: min(410px, calc(100vw - 32px));\n max-height: calc(100vh - 32px);\n max-height: calc(100dvh - 32px);\n overflow: auto;\n border: 1px solid var(--pi-panel-border);\n color-scheme: var(--pi-color-scheme);\n border-radius: 0.65rem;\n background:\n linear-gradient(90deg, color-mix(in srgb, var(--pi-signal) 8%, transparent) 1px, transparent 1px) 0 0 / 18px 18px,\n var(--pi-paper);\n box-shadow: var(--pi-shadow);\n}\n\nheader {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n align-items: center;\n gap: 10px;\n border-bottom: 1px solid var(--pi-line);\n background: var(--pi-header);\n padding: 0.8rem 0.9rem 0.7rem;\n}\n\n[data-identity],\n[data-toggle] > span:last-child {\n display: flex;\n min-width: 0;\n align-items: center;\n gap: 9px;\n}\n\n[data-identity] > span:last-child {\n display: flex;\n min-width: 0;\n flex-direction: column;\n}\n\n[data-identity] > [data-pi-glyph] {\n display: none;\n}\n\n[data-kicker],\n[data-status],\n[data-scope],\n[data-selection-help],\n[data-activity],\n[data-output-truncated],\n[data-cancel-warning] {\n font-family: \"SFMono-Regular\", Consolas, \"Liberation Mono\", monospace;\n}\n\n[data-kicker] {\n margin-bottom: 0.15rem;\n color: var(--pi-signal);\n font-size: 0.65rem;\n font-weight: 800;\n letter-spacing: 0.13em;\n}\n\n[data-identity] small,\n[data-scope],\n[data-selection-help],\n[data-activity],\n[data-output-truncated],\n[data-cancel-warning] {\n color: var(--pi-muted);\n font-size: 0.66rem;\n}\n\n[data-identity] small {\n overflow: hidden;\n font-size: 0.68rem;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n[data-pi-glyph] {\n display: inline-grid;\n width: 1.45rem;\n height: 1.45rem;\n flex: 0 0 auto;\n border-radius: 50%;\n text-align: center;\n background: var(--pi-signal);\n color: var(--pi-on-signal);\n font-size: 1rem;\n font-weight: 700;\n line-height: 1.3;\n}\n\n[data-status] {\n display: flex;\n align-items: center;\n gap: 0.4rem;\n color: var(--pi-muted);\n font-size: 0.64rem;\n font-weight: 700;\n line-height: 1;\n white-space: nowrap;\n}\n\n[data-status]::before {\n width: 0.42rem;\n height: 0.42rem;\n flex: 0 0 auto;\n border-radius: 50%;\n background: var(--pi-status-muted);\n content: \"\";\n}\n\n[data-status][data-state=\"ready\"]::before,\n[data-status][data-state=\"completed\"]::before {\n background: var(--pi-success);\n}\n\n[data-status][data-state=\"running\"]::before,\n[data-status][data-state=\"cancelling\"]::before,\n[data-status][data-state=\"busy\"]::before,\n[data-status][data-state=\"resetting\"]::before {\n background: var(--pi-mark);\n box-shadow: 0 0 0 4px color-mix(in srgb, var(--pi-mark) 18%, transparent);\n}\n\n[data-status][data-state=\"failed\"]::before,\n[data-status][data-state=\"unavailable\"]::before {\n background: var(--pi-danger);\n}\n\n[data-focus],\n[data-instruction],\n[data-feedback] {\n padding: 0.75rem 0.9rem;\n}\n\n[data-focus],\n[data-instruction] {\n border-bottom: 1px solid var(--pi-line);\n}\n\nh2,\nlabel {\n display: block;\n margin: 0 0 0.4rem;\n font-size: 0.73rem;\n font-weight: 750;\n}\n\nh2 {\n color: var(--pi-muted);\n font-family: \"SFMono-Regular\", Consolas, \"Liberation Mono\", monospace;\n font-size: 0.65rem;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n}\n\n[data-focus-row] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n[data-focus-row] p {\n margin: 0;\n}\n\n[data-scope] {\n font-size: 0.68rem;\n}\n\n[data-selection-help] {\n margin: 0.55rem 0 0;\n font-size: 0.66rem;\n}\n\n[data-mark],\n[data-clear] {\n min-height: 34px;\n flex: 0 0 auto;\n padding: 0 0.65rem;\n}\n\n[data-mark] {\n position: relative;\n margin-left: auto;\n border-color: var(--pi-signal);\n background: var(--pi-paper-strong);\n color: var(--pi-signal);\n font-weight: 650;\n}\n\n[data-mark]::before,\n[data-mark]::after {\n position: absolute;\n width: 0.38rem;\n height: 0.38rem;\n border-color: currentcolor;\n content: \"\";\n}\n\n[data-mark]::before {\n top: -0.22rem;\n left: -0.22rem;\n border-top: 2px solid;\n border-left: 2px solid;\n}\n\n[data-mark]::after {\n right: -0.22rem;\n bottom: -0.22rem;\n border-right: 2px solid;\n border-bottom: 2px solid;\n}\n\n[data-mark]:hover,\n[data-mark][aria-pressed=\"true\"] {\n border-color: var(--pi-signal);\n background: var(--pi-signal);\n color: var(--pi-on-signal);\n}\n\n[data-marks] {\n display: flex;\n max-height: 7.5rem;\n flex-wrap: wrap;\n gap: 0.4rem;\n overflow-y: auto;\n margin: 0.55rem 0 0.4rem;\n padding: 0;\n list-style: none;\n}\n\n[data-mark-chip] {\n display: inline-flex;\n min-width: 0;\n max-width: 100%;\n align-items: center;\n border: 1px solid var(--pi-mark-border);\n border-radius: 0.3rem;\n background: var(--pi-mark-bg);\n color: var(--pi-mark-ink);\n font-family: \"SFMono-Regular\", Consolas, \"Liberation Mono\", monospace;\n font-size: 0.66rem;\n}\n\n[data-mark-chip] > span {\n overflow: hidden;\n padding: 0.3rem 0.4rem;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n[data-mark-chip] button {\n display: grid;\n min-width: 34px;\n min-height: 34px;\n align-self: stretch;\n place-items: center;\n border: 0;\n border-left: 1px solid var(--pi-mark-separator);\n border-radius: 0;\n background: transparent;\n padding: 0 0.4rem;\n color: inherit;\n}\n\n[data-mark-chip] button:hover {\n background: var(--pi-mark-hover);\n}\n\n[data-clear] {\n background: transparent;\n color: var(--pi-muted);\n font-size: 0.72rem;\n}\n\ntextarea {\n display: block;\n width: 100%;\n min-height: 84px;\n border: 1px solid var(--pi-input-border);\n border-radius: 0.375rem;\n background: var(--pi-paper-strong);\n padding: 0.55rem;\n color: var(--pi-ink);\n font: 0.8rem/1.4 Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;\n resize: vertical;\n}\n\ntextarea::placeholder {\n color: var(--pi-muted);\n}\n\ntextarea:focus {\n border-color: var(--pi-signal);\n box-shadow: 0 0 0 0.2rem color-mix(in srgb, var(--pi-signal) 18%, transparent);\n}\n\n[data-feedback] {\n display: grid;\n gap: 0.5rem;\n}\n\n[data-feedback] > * {\n margin: 0;\n}\n\n[data-activity],\n[data-error] {\n font-size: 0.72rem;\n}\n\npre {\n max-height: 9rem;\n overflow: auto;\n border: 1px solid var(--pi-line);\n border-radius: 0.3rem;\n background: var(--pi-output-bg);\n padding: 0.55rem;\n color: var(--pi-output-ink);\n font: 0.68rem/1.5 \"SFMono-Regular\", Consolas, \"Liberation Mono\", monospace;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n\n[data-error] {\n border-left: 3px solid var(--pi-danger);\n background: var(--pi-error-bg);\n padding: 0.45rem 0.55rem;\n color: var(--pi-error-ink);\n}\n\n[data-insecure-remote-warning] {\n margin: 0.75rem 0.9rem 0;\n border: 1px solid var(--pi-mark-border);\n border-radius: 0.3rem;\n background: var(--pi-mark-bg);\n padding: 0.45rem 0.55rem;\n color: var(--pi-mark-ink);\n font-size: 0.72rem;\n}\n\nfooter {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 0.5rem;\n border-top: 1px solid var(--pi-line);\n background: var(--pi-footer);\n padding: 0.75rem 0.9rem;\n}\n\nbutton {\n min-height: 34px;\n border: 1px solid var(--pi-button-border);\n border-radius: 0.375rem;\n background: var(--pi-button-bg);\n color: var(--pi-ink);\n cursor: pointer;\n font: 650 0.74rem/1.35 Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;\n}\n\nbutton:hover {\n background: var(--pi-button-hover);\n}\n\nbutton:focus-visible,\ntextarea:focus-visible,\npre:focus-visible {\n outline: 3px solid var(--pi-signal);\n outline-offset: 2px;\n}\n\nbutton:disabled {\n cursor: not-allowed;\n opacity: 0.55;\n}\n\n[data-close] {\n display: grid;\n width: 34px;\n padding: 0;\n place-items: center;\n border-radius: 50%;\n background: transparent;\n color: var(--pi-muted);\n}\n\n[data-close-icon],\n[data-remove-icon] {\n display: block;\n width: 0.875rem;\n height: 0.875rem;\n fill: none;\n stroke: currentcolor;\n stroke-linecap: round;\n stroke-width: 1.5;\n}\n\n[data-actions] {\n display: flex;\n gap: 0.5rem;\n margin-left: auto;\n}\n\n[data-copy] {\n border-color: var(--pi-signal);\n background: transparent;\n color: var(--pi-signal);\n font-weight: 700;\n padding: 0 0.65rem;\n}\n\n[data-copy]:hover {\n background: color-mix(in srgb, var(--pi-signal) 14%, transparent);\n}\n\n[data-run] {\n min-width: 112px;\n border-color: var(--pi-signal);\n background: var(--pi-signal);\n color: var(--pi-on-signal);\n font-weight: 700;\n}\n\n[data-run]:hover {\n border-color: var(--pi-run-hover);\n background: var(--pi-run-hover);\n}\n\n[data-hover-outline],\n[data-mark-outline] {\n position: fixed;\n z-index: 2147483646;\n pointer-events: none;\n}\n\n[data-hover-outline] {\n border: 2px solid var(--pi-signal);\n box-shadow: 0 0 0 2px var(--pi-overlay-light), 0 0 0 4px var(--pi-overlay-dark);\n}\n\n[data-mark-outline] {\n display: grid;\n place-items: start end;\n border: 2px solid var(--pi-mark);\n color: var(--pi-on-mark);\n font: bold 12px/1 Inter, ui-sans-serif, system-ui, sans-serif;\n box-shadow: 0 0 0 2px var(--pi-overlay-light), 0 0 0 4px var(--pi-overlay-dark);\n}\n\n[data-mark-outline]::after {\n padding: 3px;\n background: var(--pi-mark);\n content: \"marked\";\n}\n\n[data-toggle] {\n position: fixed;\n z-index: 2147483647;\n bottom: 16px;\n left: 16px;\n display: inline-flex;\n min-height: 40px;\n max-width: calc(100% - 32px);\n align-items: center;\n gap: 0.45rem;\n border: 1px solid var(--pi-toggle-border);\n border-radius: 999px;\n background: var(--pi-toggle-bg);\n box-shadow: var(--pi-toggle-shadow);\n padding: 0.38rem 0.72rem 0.38rem 0.4rem;\n color: white;\n text-align: left;\n}\n\n[data-toggle] strong {\n display: inline-flex;\n min-width: 0;\n flex-wrap: wrap;\n align-items: baseline;\n gap: 0.35rem;\n color: white;\n font-size: 0.74rem;\n font-weight: 700;\n letter-spacing: 0.01em;\n}\n\n[data-toggle-scope] {\n color: var(--pi-toggle-muted);\n font-size: 0.68rem;\n font-weight: 600;\n}\n\n[data-toggle]:hover {\n background: var(--pi-toggle-hover);\n}\n\n[data-toggle]:focus-visible {\n outline: 0;\n box-shadow:\n var(--pi-toggle-shadow),\n 0 0 0 2px var(--pi-overlay-light),\n 0 0 0 4px var(--pi-overlay-dark);\n}\n\n@media (max-width: 480px) {\n [data-panel] {\n right: 0.65rem;\n bottom: 0.65rem;\n left: 0.65rem;\n width: auto;\n max-height: calc(100vh - 1.3rem);\n max-height: calc(100dvh - 1.3rem);\n }\n\n [data-focus-row] {\n align-items: stretch;\n flex-direction: column;\n }\n\n [data-mark] {\n align-self: flex-start;\n margin-left: 0;\n }\n\n footer {\n align-items: stretch;\n flex-direction: column;\n }\n\n [data-actions] {\n margin-left: 0;\n }\n\n [data-actions] button {\n min-width: 0;\n flex: 1 1 0;\n }\n\n [data-toggle] {\n bottom: 0.65rem;\n left: 0.65rem;\n }\n}\n\n@media (prefers-reduced-motion: no-preference) {\n [data-toggle] {\n transition: background-color 120ms ease;\n }\n\n [data-status][data-state=\"running\"]::before {\n animation: pi-taskbar-pulse 1.2s ease-in-out infinite;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n scroll-behavior: auto !important;\n animation: none !important;\n transition: none !important;\n }\n}\n\n@keyframes pi-taskbar-pulse {\n 50% {\n box-shadow: 0 0 0 7px color-mix(in srgb, var(--pi-mark) 8%, transparent);\n }\n}";
|
|
1181
1291
|
const contextProvider = ({
|
|
1182
1292
|
framework: "rails",
|
|
1183
1293
|
sourceHint(element) {
|
|
@@ -1276,7 +1386,7 @@ function hint(status, references = []) {
|
|
|
1276
1386
|
contractVersion: 1,
|
|
1277
1387
|
contextProvider,
|
|
1278
1388
|
framework: "rails",
|
|
1279
|
-
productVersion: "0.
|
|
1389
|
+
productVersion: "0.4.1",
|
|
1280
1390
|
refreshOnCompletion: true,
|
|
1281
1391
|
});
|
|
1282
1392
|
|
|
@@ -1284,7 +1394,7 @@ function hint(status, references = []) {
|
|
|
1284
1394
|
contractVersion: 1,
|
|
1285
1395
|
framework: "rails",
|
|
1286
1396
|
mount: client.mount,
|
|
1287
|
-
productVersion: "0.
|
|
1397
|
+
productVersion: "0.4.1",
|
|
1288
1398
|
});
|
|
1289
1399
|
|
|
1290
1400
|
const bootstrap = globalThis.document?.querySelector?.("[data-pi-browser-taskbar-bootstrap]");
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pi-browser-taskbar-rails
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dave Lens
|
|
@@ -60,8 +60,8 @@ licenses:
|
|
|
60
60
|
- MIT
|
|
61
61
|
metadata:
|
|
62
62
|
homepage_uri: https://github.com/davelens/pi-browser-taskbar
|
|
63
|
-
source_code_uri: https://github.com/davelens/pi-browser-taskbar/tree/v0.
|
|
64
|
-
changelog_uri: https://github.com/davelens/pi-browser-taskbar/blob/v0.
|
|
63
|
+
source_code_uri: https://github.com/davelens/pi-browser-taskbar/tree/v0.4.1
|
|
64
|
+
changelog_uri: https://github.com/davelens/pi-browser-taskbar/blob/v0.4.1/packages/rails/CHANGELOG.md
|
|
65
65
|
post_install_message:
|
|
66
66
|
rdoc_options: []
|
|
67
67
|
require_paths:
|