palmier 1.1.11 → 1.1.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.
- package/dist/agents/agent.d.ts +4 -1
- package/dist/agents/codex.js +1 -0
- package/dist/commands/run.d.ts +3 -0
- package/dist/commands/run.js +42 -14
- package/dist/pwa/assets/{index-DvUi9Jhi.css → index-ByB7B0d2.css} +1 -1
- package/dist/pwa/assets/{index-DO60N3KY.js → index-C09PWoQd.js} +2 -2
- package/dist/pwa/assets/{web-DjwtZB4p.js → web-0ZvmFBgz.js} +1 -1
- package/dist/pwa/assets/{web-BQcwgjLy.js → web-Bt4bEHcd.js} +1 -1
- package/dist/pwa/assets/{web-dCWmWPLg.js → web-DurpjXBX.js} +1 -1
- package/dist/pwa/index.html +2 -2
- package/dist/rpc-handler.js +8 -3
- package/package.json +1 -1
package/dist/agents/agent.d.ts
CHANGED
|
@@ -30,8 +30,11 @@ export interface AgentTool {
|
|
|
30
30
|
supportsPermissions?: boolean;
|
|
31
31
|
/** Whether this agent supports yolo mode (auto-approve all tools). */
|
|
32
32
|
supportsYolo?: boolean;
|
|
33
|
-
/** When true, the run loop will not
|
|
33
|
+
/** When true, the run loop will not persist the agent's stderr output. */
|
|
34
34
|
suppressStdErr?: boolean;
|
|
35
|
+
/** Matches the model name (capture group 1) in the banner the CLI prints on stderr.
|
|
36
|
+
* Takes precedence over the agent's self-reported model marker. */
|
|
37
|
+
stderrModelPattern?: RegExp;
|
|
35
38
|
npmPackage?: string;
|
|
36
39
|
/** Optional human-readable note about free-usage availability (e.g. "Free Tier").
|
|
37
40
|
* Surfaced next to the agent in the installer. */
|
package/dist/agents/codex.js
CHANGED
package/dist/commands/run.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { AgentTool } from "../agents/agent.js";
|
|
1
2
|
import type { TaskRunningState, RequiredPermission } from "../types.js";
|
|
2
3
|
export declare function stripPalmierMarkers(output: string): string;
|
|
3
4
|
export declare function runCommand(taskId: string): Promise<void>;
|
|
@@ -5,5 +6,7 @@ export declare function runCommand(taskId: string): Promise<void>;
|
|
|
5
6
|
export declare function listLinkedTaskFiles(taskDir: string, runId: string, output: string): string[];
|
|
6
7
|
export declare function parsePermissions(output: string): RequiredPermission[];
|
|
7
8
|
export declare function parseAgentModel(output: string): string | undefined;
|
|
9
|
+
/** Returns a function that accumulates stderr chunks and yields the model once the CLI banner reveals it. */
|
|
10
|
+
export declare function createCliModelCapture(agent: AgentTool): (stderrChunk: string) => string | undefined;
|
|
8
11
|
/** Falls back to "finished" if no success/failure marker is found. */
|
|
9
12
|
export declare function parseTaskOutcome(output: string): TaskRunningState;
|
package/dist/commands/run.js
CHANGED
|
@@ -22,8 +22,9 @@ async function invokeAgentWithRetries(ctx, invokeTask) {
|
|
|
22
22
|
const lineBufs = { stdout: "", stderr: "" };
|
|
23
23
|
let notifyPending = false;
|
|
24
24
|
let notifyTimer;
|
|
25
|
-
let
|
|
26
|
-
let
|
|
25
|
+
let agentModel;
|
|
26
|
+
let agentModelWritten = false;
|
|
27
|
+
const captureCliModel = createCliModelCapture(ctx.agent);
|
|
27
28
|
function throttledNotify() {
|
|
28
29
|
if (notifyPending)
|
|
29
30
|
return;
|
|
@@ -43,19 +44,26 @@ async function invokeAgentWithRetries(ctx, invokeTask) {
|
|
|
43
44
|
return writer;
|
|
44
45
|
}
|
|
45
46
|
function flushAgentModel() {
|
|
46
|
-
if (!
|
|
47
|
+
if (!agentModel || agentModelWritten || !writer)
|
|
47
48
|
return;
|
|
48
|
-
writer.write(formatAgentModelComment(
|
|
49
|
-
|
|
49
|
+
writer.write(formatAgentModelComment(agentModel));
|
|
50
|
+
agentModelWritten = true;
|
|
50
51
|
throttledNotify();
|
|
51
52
|
}
|
|
53
|
+
function onStderr(chunk) {
|
|
54
|
+
if (!ctx.agent.suppressStdErr)
|
|
55
|
+
emit("stderr", chunk);
|
|
56
|
+
const cliModel = captureCliModel(chunk);
|
|
57
|
+
if (cliModel && !agentModelWritten)
|
|
58
|
+
agentModel = cliModel;
|
|
59
|
+
flushAgentModel();
|
|
60
|
+
}
|
|
52
61
|
function emit(stream, chunk) {
|
|
53
62
|
lineBufs[stream] += chunk;
|
|
54
63
|
const lines = lineBufs[stream].split("\n");
|
|
55
64
|
lineBufs[stream] = lines.pop() ?? "";
|
|
56
|
-
if (stream === "stdout" && !
|
|
57
|
-
|
|
58
|
-
agentModelSeen = !!pendingAgentModel;
|
|
65
|
+
if (stream === "stdout" && !agentModel) {
|
|
66
|
+
agentModel = parseAgentModel(lines.join("\n"));
|
|
59
67
|
}
|
|
60
68
|
const filtered = lines.filter((l) => !l.startsWith("[PALMIER"));
|
|
61
69
|
if (filtered.length > 0) {
|
|
@@ -78,7 +86,7 @@ async function invokeAgentWithRetries(ctx, invokeTask) {
|
|
|
78
86
|
resolveOnFailure: true,
|
|
79
87
|
stdin,
|
|
80
88
|
onStdout: (chunk) => emit("stdout", chunk),
|
|
81
|
-
onStderr
|
|
89
|
+
onStderr,
|
|
82
90
|
});
|
|
83
91
|
if (notifyTimer)
|
|
84
92
|
clearTimeout(notifyTimer);
|
|
@@ -402,14 +410,34 @@ export function parseAgentModel(output) {
|
|
|
402
410
|
const regex = new RegExp(`^\\${AGENT_MODEL_PREFIX}[ \\t]+(.+)$`, "gm");
|
|
403
411
|
let match;
|
|
404
412
|
while ((match = regex.exec(output)) !== null) {
|
|
405
|
-
const model = match[1]
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
continue;
|
|
409
|
-
return model;
|
|
413
|
+
const model = sanitizeAgentModel(match[1]);
|
|
414
|
+
if (model)
|
|
415
|
+
return model;
|
|
410
416
|
}
|
|
411
417
|
return undefined;
|
|
412
418
|
}
|
|
419
|
+
/** Returns a function that accumulates stderr chunks and yields the model once the CLI banner reveals it. */
|
|
420
|
+
export function createCliModelCapture(agent) {
|
|
421
|
+
let head = "";
|
|
422
|
+
let model;
|
|
423
|
+
return (chunk) => {
|
|
424
|
+
// The banner is printed at startup, so stop buffering once well past it.
|
|
425
|
+
if (model || !agent.stderrModelPattern || head.length > 8192)
|
|
426
|
+
return model;
|
|
427
|
+
head += chunk;
|
|
428
|
+
const completeLines = head.slice(0, head.lastIndexOf("\n") + 1);
|
|
429
|
+
const raw = completeLines.match(agent.stderrModelPattern)?.[1];
|
|
430
|
+
model = raw ? sanitizeAgentModel(raw) : undefined;
|
|
431
|
+
return model;
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
function sanitizeAgentModel(raw) {
|
|
435
|
+
const model = raw.trim();
|
|
436
|
+
// Skip the "<model>" placeholder echoed from the prompt, and values that would break the run-file comment.
|
|
437
|
+
if (!model || model.startsWith("<") || model.includes("-->") || model.length > 100)
|
|
438
|
+
return undefined;
|
|
439
|
+
return model;
|
|
440
|
+
}
|
|
413
441
|
/** Falls back to "finished" if no success/failure marker is found. */
|
|
414
442
|
export function parseTaskOutcome(output) {
|
|
415
443
|
const lastChunk = output.slice(-500);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
@font-face{font-family:Plus Jakarta Sans Variable;font-style:normal;font-display:swap;font-weight:200 800;src:url(data:font/woff2;base64,d09GMgABAAAAAAa0ABQAAAAADOwAAAZHAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhYbbhwoP0hWQVJtP01WQVJGBmA/U1RBVIEcAGQvXBEICoMkgmcLFgAwhEwBNgIkAyYEIAWGXAdiDAcbOgtRlHLSRcD8TEzkdoghPRuspKefbVnJIM5yRfA8vZv9uTNJSCZY21Scrigr6qyJ/C3sE1OFKuVP3e+lxUTbYio1zb/kFdk2bufY2BlhWERRBrcDUBhB5GEpd2Cy+MDxqf9zLPX+XVsk5r+s50d6IpWLatqbdT6f2MAikiOKQocbjya2QT0DqPDX4R0jQBgAUAiCRhDA0EkvYeLk9X3I2bEWI8jBAihIANm+kUWQBgggWChcBBdFhXlAUgOCAgBA0AgKjUJ8HKvjddFCKSgAVklEBYAeEJgCQJH0qB3B+neDg4sAA4hAD0AVIEAA0IACJGeaUjMIIIhBUE/zNABjTQMBwEVRcwcYBUCObLERABAgjAA1M/ZSa9hSi4OlpsnZ2KBOVUsAZlRGl1W0NZ6gSwhQPIAFs7YFL0QS91vRQgdgx2VDAnIegKpQvwAJIoLgooBAGtCJcHizg0TDiz8vhPgIcVXaDJu37ZyDAIjFy4AAiC1JAA0olJwN6nFAACQk/zfQVUuA3t5ELKMT9hpBSRj+HBSggYCIAIEkUoC4PCIQIWHGA8+IStxf0PW15ntP22gc+Wo+BLyQAHECQiAVd+c3Ba8gZ4NOACBaLOhsbIMkAXEmuHsSAvkf4oJaAogH6nEQAzoBIEihUAwAA0AACAObAGcANYAAABaqgMmpWAhiiVyrvNyqFV8tMQ5Iyq6r9Lf7W82i8ILl2cv8zbfdJ5lnPzSnvt/XXPfRR/5pH3xA+u5uS0798EPJ3Fft33w36Wc+8E/7aIB/9fvvb1pE9erNXLB9mkw//cSg8Cnx03VGXDvZnRzKqV9Xkhn7eRHb3wVjHpg19nkZpX9bBU+vnHegrsuQcbW9Bi7oO33h+8SU0Tly/MbeYUuG1cftVz6oNxrW0qH1iezq446fkDFo/rgvTkqt7zmteFzncZ0uxXti09FFF2z+C7CODpjUudOE5NSeb3bv/mbPKcmOEzpWQ3VBgBAuj/AOY3qMm7UvgA8qo3+qvAUBBAX0wADQG4AG+jCKaSxkBe/zvcTG8jRpRZgqhCog4sd++cOo7J+/RdvaaMoc78Ri/PNPSclx6fDvG1Kt3qQFi1rq+5EaavTtt9TVvfvucYsA5wc4oESU+E1ikF9TkrOkIsIH5Fawx7SBNLnMcWlM3skBluCmQNs7GeyFvYVDamsqwhxx18n/+WdxzDgOLU1AqbUlb3m+KOT9+ONvY/7XlrdLS//5v7nN97XHj0VzJpJvz4spq0V7ioXDuv2YrSxtF/KZmvbWfKtorXSh8dfvgGu+ev/nFSaXM6jyuCE/f/EpmuP7Rqu8R98vP/+tXUdrOgKlZP9Q/s+fRF9+3CHZd4EugfPv158me9X7v/6aSMCxMJmIr//65bNXngl7+uiPP5oKx+y27D8trp+psUzMacpm80XlnYeMAct0LynxhNYgaP3dtn8/LBAi+ksr+7NvjjtJV+UXrz0uLXV1x08AZRN1S2A8EaVE5afk/dfGjz//+fdHn36Xdttz2d9/z+bawZ8/slNN1aYtq+ZPGzNuPGdwOsfYflwmHCkPgs5DcKizvdpS/3gEUMW9/lvQvWp1bGTW1fpngC/uSVYAfH3TeSusL8TtlHUD4KAAEHjahk4YpuffGwEBN/dUmpHqdHyJ3Ap8O3UlQ4gCNrMRwLBBKiskL6a+RoBi/9XGlgc8L4/CUejQxaiIyqmomdhktOhfgDbDfaNDb4+yKIPd6IgmzDa0CByijWFmL2dlSRKagTIWXeIU9HDphoZiJeBTjAefHMxDhVSRFUgVcOkW3EGMahYVMFjWHhMluB2wAcbHYqF1LpsDF9C6s+CI2fDgh4wSuFEyGadjXAmIk3CugIRibLIti9ZtC8S4VSqfikGqPaoI122XyRYLBmsOmdiiTpqK1OklUQzpMcZmQRQV4M4oJCMkfRQXK+qvjifUcQd1bRdetW/LWjacYxvcttnVjWg5h0q4xw6rZyejSpZVZ78LzC4uyDNRQ4bymHSTMyM+SZ7D75mg/7YTlmNz7W8T00h0VEiGKB+F7iWYZFvSTiA4LVxttm2ATt5EoUWLJbY4EnLGrfsvEROlHtzlKn3H9VUT5tU/2dt3/EBv7foYzV/W4upyj04woO/gh6Vwwt3WGQAA) format("woff2-variations");unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Plus Jakarta Sans Variable;font-style:normal;font-display:swap;font-weight:200 800;src:url(/assets/plus-jakarta-sans-vietnamese-wght-normal-qRpaaN48.woff2) format("woff2-variations");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Plus Jakarta Sans Variable;font-style:normal;font-display:swap;font-weight:200 800;src:url(/assets/plus-jakarta-sans-latin-ext-wght-normal-DmpS2jIq.woff2) format("woff2-variations");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Plus Jakarta Sans Variable;font-style:normal;font-display:swap;font-weight:200 800;src:url(/assets/plus-jakarta-sans-latin-wght-normal-eXO_dkmS.woff2) format("woff2-variations");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}:root{--color-bg: #F7F8FC;--color-surface: #ffffff;--color-primary: #2E5CE5;--color-primary-hover: #1D4ED8;--color-primary-subtle: #EEF2FF;--color-secondary: #64748B;--color-secondary-hover: #475569;--color-text: #1A1F36;--color-text-secondary: #697386;--color-muted: #94A3B8;--color-success: #22C55E;--color-error: #EF4444;--color-error-bg: #FEF2F2;--color-warning: #F59E0B;--color-border: #E2E8F0;--color-border-subtle: #F1F5F9;--color-hover: rgba(15, 23, 42, .06);--color-overlay: rgba(15, 23, 42, .5);--color-input-focus: rgba(46, 92, 229, .15);--shadow-xs: 0 1px 2px rgba(15, 23, 42, .05);--shadow-sm: 0 1px 3px rgba(15, 23, 42, .06), 0 1px 2px rgba(15, 23, 42, .04);--shadow-md: 0 4px 6px -1px rgba(15, 23, 42, .07), 0 2px 4px -2px rgba(15, 23, 42, .05);--shadow-lg: 0 10px 15px -3px rgba(15, 23, 42, .08), 0 4px 6px -4px rgba(15, 23, 42, .04);--shadow-xl: 0 20px 25px -5px rgba(15, 23, 42, .1), 0 8px 10px -6px rgba(15, 23, 42, .06);--radius-sm: 8px;--radius-md: 12px;--radius-lg: 16px;--radius-full: 50%;--font-sans: "Plus Jakarta Sans Variable", "Plus Jakarta Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;--space-xs: 4px;--space-sm: 8px;--space-md: 16px;--space-lg: 24px;--space-xl: 32px;--space-2xl: 48px;--transition-fast: .12s ease;--transition-base: .2s ease}*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}html{font-size:16px;-webkit-text-size-adjust:100%}body{font-family:var(--font-sans);background:var(--color-bg);color:var(--color-text);line-height:1.6;min-height:100dvh;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;overscroll-behavior-y:contain}.pull-to-refresh{position:fixed;top:-48px;left:0;right:0;height:48px;display:flex;align-items:center;justify-content:center;pointer-events:none;z-index:40;transition:opacity .15s}.pull-to-refresh-badge{width:40px;height:40px;border-radius:50%;background:var(--color-surface);border:1px solid var(--color-border);box-shadow:var(--shadow-md);display:flex;align-items:center;justify-content:center;color:var(--color-text-secondary)}#root{min-height:100dvh}.btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;border:1px solid transparent;border-radius:var(--radius-sm);font-family:var(--font-sans);font-size:.875rem;font-weight:600;padding:10px 18px;cursor:pointer;transition:all var(--transition-base);-webkit-tap-highlight-color:transparent;letter-spacing:-.01em;line-height:1.25}.btn:disabled{opacity:.45;cursor:not-allowed}.btn:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}.btn-primary{background:var(--color-primary);color:#fff;box-shadow:0 1px 2px #2e5ce54d,inset 0 1px #ffffff1a}.btn-primary:hover:not(:disabled){background:var(--color-primary-hover);box-shadow:0 2px 4px #2e5ce559,inset 0 1px #ffffff1a;transform:translateY(-.5px)}.btn-primary:active:not(:disabled){transform:translateY(0);box-shadow:0 1px 2px #2e5ce54d}.btn-secondary{background:var(--color-surface);color:var(--color-text);border-color:var(--color-border);box-shadow:var(--shadow-xs)}.btn-secondary:hover:not(:disabled){background:var(--color-border-subtle);border-color:#cbd5e1}.btn-danger{background:var(--color-error);color:#fff;box-shadow:0 1px 2px #ef44444d}.btn-danger:hover:not(:disabled){background:#dc2626;box-shadow:0 2px 4px #ef444459}.btn-link{background:none;border:none;color:var(--color-primary);padding:0;font-weight:500;box-shadow:none}.btn-link:hover:not(:disabled){text-decoration:underline;background:none;box-shadow:none}.btn-spinner{display:inline-block;width:14px;height:14px;border:2px solid rgba(255,255,255,.3);border-top-color:#fff;border-radius:50%;animation:spin .6s linear infinite;vertical-align:middle;margin-right:6px}.btn-spinner-current{border-color:#7f7f7f40;border-top-color:currentColor}.btn-sm{font-size:.8125rem;padding:6px 12px;border-radius:6px}.btn-full{width:100%}.form-label{display:flex;flex-direction:column;gap:6px;font-size:.8125rem;font-weight:600;color:var(--color-text);margin-bottom:var(--space-md);letter-spacing:-.01em}.form-input,.form-textarea,.form-select{font-family:var(--font-sans);font-size:.9375rem;padding:10px 12px;border:1.5px solid var(--color-border);border-radius:var(--radius-sm);background:var(--color-surface);color:var(--color-text);transition:border-color var(--transition-fast),box-shadow var(--transition-fast);width:100%}.form-input:focus,.form-textarea:focus,.form-select:focus{outline:none;border-color:var(--color-primary);box-shadow:0 0 0 3px var(--color-input-focus)}.form-input-mono{font-family:SF Mono,Fira Code,Cascadia Code,monospace;font-size:.8125rem}.form-input::placeholder,.form-textarea::placeholder{color:var(--color-muted)}.form-textarea{resize:vertical;min-height:80px;line-height:1.5}.form-error{background:var(--color-error-bg);color:var(--color-error);border:1px solid #FECACA;border-radius:var(--radius-sm);padding:var(--space-sm) var(--space-md);font-size:.8125rem;font-weight:500;margin-bottom:var(--space-md)}.form-warning{background:#fef3c7;color:#92400e;border:1px solid #FDE68A;border-radius:var(--radius-sm);padding:var(--space-sm) var(--space-md);font-size:.8125rem;font-weight:500;margin-bottom:var(--space-md)}.dashboard{min-height:100dvh;display:flex;flex-direction:column;padding-bottom:0}.dashboard-main{flex:1;padding:var(--space-md);width:100%}.status-dot{display:inline-block;width:8px;height:8px;border-radius:var(--radius-full);flex-shrink:0;box-shadow:0 0 0 2px #fffc}.status-spinner{display:inline-flex;align-items:center;gap:2px;flex-shrink:0;height:8px}.status-spinner:before,.status-spinner>span,.status-spinner:after{content:"";display:block;width:3px;height:3px;border-radius:var(--radius-full);background-color:var(--color-success);animation:marching-dot 1.2s ease-in-out infinite}.status-spinner:before{animation-delay:0s}.status-spinner>span{animation-delay:.2s}.status-spinner:after{animation-delay:.4s}@keyframes marching-dot{0%,60%,to{opacity:.25;transform:scale(.8)}30%{opacity:1;transform:scale(1)}}.pair-page{display:flex;align-items:flex-start;justify-content:center;min-height:100dvh;padding:var(--space-xl) var(--space-md);background:var(--color-bg)}.pair-card{width:100%;max-width:420px;display:flex;flex-direction:column;gap:var(--space-lg)}.pair-header{text-align:center}.pair-title{font-size:1.5rem;font-weight:700;color:var(--color-text);letter-spacing:-.02em}.pair-subtitle{margin-top:var(--space-xs);font-size:.875rem;color:var(--color-text-secondary)}.pair-instructions{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-md);padding:var(--space-md);display:flex;flex-direction:column;gap:var(--space-md)}.pair-instruction-block{display:flex;flex-direction:column;gap:var(--space-sm)}.pair-instruction-heading{font-size:.8125rem;font-weight:600;color:var(--color-text);letter-spacing:-.01em}.pair-steps{list-style:none;counter-reset:pair-step;display:flex;flex-direction:column;gap:6px;padding:0}.pair-steps li{counter-increment:pair-step;font-size:.8125rem;color:var(--color-text-secondary);line-height:1.5;display:flex;flex-wrap:wrap;gap:0 var(--space-sm)}.pair-steps li:before{content:counter(pair-step) ".";font-weight:600;color:var(--color-muted);min-width:16px;flex-shrink:0}.pair-steps li .pair-command{flex-basis:100%}.pair-steps code{font-family:SF Mono,Fira Code,Cascadia Code,monospace;font-size:.75rem;background:var(--color-bg);border:1px solid var(--color-border);border-radius:4px;padding:1px 5px;color:var(--color-text);white-space:nowrap}.pair-command{display:block;margin-top:4px;padding:6px 10px!important;border-radius:var(--radius-sm)!important;overflow-x:auto;-webkit-overflow-scrolling:touch}.pair-platform-label{display:block;flex-basis:100%;margin-top:8px;font-size:.75rem;font-weight:600;color:var(--color-muted)}.pair-instruction-divider{height:1px;background:var(--color-border)}.pair-form{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-md);padding:var(--space-lg);display:flex;flex-direction:column;gap:var(--space-md);box-shadow:var(--shadow-sm)}.pair-code-input{font-size:1.5rem!important;letter-spacing:.25em;text-align:center;padding:14px 12px!important;text-transform:uppercase}.pair-code-input::placeholder{letter-spacing:.25em;opacity:.35}.pair-label-hint{font-weight:400;color:var(--color-muted);font-size:.75rem}.pair-error{font-size:.8125rem;color:var(--color-error);background:var(--color-error-bg);padding:var(--space-sm) var(--space-md);border-radius:var(--radius-sm);line-height:1.4}.loading-state,.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:var(--space-2xl) 0;gap:var(--space-sm)}.empty-state-text{font-size:1rem;font-weight:600;color:var(--color-text-secondary)}.empty-state-hint{font-size:.8125rem;color:var(--color-muted)}.revoked-state{display:flex;flex-direction:column;align-items:center;text-align:center;padding:var(--space-2xl) var(--space-lg);margin:var(--space-md) 0;background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-md);animation:revokedFadeIn .35s ease}@keyframes revokedFadeIn{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}.revoked-icon{width:56px;height:56px;display:flex;align-items:center;justify-content:center;border-radius:var(--radius-full);background:var(--color-error-bg);color:var(--color-error);margin-bottom:var(--space-md)}.revoked-title{font-size:1.125rem;font-weight:700;color:var(--color-text);margin-bottom:var(--space-xs)}.revoked-description{font-size:.875rem;line-height:1.6;color:var(--color-text-secondary);max-width:320px;margin-bottom:var(--space-lg)}.revoked-command{padding:8px 16px;background:var(--color-bg);border:1px solid var(--color-border);border-radius:var(--radius-sm);margin-bottom:var(--space-lg)}.revoked-command code{font-family:SF Mono,Fira Code,Cascadia Code,monospace;font-size:.8125rem;color:var(--color-text);letter-spacing:-.01em}.revoked-actions{display:flex;gap:var(--space-sm);width:100%;max-width:280px}.revoked-actions .btn{flex:1}.spinner{width:24px;height:24px;border:2.5px solid var(--color-border);border-top-color:var(--color-primary);border-radius:var(--radius-full);animation:spin .7s linear infinite}.spinner-lg{width:40px;height:40px;border-width:3px}.capability-toggles-loading{display:flex;justify-content:center;padding:var(--space-lg)}@keyframes spin{to{transform:rotate(360deg)}}.session-composer{background:var(--color-surface);border-radius:var(--radius-md);border:1px solid var(--color-border);box-shadow:var(--shadow-sm);padding:var(--space-sm);margin-bottom:var(--space-md);display:flex;flex-direction:column;gap:var(--space-sm)}.session-composer:focus-within{border-color:var(--color-primary);box-shadow:0 0 0 2px var(--color-input-focus)}.session-composer-textarea{width:100%;border:none;resize:vertical;outline:none;background:transparent;color:var(--color-text);font-family:var(--font-sans);font-size:.9375rem;line-height:1.5;padding:var(--space-xs) var(--space-sm);min-height:3.5em}.session-composer-textarea::placeholder{color:var(--color-muted)}.session-composer-controls{display:flex;align-items:center;gap:var(--space-sm);padding-left:var(--space-xs)}.session-composer-yolo{display:inline-flex;align-items:center;gap:4px;font-size:.8rem;color:var(--color-text-secondary);cursor:pointer;-webkit-user-select:none;user-select:none}.session-composer-yolo input{margin:0;cursor:pointer}.session-composer-controls .chat-send-btn{margin-left:auto}.fab{position:fixed;right:var(--space-lg);bottom:calc(var(--space-lg) + env(safe-area-inset-bottom,0px));width:56px;height:56px;border-radius:50%;border:none;background:var(--color-primary);color:#fff;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:var(--shadow-lg);transition:background var(--transition-base),transform var(--transition-fast),box-shadow var(--transition-base);z-index:50;-webkit-tap-highlight-color:transparent}.fab:hover{background:var(--color-primary-hover);box-shadow:var(--shadow-xl);transform:translateY(-1px)}.fab:active{transform:translateY(0)}.fab:focus-visible{outline:2px solid var(--color-primary);outline-offset:3px}.section-label{font-size:.6875rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--color-muted);margin:var(--space-md) 0 var(--space-xs)}.agent-picker-section-inline{display:flex;align-items:center;gap:var(--space-xs)}.agent-picker-section-inline .form-select{width:auto;min-width:0;font-size:.8rem;padding:4px 8px}.agent-picker-section-inline .agent-picker-single{font-size:.8rem;color:var(--color-text)}.task-list{display:flex;flex-direction:column;gap:10px;padding-bottom:calc(56px + var(--space-lg) * 2 + env(safe-area-inset-bottom,0px))}.task-card{background:var(--color-surface);border-radius:var(--radius-md);border:1px solid var(--color-border);box-shadow:var(--shadow-sm);padding:var(--space-md);display:flex;flex-direction:column;gap:var(--space-sm);cursor:pointer;transition:box-shadow var(--transition-base),border-color var(--transition-base);-webkit-tap-highlight-color:transparent}.task-card:hover{box-shadow:var(--shadow-md);border-color:#cbd5e1}.task-card-header{display:flex;align-items:center;justify-content:space-between;gap:var(--space-sm)}.task-card-title-row{display:flex;align-items:center;gap:10px;min-width:0;flex:1}.task-card-name{font-size:.9375rem;font-weight:600;letter-spacing:-.01em;color:var(--color-text);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.task-card-meta{display:flex;flex-wrap:wrap;gap:var(--space-sm);font-size:.75rem;color:var(--color-text-secondary)}.task-card-agent{color:var(--color-text-tertiary)}.task-card-last-event-link{color:var(--color-primary);cursor:pointer;text-decoration:underline}.task-card-actions{display:flex;gap:var(--space-xs);flex-shrink:0}.task-card-menu{position:relative}.task-card-menu-btn{background:none;border:none;color:var(--color-text-secondary);font-size:1.5rem;min-width:44px;min-height:44px;display:flex;align-items:center;justify-content:center;border-radius:var(--radius-sm);cursor:pointer;line-height:1}.task-card-menu-btn:hover{background:var(--color-hover);color:var(--color-text)}.task-card-menu-dropdown{position:absolute;right:0;top:100%;margin-top:4px;background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-md);box-shadow:var(--shadow-md);min-width:150px;z-index:10;overflow:hidden}.task-card-menu-dropdown button{display:flex;align-items:center;gap:var(--space-sm);width:100%;text-align:left;padding:var(--space-sm) var(--space-md);background:none;border:none;font-size:.9375rem;color:var(--color-text);cursor:pointer;white-space:nowrap}.task-card-menu-dropdown button:hover{background:var(--color-hover)}.task-card-menu-dropdown .menu-item-danger{color:var(--color-error)}.menu-icon{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;font-size:.875rem;flex-shrink:0;line-height:1}.bottom-sheet-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:var(--color-overlay);z-index:1000;display:flex;align-items:flex-end;justify-content:center;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);animation:fadeIn var(--transition-fast)}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.bottom-sheet{background:var(--color-surface);border-radius:var(--radius-lg) var(--radius-lg) 0 0;width:100%;max-width:480px;padding:var(--space-sm) var(--space-md) var(--space-xl);box-shadow:var(--shadow-xl);animation:sheetSlideUp .25s cubic-bezier(.16,1,.3,1)}@keyframes sheetSlideUp{0%{transform:translateY(100%)}to{transform:translateY(0)}}.bottom-sheet-handle{width:36px;height:4px;background:var(--color-border);border-radius:2px;margin:0 auto var(--space-md)}.bottom-sheet-title{font-size:.9375rem;font-weight:600;color:var(--color-text);padding:0 var(--space-xs) var(--space-md);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.bottom-sheet-actions{display:flex;flex-direction:column}.bottom-sheet-actions button{display:flex;align-items:center;gap:var(--space-md);width:100%;text-align:left;padding:var(--space-md);background:none;border:none;border-radius:var(--radius-sm);font-size:.9375rem;font-family:var(--font-sans);color:var(--color-text);cursor:pointer;transition:background var(--transition-fast)}.bottom-sheet-actions button:active{background:var(--color-hover)}.bottom-sheet-actions .menu-item-danger{color:var(--color-error)}.task-form-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:transparent;display:flex;align-items:stretch;justify-content:center;z-index:100;padding:0;overflow:hidden;overscroll-behavior:contain}.task-form{background:var(--color-surface);border-radius:0;padding:var(--space-lg) var(--space-md);width:100%;max-width:none;max-height:none;overflow-y:auto;animation:slideUp .25s cubic-bezier(.16,1,.3,1);display:flex;flex-direction:column;gap:var(--space-md)}@media(min-width:600px){.task-form-overlay{background:var(--color-overlay);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);align-items:center;padding:var(--space-md)}.task-form{border-radius:var(--radius-lg);box-shadow:var(--shadow-xl);max-width:540px;max-height:90dvh;padding:var(--space-lg)}}@keyframes slideUp{0%{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}.task-form-header{display:flex;align-items:center;justify-content:space-between}.task-form h2{font-size:1.0625rem;font-weight:700;letter-spacing:-.02em;margin-bottom:0}.plan-actions{display:flex;gap:var(--space-sm);flex-wrap:wrap}.permissions-dialog{display:flex;flex-direction:column;gap:var(--space-md);overflow:hidden;flex:1;min-height:0}.permissions-dialog h2{margin:0;font-size:1.125rem}.permissions-dialog-scroll{flex:1;min-height:0;overflow-y:auto}.permissions-empty{color:var(--color-text-secondary);font-size:.875rem;font-style:italic;margin:var(--space-md) 0}.permissions-section{border-top:1px solid var(--color-border);padding-top:var(--space-md);margin-top:var(--space-md)}.permissions-section h3{margin:0 0 var(--space-xs) 0;font-size:.95rem}.permissions-list{margin:0;padding-left:1.25em}.permission-item{margin-bottom:var(--space-sm);display:flex;flex-direction:column}.permission-tool{font-weight:600;font-family:var(--font-mono, monospace)}.permission-desc{color:var(--color-text-secondary);font-size:.9em}.permissions-dialog-actions{display:flex;gap:var(--space-sm);align-items:center;justify-content:flex-end}@media(min-width:600px){.permissions-dialog{max-width:none}}.result-times{display:flex;flex-direction:column;gap:var(--space-xs);font-size:.8125rem;color:var(--color-text-secondary);margin-bottom:var(--space-sm)}.skeleton-line{height:.875rem;border-radius:var(--radius-sm);background:var(--color-border);animation:skeleton-pulse 1.2s ease-in-out infinite}@keyframes skeleton-pulse{0%,to{opacity:.4}50%{opacity:1}}.granted-permissions-row{flex-basis:100%}.granted-permissions-row .btn-link{padding:0}.schedule-section{display:flex;flex-direction:column;gap:var(--space-sm)}.schedule-section-title{font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--color-muted);margin:0}.schedule-section-hint{font-weight:400;text-transform:none;letter-spacing:0;color:var(--color-text-secondary);margin-left:6px}.schedule-reactive{display:flex;flex-direction:column;gap:var(--space-xs)}.yolo-inline{display:inline-flex;align-items:center;gap:4px;font-size:.8rem;color:var(--color-text-secondary);cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap}.yolo-inline input{margin:0;cursor:pointer}.yolo-warning{flex-basis:100%;margin:0;font-size:.75rem;color:var(--color-text-secondary);line-height:1.4}.trigger-row-card{display:flex;align-items:center;gap:8px;padding:4px 0}.trigger-row-content{display:flex;flex-direction:column;gap:4px;flex:1;min-width:0}.trigger-row-top{display:flex;align-items:center;gap:8px}.trigger-row-top .form-select{flex:0 0 auto;width:auto}.trigger-row-top .form-input{flex:1}.trigger-details{display:flex;gap:6px}.trigger-details .form-input[type=date]{flex:1;min-width:0}.trigger-details .form-input[type=time]{flex:0 0 auto;width:auto}.schedule-section>.form-select,.trigger-row-card .form-select,.trigger-row-card .form-input{margin-bottom:0;font-size:.8125rem;padding:6px 8px;height:32px;box-sizing:border-box;min-width:0}.schedule-section>.form-select{width:100%}.trigger-row-card .form-select,.trigger-row-card .form-input{flex:1}.trigger-remove-btn{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;border:none;border-radius:var(--radius-full);background:transparent;color:var(--color-muted);font-size:1.1rem;line-height:1;cursor:pointer;transition:all var(--transition-fast);flex-shrink:0}.trigger-remove-btn:hover{background:var(--color-error-bg);color:var(--color-error)}.trigger-add-btn{display:inline-flex;align-items:center;gap:4px;border:1px dashed var(--color-border);border-radius:var(--radius-sm);background:transparent;color:var(--color-text-secondary);font-family:var(--font-sans);font-size:.8125rem;font-weight:500;padding:8px 14px;cursor:pointer;transition:all var(--transition-fast);width:100%;justify-content:center}.trigger-add-btn:hover{border-color:var(--color-primary);color:var(--color-primary);background:var(--color-primary-subtle)}.form-select{width:auto;min-width:80px}.toggles-section{display:flex;flex-direction:column;gap:10px;margin-bottom:var(--space-md)}.toggle-label{display:flex;align-items:center;gap:10px;font-size:.875rem;font-weight:500;cursor:pointer;-webkit-tap-highlight-color:transparent;color:var(--color-text)}.toggle-label input[type=checkbox]{width:16px;height:16px;accent-color:var(--color-primary);border-radius:4px}.toggles-group{display:flex;flex-direction:column;gap:var(--space-xs)}.command-section,.command-section-active .toggle-label,.task-title-field,.task-title-help{margin-bottom:0}.command-help-text{font-size:.75rem;color:var(--color-text-secondary);line-height:1.4;margin:6px 0 10px}.command-section-active .form-input{font-size:.8125rem;padding:6px 8px;height:32px;box-sizing:border-box}.form-actions{display:flex;gap:var(--space-sm);position:sticky;bottom:0;background:var(--color-surface);padding:var(--space-sm) 0}.confirm-modal-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:var(--color-overlay);display:flex;align-items:center;justify-content:center;z-index:1000;padding:var(--space-md);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.confirm-modal{background:var(--color-surface);border-radius:var(--radius-lg);border:1px solid var(--color-border);padding:var(--space-xl);width:100%;max-width:380px;text-align:center;box-shadow:var(--shadow-xl);animation:slideUp .25s cubic-bezier(.16,1,.3,1)}.confirm-modal-title{font-size:1.125rem;font-weight:700;letter-spacing:-.02em;margin-bottom:var(--space-xs)}.confirm-modal-subtitle{font-size:.8rem;color:var(--color-muted);margin-bottom:var(--space-sm)}.confirm-modal-message{font-size:.9375rem;color:var(--color-text-secondary);margin-bottom:var(--space-lg);line-height:1.5}.confirm-modal-actions{display:flex;gap:var(--space-sm);justify-content:center}.confirm-modal-actions .btn{flex:1;padding:10px var(--space-lg);font-size:.875rem}.choice-options-stacked{flex-direction:column}.permission-modal{text-align:left;max-width:400px}.permission-modal .confirm-modal-title{text-align:center}.permission-modal .confirm-modal-message{text-align:center;word-break:break-word}.permission-list{display:flex;flex-direction:column;gap:var(--space-xs);margin-bottom:var(--space-lg)}.permission-item{display:flex;flex-direction:column;gap:2px;padding:var(--space-sm);background:var(--color-hover);border-radius:var(--radius-sm)}.permission-name{font-size:.8125rem;font-weight:600;color:var(--color-text)}.permission-desc{font-size:.75rem;color:var(--color-text-secondary);line-height:1.4}.permission-actions{display:flex;gap:var(--space-sm)}.permission-actions .btn{flex:1;padding:10px var(--space-md);font-size:.875rem}.permission-abort-link{display:block;width:100%;margin-top:var(--space-sm);background:none;border:none;color:var(--color-error);font-size:.8125rem;cursor:pointer;text-align:center;padding:var(--space-xs) 0;opacity:.8}.permission-abort-link:hover:not(:disabled){opacity:1;text-decoration:underline}.permission-abort-link:disabled{opacity:.45;cursor:not-allowed}.input-modal{text-align:left;max-width:400px}.input-modal .confirm-modal-title{text-align:center}.input-modal .confirm-modal-message{text-align:center;word-break:break-word}.input-list{display:flex;flex-direction:column;gap:var(--space-md);margin-bottom:var(--space-lg)}.input-item{display:flex;flex-direction:column;gap:var(--space-xs)}.input-label{font-size:.8125rem;font-weight:600;color:var(--color-text)}.input-field{width:100%;padding:var(--space-sm) var(--space-md);font-size:.875rem;border:1px solid var(--color-border);border-radius:var(--radius-sm);background:var(--color-surface);color:var(--color-text);box-sizing:border-box}.input-field:focus{outline:none;border-color:var(--color-primary);box-shadow:0 0 0 2px rgba(var(--color-primary-rgb, 99, 102, 241),.2)}.input-save-toggle{margin-bottom:var(--space-lg)}.input-actions{display:flex;gap:var(--space-sm)}.input-actions .btn{flex:1;padding:10px var(--space-md);font-size:.875rem}.passwords-dialog{text-align:left;max-width:420px}.passwords-dialog .confirm-modal-title{text-align:center}.passwords-dialog-scroll{max-height:min(50vh,400px);overflow-y:auto;margin-bottom:var(--space-lg);scrollbar-width:thin;scrollbar-color:var(--color-border) transparent}.passwords-empty{font-size:.875rem;color:var(--color-muted);text-align:center;padding:var(--space-md) 0;line-height:1.5}.passwords-list{list-style:none;margin:0;padding:0}.password-item{display:flex;align-items:center;gap:var(--space-sm);padding:var(--space-sm) 0;border-bottom:1px solid var(--color-border)}.password-item:last-child{border-bottom:none}.password-item-text{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0}.password-item-origin{font-size:.875rem;font-weight:500;color:var(--color-text);overflow-wrap:anywhere}.password-item-username{font-size:.8125rem;color:var(--color-muted);overflow-wrap:anywhere}.password-delete-btn{display:flex;align-items:center;justify-content:center;width:28px;height:28px;border:none;background:none;cursor:pointer;color:var(--color-muted);border-radius:6px;flex-shrink:0;opacity:.7;transition:all var(--transition-fast)}.password-delete-btn:hover{color:var(--color-error);background:var(--color-error-bg);opacity:1}.host-picker-inline{margin:0 calc(var(--space-sm) * -1)}.host-picker-list{max-height:240px;overflow-y:auto;overflow-x:hidden;padding:2px var(--space-sm);scrollbar-width:thin;scrollbar-color:var(--color-border) transparent}.host-picker-list::-webkit-scrollbar{width:6px}.host-picker-list::-webkit-scrollbar-thumb{background:var(--color-border);border-radius:3px}.host-picker-item-wrapper{position:relative}.host-picker-item{position:relative;display:flex;align-items:center;gap:8px;padding:9px 12px 9px 14px;margin:1px 0;border:none;background:none;cursor:pointer;font-family:var(--font-sans);font-size:.8125rem;color:var(--color-text-secondary);text-align:left;border-radius:8px;transition:background var(--transition-fast),color var(--transition-fast);-webkit-tap-highlight-color:transparent}.host-picker-item:hover{background:var(--color-border-subtle);color:var(--color-text)}.host-picker-item-active{background:var(--color-primary-subtle);color:var(--color-text);font-weight:500}.host-picker-item-active:hover{background:var(--color-primary-subtle)}.host-picker-item-active:before{content:"";position:absolute;left:4px;top:9px;bottom:9px;width:2px;border-radius:2px;background:var(--color-primary)}.host-picker-item-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:flex;align-items:center;gap:6px}.host-picker-pending{font-size:.6875rem;font-weight:500;color:var(--color-muted);background:var(--color-border-subtle);padding:1px 6px;border-radius:4px;flex-shrink:0}.host-picker-item-actions{flex-shrink:0;width:24px;display:flex;align-items:center;justify-content:center}.host-picker-edit-btn{display:flex;align-items:center;justify-content:center;width:22px;height:22px;border:none;background:none;cursor:pointer;color:var(--color-muted);border-radius:6px;flex-shrink:0;opacity:.7;transition:all var(--transition-fast)}.host-picker-item:hover .host-picker-edit-btn,.host-picker-edit-btn:focus-visible{opacity:1}.host-picker-edit-btn:hover{color:var(--color-primary);background:#2e5ce51f;opacity:1}.host-picker-rename-input{font-size:.8125rem!important;padding:3px 6px!important;flex:1;min-width:0}.host-picker-delete-btn{display:flex;align-items:center;justify-content:center;width:22px;height:22px;border:none;background:none;cursor:pointer;color:var(--color-muted);border-radius:6px;flex-shrink:0;opacity:.7;transition:all var(--transition-fast)}@media(hover:hover)and (pointer:fine){.host-picker-delete-btn{opacity:0}.host-picker-item:hover .host-picker-delete-btn,.host-picker-delete-btn:focus-visible{opacity:.7}}.host-picker-delete-btn:hover{color:var(--color-error);background:var(--color-error-bg);opacity:1}.hamburger-btn{display:flex;align-items:center;justify-content:center;width:40px;height:40px;padding:0;border:none;background:none;color:var(--color-text-secondary);cursor:pointer;border-radius:var(--radius-sm);transition:background var(--transition-fast),color var(--transition-fast);-webkit-tap-highlight-color:transparent}.hamburger-btn:hover{background:var(--color-border-subtle);color:var(--color-text)}.hamburger-btn:active{background:var(--color-primary-subtle);color:var(--color-primary)}.drawer-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:var(--color-overlay);z-index:100;animation:drawerFadeIn .2s ease}.drawer-panel{position:fixed;top:0;left:0;bottom:0;width:296px;max-width:84vw;background:var(--color-surface);box-shadow:var(--shadow-xl);z-index:101;display:flex;flex-direction:column;overflow-y:auto;overscroll-behavior:contain;animation:drawerSlideIn .25s ease;scrollbar-width:thin;scrollbar-color:var(--color-border) transparent}.drawer-panel::-webkit-scrollbar{width:6px}.drawer-panel::-webkit-scrollbar-thumb{background:var(--color-border);border-radius:3px}.drawer-close-btn{position:absolute;top:8px;right:8px;z-index:1;display:flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;border:none;background:none;color:var(--color-text-secondary);cursor:pointer;border-radius:var(--radius-sm);transition:background var(--transition-fast)}.drawer-close-btn:hover{background:var(--color-border-subtle);color:var(--color-text)}.drawer-section{padding:var(--space-md);display:flex;flex-direction:column;gap:var(--space-sm)}.drawer-section+.drawer-section{padding-top:0}.drawer-section:has(>.host-picker-inline){padding-bottom:var(--space-xs)}.drawer-section-label{font-size:.6875rem;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--color-muted);margin:0 0 var(--space-xs)}.drawer-section-hint{font-size:.8125rem;color:var(--color-muted);line-height:1.45;margin:0 0 var(--space-sm) 0}.pair-checkbox{display:flex;align-items:flex-start;gap:var(--space-sm);padding:var(--space-sm) 0;cursor:pointer}.pair-checkbox input[type=checkbox]{margin-top:.2rem;flex-shrink:0}.pair-checkbox-text{display:flex;flex-direction:column;gap:.15rem}.pair-checkbox-title{font-size:.9375rem;font-weight:500}.pair-checkbox-hint{font-size:.8125rem;color:var(--color-muted);line-height:1.4}.drawer-toggle-group{display:flex;flex-direction:column;gap:var(--space-sm)}.drawer-toggle-group-divided{border-top:1px solid var(--color-border);padding-top:var(--space-sm);margin-top:var(--space-xs)}.drawer-toggle{display:flex;align-items:center;justify-content:space-between;gap:var(--space-sm)}.drawer-toggle-label{font-size:.85rem;color:var(--color-text)}.toggle-switch{position:relative;width:40px;height:22px;border-radius:11px;border:none;background:var(--color-border);cursor:pointer;padding:0;transition:background .2s;flex-shrink:0}.toggle-switch-on{background:var(--color-primary)}.toggle-switch-thumb{position:absolute;top:2px;left:2px;width:18px;height:18px;border-radius:50%;background:#fff;transition:transform .2s}.toggle-switch-on .toggle-switch-thumb{transform:translate(18px)}.toggle-switch:disabled{opacity:.5;cursor:not-allowed}.drawer-footer{margin-top:auto;padding:var(--space-md);display:flex;flex-direction:column;gap:var(--space-md);border-top:1px solid var(--color-border-subtle)}.drawer-version{font-size:.75rem;color:var(--color-muted);font-variant-numeric:tabular-nums}.drawer-agents{display:flex;flex-direction:column;gap:var(--space-sm)}.drawer-agents-section{display:flex;flex-direction:column;gap:3px}.drawer-agents-heading{font-size:.6875rem;font-weight:600;color:var(--color-muted);text-transform:uppercase;letter-spacing:.06em;margin-bottom:2px}.drawer-agents-row{display:flex;justify-content:space-between;align-items:baseline;gap:var(--space-sm);font-size:.75rem;color:var(--color-text-secondary)}.drawer-agents-version{font-variant-numeric:tabular-nums;color:var(--color-muted)}.drawer-host-info{display:flex;flex-direction:column;gap:3px}.drawer-host-time{font-size:.75rem;color:var(--color-text-secondary);font-variant-numeric:tabular-nums}.drawer-legal{display:flex;align-items:center;flex-wrap:wrap;gap:0 var(--space-xs);font-size:.6875rem;color:var(--color-muted);letter-spacing:.02em}.drawer-legal a{color:var(--color-muted);text-decoration:none;transition:color var(--transition-fast)}.drawer-legal a:hover{color:var(--color-primary)}.drawer-legal-sep{opacity:.55}.drawer-divider{height:1px;background:var(--color-border-subtle);margin:0 var(--space-md)}@keyframes drawerFadeIn{0%{opacity:0}to{opacity:1}}@keyframes drawerFadeOut{0%{opacity:1}to{opacity:0}}@keyframes drawerSlideIn{0%{transform:translate(-100%)}to{transform:translate(0)}}@keyframes drawerSlideOut{0%{transform:translate(0)}to{transform:translate(-100%)}}.drawer-overlay-closing{animation:drawerFadeOut .2s ease forwards}.drawer-panel-closing{animation:drawerSlideOut .2s ease forwards}.app-header{position:sticky;top:0;z-index:10;background:color-mix(in srgb,var(--color-surface) 92%,transparent);border-bottom:1px solid var(--color-border);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.app-title-bar{position:relative;display:flex;align-items:center;justify-content:center;padding:8px 0}.app-title-bar .hamburger-btn{position:absolute;left:4px;top:50%;transform:translateY(-50%)}.app-title{margin:0;font-size:1rem;font-weight:700;letter-spacing:-.01em;color:#1e3a8a}.conn-status{position:absolute;right:4px;top:50%;transform:translateY(-50%);display:inline-flex;color:#60a5fa}.conn-status--lan{color:#2563eb}.conn-status--disconnected{color:#dc2626}.conn-status-btn{background:none;border:none;padding:4px 8px;cursor:pointer;line-height:1;display:inline-flex;align-items:center;justify-content:center;border-radius:6px;color:inherit}.conn-status-btn:hover,.conn-status-btn:focus-visible{background:var(--color-bg);outline:none}.conn-status-popover{position:absolute;top:calc(100% + 6px);right:0;background:var(--color-text);color:var(--color-surface);font-size:.75rem;font-weight:500;padding:6px 10px;border-radius:6px;white-space:nowrap;pointer-events:none;opacity:0;transform:translateY(-2px);transition:opacity .12s,transform .12s;z-index:20}.conn-status:hover .conn-status-popover,.conn-status-popover--open{opacity:1;transform:translateY(0)}.conn-status--connecting .conn-status-btn>svg{animation:conn-status-pulse 1.2s ease-in-out infinite}@keyframes conn-status-pulse{0%,to{opacity:.35}50%{opacity:1}}.tab-bar{display:flex;align-items:center}.tab-btn{flex:1;display:flex;align-items:center;justify-content:center;gap:6px;padding:12px 0;border:none;background:none;font-family:var(--font-sans);font-size:.875rem;font-weight:600;color:var(--color-text-secondary);cursor:pointer;border-bottom:2px solid transparent;transition:color var(--transition-fast),border-color var(--transition-fast)}.tab-icon{flex-shrink:0}.tab-btn:hover{color:var(--color-text)}.tab-btn-active{color:var(--color-primary);border-bottom-color:var(--color-primary)}.sessions-view{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center}.sessions-card{background:var(--color-surface);border-radius:var(--radius-md);border:1px solid var(--color-border);box-shadow:var(--shadow-sm);padding:var(--space-md);display:flex;align-items:center;gap:var(--space-sm);cursor:pointer;transition:box-shadow var(--transition-base),border-color var(--transition-base);-webkit-tap-highlight-color:transparent}.sessions-card:hover{box-shadow:var(--shadow-md);border-color:#cbd5e1}.sessions-card-body{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--space-xs)}.sessions-card-name{font-size:.9375rem;font-weight:600;letter-spacing:-.01em;color:var(--color-text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.sessions-card-meta{display:flex;flex-wrap:wrap;gap:var(--space-sm);font-size:.75rem;color:var(--color-text-secondary)}.sessions-card-chevron{flex-shrink:0;align-self:center;color:var(--color-text-secondary);font-size:1.25rem;line-height:1;opacity:.4;transition:opacity var(--transition-base)}.sessions-card:hover .sessions-card-chevron{opacity:.8}.star-button{flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;margin:-8px 0;border:none;border-radius:var(--radius-full);background:none;cursor:pointer;color:var(--color-muted);transition:color var(--transition-fast),background var(--transition-fast);-webkit-tap-highlight-color:transparent}.star-button:hover{background:var(--color-hover)}.star-button--on{color:var(--color-warning)}.star-button:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}.sessions-filter-chip{display:inline-flex;align-items:center;gap:var(--space-xs);padding:4px 10px;font-size:.8125rem;color:var(--color-text-secondary);background:var(--color-bg);border:1px solid var(--color-border);border-radius:999px}.sessions-filter-chip button{display:inline-flex;align-items:center;justify-content:center;border:none;background:none;cursor:pointer;padding:0;color:var(--color-text-secondary);font-size:1rem;line-height:1}.sessions-filter-chip button:hover{color:var(--color-text)}.run-detail{display:flex;flex-direction:column;gap:var(--space-md);background:var(--color-surface);border-radius:var(--radius-md);border:1px solid var(--color-border);box-shadow:var(--shadow-sm);padding:var(--space-md)}.run-detail-header{display:flex;align-items:center;justify-content:space-between}.run-detail-back{display:inline-flex;align-items:center;gap:var(--space-xs);align-self:flex-start;border:none;background:none;cursor:pointer;padding:0;color:var(--color-text-secondary);font-size:.8125rem}.run-detail-back:hover{color:var(--color-text)}.run-detail-back--footer{align-self:center;margin-top:var(--space-sm);padding:8px 16px;border:1px solid var(--color-border);border-radius:var(--radius-md)}.run-detail-back--footer:hover{background:var(--color-surface-hover, var(--color-bg))}.chat-thread{display:flex;flex-direction:column;gap:var(--space-sm);overflow-y:auto;flex:1;min-height:0}.chat-message{display:flex;flex-direction:column;gap:var(--space-xs);max-width:85%;min-width:0;padding:var(--space-sm) var(--space-md);border-radius:var(--radius-md);font-size:.8125rem;line-height:1.6}.chat-message--assistant{align-self:flex-start;background:var(--color-surface);border:1px solid var(--color-border)}.chat-message--user{align-self:flex-end;background:var(--color-primary-subtle);border:1px solid var(--color-border-subtle)}.chat-message--assistant.chat-message--stderr .chat-message-content,.chat-message--assistant.chat-message--stderr .chat-message-content pre,.chat-message--assistant.chat-message--stderr .chat-message-content code{color:var(--color-error)}.chat-message-agent{font-size:.6875rem;font-weight:500;color:var(--color-text-tertiary);margin-bottom:var(--space-xs)}.chat-message-agent-version,.chat-message-agent-model{font-weight:400;opacity:.7}.chat-message-content{color:var(--color-text);overflow-wrap:break-word}.chat-message-content h1,.chat-message-content h2,.chat-message-content h3,.chat-message-content h4{margin:.75em 0 .25em;font-weight:600}.chat-message-content h1{font-size:1.1rem}.chat-message-content h2{font-size:1rem}.chat-message-content h3{font-size:.9375rem}.chat-message-content p{margin:.5em 0}.chat-message-content ul,.chat-message-content ol{margin:.5em 0;padding-left:1.5em}.chat-message-content code{font-size:.8em;background:var(--color-hover);padding:.15em .35em;border-radius:4px}.chat-message-content pre{background:var(--color-bg);border-radius:var(--radius-sm);padding:var(--space-sm);overflow-x:auto;margin:.5em 0}.chat-message-content pre code{background:none;padding:0}.chat-message-content table{border-collapse:collapse;width:100%;margin:.5em 0}.chat-message-content th,.chat-message-content td{border:1px solid var(--color-border);padding:.35em .6em;text-align:left}.chat-message-content th{background:var(--color-bg);font-weight:600}.chat-message-meta{display:flex;align-items:center;gap:var(--space-xs);font-size:.6875rem;color:var(--color-muted)}.chat-message-type{font-weight:600;text-transform:uppercase;letter-spacing:.04em;font-size:.625rem}.chat-message-attachments{display:flex;flex-wrap:wrap;gap:var(--space-xs)}.chat-attachment-chip{display:inline-flex;align-items:center;padding:.2em .6em;font-size:.75rem;background:var(--color-bg);border:1px solid var(--color-border);border-radius:var(--radius-sm);cursor:pointer;color:var(--color-primary);font-weight:500}.chat-attachment-chip:hover{background:var(--color-primary-subtle)}.chat-message-report{margin-top:var(--space-xs);padding:var(--space-sm);background:var(--color-bg);border-radius:var(--radius-sm);border:1px solid var(--color-border);font-size:.8125rem;line-height:1.6;color:var(--color-text-secondary)}.chat-status{display:flex;flex-direction:column;align-items:center;gap:var(--space-xs);font-size:.6875rem;color:var(--color-muted);padding:var(--space-xs) 0}.chat-status>div{display:flex;align-items:center;gap:var(--space-xs)}.chat-status--error{color:var(--color-error)}.chat-status-detail{margin-top:var(--space-xs);padding:var(--space-sm);background:var(--color-bg);border:1px solid var(--color-border);border-radius:var(--radius-sm);font-size:.75rem;font-family:SF Mono,Fira Code,monospace;white-space:pre-wrap;word-break:break-word;max-width:100%;max-height:200px;overflow-y:auto;color:var(--color-text-secondary)}.chat-status-time{color:var(--color-muted)}.chat-stop-btn{display:flex;align-items:center;justify-content:center;width:36px;height:36px;padding:0;border-radius:50%;flex-shrink:0;margin-left:auto;background:var(--color-error);color:#fff;border-color:var(--color-error)}.chat-stop-btn:hover:not(:disabled){background:#dc2626;border-color:#dc2626}.chat-input-bar{display:flex;gap:var(--space-xs);padding:var(--space-sm) 0;flex-shrink:0}.chat-input{flex:1;min-width:0;padding:var(--space-sm) var(--space-md);border:1px solid var(--color-border);border-radius:var(--radius-md);font-size:.8125rem;outline:none;background:var(--color-surface);color:var(--color-text)}.chat-input:focus{border-color:var(--color-primary);box-shadow:0 0 0 2px var(--color-primary-subtle)}.chat-input:disabled{opacity:.6}.chat-send-btn{display:flex;align-items:center;justify-content:center;width:36px;height:36px;padding:0;border-radius:50%;flex-shrink:0}.report-dialog-overlay{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1000;background:var(--color-overlay);display:flex;align-items:stretch;justify-content:center}.report-dialog{display:flex;flex-direction:column;width:100%;max-width:800px;background:var(--color-surface);overflow:hidden}.report-dialog-header{display:flex;align-items:center;justify-content:space-between;padding:var(--space-sm) var(--space-md);border-bottom:1px solid var(--color-border);flex-shrink:0}.report-dialog-title{font-size:.875rem;font-weight:600;color:var(--color-text)}.report-dialog-close{display:flex;align-items:center;justify-content:center;border:none;background:none;cursor:pointer;color:var(--color-text-secondary);padding:4px;border-radius:var(--radius-sm)}.report-dialog-close:hover{background:var(--color-hover);color:var(--color-text)}.report-dialog-body{flex:1;overflow-y:auto;padding:var(--space-md);font-size:.8125rem;line-height:1.6;color:var(--color-text)}.report-dialog-body h1,.report-dialog-body h2,.report-dialog-body h3,.report-dialog-body h4{margin:.75em 0 .25em;font-weight:600}.report-dialog-body h1{font-size:1.1rem}.report-dialog-body h2{font-size:1rem}.report-dialog-body h3{font-size:.9375rem}.report-dialog-body p{margin:.5em 0}.report-dialog-body img{max-width:100%;height:auto}.report-dialog-body ul,.report-dialog-body ol{margin:.5em 0;padding-left:1.5em}.report-dialog-body code{font-size:.8em;background:var(--color-hover);padding:.15em .35em;border-radius:4px}.report-dialog-body pre{background:var(--color-bg);border-radius:var(--radius-sm);padding:var(--space-sm);overflow-x:auto;margin:.5em 0}.report-dialog-body pre code{background:none;padding:0}.report-dialog-body table{border-collapse:collapse;width:100%;margin:.5em 0}.report-dialog-body th,.report-dialog-body td{border:1px solid var(--color-border);padding:.35em .6em;text-align:left}.report-dialog-body th{background:var(--color-bg);font-weight:600}.report-dialog-body--frame{display:flex;padding:0}.file-viewer-frame{flex:1;width:100%;border:none;background:#fff}.file-viewer-text{margin:0;white-space:pre-wrap;word-break:break-word;font-size:.75rem}.file-viewer-loading{display:flex;flex-direction:column;gap:var(--space-sm)}.file-viewer-message{color:var(--color-text-secondary)}.file-viewer-download{display:flex;flex-direction:column;align-items:flex-start;gap:var(--space-sm)}.md-file-link{cursor:pointer}.md-file-image{max-width:100%;height:auto;cursor:zoom-in}.md-image-loading{display:block;width:100%;max-width:240px;height:6rem}.md-image-missing{font-style:italic;color:var(--color-text-secondary)}.chat-typing-indicator{display:flex;align-items:center;gap:4px;padding:4px 0}.chat-typing-indicator span{width:6px;height:6px;border-radius:50%;background:var(--color-muted);animation:chat-typing 1.4s infinite}.chat-typing-indicator span:nth-child(2){animation-delay:.2s}.chat-typing-indicator span:nth-child(3){animation-delay:.4s}@keyframes chat-typing{0%,60%,to{opacity:.3;transform:scale(.8)}30%{opacity:1;transform:scale(1)}}.pair-consent{font-size:.75rem;color:var(--color-muted);text-align:center;line-height:1.5}.pair-consent a{color:var(--color-muted);text-decoration:underline}.pair-consent a:hover{color:var(--color-text-secondary)}.dashboard-content{display:flex;flex-direction:column;flex:1;min-height:100dvh;max-width:800px;margin:0 auto;width:100%}.drawer-panel-desktop{position:sticky;top:0;height:100dvh;width:320px;min-width:320px;background:var(--color-surface);border-right:1px solid var(--color-border);display:flex;flex-direction:column;overflow-y:auto;overscroll-behavior:contain;animation:none}@media(min-width:768px){.dashboard{flex-direction:row}.dashboard-main{padding:var(--space-lg)}.fab{right:max(var(--space-lg),calc((100vw - 1080px)/2))}}.swipe-row{position:relative;overflow:hidden;touch-action:pan-y}.swipe-row-action{position:absolute;top:0;right:0;bottom:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;background:var(--color-error, #dc2626);color:#fff;border:none;font-size:.75rem;font-weight:600;cursor:pointer;padding:0}.swipe-row-action--hidden{visibility:hidden;transition:visibility 0s linear .2s}.swipe-row-action-label{font-size:.75rem;line-height:1}.swipe-row-action:focus-visible{outline:2px solid var(--color-accent, #2E5CE5);outline-offset:-4px}.swipe-row-content{position:relative;background:var(--color-surface);transition:transform .2s cubic-bezier(.22,1,.36,1);will-change:transform}.swipe-row-content-dragging{transition:none}.app-filter-help{margin-top:var(--space-xs)}.app-filter-trigger{display:inline-block;padding:0;font-size:.875rem;font-weight:500;text-align:left}.app-filter-selected{display:inline-flex;align-items:center;gap:var(--space-sm);padding:6px 10px;border:1px solid var(--color-border);border-radius:var(--radius-md);background:var(--color-surface);max-width:100%}.app-filter-selected-name{font-size:.9375rem;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.app-filter-selected-pkg{font-size:.75rem;color:var(--color-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.app-filter-selected-clear{display:flex;align-items:center;justify-content:center;width:22px;height:22px;padding:0;margin-left:auto;border:none;background:none;color:var(--color-muted);font-size:.875rem;cursor:pointer;border-radius:var(--radius-sm)}.app-filter-selected-clear:hover{background:var(--color-border-subtle);color:var(--color-text)}.app-filter-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:var(--color-overlay);display:flex;align-items:center;justify-content:center;z-index:1100;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);padding:var(--space-md)}.app-filter-dialog{background:var(--color-surface);width:100%;max-width:480px;max-height:80dvh;border-radius:var(--radius-lg);box-shadow:var(--shadow-xl);display:flex;flex-direction:column;overflow:hidden}.app-filter-header{display:flex;align-items:center;justify-content:space-between;padding:var(--space-md) var(--space-lg);border-bottom:1px solid var(--color-border)}.app-filter-header h2{margin:0;font-size:1rem;font-weight:600}.app-filter-close{display:flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;border:none;background:none;color:var(--color-muted);cursor:pointer;border-radius:var(--radius-sm)}.app-filter-close:hover{background:var(--color-border-subtle);color:var(--color-text)}.app-filter-search{margin:var(--space-md) var(--space-lg) 0;width:calc(100% - 2 * var(--space-lg))}.app-filter-list{flex:1;overflow-y:auto;list-style:none;margin:0;padding:var(--space-xs) 0 var(--space-md)}.app-filter-row{display:flex;align-items:center;gap:var(--space-md);padding:10px var(--space-lg);cursor:pointer;-webkit-user-select:none;user-select:none}.app-filter-row:hover{background:var(--color-hover, rgba(0, 0, 0, .04))}.app-filter-row-labels{display:flex;flex-direction:column;min-width:0;flex:1}.app-filter-row-name{font-size:.9375rem;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.app-filter-row-pkg{font-size:.75rem;color:var(--color-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.app-filter-empty{padding:var(--space-lg);text-align:center;color:var(--color-muted);font-size:.875rem}.app-filter-skeleton{cursor:default}.app-filter-skeleton-bar{flex:1;height:14px;border-radius:4px;background:linear-gradient(90deg,var(--color-border-subtle) 25%,var(--color-border) 50%,var(--color-border-subtle) 75%);background-size:200% 100%;animation:appFilterShimmer 1.2s ease-in-out infinite}@keyframes appFilterShimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.pair-setup{min-height:100dvh;display:flex;justify-content:center;padding:var(--space-lg);background:var(--color-bg)}.pair-setup-inner{width:100%;max-width:480px;display:flex;flex-direction:column;gap:var(--space-lg)}.pair-setup-title{margin:0;font-size:1.25rem;font-weight:600;line-height:1.35}.pair-setup-description{margin:0;color:var(--color-muted);font-size:.875rem}.pair-setup-loading{padding:var(--space-xl, 32px) var(--space-lg);min-height:200px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-md);color:var(--color-muted);font-size:.95rem}.pair-setup-actions{margin-top:var(--space-md)}
|
|
1
|
+
@font-face{font-family:Plus Jakarta Sans Variable;font-style:normal;font-display:swap;font-weight:200 800;src:url(data:font/woff2;base64,d09GMgABAAAAAAa0ABQAAAAADOwAAAZHAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhYbbhwoP0hWQVJtP01WQVJGBmA/U1RBVIEcAGQvXBEICoMkgmcLFgAwhEwBNgIkAyYEIAWGXAdiDAcbOgtRlHLSRcD8TEzkdoghPRuspKefbVnJIM5yRfA8vZv9uTNJSCZY21Scrigr6qyJ/C3sE1OFKuVP3e+lxUTbYio1zb/kFdk2bufY2BlhWERRBrcDUBhB5GEpd2Cy+MDxqf9zLPX+XVsk5r+s50d6IpWLatqbdT6f2MAikiOKQocbjya2QT0DqPDX4R0jQBgAUAiCRhDA0EkvYeLk9X3I2bEWI8jBAihIANm+kUWQBgggWChcBBdFhXlAUgOCAgBA0AgKjUJ8HKvjddFCKSgAVklEBYAeEJgCQJH0qB3B+neDg4sAA4hAD0AVIEAA0IACJGeaUjMIIIhBUE/zNABjTQMBwEVRcwcYBUCObLERABAgjAA1M/ZSa9hSi4OlpsnZ2KBOVUsAZlRGl1W0NZ6gSwhQPIAFs7YFL0QS91vRQgdgx2VDAnIegKpQvwAJIoLgooBAGtCJcHizg0TDiz8vhPgIcVXaDJu37ZyDAIjFy4AAiC1JAA0olJwN6nFAACQk/zfQVUuA3t5ELKMT9hpBSRj+HBSggYCIAIEkUoC4PCIQIWHGA8+IStxf0PW15ntP22gc+Wo+BLyQAHECQiAVd+c3Ba8gZ4NOACBaLOhsbIMkAXEmuHsSAvkf4oJaAogH6nEQAzoBIEihUAwAA0AACAObAGcANYAAABaqgMmpWAhiiVyrvNyqFV8tMQ5Iyq6r9Lf7W82i8ILl2cv8zbfdJ5lnPzSnvt/XXPfRR/5pH3xA+u5uS0798EPJ3Fft33w36Wc+8E/7aIB/9fvvb1pE9erNXLB9mkw//cSg8Cnx03VGXDvZnRzKqV9Xkhn7eRHb3wVjHpg19nkZpX9bBU+vnHegrsuQcbW9Bi7oO33h+8SU0Tly/MbeYUuG1cftVz6oNxrW0qH1iezq446fkDFo/rgvTkqt7zmteFzncZ0uxXti09FFF2z+C7CODpjUudOE5NSeb3bv/mbPKcmOEzpWQ3VBgBAuj/AOY3qMm7UvgA8qo3+qvAUBBAX0wADQG4AG+jCKaSxkBe/zvcTG8jRpRZgqhCog4sd++cOo7J+/RdvaaMoc78Ri/PNPSclx6fDvG1Kt3qQFi1rq+5EaavTtt9TVvfvucYsA5wc4oESU+E1ikF9TkrOkIsIH5Fawx7SBNLnMcWlM3skBluCmQNs7GeyFvYVDamsqwhxx18n/+WdxzDgOLU1AqbUlb3m+KOT9+ONvY/7XlrdLS//5v7nN97XHj0VzJpJvz4spq0V7ioXDuv2YrSxtF/KZmvbWfKtorXSh8dfvgGu+ev/nFSaXM6jyuCE/f/EpmuP7Rqu8R98vP/+tXUdrOgKlZP9Q/s+fRF9+3CHZd4EugfPv158me9X7v/6aSMCxMJmIr//65bNXngl7+uiPP5oKx+y27D8trp+psUzMacpm80XlnYeMAct0LynxhNYgaP3dtn8/LBAi+ksr+7NvjjtJV+UXrz0uLXV1x08AZRN1S2A8EaVE5afk/dfGjz//+fdHn36Xdttz2d9/z+bawZ8/slNN1aYtq+ZPGzNuPGdwOsfYflwmHCkPgs5DcKizvdpS/3gEUMW9/lvQvWp1bGTW1fpngC/uSVYAfH3TeSusL8TtlHUD4KAAEHjahk4YpuffGwEBN/dUmpHqdHyJ3Ap8O3UlQ4gCNrMRwLBBKiskL6a+RoBi/9XGlgc8L4/CUejQxaiIyqmomdhktOhfgDbDfaNDb4+yKIPd6IgmzDa0CByijWFmL2dlSRKagTIWXeIU9HDphoZiJeBTjAefHMxDhVSRFUgVcOkW3EGMahYVMFjWHhMluB2wAcbHYqF1LpsDF9C6s+CI2fDgh4wSuFEyGadjXAmIk3CugIRibLIti9ZtC8S4VSqfikGqPaoI122XyRYLBmsOmdiiTpqK1OklUQzpMcZmQRQV4M4oJCMkfRQXK+qvjifUcQd1bRdetW/LWjacYxvcttnVjWg5h0q4xw6rZyejSpZVZ78LzC4uyDNRQ4bymHSTMyM+SZ7D75mg/7YTlmNz7W8T00h0VEiGKB+F7iWYZFvSTiA4LVxttm2ATt5EoUWLJbY4EnLGrfsvEROlHtzlKn3H9VUT5tU/2dt3/EBv7foYzV/W4upyj04woO/gh6Vwwt3WGQAA) format("woff2-variations");unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Plus Jakarta Sans Variable;font-style:normal;font-display:swap;font-weight:200 800;src:url(/assets/plus-jakarta-sans-vietnamese-wght-normal-qRpaaN48.woff2) format("woff2-variations");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Plus Jakarta Sans Variable;font-style:normal;font-display:swap;font-weight:200 800;src:url(/assets/plus-jakarta-sans-latin-ext-wght-normal-DmpS2jIq.woff2) format("woff2-variations");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Plus Jakarta Sans Variable;font-style:normal;font-display:swap;font-weight:200 800;src:url(/assets/plus-jakarta-sans-latin-wght-normal-eXO_dkmS.woff2) format("woff2-variations");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}:root{--color-bg: #F7F8FC;--color-surface: #ffffff;--color-primary: #2E5CE5;--color-primary-hover: #1D4ED8;--color-primary-subtle: #EEF2FF;--color-secondary: #64748B;--color-secondary-hover: #475569;--color-text: #1A1F36;--color-text-secondary: #697386;--color-muted: #94A3B8;--color-success: #22C55E;--color-error: #EF4444;--color-error-bg: #FEF2F2;--color-warning: #F59E0B;--color-border: #E2E8F0;--color-border-subtle: #F1F5F9;--color-hover: rgba(15, 23, 42, .06);--color-overlay: rgba(15, 23, 42, .5);--color-input-focus: rgba(46, 92, 229, .15);--shadow-xs: 0 1px 2px rgba(15, 23, 42, .05);--shadow-sm: 0 1px 3px rgba(15, 23, 42, .06), 0 1px 2px rgba(15, 23, 42, .04);--shadow-md: 0 4px 6px -1px rgba(15, 23, 42, .07), 0 2px 4px -2px rgba(15, 23, 42, .05);--shadow-lg: 0 10px 15px -3px rgba(15, 23, 42, .08), 0 4px 6px -4px rgba(15, 23, 42, .04);--shadow-xl: 0 20px 25px -5px rgba(15, 23, 42, .1), 0 8px 10px -6px rgba(15, 23, 42, .06);--radius-sm: 8px;--radius-md: 12px;--radius-lg: 16px;--radius-full: 50%;--font-sans: "Plus Jakarta Sans Variable", "Plus Jakarta Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;--space-xs: 4px;--space-sm: 8px;--space-md: 16px;--space-lg: 24px;--space-xl: 32px;--space-2xl: 48px;--transition-fast: .12s ease;--transition-base: .2s ease}*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}html{font-size:16px;-webkit-text-size-adjust:100%}body{font-family:var(--font-sans);background:var(--color-bg);color:var(--color-text);line-height:1.6;min-height:100dvh;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;overscroll-behavior-y:contain}.pull-to-refresh{position:fixed;top:-48px;left:0;right:0;height:48px;display:flex;align-items:center;justify-content:center;pointer-events:none;z-index:40;transition:opacity .15s}.pull-to-refresh-badge{width:40px;height:40px;border-radius:50%;background:var(--color-surface);border:1px solid var(--color-border);box-shadow:var(--shadow-md);display:flex;align-items:center;justify-content:center;color:var(--color-text-secondary)}#root{min-height:100dvh}.btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;border:1px solid transparent;border-radius:var(--radius-sm);font-family:var(--font-sans);font-size:.875rem;font-weight:600;padding:10px 18px;cursor:pointer;transition:all var(--transition-base);-webkit-tap-highlight-color:transparent;letter-spacing:-.01em;line-height:1.25}.btn:disabled{opacity:.45;cursor:not-allowed}.btn:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}.btn-primary{background:var(--color-primary);color:#fff;box-shadow:0 1px 2px #2e5ce54d,inset 0 1px #ffffff1a}.btn-primary:hover:not(:disabled){background:var(--color-primary-hover);box-shadow:0 2px 4px #2e5ce559,inset 0 1px #ffffff1a;transform:translateY(-.5px)}.btn-primary:active:not(:disabled){transform:translateY(0);box-shadow:0 1px 2px #2e5ce54d}.btn-secondary{background:var(--color-surface);color:var(--color-text);border-color:var(--color-border);box-shadow:var(--shadow-xs)}.btn-secondary:hover:not(:disabled){background:var(--color-border-subtle);border-color:#cbd5e1}.btn-danger{background:var(--color-error);color:#fff;box-shadow:0 1px 2px #ef44444d}.btn-danger:hover:not(:disabled){background:#dc2626;box-shadow:0 2px 4px #ef444459}.btn-link{background:none;border:none;color:var(--color-primary);padding:0;font-weight:500;box-shadow:none}.btn-link:hover:not(:disabled){text-decoration:underline;background:none;box-shadow:none}.btn-spinner{display:inline-block;width:14px;height:14px;border:2px solid rgba(255,255,255,.3);border-top-color:#fff;border-radius:50%;animation:spin .6s linear infinite;vertical-align:middle;margin-right:6px}.btn-spinner-current{border-color:#7f7f7f40;border-top-color:currentColor}.btn-sm{font-size:.8125rem;padding:6px 12px;border-radius:6px}.btn-full{width:100%}.form-label{display:flex;flex-direction:column;gap:6px;font-size:.8125rem;font-weight:600;color:var(--color-text);margin-bottom:var(--space-md);letter-spacing:-.01em}.form-input,.form-textarea,.form-select{font-family:var(--font-sans);font-size:.9375rem;padding:10px 12px;border:1.5px solid var(--color-border);border-radius:var(--radius-sm);background:var(--color-surface);color:var(--color-text);transition:border-color var(--transition-fast),box-shadow var(--transition-fast);width:100%}.form-input:focus,.form-textarea:focus,.form-select:focus{outline:none;border-color:var(--color-primary);box-shadow:0 0 0 3px var(--color-input-focus)}.form-input-mono{font-family:SF Mono,Fira Code,Cascadia Code,monospace;font-size:.8125rem}.form-input::placeholder,.form-textarea::placeholder{color:var(--color-muted)}.form-textarea{resize:vertical;min-height:80px;line-height:1.5}.form-error{background:var(--color-error-bg);color:var(--color-error);border:1px solid #FECACA;border-radius:var(--radius-sm);padding:var(--space-sm) var(--space-md);font-size:.8125rem;font-weight:500;margin-bottom:var(--space-md)}.form-warning{background:#fef3c7;color:#92400e;border:1px solid #FDE68A;border-radius:var(--radius-sm);padding:var(--space-sm) var(--space-md);font-size:.8125rem;font-weight:500;margin-bottom:var(--space-md)}.dashboard{min-height:100dvh;display:flex;flex-direction:column;padding-bottom:0}.dashboard-main{flex:1;padding:var(--space-md);width:100%}.status-dot{display:inline-block;width:8px;height:8px;border-radius:var(--radius-full);flex-shrink:0;box-shadow:0 0 0 2px #fffc}.status-spinner{display:inline-flex;align-items:center;gap:2px;flex-shrink:0;height:8px}.status-spinner:before,.status-spinner>span,.status-spinner:after{content:"";display:block;width:3px;height:3px;border-radius:var(--radius-full);background-color:var(--color-success);animation:marching-dot 1.2s ease-in-out infinite}.status-spinner:before{animation-delay:0s}.status-spinner>span{animation-delay:.2s}.status-spinner:after{animation-delay:.4s}@keyframes marching-dot{0%,60%,to{opacity:.25;transform:scale(.8)}30%{opacity:1;transform:scale(1)}}.pair-page{display:flex;align-items:flex-start;justify-content:center;min-height:100dvh;padding:var(--space-xl) var(--space-md);background:var(--color-bg)}.pair-card{width:100%;max-width:420px;display:flex;flex-direction:column;gap:var(--space-lg)}.pair-header{text-align:center}.pair-title{font-size:1.5rem;font-weight:700;color:var(--color-text);letter-spacing:-.02em}.pair-subtitle{margin-top:var(--space-xs);font-size:.875rem;color:var(--color-text-secondary)}.pair-instructions{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-md);padding:var(--space-md);display:flex;flex-direction:column;gap:var(--space-md)}.pair-instruction-block{display:flex;flex-direction:column;gap:var(--space-sm)}.pair-instruction-heading{font-size:.8125rem;font-weight:600;color:var(--color-text);letter-spacing:-.01em}.pair-steps{list-style:none;counter-reset:pair-step;display:flex;flex-direction:column;gap:6px;padding:0}.pair-steps li{counter-increment:pair-step;font-size:.8125rem;color:var(--color-text-secondary);line-height:1.5;display:flex;flex-wrap:wrap;gap:0 var(--space-sm)}.pair-steps li:before{content:counter(pair-step) ".";font-weight:600;color:var(--color-muted);min-width:16px;flex-shrink:0}.pair-steps li .pair-command{flex-basis:100%}.pair-steps code{font-family:SF Mono,Fira Code,Cascadia Code,monospace;font-size:.75rem;background:var(--color-bg);border:1px solid var(--color-border);border-radius:4px;padding:1px 5px;color:var(--color-text);white-space:nowrap}.pair-command{display:block;margin-top:4px;padding:6px 10px!important;border-radius:var(--radius-sm)!important;overflow-x:auto;-webkit-overflow-scrolling:touch}.pair-platform-label{display:block;flex-basis:100%;margin-top:8px;font-size:.75rem;font-weight:600;color:var(--color-muted)}.pair-instruction-divider{height:1px;background:var(--color-border)}.pair-form{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-md);padding:var(--space-lg);display:flex;flex-direction:column;gap:var(--space-md);box-shadow:var(--shadow-sm)}.pair-code-input{font-size:1.5rem!important;letter-spacing:.25em;text-align:center;padding:14px 12px!important;text-transform:uppercase}.pair-code-input::placeholder{letter-spacing:.25em;opacity:.35}.pair-label-hint{font-weight:400;color:var(--color-muted);font-size:.75rem}.pair-error{font-size:.8125rem;color:var(--color-error);background:var(--color-error-bg);padding:var(--space-sm) var(--space-md);border-radius:var(--radius-sm);line-height:1.4}.loading-state,.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:var(--space-2xl) 0;gap:var(--space-sm)}.empty-state-text{font-size:1rem;font-weight:600;color:var(--color-text-secondary)}.empty-state-hint{font-size:.8125rem;color:var(--color-muted)}.revoked-state{display:flex;flex-direction:column;align-items:center;text-align:center;padding:var(--space-2xl) var(--space-lg);margin:var(--space-md) 0;background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-md);animation:revokedFadeIn .35s ease}@keyframes revokedFadeIn{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}.revoked-icon{width:56px;height:56px;display:flex;align-items:center;justify-content:center;border-radius:var(--radius-full);background:var(--color-error-bg);color:var(--color-error);margin-bottom:var(--space-md)}.revoked-title{font-size:1.125rem;font-weight:700;color:var(--color-text);margin-bottom:var(--space-xs)}.revoked-description{font-size:.875rem;line-height:1.6;color:var(--color-text-secondary);max-width:320px;margin-bottom:var(--space-lg)}.revoked-command{padding:8px 16px;background:var(--color-bg);border:1px solid var(--color-border);border-radius:var(--radius-sm);margin-bottom:var(--space-lg)}.revoked-command code{font-family:SF Mono,Fira Code,Cascadia Code,monospace;font-size:.8125rem;color:var(--color-text);letter-spacing:-.01em}.revoked-actions{display:flex;gap:var(--space-sm);width:100%;max-width:280px}.revoked-actions .btn{flex:1}.spinner{width:24px;height:24px;border:2.5px solid var(--color-border);border-top-color:var(--color-primary);border-radius:var(--radius-full);animation:spin .7s linear infinite}.spinner-lg{width:40px;height:40px;border-width:3px}.capability-toggles-loading{display:flex;justify-content:center;padding:var(--space-lg)}@keyframes spin{to{transform:rotate(360deg)}}.session-composer{background:var(--color-surface);border-radius:var(--radius-md);border:1px solid var(--color-border);box-shadow:var(--shadow-sm);padding:var(--space-sm);margin-bottom:var(--space-md);display:flex;flex-direction:column;gap:var(--space-sm)}.session-composer:focus-within{border-color:var(--color-primary);box-shadow:0 0 0 2px var(--color-input-focus)}.session-composer-textarea{width:100%;border:none;resize:vertical;outline:none;background:transparent;color:var(--color-text);font-family:var(--font-sans);font-size:.9375rem;line-height:1.5;padding:var(--space-xs) var(--space-sm);min-height:3.5em}.session-composer-textarea::placeholder{color:var(--color-muted)}.session-composer-controls{display:flex;align-items:center;gap:var(--space-sm);padding-left:var(--space-xs)}.session-composer-yolo{display:inline-flex;align-items:center;gap:4px;font-size:.8rem;color:var(--color-text-secondary);cursor:pointer;-webkit-user-select:none;user-select:none}.session-composer-yolo input{margin:0;cursor:pointer}.session-composer-controls .chat-send-btn{margin-left:auto}.fab{position:fixed;right:var(--space-lg);bottom:calc(var(--space-lg) + env(safe-area-inset-bottom,0px));width:56px;height:56px;border-radius:50%;border:none;background:var(--color-primary);color:#fff;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:var(--shadow-lg);transition:background var(--transition-base),transform var(--transition-fast),box-shadow var(--transition-base);z-index:50;-webkit-tap-highlight-color:transparent}.fab:hover{background:var(--color-primary-hover);box-shadow:var(--shadow-xl);transform:translateY(-1px)}.fab:active{transform:translateY(0)}.fab:focus-visible{outline:2px solid var(--color-primary);outline-offset:3px}.section-label{font-size:.6875rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--color-muted);margin:var(--space-md) 0 var(--space-xs)}.agent-picker-section-inline{display:flex;align-items:center;gap:var(--space-xs)}.agent-picker-section-inline .form-select{width:auto;min-width:0;font-size:.8rem;padding:4px 8px}.agent-picker-section-inline .agent-picker-single{font-size:.8rem;color:var(--color-text)}.task-list{display:flex;flex-direction:column;gap:10px;padding-bottom:calc(56px + var(--space-lg) * 2 + env(safe-area-inset-bottom,0px))}.task-card{background:var(--color-surface);border-radius:var(--radius-md);border:1px solid var(--color-border);box-shadow:var(--shadow-sm);padding:var(--space-md);display:flex;flex-direction:column;gap:var(--space-sm);cursor:pointer;transition:box-shadow var(--transition-base),border-color var(--transition-base);-webkit-tap-highlight-color:transparent}.task-card:hover{box-shadow:var(--shadow-md);border-color:#cbd5e1}.task-card-header{display:flex;align-items:center;justify-content:space-between;gap:var(--space-sm)}.task-card-title-row{display:flex;align-items:center;gap:10px;min-width:0;flex:1}.task-card-name{font-size:.9375rem;font-weight:600;letter-spacing:-.01em;color:var(--color-text);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.task-card-meta{display:flex;flex-wrap:wrap;gap:var(--space-sm);font-size:.75rem;color:var(--color-text-secondary)}.task-card-agent{color:var(--color-text-tertiary)}.task-card-last-event-link{color:var(--color-primary);cursor:pointer;text-decoration:underline}.task-card-actions{display:flex;gap:var(--space-xs);flex-shrink:0}.task-card-menu{position:relative}.task-card-menu-btn{background:none;border:none;color:var(--color-text-secondary);font-size:1.5rem;min-width:44px;min-height:44px;display:flex;align-items:center;justify-content:center;border-radius:var(--radius-sm);cursor:pointer;line-height:1}.task-card-menu-btn:hover{background:var(--color-hover);color:var(--color-text)}.task-card-menu-dropdown{position:absolute;right:0;top:100%;margin-top:4px;background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-md);box-shadow:var(--shadow-md);min-width:150px;z-index:10;overflow:hidden}.task-card-menu-dropdown button{display:flex;align-items:center;gap:var(--space-sm);width:100%;text-align:left;padding:var(--space-sm) var(--space-md);background:none;border:none;font-size:.9375rem;color:var(--color-text);cursor:pointer;white-space:nowrap}.task-card-menu-dropdown button:hover{background:var(--color-hover)}.task-card-menu-dropdown .menu-item-danger{color:var(--color-error)}.menu-icon{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;font-size:.875rem;flex-shrink:0;line-height:1}.bottom-sheet-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:var(--color-overlay);z-index:1000;display:flex;align-items:flex-end;justify-content:center;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);animation:fadeIn var(--transition-fast)}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.bottom-sheet{background:var(--color-surface);border-radius:var(--radius-lg) var(--radius-lg) 0 0;width:100%;max-width:480px;padding:var(--space-sm) var(--space-md) var(--space-xl);box-shadow:var(--shadow-xl);animation:sheetSlideUp .25s cubic-bezier(.16,1,.3,1)}@keyframes sheetSlideUp{0%{transform:translateY(100%)}to{transform:translateY(0)}}.bottom-sheet-handle{width:36px;height:4px;background:var(--color-border);border-radius:2px;margin:0 auto var(--space-md)}.bottom-sheet-title{font-size:.9375rem;font-weight:600;color:var(--color-text);padding:0 var(--space-xs) var(--space-md);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.bottom-sheet-actions{display:flex;flex-direction:column}.bottom-sheet-actions button{display:flex;align-items:center;gap:var(--space-md);width:100%;text-align:left;padding:var(--space-md);background:none;border:none;border-radius:var(--radius-sm);font-size:.9375rem;font-family:var(--font-sans);color:var(--color-text);cursor:pointer;transition:background var(--transition-fast)}.bottom-sheet-actions button:active{background:var(--color-hover)}.bottom-sheet-actions .menu-item-danger{color:var(--color-error)}.task-form-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:transparent;display:flex;align-items:stretch;justify-content:center;z-index:100;padding:0;overflow:hidden;overscroll-behavior:contain}.task-form{background:var(--color-surface);border-radius:0;padding:var(--space-lg) var(--space-md);width:100%;max-width:none;max-height:none;overflow-y:auto;animation:slideUp .25s cubic-bezier(.16,1,.3,1);display:flex;flex-direction:column;gap:var(--space-md)}@media(min-width:600px){.task-form-overlay{background:var(--color-overlay);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);align-items:center;padding:var(--space-md)}.task-form{border-radius:var(--radius-lg);box-shadow:var(--shadow-xl);max-width:540px;max-height:90dvh;padding:var(--space-lg)}}@keyframes slideUp{0%{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}.task-form-header{display:flex;align-items:center;justify-content:space-between}.task-form h2{font-size:1.0625rem;font-weight:700;letter-spacing:-.02em;margin-bottom:0}.plan-actions{display:flex;gap:var(--space-sm);flex-wrap:wrap}.permissions-dialog{display:flex;flex-direction:column;gap:var(--space-md);overflow:hidden;flex:1;min-height:0}.permissions-dialog h2{margin:0;font-size:1.125rem}.permissions-dialog-scroll{flex:1;min-height:0;overflow-y:auto}.permissions-empty{color:var(--color-text-secondary);font-size:.875rem;font-style:italic;margin:var(--space-md) 0}.permissions-section{border-top:1px solid var(--color-border);padding-top:var(--space-md);margin-top:var(--space-md)}.permissions-section h3{margin:0 0 var(--space-xs) 0;font-size:.95rem}.permissions-list{margin:0;padding-left:1.25em}.permission-item{margin-bottom:var(--space-sm);display:flex;flex-direction:column}.permission-tool{font-weight:600;font-family:var(--font-mono, monospace)}.permission-desc{color:var(--color-text-secondary);font-size:.9em}.permissions-dialog-actions{display:flex;gap:var(--space-sm);align-items:center;justify-content:flex-end}@media(min-width:600px){.permissions-dialog{max-width:none}}.result-times{display:flex;flex-direction:column;gap:var(--space-xs);font-size:.8125rem;color:var(--color-text-secondary);margin-bottom:var(--space-sm)}.skeleton-line{height:.875rem;border-radius:var(--radius-sm);background:var(--color-border);animation:skeleton-pulse 1.2s ease-in-out infinite}@keyframes skeleton-pulse{0%,to{opacity:.4}50%{opacity:1}}.granted-permissions-row{flex-basis:100%}.granted-permissions-row .btn-link{padding:0}.schedule-section{display:flex;flex-direction:column;gap:var(--space-sm)}.schedule-section-title{font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--color-muted);margin:0}.schedule-section-hint{font-weight:400;text-transform:none;letter-spacing:0;color:var(--color-text-secondary);margin-left:6px}.schedule-reactive{display:flex;flex-direction:column;gap:var(--space-xs)}.yolo-inline{display:inline-flex;align-items:center;gap:4px;font-size:.8rem;color:var(--color-text-secondary);cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap}.yolo-inline input{margin:0;cursor:pointer}.yolo-warning{flex-basis:100%;margin:0;font-size:.75rem;color:var(--color-text-secondary);line-height:1.4}.trigger-row-card{display:flex;align-items:center;gap:8px;padding:4px 0}.trigger-row-content{display:flex;flex-direction:column;gap:4px;flex:1;min-width:0}.trigger-row-top{display:flex;align-items:center;gap:8px}.trigger-row-top .form-select{flex:0 0 auto;width:auto}.trigger-row-top .form-input{flex:1}.trigger-details{display:flex;gap:6px}.trigger-details .form-input[type=date]{flex:1;min-width:0}.trigger-details .form-input[type=time]{flex:0 0 auto;width:auto}.schedule-section>.form-select,.trigger-row-card .form-select,.trigger-row-card .form-input{margin-bottom:0;font-size:.8125rem;padding:6px 8px;height:32px;box-sizing:border-box;min-width:0}.schedule-section>.form-select{width:100%}.trigger-row-card .form-select,.trigger-row-card .form-input{flex:1}.trigger-remove-btn{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;border:none;border-radius:var(--radius-full);background:transparent;color:var(--color-muted);font-size:1.1rem;line-height:1;cursor:pointer;transition:all var(--transition-fast);flex-shrink:0}.trigger-remove-btn:hover{background:var(--color-error-bg);color:var(--color-error)}.trigger-add-btn{display:inline-flex;align-items:center;gap:4px;border:1px dashed var(--color-border);border-radius:var(--radius-sm);background:transparent;color:var(--color-text-secondary);font-family:var(--font-sans);font-size:.8125rem;font-weight:500;padding:8px 14px;cursor:pointer;transition:all var(--transition-fast);width:100%;justify-content:center}.trigger-add-btn:hover{border-color:var(--color-primary);color:var(--color-primary);background:var(--color-primary-subtle)}.form-select{width:auto;min-width:80px}.toggles-section{display:flex;flex-direction:column;gap:10px;margin-bottom:var(--space-md)}.toggle-label{display:flex;align-items:center;gap:10px;font-size:.875rem;font-weight:500;cursor:pointer;-webkit-tap-highlight-color:transparent;color:var(--color-text)}.toggle-label input[type=checkbox]{width:16px;height:16px;accent-color:var(--color-primary);border-radius:4px}.toggles-group{display:flex;flex-direction:column;gap:var(--space-xs)}.command-section,.command-section-active .toggle-label,.task-title-field,.task-title-help{margin-bottom:0}.command-help-text{font-size:.75rem;color:var(--color-text-secondary);line-height:1.4;margin:6px 0 10px}.command-section-active .form-input{font-size:.8125rem;padding:6px 8px;height:32px;box-sizing:border-box}.form-actions{display:flex;gap:var(--space-sm);position:sticky;bottom:0;background:var(--color-surface);padding:var(--space-sm) 0}.confirm-modal-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:var(--color-overlay);display:flex;align-items:center;justify-content:center;z-index:1000;padding:var(--space-md);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.confirm-modal{background:var(--color-surface);border-radius:var(--radius-lg);border:1px solid var(--color-border);padding:var(--space-xl);width:100%;max-width:380px;text-align:center;box-shadow:var(--shadow-xl);animation:slideUp .25s cubic-bezier(.16,1,.3,1)}.confirm-modal-title{font-size:1.125rem;font-weight:700;letter-spacing:-.02em;margin-bottom:var(--space-xs)}.confirm-modal-subtitle{font-size:.8rem;color:var(--color-muted);margin-bottom:var(--space-sm)}.confirm-modal-message{font-size:.9375rem;color:var(--color-text-secondary);margin-bottom:var(--space-lg);line-height:1.5}.confirm-modal-actions{display:flex;gap:var(--space-sm);justify-content:center}.confirm-modal-actions .btn{flex:1;padding:10px var(--space-lg);font-size:.875rem}.choice-options-stacked{flex-direction:column}.permission-modal{text-align:left;max-width:400px}.permission-modal .confirm-modal-title{text-align:center}.permission-modal .confirm-modal-message{text-align:center;word-break:break-word}.permission-list{display:flex;flex-direction:column;gap:var(--space-xs);margin-bottom:var(--space-lg)}.permission-item{display:flex;flex-direction:column;gap:2px;padding:var(--space-sm);background:var(--color-hover);border-radius:var(--radius-sm)}.permission-name{font-size:.8125rem;font-weight:600;color:var(--color-text)}.permission-desc{font-size:.75rem;color:var(--color-text-secondary);line-height:1.4}.permission-actions{display:flex;gap:var(--space-sm)}.permission-actions .btn{flex:1;padding:10px var(--space-md);font-size:.875rem}.permission-abort-link{display:block;width:100%;margin-top:var(--space-sm);background:none;border:none;color:var(--color-error);font-size:.8125rem;cursor:pointer;text-align:center;padding:var(--space-xs) 0;opacity:.8}.permission-abort-link:hover:not(:disabled){opacity:1;text-decoration:underline}.permission-abort-link:disabled{opacity:.45;cursor:not-allowed}.input-modal{text-align:left;max-width:400px}.input-modal .confirm-modal-title{text-align:center}.input-modal .confirm-modal-message{text-align:center;word-break:break-word}.input-list{display:flex;flex-direction:column;gap:var(--space-md);margin-bottom:var(--space-lg)}.input-item{display:flex;flex-direction:column;gap:var(--space-xs)}.input-label{font-size:.8125rem;font-weight:600;color:var(--color-text)}.input-field{width:100%;padding:var(--space-sm) var(--space-md);font-size:.875rem;border:1px solid var(--color-border);border-radius:var(--radius-sm);background:var(--color-surface);color:var(--color-text);box-sizing:border-box}.input-field:focus{outline:none;border-color:var(--color-primary);box-shadow:0 0 0 2px rgba(var(--color-primary-rgb, 99, 102, 241),.2)}.input-save-toggle{margin-bottom:var(--space-lg)}.input-actions{display:flex;gap:var(--space-sm)}.input-actions .btn{flex:1;padding:10px var(--space-md);font-size:.875rem}.passwords-dialog{text-align:left;max-width:420px}.passwords-dialog .confirm-modal-title{text-align:center}.passwords-dialog-scroll{max-height:min(50vh,400px);overflow-y:auto;margin-bottom:var(--space-lg);scrollbar-width:thin;scrollbar-color:var(--color-border) transparent}.passwords-empty{font-size:.875rem;color:var(--color-muted);text-align:center;padding:var(--space-md) 0;line-height:1.5}.passwords-list{list-style:none;margin:0;padding:0}.password-item{display:flex;align-items:center;gap:var(--space-sm);padding:var(--space-sm) 0;border-bottom:1px solid var(--color-border)}.password-item:last-child{border-bottom:none}.password-item-text{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0}.password-item-origin{font-size:.875rem;font-weight:500;color:var(--color-text);overflow-wrap:anywhere}.password-item-username{font-size:.8125rem;color:var(--color-muted);overflow-wrap:anywhere}.password-delete-btn{display:flex;align-items:center;justify-content:center;width:28px;height:28px;border:none;background:none;cursor:pointer;color:var(--color-muted);border-radius:6px;flex-shrink:0;opacity:.7;transition:all var(--transition-fast)}.password-delete-btn:hover{color:var(--color-error);background:var(--color-error-bg);opacity:1}.host-picker-inline{margin:0 calc(var(--space-sm) * -1)}.host-picker-list{max-height:240px;overflow-y:auto;overflow-x:hidden;padding:2px var(--space-sm);scrollbar-width:thin;scrollbar-color:var(--color-border) transparent}.host-picker-list::-webkit-scrollbar{width:6px}.host-picker-list::-webkit-scrollbar-thumb{background:var(--color-border);border-radius:3px}.host-picker-item-wrapper{position:relative}.host-picker-item{position:relative;display:flex;align-items:center;gap:8px;padding:9px 12px 9px 14px;margin:1px 0;border:none;background:none;cursor:pointer;font-family:var(--font-sans);font-size:.8125rem;color:var(--color-text-secondary);text-align:left;border-radius:8px;transition:background var(--transition-fast),color var(--transition-fast);-webkit-tap-highlight-color:transparent}.host-picker-item:hover{background:var(--color-border-subtle);color:var(--color-text)}.host-picker-item-active{background:var(--color-primary-subtle);color:var(--color-text);font-weight:500}.host-picker-item-active:hover{background:var(--color-primary-subtle)}.host-picker-item-active:before{content:"";position:absolute;left:4px;top:9px;bottom:9px;width:2px;border-radius:2px;background:var(--color-primary)}.host-picker-item-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:flex;align-items:center;gap:6px}.host-picker-pending{font-size:.6875rem;font-weight:500;color:var(--color-muted);background:var(--color-border-subtle);padding:1px 6px;border-radius:4px;flex-shrink:0}.host-picker-item-actions{flex-shrink:0;width:24px;display:flex;align-items:center;justify-content:center}.host-picker-edit-btn{display:flex;align-items:center;justify-content:center;width:22px;height:22px;border:none;background:none;cursor:pointer;color:var(--color-muted);border-radius:6px;flex-shrink:0;opacity:.7;transition:all var(--transition-fast)}.host-picker-item:hover .host-picker-edit-btn,.host-picker-edit-btn:focus-visible{opacity:1}.host-picker-edit-btn:hover{color:var(--color-primary);background:#2e5ce51f;opacity:1}.host-picker-rename-input{font-size:.8125rem!important;padding:3px 6px!important;flex:1;min-width:0}.host-picker-delete-btn{display:flex;align-items:center;justify-content:center;width:22px;height:22px;border:none;background:none;cursor:pointer;color:var(--color-muted);border-radius:6px;flex-shrink:0;opacity:.7;transition:all var(--transition-fast)}@media(hover:hover)and (pointer:fine){.host-picker-delete-btn{opacity:0}.host-picker-item:hover .host-picker-delete-btn,.host-picker-delete-btn:focus-visible{opacity:.7}}.host-picker-delete-btn:hover{color:var(--color-error);background:var(--color-error-bg);opacity:1}.hamburger-btn{display:flex;align-items:center;justify-content:center;width:40px;height:40px;padding:0;border:none;background:none;color:var(--color-text-secondary);cursor:pointer;border-radius:var(--radius-sm);transition:background var(--transition-fast),color var(--transition-fast);-webkit-tap-highlight-color:transparent}.hamburger-btn:hover{background:var(--color-border-subtle);color:var(--color-text)}.hamburger-btn:active{background:var(--color-primary-subtle);color:var(--color-primary)}.drawer-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:var(--color-overlay);z-index:100;animation:drawerFadeIn .2s ease}.drawer-panel{position:fixed;top:0;left:0;bottom:0;width:296px;max-width:84vw;background:var(--color-surface);box-shadow:var(--shadow-xl);z-index:101;display:flex;flex-direction:column;overflow-y:auto;overscroll-behavior:contain;animation:drawerSlideIn .25s ease;scrollbar-width:thin;scrollbar-color:var(--color-border) transparent}.drawer-panel::-webkit-scrollbar{width:6px}.drawer-panel::-webkit-scrollbar-thumb{background:var(--color-border);border-radius:3px}.drawer-close-btn{position:absolute;top:8px;right:8px;z-index:1;display:flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;border:none;background:none;color:var(--color-text-secondary);cursor:pointer;border-radius:var(--radius-sm);transition:background var(--transition-fast)}.drawer-close-btn:hover{background:var(--color-border-subtle);color:var(--color-text)}.drawer-section{padding:var(--space-md);display:flex;flex-direction:column;gap:var(--space-sm)}.drawer-section+.drawer-section{padding-top:0}.drawer-section:has(>.host-picker-inline){padding-bottom:var(--space-xs)}.drawer-section-label{font-size:.6875rem;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--color-muted);margin:0 0 var(--space-xs)}.drawer-section-hint{font-size:.8125rem;color:var(--color-muted);line-height:1.45;margin:0 0 var(--space-sm) 0}.pair-checkbox{display:flex;align-items:flex-start;gap:var(--space-sm);padding:var(--space-sm) 0;cursor:pointer}.pair-checkbox input[type=checkbox]{margin-top:.2rem;flex-shrink:0}.pair-checkbox-text{display:flex;flex-direction:column;gap:.15rem}.pair-checkbox-title{font-size:.9375rem;font-weight:500}.pair-checkbox-hint{font-size:.8125rem;color:var(--color-muted);line-height:1.4}.drawer-toggle-group{display:flex;flex-direction:column;gap:var(--space-sm)}.drawer-toggle-group-divided{border-top:1px solid var(--color-border);padding-top:var(--space-sm);margin-top:var(--space-xs)}.drawer-toggle{display:flex;align-items:center;justify-content:space-between;gap:var(--space-sm)}.drawer-toggle-label{font-size:.85rem;color:var(--color-text)}.toggle-switch{position:relative;width:40px;height:22px;border-radius:11px;border:none;background:var(--color-border);cursor:pointer;padding:0;transition:background .2s;flex-shrink:0}.toggle-switch-on{background:var(--color-primary)}.toggle-switch-thumb{position:absolute;top:2px;left:2px;width:18px;height:18px;border-radius:50%;background:#fff;transition:transform .2s}.toggle-switch-on .toggle-switch-thumb{transform:translate(18px)}.toggle-switch:disabled{opacity:.5;cursor:not-allowed}.drawer-footer{margin-top:auto;padding:var(--space-md);display:flex;flex-direction:column;gap:var(--space-md);border-top:1px solid var(--color-border-subtle)}.drawer-version{font-size:.75rem;color:var(--color-muted);font-variant-numeric:tabular-nums}.drawer-agents{display:flex;flex-direction:column;gap:var(--space-sm)}.drawer-agents-section{display:flex;flex-direction:column;gap:3px}.drawer-agents-heading{font-size:.6875rem;font-weight:600;color:var(--color-muted);text-transform:uppercase;letter-spacing:.06em;margin-bottom:2px}.drawer-agents-row{display:flex;justify-content:space-between;align-items:baseline;gap:var(--space-sm);font-size:.75rem;color:var(--color-text-secondary)}.drawer-agents-version{font-variant-numeric:tabular-nums;color:var(--color-muted)}.drawer-host-info{display:flex;flex-direction:column;gap:3px}.drawer-host-time{font-size:.75rem;color:var(--color-text-secondary);font-variant-numeric:tabular-nums}.drawer-legal{display:flex;align-items:center;flex-wrap:wrap;gap:0 var(--space-xs);font-size:.6875rem;color:var(--color-muted);letter-spacing:.02em}.drawer-legal a{color:var(--color-muted);text-decoration:none;transition:color var(--transition-fast)}.drawer-legal a:hover{color:var(--color-primary)}.drawer-legal-sep{opacity:.55}.drawer-divider{height:1px;background:var(--color-border-subtle);margin:0 var(--space-md)}@keyframes drawerFadeIn{0%{opacity:0}to{opacity:1}}@keyframes drawerFadeOut{0%{opacity:1}to{opacity:0}}@keyframes drawerSlideIn{0%{transform:translate(-100%)}to{transform:translate(0)}}@keyframes drawerSlideOut{0%{transform:translate(0)}to{transform:translate(-100%)}}.drawer-overlay-closing{animation:drawerFadeOut .2s ease forwards}.drawer-panel-closing{animation:drawerSlideOut .2s ease forwards}.app-header{position:sticky;top:0;z-index:10;background:color-mix(in srgb,var(--color-surface) 92%,transparent);border-bottom:1px solid var(--color-border);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.app-title-bar{position:relative;display:flex;align-items:center;justify-content:center;padding:8px 0}.app-title-bar .hamburger-btn{position:absolute;left:4px;top:50%;transform:translateY(-50%)}.app-title{margin:0;font-size:1rem;font-weight:700;letter-spacing:-.01em;color:#1e3a8a}.conn-status{position:absolute;right:4px;top:50%;transform:translateY(-50%);display:inline-flex;color:#60a5fa}.conn-status--lan{color:#2563eb}.conn-status--disconnected{color:#dc2626}.conn-status-btn{background:none;border:none;padding:4px 8px;cursor:pointer;line-height:1;display:inline-flex;align-items:center;justify-content:center;border-radius:6px;color:inherit}.conn-status-btn:hover,.conn-status-btn:focus-visible{background:var(--color-bg);outline:none}.conn-status-popover{position:absolute;top:calc(100% + 6px);right:0;background:var(--color-text);color:var(--color-surface);font-size:.75rem;font-weight:500;padding:6px 10px;border-radius:6px;white-space:nowrap;pointer-events:none;opacity:0;transform:translateY(-2px);transition:opacity .12s,transform .12s;z-index:20}.conn-status:hover .conn-status-popover,.conn-status-popover--open{opacity:1;transform:translateY(0)}.conn-status--connecting .conn-status-btn>svg{animation:conn-status-pulse 1.2s ease-in-out infinite}@keyframes conn-status-pulse{0%,to{opacity:.35}50%{opacity:1}}.tab-bar{display:flex;align-items:center}.tab-btn{flex:1;display:flex;align-items:center;justify-content:center;gap:6px;padding:12px 0;border:none;background:none;font-family:var(--font-sans);font-size:.875rem;font-weight:600;color:var(--color-text-secondary);cursor:pointer;border-bottom:2px solid transparent;transition:color var(--transition-fast),border-color var(--transition-fast)}.tab-icon{flex-shrink:0}.tab-btn:hover{color:var(--color-text)}.tab-btn-active{color:var(--color-primary);border-bottom-color:var(--color-primary)}.sessions-view{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center}.sessions-card{background:var(--color-surface);border-radius:var(--radius-md);border:1px solid var(--color-border);box-shadow:var(--shadow-sm);padding:var(--space-md);display:flex;align-items:center;gap:var(--space-sm);cursor:pointer;transition:box-shadow var(--transition-base),border-color var(--transition-base);-webkit-tap-highlight-color:transparent}.sessions-card:hover{box-shadow:var(--shadow-md);border-color:#cbd5e1}.sessions-card-body{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--space-xs)}.sessions-card-name{font-size:.9375rem;font-weight:600;letter-spacing:-.01em;color:var(--color-text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.sessions-card-meta{display:flex;flex-wrap:wrap;gap:var(--space-sm);font-size:.75rem;color:var(--color-text-secondary)}.sessions-card-chevron{flex-shrink:0;align-self:center;color:var(--color-text-secondary);font-size:1.25rem;line-height:1;opacity:.4;transition:opacity var(--transition-base)}.sessions-card:hover .sessions-card-chevron{opacity:.8}.star-button{flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;margin:-8px 0;border:none;border-radius:var(--radius-full);background:none;cursor:pointer;color:var(--color-muted);transition:color var(--transition-fast),background var(--transition-fast);-webkit-tap-highlight-color:transparent}.star-button:hover{background:var(--color-hover)}.star-button--on{color:var(--color-warning)}.star-button:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}.sessions-filter-chip{display:inline-flex;align-items:center;gap:var(--space-xs);padding:4px 10px;font-size:.8125rem;color:var(--color-text-secondary);background:var(--color-bg);border:1px solid var(--color-border);border-radius:999px}.sessions-filter-chip button{display:inline-flex;align-items:center;justify-content:center;border:none;background:none;cursor:pointer;padding:0;color:var(--color-text-secondary);font-size:1rem;line-height:1}.sessions-filter-chip button:hover{color:var(--color-text)}.run-detail{display:flex;flex-direction:column;gap:var(--space-md);background:var(--color-surface);border-radius:var(--radius-md);border:1px solid var(--color-border);box-shadow:var(--shadow-sm);padding:var(--space-md)}.run-detail-header{display:flex;align-items:center;justify-content:space-between}.run-detail-back{display:inline-flex;align-items:center;gap:var(--space-xs);align-self:flex-start;border:none;background:none;cursor:pointer;padding:0;color:var(--color-text-secondary);font-size:.8125rem}.run-detail-back:hover{color:var(--color-text)}.run-detail-back--footer{align-self:center;margin-top:var(--space-sm);padding:8px 16px;border:1px solid var(--color-border);border-radius:var(--radius-md)}.run-detail-back--footer:hover{background:var(--color-surface-hover, var(--color-bg))}.chat-thread{display:flex;flex-direction:column;gap:var(--space-sm);overflow-y:auto;flex:1;min-height:0}.chat-message{display:flex;flex-direction:column;gap:var(--space-xs);max-width:85%;min-width:0;padding:var(--space-sm) var(--space-md);border-radius:var(--radius-md);font-size:.8125rem;line-height:1.6}.chat-message--assistant{align-self:flex-start;background:var(--color-surface);border:1px solid var(--color-border)}.chat-message--user{align-self:flex-end;background:var(--color-primary-subtle);border:1px solid var(--color-border-subtle)}.chat-message--assistant.chat-message--stderr .chat-message-content,.chat-message--assistant.chat-message--stderr .chat-message-content pre,.chat-message--assistant.chat-message--stderr .chat-message-content code{color:var(--color-error)}.chat-message-agent{font-size:.6875rem;font-weight:500;color:var(--color-text-tertiary);margin-bottom:var(--space-xs)}.chat-message-agent-version{font-weight:400;opacity:.7}.chat-message-content{color:var(--color-text);overflow-wrap:break-word}.chat-message-content h1,.chat-message-content h2,.chat-message-content h3,.chat-message-content h4{margin:.75em 0 .25em;font-weight:600}.chat-message-content h1{font-size:1.1rem}.chat-message-content h2{font-size:1rem}.chat-message-content h3{font-size:.9375rem}.chat-message-content p{margin:.5em 0}.chat-message-content ul,.chat-message-content ol{margin:.5em 0;padding-left:1.5em}.chat-message-content code{font-size:.8em;background:var(--color-hover);padding:.15em .35em;border-radius:4px}.chat-message-content pre{background:var(--color-bg);border-radius:var(--radius-sm);padding:var(--space-sm);overflow-x:auto;margin:.5em 0}.chat-message-content pre code{background:none;padding:0}.chat-message-content table{border-collapse:collapse;width:100%;margin:.5em 0}.chat-message-content th,.chat-message-content td{border:1px solid var(--color-border);padding:.35em .6em;text-align:left}.chat-message-content th{background:var(--color-bg);font-weight:600}.chat-message-meta{display:flex;align-items:center;gap:var(--space-xs);font-size:.6875rem;color:var(--color-muted)}.chat-message-type{font-weight:600;text-transform:uppercase;letter-spacing:.04em;font-size:.625rem}.chat-message-attachments{display:flex;flex-wrap:wrap;gap:var(--space-xs)}.chat-attachment-chip{display:inline-flex;align-items:center;padding:.2em .6em;font-size:.75rem;background:var(--color-bg);border:1px solid var(--color-border);border-radius:var(--radius-sm);cursor:pointer;color:var(--color-primary);font-weight:500}.chat-attachment-chip:hover{background:var(--color-primary-subtle)}.chat-message-report{margin-top:var(--space-xs);padding:var(--space-sm);background:var(--color-bg);border-radius:var(--radius-sm);border:1px solid var(--color-border);font-size:.8125rem;line-height:1.6;color:var(--color-text-secondary)}.chat-status{display:flex;flex-direction:column;align-items:center;gap:var(--space-xs);font-size:.6875rem;color:var(--color-muted);padding:var(--space-xs) 0}.chat-status>div{display:flex;align-items:center;gap:var(--space-xs)}.chat-status--error{color:var(--color-error)}.chat-status-detail{margin-top:var(--space-xs);padding:var(--space-sm);background:var(--color-bg);border:1px solid var(--color-border);border-radius:var(--radius-sm);font-size:.75rem;font-family:SF Mono,Fira Code,monospace;white-space:pre-wrap;word-break:break-word;max-width:100%;max-height:200px;overflow-y:auto;color:var(--color-text-secondary)}.chat-status-time{color:var(--color-muted)}.chat-stop-btn{display:flex;align-items:center;justify-content:center;width:36px;height:36px;padding:0;border-radius:50%;flex-shrink:0;margin-left:auto;background:var(--color-error);color:#fff;border-color:var(--color-error)}.chat-stop-btn:hover:not(:disabled){background:#dc2626;border-color:#dc2626}.chat-input-bar{display:flex;gap:var(--space-xs);padding:var(--space-sm) 0;flex-shrink:0}.chat-input{flex:1;min-width:0;padding:var(--space-sm) var(--space-md);border:1px solid var(--color-border);border-radius:var(--radius-md);font-size:.8125rem;outline:none;background:var(--color-surface);color:var(--color-text)}.chat-input:focus{border-color:var(--color-primary);box-shadow:0 0 0 2px var(--color-primary-subtle)}.chat-input:disabled{opacity:.6}.chat-send-btn{display:flex;align-items:center;justify-content:center;width:36px;height:36px;padding:0;border-radius:50%;flex-shrink:0}.report-dialog-overlay{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1000;background:var(--color-overlay);display:flex;align-items:stretch;justify-content:center}.report-dialog{display:flex;flex-direction:column;width:100%;max-width:800px;background:var(--color-surface);overflow:hidden}.report-dialog-header{display:flex;align-items:center;justify-content:space-between;padding:var(--space-sm) var(--space-md);border-bottom:1px solid var(--color-border);flex-shrink:0}.report-dialog-title{font-size:.875rem;font-weight:600;color:var(--color-text)}.report-dialog-close{display:flex;align-items:center;justify-content:center;border:none;background:none;cursor:pointer;color:var(--color-text-secondary);padding:4px;border-radius:var(--radius-sm)}.report-dialog-close:hover{background:var(--color-hover);color:var(--color-text)}.report-dialog-body{flex:1;overflow-y:auto;padding:var(--space-md);font-size:.8125rem;line-height:1.6;color:var(--color-text)}.report-dialog-body h1,.report-dialog-body h2,.report-dialog-body h3,.report-dialog-body h4{margin:.75em 0 .25em;font-weight:600}.report-dialog-body h1{font-size:1.1rem}.report-dialog-body h2{font-size:1rem}.report-dialog-body h3{font-size:.9375rem}.report-dialog-body p{margin:.5em 0}.report-dialog-body img{max-width:100%;height:auto}.report-dialog-body ul,.report-dialog-body ol{margin:.5em 0;padding-left:1.5em}.report-dialog-body code{font-size:.8em;background:var(--color-hover);padding:.15em .35em;border-radius:4px}.report-dialog-body pre{background:var(--color-bg);border-radius:var(--radius-sm);padding:var(--space-sm);overflow-x:auto;margin:.5em 0}.report-dialog-body pre code{background:none;padding:0}.report-dialog-body table{border-collapse:collapse;width:100%;margin:.5em 0}.report-dialog-body th,.report-dialog-body td{border:1px solid var(--color-border);padding:.35em .6em;text-align:left}.report-dialog-body th{background:var(--color-bg);font-weight:600}.report-dialog-body--frame{display:flex;padding:0}.file-viewer-frame{flex:1;width:100%;border:none;background:#fff}.file-viewer-text{margin:0;white-space:pre-wrap;word-break:break-word;font-size:.75rem}.file-viewer-loading{display:flex;flex-direction:column;gap:var(--space-sm)}.file-viewer-message{color:var(--color-text-secondary)}.file-viewer-download{display:flex;flex-direction:column;align-items:flex-start;gap:var(--space-sm)}.md-file-link{cursor:pointer}.md-file-image{max-width:100%;height:auto;cursor:zoom-in}.md-image-loading{display:block;width:100%;max-width:240px;height:6rem}.md-image-missing{font-style:italic;color:var(--color-text-secondary)}.chat-typing-indicator{display:flex;align-items:center;gap:4px;padding:4px 0}.chat-typing-indicator span{width:6px;height:6px;border-radius:50%;background:var(--color-muted);animation:chat-typing 1.4s infinite}.chat-typing-indicator span:nth-child(2){animation-delay:.2s}.chat-typing-indicator span:nth-child(3){animation-delay:.4s}@keyframes chat-typing{0%,60%,to{opacity:.3;transform:scale(.8)}30%{opacity:1;transform:scale(1)}}.pair-consent{font-size:.75rem;color:var(--color-muted);text-align:center;line-height:1.5}.pair-consent a{color:var(--color-muted);text-decoration:underline}.pair-consent a:hover{color:var(--color-text-secondary)}.dashboard-content{display:flex;flex-direction:column;flex:1;min-height:100dvh;max-width:800px;margin:0 auto;width:100%}.drawer-panel-desktop{position:sticky;top:0;height:100dvh;width:320px;min-width:320px;background:var(--color-surface);border-right:1px solid var(--color-border);display:flex;flex-direction:column;overflow-y:auto;overscroll-behavior:contain;animation:none}@media(min-width:768px){.dashboard{flex-direction:row}.dashboard-main{padding:var(--space-lg)}.fab{right:max(var(--space-lg),calc((100vw - 1080px)/2))}}.swipe-row{position:relative;overflow:hidden;touch-action:pan-y}.swipe-row-action{position:absolute;top:0;right:0;bottom:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;background:var(--color-error, #dc2626);color:#fff;border:none;font-size:.75rem;font-weight:600;cursor:pointer;padding:0}.swipe-row-action--hidden{visibility:hidden;transition:visibility 0s linear .2s}.swipe-row-action-label{font-size:.75rem;line-height:1}.swipe-row-action:focus-visible{outline:2px solid var(--color-accent, #2E5CE5);outline-offset:-4px}.swipe-row-content{position:relative;background:var(--color-surface);transition:transform .2s cubic-bezier(.22,1,.36,1);will-change:transform}.swipe-row-content-dragging{transition:none}.app-filter-help{margin-top:var(--space-xs)}.app-filter-trigger{display:inline-block;padding:0;font-size:.875rem;font-weight:500;text-align:left}.app-filter-selected{display:inline-flex;align-items:center;gap:var(--space-sm);padding:6px 10px;border:1px solid var(--color-border);border-radius:var(--radius-md);background:var(--color-surface);max-width:100%}.app-filter-selected-name{font-size:.9375rem;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.app-filter-selected-pkg{font-size:.75rem;color:var(--color-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.app-filter-selected-clear{display:flex;align-items:center;justify-content:center;width:22px;height:22px;padding:0;margin-left:auto;border:none;background:none;color:var(--color-muted);font-size:.875rem;cursor:pointer;border-radius:var(--radius-sm)}.app-filter-selected-clear:hover{background:var(--color-border-subtle);color:var(--color-text)}.app-filter-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:var(--color-overlay);display:flex;align-items:center;justify-content:center;z-index:1100;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);padding:var(--space-md)}.app-filter-dialog{background:var(--color-surface);width:100%;max-width:480px;max-height:80dvh;border-radius:var(--radius-lg);box-shadow:var(--shadow-xl);display:flex;flex-direction:column;overflow:hidden}.app-filter-header{display:flex;align-items:center;justify-content:space-between;padding:var(--space-md) var(--space-lg);border-bottom:1px solid var(--color-border)}.app-filter-header h2{margin:0;font-size:1rem;font-weight:600}.app-filter-close{display:flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;border:none;background:none;color:var(--color-muted);cursor:pointer;border-radius:var(--radius-sm)}.app-filter-close:hover{background:var(--color-border-subtle);color:var(--color-text)}.app-filter-search{margin:var(--space-md) var(--space-lg) 0;width:calc(100% - 2 * var(--space-lg))}.app-filter-list{flex:1;overflow-y:auto;list-style:none;margin:0;padding:var(--space-xs) 0 var(--space-md)}.app-filter-row{display:flex;align-items:center;gap:var(--space-md);padding:10px var(--space-lg);cursor:pointer;-webkit-user-select:none;user-select:none}.app-filter-row:hover{background:var(--color-hover, rgba(0, 0, 0, .04))}.app-filter-row-labels{display:flex;flex-direction:column;min-width:0;flex:1}.app-filter-row-name{font-size:.9375rem;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.app-filter-row-pkg{font-size:.75rem;color:var(--color-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.app-filter-empty{padding:var(--space-lg);text-align:center;color:var(--color-muted);font-size:.875rem}.app-filter-skeleton{cursor:default}.app-filter-skeleton-bar{flex:1;height:14px;border-radius:4px;background:linear-gradient(90deg,var(--color-border-subtle) 25%,var(--color-border) 50%,var(--color-border-subtle) 75%);background-size:200% 100%;animation:appFilterShimmer 1.2s ease-in-out infinite}@keyframes appFilterShimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.pair-setup{min-height:100dvh;display:flex;justify-content:center;padding:var(--space-lg);background:var(--color-bg)}.pair-setup-inner{width:100%;max-width:480px;display:flex;flex-direction:column;gap:var(--space-lg)}.pair-setup-title{margin:0;font-size:1.25rem;font-weight:600;line-height:1.35}.pair-setup-description{margin:0;color:var(--color-muted);font-size:.875rem}.pair-setup-loading{padding:var(--space-xl, 32px) var(--space-lg);min-height:200px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-md);color:var(--color-muted);font-size:.95rem}.pair-setup-actions{margin-top:var(--space-md)}
|
|
@@ -84,7 +84,7 @@ ${d}`),g(S);return}f(null,j),s.strategy===Mr.Count&&(m--,m===0&&g()),s.strategy=
|
|
|
84
84
|
|
|
85
85
|
${f.stack}`),d.unsubscribe(),c.reject(m)):(m=gx(b),m?(f&&(m.stack+=`
|
|
86
86
|
|
|
87
|
-
${f.stack}`),c.reject(m)):c.resolve(b))}});return d.requestSubject=t,this.protocol.publish(t,r,{reply:o,headers:s.headers}),c}else{const o=new xx(this.protocol.muxSubscriptions,t,s,l);this.protocol.request(o);try{this.publish(t,r,{reply:`${this.protocol.muxSubscriptions.baseInbox}${o.token}`,headers:s.headers})}catch(f){o.cancel(f)}const c=Promise.race([o.timer,o.deferred]);return c.catch(()=>{o.cancel()}),c}}flush(){return this.isClosed()?Promise.reject(De.errorForCode(Ce.ConnectionClosed)):this.protocol.flush()}drain(){return this.isClosed()?Promise.reject(De.errorForCode(Ce.ConnectionClosed)):this.isDraining()?Promise.reject(De.errorForCode(Ce.ConnectionDraining)):(this.draining=!0,this.protocol.drain())}isClosed(){return this.protocol.isClosed()}isDraining(){return this.draining}getServer(){const t=this.protocol.getServer();return t?t.listen:""}status(){const t=new wn;return t.iterClosed.then(()=>{const r=this.listeners.indexOf(t);this.listeners.splice(r,1)}),this.listeners.push(t),t}get info(){return this.protocol.isClosed()?void 0:this.protocol.info}async context(){return(await this.request("$SYS.REQ.USER.INFO")).json((r,s)=>r==="time"?new Date(Date.parse(s)):s)}stats(){return{inBytes:this.protocol.inBytes,outBytes:this.protocol.outBytes,inMsgs:this.protocol.inMsgs,outMsgs:this.protocol.outMsgs}}async jetstreamManager(t={}){const r=new Fk(this,t);if(t.checkAPI!==!1)try{await r.getAccountInfo()}catch(s){const l=s;throw l.code===Ce.NoResponders&&(l.code=Ce.JetStreamNotEnabled),l}return r}jetstream(t={}){return new Id(this,t)}getServerVersion(){const t=this.info;return t?ws(t.version):void 0}async rtt(){if(!this.protocol._closed&&!this.protocol.connected)throw De.errorForCode(Ce.Disconnect);const t=Date.now();return await this.flush(),Date.now()-t}get features(){return this.protocol.features}get services(){return this._services||(this._services=new Gk(this)),this._services}reconnect(){return this.isClosed()?Promise.reject(De.errorForCode(Ce.ConnectionClosed)):this.isDraining()?Promise.reject(De.errorForCode(Ce.ConnectionDraining)):this.protocol.reconnect()}}class Gk{constructor(t){C(this,"nc");this.nc=t}add(t){try{return new Xl(this.nc,t).start()}catch(r){return Promise.reject(r)}}client(t,r){return new Ck(this.nc,t,r)}}class Jk{constructor(t,r,s){C(this,"bucket");C(this,"sm");C(this,"prefixLen");this.bucket=t,this.prefixLen=r,this.sm=s}get key(){return this.sm.subject.substring(this.prefixLen)}get value(){return this.sm.data}get delta(){return 0}get created(){return this.sm.time}get revision(){return this.sm.seq}get operation(){return this.sm.header.get(Pu)||"PUT"}get length(){const t=this.sm.header.get(Bn.MessageSizeHdr)||"";return t!==""?parseInt(t,10):this.sm.data.length}json(){return this.sm.json()}string(){return this.sm.string()}}class Xk{constructor(t,r,s){C(this,"bucket");C(this,"key");C(this,"sm");this.bucket=t,this.key=r,this.sm=s}get value(){return this.sm.data}get created(){return new Date(Ud(this.sm.info.timestampNanos))}get revision(){return this.sm.seq}get operation(){var t;return((t=this.sm.headers)==null?void 0:t.get(Pu))||"PUT"}get delta(){return this.sm.info.pending}get length(){var r;const t=((r=this.sm.headers)==null?void 0:r.get(Bn.MessageSizeHdr))||"";return t!==""?parseInt(t,10):this.sm.data.length}json(){return this.sm.json()}string(){return this.sm.string()}}class Rx extends C2{constructor(r,s,l){super(r.nc,s,l);C(this,"js");C(this,"monitor");this.js=r,this.monitor=null,this.sub.closed.then(()=>{this.monitor&&this.monitor.cancel()})}set info(r){this.sub.info=r}get info(){return this.sub.info}_resetOrderedConsumer(r){if(this.info===null||this.sub.isClosed())return;const s=gi(this.js.nc.options.inboxPrefix);this.js.nc._resub(this.sub,s);const o=this.info;o.config.name=Ki.next(),o.ordered_consumer_sequence.delivery_seq=0,o.flow_control.heartbeat_count=0,o.flow_control.fc_count=0,o.flow_control.consumer_restarts++,o.deliver=s,o.config.deliver_subject=s,o.config.deliver_policy=sn.StartSequence,o.config.opt_start_seq=r;const c={};c.stream_name=this.info.stream,c.config=o.config;const f=`${o.api.prefix}.CONSUMER.CREATE.${o.stream}`;this.js._request(f,c,{retries:-1}).then(d=>{const m=d,b=this.sub.info;b.last=m,this.info.config=m.config,this.info.name=m.name}).catch(d=>{const m=new De(`unable to recreate ordered consumer ${o.stream} at seq ${r}`,Ce.RequestError,d);this.sub.callback(m,{})})}_maybeSetupHbMonitoring(){var s,l;const r=((l=(s=this.info)==null?void 0:s.config)==null?void 0:l.idle_heartbeat)||0;r&&this._setupHbMonitoring(Ud(r))}_setupHbMonitoring(r,s=0){const l={cancelAfter:0,maxOut:2};s&&(l.cancelAfter=s);const o=this.sub,c=f=>{var b,g,x,v;const d=a2(409,`${_r.IdleHeartbeatMissed}: ${f}`,this.sub.subject);if(!((b=this.info)==null?void 0:b.ordered))this.sub.callback(null,d);else{if(!this.js.nc.protocol.connected)return!1;const S=((x=(g=this.info)==null?void 0:g.ordered_consumer_sequence)==null?void 0:x.stream_seq)||0;return this._resetOrderedConsumer(S+1),(v=this.monitor)==null||v.restart(),!1}return!o.noIterator};this.monitor=new Bd(r,c,l)}_checkHbOrderConsumer(r){const s=r.headers.get(Bn.ConsumerStalledHdr);s!==""&&this.js.nc.publish(s);const l=parseInt(r.headers.get(Bn.LastConsumerSeqHdr),10),o=this.info.ordered_consumer_sequence;return this.info.flow_control.heartbeat_count++,l!==o.delivery_seq&&this._resetOrderedConsumer(o.stream_seq+1),!1}_checkOrderedConsumer(r){const s=this.info.ordered_consumer_sequence,l=r.info.streamSequence,o=r.info.deliverySequence;return o!=s.delivery_seq+1?(this._resetOrderedConsumer(s.stream_seq+1),!1):(s.delivery_seq=o,s.stream_seq=l,!0)}async destroy(){this.isClosed()||await this.drain();const r=this.sub.info,s=r.config.durable_name||r.name,l=`${r.api.prefix}.CONSUMER.DELETE.${r.stream}.${s}`;await r.api._request(l)}async consumerInfo(){const r=this.sub.info,s=r.config.durable_name||r.name,l=`${r.api.prefix}.CONSUMER.INFO.${r.stream}.${s}`,o=await r.api._request(l);return r.last=o,o}}class Kk extends Rx{constructor(t,r,s){super(t,r,s)}pull(t={batch:1}){const{stream:r,config:s,name:l}=this.sub.info,o=s.durable_name??l,c={};if(c.batch=t.batch||1,c.no_wait=t.no_wait||!1,(t.max_bytes??0)>0){const m=this.js.nc.features.get(gt.JS_PULL_MAX_BYTES);if(!m.ok)throw new Error(`max_bytes is only supported on servers ${m.min} or better`);c.max_bytes=t.max_bytes}let f=0;t.expires&&t.expires>0&&(f=t.expires,c.expires=Gt(f));let d=0;if(t.idle_heartbeat&&t.idle_heartbeat>0&&(d=t.idle_heartbeat,c.idle_heartbeat=Gt(d)),d&&f===0)throw new Error("idle_heartbeat requires expires");if(d>f)throw new Error("expires must be greater than idle_heartbeat");if(this.info){this.monitor&&this.monitor.cancel(),f&&d&&(this.monitor?this.monitor._change(d,f):this._setupHbMonitoring(d,f));const m=this.info.api,b=`${m.prefix}.CONSUMER.MSG.NEXT.${r}.${o}`,g=this.sub.subject;m.nc.publish(b,m.jc.encode(c),{reply:g})}}}function Qk(e,t){return e?Wk(t):Zk(t)}function Zk(e){return(t,r)=>t?[t,null]:(t=pa(r),t?[t,null]:[null,Fl(r,e)])}function Wk(e){return(t,r)=>{if(t)return[t,null];const s=pa(r);return s!==null?[Mx(s),null]:[null,Fl(r,e)]}}function Mx(e){if(e!==null)switch(e.code){case Ce.JetStream404NoMessages:case Ce.JetStream408RequestTimeout:return null;case Ce.JetStream409:return l2(e)?e:null;default:return e}return null}function eE(e){e&&e.ack()}function tE(e){const t=e.split(".");if(t.length===9&&t.splice(2,0,"_",""),t.length<11||t[0]!=="$JS"||t[1]!=="ACK")throw new Error("not js message");const r={};return r.domain=t[2]==="_"?"":t[2],r.account_hash=t[3],r.stream=t[4],r.consumer=t[5],r.deliveryCount=parseInt(t[6],10),r.redeliveryCount=r.deliveryCount,r.redelivered=r.deliveryCount>1,r.streamSequence=parseInt(t[7],10),r.deliverySequence=parseInt(t[8],10),r.timestampNanos=parseInt(t[9],10),r.pending=parseInt(t[10],10),r}class nE{constructor(t,r){C(this,"msg");C(this,"di");C(this,"didAck");C(this,"timeout");this.msg=t,this.didAck=!1,this.timeout=r}get subject(){return this.msg.subject}get sid(){return this.msg.sid}get data(){return this.msg.data}get headers(){return this.msg.headers}get info(){return this.di||(this.di=tE(this.reply)),this.di}get redelivered(){return this.info.deliveryCount>1}get reply(){return this.msg.reply||""}get seq(){return this.info.streamSequence}doAck(t){this.didAck||(this.didAck=!this.isWIP(t),this.msg.respond(t))}isWIP(t){return t.length===4&&t[0]===Sl[0]&&t[1]===Sl[1]&&t[2]===Sl[2]&&t[3]===Sl[3]}async ackAck(t){var s;t=t||{},t.timeout=t.timeout||this.timeout;const r=Jt();if(this.didAck)r.resolve(!1);else if(this.didAck=!0,this.msg.reply){const o=this.msg.publisher,c=!((s=o.options)!=null&&s.noAsyncTraces),f=new xx(o.muxSubscriptions,this.msg.reply,{timeout:t.timeout},c);o.request(f);try{o.publish(this.msg.reply,B0,{reply:`${o.muxSubscriptions.baseInbox}${f.token}`})}catch(d){f.cancel(d)}try{await Promise.race([f.timer,f.deferred]),r.resolve(!0)}catch(d){f.cancel(d),r.reject(d)}}else r.resolve(!1);return r}ack(){this.doAck(B0)}nak(t){let r=zk;t&&(r=Ru().encode(`-NAK ${JSON.stringify({delay:Gt(t)})}`)),this.doAck(r)}working(){this.doAck(Sl)}next(t,r={batch:1}){const s={};s.batch=r.batch||1,s.no_wait=r.no_wait||!1,r.expires&&r.expires>0&&(s.expires=Gt(r.expires));const l=Dr().encode(s),o=Sa.concat(Uk,Bk,l),c=t?{reply:t}:void 0;this.msg.respond(o,c)}term(t=""){let r=Pk;(t==null?void 0:t.length)>0&&(r=Ru().encode(`+TERM ${t}`)),this.doAck(r)}json(){return this.msg.json()}string(){return this.msg.string()}}const rE="1.30.3",iE="nats.ws";class sE{constructor(){C(this,"version");C(this,"lang");C(this,"closeError");C(this,"connected");C(this,"done");C(this,"socket");C(this,"options");C(this,"socketClosed");C(this,"encrypted");C(this,"peeked");C(this,"yields");C(this,"signal");C(this,"closedNotification");this.version=rE,this.lang=iE,this.connected=!1,this.done=!1,this.socketClosed=!1,this.encrypted=!1,this.peeked=!1,this.yields=[],this.signal=Jt(),this.closedNotification=Jt()}async connect(t,r){const s=Jt();if(r.tls)return s.reject(new De("tls",Ce.InvalidOption)),s;this.options=r;const l=t.src;if(r.wsFactory){const{socket:o,encrypted:c}=await r.wsFactory(t.src,r);this.socket=o,this.encrypted=c}else this.encrypted=l.indexOf("wss://")===0,this.socket=new WebSocket(l);return this.socket.binaryType="arraybuffer",this.socket.onopen=()=>{this.isDiscarded()},this.socket.onmessage=o=>{if(this.isDiscarded())return;if(this.yields.push(new Uint8Array(o.data)),this.peeked){this.signal.resolve();return}const c=Sa.concat(...this.yields),f=R2(c);if(f!==""){const d=bk.exec(f);if(!d){r.debug&&console.error("!!!",fu(c)),s.reject(new Error("unexpected response from server"));return}try{const m=JSON.parse(d[1]);gk(m,this.options),this.peeked=!0,this.connected=!0,this.signal.resolve(),s.resolve()}catch(m){s.reject(m);return}}},this.socket.onclose=o=>{if(this.isDiscarded())return;this.socketClosed=!0;let c;this.done||(o.wasClean||(c=new Error(o.reason)),this._closed(c))},this.socket.onerror=o=>{if(this.isDiscarded())return;const c=o,f=new De(c.message,Ce.Unknown,new Error(c.error));s.reject(f)},s}disconnect(){this._closed(void 0,!0)}async _closed(t,r=!0){if(!this.isDiscarded()&&this.connected&&!this.done){if(this.closeError=t,!t)for(;!this.socketClosed&&this.socket.bufferedAmount>0;)await ja(100);this.done=!0;try{this.socket.close(t?1002:1e3,t?t.message:void 0)}catch{}r&&this.closedNotification.resolve(t)}}get isClosed(){return this.done}[Symbol.asyncIterator](){return this.iterate()}async*iterate(){for(;;){if(this.isDiscarded())return;this.yields.length===0&&await this.signal;const t=this.yields;this.yields=[];for(let r=0;r<t.length;r++)this.options.debug&&console.info(`> ${fu(t[r])}`),yield t[r];if(this.done)break;this.yields.length===0&&(t.length=0,this.yields=t,this.signal=Jt())}}isEncrypted(){return this.connected&&this.encrypted}send(t){if(!this.isDiscarded())try{this.socket.send(t.buffer),this.options.debug&&console.info(`< ${fu(t)}`);return}catch(r){this.options.debug&&console.error(`!!! ${fu(t)}: ${r}`)}}close(t){return this._closed(t,!1)}closed(){return this.closedNotification}isDiscarded(){return this.done?(this.discard(),!0):!1}discard(){var t;this.done=!0;try{(t=this.socket)==null||t.close()}catch{}}}function aE(e,t){/^(.*:\/\/)(.*)/.test(e)||(typeof t=="boolean"?e=`${t===!0?"https":"http"}://${e}`:e=`https://${e}`);let s=new URL(e);const l=s.protocol.toLowerCase();l==="ws:"&&(t=!1),l==="wss:"&&(t=!0),l!=="https:"&&l!=="http"&&(e=e.replace(/^(.*:\/\/)(.*)/gm,"$2"),s=new URL(`http://${e}`));let o,c;const f=s.hostname,d=s.pathname,m=s.search||"";switch(l){case"http:":case"ws:":case"nats:":c=s.port||"80",o="ws:";break;case"https:":case"wss:":case"tls:":c=s.port||"443",o="wss:";break;default:c=s.port||t===!0?"443":"80",o=t===!0?"wss:":"ws:";break}return`${o}//${f}:${c}${d}${m}`}function Dx(e={}){return A2({defaultPort:443,urlParseFn:aE,factory:()=>new sE}),Fd.connect(e)}/*! Capacitor: https://capacitorjs.com/ - MIT License */var _a;(function(e){e.Unimplemented="UNIMPLEMENTED",e.Unavailable="UNAVAILABLE"})(_a||(_a={}));class Nh extends Error{constructor(t,r,s){super(t),this.message=t,this.code=r,this.data=s}}const lE=e=>{var t,r;return e!=null&&e.androidBridge?"android":!((r=(t=e==null?void 0:e.webkit)===null||t===void 0?void 0:t.messageHandlers)===null||r===void 0)&&r.bridge?"ios":"web"},oE=e=>{const t=e.CapacitorCustomPlatform||null,r=e.Capacitor||{},s=r.Plugins=r.Plugins||{},l=()=>t!==null?t.name:lE(e),o=()=>l()!=="web",c=g=>{const x=m.get(g);return!!(x!=null&&x.platforms.has(l())||f(g))},f=g=>{var x;return(x=r.PluginHeaders)===null||x===void 0?void 0:x.find(v=>v.name===g)},d=g=>e.console.error(g),m=new Map,b=(g,x={})=>{const v=m.get(g);if(v)return console.warn(`Capacitor plugin "${g}" already registered. Cannot register plugins twice.`),v.proxy;const S=l(),j=f(g);let R;const M=async()=>(!R&&S in x?R=typeof x[S]=="function"?R=await x[S]():R=x[S]:t!==null&&!R&&"web"in x&&(R=typeof x.web=="function"?R=await x.web():R=x.web),R),P=(G,B)=>{var L,J;if(j){const $=j==null?void 0:j.methods.find(he=>B===he.name);if($)return $.rtype==="promise"?he=>r.nativePromise(g,B.toString(),he):(he,le)=>r.nativeCallback(g,B.toString(),he,le);if(G)return(L=G[B])===null||L===void 0?void 0:L.bind(G)}else{if(G)return(J=G[B])===null||J===void 0?void 0:J.bind(G);throw new Nh(`"${g}" plugin is not implemented on ${S}`,_a.Unimplemented)}},I=G=>{let B;const L=(...J)=>{const $=M().then(he=>{const le=P(he,G);if(le){const te=le(...J);return B=te==null?void 0:te.remove,te}else throw new Nh(`"${g}.${G}()" is not implemented on ${S}`,_a.Unimplemented)});return G==="addListener"&&($.remove=async()=>B()),$};return L.toString=()=>`${G.toString()}() { [capacitor code] }`,Object.defineProperty(L,"name",{value:G,writable:!1,configurable:!1}),L},ue=I("addListener"),q=I("removeListener"),N=(G,B)=>{const L=ue({eventName:G},B),J=async()=>{const he=await L;q({eventName:G,callbackId:he},B)},$=new Promise(he=>L.then(()=>he({remove:J})));return $.remove=async()=>{console.warn("Using addListener() without 'await' is deprecated."),await J()},$},ee=new Proxy({},{get(G,B){switch(B){case"$$typeof":return;case"toJSON":return()=>({});case"addListener":return j?N:ue;case"removeListener":return q;default:return I(B)}}});return s[g]=ee,m.set(g,{name:g,proxy:ee,platforms:new Set([...Object.keys(x),...j?[S]:[]])}),ee};return r.convertFileSrc||(r.convertFileSrc=g=>g),r.getPlatform=l,r.handleError=d,r.isNativePlatform=o,r.isPluginAvailable=c,r.registerPlugin=b,r.Exception=Nh,r.DEBUG=!!r.DEBUG,r.isLoggingEnabled=!!r.isLoggingEnabled,r},uE=e=>e.Capacitor=oE(e),Jn=uE(typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{}),ks=Jn.registerPlugin;class $d{constructor(){this.listeners={},this.retainedEventArguments={},this.windowListeners={}}addListener(t,r){let s=!1;this.listeners[t]||(this.listeners[t]=[],s=!0),this.listeners[t].push(r);const o=this.windowListeners[t];o&&!o.registered&&this.addWindowListener(o),s&&this.sendRetainedArgumentsForEvent(t);const c=async()=>this.removeListener(t,r);return Promise.resolve({remove:c})}async removeAllListeners(){this.listeners={};for(const t in this.windowListeners)this.removeWindowListener(this.windowListeners[t]);this.windowListeners={}}notifyListeners(t,r,s){const l=this.listeners[t];if(!l){if(s){let o=this.retainedEventArguments[t];o||(o=[]),o.push(r),this.retainedEventArguments[t]=o}return}l.forEach(o=>o(r))}hasListeners(t){var r;return!!(!((r=this.listeners[t])===null||r===void 0)&&r.length)}registerWindowListener(t,r){this.windowListeners[r]={registered:!1,windowEventName:t,pluginEventName:r,handler:s=>{this.notifyListeners(r,s)}}}unimplemented(t="not implemented"){return new Jn.Exception(t,_a.Unimplemented)}unavailable(t="not available"){return new Jn.Exception(t,_a.Unavailable)}async removeListener(t,r){const s=this.listeners[t];if(!s)return;const l=s.indexOf(r);this.listeners[t].splice(l,1),this.listeners[t].length||this.removeWindowListener(this.windowListeners[t])}addWindowListener(t){window.addEventListener(t.windowEventName,t.handler),t.registered=!0}removeWindowListener(t){t&&(window.removeEventListener(t.windowEventName,t.handler),t.registered=!1)}sendRetainedArgumentsForEvent(t){const r=this.retainedEventArguments[t];r&&(delete this.retainedEventArguments[t],r.forEach(s=>{this.notifyListeners(t,s)}))}}const q0=e=>encodeURIComponent(e).replace(/%(2[346B]|5E|60|7C)/g,decodeURIComponent).replace(/[()]/g,escape),I0=e=>e.replace(/(%[\dA-F]{2})+/gi,decodeURIComponent);class cE extends $d{async getCookies(){const t=document.cookie,r={};return t.split(";").forEach(s=>{if(s.length<=0)return;let[l,o]=s.replace(/=/,"CAP_COOKIE").split("CAP_COOKIE");l=I0(l).trim(),o=I0(o).trim(),r[l]=o}),r}async setCookie(t){try{const r=q0(t.key),s=q0(t.value),l=t.expires?`; expires=${t.expires.replace("expires=","")}`:"",o=(t.path||"/").replace("path=",""),c=t.url!=null&&t.url.length>0?`domain=${t.url}`:"";document.cookie=`${r}=${s||""}${l}; path=${o}; ${c};`}catch(r){return Promise.reject(r)}}async deleteCookie(t){try{document.cookie=`${t.key}=; Max-Age=0`}catch(r){return Promise.reject(r)}}async clearCookies(){try{const t=document.cookie.split(";")||[];for(const r of t)document.cookie=r.replace(/^ +/,"").replace(/=.*/,`=;expires=${new Date().toUTCString()};path=/`)}catch(t){return Promise.reject(t)}}async clearAllCookies(){try{await this.clearCookies()}catch(t){return Promise.reject(t)}}}ks("CapacitorCookies",{web:()=>new cE});const fE=async e=>new Promise((t,r)=>{const s=new FileReader;s.onload=()=>{const l=s.result;t(l.indexOf(",")>=0?l.split(",")[1]:l)},s.onerror=l=>r(l),s.readAsDataURL(e)}),hE=(e={})=>{const t=Object.keys(e);return Object.keys(e).map(l=>l.toLocaleLowerCase()).reduce((l,o,c)=>(l[o]=e[t[c]],l),{})},dE=(e,t=!0)=>e?Object.entries(e).reduce((s,l)=>{const[o,c]=l;let f,d;return Array.isArray(c)?(d="",c.forEach(m=>{f=t?encodeURIComponent(m):m,d+=`${o}=${f}&`}),d.slice(0,-1)):(f=t?encodeURIComponent(c):c,d=`${o}=${f}`),`${s}&${d}`},"").substr(1):null,mE=(e,t={})=>{const r=Object.assign({method:e.method||"GET",headers:e.headers},t),l=hE(e.headers)["content-type"]||"";if(typeof e.data=="string")r.body=e.data;else if(l.includes("application/x-www-form-urlencoded")){const o=new URLSearchParams;for(const[c,f]of Object.entries(e.data||{}))o.set(c,f);r.body=o.toString()}else if(l.includes("multipart/form-data")||e.data instanceof FormData){const o=new FormData;if(e.data instanceof FormData)e.data.forEach((f,d)=>{o.append(d,f)});else for(const f of Object.keys(e.data))o.append(f,e.data[f]);r.body=o;const c=new Headers(r.headers);c.delete("content-type"),r.headers=c}else(l.includes("application/json")||typeof e.data=="object")&&(r.body=JSON.stringify(e.data));return r};class pE extends $d{async request(t){const r=mE(t,t.webFetchExtra),s=dE(t.params,t.shouldEncodeUrlParams),l=s?`${t.url}?${s}`:t.url,o=await fetch(l,r),c=o.headers.get("content-type")||"";let{responseType:f="text"}=o.ok?t:{};c.includes("application/json")&&(f="json");let d,m;switch(f){case"arraybuffer":case"blob":m=await o.blob(),d=await fE(m);break;case"json":d=await o.json();break;case"document":case"text":default:d=await o.text()}const b={};return o.headers.forEach((g,x)=>{b[x]=g}),{data:d,headers:b,status:o.status,url:o.url}}async get(t){return this.request(Object.assign(Object.assign({},t),{method:"GET"}))}async post(t){return this.request(Object.assign(Object.assign({},t),{method:"POST"}))}async put(t){return this.request(Object.assign(Object.assign({},t),{method:"PUT"}))}async patch(t){return this.request(Object.assign(Object.assign({},t),{method:"PATCH"}))}async delete(t){return this.request(Object.assign(Object.assign({},t),{method:"DELETE"}))}}ks("CapacitorHttp",{web:()=>new pE});var F0;(function(e){e.Dark="DARK",e.Light="LIGHT",e.Default="DEFAULT"})(F0||(F0={}));var $0;(function(e){e.StatusBar="StatusBar",e.NavigationBar="NavigationBar"})($0||($0={}));class gE extends $d{async setStyle(){this.unavailable("not available for web")}async setAnimation(){this.unavailable("not available for web")}async show(){this.unavailable("not available for web")}async hide(){this.unavailable("not available for web")}}ks("SystemBars",{web:()=>new gE});const yE="modulepreload",bE=function(e){return"/"+e},V0={},Vd=function(t,r,s){let l=Promise.resolve();if(r&&r.length>0){let c=function(m){return Promise.all(m.map(b=>Promise.resolve(b).then(g=>({status:"fulfilled",value:g}),g=>({status:"rejected",reason:g}))))};document.getElementsByTagName("link");const f=document.querySelector("meta[property=csp-nonce]"),d=(f==null?void 0:f.nonce)||(f==null?void 0:f.getAttribute("nonce"));l=c(r.map(m=>{if(m=bE(m),m in V0)return;V0[m]=!0;const b=m.endsWith(".css"),g=b?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${m}"]${g}`))return;const x=document.createElement("link");if(x.rel=b?"stylesheet":yE,b||(x.as="script"),x.crossOrigin="",x.href=m,d&&x.setAttribute("nonce",d),document.head.appendChild(x),b)return new Promise((v,S)=>{x.addEventListener("load",v),x.addEventListener("error",()=>S(new Error(`Unable to preload CSS for ${m}`)))})}))}function o(c){const f=new Event("vite:preloadError",{cancelable:!0});if(f.payload=c,window.dispatchEvent(f),!f.defaultPrevented)throw c}return l.then(c=>{for(const f of c||[])f.status==="rejected"&&o(f.reason);return t().catch(o)})},pd=ks("App",{web:()=>Vd(()=>import("./web-dCWmWPLg.js"),[]).then(e=>new e.AppWeb)}),xE=ks("Network",{web:()=>Vd(()=>import("./web-DjwtZB4p.js"),[]).then(e=>new e.NetworkWeb)}),Bu=Jn.isNativePlatform()?"https://app.palmier.me":"";async function Lx(e,t,r,s){const l=`${Bu}${t}`;console.log(`[API] ${e} ${l}`);const c=await fetch(l,{method:e,headers:{"Content-Type":"application/json"},body:r!=null?JSON.stringify(r):void 0});if(!c.ok){const f=await c.text();let d;try{const m=JSON.parse(f);d=m.error??m.message??f}catch{d=f}throw console.error(`[API] ${e} ${t} failed:`,c.status,d),new Error(d||`Request failed with status ${c.status}`)}return console.log(`[API] ${e} ${t} ->`,c.status),c.json()}function vE(e,t,r){return Lx("POST",e,t)}function wE(e,t){return Lx("GET",e,void 0)}const Y0=Jn.isNativePlatform(),zx=E.createContext(null),SE=2e3,Th=6e3,_E=1500,kE=6e4;function EE({children:e,activeHost:t}){const[r,s]=E.useState(null),[l,o]=E.useState(!1),c=E.useRef(null),[f,d]=E.useState(!1),[m,b]=E.useState(!1),[g,x]=E.useState(!1),[v,S]=E.useState(!1),j=E.useRef(Ru()),R=E.useRef(new Set),M=E.useRef(0),P=!!t.directUrl,I=Y0&&!P&&!!t.lanUrl&&v,ue=m||g?"disconnected":P?f?"direct":"connecting":l?I?"lan":"nats":"connecting",q=ue!=="connecting"&&ue!=="disconnected";E.useEffect(()=>{if(!Y0||P||!t.lanUrl){S(!1);return}let G=!1;const B=t.lanUrl,L=t.hostId;async function J(){console.log("[HOST/LAN] probing",B);try{const te=await fetch(`${B}/health`,{signal:AbortSignal.timeout(_E)});if(G)return;if(!te.ok){console.log("[HOST/LAN] probe got non-ok:",te.status),S(!1);return}const V=await te.json(),Q=V.hostId===L;Q?console.log("[HOST/LAN] reachable"):console.log("[HOST/LAN] hostId mismatch — got:",V.hostId,"expected:",L),S(Q)}catch(te){G||(console.log("[HOST/LAN] probe failed:",te instanceof Error?te.message:te),S(!1))}}J();const $=window.setInterval(J,kE),he=pd.addListener("appStateChange",te=>{te.isActive&&J()}),le=xE.addListener("networkStatusChange",()=>J());return()=>{G=!0,clearInterval($),he.then(te=>te.remove()),le.then(te=>te.remove())}},[t.hostId,t.lanUrl,P]),E.useEffect(()=>{if(P){c.current&&(c.current.close().catch(()=>{}),c.current=null,s(null),o(!1));return}let G=!1,B=1e3;const L=3e4;async function J(){for(;!G;)try{const $=await fetch(`${Bu}/api/nats-credentials/${t.hostId}`);if(G)return;if($.status===401||$.status===403||$.status===404){console.error("[NATS] Host not found or rejected by relay:",$.status),x(!0);return}if(!$.ok)throw new Error(`credentials fetch ${$.status}`);const he=await $.json();if(!he.natsWsUrl){console.error("[NATS] Relay returned empty natsWsUrl — treating as terminal"),x(!0);return}if(G)return;console.log("[NATS] Connecting to",he.natsWsUrl);const le=await Dx({servers:he.natsWsUrl,authenticator:Ex(he.natsJwt,new TextEncoder().encode(he.natsNkeySeed)),pingInterval:3e4,maxPingOut:2});if(G){le.close().catch(()=>{});return}if(console.log("[NATS] Connected"),c.current=le,s(le),o(!0),B=1e3,await le.closed(),G)return;console.log("[NATS] Connection closed, will reconnect"),c.current=null,s(null),o(!1)}catch($){if(G)return;console.warn(`[NATS] Connect failed, retrying in ${B}ms:`,$),o(!1),await new Promise(he=>setTimeout(he,B)),B=Math.min(B*2,L)}}return J(),()=>{G=!0,c.current&&(c.current.close().catch(()=>{}),c.current=null,s(null),o(!1))}},[P,t]),E.useEffect(()=>{if(P)return;const G=pd.addListener("appStateChange",B=>{if(!B.isActive||!c.current)return;const L=c.current;Promise.race([L.flush(),new Promise((J,$)=>setTimeout(()=>$(new Error("ping timeout")),2e3))]).catch(()=>{console.log("[NATS] Resume probe failed — cycling conn"),L.close().catch(()=>{})})});return()=>{G.then(B=>B.remove())}},[P]),E.useEffect(()=>{if(!P){d(!1);return}const G=new AbortController;async function B(){var he;const J=new AbortController,$=setTimeout(()=>J.abort(),SE);G.signal.addEventListener("abort",()=>J.abort());try{const le=await fetch(`${t.directUrl}/events`,{headers:{Authorization:`Bearer ${t.clientToken}`},signal:J.signal});return clearTimeout($),le.ok?((he=le.body)==null?void 0:he.getReader())??null:null}catch{return clearTimeout($),null}}async function L(J){d(!0),console.log("[HOST] SSE connected to",t.directUrl),M.current=Date.now();function $(){setTimeout(()=>{G.signal.aborted||Date.now()-M.current<Th||(console.log("[HOST] Heartbeat timeout — no data for",Th/1e3,"s"),G.abort(),d(!1),console.log("[HOST] Direct host unreachable"))},Th)}$();const he=new TextDecoder;let le="";try{for(;;){const{done:te,value:V}=await J.read();if(te)break;le+=he.decode(V,{stream:!0}),M.current=Date.now(),$();const Q=le.split(`
|
|
87
|
+
${f.stack}`),c.reject(m)):c.resolve(b))}});return d.requestSubject=t,this.protocol.publish(t,r,{reply:o,headers:s.headers}),c}else{const o=new xx(this.protocol.muxSubscriptions,t,s,l);this.protocol.request(o);try{this.publish(t,r,{reply:`${this.protocol.muxSubscriptions.baseInbox}${o.token}`,headers:s.headers})}catch(f){o.cancel(f)}const c=Promise.race([o.timer,o.deferred]);return c.catch(()=>{o.cancel()}),c}}flush(){return this.isClosed()?Promise.reject(De.errorForCode(Ce.ConnectionClosed)):this.protocol.flush()}drain(){return this.isClosed()?Promise.reject(De.errorForCode(Ce.ConnectionClosed)):this.isDraining()?Promise.reject(De.errorForCode(Ce.ConnectionDraining)):(this.draining=!0,this.protocol.drain())}isClosed(){return this.protocol.isClosed()}isDraining(){return this.draining}getServer(){const t=this.protocol.getServer();return t?t.listen:""}status(){const t=new wn;return t.iterClosed.then(()=>{const r=this.listeners.indexOf(t);this.listeners.splice(r,1)}),this.listeners.push(t),t}get info(){return this.protocol.isClosed()?void 0:this.protocol.info}async context(){return(await this.request("$SYS.REQ.USER.INFO")).json((r,s)=>r==="time"?new Date(Date.parse(s)):s)}stats(){return{inBytes:this.protocol.inBytes,outBytes:this.protocol.outBytes,inMsgs:this.protocol.inMsgs,outMsgs:this.protocol.outMsgs}}async jetstreamManager(t={}){const r=new Fk(this,t);if(t.checkAPI!==!1)try{await r.getAccountInfo()}catch(s){const l=s;throw l.code===Ce.NoResponders&&(l.code=Ce.JetStreamNotEnabled),l}return r}jetstream(t={}){return new Id(this,t)}getServerVersion(){const t=this.info;return t?ws(t.version):void 0}async rtt(){if(!this.protocol._closed&&!this.protocol.connected)throw De.errorForCode(Ce.Disconnect);const t=Date.now();return await this.flush(),Date.now()-t}get features(){return this.protocol.features}get services(){return this._services||(this._services=new Gk(this)),this._services}reconnect(){return this.isClosed()?Promise.reject(De.errorForCode(Ce.ConnectionClosed)):this.isDraining()?Promise.reject(De.errorForCode(Ce.ConnectionDraining)):this.protocol.reconnect()}}class Gk{constructor(t){C(this,"nc");this.nc=t}add(t){try{return new Xl(this.nc,t).start()}catch(r){return Promise.reject(r)}}client(t,r){return new Ck(this.nc,t,r)}}class Jk{constructor(t,r,s){C(this,"bucket");C(this,"sm");C(this,"prefixLen");this.bucket=t,this.prefixLen=r,this.sm=s}get key(){return this.sm.subject.substring(this.prefixLen)}get value(){return this.sm.data}get delta(){return 0}get created(){return this.sm.time}get revision(){return this.sm.seq}get operation(){return this.sm.header.get(Pu)||"PUT"}get length(){const t=this.sm.header.get(Bn.MessageSizeHdr)||"";return t!==""?parseInt(t,10):this.sm.data.length}json(){return this.sm.json()}string(){return this.sm.string()}}class Xk{constructor(t,r,s){C(this,"bucket");C(this,"key");C(this,"sm");this.bucket=t,this.key=r,this.sm=s}get value(){return this.sm.data}get created(){return new Date(Ud(this.sm.info.timestampNanos))}get revision(){return this.sm.seq}get operation(){var t;return((t=this.sm.headers)==null?void 0:t.get(Pu))||"PUT"}get delta(){return this.sm.info.pending}get length(){var r;const t=((r=this.sm.headers)==null?void 0:r.get(Bn.MessageSizeHdr))||"";return t!==""?parseInt(t,10):this.sm.data.length}json(){return this.sm.json()}string(){return this.sm.string()}}class Rx extends C2{constructor(r,s,l){super(r.nc,s,l);C(this,"js");C(this,"monitor");this.js=r,this.monitor=null,this.sub.closed.then(()=>{this.monitor&&this.monitor.cancel()})}set info(r){this.sub.info=r}get info(){return this.sub.info}_resetOrderedConsumer(r){if(this.info===null||this.sub.isClosed())return;const s=gi(this.js.nc.options.inboxPrefix);this.js.nc._resub(this.sub,s);const o=this.info;o.config.name=Ki.next(),o.ordered_consumer_sequence.delivery_seq=0,o.flow_control.heartbeat_count=0,o.flow_control.fc_count=0,o.flow_control.consumer_restarts++,o.deliver=s,o.config.deliver_subject=s,o.config.deliver_policy=sn.StartSequence,o.config.opt_start_seq=r;const c={};c.stream_name=this.info.stream,c.config=o.config;const f=`${o.api.prefix}.CONSUMER.CREATE.${o.stream}`;this.js._request(f,c,{retries:-1}).then(d=>{const m=d,b=this.sub.info;b.last=m,this.info.config=m.config,this.info.name=m.name}).catch(d=>{const m=new De(`unable to recreate ordered consumer ${o.stream} at seq ${r}`,Ce.RequestError,d);this.sub.callback(m,{})})}_maybeSetupHbMonitoring(){var s,l;const r=((l=(s=this.info)==null?void 0:s.config)==null?void 0:l.idle_heartbeat)||0;r&&this._setupHbMonitoring(Ud(r))}_setupHbMonitoring(r,s=0){const l={cancelAfter:0,maxOut:2};s&&(l.cancelAfter=s);const o=this.sub,c=f=>{var b,g,x,v;const d=a2(409,`${_r.IdleHeartbeatMissed}: ${f}`,this.sub.subject);if(!((b=this.info)==null?void 0:b.ordered))this.sub.callback(null,d);else{if(!this.js.nc.protocol.connected)return!1;const S=((x=(g=this.info)==null?void 0:g.ordered_consumer_sequence)==null?void 0:x.stream_seq)||0;return this._resetOrderedConsumer(S+1),(v=this.monitor)==null||v.restart(),!1}return!o.noIterator};this.monitor=new Bd(r,c,l)}_checkHbOrderConsumer(r){const s=r.headers.get(Bn.ConsumerStalledHdr);s!==""&&this.js.nc.publish(s);const l=parseInt(r.headers.get(Bn.LastConsumerSeqHdr),10),o=this.info.ordered_consumer_sequence;return this.info.flow_control.heartbeat_count++,l!==o.delivery_seq&&this._resetOrderedConsumer(o.stream_seq+1),!1}_checkOrderedConsumer(r){const s=this.info.ordered_consumer_sequence,l=r.info.streamSequence,o=r.info.deliverySequence;return o!=s.delivery_seq+1?(this._resetOrderedConsumer(s.stream_seq+1),!1):(s.delivery_seq=o,s.stream_seq=l,!0)}async destroy(){this.isClosed()||await this.drain();const r=this.sub.info,s=r.config.durable_name||r.name,l=`${r.api.prefix}.CONSUMER.DELETE.${r.stream}.${s}`;await r.api._request(l)}async consumerInfo(){const r=this.sub.info,s=r.config.durable_name||r.name,l=`${r.api.prefix}.CONSUMER.INFO.${r.stream}.${s}`,o=await r.api._request(l);return r.last=o,o}}class Kk extends Rx{constructor(t,r,s){super(t,r,s)}pull(t={batch:1}){const{stream:r,config:s,name:l}=this.sub.info,o=s.durable_name??l,c={};if(c.batch=t.batch||1,c.no_wait=t.no_wait||!1,(t.max_bytes??0)>0){const m=this.js.nc.features.get(gt.JS_PULL_MAX_BYTES);if(!m.ok)throw new Error(`max_bytes is only supported on servers ${m.min} or better`);c.max_bytes=t.max_bytes}let f=0;t.expires&&t.expires>0&&(f=t.expires,c.expires=Gt(f));let d=0;if(t.idle_heartbeat&&t.idle_heartbeat>0&&(d=t.idle_heartbeat,c.idle_heartbeat=Gt(d)),d&&f===0)throw new Error("idle_heartbeat requires expires");if(d>f)throw new Error("expires must be greater than idle_heartbeat");if(this.info){this.monitor&&this.monitor.cancel(),f&&d&&(this.monitor?this.monitor._change(d,f):this._setupHbMonitoring(d,f));const m=this.info.api,b=`${m.prefix}.CONSUMER.MSG.NEXT.${r}.${o}`,g=this.sub.subject;m.nc.publish(b,m.jc.encode(c),{reply:g})}}}function Qk(e,t){return e?Wk(t):Zk(t)}function Zk(e){return(t,r)=>t?[t,null]:(t=pa(r),t?[t,null]:[null,Fl(r,e)])}function Wk(e){return(t,r)=>{if(t)return[t,null];const s=pa(r);return s!==null?[Mx(s),null]:[null,Fl(r,e)]}}function Mx(e){if(e!==null)switch(e.code){case Ce.JetStream404NoMessages:case Ce.JetStream408RequestTimeout:return null;case Ce.JetStream409:return l2(e)?e:null;default:return e}return null}function eE(e){e&&e.ack()}function tE(e){const t=e.split(".");if(t.length===9&&t.splice(2,0,"_",""),t.length<11||t[0]!=="$JS"||t[1]!=="ACK")throw new Error("not js message");const r={};return r.domain=t[2]==="_"?"":t[2],r.account_hash=t[3],r.stream=t[4],r.consumer=t[5],r.deliveryCount=parseInt(t[6],10),r.redeliveryCount=r.deliveryCount,r.redelivered=r.deliveryCount>1,r.streamSequence=parseInt(t[7],10),r.deliverySequence=parseInt(t[8],10),r.timestampNanos=parseInt(t[9],10),r.pending=parseInt(t[10],10),r}class nE{constructor(t,r){C(this,"msg");C(this,"di");C(this,"didAck");C(this,"timeout");this.msg=t,this.didAck=!1,this.timeout=r}get subject(){return this.msg.subject}get sid(){return this.msg.sid}get data(){return this.msg.data}get headers(){return this.msg.headers}get info(){return this.di||(this.di=tE(this.reply)),this.di}get redelivered(){return this.info.deliveryCount>1}get reply(){return this.msg.reply||""}get seq(){return this.info.streamSequence}doAck(t){this.didAck||(this.didAck=!this.isWIP(t),this.msg.respond(t))}isWIP(t){return t.length===4&&t[0]===Sl[0]&&t[1]===Sl[1]&&t[2]===Sl[2]&&t[3]===Sl[3]}async ackAck(t){var s;t=t||{},t.timeout=t.timeout||this.timeout;const r=Jt();if(this.didAck)r.resolve(!1);else if(this.didAck=!0,this.msg.reply){const o=this.msg.publisher,c=!((s=o.options)!=null&&s.noAsyncTraces),f=new xx(o.muxSubscriptions,this.msg.reply,{timeout:t.timeout},c);o.request(f);try{o.publish(this.msg.reply,B0,{reply:`${o.muxSubscriptions.baseInbox}${f.token}`})}catch(d){f.cancel(d)}try{await Promise.race([f.timer,f.deferred]),r.resolve(!0)}catch(d){f.cancel(d),r.reject(d)}}else r.resolve(!1);return r}ack(){this.doAck(B0)}nak(t){let r=zk;t&&(r=Ru().encode(`-NAK ${JSON.stringify({delay:Gt(t)})}`)),this.doAck(r)}working(){this.doAck(Sl)}next(t,r={batch:1}){const s={};s.batch=r.batch||1,s.no_wait=r.no_wait||!1,r.expires&&r.expires>0&&(s.expires=Gt(r.expires));const l=Dr().encode(s),o=Sa.concat(Uk,Bk,l),c=t?{reply:t}:void 0;this.msg.respond(o,c)}term(t=""){let r=Pk;(t==null?void 0:t.length)>0&&(r=Ru().encode(`+TERM ${t}`)),this.doAck(r)}json(){return this.msg.json()}string(){return this.msg.string()}}const rE="1.30.3",iE="nats.ws";class sE{constructor(){C(this,"version");C(this,"lang");C(this,"closeError");C(this,"connected");C(this,"done");C(this,"socket");C(this,"options");C(this,"socketClosed");C(this,"encrypted");C(this,"peeked");C(this,"yields");C(this,"signal");C(this,"closedNotification");this.version=rE,this.lang=iE,this.connected=!1,this.done=!1,this.socketClosed=!1,this.encrypted=!1,this.peeked=!1,this.yields=[],this.signal=Jt(),this.closedNotification=Jt()}async connect(t,r){const s=Jt();if(r.tls)return s.reject(new De("tls",Ce.InvalidOption)),s;this.options=r;const l=t.src;if(r.wsFactory){const{socket:o,encrypted:c}=await r.wsFactory(t.src,r);this.socket=o,this.encrypted=c}else this.encrypted=l.indexOf("wss://")===0,this.socket=new WebSocket(l);return this.socket.binaryType="arraybuffer",this.socket.onopen=()=>{this.isDiscarded()},this.socket.onmessage=o=>{if(this.isDiscarded())return;if(this.yields.push(new Uint8Array(o.data)),this.peeked){this.signal.resolve();return}const c=Sa.concat(...this.yields),f=R2(c);if(f!==""){const d=bk.exec(f);if(!d){r.debug&&console.error("!!!",fu(c)),s.reject(new Error("unexpected response from server"));return}try{const m=JSON.parse(d[1]);gk(m,this.options),this.peeked=!0,this.connected=!0,this.signal.resolve(),s.resolve()}catch(m){s.reject(m);return}}},this.socket.onclose=o=>{if(this.isDiscarded())return;this.socketClosed=!0;let c;this.done||(o.wasClean||(c=new Error(o.reason)),this._closed(c))},this.socket.onerror=o=>{if(this.isDiscarded())return;const c=o,f=new De(c.message,Ce.Unknown,new Error(c.error));s.reject(f)},s}disconnect(){this._closed(void 0,!0)}async _closed(t,r=!0){if(!this.isDiscarded()&&this.connected&&!this.done){if(this.closeError=t,!t)for(;!this.socketClosed&&this.socket.bufferedAmount>0;)await ja(100);this.done=!0;try{this.socket.close(t?1002:1e3,t?t.message:void 0)}catch{}r&&this.closedNotification.resolve(t)}}get isClosed(){return this.done}[Symbol.asyncIterator](){return this.iterate()}async*iterate(){for(;;){if(this.isDiscarded())return;this.yields.length===0&&await this.signal;const t=this.yields;this.yields=[];for(let r=0;r<t.length;r++)this.options.debug&&console.info(`> ${fu(t[r])}`),yield t[r];if(this.done)break;this.yields.length===0&&(t.length=0,this.yields=t,this.signal=Jt())}}isEncrypted(){return this.connected&&this.encrypted}send(t){if(!this.isDiscarded())try{this.socket.send(t.buffer),this.options.debug&&console.info(`< ${fu(t)}`);return}catch(r){this.options.debug&&console.error(`!!! ${fu(t)}: ${r}`)}}close(t){return this._closed(t,!1)}closed(){return this.closedNotification}isDiscarded(){return this.done?(this.discard(),!0):!1}discard(){var t;this.done=!0;try{(t=this.socket)==null||t.close()}catch{}}}function aE(e,t){/^(.*:\/\/)(.*)/.test(e)||(typeof t=="boolean"?e=`${t===!0?"https":"http"}://${e}`:e=`https://${e}`);let s=new URL(e);const l=s.protocol.toLowerCase();l==="ws:"&&(t=!1),l==="wss:"&&(t=!0),l!=="https:"&&l!=="http"&&(e=e.replace(/^(.*:\/\/)(.*)/gm,"$2"),s=new URL(`http://${e}`));let o,c;const f=s.hostname,d=s.pathname,m=s.search||"";switch(l){case"http:":case"ws:":case"nats:":c=s.port||"80",o="ws:";break;case"https:":case"wss:":case"tls:":c=s.port||"443",o="wss:";break;default:c=s.port||t===!0?"443":"80",o=t===!0?"wss:":"ws:";break}return`${o}//${f}:${c}${d}${m}`}function Dx(e={}){return A2({defaultPort:443,urlParseFn:aE,factory:()=>new sE}),Fd.connect(e)}/*! Capacitor: https://capacitorjs.com/ - MIT License */var _a;(function(e){e.Unimplemented="UNIMPLEMENTED",e.Unavailable="UNAVAILABLE"})(_a||(_a={}));class Nh extends Error{constructor(t,r,s){super(t),this.message=t,this.code=r,this.data=s}}const lE=e=>{var t,r;return e!=null&&e.androidBridge?"android":!((r=(t=e==null?void 0:e.webkit)===null||t===void 0?void 0:t.messageHandlers)===null||r===void 0)&&r.bridge?"ios":"web"},oE=e=>{const t=e.CapacitorCustomPlatform||null,r=e.Capacitor||{},s=r.Plugins=r.Plugins||{},l=()=>t!==null?t.name:lE(e),o=()=>l()!=="web",c=g=>{const x=m.get(g);return!!(x!=null&&x.platforms.has(l())||f(g))},f=g=>{var x;return(x=r.PluginHeaders)===null||x===void 0?void 0:x.find(v=>v.name===g)},d=g=>e.console.error(g),m=new Map,b=(g,x={})=>{const v=m.get(g);if(v)return console.warn(`Capacitor plugin "${g}" already registered. Cannot register plugins twice.`),v.proxy;const S=l(),j=f(g);let R;const M=async()=>(!R&&S in x?R=typeof x[S]=="function"?R=await x[S]():R=x[S]:t!==null&&!R&&"web"in x&&(R=typeof x.web=="function"?R=await x.web():R=x.web),R),P=(G,B)=>{var L,J;if(j){const $=j==null?void 0:j.methods.find(he=>B===he.name);if($)return $.rtype==="promise"?he=>r.nativePromise(g,B.toString(),he):(he,le)=>r.nativeCallback(g,B.toString(),he,le);if(G)return(L=G[B])===null||L===void 0?void 0:L.bind(G)}else{if(G)return(J=G[B])===null||J===void 0?void 0:J.bind(G);throw new Nh(`"${g}" plugin is not implemented on ${S}`,_a.Unimplemented)}},I=G=>{let B;const L=(...J)=>{const $=M().then(he=>{const le=P(he,G);if(le){const te=le(...J);return B=te==null?void 0:te.remove,te}else throw new Nh(`"${g}.${G}()" is not implemented on ${S}`,_a.Unimplemented)});return G==="addListener"&&($.remove=async()=>B()),$};return L.toString=()=>`${G.toString()}() { [capacitor code] }`,Object.defineProperty(L,"name",{value:G,writable:!1,configurable:!1}),L},ue=I("addListener"),q=I("removeListener"),N=(G,B)=>{const L=ue({eventName:G},B),J=async()=>{const he=await L;q({eventName:G,callbackId:he},B)},$=new Promise(he=>L.then(()=>he({remove:J})));return $.remove=async()=>{console.warn("Using addListener() without 'await' is deprecated."),await J()},$},ee=new Proxy({},{get(G,B){switch(B){case"$$typeof":return;case"toJSON":return()=>({});case"addListener":return j?N:ue;case"removeListener":return q;default:return I(B)}}});return s[g]=ee,m.set(g,{name:g,proxy:ee,platforms:new Set([...Object.keys(x),...j?[S]:[]])}),ee};return r.convertFileSrc||(r.convertFileSrc=g=>g),r.getPlatform=l,r.handleError=d,r.isNativePlatform=o,r.isPluginAvailable=c,r.registerPlugin=b,r.Exception=Nh,r.DEBUG=!!r.DEBUG,r.isLoggingEnabled=!!r.isLoggingEnabled,r},uE=e=>e.Capacitor=oE(e),Jn=uE(typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{}),ks=Jn.registerPlugin;class $d{constructor(){this.listeners={},this.retainedEventArguments={},this.windowListeners={}}addListener(t,r){let s=!1;this.listeners[t]||(this.listeners[t]=[],s=!0),this.listeners[t].push(r);const o=this.windowListeners[t];o&&!o.registered&&this.addWindowListener(o),s&&this.sendRetainedArgumentsForEvent(t);const c=async()=>this.removeListener(t,r);return Promise.resolve({remove:c})}async removeAllListeners(){this.listeners={};for(const t in this.windowListeners)this.removeWindowListener(this.windowListeners[t]);this.windowListeners={}}notifyListeners(t,r,s){const l=this.listeners[t];if(!l){if(s){let o=this.retainedEventArguments[t];o||(o=[]),o.push(r),this.retainedEventArguments[t]=o}return}l.forEach(o=>o(r))}hasListeners(t){var r;return!!(!((r=this.listeners[t])===null||r===void 0)&&r.length)}registerWindowListener(t,r){this.windowListeners[r]={registered:!1,windowEventName:t,pluginEventName:r,handler:s=>{this.notifyListeners(r,s)}}}unimplemented(t="not implemented"){return new Jn.Exception(t,_a.Unimplemented)}unavailable(t="not available"){return new Jn.Exception(t,_a.Unavailable)}async removeListener(t,r){const s=this.listeners[t];if(!s)return;const l=s.indexOf(r);this.listeners[t].splice(l,1),this.listeners[t].length||this.removeWindowListener(this.windowListeners[t])}addWindowListener(t){window.addEventListener(t.windowEventName,t.handler),t.registered=!0}removeWindowListener(t){t&&(window.removeEventListener(t.windowEventName,t.handler),t.registered=!1)}sendRetainedArgumentsForEvent(t){const r=this.retainedEventArguments[t];r&&(delete this.retainedEventArguments[t],r.forEach(s=>{this.notifyListeners(t,s)}))}}const q0=e=>encodeURIComponent(e).replace(/%(2[346B]|5E|60|7C)/g,decodeURIComponent).replace(/[()]/g,escape),I0=e=>e.replace(/(%[\dA-F]{2})+/gi,decodeURIComponent);class cE extends $d{async getCookies(){const t=document.cookie,r={};return t.split(";").forEach(s=>{if(s.length<=0)return;let[l,o]=s.replace(/=/,"CAP_COOKIE").split("CAP_COOKIE");l=I0(l).trim(),o=I0(o).trim(),r[l]=o}),r}async setCookie(t){try{const r=q0(t.key),s=q0(t.value),l=t.expires?`; expires=${t.expires.replace("expires=","")}`:"",o=(t.path||"/").replace("path=",""),c=t.url!=null&&t.url.length>0?`domain=${t.url}`:"";document.cookie=`${r}=${s||""}${l}; path=${o}; ${c};`}catch(r){return Promise.reject(r)}}async deleteCookie(t){try{document.cookie=`${t.key}=; Max-Age=0`}catch(r){return Promise.reject(r)}}async clearCookies(){try{const t=document.cookie.split(";")||[];for(const r of t)document.cookie=r.replace(/^ +/,"").replace(/=.*/,`=;expires=${new Date().toUTCString()};path=/`)}catch(t){return Promise.reject(t)}}async clearAllCookies(){try{await this.clearCookies()}catch(t){return Promise.reject(t)}}}ks("CapacitorCookies",{web:()=>new cE});const fE=async e=>new Promise((t,r)=>{const s=new FileReader;s.onload=()=>{const l=s.result;t(l.indexOf(",")>=0?l.split(",")[1]:l)},s.onerror=l=>r(l),s.readAsDataURL(e)}),hE=(e={})=>{const t=Object.keys(e);return Object.keys(e).map(l=>l.toLocaleLowerCase()).reduce((l,o,c)=>(l[o]=e[t[c]],l),{})},dE=(e,t=!0)=>e?Object.entries(e).reduce((s,l)=>{const[o,c]=l;let f,d;return Array.isArray(c)?(d="",c.forEach(m=>{f=t?encodeURIComponent(m):m,d+=`${o}=${f}&`}),d.slice(0,-1)):(f=t?encodeURIComponent(c):c,d=`${o}=${f}`),`${s}&${d}`},"").substr(1):null,mE=(e,t={})=>{const r=Object.assign({method:e.method||"GET",headers:e.headers},t),l=hE(e.headers)["content-type"]||"";if(typeof e.data=="string")r.body=e.data;else if(l.includes("application/x-www-form-urlencoded")){const o=new URLSearchParams;for(const[c,f]of Object.entries(e.data||{}))o.set(c,f);r.body=o.toString()}else if(l.includes("multipart/form-data")||e.data instanceof FormData){const o=new FormData;if(e.data instanceof FormData)e.data.forEach((f,d)=>{o.append(d,f)});else for(const f of Object.keys(e.data))o.append(f,e.data[f]);r.body=o;const c=new Headers(r.headers);c.delete("content-type"),r.headers=c}else(l.includes("application/json")||typeof e.data=="object")&&(r.body=JSON.stringify(e.data));return r};class pE extends $d{async request(t){const r=mE(t,t.webFetchExtra),s=dE(t.params,t.shouldEncodeUrlParams),l=s?`${t.url}?${s}`:t.url,o=await fetch(l,r),c=o.headers.get("content-type")||"";let{responseType:f="text"}=o.ok?t:{};c.includes("application/json")&&(f="json");let d,m;switch(f){case"arraybuffer":case"blob":m=await o.blob(),d=await fE(m);break;case"json":d=await o.json();break;case"document":case"text":default:d=await o.text()}const b={};return o.headers.forEach((g,x)=>{b[x]=g}),{data:d,headers:b,status:o.status,url:o.url}}async get(t){return this.request(Object.assign(Object.assign({},t),{method:"GET"}))}async post(t){return this.request(Object.assign(Object.assign({},t),{method:"POST"}))}async put(t){return this.request(Object.assign(Object.assign({},t),{method:"PUT"}))}async patch(t){return this.request(Object.assign(Object.assign({},t),{method:"PATCH"}))}async delete(t){return this.request(Object.assign(Object.assign({},t),{method:"DELETE"}))}}ks("CapacitorHttp",{web:()=>new pE});var F0;(function(e){e.Dark="DARK",e.Light="LIGHT",e.Default="DEFAULT"})(F0||(F0={}));var $0;(function(e){e.StatusBar="StatusBar",e.NavigationBar="NavigationBar"})($0||($0={}));class gE extends $d{async setStyle(){this.unavailable("not available for web")}async setAnimation(){this.unavailable("not available for web")}async show(){this.unavailable("not available for web")}async hide(){this.unavailable("not available for web")}}ks("SystemBars",{web:()=>new gE});const yE="modulepreload",bE=function(e){return"/"+e},V0={},Vd=function(t,r,s){let l=Promise.resolve();if(r&&r.length>0){let c=function(m){return Promise.all(m.map(b=>Promise.resolve(b).then(g=>({status:"fulfilled",value:g}),g=>({status:"rejected",reason:g}))))};document.getElementsByTagName("link");const f=document.querySelector("meta[property=csp-nonce]"),d=(f==null?void 0:f.nonce)||(f==null?void 0:f.getAttribute("nonce"));l=c(r.map(m=>{if(m=bE(m),m in V0)return;V0[m]=!0;const b=m.endsWith(".css"),g=b?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${m}"]${g}`))return;const x=document.createElement("link");if(x.rel=b?"stylesheet":yE,b||(x.as="script"),x.crossOrigin="",x.href=m,d&&x.setAttribute("nonce",d),document.head.appendChild(x),b)return new Promise((v,S)=>{x.addEventListener("load",v),x.addEventListener("error",()=>S(new Error(`Unable to preload CSS for ${m}`)))})}))}function o(c){const f=new Event("vite:preloadError",{cancelable:!0});if(f.payload=c,window.dispatchEvent(f),!f.defaultPrevented)throw c}return l.then(c=>{for(const f of c||[])f.status==="rejected"&&o(f.reason);return t().catch(o)})},pd=ks("App",{web:()=>Vd(()=>import("./web-DurpjXBX.js"),[]).then(e=>new e.AppWeb)}),xE=ks("Network",{web:()=>Vd(()=>import("./web-0ZvmFBgz.js"),[]).then(e=>new e.NetworkWeb)}),Bu=Jn.isNativePlatform()?"https://app.palmier.me":"";async function Lx(e,t,r,s){const l=`${Bu}${t}`;console.log(`[API] ${e} ${l}`);const c=await fetch(l,{method:e,headers:{"Content-Type":"application/json"},body:r!=null?JSON.stringify(r):void 0});if(!c.ok){const f=await c.text();let d;try{const m=JSON.parse(f);d=m.error??m.message??f}catch{d=f}throw console.error(`[API] ${e} ${t} failed:`,c.status,d),new Error(d||`Request failed with status ${c.status}`)}return console.log(`[API] ${e} ${t} ->`,c.status),c.json()}function vE(e,t,r){return Lx("POST",e,t)}function wE(e,t){return Lx("GET",e,void 0)}const Y0=Jn.isNativePlatform(),zx=E.createContext(null),SE=2e3,Th=6e3,_E=1500,kE=6e4;function EE({children:e,activeHost:t}){const[r,s]=E.useState(null),[l,o]=E.useState(!1),c=E.useRef(null),[f,d]=E.useState(!1),[m,b]=E.useState(!1),[g,x]=E.useState(!1),[v,S]=E.useState(!1),j=E.useRef(Ru()),R=E.useRef(new Set),M=E.useRef(0),P=!!t.directUrl,I=Y0&&!P&&!!t.lanUrl&&v,ue=m||g?"disconnected":P?f?"direct":"connecting":l?I?"lan":"nats":"connecting",q=ue!=="connecting"&&ue!=="disconnected";E.useEffect(()=>{if(!Y0||P||!t.lanUrl){S(!1);return}let G=!1;const B=t.lanUrl,L=t.hostId;async function J(){console.log("[HOST/LAN] probing",B);try{const te=await fetch(`${B}/health`,{signal:AbortSignal.timeout(_E)});if(G)return;if(!te.ok){console.log("[HOST/LAN] probe got non-ok:",te.status),S(!1);return}const V=await te.json(),Q=V.hostId===L;Q?console.log("[HOST/LAN] reachable"):console.log("[HOST/LAN] hostId mismatch — got:",V.hostId,"expected:",L),S(Q)}catch(te){G||(console.log("[HOST/LAN] probe failed:",te instanceof Error?te.message:te),S(!1))}}J();const $=window.setInterval(J,kE),he=pd.addListener("appStateChange",te=>{te.isActive&&J()}),le=xE.addListener("networkStatusChange",()=>J());return()=>{G=!0,clearInterval($),he.then(te=>te.remove()),le.then(te=>te.remove())}},[t.hostId,t.lanUrl,P]),E.useEffect(()=>{if(P){c.current&&(c.current.close().catch(()=>{}),c.current=null,s(null),o(!1));return}let G=!1,B=1e3;const L=3e4;async function J(){for(;!G;)try{const $=await fetch(`${Bu}/api/nats-credentials/${t.hostId}`);if(G)return;if($.status===401||$.status===403||$.status===404){console.error("[NATS] Host not found or rejected by relay:",$.status),x(!0);return}if(!$.ok)throw new Error(`credentials fetch ${$.status}`);const he=await $.json();if(!he.natsWsUrl){console.error("[NATS] Relay returned empty natsWsUrl — treating as terminal"),x(!0);return}if(G)return;console.log("[NATS] Connecting to",he.natsWsUrl);const le=await Dx({servers:he.natsWsUrl,authenticator:Ex(he.natsJwt,new TextEncoder().encode(he.natsNkeySeed)),pingInterval:3e4,maxPingOut:2});if(G){le.close().catch(()=>{});return}if(console.log("[NATS] Connected"),c.current=le,s(le),o(!0),B=1e3,await le.closed(),G)return;console.log("[NATS] Connection closed, will reconnect"),c.current=null,s(null),o(!1)}catch($){if(G)return;console.warn(`[NATS] Connect failed, retrying in ${B}ms:`,$),o(!1),await new Promise(he=>setTimeout(he,B)),B=Math.min(B*2,L)}}return J(),()=>{G=!0,c.current&&(c.current.close().catch(()=>{}),c.current=null,s(null),o(!1))}},[P,t]),E.useEffect(()=>{if(P)return;const G=pd.addListener("appStateChange",B=>{if(!B.isActive||!c.current)return;const L=c.current;Promise.race([L.flush(),new Promise((J,$)=>setTimeout(()=>$(new Error("ping timeout")),2e3))]).catch(()=>{console.log("[NATS] Resume probe failed — cycling conn"),L.close().catch(()=>{})})});return()=>{G.then(B=>B.remove())}},[P]),E.useEffect(()=>{if(!P){d(!1);return}const G=new AbortController;async function B(){var he;const J=new AbortController,$=setTimeout(()=>J.abort(),SE);G.signal.addEventListener("abort",()=>J.abort());try{const le=await fetch(`${t.directUrl}/events`,{headers:{Authorization:`Bearer ${t.clientToken}`},signal:J.signal});return clearTimeout($),le.ok?((he=le.body)==null?void 0:he.getReader())??null:null}catch{return clearTimeout($),null}}async function L(J){d(!0),console.log("[HOST] SSE connected to",t.directUrl),M.current=Date.now();function $(){setTimeout(()=>{G.signal.aborted||Date.now()-M.current<Th||(console.log("[HOST] Heartbeat timeout — no data for",Th/1e3,"s"),G.abort(),d(!1),console.log("[HOST] Direct host unreachable"))},Th)}$();const he=new TextDecoder;let le="";try{for(;;){const{done:te,value:V}=await J.read();if(te)break;le+=he.decode(V,{stream:!0}),M.current=Date.now(),$();const Q=le.split(`
|
|
88
88
|
`);le=Q.pop()??"";for(const X of Q)if(X.startsWith("data: ")){const xe=X.slice(6);try{const A=JSON.parse(xe);if(A.task_id&&A.event_type){const z=`host-event.${t.hostId}.${A.task_id}`;for(const W of R.current)W({subject:z,data:j.current.encode(xe)})}}catch{}}}}catch{}}return(async()=>{const J=await B();J&&await L(J)})(),()=>{G.abort(),d(!1)}},[t,P]);const N=E.useCallback(async(G,B,L)=>{function J(le){le&&typeof le=="object"&&le.error==="Unauthorized"&&b(!0)}async function $(le,te){console.log(`[HOST/${te}] → ${G}`,B??"");const V=await fetch(`${le}/rpc/${G}`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t.clientToken}`},body:B!=null?JSON.stringify(B):void 0,signal:L!=null&&L.timeout?AbortSignal.timeout(L.timeout):void 0});if(V.status===401)throw b(!0),new Error("Unauthorized");const Q=await V.json();return J(Q),console.log(`[HOST/${te}] ← ${G}`,Q),Q}async function he(){if(!c.current)throw new Error("Not connected");const le=`host.${t.hostId}.rpc.${G}`,te={...B??{},clientToken:t.clientToken},V=j.current.encode(JSON.stringify(te));console.log(`[HOST/NATS] → ${G}`,B??"");const Q=await c.current.request(le,V,{timeout:(L==null?void 0:L.timeout)??1e4}),X=JSON.parse(j.current.decode(Q.data));return J(X),console.log(`[HOST/NATS] ← ${G}`,X),X}if(P)return $(t.directUrl,"HTTP");if(I&&t.lanUrl)try{return await $(t.lanUrl,"LAN")}catch(le){if(le instanceof Error&&le.message==="Unauthorized")throw le;console.log("[HOST/LAN] failed, falling back to NATS:",le),S(!1)}return he()},[t,P,I]),ee=E.useCallback((G,B)=>{if(P)return R.current.add(B),()=>{R.current.delete(B)};if(c.current){const L=c.current.subscribe(`host-event.${G}.>`);let J=!1;return(async()=>{try{for await(const $ of L){if(J)break;B({subject:$.subject,data:$.data})}}catch{}})(),()=>{J=!0,L.unsubscribe()}}return()=>{}},[t,P]);return y.jsx(zx.Provider,{value:{connected:q,mode:ue,nc:r,request:N,subscribeEvents:ee,activeHost:t,unauthorized:m},children:e})}function xi(){const e=E.useContext(zx);if(!e)throw new Error("useHostConnection must be used within HostConnectionProvider");return e}const On=Jn.isNativePlatform()?ks("Device"):null;function CE(e,t){const r=new Date(e),s=new Date,l={year:"numeric",month:"2-digit",day:"2-digit",timeZone:t};return r.toLocaleDateString(void 0,l)===s.toLocaleDateString(void 0,l)?new Intl.DateTimeFormat(void 0,{timeStyle:"short",timeZone:t}).format(r):new Intl.DateTimeFormat(void 0,{dateStyle:"medium",timeStyle:"short",timeZone:t}).format(r)}function Yd(){const{activeHost:e}=xi(),t=e.timezone;return E.useCallback(r=>CE(r,t),[t])}function AE(e){const t=new Intl.DateTimeFormat("en-CA",{timeZone:e,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",hour12:!1}).formatToParts(new Date),r=s=>{var l;return((l=t.find(o=>o.type===s))==null?void 0:l.value)??""};return{date:`${r("year")}-${r("month")}-${r("day")}`,time:`${r("hour")}:${r("minute")}`}}function jE(e){const t=new Intl.DateTimeFormat("en-CA",{timeZone:e,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",hour12:!1}).formatToParts(new Date),r=s=>{var l;return Number(((l=t.find(o=>o.type===s))==null?void 0:l.value)??"0")};return{year:r("year"),month:r("month"),day:r("day"),hour:r("hour")%24,minute:r("minute")}}function NE(e,t,r){return new Date(Date.UTC(e,t-1,r)).getUTCDay()}function TE(e,t){return new Date(Date.UTC(e,t,0)).getUTCDate()}function G0(e,t){const r=new Date(Date.UTC(e.year,e.month-1,e.day));return r.setUTCDate(r.getUTCDate()+t),{year:r.getUTCFullYear(),month:r.getUTCMonth()+1,day:r.getUTCDate(),hour:e.hour,minute:e.minute}}function Dl(e,t){return e.year!==t.year?e.year-t.year:e.month!==t.month?e.month-t.month:e.day!==t.day?e.day-t.day:e.hour!==t.hour?e.hour-t.hour:e.minute-t.minute}function OE(e,t){const r=Date.UTC(e.year,e.month-1,e.day,e.hour,e.minute);if(!t)return r;const s=new Intl.DateTimeFormat("en-CA",{timeZone:t,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1}).formatToParts(new Date(r)),l=c=>{var f;return Number(((f=s.find(d=>d.type===c))==null?void 0:f.value)??"0")},o=Date.UTC(l("year"),l("month")-1,l("day"),l("hour")%24,l("minute"),l("second"));return r-(o-r)}function RE(e,t){const r=e.split(" ");if(r.length!==5)return null;const[s,l,o,,c]=r;if(l==="*"){const b=Number(s);if(Number.isNaN(b))return null;if(b>t.minute)return{...t,minute:b};const g=new Date(Date.UTC(t.year,t.month-1,t.day,t.hour+1,b));return{year:g.getUTCFullYear(),month:g.getUTCMonth()+1,day:g.getUTCDate(),hour:g.getUTCHours(),minute:g.getUTCMinutes()}}const f=Number(s),d=Number(l);if(Number.isNaN(f)||Number.isNaN(d))return null;if(c!=="*"){const b=Number(c);if(Number.isNaN(b))return null;for(let g=0;g<8;g++){const x=G0({...t,hour:d,minute:f},g);if(NE(x.year,x.month,x.day)===b&&Dl(x,t)>0)return x}return null}if(o!=="*"){const b=Number(o);if(Number.isNaN(b))return null;let g=t.year,x=t.month;for(let v=0;v<24;v++){if(b<=TE(g,x)){const S={year:g,month:x,day:b,hour:d,minute:f};if(Dl(S,t)>0)return S}x++,x>12&&(x=1,g++)}return null}const m={...t,hour:d,minute:f};return Dl(m,t)>0?m:G0(m,1)}function ME(e){const t=/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})/.exec(e);return t?{year:Number(t[1]),month:Number(t[2]),day:Number(t[3]),hour:Number(t[4]),minute:Number(t[5])}:null}function DE(e,t,r){if(!e||!t||t.length===0||e==="on_new_notification"||e==="on_new_sms")return null;const s=jE(r),l=[];for(const o of t)if(e==="specific_times"){const c=ME(o);c&&Dl(c,s)>0&&l.push(c)}else{const c=RE(o,s);c&&l.push(c)}return l.length===0?null:(l.sort(Dl),OE(l[0],r))}const Ux={};function LE(e){for(const t of e)Ux[t.key]=t.label}function gd(e){return Ux[e]??e}const zE=()=>window.matchMedia("(max-width: 600px)").matches;function UE({task:e,lastEvent:t,onEdit:r,onDelete:s,onViewRun:l}){var V;const{request:o,activeHost:c}=xi(),f=Yd(),d=c.timezone,[m,b]=E.useState(!1),[g,x]=E.useState(!1),[v,S]=E.useState(!1),j=E.useRef(null),R=(t==null?void 0:t.running_state)==="started",M=(((V=e.schedule_values)==null?void 0:V.length)??0)>0,P=e.schedule_type==="on_new_notification"||e.schedule_type==="on_new_sms",I=!!e.command,ue=!!e.schedule_type&&(M||P)||I,N=!!e.schedule_enabled&&ue?R?"var(--color-success)":(t==null?void 0:t.running_state)==="failed"?"var(--color-error)":"var(--color-success)":"var(--color-text-secondary)";E.useEffect(()=>{if(!g)return;function Q(X){j.current&&!j.current.contains(X.target)&&x(!1)}return document.addEventListener("mousedown",Q),()=>document.removeEventListener("mousedown",Q)},[g]);function ee(){zE()?S(!0):x(Q=>!Q)}function G(){x(!1),S(!1)}async function B(){if(G(),!!confirm("Abort this task?")){b(!0);try{await o("task.abort",{id:e.id})}catch(Q){console.error("Abort failed:",Q)}finally{b(!1)}}}async function L(){G();try{const Q=await o("task.run",{id:e.id});l(e.id,Q.run_id)}catch(Q){console.error("Run failed:",Q)}}async function J(){if(G(),!!confirm("Delete this task? Results and reports will be kept."))try{await o("task.delete",{id:e.id}),s(e.id)}catch(Q){console.error("Delete failed:",Q)}}const $={started:"Started",finished:"Finished",aborted:"Aborted",failed:"Failed"};function he(){if(I)return"On Command Output";if(e.schedule_type==="on_new_notification")return"On new notification";if(e.schedule_type==="on_new_sms")return"On new SMS";const Q=DE(e.schedule_type,e.schedule_values,d);return Q===null?"No upcoming runs":`Next: ${f(Q)}`}const le=he(),te=y.jsxs(y.Fragment,{children:[y.jsxs("button",{onClick:()=>{G(),r(e)},children:[y.jsx("span",{className:"menu-icon",children:"✎"}),"Edit"]}),y.jsxs("button",{onClick:()=>{G(),l(e.id)},children:[y.jsx("span",{className:"menu-icon",children:"📄"}),"View All Runs"]}),R?y.jsxs("button",{className:"menu-item-danger",onClick:B,disabled:m,children:[y.jsx("span",{className:"menu-icon",children:"◼"}),"Abort"]}):y.jsxs(y.Fragment,{children:[y.jsxs("button",{onClick:L,children:[y.jsx("span",{className:"menu-icon",children:"▶"}),"Run Now"]}),y.jsxs("button",{className:"menu-item-danger",onClick:J,children:[y.jsx("span",{className:"menu-icon",children:"🗑"}),"Delete"]})]})]});return y.jsxs(y.Fragment,{children:[y.jsxs("div",{className:"task-card",onClick:()=>l(e.id,R?"latest":void 0),children:[y.jsxs("div",{className:"task-card-header",children:[y.jsxs("div",{className:"task-card-title-row",children:[R?y.jsx("span",{className:"status-spinner",children:y.jsx("span",{})}):y.jsx("span",{className:"status-dot",style:{backgroundColor:N}}),y.jsx("h3",{className:"task-card-name",children:e.custom_name||e.name||e.user_prompt})]}),y.jsx("div",{className:"task-card-actions",onClick:Q=>Q.stopPropagation(),children:y.jsxs("div",{className:"task-card-menu",ref:j,children:[y.jsx("button",{className:"task-card-menu-btn",onClick:ee,"aria-label":"Task actions",children:"⋮"}),g&&y.jsx("div",{className:"task-card-menu-dropdown",children:te})]})})]}),y.jsxs("div",{className:"task-card-meta",children:[e.agent&&y.jsx("span",{className:"task-card-agent",children:gd(e.agent)}),t&&$[t.running_state]&&y.jsxs("span",{className:"task-card-last-event",children:[$[t.running_state]," ",f(t.time_stamp)]}),ue&&y.jsx("span",{className:"task-card-triggers",children:e.schedule_enabled?le:"Schedule disabled"})]})]}),v&&pi.createPortal(y.jsx("div",{className:"bottom-sheet-overlay",onClick:()=>S(!1),children:y.jsxs("div",{className:"bottom-sheet",onClick:Q=>Q.stopPropagation(),children:[y.jsx("div",{className:"bottom-sheet-handle"}),y.jsx("div",{className:"bottom-sheet-title",children:e.custom_name||e.name||e.user_prompt}),y.jsx("div",{className:"bottom-sheet-actions",children:te})]})}),document.body)]})}function PE({permissions:e}){return y.jsxs("div",{className:"permissions-dialog",children:[y.jsx("h2",{children:"Granted Permissions"}),y.jsx("div",{className:"permissions-dialog-scroll",children:e&&e.length>0?y.jsx("div",{className:"permissions-section",children:y.jsx("ul",{className:"permissions-list",children:e.map((t,r)=>y.jsxs("li",{className:"permission-item",children:[y.jsx("span",{className:"permission-tool",children:t.name}),y.jsx("span",{className:"permission-desc",children:t.description})]},r))})}):y.jsx("p",{className:"permissions-empty",children:"No permissions have been granted for this task."})}),y.jsx("div",{className:"permissions-dialog-actions",children:y.jsx("button",{className:"btn btn-secondary",onClick:()=>history.back(),children:"Back"})})]})}const ua=[];function BE(){const e=ua.pop();e&&(e.pushed.current=!1,e.close())}let J0=!1;function HE(){J0||(J0=!0,window.addEventListener("popstate",BE))}function yd(e,t){const r=E.useRef(!1),s=E.useRef(t);s.current=t;const l=E.useCallback(()=>s.current(),[]),o=E.useRef({close:l,pushed:r});o.current.close=l,E.useEffect(()=>{if(e&&!r.current)HE(),history.pushState({modal:!0},""),ua.push(o.current),r.current=!0;else if(!e&&r.current){r.current=!1;const c=ua.indexOf(o.current);c!==-1&&ua.splice(c,1),history.back()}},[e,l]),E.useEffect(()=>{const c=o.current;return()=>{if(r.current){r.current=!1;const f=ua.indexOf(c);f!==-1&&ua.splice(f,1),history.back()}}},[])}const qE=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],IE=["specific_times","hourly","daily","weekly","monthly"];function pu(e){return IE.includes(e)}function FE(e){return e==="on_new_notification"||e==="on_new_sms"}function mi(e="daily"){return{schedule:e,time:"00:00",dayOfWeek:"1",dayOfMonth:"1",onceDate:"",onceTime:"00:00"}}function $E(e){const t=e.split(" ");if(t.length!==5)return mi();const[r,s,l,,o]=t;if(s==="*")return mi("hourly");const c=`${s.padStart(2,"0")}:${r.padStart(2,"0")}`;return o!=="*"?{...mi("weekly"),time:c,dayOfWeek:o}:l!=="*"?{...mi("monthly"),time:c,dayOfMonth:l}:{...mi("daily"),time:c}}function Px(e,t){if(e==="specific_times"){const[r,s]=t.split("T");return{...mi("specific_times"),onceDate:r??"",onceTime:(s??"09:00").slice(0,5)}}return $E(t)}function VE(e){const[t,r]=e.time.split(":").map(Number);switch(e.schedule){case"hourly":return"0 * * * *";case"daily":return`${r} ${t} * * *`;case"weekly":return`${r} ${t} * * ${e.dayOfWeek}`;case"monthly":return`${r} ${t} ${e.dayOfMonth} * *`;default:return"0 * * * *"}}function YE(e){return e.schedule==="specific_times"?e.onceDate?`${e.onceDate}T${e.onceTime}`:null:VE(e)}function Oh(e){return e==="specific_times"?"specific_times":e==="on_new_notification"?"on_new_notification":e==="on_new_sms"?"on_new_sms":"crons"}function Rh(e){var s;if(!e)return"daily";if(e.command)return"command";const t=e.schedule_type;if(t==="on_new_notification"||t==="on_new_sms")return t;if(t!=="crons"&&t!=="specific_times")return"ondemand";const r=(s=e.schedule_values)==null?void 0:s[0];return r?Px(t,r).schedule:"ondemand"}function GE({initial:e,agents:t,hostPlatform:r,isNotificationListener:s,onSaved:l,onCancel:o}){var Kn;const{request:c,activeHost:f}=xi(),{setHostLastAgent:d}=Zi(),m=()=>{var Re;const we=f.lastAgent,Ye=t.map(bt=>bt.key);return we&&Ye.includes(we)?we:((Re=t[0])==null?void 0:Re.key)??""},[b,g]=E.useState((e==null?void 0:e.custom_name)??""),[x,v]=E.useState((e==null?void 0:e.user_prompt)??""),[S,j]=E.useState((e==null?void 0:e.agent)??m()),R=!!((Kn=e==null?void 0:e.permissions)!=null&&Kn.length)&&S===(e==null?void 0:e.agent),[M,P]=E.useState(!1),I=E.useCallback(()=>P(!1),[]);yd(M,I);const[ue,q]=E.useState(null),[N,ee]=E.useState(()=>Rh(e)),[G,B]=E.useState(()=>{const we=e==null?void 0:e.schedule_type,Ye=e==null?void 0:e.schedule_values;if(Ye&&(we==="crons"||we==="specific_times"))return Ye.map(bt=>Px(we,bt));const Re=Rh(e);return pu(Re)?[mi(Re)]:[]}),[L,J]=E.useState((e==null?void 0:e.requires_confirmation)??!1),[$,he]=E.useState(e!=null&&e.schedule_type||e!=null&&e.command?e.schedule_enabled??!0:!0),[le,te]=E.useState((e==null?void 0:e.yolo_mode)??!1),[V,Q]=E.useState((e==null?void 0:e.foreground_mode)??!1),[X,xe]=E.useState((e==null?void 0:e.command)??""),[A,z]=E.useState(!1),W=(e==null?void 0:e.schedule_type)==="on_new_notification"&&e.schedule_values&&e.schedule_values.length>0?e.schedule_values[0]:"",[T,ve]=E.useState(W),[je,Ne]=E.useState([]),[ce,Ae]=E.useState(!1),[ke,Qe]=E.useState(!1),[Lt,dn]=E.useState(""),tn=E.useCallback(()=>Qe(!1),[]);yd(ke,tn),E.useEffect(()=>{if(N!=="on_new_notification"||!s||!Jn.isNativePlatform()||!On)return;let we=!1;return Ae(!0),On.getInstalledApps().then(({apps:Ye})=>{if(we)return;const Re="com.palmier.app",bt=Ye.filter(ln=>ln.packageName!==Re).sort((ln,Hn)=>(ln.appName||ln.packageName).localeCompare(Hn.appName||Hn.packageName));Ne(bt)}).catch(()=>{}).finally(()=>{we||Ae(!1)}),()=>{we=!0}},[N,s]);const Ft=(e==null?void 0:e.schedule_type)==="on_new_sms"&&e.schedule_values&&e.schedule_values.length>0?e.schedule_values[0]:"",[$t,an]=E.useState(Ft),bn=E.useRef(null),Be=pu(N),nt=N==="command",st=FE(N),Ot=N==="specific_times"||N==="daily"||N==="weekly"||N==="monthly",_t=t.find(we=>we.key===S),mn=!!(_t!=null&&_t.supportsYolo);E.useEffect(()=>{!mn&&le&&te(!1)},[mn,le]);const at=!!e,Cr=Rh(e),ae=at&&b.trim()!==((e==null?void 0:e.custom_name)??""),_e=!at||ae||x!==((e==null?void 0:e.user_prompt)??"")||S!==((e==null?void 0:e.agent)??"")||N!==Cr||L!==((e==null?void 0:e.requires_confirmation)??!1)||$!==(e!=null&&e.schedule_type||e!=null&&e.command?e.schedule_enabled??!0:!0)||le!==((e==null?void 0:e.yolo_mode)??!1)||V!==((e==null?void 0:e.foreground_mode)??!1)||nt&&X!==((e==null?void 0:e.command)??"")||Be&&(JSON.stringify(Vt())!==JSON.stringify((e==null?void 0:e.schedule_values)??[])||Oh(N)!==((e==null?void 0:e.schedule_type)??void 0))||st&&N!==(e==null?void 0:e.schedule_type)||N==="on_new_notification"&&T.trim()!==W.trim()||N==="on_new_sms"&&$t.trim()!==Ft.trim(),Me=AE(f.timezone),Ge=Be&&G.some(we=>we.schedule==="specific_times"&&(!we.onceDate||we.onceDate<Me.date||we.onceDate===Me.date&&(we.onceTime??"")<=Me.time)),rt=_e&&!!x.trim()&&!Ge&&(!nt||!!X.trim())&&(!Be||G.length>0);function zt(we,Ye){B(Re=>Re.map((bt,ln)=>ln===we?{...bt,...Ye}:bt))}function Sn(we){B(Ye=>Ye.filter((Re,bt)=>bt!==we))}function Kt(){pu(N)&&B(we=>[...we,we.length>0?{...we[we.length-1]}:mi(N)])}function yt(we){ee(we),pu(we)?B([mi(we)]):(B([]),J(!1)),we==="command"?setTimeout(()=>{var Ye;return(Ye=bn.current)==null?void 0:Ye.focus()},0):xe(""),we!=="on_new_notification"&&ve(W),we!=="on_new_sms"&&an(Ft)}function Vt(){return G.flatMap(we=>{const Ye=YE(we);return Ye?[Ye]:[]})}function Ze(){return le?confirm(`Yolo mode is enabled. The agent will auto-approve all tool calls — it can read, write, delete files, run arbitrary commands, and access the network without asking for permission.
|
|
89
89
|
|
|
90
90
|
Are you sure you want to continue?`):!0}async function An(){z(!0),q(null);try{const we=Be?Vt():N==="on_new_notification"&&T.trim()?[T.trim()]:N==="on_new_sms"&&$t.trim()?[$t.trim()]:[],Ye=Be||st?Oh(N):null,Re={user_prompt:x,agent:S,schedule_type:Ye,schedule_values:we.length>0?we:null,schedule_enabled:N==="ondemand"?!0:$,requires_confirmation:Be?L:!1,yolo_mode:le,foreground_mode:V,command:nt?X:""};at&&(Re.id=e.id,ae&&(Re.custom_name=b.trim()));const ln=await c(at?"task.update":"task.create",Re,{timeout:45e3});if(ln.error){q(ln.error);return}at||d(f.hostId,S),l(ln)}catch(we){q(we instanceof Error?we.message:String(we))}finally{z(!1)}}const pn=at?"Save":(Be||st||nt)&&$?"Schedule":"Save";return y.jsxs("div",{className:"task-form-overlay",children:[y.jsx("div",{className:"task-form",children:M?y.jsx(PE,{permissions:e==null?void 0:e.permissions}):y.jsxs(y.Fragment,{children:[y.jsx("div",{className:"task-form-header",children:y.jsx("h2",{children:e?"Edit Task":"New Task"})}),ue&&y.jsx("div",{className:"form-error",children:ue}),at&&y.jsxs("div",{children:[y.jsxs("label",{className:"form-label task-title-field",children:["Title",y.jsx("input",{className:"form-input",type:"text",value:b,onChange:we=>g(we.target.value),placeholder:e.name,maxLength:80,disabled:A})]}),y.jsx("p",{className:"command-help-text task-title-help",children:"Leave empty to use an auto-generated title."})]}),y.jsx("textarea",{autoFocus:!e,className:"form-textarea",value:x,onChange:we=>v(we.target.value),placeholder:nt?"If the input email contains an event, create a calendar entry for it.":"Research today's top AI news and write a summary.",rows:4,disabled:A}),y.jsxs("div",{className:"plan-actions",children:[t.length>0&&y.jsx("div",{className:"agent-picker-section-inline",children:t.length>1?y.jsx("select",{className:"form-select form-select-sm",value:S,onChange:we=>j(we.target.value),disabled:A,children:t.map(we=>y.jsx("option",{value:we.key,children:we.label},we.key))}):y.jsx("span",{className:"agent-picker-single",children:(_t==null?void 0:_t.label)??t[0].label})}),mn&&y.jsxs("label",{className:"yolo-inline",style:{marginLeft:"auto"},children:[y.jsx("input",{type:"checkbox",checked:le,onChange:we=>te(we.target.checked),disabled:A}),"Yolo"]}),mn&&le&&y.jsx("p",{className:"yolo-warning",children:"The agent will auto-approve all tool calls without asking for permission."}),R&&y.jsx("div",{className:"granted-permissions-row",children:y.jsx("button",{className:"btn btn-link",onClick:()=>P(!0),children:"Granted Permissions"})})]}),y.jsx("div",{className:"toggles-group",children:y.jsxs("div",{className:"schedule-section",children:[y.jsxs("h3",{className:"schedule-section-title",children:["Schedule ",Ot&&y.jsx("span",{className:"schedule-section-hint",children:"based on host time"})]}),y.jsxs("select",{className:"form-select",value:N,onChange:we=>yt(we.target.value),disabled:A,children:[y.jsx("option",{value:"ondemand",children:"On User Demand"}),y.jsx("option",{value:"specific_times",children:"Specific Times"}),y.jsx("option",{value:"hourly",children:"Hourly"}),y.jsx("option",{value:"daily",children:"Daily"}),y.jsx("option",{value:"weekly",children:"Weekly"}),y.jsx("option",{value:"monthly",children:"Monthly"}),y.jsx("option",{value:"on_new_notification",children:"On New Notification"}),y.jsx("option",{value:"on_new_sms",children:"On New SMS"}),y.jsx("option",{value:"command",children:"On Command Output"})]}),st&&y.jsxs("div",{className:"schedule-reactive",children:[y.jsxs("p",{className:"command-help-text",children:[N==="on_new_notification"?"Runs each time a new push notification arrives on the paired Android device.":"Runs each time a new SMS arrives on the paired Android device."," ","The triggering payload is spliced into your task prompt — reference it as “the new ",N==="on_new_notification"?"notification":"SMS","”."]}),N==="on_new_notification"&&(()=>{const we=je.find(Re=>Re.packageName===T),Ye=(we==null?void 0:we.appName)||T;return y.jsxs(y.Fragment,{children:[s?T.trim()?y.jsxs("div",{className:"app-filter-selected",children:[y.jsx("span",{className:"app-filter-selected-name",children:Ye}),(we==null?void 0:we.appName)&&y.jsx("span",{className:"app-filter-selected-pkg",children:we.packageName}),y.jsx("button",{type:"button",className:"app-filter-selected-clear",onClick:()=>ve(""),"aria-label":"Clear app filter",disabled:A,children:"✕"})]}):y.jsx("button",{type:"button",className:"btn btn-link app-filter-trigger",onClick:()=>{dn(""),Qe(!0)},disabled:A,children:"Select app"}):y.jsx("input",{className:"form-input",type:"text",value:T,onChange:Re=>ve(Re.target.value),placeholder:"App (optional), e.g. com.google.android.gm",disabled:A}),y.jsx("p",{className:"command-help-text app-filter-help",children:T.trim()?`Only notifications from ${Ye} will trigger this task.`:"Every notification from your device triggers this task."})]})})(),N==="on_new_sms"&&y.jsxs(y.Fragment,{children:[y.jsx("input",{className:"form-input",type:"text",value:$t,onChange:we=>an(we.target.value),placeholder:"From (optional), e.g. +1 555-1234)",disabled:A}),y.jsx("p",{className:"command-help-text app-filter-help",children:$t.trim()?`Only SMS from ${$t.trim()} will trigger this task. Formatting (spaces, dashes, parens) is ignored.`:"Every SMS that arrives on your device triggers this task."})]})]}),nt&&y.jsxs("div",{className:"schedule-reactive",children:[y.jsx("p",{className:"command-help-text",children:"Runs a command and invokes the task for each line of output. Use “the input” in your task description to reference each line."}),y.jsx("input",{ref:bn,className:"form-input form-input-mono",type:"text",value:X,onChange:we=>xe(we.target.value),placeholder:"gws gmail +watch --project my-project",disabled:A})]}),Be&&N!=="hourly"&&y.jsxs(y.Fragment,{children:[G.map((we,Ye)=>y.jsxs("div",{className:"trigger-row-card",children:[y.jsxs("div",{className:"trigger-row-content",children:[N==="daily"&&y.jsx("input",{className:"form-input",type:"time",value:we.time,onChange:Re=>zt(Ye,{time:Re.target.value})}),N==="weekly"&&y.jsxs("div",{className:"trigger-row-top",children:[y.jsx("select",{className:"form-select",value:we.dayOfWeek,onChange:Re=>zt(Ye,{dayOfWeek:Re.target.value}),children:qE.map((Re,bt)=>y.jsx("option",{value:String(bt),children:Re},bt))}),y.jsx("input",{className:"form-input",type:"time",value:we.time,onChange:Re=>zt(Ye,{time:Re.target.value})})]}),N==="monthly"&&y.jsxs("div",{className:"trigger-row-top",children:[y.jsx("select",{className:"form-select",value:we.dayOfMonth,onChange:Re=>zt(Ye,{dayOfMonth:Re.target.value}),children:Array.from({length:28},(Re,bt)=>bt+1).map(Re=>y.jsxs("option",{value:String(Re),children:["Day ",Re]},Re))}),y.jsx("input",{className:"form-input",type:"time",value:we.time,onChange:Re=>zt(Ye,{time:Re.target.value})})]}),N==="specific_times"&&y.jsxs("div",{className:"trigger-row-top",children:[y.jsx("input",{className:"form-input",type:"date",value:we.onceDate,min:Me.date,onChange:Re=>zt(Ye,{onceDate:Re.target.value})}),y.jsx("input",{className:"form-input",type:"time",value:we.onceTime,min:we.onceDate===Me.date?Me.time:void 0,onChange:Re=>zt(Ye,{onceTime:Re.target.value})})]})]}),G.length>1&&y.jsx("button",{className:"trigger-remove-btn",onClick:()=>Sn(Ye),title:"Remove trigger",children:"×"})]},Ye)),y.jsx("button",{className:"trigger-add-btn",onClick:Kt,children:"+ Add"})]}),r==="win32"&&y.jsxs("label",{className:"toggle-label",children:[y.jsx("input",{type:"checkbox",checked:V,onChange:we=>Q(we.target.checked),disabled:A}),"Run in the foreground (host must login to Windows)"]}),Be&&y.jsxs("label",{className:"toggle-label",children:[y.jsx("input",{type:"checkbox",checked:L,onChange:we=>J(we.target.checked),disabled:A}),"Confirm before each run"]}),N!=="ondemand"&&y.jsxs("label",{className:"toggle-label",children:[y.jsx("input",{type:"checkbox",checked:$,onChange:we=>he(we.target.checked),disabled:A}),"Enabled"]})]})}),!le&&_t&&!_t.supportsPermissions&&y.jsxs("div",{className:"form-warning",children:["Palmier does not support runtime permission granting for ",_t.label,". The task may fail if required permissions are not pre-configured."]}),y.jsxs("div",{className:"form-actions",children:[y.jsxs("button",{className:"btn btn-primary",onClick:()=>Ze()&&An(),disabled:!rt||A,children:[A&&y.jsx("span",{className:"btn-spinner"}),pn]}),y.jsx("button",{className:"btn btn-secondary",onClick:()=>{_e&&x.trim()&&!confirm("You have unsaved changes. Discard?")||o()},style:{marginLeft:"auto"},children:"Cancel"})]})]})}),ke&&(()=>{const we=Lt.trim().toLowerCase(),Ye=we?je.filter(Re=>Re.packageName.toLowerCase().includes(we)||Re.appName.toLowerCase().includes(we)):je;return y.jsx("div",{className:"app-filter-overlay",onClick:tn,children:y.jsxs("div",{className:"app-filter-dialog",onClick:Re=>Re.stopPropagation(),children:[y.jsxs("div",{className:"app-filter-header",children:[y.jsx("h2",{children:"Select app"}),y.jsx("button",{className:"app-filter-close",onClick:tn,"aria-label":"Close",children:y.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",children:y.jsx("path",{d:"M4 4L12 12M12 4L4 12",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})})})]}),y.jsx("input",{className:"form-input app-filter-search",type:"text",value:Lt,onChange:Re=>dn(Re.target.value),onKeyDown:Re=>{Re.key==="Enter"&&Lt.trim()&&(ve(Lt.trim()),tn())},placeholder:"Search or type a package name",autoFocus:!0}),y.jsxs("ul",{className:"app-filter-list",children:[ce&&je.length===0?Array.from({length:6}).map((Re,bt)=>y.jsx("li",{className:"app-filter-row app-filter-skeleton",children:y.jsx("div",{className:"app-filter-skeleton-bar"})},`sk-${bt}`)):Ye.length===0&&!Lt.trim()?y.jsx("li",{className:"app-filter-empty",children:"No apps"}):Ye.map(Re=>y.jsx("li",{className:"app-filter-row",onClick:()=>{ve(Re.packageName),tn()},children:y.jsxs("div",{className:"app-filter-row-labels",children:[y.jsx("div",{className:"app-filter-row-name",children:Re.appName||Re.packageName}),Re.appName&&y.jsx("div",{className:"app-filter-row-pkg",children:Re.packageName})]})},Re.packageName)),Lt.trim()&&y.jsx("li",{className:"app-filter-row",onClick:()=>{ve(Lt.trim()),tn()},children:y.jsx("div",{className:"app-filter-row-labels",children:y.jsx("div",{className:"app-filter-row-name",children:Lt.trim()})})})]})]})})})()]})}function Bx({pullDistance:e,refreshing:t,threshold:r}){const s=e>0||t,l=e>=r;return y.jsx("div",{className:"pull-to-refresh",style:{transform:`translateY(${e}px)`,opacity:s?Math.min(1,e/30):0},"aria-hidden":!s,children:y.jsx("div",{className:"pull-to-refresh-badge",children:t?y.jsx("div",{className:"spinner"}):y.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.25",strokeLinecap:"round",strokeLinejoin:"round",style:{transform:l?"rotate(180deg)":"rotate(0deg)",transition:"transform 0.15s"},children:[y.jsx("line",{x1:"12",y1:"5",x2:"12",y2:"19"}),y.jsx("polyline",{points:"19 12 12 19 5 12"})]})})})}function Hx({onRefresh:e,threshold:t=70,maxPull:r=110,enabled:s=!0}){const[l,o]=E.useState(0),[c,f]=E.useState(!1),d=E.useRef(null),m=E.useRef(!1),b=E.useRef(0),g=E.useRef(!1),x=E.useRef(e);return E.useEffect(()=>{x.current=e}),E.useEffect(()=>{if(!s)return;const v=R=>{if(g.current||window.scrollY>0){d.current=null;return}if(JE(R.target)){d.current=null;return}d.current=R.touches[0].clientY,m.current=!1,b.current=0},S=R=>{if(g.current||d.current==null)return;const M=R.touches[0].clientY-d.current;if(M<=0){m.current=!1,b.current=0,o(0);return}m.current=!0;const P=Math.min(r,M*.5);b.current=P,o(P),R.cancelable&&R.preventDefault()},j=()=>{if(!m.current){d.current=null,o(0);return}const R=b.current;d.current=null,m.current=!1,b.current=0,R>=t?(g.current=!0,f(!0),o(t),Promise.resolve(x.current()).catch(()=>{}).finally(()=>{g.current=!1,f(!1),o(0)})):o(0)};return window.addEventListener("touchstart",v,{passive:!0}),window.addEventListener("touchmove",S,{passive:!1}),window.addEventListener("touchend",j,{passive:!0}),window.addEventListener("touchcancel",j,{passive:!0}),()=>{window.removeEventListener("touchstart",v),window.removeEventListener("touchmove",S),window.removeEventListener("touchend",j),window.removeEventListener("touchcancel",j)}},[s,t,r]),{pullDistance:l,refreshing:c,threshold:t}}function JE(e){let t=e;for(;t&&t!==document.body&&t!==document.documentElement;){const r=window.getComputedStyle(t).overflowY;if((r==="auto"||r==="scroll")&&t.scrollHeight>t.clientHeight)return!0;t=t.parentElement}return!1}function XE(e){return JSON.stringify([e.user_prompt,e.agent??null,e.schedule_type??null,e.schedule_values??null,e.schedule_enabled,e.requires_confirmation,e.yolo_mode??!1,e.foreground_mode??!1,e.command??"",e.permissions??null])}function KE({connected:e,hostId:t,request:r,subscribeEvents:s,agents:l,hostPlatform:o,isNotificationListener:c,onViewRun:f,hostInfoStatus:d}){const[m,b]=E.useState([]),[g,x]=E.useState(!1),[v,S]=E.useState(null),[j,R]=E.useState(new Map),[M,P]=E.useState(!1),[I,ue]=E.useState(void 0),q=E.useCallback(()=>{P(!1),ue(void 0)},[]),N=E.useCallback(async()=>{if(e){x(!0),S(null);try{const J=(await r("task.list")).tasks??[],$=new Map;for(const he of J)he.status&&$.set(he.id,he.status);R($),b(J)}catch(L){const J=L instanceof Error?L.message:String(L);J==="Not connected"||J.includes("503")||J.toLowerCase().includes("no responders")?S(null):S(J),b([])}finally{x(!1)}}},[e,t,r]);E.useEffect(()=>{e?N():(b([]),x(!1))},[e,t,N]);const ee=Hx({onRefresh:N,enabled:e});E.useEffect(()=>!e||!t?void 0:s(t,async J=>{const $=J.subject.split(".");if($.length<3)return;const he=$.slice(2).join(".");let le={};try{le=JSON.parse(new TextDecoder().decode(J.data))}catch{return}const te=le.event_type;if(!(te!=="running-state"&&te!=="permission-resolved"))try{const V=await r("task.status",{id:he},{timeout:5e3});if(V.error)return;R(Q=>{const X=new Map(Q);return X.set(he,V),X})}catch{}}),[e,t,s,r]);function G(L){b(J=>{const $=J.findIndex(he=>he.id===L.id);if($>=0){const he=[...J];return he[$]=L,he}return[L,...J]}),P(!1),ue(void 0)}function B(L){b(J=>J.filter($=>$.id!==L)),R(J=>{const $=new Map(J);return $.delete(L),$})}return y.jsxs(y.Fragment,{children:[y.jsx(Bx,{pullDistance:ee.pullDistance,refreshing:ee.refreshing,threshold:ee.threshold}),v&&y.jsxs("div",{className:"form-error",children:[v,v.toLowerCase().includes("failed to fetch")&&y.jsxs(y.Fragment,{children:[" ",y.jsx("a",{href:"#",onClick:L=>{L.preventDefault(),window.location.reload()},children:"Reload"})]})]}),g&&!m.length&&d==="ready"?y.jsx("div",{className:"task-list",children:[0,1,2].map(L=>y.jsxs("div",{className:"task-card",style:{pointerEvents:"none"},children:[y.jsx("div",{className:"task-card-header",children:y.jsxs("div",{className:"task-card-title-row",children:[y.jsx("div",{className:"skeleton-line",style:{width:10,height:10,borderRadius:"50%"}}),y.jsx("div",{className:"skeleton-line",style:{width:`${60+L*12}%`}})]})}),y.jsxs("div",{className:"task-card-meta",children:[y.jsx("div",{className:"skeleton-line",style:{width:"30%"}}),y.jsx("div",{className:"skeleton-line",style:{width:"25%"}})]})]},L))}):m.length===0?d==="loading"?y.jsx("div",{className:"empty-state",children:y.jsx("p",{className:"empty-state-text",children:"Connecting to host…"})}):d==="error"?y.jsxs("div",{className:"empty-state",children:[y.jsx("p",{className:"empty-state-text",children:"Couldn't reach host"}),y.jsxs("p",{className:"empty-state-hint",children:["The host didn't respond. Try running ",y.jsx("code",{children:"palmier restart"})," on the host machine to restart the daemon."]})]}):y.jsxs("div",{className:"empty-state",children:[y.jsx("p",{className:"empty-state-text",children:"No tasks yet"}),y.jsx("p",{className:"empty-state-hint",children:"Tap the + button to create your first task."})]}):y.jsx("div",{className:"task-list",children:m.map(L=>y.jsx(UE,{task:L,lastEvent:j.get(L.id),onEdit:J=>{ue(J),P(!0),r("task.get",{id:J.id}).then($=>{$.error||ue($)}).catch(()=>{})},onDelete:B,onViewRun:f},L.id))}),y.jsx("button",{className:"fab",onClick:()=>{ue(void 0),P(!0)},"aria-label":"New task",title:"New task",children:y.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",children:[y.jsx("line",{x1:"12",y1:"5",x2:"12",y2:"19"}),y.jsx("line",{x1:"5",y1:"12",x2:"19",y2:"12"})]})}),M&&y.jsx(GE,{initial:I,agents:l,hostPlatform:o,isNotificationListener:c,onSaved:G,onCancel:q},I?XE(I):"new")]})}let ba=null;function X0(e){ba&&(e.preventDefault(),e.returnValue="")}function Mh(e){const t=!!ba;ba=e;const r=!!ba;r&&!t?window.addEventListener("beforeunload",X0):!r&&t&&window.removeEventListener("beforeunload",X0)}function Ss(){return ba?window.confirm(ba):!0}function QE(){const e=Gr(),t=Er(),{hostId:r}=Yu(),s=t.pathname.endsWith("/tasks"),l=!s;function o(c){Ss()&&r&&e(`/hosts/${encodeURIComponent(r)}${c}`)}return y.jsxs(y.Fragment,{children:[y.jsxs("button",{className:`tab-btn ${l?"tab-btn-active":""}`,onClick:()=>o(""),children:[y.jsx("svg",{className:"tab-icon",width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",children:y.jsx("path",{d:"M2 8H4.5L6 4L8 12L10 6L11.5 8H14"})}),"Sessions"]}),y.jsxs("button",{className:`tab-btn ${s?"tab-btn-active":""}`,onClick:()=>o("/tasks"),children:[y.jsxs("svg",{className:"tab-icon",width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",children:[y.jsx("rect",{x:"2",y:"2",width:"12",height:"12",rx:"2"}),y.jsx("path",{d:"M5.5 8L7 9.5L10.5 6"})]}),"Tasks"]})]})}function qx(e){const[t,r]=E.useState(()=>window.matchMedia(e).matches);return E.useEffect(()=>{const s=window.matchMedia(e),l=o=>r(o.matches);return s.addEventListener("change",l),r(s.matches),()=>s.removeEventListener("change",l)},[e]),t}const Cu=Jn.isNativePlatform(),ZE=["Device","Data","Messaging"],WE=[{capability:"sms-read",label:"Read SMS",group:"Messaging"},{capability:"sms-send",label:"Send SMS",group:"Messaging"},{capability:"send-email",label:"Prompt Email to Send",group:"Messaging"},{capability:"notifications",label:"Notifications from Other Apps",group:"Data"},{capability:"contacts",label:"Manage Contacts",group:"Data"},{capability:"calendar",label:"Manage Calendar",group:"Data"},{capability:"location",label:"Get Location",group:"Device"},{capability:"dnd",label:"Set Ringer Mode",group:"Device"},{capability:"alarm",label:"Trigger Alarms",group:"Device"}];async function eC(){if(!Cu||!On)return new Set;try{const{capabilities:e}=await On.getCapabilityStatus();return new Set(e.filter(t=>t.enabled).map(t=>t.name))}catch{return new Set}}function Ix({onChange:e,confirmDisable:t=!1}){const[r,s]=E.useState(new Map),[l,o]=E.useState(null),[c,f]=E.useState(null),d=E.useCallback(async()=>{if(!(!Cu||!On))try{const{capabilities:S}=await On.getCapabilityStatus(),j=new Map;for(const R of S)j.set(R.name,R);s(j),e==null||e(new Set(S.filter(R=>R.enabled).map(R=>R.name)))}catch(S){console.error("Failed to read capability status:",S)}},[e]);E.useEffect(()=>{d()},[d]),E.useEffect(()=>{if(!Cu)return;const S=pd.addListener("resume",d);return()=>{S.then(j=>j.remove())}},[d]);async function m(S,j){if(On){o(S.capability);try{const R=await On.setCapabilityEnabled({capability:S.capability,enabled:j});!R.enabled&&R.reason==="no-email-client"&&alert("No email app is installed on this device. Install one (e.g. Gmail) before enabling Send Email."),await d()}catch(R){console.error(`Failed to toggle ${S.capability}:`,R)}finally{o(null)}}}function b(S){const j=r.get(S.capability);if(j){if(j.enabled&&t){f(S);return}m(S,!j.enabled)}}function g(){const S=c;S&&(f(null),m(S,!1))}if(!Cu)return null;const x=ZE.map(S=>({group:S,items:WE.filter(j=>{const R=r.get(j.capability);return j.group===S&&(R==null?void 0:R.supported)})})).filter(S=>S.items.length>0);if(x.length===0)return y.jsx("div",{className:"capability-toggles-loading",children:y.jsx("span",{className:"spinner"})});const v=c&&pi.createPortal(y.jsx("div",{className:"confirm-modal-overlay",onClick:()=>f(null),children:y.jsxs("div",{className:"confirm-modal",onClick:S=>S.stopPropagation(),children:[y.jsxs("h2",{className:"confirm-modal-title",children:["Disable ",c.label,"?"]}),y.jsxs("p",{className:"confirm-modal-message",children:["All hosts linked to this device will no longer be able to use ",c.label,"."]}),y.jsxs("div",{className:"confirm-modal-actions",children:[y.jsx("button",{className:"btn btn-secondary",onClick:()=>f(null),children:"Cancel"}),y.jsx("button",{className:"btn btn-danger",onClick:g,children:"Disable"})]})]})}),document.body);return y.jsxs(y.Fragment,{children:[x.map(({group:S,items:j},R)=>y.jsx("div",{className:R>0?"drawer-toggle-group drawer-toggle-group-divided":"drawer-toggle-group",children:j.map(M=>{const P=r.get(M.capability),I=!!(P!=null&&P.enabled);return y.jsxs("label",{className:"drawer-toggle",children:[y.jsx("span",{className:"drawer-toggle-label",children:M.label}),y.jsx("button",{className:`toggle-switch ${I?"toggle-switch-on":""}`,onClick:()=>b(M),disabled:l===M.capability,role:"switch","aria-checked":I,children:y.jsx("span",{className:"toggle-switch-thumb"})})]},M.capability)})},S)),v]})}function Dh(e){return e.replace(/^https:\/\//,"")}function tC({request:e,onClose:t}){const[r,s]=E.useState(null),[l,o]=E.useState(!1),[c,f]=E.useState(null),[d,m]=E.useState(!1);E.useEffect(()=>{let x=!1;return e("passwords.list").then(v=>{x||(v.passwords?s([...v.passwords].sort((S,j)=>S.origin===j.origin?S.username.localeCompare(j.username):S.origin.localeCompare(j.origin))):o(!0))}).catch(()=>{x||o(!0)}),()=>{x=!0}},[e]);async function b(){if(!c)return;const{origin:x,username:v}=c;m(!0);try{await e("passwords.delete",{origin:x,username:v}),s(S=>(S==null?void 0:S.filter(j=>!(j.origin===x&&j.username===v)))??S),f(null)}catch(S){console.error("Failed to delete password:",S)}finally{m(!1)}}const g=c&&pi.createPortal(y.jsx("div",{className:"confirm-modal-overlay",onClick:()=>{d||f(null)},children:y.jsxs("div",{className:"confirm-modal",onClick:x=>x.stopPropagation(),children:[y.jsx("h2",{className:"confirm-modal-title",children:"Remove password?"}),y.jsxs("p",{className:"confirm-modal-message",children:["The saved password for ",y.jsx("strong",{children:c.username})," on"," ",y.jsx("strong",{children:Dh(c.origin)})," will be removed from this host."]}),y.jsxs("div",{className:"confirm-modal-actions",children:[y.jsx("button",{className:"btn btn-secondary",onClick:()=>f(null),disabled:d,children:"Cancel"}),y.jsx("button",{className:"btn btn-danger",onClick:b,disabled:d,children:d?"Removing…":"Remove"})]})]})}),document.body);return pi.createPortal(y.jsxs(y.Fragment,{children:[y.jsx("div",{className:"confirm-modal-overlay",onClick:t,children:y.jsxs("div",{className:"confirm-modal passwords-dialog",onClick:x=>x.stopPropagation(),children:[y.jsx("h2",{className:"confirm-modal-title",children:"Saved Passwords"}),y.jsx("div",{className:"passwords-dialog-scroll",children:l?y.jsx("p",{className:"passwords-empty",children:"Couldn't load saved passwords."}):r===null?y.jsx("p",{className:"passwords-empty",children:"Loading…"}):r.length===0?y.jsx("p",{className:"passwords-empty",children:"No saved passwords. Passwords are saved when you approve them during a task."}):y.jsx("ul",{className:"passwords-list",children:r.map(x=>y.jsxs("li",{className:"password-item",children:[y.jsxs("div",{className:"password-item-text",children:[y.jsx("span",{className:"password-item-origin",children:Dh(x.origin)}),y.jsx("span",{className:"password-item-username",children:x.username})]}),y.jsx("button",{className:"password-delete-btn",onClick:()=>f(x),"aria-label":`Remove password for ${x.username} on ${Dh(x.origin)}`,children:y.jsx("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",children:y.jsx("path",{d:"M4 5.5V11C4 11.2761 4.22386 11.5 4.5 11.5H9.5C9.77614 11.5 10 11.2761 10 11V5.5M3 4H11M5.5 4V3C5.5 2.72386 5.72386 2.5 6 2.5H8C8.27614 2.5 8.5 2.72386 8.5 3V4M6.5 6.5V9.5M7.5 6.5V9.5",stroke:"currentColor",strokeWidth:"1.2",strokeLinecap:"round",strokeLinejoin:"round"})})})]},`${x.origin}
|
|
@@ -118,4 +118,4 @@ Are you sure you want to continue?`):!0}async function ue(){if(!(!P||!I())){v(!0
|
|
|
118
118
|
`))+1))}const c="#".repeat(l),f=r.enter("headingAtx"),d=r.enter("phrasing");o.move(c+" ");let m=r.containerPhrasing(e,{before:"# ",after:`
|
|
119
119
|
`,...o.current()});return/^[\t ]/.test(m)&&(m=Vl(m.charCodeAt(0))+m.slice(1)),m=m?c+" "+m:c,r.options.closeAtx&&(m+=" "+c),d(),f(),m}M1.peek=O3;function M1(e){return e.value||""}function O3(){return"<"}D1.peek=R3;function D1(e,t,r,s){const l=um(r),o=l==='"'?"Quote":"Apostrophe",c=r.enter("image");let f=r.enter("label");const d=r.createTracker(s);let m=d.move("![");return m+=d.move(r.safe(e.alt,{before:m,after:"]",...d.current()})),m+=d.move("]("),f(),!e.url&&e.title||/[\0- \u007F]/.test(e.url)?(f=r.enter("destinationLiteral"),m+=d.move("<"),m+=d.move(r.safe(e.url,{before:m,after:">",...d.current()})),m+=d.move(">")):(f=r.enter("destinationRaw"),m+=d.move(r.safe(e.url,{before:m,after:e.title?" ":")",...d.current()}))),f(),e.title&&(f=r.enter(`title${o}`),m+=d.move(" "+l),m+=d.move(r.safe(e.title,{before:m,after:l,...d.current()})),m+=d.move(l),f()),m+=d.move(")"),c(),m}function R3(){return"!"}L1.peek=M3;function L1(e,t,r,s){const l=e.referenceType,o=r.enter("imageReference");let c=r.enter("label");const f=r.createTracker(s);let d=f.move("![");const m=r.safe(e.alt,{before:d,after:"]",...f.current()});d+=f.move(m+"]["),c();const b=r.stack;r.stack=[],c=r.enter("reference");const g=r.safe(r.associationId(e),{before:d,after:"]",...f.current()});return c(),r.stack=b,o(),l==="full"||!m||m!==g?d+=f.move(g+"]"):l==="shortcut"?d=d.slice(0,-1):d+=f.move("]"),d}function M3(){return"!"}z1.peek=D3;function z1(e,t,r){let s=e.value||"",l="`",o=-1;for(;new RegExp("(^|[^`])"+l+"([^`]|$)").test(s);)l+="`";for(/[^ \r\n]/.test(s)&&(/^[ \r\n]/.test(s)&&/[ \r\n]$/.test(s)||/^`|`$/.test(s))&&(s=" "+s+" ");++o<r.unsafe.length;){const c=r.unsafe[o],f=r.compilePattern(c);let d;if(c.atBreak)for(;d=f.exec(s);){let m=d.index;s.charCodeAt(m)===10&&s.charCodeAt(m-1)===13&&m--,s=s.slice(0,m)+" "+s.slice(d.index+1)}}return l+s+l}function D3(){return"`"}function U1(e,t){const r=em(e);return!!(!t.options.resourceLink&&e.url&&!e.title&&e.children&&e.children.length===1&&e.children[0].type==="text"&&(r===e.url||"mailto:"+r===e.url)&&/^[a-z][a-z+.-]+:/i.test(e.url)&&!/[\0- <>\u007F]/.test(e.url))}P1.peek=L3;function P1(e,t,r,s){const l=um(r),o=l==='"'?"Quote":"Apostrophe",c=r.createTracker(s);let f,d;if(U1(e,r)){const b=r.stack;r.stack=[],f=r.enter("autolink");let g=c.move("<");return g+=c.move(r.containerPhrasing(e,{before:g,after:">",...c.current()})),g+=c.move(">"),f(),r.stack=b,g}f=r.enter("link"),d=r.enter("label");let m=c.move("[");return m+=c.move(r.containerPhrasing(e,{before:m,after:"](",...c.current()})),m+=c.move("]("),d(),!e.url&&e.title||/[\0- \u007F]/.test(e.url)?(d=r.enter("destinationLiteral"),m+=c.move("<"),m+=c.move(r.safe(e.url,{before:m,after:">",...c.current()})),m+=c.move(">")):(d=r.enter("destinationRaw"),m+=c.move(r.safe(e.url,{before:m,after:e.title?" ":")",...c.current()}))),d(),e.title&&(d=r.enter(`title${o}`),m+=c.move(" "+l),m+=c.move(r.safe(e.title,{before:m,after:l,...c.current()})),m+=c.move(l),d()),m+=c.move(")"),f(),m}function L3(e,t,r){return U1(e,r)?"<":"["}B1.peek=z3;function B1(e,t,r,s){const l=e.referenceType,o=r.enter("linkReference");let c=r.enter("label");const f=r.createTracker(s);let d=f.move("[");const m=r.containerPhrasing(e,{before:d,after:"]",...f.current()});d+=f.move(m+"]["),c();const b=r.stack;r.stack=[],c=r.enter("reference");const g=r.safe(r.associationId(e),{before:d,after:"]",...f.current()});return c(),r.stack=b,o(),l==="full"||!m||m!==g?d+=f.move(g+"]"):l==="shortcut"?d=d.slice(0,-1):d+=f.move("]"),d}function z3(){return"["}function cm(e){const t=e.options.bullet||"*";if(t!=="*"&&t!=="+"&&t!=="-")throw new Error("Cannot serialize items with `"+t+"` for `options.bullet`, expected `*`, `+`, or `-`");return t}function U3(e){const t=cm(e),r=e.options.bulletOther;if(!r)return t==="*"?"-":"*";if(r!=="*"&&r!=="+"&&r!=="-")throw new Error("Cannot serialize items with `"+r+"` for `options.bulletOther`, expected `*`, `+`, or `-`");if(r===t)throw new Error("Expected `bullet` (`"+t+"`) and `bulletOther` (`"+r+"`) to be different");return r}function P3(e){const t=e.options.bulletOrdered||".";if(t!=="."&&t!==")")throw new Error("Cannot serialize items with `"+t+"` for `options.bulletOrdered`, expected `.` or `)`");return t}function H1(e){const t=e.options.rule||"*";if(t!=="*"&&t!=="-"&&t!=="_")throw new Error("Cannot serialize rules with `"+t+"` for `options.rule`, expected `*`, `-`, or `_`");return t}function B3(e,t,r,s){const l=r.enter("list"),o=r.bulletCurrent;let c=e.ordered?P3(r):cm(r);const f=e.ordered?c==="."?")":".":U3(r);let d=t&&r.bulletLastUsed?c===r.bulletLastUsed:!1;if(!e.ordered){const b=e.children?e.children[0]:void 0;if((c==="*"||c==="-")&&b&&(!b.children||!b.children[0])&&r.stack[r.stack.length-1]==="list"&&r.stack[r.stack.length-2]==="listItem"&&r.stack[r.stack.length-3]==="list"&&r.stack[r.stack.length-4]==="listItem"&&r.indexStack[r.indexStack.length-1]===0&&r.indexStack[r.indexStack.length-2]===0&&r.indexStack[r.indexStack.length-3]===0&&(d=!0),H1(r)===c&&b){let g=-1;for(;++g<e.children.length;){const x=e.children[g];if(x&&x.type==="listItem"&&x.children&&x.children[0]&&x.children[0].type==="thematicBreak"){d=!0;break}}}}d&&(c=f),r.bulletCurrent=c;const m=r.containerFlow(e,s);return r.bulletLastUsed=c,r.bulletCurrent=o,l(),m}function H3(e){const t=e.options.listItemIndent||"one";if(t!=="tab"&&t!=="one"&&t!=="mixed")throw new Error("Cannot serialize items with `"+t+"` for `options.listItemIndent`, expected `tab`, `one`, or `mixed`");return t}function q3(e,t,r,s){const l=H3(r);let o=r.bulletCurrent||cm(r);t&&t.type==="list"&&t.ordered&&(o=(typeof t.start=="number"&&t.start>-1?t.start:1)+(r.options.incrementListMarker===!1?0:t.children.indexOf(e))+o);let c=o.length+1;(l==="tab"||l==="mixed"&&(t&&t.type==="list"&&t.spread||e.spread))&&(c=Math.ceil(c/4)*4);const f=r.createTracker(s);f.move(o+" ".repeat(c-o.length)),f.shift(c);const d=r.enter("listItem"),m=r.indentLines(r.containerFlow(e,f.current()),b);return d(),m;function b(g,x,v){return x?(v?"":" ".repeat(c))+g:(v?o:o+" ".repeat(c-o.length))+g}}function I3(e,t,r,s){const l=r.enter("paragraph"),o=r.enter("phrasing"),c=r.containerPhrasing(e,s);return o(),l(),c}const F3=nc(["break","delete","emphasis","footnote","footnoteReference","image","imageReference","inlineCode","inlineMath","link","linkReference","mdxJsxTextElement","mdxTextExpression","strong","text","textDirective"]);function $3(e,t,r,s){return(e.children.some(function(c){return F3(c)})?r.containerPhrasing:r.containerFlow).call(r,e,s)}function V3(e){const t=e.options.strong||"*";if(t!=="*"&&t!=="_")throw new Error("Cannot serialize strong with `"+t+"` for `options.strong`, expected `*`, or `_`");return t}q1.peek=Y3;function q1(e,t,r,s){const l=V3(r),o=r.enter("strong"),c=r.createTracker(s),f=c.move(l+l);let d=c.move(r.containerPhrasing(e,{after:l,before:f,...c.current()}));const m=d.charCodeAt(0),b=Fu(s.before.charCodeAt(s.before.length-1),m,l);b.inside&&(d=Vl(m)+d.slice(1));const g=d.charCodeAt(d.length-1),x=Fu(s.after.charCodeAt(0),g,l);x.inside&&(d=d.slice(0,-1)+Vl(g));const v=c.move(l+l);return o(),r.attentionEncodeSurroundingInfo={after:x.outside,before:b.outside},f+d+v}function Y3(e,t,r){return r.options.strong||"*"}function G3(e,t,r,s){return r.safe(e.value,s)}function J3(e){const t=e.options.ruleRepetition||3;if(t<3)throw new Error("Cannot serialize rules with repetition `"+t+"` for `options.ruleRepetition`, expected `3` or more");return t}function X3(e,t,r){const s=(H1(r)+(r.options.ruleSpaces?" ":"")).repeat(J3(r));return r.options.ruleSpaces?s.slice(0,-1):s}const I1={blockquote:b3,break:Hb,code:k3,definition:C3,emphasis:R1,hardBreak:Hb,heading:T3,html:M1,image:D1,imageReference:L1,inlineCode:z1,link:P1,linkReference:B1,list:B3,listItem:q3,paragraph:I3,root:$3,strong:q1,text:G3,thematicBreak:X3};function K3(){return{enter:{table:Q3,tableData:qb,tableHeader:qb,tableRow:W3},exit:{codeText:eO,table:Z3,tableData:Qh,tableHeader:Qh,tableRow:Qh}}}function Q3(e){const t=e._align;this.enter({type:"table",align:t.map(function(r){return r==="none"?null:r}),children:[]},e),this.data.inTable=!0}function Z3(e){this.exit(e),this.data.inTable=void 0}function W3(e){this.enter({type:"tableRow",children:[]},e)}function Qh(e){this.exit(e)}function qb(e){this.enter({type:"tableCell",children:[]},e)}function eO(e){let t=this.resume();this.data.inTable&&(t=t.replace(/\\([\\|])/g,tO));const r=this.stack[this.stack.length-1];r.type,r.value=t,this.exit(e)}function tO(e,t){return t==="|"?t:e}function nO(e){const t=e||{},r=t.tableCellPadding,s=t.tablePipeAlign,l=t.stringLength,o=r?" ":"|";return{unsafe:[{character:"\r",inConstruct:"tableCell"},{character:`
|
|
120
120
|
`,inConstruct:"tableCell"},{atBreak:!0,character:"|",after:"[ :-]"},{character:"|",inConstruct:"tableCell"},{atBreak:!0,character:":",after:"-"},{atBreak:!0,character:"-",after:"[:|-]"}],handlers:{inlineCode:x,table:c,tableCell:d,tableRow:f}};function c(v,S,j,R){return m(b(v,j,R),v.align)}function f(v,S,j,R){const M=g(v,j,R),P=m([M]);return P.slice(0,P.indexOf(`
|
|
121
|
-
`))}function d(v,S,j,R){const M=j.enter("tableCell"),P=j.enter("phrasing"),I=j.containerPhrasing(v,{...R,before:o,after:o});return P(),M(),I}function m(v,S){return g3(v,{align:S,alignDelimiters:s,padding:r,stringLength:l})}function b(v,S,j){const R=v.children;let M=-1;const P=[],I=S.enter("table");for(;++M<R.length;)P[M]=g(R[M],S,j);return I(),P}function g(v,S,j){const R=v.children;let M=-1;const P=[],I=S.enter("tableRow");for(;++M<R.length;)P[M]=d(R[M],v,S,j);return I(),P}function x(v,S,j){let R=I1.inlineCode(v,S,j);return j.stack.includes("tableCell")&&(R=R.replace(/\|/g,"\\$&")),R}}function rO(){return{exit:{taskListCheckValueChecked:Ib,taskListCheckValueUnchecked:Ib,paragraph:sO}}}function iO(){return{unsafe:[{atBreak:!0,character:"-",after:"[:|-]"}],handlers:{listItem:aO}}}function Ib(e){const t=this.stack[this.stack.length-2];t.type,t.checked=e.type==="taskListCheckValueChecked"}function sO(e){const t=this.stack[this.stack.length-2];if(t&&t.type==="listItem"&&typeof t.checked=="boolean"){const r=this.stack[this.stack.length-1];r.type;const s=r.children[0];if(s&&s.type==="text"){const l=t.children;let o=-1,c;for(;++o<l.length;){const f=l[o];if(f.type==="paragraph"){c=f;break}}c===r&&(s.value=s.value.slice(1),s.value.length===0?r.children.shift():r.position&&s.position&&typeof s.position.start.offset=="number"&&(s.position.start.column++,s.position.start.offset++,r.position.start=Object.assign({},s.position.start)))}}this.exit(e)}function aO(e,t,r,s){const l=e.children[0],o=typeof e.checked=="boolean"&&l&&l.type==="paragraph",c="["+(e.checked?"x":" ")+"] ",f=r.createTracker(s);o&&f.move(c);let d=I1.listItem(e,t,r,{...s,...f.current()});return o&&(d=d.replace(/^(?:[*+-]|\d+\.)([\r\n]| {1,3})/,m)),d;function m(b){return b+c}}function lO(){return[BT(),a3(),c3(),K3(),rO()]}function oO(e){return{extensions:[HT(),l3(e),f3(),nO(e),iO()]}}const uO={tokenize:pO,partial:!0},F1={tokenize:gO,partial:!0},$1={tokenize:yO,partial:!0},V1={tokenize:bO,partial:!0},cO={tokenize:xO,partial:!0},Y1={name:"wwwAutolink",tokenize:dO,previous:J1},G1={name:"protocolAutolink",tokenize:mO,previous:X1},vi={name:"emailAutolink",tokenize:hO,previous:K1},Jr={};function fO(){return{text:Jr}}let vs=48;for(;vs<123;)Jr[vs]=vi,vs++,vs===58?vs=65:vs===91&&(vs=97);Jr[43]=vi;Jr[45]=vi;Jr[46]=vi;Jr[95]=vi;Jr[72]=[vi,G1];Jr[104]=[vi,G1];Jr[87]=[vi,Y1];Jr[119]=[vi,Y1];function hO(e,t,r){const s=this;let l,o;return c;function c(g){return!jd(g)||!K1.call(s,s.previous)||fm(s.events)?r(g):(e.enter("literalAutolink"),e.enter("literalAutolinkEmail"),f(g))}function f(g){return jd(g)?(e.consume(g),f):g===64?(e.consume(g),d):r(g)}function d(g){return g===46?e.check(cO,b,m)(g):g===45||g===95||Rn(g)?(o=!0,e.consume(g),d):b(g)}function m(g){return e.consume(g),l=!0,d}function b(g){return o&&l&&Pn(s.previous)?(e.exit("literalAutolinkEmail"),e.exit("literalAutolink"),t(g)):r(g)}}function dO(e,t,r){const s=this;return l;function l(c){return c!==87&&c!==119||!J1.call(s,s.previous)||fm(s.events)?r(c):(e.enter("literalAutolink"),e.enter("literalAutolinkWww"),e.check(uO,e.attempt(F1,e.attempt($1,o),r),r)(c))}function o(c){return e.exit("literalAutolinkWww"),e.exit("literalAutolink"),t(c)}}function mO(e,t,r){const s=this;let l="",o=!1;return c;function c(g){return(g===72||g===104)&&X1.call(s,s.previous)&&!fm(s.events)?(e.enter("literalAutolink"),e.enter("literalAutolinkHttp"),l+=String.fromCodePoint(g),e.consume(g),f):r(g)}function f(g){if(Pn(g)&&l.length<5)return l+=String.fromCodePoint(g),e.consume(g),f;if(g===58){const x=l.toLowerCase();if(x==="http"||x==="https")return e.consume(g),d}return r(g)}function d(g){return g===47?(e.consume(g),o?m:(o=!0,d)):r(g)}function m(g){return g===null||Hu(g)||Dt(g)||_s(g)||Wu(g)?r(g):e.attempt(F1,e.attempt($1,b),r)(g)}function b(g){return e.exit("literalAutolinkHttp"),e.exit("literalAutolink"),t(g)}}function pO(e,t,r){let s=0;return l;function l(c){return(c===87||c===119)&&s<3?(s++,e.consume(c),l):c===46&&s===3?(e.consume(c),o):r(c)}function o(c){return c===null?r(c):t(c)}}function gO(e,t,r){let s,l,o;return c;function c(m){return m===46||m===95?e.check(V1,d,f)(m):m===null||Dt(m)||_s(m)||m!==45&&Wu(m)?d(m):(o=!0,e.consume(m),c)}function f(m){return m===95?s=!0:(l=s,s=void 0),e.consume(m),c}function d(m){return l||s||!o?r(m):t(m)}}function yO(e,t){let r=0,s=0;return l;function l(c){return c===40?(r++,e.consume(c),l):c===41&&s<r?o(c):c===33||c===34||c===38||c===39||c===41||c===42||c===44||c===46||c===58||c===59||c===60||c===63||c===93||c===95||c===126?e.check(V1,t,o)(c):c===null||Dt(c)||_s(c)?t(c):(e.consume(c),l)}function o(c){return c===41&&s++,e.consume(c),l}}function bO(e,t,r){return s;function s(f){return f===33||f===34||f===39||f===41||f===42||f===44||f===46||f===58||f===59||f===63||f===95||f===126?(e.consume(f),s):f===38?(e.consume(f),o):f===93?(e.consume(f),l):f===60||f===null||Dt(f)||_s(f)?t(f):r(f)}function l(f){return f===null||f===40||f===91||Dt(f)||_s(f)?t(f):s(f)}function o(f){return Pn(f)?c(f):r(f)}function c(f){return f===59?(e.consume(f),s):Pn(f)?(e.consume(f),c):r(f)}}function xO(e,t,r){return s;function s(o){return e.consume(o),l}function l(o){return Rn(o)?r(o):t(o)}}function J1(e){return e===null||e===40||e===42||e===95||e===91||e===93||e===126||Dt(e)}function X1(e){return!Pn(e)}function K1(e){return!(e===47||jd(e))}function jd(e){return e===43||e===45||e===46||e===95||Rn(e)}function fm(e){let t=e.length,r=!1;for(;t--;){const s=e[t][1];if((s.type==="labelLink"||s.type==="labelImage")&&!s._balanced){r=!0;break}if(s._gfmAutolinkLiteralWalkedInto){r=!1;break}}return e.length>0&&!r&&(e[e.length-1][1]._gfmAutolinkLiteralWalkedInto=!0),r}const vO={tokenize:jO,partial:!0};function wO(){return{document:{91:{name:"gfmFootnoteDefinition",tokenize:EO,continuation:{tokenize:CO},exit:AO}},text:{91:{name:"gfmFootnoteCall",tokenize:kO},93:{name:"gfmPotentialFootnoteCall",add:"after",tokenize:SO,resolveTo:_O}}}}function SO(e,t,r){const s=this;let l=s.events.length;const o=s.parser.gfmFootnotes||(s.parser.gfmFootnotes=[]);let c;for(;l--;){const d=s.events[l][1];if(d.type==="labelImage"){c=d;break}if(d.type==="gfmFootnoteCall"||d.type==="labelLink"||d.type==="label"||d.type==="image"||d.type==="link")break}return f;function f(d){if(!c||!c._balanced)return r(d);const m=Lr(s.sliceSerialize({start:c.end,end:s.now()}));return m.codePointAt(0)!==94||!o.includes(m.slice(1))?r(d):(e.enter("gfmFootnoteCallLabelMarker"),e.consume(d),e.exit("gfmFootnoteCallLabelMarker"),t(d))}}function _O(e,t){let r=e.length;for(;r--;)if(e[r][1].type==="labelImage"&&e[r][0]==="enter"){e[r][1];break}e[r+1][1].type="data",e[r+3][1].type="gfmFootnoteCallLabelMarker";const s={type:"gfmFootnoteCall",start:Object.assign({},e[r+3][1].start),end:Object.assign({},e[e.length-1][1].end)},l={type:"gfmFootnoteCallMarker",start:Object.assign({},e[r+3][1].end),end:Object.assign({},e[r+3][1].end)};l.end.column++,l.end.offset++,l.end._bufferIndex++;const o={type:"gfmFootnoteCallString",start:Object.assign({},l.end),end:Object.assign({},e[e.length-1][1].start)},c={type:"chunkString",contentType:"string",start:Object.assign({},o.start),end:Object.assign({},o.end)},f=[e[r+1],e[r+2],["enter",s,t],e[r+3],e[r+4],["enter",l,t],["exit",l,t],["enter",o,t],["enter",c,t],["exit",c,t],["exit",o,t],e[e.length-2],e[e.length-1],["exit",s,t]];return e.splice(r,e.length-r+1,...f),e}function kO(e,t,r){const s=this,l=s.parser.gfmFootnotes||(s.parser.gfmFootnotes=[]);let o=0,c;return f;function f(g){return e.enter("gfmFootnoteCall"),e.enter("gfmFootnoteCallLabelMarker"),e.consume(g),e.exit("gfmFootnoteCallLabelMarker"),d}function d(g){return g!==94?r(g):(e.enter("gfmFootnoteCallMarker"),e.consume(g),e.exit("gfmFootnoteCallMarker"),e.enter("gfmFootnoteCallString"),e.enter("chunkString").contentType="string",m)}function m(g){if(o>999||g===93&&!c||g===null||g===91||Dt(g))return r(g);if(g===93){e.exit("chunkString");const x=e.exit("gfmFootnoteCallString");return l.includes(Lr(s.sliceSerialize(x)))?(e.enter("gfmFootnoteCallLabelMarker"),e.consume(g),e.exit("gfmFootnoteCallLabelMarker"),e.exit("gfmFootnoteCall"),t):r(g)}return Dt(g)||(c=!0),o++,e.consume(g),g===92?b:m}function b(g){return g===91||g===92||g===93?(e.consume(g),o++,m):m(g)}}function EO(e,t,r){const s=this,l=s.parser.gfmFootnotes||(s.parser.gfmFootnotes=[]);let o,c=0,f;return d;function d(S){return e.enter("gfmFootnoteDefinition")._container=!0,e.enter("gfmFootnoteDefinitionLabel"),e.enter("gfmFootnoteDefinitionLabelMarker"),e.consume(S),e.exit("gfmFootnoteDefinitionLabelMarker"),m}function m(S){return S===94?(e.enter("gfmFootnoteDefinitionMarker"),e.consume(S),e.exit("gfmFootnoteDefinitionMarker"),e.enter("gfmFootnoteDefinitionLabelString"),e.enter("chunkString").contentType="string",b):r(S)}function b(S){if(c>999||S===93&&!f||S===null||S===91||Dt(S))return r(S);if(S===93){e.exit("chunkString");const j=e.exit("gfmFootnoteDefinitionLabelString");return o=Lr(s.sliceSerialize(j)),e.enter("gfmFootnoteDefinitionLabelMarker"),e.consume(S),e.exit("gfmFootnoteDefinitionLabelMarker"),e.exit("gfmFootnoteDefinitionLabel"),x}return Dt(S)||(f=!0),c++,e.consume(S),S===92?g:b}function g(S){return S===91||S===92||S===93?(e.consume(S),c++,b):b(S)}function x(S){return S===58?(e.enter("definitionMarker"),e.consume(S),e.exit("definitionMarker"),l.includes(o)||l.push(o),pt(e,v,"gfmFootnoteDefinitionWhitespace")):r(S)}function v(S){return t(S)}}function CO(e,t,r){return e.check(Ql,t,e.attempt(vO,t,r))}function AO(e){e.exit("gfmFootnoteDefinition")}function jO(e,t,r){const s=this;return pt(e,l,"gfmFootnoteDefinitionIndent",5);function l(o){const c=s.events[s.events.length-1];return c&&c[1].type==="gfmFootnoteDefinitionIndent"&&c[2].sliceSerialize(c[1],!0).length===4?t(o):r(o)}}function NO(e){let r=(e||{}).singleTilde;const s={name:"strikethrough",tokenize:o,resolveAll:l};return r==null&&(r=!0),{text:{126:s},insideSpan:{null:[s]},attentionMarkers:{null:[126]}};function l(c,f){let d=-1;for(;++d<c.length;)if(c[d][0]==="enter"&&c[d][1].type==="strikethroughSequenceTemporary"&&c[d][1]._close){let m=d;for(;m--;)if(c[m][0]==="exit"&&c[m][1].type==="strikethroughSequenceTemporary"&&c[m][1]._open&&c[d][1].end.offset-c[d][1].start.offset===c[m][1].end.offset-c[m][1].start.offset){c[d][1].type="strikethroughSequence",c[m][1].type="strikethroughSequence";const b={type:"strikethrough",start:Object.assign({},c[m][1].start),end:Object.assign({},c[d][1].end)},g={type:"strikethroughText",start:Object.assign({},c[m][1].end),end:Object.assign({},c[d][1].start)},x=[["enter",b,f],["enter",c[m][1],f],["exit",c[m][1],f],["enter",g,f]],v=f.parser.constructs.insideSpan.null;v&&ur(x,x.length,0,ec(v,c.slice(m+1,d),f)),ur(x,x.length,0,[["exit",g,f],["enter",c[d][1],f],["exit",c[d][1],f],["exit",b,f]]),ur(c,m-1,d-m+3,x),d=m+x.length-2;break}}for(d=-1;++d<c.length;)c[d][1].type==="strikethroughSequenceTemporary"&&(c[d][1].type="data");return c}function o(c,f,d){const m=this.previous,b=this.events;let g=0;return x;function x(S){return m===126&&b[b.length-1][1].type!=="characterEscape"?d(S):(c.enter("strikethroughSequenceTemporary"),v(S))}function v(S){const j=ka(m);if(S===126)return g>1?d(S):(c.consume(S),g++,v);if(g<2&&!r)return d(S);const R=c.exit("strikethroughSequenceTemporary"),M=ka(S);return R._open=!M||M===2&&!!j,R._close=!j||j===2&&!!M,f(S)}}}class TO{constructor(){this.map=[]}add(t,r,s){OO(this,t,r,s)}consume(t){if(this.map.sort(function(o,c){return o[0]-c[0]}),this.map.length===0)return;let r=this.map.length;const s=[];for(;r>0;)r-=1,s.push(t.slice(this.map[r][0]+this.map[r][1]),this.map[r][2]),t.length=this.map[r][0];s.push(t.slice()),t.length=0;let l=s.pop();for(;l;){for(const o of l)t.push(o);l=s.pop()}this.map.length=0}}function OO(e,t,r,s){let l=0;if(!(r===0&&s.length===0)){for(;l<e.map.length;){if(e.map[l][0]===t){e.map[l][1]+=r,e.map[l][2].push(...s);return}l+=1}e.map.push([t,r,s])}}function RO(e,t){let r=!1;const s=[];for(;t<e.length;){const l=e[t];if(r){if(l[0]==="enter")l[1].type==="tableContent"&&s.push(e[t+1][1].type==="tableDelimiterMarker"?"left":"none");else if(l[1].type==="tableContent"){if(e[t-1][1].type==="tableDelimiterMarker"){const o=s.length-1;s[o]=s[o]==="left"?"center":"right"}}else if(l[1].type==="tableDelimiterRow")break}else l[0]==="enter"&&l[1].type==="tableDelimiterRow"&&(r=!0);t+=1}return s}function MO(){return{flow:{null:{name:"table",tokenize:DO,resolveAll:LO}}}}function DO(e,t,r){const s=this;let l=0,o=0,c;return f;function f(L){let J=s.events.length-1;for(;J>-1;){const le=s.events[J][1].type;if(le==="lineEnding"||le==="linePrefix")J--;else break}const $=J>-1?s.events[J][1].type:null,he=$==="tableHead"||$==="tableRow"?N:d;return he===N&&s.parser.lazy[s.now().line]?r(L):he(L)}function d(L){return e.enter("tableHead"),e.enter("tableRow"),m(L)}function m(L){return L===124||(c=!0,o+=1),b(L)}function b(L){return L===null?r(L):Fe(L)?o>1?(o=0,s.interrupt=!0,e.exit("tableRow"),e.enter("lineEnding"),e.consume(L),e.exit("lineEnding"),v):r(L):ut(L)?pt(e,b,"whitespace")(L):(o+=1,c&&(c=!1,l+=1),L===124?(e.enter("tableCellDivider"),e.consume(L),e.exit("tableCellDivider"),c=!0,b):(e.enter("data"),g(L)))}function g(L){return L===null||L===124||Dt(L)?(e.exit("data"),b(L)):(e.consume(L),L===92?x:g)}function x(L){return L===92||L===124?(e.consume(L),g):g(L)}function v(L){return s.interrupt=!1,s.parser.lazy[s.now().line]?r(L):(e.enter("tableDelimiterRow"),c=!1,ut(L)?pt(e,S,"linePrefix",s.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(L):S(L))}function S(L){return L===45||L===58?R(L):L===124?(c=!0,e.enter("tableCellDivider"),e.consume(L),e.exit("tableCellDivider"),j):q(L)}function j(L){return ut(L)?pt(e,R,"whitespace")(L):R(L)}function R(L){return L===58?(o+=1,c=!0,e.enter("tableDelimiterMarker"),e.consume(L),e.exit("tableDelimiterMarker"),M):L===45?(o+=1,M(L)):L===null||Fe(L)?ue(L):q(L)}function M(L){return L===45?(e.enter("tableDelimiterFiller"),P(L)):q(L)}function P(L){return L===45?(e.consume(L),P):L===58?(c=!0,e.exit("tableDelimiterFiller"),e.enter("tableDelimiterMarker"),e.consume(L),e.exit("tableDelimiterMarker"),I):(e.exit("tableDelimiterFiller"),I(L))}function I(L){return ut(L)?pt(e,ue,"whitespace")(L):ue(L)}function ue(L){return L===124?S(L):L===null||Fe(L)?!c||l!==o?q(L):(e.exit("tableDelimiterRow"),e.exit("tableHead"),t(L)):q(L)}function q(L){return r(L)}function N(L){return e.enter("tableRow"),ee(L)}function ee(L){return L===124?(e.enter("tableCellDivider"),e.consume(L),e.exit("tableCellDivider"),ee):L===null||Fe(L)?(e.exit("tableRow"),t(L)):ut(L)?pt(e,ee,"whitespace")(L):(e.enter("data"),G(L))}function G(L){return L===null||L===124||Dt(L)?(e.exit("data"),ee(L)):(e.consume(L),L===92?B:G)}function B(L){return L===92||L===124?(e.consume(L),G):G(L)}}function LO(e,t){let r=-1,s=!0,l=0,o=[0,0,0,0],c=[0,0,0,0],f=!1,d=0,m,b,g;const x=new TO;for(;++r<e.length;){const v=e[r],S=v[1];v[0]==="enter"?S.type==="tableHead"?(f=!1,d!==0&&(Fb(x,t,d,m,b),b=void 0,d=0),m={type:"table",start:Object.assign({},S.start),end:Object.assign({},S.end)},x.add(r,0,[["enter",m,t]])):S.type==="tableRow"||S.type==="tableDelimiterRow"?(s=!0,g=void 0,o=[0,0,0,0],c=[0,r+1,0,0],f&&(f=!1,b={type:"tableBody",start:Object.assign({},S.start),end:Object.assign({},S.end)},x.add(r,0,[["enter",b,t]])),l=S.type==="tableDelimiterRow"?2:b?3:1):l&&(S.type==="data"||S.type==="tableDelimiterMarker"||S.type==="tableDelimiterFiller")?(s=!1,c[2]===0&&(o[1]!==0&&(c[0]=c[1],g=xu(x,t,o,l,void 0,g),o=[0,0,0,0]),c[2]=r)):S.type==="tableCellDivider"&&(s?s=!1:(o[1]!==0&&(c[0]=c[1],g=xu(x,t,o,l,void 0,g)),o=c,c=[o[1],r,0,0])):S.type==="tableHead"?(f=!0,d=r):S.type==="tableRow"||S.type==="tableDelimiterRow"?(d=r,o[1]!==0?(c[0]=c[1],g=xu(x,t,o,l,r,g)):c[1]!==0&&(g=xu(x,t,c,l,r,g)),l=0):l&&(S.type==="data"||S.type==="tableDelimiterMarker"||S.type==="tableDelimiterFiller")&&(c[3]=r)}for(d!==0&&Fb(x,t,d,m,b),x.consume(t.events),r=-1;++r<t.events.length;){const v=t.events[r];v[0]==="enter"&&v[1].type==="table"&&(v[1]._align=RO(t.events,r))}return e}function xu(e,t,r,s,l,o){const c=s===1?"tableHeader":s===2?"tableDelimiter":"tableData",f="tableContent";r[0]!==0&&(o.end=Object.assign({},ca(t.events,r[0])),e.add(r[0],0,[["exit",o,t]]));const d=ca(t.events,r[1]);if(o={type:c,start:Object.assign({},d),end:Object.assign({},d)},e.add(r[1],0,[["enter",o,t]]),r[2]!==0){const m=ca(t.events,r[2]),b=ca(t.events,r[3]),g={type:f,start:Object.assign({},m),end:Object.assign({},b)};if(e.add(r[2],0,[["enter",g,t]]),s!==2){const x=t.events[r[2]],v=t.events[r[3]];if(x[1].end=Object.assign({},v[1].end),x[1].type="chunkText",x[1].contentType="text",r[3]>r[2]+1){const S=r[2]+1,j=r[3]-r[2]-1;e.add(S,j,[])}}e.add(r[3]+1,0,[["exit",g,t]])}return l!==void 0&&(o.end=Object.assign({},ca(t.events,l)),e.add(l,0,[["exit",o,t]]),o=void 0),o}function Fb(e,t,r,s,l){const o=[],c=ca(t.events,r);l&&(l.end=Object.assign({},c),o.push(["exit",l,t])),s.end=Object.assign({},c),o.push(["exit",s,t]),e.add(r+1,0,o)}function ca(e,t){const r=e[t],s=r[0]==="enter"?"start":"end";return r[1][s]}const zO={name:"tasklistCheck",tokenize:PO};function UO(){return{text:{91:zO}}}function PO(e,t,r){const s=this;return l;function l(d){return s.previous!==null||!s._gfmTasklistFirstContentOfListItem?r(d):(e.enter("taskListCheck"),e.enter("taskListCheckMarker"),e.consume(d),e.exit("taskListCheckMarker"),o)}function o(d){return Dt(d)?(e.enter("taskListCheckValueUnchecked"),e.consume(d),e.exit("taskListCheckValueUnchecked"),c):d===88||d===120?(e.enter("taskListCheckValueChecked"),e.consume(d),e.exit("taskListCheckValueChecked"),c):r(d)}function c(d){return d===93?(e.enter("taskListCheckMarker"),e.consume(d),e.exit("taskListCheckMarker"),e.exit("taskListCheck"),f):r(d)}function f(d){return Fe(d)?t(d):ut(d)?e.check({tokenize:BO},t,r)(d):r(d)}}function BO(e,t,r){return pt(e,s,"whitespace");function s(l){return l===null?r(l):t(l)}}function HO(e){return i1([fO(),wO(),NO(e),MO(),UO()])}const qO={};function IO(e){const t=this,r=e||qO,s=t.data(),l=s.micromarkExtensions||(s.micromarkExtensions=[]),o=s.fromMarkdownExtensions||(s.fromMarkdownExtensions=[]),c=s.toMarkdownExtensions||(s.toMarkdownExtensions=[]);l.push(HO(r)),o.push(lO()),c.push(oO(r))}function FO(e){A1(e,[/\r?\n|\r/g,$O])}function $O(){return{type:"break"}}function VO(){return function(e){FO(e)}}const hm=E.createContext(null);function Q1(e,t){const r=C1(t);return e&&r!==null?jT(r,e.baseFile):null}function YO({node:e,href:t,...r}){const s=E.useContext(hm),l=Q1(s,t);return!s||l===null?y.jsx("a",{...r,href:t,target:"_blank",rel:"noopener noreferrer"}):y.jsx("a",{...r,href:t,className:"md-file-link",onClick:o=>{o.preventDefault(),s.openFile(l)}})}function GO({node:e,src:t,alt:r,...s}){const l=E.useContext(hm),o=Q1(l,typeof t=="string"?t:void 0),[c,f]=E.useState(),[d,m]=E.useState(!1),b=l==null?void 0:l.loadFile;return E.useEffect(()=>{if(o===null||!b)return;let g=!1,x;return m(!1),b(o).then(v=>{g||(x=URL.createObjectURL(v),f(x))}).catch(()=>{g||m(!0)}),()=>{g=!0,x&&URL.revokeObjectURL(x)}},[o,b]),!l||o===null?y.jsx("img",{...s,src:t,alt:r}):d?y.jsx("span",{className:"md-image-missing",children:r||o}):c?y.jsx("img",{...s,src:c,alt:r,className:"md-file-image",onClick:()=>l.openFile(o)}):y.jsx("span",{className:"md-image-loading skeleton-line"})}const JO={a:YO,img:GO};function Z1({content:e,files:t,baseFile:r}){const s=E.useMemo(()=>({openFile:t.openFile,loadFile:t.loadFile,baseFile:r}),[t.openFile,t.loadFile,r]);return y.jsx(hm.Provider,{value:s,children:y.jsx(wT,{remarkPlugins:[IO,VO],urlTransform:CT,components:JO,children:e})})}function XO({filePath:e,files:t,onClose:r}){const[s,l]=E.useState(null),[o,c]=E.useState(null),{loadFile:f}=t;E.useEffect(()=>{let b=!1,g;return l(null),c(null),(async()=>{try{const x=await f(e),v=MT(x.type),S={kind:v,size:x.size};if(v==="markdown"||v==="text"||v==="html"?S.text=await x.text():(g=URL.createObjectURL(x),S.objectUrl=g),b){g&&URL.revokeObjectURL(g);return}l(S)}catch(x){b||c(x instanceof Error?x.message:"Failed to load file.")}})(),()=>{b=!0,g&&URL.revokeObjectURL(g)}},[e,f]);const d=NT(e);function m(){if(o)return y.jsx("p",{className:"file-viewer-message",children:o});if(!s)return y.jsxs("div",{className:"file-viewer-loading",children:[y.jsx("div",{className:"skeleton-line",style:{width:"40%"}}),y.jsx("div",{className:"skeleton-line",style:{width:"100%",height:"8rem"}})]});switch(s.kind){case"markdown":return y.jsx(Z1,{content:s.text??"",files:t,baseFile:e});case"text":return y.jsx("pre",{className:"file-viewer-text",children:s.text});case"html":return y.jsx("iframe",{className:"file-viewer-frame",sandbox:"",srcDoc:s.text,title:d});case"image":return y.jsx("img",{src:s.objectUrl,alt:d,style:{maxWidth:"100%",height:"auto"}});case"binary":return Jn.isNativePlatform()?y.jsx("p",{className:"file-viewer-message",children:"Downloading this file type isn't supported in the app yet."}):y.jsxs("div",{className:"file-viewer-download",children:[y.jsxs("p",{className:"file-viewer-message",children:["This file can't be previewed (",DT(s.size),")."]}),y.jsx("a",{className:"btn btn-primary",href:s.objectUrl,download:d,children:"Download"})]})}}return y.jsx("div",{className:"report-dialog-overlay",onClick:r,children:y.jsxs("div",{className:"report-dialog",onClick:b=>b.stopPropagation(),children:[y.jsxs("div",{className:"report-dialog-header",children:[y.jsx("span",{className:"report-dialog-title",children:d}),y.jsx("button",{className:"report-dialog-close",onClick:r,"aria-label":"Close",children:y.jsxs("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[y.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),y.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})})]}),y.jsx("div",{className:`report-dialog-body${(s==null?void 0:s.kind)==="html"?" report-dialog-body--frame":""}`,children:m()})]})})}function KO({connected:e,hostId:t,request:r,subscribeEvents:s,taskId:l,runId:o}){const c=Gr(),f=Yd(),[d,m]=E.useState(!0),[b,g]=E.useState([]),[x,v]=E.useState(),[S,j]=E.useState(),[R,M]=E.useState(),[P,I]=E.useState(!1),ue=x==="started",q=x==="followup",N=x==="started"||x==="followup",[ee,G]=E.useState(null);yd(ee!==null,()=>G(null));const[B,L]=E.useState(!1),[J,$]=E.useState(""),[he,le]=E.useState(!1),te=E.useRef(null),V=E.useRef(null),Q=E.useRef(null),[X,xe]=E.useState(o==="latest"?void 0:o),A=o==="latest"&&X===null;E.useEffect(()=>{if(o!=="latest"){xe(o);return}e&&(xe(void 0),r("taskrun.list",{task_id:l,limit:1}).then(ce=>{var Ae,ke;return xe(((ke=(Ae=ce.entries)==null?void 0:Ae[0])==null?void 0:ke.run_id)??null)}).catch(()=>xe(null)))},[o,l,e,r]);async function z(){if(X)try{const ce=await r("task.result",{id:l,run_id:X});if(ce.error){console.error("No result:",ce.error),c(t?`/hosts/${encodeURIComponent(t)}`:"/",{replace:!0});return}g(ce.messages??[]),v(ce.running_state),j(ce.agent),M(ce.agent_version),I(!!ce.starred)}catch(ce){console.error("Failed to load result:",ce),c(t?`/hosts/${encodeURIComponent(t)}`:"/",{replace:!0})}finally{m(!1)}}async function W(){if(!X)return;const ce=!P;I(ce);try{const Ae=await r("taskrun.star",{task_id:l,run_id:X,starred:ce});if(Ae.error)throw new Error(Ae.error)}catch(Ae){console.error("Failed to update star:",Ae),I(!ce)}}const T=E.useCallback(ce=>X?OT(r,l,X,ce):Promise.reject(new Error("Run not loaded.")),[r,l,X]),ve=E.useMemo(()=>({openFile:G,loadFile:T}),[T]);E.useEffect(()=>{!e||!X||(m(!0),z())},[e,l,X]),E.useEffect(()=>!e||!t||!X?void 0:s(t,async Ae=>{try{const ke=JSON.parse(new TextDecoder().decode(Ae.data));if(ke.event_type!=="running-state"&&ke.event_type!=="result-updated"||Ae.subject.split(".").pop()!==l||ke.event_type==="result-updated"&&ke.run_id&&ke.run_id!==X)return;z()}catch{}}),[e,t,l,X,s,r]),E.useEffect(()=>{te.current&&(te.current.scrollTop=te.current.scrollHeight)},[b]),E.useEffect(()=>{d||A||!X||Q.current!==X&&(Q.current=X,requestAnimationFrame(()=>{te.current&&(te.current.scrollTop=te.current.scrollHeight),window.scrollTo({top:document.documentElement.scrollHeight,behavior:"auto"})}))},[d,A,X]);function je(ce){if(ce==="input")return"User Input";if(ce==="permission")return"Permission";if(ce==="confirmation")return"Confirmation"}function Ne(ce){return ce==="started"?"Task started":ce==="finished"?"Task finished":ce==="failed"?"Task failed":ce==="error"?"Command failed":ce==="aborted"?"Task aborted":ce==="confirmation"?"Task confirmed":ce==="stopped"?"Follow-up stopped":ce??""}return y.jsxs("div",{className:"run-detail",children:[y.jsxs("div",{className:"run-detail-header",children:[y.jsxs("button",{className:"run-detail-back",onClick:()=>c(-1),children:[y.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:y.jsx("path",{d:"M15 18l-6-6 6-6"})}),"Back"]}),!d&&!A&&y.jsx(Fx,{starred:P,onToggle:W})]}),A?y.jsxs("div",{className:"empty-state",children:[y.jsx("p",{className:"empty-state-text",children:"No runs yet"}),y.jsx("p",{className:"empty-state-hint",children:"This task hasn't been executed yet. Run it from the task menu or wait for its next trigger."})]}):d?y.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"var(--space-sm)",padding:"var(--space-sm) 0"},children:[y.jsx("div",{className:"skeleton-line",style:{width:"40%"}}),y.jsx("div",{className:"skeleton-line",style:{width:"55%"}}),y.jsx("div",{className:"skeleton-line",style:{width:"100%",height:"8rem",marginTop:"var(--space-sm)"}})]}):y.jsxs(y.Fragment,{children:[y.jsxs("div",{className:"chat-thread",ref:te,children:[b.map((ce,Ae)=>{const ke=N&&ce.role==="assistant"&&!b.slice(Ae+1).some(Qe=>Qe.role==="assistant"||Qe.role==="user");return ce.role==="status"?y.jsxs("div",{className:`chat-status${ce.type==="error"?" chat-status--error":""}`,children:[y.jsxs("div",{children:[Ne(ce.type),ce.time>0&&y.jsx("span",{className:"chat-status-time",children:f(ce.time)})]}),ce.content&&y.jsx("pre",{className:"chat-status-detail",children:ce.content})]},Ae):y.jsxs("div",{className:`chat-message chat-message--${ce.role}${ce.role==="assistant"&&ce.stream==="stderr"?" chat-message--stderr":""}`,children:[ce.role==="assistant"&&S&&y.jsxs("div",{className:"chat-message-agent",children:[gd(S),R&&y.jsxs("span",{className:"chat-message-agent-version",children:[" v",R]}),ce.model&&y.jsxs("span",{className:"chat-message-agent-model",children:[" · ",ce.model]})]}),y.jsxs("div",{className:"chat-message-content",children:[y.jsx(Z1,{content:ce.content,files:ve}),ke&&y.jsxs("div",{className:"chat-typing-indicator",children:[y.jsx("span",{}),y.jsx("span",{}),y.jsx("span",{})]})]}),ce.attachments&&ce.attachments.length>0&&y.jsx("div",{className:"chat-message-attachments",children:ce.attachments.map(Qe=>y.jsx("button",{className:"chat-attachment-chip",onClick:()=>G(Qe),children:Qe},Qe))}),y.jsxs("div",{className:"chat-message-meta",children:[je(ce.type)&&y.jsx("span",{className:"chat-message-type",children:je(ce.type)}),ce.time>0&&y.jsx("span",{children:f(ce.time)})]})]},Ae)}),N&&(()=>{const ce=b.filter(Ae=>Ae.role!=="status");return ce.length===0||ce[ce.length-1].role!=="assistant"})()&&y.jsxs("div",{className:"chat-message chat-message--assistant",children:[S&&y.jsxs("div",{className:"chat-message-agent",children:[gd(S),R&&y.jsxs("span",{className:"chat-message-agent-version",children:[" v",R]})]}),y.jsxs("div",{className:"chat-typing-indicator",children:[y.jsx("span",{}),y.jsx("span",{}),y.jsx("span",{})]})]})]}),ue||q?y.jsx("div",{className:"chat-input-bar",children:y.jsx("button",{className:"btn btn-secondary chat-stop-btn",disabled:B,"aria-label":"Abort task",onClick:async()=>{if(confirm("Abort this task?")){L(!0);try{await r("task.abort",{id:l})}catch(ce){console.error("Abort failed:",ce)}finally{L(!1)}}},children:y.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"currentColor",children:y.jsx("rect",{x:"6",y:"6",width:"12",height:"12",rx:"2"})})})}):y.jsxs("form",{className:"chat-input-bar",onSubmit:async ce=>{ce.preventDefault();const Ae=J.trim();if(!(!Ae||he)){le(!0);try{await r("task.followup",{id:l,run_id:X,message:Ae}),$("")}catch(ke){console.error("Follow-up failed:",ke)}finally{le(!1)}}},children:[y.jsx("input",{ref:V,className:"chat-input",type:"text",placeholder:"Follow-up message",value:J,onChange:ce=>$(ce.target.value),disabled:he}),y.jsx("button",{className:"btn btn-primary chat-send-btn",type:"submit",disabled:!J.trim()||he,children:y.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[y.jsx("line",{x1:"22",y1:"2",x2:"11",y2:"13"}),y.jsx("polygon",{points:"22 2 15 22 11 13 2 9 22 2"})]})})]}),y.jsxs("button",{className:"run-detail-back run-detail-back--footer",onClick:()=>c(-1),children:[y.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:y.jsx("path",{d:"M15 18l-6-6 6-6"})}),"Back"]})]}),ee&&y.jsx(XO,{filePath:ee,files:ve,onClose:()=>G(null)})]})}function Zh({title:e,message:t,onUpdate:r,onDismiss:s}){return y.jsx("div",{className:"confirm-modal-overlay",children:y.jsxs("div",{className:"confirm-modal",children:[y.jsx("h2",{className:"confirm-modal-title",children:e}),y.jsx("p",{className:"confirm-modal-message",children:t}),y.jsxs("div",{className:"confirm-modal-actions",children:[y.jsx("button",{className:"btn btn-primary",onClick:r,children:"Update Now"}),s&&y.jsx("button",{className:"btn btn-secondary",onClick:s,children:"Dismiss"})]})]})})}function QO(){const{activeHost:e}=xi(),t=E.useRef(null);E.useEffect(()=>{if(Jn.isNativePlatform()||e.directUrl||t.current===e.hostId)return;async function r(){var s;try{if(!("serviceWorker"in navigator)||!("PushManager"in window)){console.warn("[Push] Push notifications not supported");return}const l=await navigator.serviceWorker.ready;(s=l.active)==null||s.postMessage({type:"set-host-id",hostId:e.hostId});let o=await l.pushManager.getSubscription();if(!o){const{publicKey:f}=await wE("/api/push/vapid-key");if(!f){console.warn("[Push] No VAPID public key configured on server");return}if(await Notification.requestPermission()!=="granted"){console.log("[Push] Permission denied");return}o=await l.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:f})}const c=o.toJSON();await vE("/api/push/subscribe",{hostId:e.hostId,endpoint:c.endpoint,keys:{p256dh:c.keys.p256dh,auth:c.keys.auth}}),t.current=e.hostId}catch(l){console.error("[Push] Subscription failed:",l)}}r()},[e])}const ZO="0.9.9";function vu(e,t){if(e.includes("-"))return!1;const r=e.split(".").map(Number),s=t.split(".").map(Number);for(let l=0;l<3;l++){if((r[l]??0)<(s[l]??0))return!0;if((r[l]??0)>(s[l]??0))return!1}return!1}function wu(){const{removePairedHost:e,setHostLanUrl:t,setHostTimezone:r}=Zi(),{connected:s,request:l,subscribeEvents:o,unauthorized:c,activeHost:f}=xi(),d=f.hostId,m=f.clientToken||null,b=Gr(),g=Er(),x=Yu(),v=qx("(min-width: 768px)"),S=g.pathname.endsWith("/tasks"),j=x.runId?void 0:x.taskId,R=!!(x.taskId&&x.runId),[M,P]=E.useState(!1),[I,ue]=E.useState(!1),[q,N]=E.useState(null),[ee,G]=E.useState(null),[B,L]=E.useState(null),[J,$]=E.useState(null),[he,le]=E.useState({}),[te,V]=E.useState({}),[Q,X]=E.useState(null),[xe,A]=E.useState(null),[z,W]=E.useState(null),[T,ve]=E.useState(null),[je,Ne]=E.useState(new Set),[ce,Ae]=E.useState([]),[ke,Qe]=E.useState(),[Lt,dn]=E.useState("loading"),tn=!!m&&T===m,[Ft,$t]=E.useState(new Map),[an,bn]=E.useState(new Map),[Be,nt]=E.useState(new Map),[st,Ot]=E.useState(new Map),[_t,mn]=E.useState(new Map),[at,Cr]=E.useState(new Map),[ae,_e]=E.useState(new Map),[Me,Ge]=E.useState(new Map);QO(),E.useEffect(()=>{window.scrollTo(0,0)},[d]),E.useEffect(()=>{let de=!1;return eC().then(Ee=>{de||Ne(Ee)}),()=>{de=!0}},[]),E.useEffect(()=>{if(!s){dn("loading");return}dn("loading");let de=!1;return l("host.info",void 0,{timeout:15e3}).then(Ee=>{var We,Zt,Qt,Rt,ft,Bt,jn,Pr,wi;if(de)return;Ae(Ee.agents??[]),X(Ee.playwright_cli??null),Qe(Ee.host_platform),ve(Ee.linked_client_token??null),LE(Ee.agents??[]);const He=Ee.version??null;G(He),P(!!He&&vu(He,ZO)),t(d,Ee.lan_url??void 0),r(d,Ee.host_timezone);const Ve=new Map,qe=new Map,ct=new Map,Xe=new Map,Pe=new Map;for(const Ut of Ee.pending_prompts??[])if(Ut.type==="confirmation")Ve.set(Ut.key,{description:((We=Ut.meta)==null?void 0:We.description)??"",sessionName:(Zt=Ut.meta)==null?void 0:Zt.session_name});else if(Ut.type==="choice")qe.set(Ut.key,{question:((Qt=Ut.meta)==null?void 0:Qt.description)??"",options:Ut.params??[],sessionName:(Rt=Ut.meta)==null?void 0:Rt.session_name});else if(Ut.type==="permission")ct.set(Ut.key,{permissions:Ut.params??[],sessionName:(ft=Ut.meta)==null?void 0:ft.session_name});else if(Ut.type==="input"){const ns=Ut.params??((Bt=Ut.meta)==null?void 0:Bt.input_questions)??[];Xe.set(Ut.key,{questions:ns,description:(jn=Ut.meta)==null?void 0:jn.description,sessionName:(Pr=Ut.meta)==null?void 0:Pr.session_name,secret:(wi=Ut.meta)==null?void 0:wi.secret}),Pe.set(Ut.key,new Array(ns.length).fill(""))}$t(Ve),bn(qe),nt(ct),Ot(Xe),mn(Pe),dn("ready")}).catch(()=>{de||dn("error")}),()=>{de=!0}},[s,d,l,t,r]),E.useEffect(()=>s?o(d,Ee=>{const He=Ee.subject.split(".");if(He.length<3)return;const Ve=He.slice(2).join(".");let qe={};try{qe=JSON.parse(new TextDecoder().decode(Ee.data))}catch{return}const ct=qe.event_type,Xe=qe.session_id;if(ct==="input-request"&&Xe){const Pe=qe.input_questions,We=qe.session_name,Zt=qe.description,Qt=qe.secret;Pe!=null&&Pe.length&&(Ot(Rt=>{if(Rt.has(Xe))return Rt;const ft=new Map(Rt);return ft.set(Xe,{questions:Pe,description:Zt,sessionName:We,secret:Qt}),ft}),mn(Rt=>{if(Rt.has(Xe))return Rt;const ft=new Map(Rt);return ft.set(Xe,new Array(Pe.length).fill("")),ft}));return}if(ct==="input-resolved"&&Xe){Ot(Pe=>{if(!Pe.has(Xe))return Pe;const We=new Map(Pe);return We.delete(Xe),We}),mn(Pe=>{const We=new Map(Pe);return We.delete(Xe),We}),Cr(Pe=>{if(!Pe.has(Xe))return Pe;const We=new Map(Pe);return We.delete(Xe),We});return}if(ct==="confirm-request"&&Xe){const Pe=qe.description,We=qe.session_name;Pe&&$t(Zt=>{if(Zt.has(Xe))return Zt;const Qt=new Map(Zt);return Qt.set(Xe,{description:Pe,sessionName:We}),Qt});return}if(ct==="confirm-resolved"&&Xe){$t(Pe=>{if(!Pe.has(Xe))return Pe;const We=new Map(Pe);return We.delete(Xe),We});return}if(ct==="choice-request"&&Xe){const Pe=qe.description,We=qe.options,Zt=qe.session_name;Pe&&(We!=null&&We.length)&&bn(Qt=>{if(Qt.has(Xe))return Qt;const Rt=new Map(Qt);return Rt.set(Xe,{question:Pe,options:We,sessionName:Zt}),Rt});return}if(ct==="choice-resolved"&&Xe){bn(Pe=>{if(!Pe.has(Xe))return Pe;const We=new Map(Pe);return We.delete(Xe),We});return}if(ct==="permission-request"){const Pe=qe.required_permissions,We=qe.session_name;Pe!=null&&Pe.length&&nt(Zt=>{if(Zt.has(Ve))return Zt;const Qt=new Map(Zt);return Qt.set(Ve,{permissions:Pe,sessionName:We}),Qt});return}if(ct==="permission-resolved"){nt(Pe=>{if(!Pe.has(Ve))return Pe;const We=new Map(Pe);return We.delete(Ve),We});return}}):void 0,[s,d,o]);async function rt(de,Ee,He,Ve){if(!ae.has(de)){_e(qe=>new Map(qe).set(de,Ee)),Ge(qe=>{const ct=new Map(qe);return ct.delete(de),ct});try{await l("task.user_input",{id:de,value:He},{timeout:3e4}),Ve()}catch(qe){console.error("[Dashboard] Failed to send user input:",qe),Ge(ct=>new Map(ct).set(de,"Couldn't reach the host. Try again."))}finally{_e(qe=>{const ct=new Map(qe);return ct.delete(de),ct})}}}function zt(de,Ee){rt(de,Ee,[Ee],()=>{$t(He=>{const Ve=new Map(He);return Ve.delete(de),Ve})})}function Sn(de,Ee){rt(de,Ee,[Ee],()=>{bn(He=>{const Ve=new Map(He);return Ve.delete(de),Ve})})}function Kt(de,Ee){rt(de,Ee,[Ee],()=>{nt(He=>{const Ve=new Map(He);return Ve.delete(de),Ve})})}function yt(de,Ee,He){rt(de,Ee,He,()=>{Ot(Ve=>{const qe=new Map(Ve);return qe.delete(de),qe}),mn(Ve=>{const qe=new Map(Ve);return qe.delete(de),qe}),Cr(Ve=>{const qe=new Map(Ve);return qe.delete(de),qe})})}function Vt(de,Ee){if(!Ss())return;const He=`/hosts/${encodeURIComponent(d)}/runs/${encodeURIComponent(de)}`;b(Ee?`${He}/${encodeURIComponent(Ee)}`:He)}E.useEffect(()=>{if(!ee)return;let de=!1;return fetch("https://registry.npmjs.org/palmier/latest").then(Ee=>Ee.ok?Ee.json():null).then(Ee=>{!de&&(Ee!=null&&Ee.version)&&L(Ee.version)}).catch(()=>{}),()=>{de=!0}},[ee]),E.useEffect(()=>{let de=!1;for(const Ee of ce)!Ee.version||!Ee.npmPackage||fetch(`https://registry.npmjs.org/${Ee.npmPackage}/latest`).then(He=>He.ok?He.json():null).then(He=>{de||!(He!=null&&He.version)||le(Ve=>Ve[Ee.key]===He.version?Ve:{...Ve,[Ee.key]:He.version})}).catch(()=>{});return()=>{de=!0}},[ce]);const Ze=ce.find(de=>{if(!de.version)return!1;const Ee=he[de.key];return!Ee||!vu(de.version,Ee)?!1:te[de.key]!==Ee});function An(de,Ee){V(He=>({...He,[de]:Ee}))}async function pn(de){ue("agent"),N(null);try{const Ee=await l("host.updateAgent",{key:de});if(Ee.error){N(Ee.error),ue(!1);return}const He=await l("host.info");He.agents&&Ae(He.agents)}catch(Ee){N(Ee instanceof Error?Ee.message:String(Ee))}finally{ue(!1)}}E.useEffect(()=>{if(!(Q!=null&&Q.npmPackage))return;let de=!1;return fetch(`https://registry.npmjs.org/${Q.npmPackage}/latest`).then(Ee=>Ee.ok?Ee.json():null).then(Ee=>{!de&&(Ee!=null&&Ee.version)&&A(Ee.version)}).catch(()=>{}),()=>{de=!0}},[Q==null?void 0:Q.npmPackage,Q==null?void 0:Q.version]);const Kn=Q&&xe&&vu(Q.version,xe)&&z!==xe?Q:null;function we(de){W(de)}async function Ye(){ue("playwright"),N(null);try{const de=await l("host.updatePlaywrightCli");if(de.error){N(de.error),ue(!1);return}const Ee=await l("host.info");X(Ee.playwright_cli??null)}catch(de){N(de instanceof Error?de.message:String(de))}finally{ue(!1)}}const Re=!M&&!!ee&&!!B&&vu(ee,B)&&J!==B;function bt(){B&&$(B)}async function ln(){ue("daemon"),N(null);try{const de=await l("host.update");if(de.error){N(de.error),ue(!1);return}}catch{}setTimeout(()=>window.location.reload(),3e4)}const Hn=Ft.size>0||an.size>0||Be.size>0||st.size>0,ts=s&&!c;return y.jsxs("div",{className:"dashboard",children:[v&&y.jsx(Q0,{daemonVersion:ee,agents:ce,playwrightCli:Q,linkedClientToken:T,request:l,onEnabledCapabilitiesChange:Ne,onLinkedClientTokenChange:ve}),y.jsxs("div",{className:"dashboard-content",children:[y.jsxs("header",{className:"app-header",children:[y.jsxs("div",{className:"app-title-bar",children:[!v&&y.jsx(Q0,{daemonVersion:ee,agents:ce,playwrightCli:Q,linkedClientToken:T,request:l,onEnabledCapabilitiesChange:Ne,onLinkedClientTokenChange:ve}),y.jsx("h1",{className:"app-title",children:"Palmier"}),y.jsx(aC,{})]}),y.jsx("div",{className:"tab-bar",children:y.jsx(QE,{})})]}),y.jsx("main",{className:"dashboard-main",children:c?y.jsxs("div",{className:"revoked-state",children:[y.jsx("div",{className:"revoked-icon",children:y.jsxs("svg",{width:"32",height:"32",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",children:[y.jsx("rect",{x:"3",y:"11",width:"18",height:"11",rx:"2",ry:"2"}),y.jsx("path",{d:"M7 11V7a5 5 0 0 1 10 0v4"}),y.jsx("line",{x1:"12",y1:"15",x2:"12",y2:"18"})]})}),y.jsx("h2",{className:"revoked-title",children:"Client Revoked"}),y.jsx("p",{className:"revoked-description",children:"This client was revoked by the host. To reconnect, generate a new pairing code on the host machine."}),y.jsx("div",{className:"revoked-command",children:y.jsx("code",{children:"palmier pair"})}),y.jsxs("div",{className:"revoked-actions",children:[y.jsx("button",{className:"btn btn-primary",onClick:()=>{Ss()&&b("/pair")},children:"Re-pair Device"}),y.jsx("button",{className:"btn btn-secondary",onClick:()=>{e(d),b("/",{replace:!0})},children:"Remove Host"})]})]}):ts?y.jsxs(y.Fragment,{children:[S&&!R&&y.jsx(KE,{connected:s,hostId:d,request:l,subscribeEvents:o,agents:ce,hostPlatform:ke,isNotificationListener:tn&&je.has("notifications"),onViewRun:Vt,hostInfoStatus:Lt}),R?y.jsx(KO,{connected:s,hostId:d,request:l,subscribeEvents:o,taskId:x.taskId,runId:decodeURIComponent(x.runId)}):S?null:y.jsx(cC,{connected:s,hostId:d,request:l,subscribeEvents:o,agents:ce,hostPlatform:ke,filterTaskId:j,onClearFilter:()=>{Ss()&&b(`/hosts/${encodeURIComponent(d)}`)},hostInfoStatus:Lt})]}):y.jsx("div",{className:"empty-state",children:y.jsx("p",{className:"empty-state-text",children:"Connecting to host…"})})}),(M||Re)&&!I&&!q&&!Hn&&y.jsx(Zh,{title:M?"Update Required":"Update Available",message:M?`Your Palmier host${ee?` (v${ee})`:""} is too old for this version of the app. Please update to continue.`:`A new version of Palmier (v${B}) is available. You're running v${ee}.`,onUpdate:ln,onDismiss:M?void 0:bt}),!M&&!Re&&Ze&&!I&&!q&&!Hn&&y.jsx(Zh,{title:"Agent Update Available",message:`A new version of ${Ze.label} (v${he[Ze.key]}) is available. You're running v${Ze.version}.`,onUpdate:()=>pn(Ze.key),onDismiss:()=>An(Ze.key,he[Ze.key])}),!M&&!Re&&!Ze&&Kn&&xe&&!I&&!q&&!Hn&&y.jsx(Zh,{title:"Browser Automation Update Available",message:`A new version of ${Kn.label} (v${xe}) is available. You're running v${Kn.version}.`,onUpdate:Ye,onDismiss:()=>we(xe)}),I&&y.jsx("div",{className:"confirm-modal-overlay",children:y.jsxs("div",{className:"confirm-modal",children:[y.jsx("h2",{className:"confirm-modal-title",children:"Updating..."}),y.jsx("p",{className:"confirm-modal-message",children:I==="daemon"?"Installing update and restarting daemon. Please wait...":"Installing update. Please wait..."})]})}),q&&y.jsx("div",{className:"confirm-modal-overlay",children:y.jsxs("div",{className:"confirm-modal",children:[y.jsx("h2",{className:"confirm-modal-title",children:"Update Failed"}),y.jsx("p",{className:"confirm-modal-message",style:{whiteSpace:"pre-line"},children:q}),y.jsx("div",{className:"confirm-modal-actions",children:y.jsx("button",{className:"btn btn-secondary",onClick:()=>{N(null)},children:"Retry"})})]})})]}),pi.createPortal(y.jsxs(y.Fragment,{children:[[...Ft.entries()].map(([de,{description:Ee,sessionName:He}])=>y.jsx("div",{className:"confirm-modal-overlay",children:y.jsxs("div",{className:"confirm-modal",children:[y.jsx("h2",{className:"confirm-modal-title",children:"Confirmation Required"}),He&&y.jsx("p",{className:"confirm-modal-subtitle",children:He}),y.jsx("p",{className:"confirm-modal-message",children:Ee}),Me.has(de)&&y.jsx("p",{className:"form-error",children:Me.get(de)}),y.jsxs("div",{className:"confirm-modal-actions",children:[y.jsxs("button",{className:"btn btn-primary",disabled:ae.has(de),onClick:()=>zt(de,"confirmed"),children:[ae.get(de)==="confirmed"&&y.jsx("span",{className:"btn-spinner"}),"Confirm"]}),y.jsxs("button",{className:"btn btn-secondary",disabled:ae.has(de),onClick:()=>zt(de,"aborted"),children:[ae.get(de)==="aborted"&&y.jsx("span",{className:"btn-spinner btn-spinner-current"}),"Abort"]})]})]})},de)),[...an.entries()].map(([de,{question:Ee,options:He,sessionName:Ve}])=>y.jsx("div",{className:"confirm-modal-overlay",children:y.jsxs("div",{className:"confirm-modal",children:[y.jsx("h2",{className:"confirm-modal-title",children:"Question"}),Ve&&y.jsx("p",{className:"confirm-modal-subtitle",children:Ve}),y.jsx("p",{className:"confirm-modal-message",children:Ee}),Me.has(de)&&y.jsx("p",{className:"form-error",children:Me.get(de)}),y.jsx("div",{className:`confirm-modal-actions${He.length===2&&He.every(qe=>qe.length<=16)?"":" choice-options-stacked"}`,children:He.map((qe,ct)=>y.jsxs("button",{className:"btn btn-secondary",disabled:ae.has(de),onClick:()=>Sn(de,String(ct)),children:[ae.get(de)===String(ct)&&y.jsx("span",{className:"btn-spinner btn-spinner-current"}),qe]},ct))}),y.jsxs("button",{className:"permission-abort-link",disabled:ae.has(de),onClick:()=>Sn(de,"aborted"),children:[ae.get(de)==="aborted"&&y.jsx("span",{className:"btn-spinner btn-spinner-current"}),"Abort Task"]})]})},de)),[...Be.entries()].map(([de,{permissions:Ee,sessionName:He}])=>y.jsx("div",{className:"confirm-modal-overlay",children:y.jsxs("div",{className:"confirm-modal permission-modal",children:[y.jsx("h2",{className:"confirm-modal-title",children:"Permission Required"}),y.jsx("p",{className:"confirm-modal-message",children:y.jsx("strong",{children:He||de})}),y.jsx("div",{className:"permission-list",children:Ee.map((Ve,qe)=>y.jsxs("div",{className:"permission-item",children:[y.jsx("span",{className:"permission-name",children:Ve.name}),Ve.description&&y.jsx("span",{className:"permission-desc",children:Ve.description})]},qe))}),Me.has(de)&&y.jsx("p",{className:"form-error",children:Me.get(de)}),y.jsxs("div",{className:"permission-actions",children:[y.jsxs("button",{className:"btn btn-primary",disabled:ae.has(de),onClick:()=>Kt(de,"granted"),children:[ae.get(de)==="granted"&&y.jsx("span",{className:"btn-spinner"}),"Allow Once"]}),y.jsxs("button",{className:"btn btn-secondary",disabled:ae.has(de),onClick:()=>Kt(de,"granted_all"),children:[ae.get(de)==="granted_all"&&y.jsx("span",{className:"btn-spinner btn-spinner-current"}),"Allow Always"]})]}),y.jsxs("button",{className:"permission-abort-link",disabled:ae.has(de),onClick:()=>Kt(de,"aborted"),children:[ae.get(de)==="aborted"&&y.jsx("span",{className:"btn-spinner btn-spinner-current"}),"Deny & Abort Task"]})]})},de)),[...st.entries()].map(([de,{questions:Ee,description:He,sessionName:Ve,secret:qe}])=>{const ct=_t.get(de)??new Array(Ee.length).fill("");return y.jsx("div",{className:"confirm-modal-overlay",children:y.jsxs("div",{className:"confirm-modal input-modal",children:[y.jsx("h2",{className:"confirm-modal-title",children:qe?"Password Required":"Input Required"}),Ve&&y.jsx("p",{className:"confirm-modal-subtitle",children:Ve}),He&&y.jsx("p",{className:"confirm-modal-message",children:He}),y.jsx("div",{className:"input-list",children:Ee.map((Xe,Pe)=>y.jsxs("div",{className:"input-item",children:[y.jsx("label",{className:"input-label",children:Xe}),y.jsx("input",{type:qe?"password":"text",autoComplete:qe?"off":void 0,className:"input-field",value:ct[Pe]??"",onChange:We=>{mn(Zt=>{const Qt=new Map(Zt),Rt=[...Qt.get(de)??[]];return Rt[Pe]=We.target.value,Qt.set(de,Rt),Qt})},disabled:ae.has(de),autoFocus:Pe===0})]},Pe))}),qe&&y.jsxs("label",{className:"toggle-label input-save-toggle",children:[y.jsx("input",{type:"checkbox",checked:at.get(de)??!0,disabled:ae.has(de),onChange:Xe=>Cr(Pe=>new Map(Pe).set(de,Xe.target.checked))}),"Save this password"]}),Me.has(de)&&y.jsx("p",{className:"form-error",children:Me.get(de)}),y.jsx("div",{className:"input-actions",children:y.jsxs("button",{className:"btn btn-primary",disabled:ae.has(de)||ct.some(Xe=>!Xe.trim()),onClick:()=>{const Xe=qe?[...ct,at.get(de)??!0?"save":"nosave"]:ct;yt(de,"submit",Xe)},children:[ae.get(de)==="submit"&&y.jsx("span",{className:"btn-spinner"}),"Submit"]})}),y.jsxs("button",{className:"permission-abort-link",disabled:ae.has(de),onClick:()=>yt(de,"aborted",["aborted"]),children:[ae.get(de)==="aborted"&&y.jsx("span",{className:"btn-spinner btn-spinner-current"}),"Abort"]})]})},de)})]}),document.body)]})}const WO=ks("Preferences",{web:()=>Vd(()=>import("./web-BQcwgjLy.js"),[]).then(e=>new e.PreferencesWeb)}),Al=!!window.__PALMIER_SERVE__&&(window.location.hostname==="localhost"||window.location.hostname==="127.0.0.1"),$b=Jn.isNativePlatform();function e4(){const[e,t]=E.useState(""),[r,s]=E.useState(!0),[l,o]=E.useState(!1),[c,f]=E.useState(null),{addPairedHost:d,pairedHosts:m}=Zi(),b=Gr();async function g(){const x=e.trim().toUpperCase();if(!x){f("Enter a pairing code.");return}o(!0),f(null);try{let v;if(Al){const R=await fetch("/pair",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({code:x,label:navigator.userAgent})});if(!R.ok){const M=await R.json().catch(()=>({error:"Connection failed"}));throw new Error(M.error||`HTTP ${R.status}`)}v=await R.json()}else{const R=await fetch(`${Bu}/api/config`);if(!R.ok)throw new Error("Failed to fetch server config");const M=await R.json();if(!M.natsWsUrl)throw new Error("Server has no NATS WebSocket URL configured");const P=await Dx({servers:M.natsWsUrl,authenticator:Ex(M.natsJwt,new TextEncoder().encode(M.natsNkeySeed))}),I=Ru(),ue=`pair.${x}`,q=await P.request(ue,I.encode(JSON.stringify({label:navigator.userAgent})),{timeout:1e4});v=JSON.parse(I.decode(q.data)),await P.close()}const S={hostId:v.hostId,clientToken:v.clientToken,directUrl:Al?window.location.origin:void 0,...v.hostName?{name:v.hostName}:{}};if(d(S),Jn.isNativePlatform()&&On){await WO.set({key:"hostId",value:v.hostId});try{const{token:R}=await On.getFcmToken();await fetch(`${Bu}/api/fcm/register`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({hostId:v.hostId,fcmToken:R})})}catch(R){console.warn("FCM token registration failed:",R)}}const j=`/hosts/${encodeURIComponent(v.hostId)}`;b($b&&r?`${j}/pair/setup`:j)}catch(v){const S=v instanceof Error?v.message:String(v);S.includes("timeout")||S.includes("TIMEOUT")||S.includes("503")||S.toLowerCase().includes("no responders")?f("Code not found or expired. Check the code and try again."):f(S)}finally{o(!1)}}return y.jsx("div",{className:"pair-page",children:y.jsxs("div",{className:"pair-card",children:[y.jsxs("div",{className:"pair-header",children:[y.jsx("h1",{className:"pair-title",children:Al?"Pair":"Pair with Host"}),y.jsx("p",{className:"pair-subtitle",children:Al?"Enter the pairing code shown in your terminal.":"Connect this device to a Palmier host"})]}),!Al&&y.jsxs("div",{className:"pair-instructions",children:[y.jsxs("div",{className:"pair-instruction-block",children:[y.jsx("h3",{className:"pair-instruction-heading",children:"Setting up a new host?"}),y.jsxs("ol",{className:"pair-steps",children:[y.jsxs("li",{children:["Install Palmier on your host machine.",y.jsx("span",{className:"pair-platform-label",children:"Linux / macOS:"}),y.jsx("code",{className:"pair-command",children:"curl -fsSL https://palmier.me/install.sh | bash"}),y.jsx("span",{className:"pair-platform-label",children:"Windows (PowerShell):"}),y.jsx("code",{className:"pair-command",children:"irm https://palmier.me/install.ps1 | iex"})]}),y.jsxs("li",{children:["Run the setup wizard:",y.jsx("code",{className:"pair-command",children:"palmier init"})]}),y.jsx("li",{children:"A pairing code will display automatically"})]})]}),y.jsx("div",{className:"pair-instruction-divider"}),y.jsxs("div",{className:"pair-instruction-block",children:[y.jsx("h3",{className:"pair-instruction-heading",children:"Pairing an existing host?"}),y.jsxs("ol",{className:"pair-steps",children:[y.jsxs("li",{children:["Run ",y.jsx("code",{children:"palmier pair"})," on the host machine"]}),y.jsx("li",{children:"Enter the 6-character code below"})]})]})]}),y.jsxs("div",{className:"pair-form",children:[y.jsxs("label",{className:"form-label",htmlFor:"pair-code",children:["Pairing code",y.jsx("input",{id:"pair-code",type:"text",maxLength:6,value:e,onChange:x=>t(x.target.value.toUpperCase()),placeholder:"A7K9M2",className:"form-input form-input-mono pair-code-input",autoFocus:!0,autoComplete:"off",disabled:l})]}),$b&&y.jsxs("label",{className:"pair-checkbox",children:[y.jsx("input",{type:"checkbox",checked:r,onChange:x=>s(x.target.checked),disabled:l}),y.jsxs("span",{className:"pair-checkbox-text",children:[y.jsx("span",{className:"pair-checkbox-title",children:"Link the host to this device"}),y.jsx("span",{className:"pair-checkbox-hint",children:r?"The host will use this device for SMS, contacts, calendar, location, and alarms. Only one device can be linked to the host.":"This device won't provide SMS, contacts, calendar, location, or alarms to the host. You can link it later from the menu."})]})]}),c&&y.jsx("p",{className:"pair-error",children:c}),y.jsxs("button",{className:"btn btn-primary btn-full",onClick:g,disabled:l||!e.trim(),children:[l&&y.jsx("span",{className:"btn-spinner"}),l?"Pairing...":"Pair"]}),m.length>0&&y.jsx("button",{className:"btn btn-secondary btn-full",onClick:()=>b("/"),disabled:l,children:"Cancel"}),y.jsxs("p",{className:"pair-consent",children:["By pairing, you agree to our"," ",y.jsx("a",{href:"https://www.palmier.me/terms",target:"_blank",rel:"noopener noreferrer",children:"Terms of Service"})," and"," ",y.jsx("a",{href:"https://www.palmier.me/privacy",target:"_blank",rel:"noopener noreferrer",children:"Privacy Policy"}),"."]})]})]})})}function t4(){const e=Gr(),{connected:t,request:r,activeHost:s}=xi(),{setHostLanUrl:l,pairedHosts:o}=Zi(),c=o.length<=1,[f,d]=E.useState("loading"),[m,b]=E.useState(null),[g,x]=E.useState(null);function v(){e(`/hosts/${encodeURIComponent(s.hostId)}`,{replace:!0})}E.useEffect(()=>{if(!t||f!=="loading")return;let P=!1;return r("host.info").catch(()=>({})).then(I=>{if(P)return;l(s.hostId,I.lan_url??void 0);const ue=I.linked_client_token??null;b(ue);const q=!!ue&&ue!==s.clientToken;d(q?"confirming":"linking")}),()=>{P=!0}},[t,f,s,r,l]),E.useEffect(()=>{if(f!=="linking")return;let P=!1;return(async()=>{try{if(On){const{token:I}=await On.getFcmToken();if(!I)throw new Error("Could not read FCM token");await r("device.link",{fcmToken:I})}if(P)return;c?d("wizard"):v()}catch(I){if(P)return;x(I instanceof Error?I.message:String(I)),d("linkError")}})(),()=>{P=!0}},[f]);function S(){d("linking")}function j(){v()}function R(){x(null),d("linking")}const M=f==="confirming"&&pi.createPortal(y.jsx("div",{className:"confirm-modal-overlay",onClick:j,children:y.jsxs("div",{className:"confirm-modal",onClick:P=>P.stopPropagation(),children:[y.jsx("h2",{className:"confirm-modal-title",children:"Link the host to this device?"}),y.jsx("p",{className:"confirm-modal-message",children:"Another device is already linked to this host. Only one device can be linked to the host — switching will disable those capabilities on the currently linked device."}),y.jsxs("div",{className:"confirm-modal-actions",children:[y.jsx("button",{className:"btn btn-secondary",onClick:j,children:"Cancel"}),y.jsx("button",{className:"btn btn-primary",onClick:S,children:"Link"})]})]})}),document.body);if(f==="loading"||f==="confirming"||f==="linking"||f==="linkError"){const P=c,I=f==="loading"||f==="confirming"||f==="linking";return y.jsxs("div",{className:"pair-setup",children:[y.jsxs("div",{className:"pair-setup-inner",children:[P&&y.jsx("h1",{className:"pair-setup-title",children:"Device Capabilities"}),y.jsxs("div",{className:"pair-setup-loading",children:[I&&y.jsx("span",{className:"spinner spinner-lg"}),f==="loading"&&y.jsx("span",{children:"Connecting to host…"}),f==="confirming"&&y.jsx("span",{children:"Awaiting confirmation…"}),f==="linking"&&y.jsx("span",{children:"Linking device…"}),f==="linkError"&&y.jsxs(y.Fragment,{children:[y.jsx("p",{className:"pair-error",children:g}),y.jsx("button",{className:"btn btn-primary",onClick:R,children:"Retry"}),y.jsx("button",{className:"btn btn-secondary",onClick:v,children:"Skip linking"})]})]})]}),M]})}return y.jsx("div",{className:"pair-setup",children:y.jsxs("div",{className:"pair-setup-inner",children:[y.jsx("h1",{className:"pair-setup-title",children:"Device Capabilities"}),y.jsx("p",{className:"pair-setup-description",children:"Choose what the host can use this device for. You can change these later from the menu."}),y.jsx(Ix,{}),y.jsx("div",{className:"pair-setup-actions",children:y.jsx("button",{className:"btn btn-primary btn-full",onClick:v,children:"Finish"})})]})})}function n4(){const e=Gr();return E.useEffect(()=>{if(!On)return;const t=On.addListener("deepLink",({path:r})=>e(r));return()=>{t.then(r=>r.remove())}},[e]),null}function r4(){const{pairedHosts:e,lastHostId:t}=Zi();if(e.length===0)return y.jsx(Bl,{to:"/pair",replace:!0});const r=e.find(s=>s.hostId===t)??e[0];return y.jsx(Bl,{to:`/hosts/${encodeURIComponent(r.hostId)}`,replace:!0})}function i4(){const{hostId:e}=Yu(),{pairedHosts:t,setLastHostId:r}=Zi(),s=t.find(l=>l.hostId===e)??null;return E.useEffect(()=>{s&&r(s.hostId)},[s==null?void 0:s.hostId,r]),s?y.jsx(EE,{activeHost:s,children:y.jsxs(ax,{children:[y.jsx(Rr,{index:!0,element:y.jsx(wu,{},e)}),y.jsx(Rr,{path:"tasks",element:y.jsx(wu,{},e)}),y.jsx(Rr,{path:"runs/:taskId",element:y.jsx(wu,{},e)}),y.jsx(Rr,{path:"runs/:taskId/:runId",element:y.jsx(wu,{},e)}),y.jsx(Rr,{path:"pair/setup",element:y.jsx(t4,{})}),y.jsx(Rr,{path:"*",element:y.jsx(Bl,{to:".",replace:!0})})]})},`${s.hostId}|${s.clientToken}`):y.jsx(Bl,{to:"/",replace:!0})}function s4(){return y.jsxs(X_,{children:[y.jsx(n4,{}),y.jsxs(ax,{children:[y.jsx(Rr,{path:"/",element:y.jsx(r4,{})}),y.jsx(Rr,{path:"/pair",element:y.jsx(e4,{})}),y.jsx(Rr,{path:"/hosts/:hostId/*",element:y.jsx(i4,{})}),y.jsx(Rr,{path:"*",element:y.jsx(Bl,{to:"/",replace:!0})})]})]})}gS.createRoot(document.getElementById("root")).render(y.jsx(E.StrictMode,{children:y.jsx(z_,{children:y.jsx(s4,{})})}));export{$d as W};
|
|
121
|
+
`))}function d(v,S,j,R){const M=j.enter("tableCell"),P=j.enter("phrasing"),I=j.containerPhrasing(v,{...R,before:o,after:o});return P(),M(),I}function m(v,S){return g3(v,{align:S,alignDelimiters:s,padding:r,stringLength:l})}function b(v,S,j){const R=v.children;let M=-1;const P=[],I=S.enter("table");for(;++M<R.length;)P[M]=g(R[M],S,j);return I(),P}function g(v,S,j){const R=v.children;let M=-1;const P=[],I=S.enter("tableRow");for(;++M<R.length;)P[M]=d(R[M],v,S,j);return I(),P}function x(v,S,j){let R=I1.inlineCode(v,S,j);return j.stack.includes("tableCell")&&(R=R.replace(/\|/g,"\\$&")),R}}function rO(){return{exit:{taskListCheckValueChecked:Ib,taskListCheckValueUnchecked:Ib,paragraph:sO}}}function iO(){return{unsafe:[{atBreak:!0,character:"-",after:"[:|-]"}],handlers:{listItem:aO}}}function Ib(e){const t=this.stack[this.stack.length-2];t.type,t.checked=e.type==="taskListCheckValueChecked"}function sO(e){const t=this.stack[this.stack.length-2];if(t&&t.type==="listItem"&&typeof t.checked=="boolean"){const r=this.stack[this.stack.length-1];r.type;const s=r.children[0];if(s&&s.type==="text"){const l=t.children;let o=-1,c;for(;++o<l.length;){const f=l[o];if(f.type==="paragraph"){c=f;break}}c===r&&(s.value=s.value.slice(1),s.value.length===0?r.children.shift():r.position&&s.position&&typeof s.position.start.offset=="number"&&(s.position.start.column++,s.position.start.offset++,r.position.start=Object.assign({},s.position.start)))}}this.exit(e)}function aO(e,t,r,s){const l=e.children[0],o=typeof e.checked=="boolean"&&l&&l.type==="paragraph",c="["+(e.checked?"x":" ")+"] ",f=r.createTracker(s);o&&f.move(c);let d=I1.listItem(e,t,r,{...s,...f.current()});return o&&(d=d.replace(/^(?:[*+-]|\d+\.)([\r\n]| {1,3})/,m)),d;function m(b){return b+c}}function lO(){return[BT(),a3(),c3(),K3(),rO()]}function oO(e){return{extensions:[HT(),l3(e),f3(),nO(e),iO()]}}const uO={tokenize:pO,partial:!0},F1={tokenize:gO,partial:!0},$1={tokenize:yO,partial:!0},V1={tokenize:bO,partial:!0},cO={tokenize:xO,partial:!0},Y1={name:"wwwAutolink",tokenize:dO,previous:J1},G1={name:"protocolAutolink",tokenize:mO,previous:X1},vi={name:"emailAutolink",tokenize:hO,previous:K1},Jr={};function fO(){return{text:Jr}}let vs=48;for(;vs<123;)Jr[vs]=vi,vs++,vs===58?vs=65:vs===91&&(vs=97);Jr[43]=vi;Jr[45]=vi;Jr[46]=vi;Jr[95]=vi;Jr[72]=[vi,G1];Jr[104]=[vi,G1];Jr[87]=[vi,Y1];Jr[119]=[vi,Y1];function hO(e,t,r){const s=this;let l,o;return c;function c(g){return!jd(g)||!K1.call(s,s.previous)||fm(s.events)?r(g):(e.enter("literalAutolink"),e.enter("literalAutolinkEmail"),f(g))}function f(g){return jd(g)?(e.consume(g),f):g===64?(e.consume(g),d):r(g)}function d(g){return g===46?e.check(cO,b,m)(g):g===45||g===95||Rn(g)?(o=!0,e.consume(g),d):b(g)}function m(g){return e.consume(g),l=!0,d}function b(g){return o&&l&&Pn(s.previous)?(e.exit("literalAutolinkEmail"),e.exit("literalAutolink"),t(g)):r(g)}}function dO(e,t,r){const s=this;return l;function l(c){return c!==87&&c!==119||!J1.call(s,s.previous)||fm(s.events)?r(c):(e.enter("literalAutolink"),e.enter("literalAutolinkWww"),e.check(uO,e.attempt(F1,e.attempt($1,o),r),r)(c))}function o(c){return e.exit("literalAutolinkWww"),e.exit("literalAutolink"),t(c)}}function mO(e,t,r){const s=this;let l="",o=!1;return c;function c(g){return(g===72||g===104)&&X1.call(s,s.previous)&&!fm(s.events)?(e.enter("literalAutolink"),e.enter("literalAutolinkHttp"),l+=String.fromCodePoint(g),e.consume(g),f):r(g)}function f(g){if(Pn(g)&&l.length<5)return l+=String.fromCodePoint(g),e.consume(g),f;if(g===58){const x=l.toLowerCase();if(x==="http"||x==="https")return e.consume(g),d}return r(g)}function d(g){return g===47?(e.consume(g),o?m:(o=!0,d)):r(g)}function m(g){return g===null||Hu(g)||Dt(g)||_s(g)||Wu(g)?r(g):e.attempt(F1,e.attempt($1,b),r)(g)}function b(g){return e.exit("literalAutolinkHttp"),e.exit("literalAutolink"),t(g)}}function pO(e,t,r){let s=0;return l;function l(c){return(c===87||c===119)&&s<3?(s++,e.consume(c),l):c===46&&s===3?(e.consume(c),o):r(c)}function o(c){return c===null?r(c):t(c)}}function gO(e,t,r){let s,l,o;return c;function c(m){return m===46||m===95?e.check(V1,d,f)(m):m===null||Dt(m)||_s(m)||m!==45&&Wu(m)?d(m):(o=!0,e.consume(m),c)}function f(m){return m===95?s=!0:(l=s,s=void 0),e.consume(m),c}function d(m){return l||s||!o?r(m):t(m)}}function yO(e,t){let r=0,s=0;return l;function l(c){return c===40?(r++,e.consume(c),l):c===41&&s<r?o(c):c===33||c===34||c===38||c===39||c===41||c===42||c===44||c===46||c===58||c===59||c===60||c===63||c===93||c===95||c===126?e.check(V1,t,o)(c):c===null||Dt(c)||_s(c)?t(c):(e.consume(c),l)}function o(c){return c===41&&s++,e.consume(c),l}}function bO(e,t,r){return s;function s(f){return f===33||f===34||f===39||f===41||f===42||f===44||f===46||f===58||f===59||f===63||f===95||f===126?(e.consume(f),s):f===38?(e.consume(f),o):f===93?(e.consume(f),l):f===60||f===null||Dt(f)||_s(f)?t(f):r(f)}function l(f){return f===null||f===40||f===91||Dt(f)||_s(f)?t(f):s(f)}function o(f){return Pn(f)?c(f):r(f)}function c(f){return f===59?(e.consume(f),s):Pn(f)?(e.consume(f),c):r(f)}}function xO(e,t,r){return s;function s(o){return e.consume(o),l}function l(o){return Rn(o)?r(o):t(o)}}function J1(e){return e===null||e===40||e===42||e===95||e===91||e===93||e===126||Dt(e)}function X1(e){return!Pn(e)}function K1(e){return!(e===47||jd(e))}function jd(e){return e===43||e===45||e===46||e===95||Rn(e)}function fm(e){let t=e.length,r=!1;for(;t--;){const s=e[t][1];if((s.type==="labelLink"||s.type==="labelImage")&&!s._balanced){r=!0;break}if(s._gfmAutolinkLiteralWalkedInto){r=!1;break}}return e.length>0&&!r&&(e[e.length-1][1]._gfmAutolinkLiteralWalkedInto=!0),r}const vO={tokenize:jO,partial:!0};function wO(){return{document:{91:{name:"gfmFootnoteDefinition",tokenize:EO,continuation:{tokenize:CO},exit:AO}},text:{91:{name:"gfmFootnoteCall",tokenize:kO},93:{name:"gfmPotentialFootnoteCall",add:"after",tokenize:SO,resolveTo:_O}}}}function SO(e,t,r){const s=this;let l=s.events.length;const o=s.parser.gfmFootnotes||(s.parser.gfmFootnotes=[]);let c;for(;l--;){const d=s.events[l][1];if(d.type==="labelImage"){c=d;break}if(d.type==="gfmFootnoteCall"||d.type==="labelLink"||d.type==="label"||d.type==="image"||d.type==="link")break}return f;function f(d){if(!c||!c._balanced)return r(d);const m=Lr(s.sliceSerialize({start:c.end,end:s.now()}));return m.codePointAt(0)!==94||!o.includes(m.slice(1))?r(d):(e.enter("gfmFootnoteCallLabelMarker"),e.consume(d),e.exit("gfmFootnoteCallLabelMarker"),t(d))}}function _O(e,t){let r=e.length;for(;r--;)if(e[r][1].type==="labelImage"&&e[r][0]==="enter"){e[r][1];break}e[r+1][1].type="data",e[r+3][1].type="gfmFootnoteCallLabelMarker";const s={type:"gfmFootnoteCall",start:Object.assign({},e[r+3][1].start),end:Object.assign({},e[e.length-1][1].end)},l={type:"gfmFootnoteCallMarker",start:Object.assign({},e[r+3][1].end),end:Object.assign({},e[r+3][1].end)};l.end.column++,l.end.offset++,l.end._bufferIndex++;const o={type:"gfmFootnoteCallString",start:Object.assign({},l.end),end:Object.assign({},e[e.length-1][1].start)},c={type:"chunkString",contentType:"string",start:Object.assign({},o.start),end:Object.assign({},o.end)},f=[e[r+1],e[r+2],["enter",s,t],e[r+3],e[r+4],["enter",l,t],["exit",l,t],["enter",o,t],["enter",c,t],["exit",c,t],["exit",o,t],e[e.length-2],e[e.length-1],["exit",s,t]];return e.splice(r,e.length-r+1,...f),e}function kO(e,t,r){const s=this,l=s.parser.gfmFootnotes||(s.parser.gfmFootnotes=[]);let o=0,c;return f;function f(g){return e.enter("gfmFootnoteCall"),e.enter("gfmFootnoteCallLabelMarker"),e.consume(g),e.exit("gfmFootnoteCallLabelMarker"),d}function d(g){return g!==94?r(g):(e.enter("gfmFootnoteCallMarker"),e.consume(g),e.exit("gfmFootnoteCallMarker"),e.enter("gfmFootnoteCallString"),e.enter("chunkString").contentType="string",m)}function m(g){if(o>999||g===93&&!c||g===null||g===91||Dt(g))return r(g);if(g===93){e.exit("chunkString");const x=e.exit("gfmFootnoteCallString");return l.includes(Lr(s.sliceSerialize(x)))?(e.enter("gfmFootnoteCallLabelMarker"),e.consume(g),e.exit("gfmFootnoteCallLabelMarker"),e.exit("gfmFootnoteCall"),t):r(g)}return Dt(g)||(c=!0),o++,e.consume(g),g===92?b:m}function b(g){return g===91||g===92||g===93?(e.consume(g),o++,m):m(g)}}function EO(e,t,r){const s=this,l=s.parser.gfmFootnotes||(s.parser.gfmFootnotes=[]);let o,c=0,f;return d;function d(S){return e.enter("gfmFootnoteDefinition")._container=!0,e.enter("gfmFootnoteDefinitionLabel"),e.enter("gfmFootnoteDefinitionLabelMarker"),e.consume(S),e.exit("gfmFootnoteDefinitionLabelMarker"),m}function m(S){return S===94?(e.enter("gfmFootnoteDefinitionMarker"),e.consume(S),e.exit("gfmFootnoteDefinitionMarker"),e.enter("gfmFootnoteDefinitionLabelString"),e.enter("chunkString").contentType="string",b):r(S)}function b(S){if(c>999||S===93&&!f||S===null||S===91||Dt(S))return r(S);if(S===93){e.exit("chunkString");const j=e.exit("gfmFootnoteDefinitionLabelString");return o=Lr(s.sliceSerialize(j)),e.enter("gfmFootnoteDefinitionLabelMarker"),e.consume(S),e.exit("gfmFootnoteDefinitionLabelMarker"),e.exit("gfmFootnoteDefinitionLabel"),x}return Dt(S)||(f=!0),c++,e.consume(S),S===92?g:b}function g(S){return S===91||S===92||S===93?(e.consume(S),c++,b):b(S)}function x(S){return S===58?(e.enter("definitionMarker"),e.consume(S),e.exit("definitionMarker"),l.includes(o)||l.push(o),pt(e,v,"gfmFootnoteDefinitionWhitespace")):r(S)}function v(S){return t(S)}}function CO(e,t,r){return e.check(Ql,t,e.attempt(vO,t,r))}function AO(e){e.exit("gfmFootnoteDefinition")}function jO(e,t,r){const s=this;return pt(e,l,"gfmFootnoteDefinitionIndent",5);function l(o){const c=s.events[s.events.length-1];return c&&c[1].type==="gfmFootnoteDefinitionIndent"&&c[2].sliceSerialize(c[1],!0).length===4?t(o):r(o)}}function NO(e){let r=(e||{}).singleTilde;const s={name:"strikethrough",tokenize:o,resolveAll:l};return r==null&&(r=!0),{text:{126:s},insideSpan:{null:[s]},attentionMarkers:{null:[126]}};function l(c,f){let d=-1;for(;++d<c.length;)if(c[d][0]==="enter"&&c[d][1].type==="strikethroughSequenceTemporary"&&c[d][1]._close){let m=d;for(;m--;)if(c[m][0]==="exit"&&c[m][1].type==="strikethroughSequenceTemporary"&&c[m][1]._open&&c[d][1].end.offset-c[d][1].start.offset===c[m][1].end.offset-c[m][1].start.offset){c[d][1].type="strikethroughSequence",c[m][1].type="strikethroughSequence";const b={type:"strikethrough",start:Object.assign({},c[m][1].start),end:Object.assign({},c[d][1].end)},g={type:"strikethroughText",start:Object.assign({},c[m][1].end),end:Object.assign({},c[d][1].start)},x=[["enter",b,f],["enter",c[m][1],f],["exit",c[m][1],f],["enter",g,f]],v=f.parser.constructs.insideSpan.null;v&&ur(x,x.length,0,ec(v,c.slice(m+1,d),f)),ur(x,x.length,0,[["exit",g,f],["enter",c[d][1],f],["exit",c[d][1],f],["exit",b,f]]),ur(c,m-1,d-m+3,x),d=m+x.length-2;break}}for(d=-1;++d<c.length;)c[d][1].type==="strikethroughSequenceTemporary"&&(c[d][1].type="data");return c}function o(c,f,d){const m=this.previous,b=this.events;let g=0;return x;function x(S){return m===126&&b[b.length-1][1].type!=="characterEscape"?d(S):(c.enter("strikethroughSequenceTemporary"),v(S))}function v(S){const j=ka(m);if(S===126)return g>1?d(S):(c.consume(S),g++,v);if(g<2&&!r)return d(S);const R=c.exit("strikethroughSequenceTemporary"),M=ka(S);return R._open=!M||M===2&&!!j,R._close=!j||j===2&&!!M,f(S)}}}class TO{constructor(){this.map=[]}add(t,r,s){OO(this,t,r,s)}consume(t){if(this.map.sort(function(o,c){return o[0]-c[0]}),this.map.length===0)return;let r=this.map.length;const s=[];for(;r>0;)r-=1,s.push(t.slice(this.map[r][0]+this.map[r][1]),this.map[r][2]),t.length=this.map[r][0];s.push(t.slice()),t.length=0;let l=s.pop();for(;l;){for(const o of l)t.push(o);l=s.pop()}this.map.length=0}}function OO(e,t,r,s){let l=0;if(!(r===0&&s.length===0)){for(;l<e.map.length;){if(e.map[l][0]===t){e.map[l][1]+=r,e.map[l][2].push(...s);return}l+=1}e.map.push([t,r,s])}}function RO(e,t){let r=!1;const s=[];for(;t<e.length;){const l=e[t];if(r){if(l[0]==="enter")l[1].type==="tableContent"&&s.push(e[t+1][1].type==="tableDelimiterMarker"?"left":"none");else if(l[1].type==="tableContent"){if(e[t-1][1].type==="tableDelimiterMarker"){const o=s.length-1;s[o]=s[o]==="left"?"center":"right"}}else if(l[1].type==="tableDelimiterRow")break}else l[0]==="enter"&&l[1].type==="tableDelimiterRow"&&(r=!0);t+=1}return s}function MO(){return{flow:{null:{name:"table",tokenize:DO,resolveAll:LO}}}}function DO(e,t,r){const s=this;let l=0,o=0,c;return f;function f(L){let J=s.events.length-1;for(;J>-1;){const le=s.events[J][1].type;if(le==="lineEnding"||le==="linePrefix")J--;else break}const $=J>-1?s.events[J][1].type:null,he=$==="tableHead"||$==="tableRow"?N:d;return he===N&&s.parser.lazy[s.now().line]?r(L):he(L)}function d(L){return e.enter("tableHead"),e.enter("tableRow"),m(L)}function m(L){return L===124||(c=!0,o+=1),b(L)}function b(L){return L===null?r(L):Fe(L)?o>1?(o=0,s.interrupt=!0,e.exit("tableRow"),e.enter("lineEnding"),e.consume(L),e.exit("lineEnding"),v):r(L):ut(L)?pt(e,b,"whitespace")(L):(o+=1,c&&(c=!1,l+=1),L===124?(e.enter("tableCellDivider"),e.consume(L),e.exit("tableCellDivider"),c=!0,b):(e.enter("data"),g(L)))}function g(L){return L===null||L===124||Dt(L)?(e.exit("data"),b(L)):(e.consume(L),L===92?x:g)}function x(L){return L===92||L===124?(e.consume(L),g):g(L)}function v(L){return s.interrupt=!1,s.parser.lazy[s.now().line]?r(L):(e.enter("tableDelimiterRow"),c=!1,ut(L)?pt(e,S,"linePrefix",s.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(L):S(L))}function S(L){return L===45||L===58?R(L):L===124?(c=!0,e.enter("tableCellDivider"),e.consume(L),e.exit("tableCellDivider"),j):q(L)}function j(L){return ut(L)?pt(e,R,"whitespace")(L):R(L)}function R(L){return L===58?(o+=1,c=!0,e.enter("tableDelimiterMarker"),e.consume(L),e.exit("tableDelimiterMarker"),M):L===45?(o+=1,M(L)):L===null||Fe(L)?ue(L):q(L)}function M(L){return L===45?(e.enter("tableDelimiterFiller"),P(L)):q(L)}function P(L){return L===45?(e.consume(L),P):L===58?(c=!0,e.exit("tableDelimiterFiller"),e.enter("tableDelimiterMarker"),e.consume(L),e.exit("tableDelimiterMarker"),I):(e.exit("tableDelimiterFiller"),I(L))}function I(L){return ut(L)?pt(e,ue,"whitespace")(L):ue(L)}function ue(L){return L===124?S(L):L===null||Fe(L)?!c||l!==o?q(L):(e.exit("tableDelimiterRow"),e.exit("tableHead"),t(L)):q(L)}function q(L){return r(L)}function N(L){return e.enter("tableRow"),ee(L)}function ee(L){return L===124?(e.enter("tableCellDivider"),e.consume(L),e.exit("tableCellDivider"),ee):L===null||Fe(L)?(e.exit("tableRow"),t(L)):ut(L)?pt(e,ee,"whitespace")(L):(e.enter("data"),G(L))}function G(L){return L===null||L===124||Dt(L)?(e.exit("data"),ee(L)):(e.consume(L),L===92?B:G)}function B(L){return L===92||L===124?(e.consume(L),G):G(L)}}function LO(e,t){let r=-1,s=!0,l=0,o=[0,0,0,0],c=[0,0,0,0],f=!1,d=0,m,b,g;const x=new TO;for(;++r<e.length;){const v=e[r],S=v[1];v[0]==="enter"?S.type==="tableHead"?(f=!1,d!==0&&(Fb(x,t,d,m,b),b=void 0,d=0),m={type:"table",start:Object.assign({},S.start),end:Object.assign({},S.end)},x.add(r,0,[["enter",m,t]])):S.type==="tableRow"||S.type==="tableDelimiterRow"?(s=!0,g=void 0,o=[0,0,0,0],c=[0,r+1,0,0],f&&(f=!1,b={type:"tableBody",start:Object.assign({},S.start),end:Object.assign({},S.end)},x.add(r,0,[["enter",b,t]])),l=S.type==="tableDelimiterRow"?2:b?3:1):l&&(S.type==="data"||S.type==="tableDelimiterMarker"||S.type==="tableDelimiterFiller")?(s=!1,c[2]===0&&(o[1]!==0&&(c[0]=c[1],g=xu(x,t,o,l,void 0,g),o=[0,0,0,0]),c[2]=r)):S.type==="tableCellDivider"&&(s?s=!1:(o[1]!==0&&(c[0]=c[1],g=xu(x,t,o,l,void 0,g)),o=c,c=[o[1],r,0,0])):S.type==="tableHead"?(f=!0,d=r):S.type==="tableRow"||S.type==="tableDelimiterRow"?(d=r,o[1]!==0?(c[0]=c[1],g=xu(x,t,o,l,r,g)):c[1]!==0&&(g=xu(x,t,c,l,r,g)),l=0):l&&(S.type==="data"||S.type==="tableDelimiterMarker"||S.type==="tableDelimiterFiller")&&(c[3]=r)}for(d!==0&&Fb(x,t,d,m,b),x.consume(t.events),r=-1;++r<t.events.length;){const v=t.events[r];v[0]==="enter"&&v[1].type==="table"&&(v[1]._align=RO(t.events,r))}return e}function xu(e,t,r,s,l,o){const c=s===1?"tableHeader":s===2?"tableDelimiter":"tableData",f="tableContent";r[0]!==0&&(o.end=Object.assign({},ca(t.events,r[0])),e.add(r[0],0,[["exit",o,t]]));const d=ca(t.events,r[1]);if(o={type:c,start:Object.assign({},d),end:Object.assign({},d)},e.add(r[1],0,[["enter",o,t]]),r[2]!==0){const m=ca(t.events,r[2]),b=ca(t.events,r[3]),g={type:f,start:Object.assign({},m),end:Object.assign({},b)};if(e.add(r[2],0,[["enter",g,t]]),s!==2){const x=t.events[r[2]],v=t.events[r[3]];if(x[1].end=Object.assign({},v[1].end),x[1].type="chunkText",x[1].contentType="text",r[3]>r[2]+1){const S=r[2]+1,j=r[3]-r[2]-1;e.add(S,j,[])}}e.add(r[3]+1,0,[["exit",g,t]])}return l!==void 0&&(o.end=Object.assign({},ca(t.events,l)),e.add(l,0,[["exit",o,t]]),o=void 0),o}function Fb(e,t,r,s,l){const o=[],c=ca(t.events,r);l&&(l.end=Object.assign({},c),o.push(["exit",l,t])),s.end=Object.assign({},c),o.push(["exit",s,t]),e.add(r+1,0,o)}function ca(e,t){const r=e[t],s=r[0]==="enter"?"start":"end";return r[1][s]}const zO={name:"tasklistCheck",tokenize:PO};function UO(){return{text:{91:zO}}}function PO(e,t,r){const s=this;return l;function l(d){return s.previous!==null||!s._gfmTasklistFirstContentOfListItem?r(d):(e.enter("taskListCheck"),e.enter("taskListCheckMarker"),e.consume(d),e.exit("taskListCheckMarker"),o)}function o(d){return Dt(d)?(e.enter("taskListCheckValueUnchecked"),e.consume(d),e.exit("taskListCheckValueUnchecked"),c):d===88||d===120?(e.enter("taskListCheckValueChecked"),e.consume(d),e.exit("taskListCheckValueChecked"),c):r(d)}function c(d){return d===93?(e.enter("taskListCheckMarker"),e.consume(d),e.exit("taskListCheckMarker"),e.exit("taskListCheck"),f):r(d)}function f(d){return Fe(d)?t(d):ut(d)?e.check({tokenize:BO},t,r)(d):r(d)}}function BO(e,t,r){return pt(e,s,"whitespace");function s(l){return l===null?r(l):t(l)}}function HO(e){return i1([fO(),wO(),NO(e),MO(),UO()])}const qO={};function IO(e){const t=this,r=e||qO,s=t.data(),l=s.micromarkExtensions||(s.micromarkExtensions=[]),o=s.fromMarkdownExtensions||(s.fromMarkdownExtensions=[]),c=s.toMarkdownExtensions||(s.toMarkdownExtensions=[]);l.push(HO(r)),o.push(lO()),c.push(oO(r))}function FO(e){A1(e,[/\r?\n|\r/g,$O])}function $O(){return{type:"break"}}function VO(){return function(e){FO(e)}}const hm=E.createContext(null);function Q1(e,t){const r=C1(t);return e&&r!==null?jT(r,e.baseFile):null}function YO({node:e,href:t,...r}){const s=E.useContext(hm),l=Q1(s,t);return!s||l===null?y.jsx("a",{...r,href:t,target:"_blank",rel:"noopener noreferrer"}):y.jsx("a",{...r,href:t,className:"md-file-link",onClick:o=>{o.preventDefault(),s.openFile(l)}})}function GO({node:e,src:t,alt:r,...s}){const l=E.useContext(hm),o=Q1(l,typeof t=="string"?t:void 0),[c,f]=E.useState(),[d,m]=E.useState(!1),b=l==null?void 0:l.loadFile;return E.useEffect(()=>{if(o===null||!b)return;let g=!1,x;return m(!1),b(o).then(v=>{g||(x=URL.createObjectURL(v),f(x))}).catch(()=>{g||m(!0)}),()=>{g=!0,x&&URL.revokeObjectURL(x)}},[o,b]),!l||o===null?y.jsx("img",{...s,src:t,alt:r}):d?y.jsx("span",{className:"md-image-missing",children:r||o}):c?y.jsx("img",{...s,src:c,alt:r,className:"md-file-image",onClick:()=>l.openFile(o)}):y.jsx("span",{className:"md-image-loading skeleton-line"})}const JO={a:YO,img:GO};function Z1({content:e,files:t,baseFile:r}){const s=E.useMemo(()=>({openFile:t.openFile,loadFile:t.loadFile,baseFile:r}),[t.openFile,t.loadFile,r]);return y.jsx(hm.Provider,{value:s,children:y.jsx(wT,{remarkPlugins:[IO,VO],urlTransform:CT,components:JO,children:e})})}function XO({filePath:e,files:t,onClose:r}){const[s,l]=E.useState(null),[o,c]=E.useState(null),{loadFile:f}=t;E.useEffect(()=>{let b=!1,g;return l(null),c(null),(async()=>{try{const x=await f(e),v=MT(x.type),S={kind:v,size:x.size};if(v==="markdown"||v==="text"||v==="html"?S.text=await x.text():(g=URL.createObjectURL(x),S.objectUrl=g),b){g&&URL.revokeObjectURL(g);return}l(S)}catch(x){b||c(x instanceof Error?x.message:"Failed to load file.")}})(),()=>{b=!0,g&&URL.revokeObjectURL(g)}},[e,f]);const d=NT(e);function m(){if(o)return y.jsx("p",{className:"file-viewer-message",children:o});if(!s)return y.jsxs("div",{className:"file-viewer-loading",children:[y.jsx("div",{className:"skeleton-line",style:{width:"40%"}}),y.jsx("div",{className:"skeleton-line",style:{width:"100%",height:"8rem"}})]});switch(s.kind){case"markdown":return y.jsx(Z1,{content:s.text??"",files:t,baseFile:e});case"text":return y.jsx("pre",{className:"file-viewer-text",children:s.text});case"html":return y.jsx("iframe",{className:"file-viewer-frame",sandbox:"",srcDoc:s.text,title:d});case"image":return y.jsx("img",{src:s.objectUrl,alt:d,style:{maxWidth:"100%",height:"auto"}});case"binary":return Jn.isNativePlatform()?y.jsx("p",{className:"file-viewer-message",children:"Downloading this file type isn't supported in the app yet."}):y.jsxs("div",{className:"file-viewer-download",children:[y.jsxs("p",{className:"file-viewer-message",children:["This file can't be previewed (",DT(s.size),")."]}),y.jsx("a",{className:"btn btn-primary",href:s.objectUrl,download:d,children:"Download"})]})}}return y.jsx("div",{className:"report-dialog-overlay",onClick:r,children:y.jsxs("div",{className:"report-dialog",onClick:b=>b.stopPropagation(),children:[y.jsxs("div",{className:"report-dialog-header",children:[y.jsx("span",{className:"report-dialog-title",children:d}),y.jsx("button",{className:"report-dialog-close",onClick:r,"aria-label":"Close",children:y.jsxs("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[y.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),y.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})})]}),y.jsx("div",{className:`report-dialog-body${(s==null?void 0:s.kind)==="html"?" report-dialog-body--frame":""}`,children:m()})]})})}function KO({connected:e,hostId:t,request:r,subscribeEvents:s,taskId:l,runId:o}){const c=Gr(),f=Yd(),[d,m]=E.useState(!0),[b,g]=E.useState([]),[x,v]=E.useState(),[S,j]=E.useState(),[R,M]=E.useState(),[P,I]=E.useState(!1),ue=x==="started",q=x==="followup",N=x==="started"||x==="followup",[ee,G]=E.useState(null);yd(ee!==null,()=>G(null));const[B,L]=E.useState(!1),[J,$]=E.useState(""),[he,le]=E.useState(!1),te=E.useRef(null),V=E.useRef(null),Q=E.useRef(null),[X,xe]=E.useState(o==="latest"?void 0:o),A=o==="latest"&&X===null;E.useEffect(()=>{if(o!=="latest"){xe(o);return}e&&(xe(void 0),r("taskrun.list",{task_id:l,limit:1}).then(ce=>{var Ae,ke;return xe(((ke=(Ae=ce.entries)==null?void 0:Ae[0])==null?void 0:ke.run_id)??null)}).catch(()=>xe(null)))},[o,l,e,r]);async function z(){if(X)try{const ce=await r("task.result",{id:l,run_id:X});if(ce.error){console.error("No result:",ce.error),c(t?`/hosts/${encodeURIComponent(t)}`:"/",{replace:!0});return}g(ce.messages??[]),v(ce.running_state),j(ce.agent),M(ce.agent_version),I(!!ce.starred)}catch(ce){console.error("Failed to load result:",ce),c(t?`/hosts/${encodeURIComponent(t)}`:"/",{replace:!0})}finally{m(!1)}}async function W(){if(!X)return;const ce=!P;I(ce);try{const Ae=await r("taskrun.star",{task_id:l,run_id:X,starred:ce});if(Ae.error)throw new Error(Ae.error)}catch(Ae){console.error("Failed to update star:",Ae),I(!ce)}}const T=E.useCallback(ce=>X?OT(r,l,X,ce):Promise.reject(new Error("Run not loaded.")),[r,l,X]),ve=E.useMemo(()=>({openFile:G,loadFile:T}),[T]);E.useEffect(()=>{!e||!X||(m(!0),z())},[e,l,X]),E.useEffect(()=>!e||!t||!X?void 0:s(t,async Ae=>{try{const ke=JSON.parse(new TextDecoder().decode(Ae.data));if(ke.event_type!=="running-state"&&ke.event_type!=="result-updated"||Ae.subject.split(".").pop()!==l||ke.event_type==="result-updated"&&ke.run_id&&ke.run_id!==X)return;z()}catch{}}),[e,t,l,X,s,r]),E.useEffect(()=>{te.current&&(te.current.scrollTop=te.current.scrollHeight)},[b]),E.useEffect(()=>{d||A||!X||Q.current!==X&&(Q.current=X,requestAnimationFrame(()=>{te.current&&(te.current.scrollTop=te.current.scrollHeight),window.scrollTo({top:document.documentElement.scrollHeight,behavior:"auto"})}))},[d,A,X]);function je(ce){if(ce==="input")return"User Input";if(ce==="permission")return"Permission";if(ce==="confirmation")return"Confirmation"}function Ne(ce){return ce==="started"?"Task started":ce==="finished"?"Task finished":ce==="failed"?"Task failed":ce==="error"?"Command failed":ce==="aborted"?"Task aborted":ce==="confirmation"?"Task confirmed":ce==="stopped"?"Follow-up stopped":ce??""}return y.jsxs("div",{className:"run-detail",children:[y.jsxs("div",{className:"run-detail-header",children:[y.jsxs("button",{className:"run-detail-back",onClick:()=>c(-1),children:[y.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:y.jsx("path",{d:"M15 18l-6-6 6-6"})}),"Back"]}),!d&&!A&&y.jsx(Fx,{starred:P,onToggle:W})]}),A?y.jsxs("div",{className:"empty-state",children:[y.jsx("p",{className:"empty-state-text",children:"No runs yet"}),y.jsx("p",{className:"empty-state-hint",children:"This task hasn't been executed yet. Run it from the task menu or wait for its next trigger."})]}):d?y.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"var(--space-sm)",padding:"var(--space-sm) 0"},children:[y.jsx("div",{className:"skeleton-line",style:{width:"40%"}}),y.jsx("div",{className:"skeleton-line",style:{width:"55%"}}),y.jsx("div",{className:"skeleton-line",style:{width:"100%",height:"8rem",marginTop:"var(--space-sm)"}})]}):y.jsxs(y.Fragment,{children:[y.jsxs("div",{className:"chat-thread",ref:te,children:[b.map((ce,Ae)=>{const ke=N&&ce.role==="assistant"&&!b.slice(Ae+1).some(Qe=>Qe.role==="assistant"||Qe.role==="user");return ce.role==="status"?y.jsxs("div",{className:`chat-status${ce.type==="error"?" chat-status--error":""}`,children:[y.jsxs("div",{children:[Ne(ce.type),ce.time>0&&y.jsx("span",{className:"chat-status-time",children:f(ce.time)})]}),ce.content&&y.jsx("pre",{className:"chat-status-detail",children:ce.content})]},Ae):y.jsxs("div",{className:`chat-message chat-message--${ce.role}${ce.role==="assistant"&&ce.stream==="stderr"?" chat-message--stderr":""}`,children:[ce.role==="assistant"&&S&&y.jsxs("div",{className:"chat-message-agent",children:[gd(S),R&&y.jsxs("span",{className:"chat-message-agent-version",children:[" v",R]})]}),y.jsxs("div",{className:"chat-message-content",children:[y.jsx(Z1,{content:ce.content,files:ve}),ke&&y.jsxs("div",{className:"chat-typing-indicator",children:[y.jsx("span",{}),y.jsx("span",{}),y.jsx("span",{})]})]}),ce.attachments&&ce.attachments.length>0&&y.jsx("div",{className:"chat-message-attachments",children:ce.attachments.map(Qe=>y.jsx("button",{className:"chat-attachment-chip",onClick:()=>G(Qe),children:Qe},Qe))}),y.jsxs("div",{className:"chat-message-meta",children:[je(ce.type)&&y.jsx("span",{className:"chat-message-type",children:je(ce.type)}),ce.model&&y.jsxs("span",{children:[ce.model," ·"]}),ce.time>0&&y.jsx("span",{children:f(ce.time)})]})]},Ae)}),N&&(()=>{const ce=b.filter(Ae=>Ae.role!=="status");return ce.length===0||ce[ce.length-1].role!=="assistant"})()&&y.jsxs("div",{className:"chat-message chat-message--assistant",children:[S&&y.jsxs("div",{className:"chat-message-agent",children:[gd(S),R&&y.jsxs("span",{className:"chat-message-agent-version",children:[" v",R]})]}),y.jsxs("div",{className:"chat-typing-indicator",children:[y.jsx("span",{}),y.jsx("span",{}),y.jsx("span",{})]})]})]}),ue||q?y.jsx("div",{className:"chat-input-bar",children:y.jsx("button",{className:"btn btn-secondary chat-stop-btn",disabled:B,"aria-label":"Abort task",onClick:async()=>{if(confirm("Abort this task?")){L(!0);try{await r("task.abort",{id:l})}catch(ce){console.error("Abort failed:",ce)}finally{L(!1)}}},children:y.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"currentColor",children:y.jsx("rect",{x:"6",y:"6",width:"12",height:"12",rx:"2"})})})}):y.jsxs("form",{className:"chat-input-bar",onSubmit:async ce=>{ce.preventDefault();const Ae=J.trim();if(!(!Ae||he)){le(!0);try{await r("task.followup",{id:l,run_id:X,message:Ae}),$("")}catch(ke){console.error("Follow-up failed:",ke)}finally{le(!1)}}},children:[y.jsx("input",{ref:V,className:"chat-input",type:"text",placeholder:"Follow-up message",value:J,onChange:ce=>$(ce.target.value),disabled:he}),y.jsx("button",{className:"btn btn-primary chat-send-btn",type:"submit",disabled:!J.trim()||he,children:y.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[y.jsx("line",{x1:"22",y1:"2",x2:"11",y2:"13"}),y.jsx("polygon",{points:"22 2 15 22 11 13 2 9 22 2"})]})})]}),y.jsxs("button",{className:"run-detail-back run-detail-back--footer",onClick:()=>c(-1),children:[y.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:y.jsx("path",{d:"M15 18l-6-6 6-6"})}),"Back"]})]}),ee&&y.jsx(XO,{filePath:ee,files:ve,onClose:()=>G(null)})]})}function Zh({title:e,message:t,onUpdate:r,onDismiss:s}){return y.jsx("div",{className:"confirm-modal-overlay",children:y.jsxs("div",{className:"confirm-modal",children:[y.jsx("h2",{className:"confirm-modal-title",children:e}),y.jsx("p",{className:"confirm-modal-message",children:t}),y.jsxs("div",{className:"confirm-modal-actions",children:[y.jsx("button",{className:"btn btn-primary",onClick:r,children:"Update Now"}),s&&y.jsx("button",{className:"btn btn-secondary",onClick:s,children:"Dismiss"})]})]})})}function QO(){const{activeHost:e}=xi(),t=E.useRef(null);E.useEffect(()=>{if(Jn.isNativePlatform()||e.directUrl||t.current===e.hostId)return;async function r(){var s;try{if(!("serviceWorker"in navigator)||!("PushManager"in window)){console.warn("[Push] Push notifications not supported");return}const l=await navigator.serviceWorker.ready;(s=l.active)==null||s.postMessage({type:"set-host-id",hostId:e.hostId});let o=await l.pushManager.getSubscription();if(!o){const{publicKey:f}=await wE("/api/push/vapid-key");if(!f){console.warn("[Push] No VAPID public key configured on server");return}if(await Notification.requestPermission()!=="granted"){console.log("[Push] Permission denied");return}o=await l.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:f})}const c=o.toJSON();await vE("/api/push/subscribe",{hostId:e.hostId,endpoint:c.endpoint,keys:{p256dh:c.keys.p256dh,auth:c.keys.auth}}),t.current=e.hostId}catch(l){console.error("[Push] Subscription failed:",l)}}r()},[e])}const ZO="0.9.9";function vu(e,t){if(e.includes("-"))return!1;const r=e.split(".").map(Number),s=t.split(".").map(Number);for(let l=0;l<3;l++){if((r[l]??0)<(s[l]??0))return!0;if((r[l]??0)>(s[l]??0))return!1}return!1}function wu(){const{removePairedHost:e,setHostLanUrl:t,setHostTimezone:r}=Zi(),{connected:s,request:l,subscribeEvents:o,unauthorized:c,activeHost:f}=xi(),d=f.hostId,m=f.clientToken||null,b=Gr(),g=Er(),x=Yu(),v=qx("(min-width: 768px)"),S=g.pathname.endsWith("/tasks"),j=x.runId?void 0:x.taskId,R=!!(x.taskId&&x.runId),[M,P]=E.useState(!1),[I,ue]=E.useState(!1),[q,N]=E.useState(null),[ee,G]=E.useState(null),[B,L]=E.useState(null),[J,$]=E.useState(null),[he,le]=E.useState({}),[te,V]=E.useState({}),[Q,X]=E.useState(null),[xe,A]=E.useState(null),[z,W]=E.useState(null),[T,ve]=E.useState(null),[je,Ne]=E.useState(new Set),[ce,Ae]=E.useState([]),[ke,Qe]=E.useState(),[Lt,dn]=E.useState("loading"),tn=!!m&&T===m,[Ft,$t]=E.useState(new Map),[an,bn]=E.useState(new Map),[Be,nt]=E.useState(new Map),[st,Ot]=E.useState(new Map),[_t,mn]=E.useState(new Map),[at,Cr]=E.useState(new Map),[ae,_e]=E.useState(new Map),[Me,Ge]=E.useState(new Map);QO(),E.useEffect(()=>{window.scrollTo(0,0)},[d]),E.useEffect(()=>{let de=!1;return eC().then(Ee=>{de||Ne(Ee)}),()=>{de=!0}},[]),E.useEffect(()=>{if(!s){dn("loading");return}dn("loading");let de=!1;return l("host.info",void 0,{timeout:15e3}).then(Ee=>{var We,Zt,Qt,Rt,ft,Bt,jn,Pr,wi;if(de)return;Ae(Ee.agents??[]),X(Ee.playwright_cli??null),Qe(Ee.host_platform),ve(Ee.linked_client_token??null),LE(Ee.agents??[]);const He=Ee.version??null;G(He),P(!!He&&vu(He,ZO)),t(d,Ee.lan_url??void 0),r(d,Ee.host_timezone);const Ve=new Map,qe=new Map,ct=new Map,Xe=new Map,Pe=new Map;for(const Ut of Ee.pending_prompts??[])if(Ut.type==="confirmation")Ve.set(Ut.key,{description:((We=Ut.meta)==null?void 0:We.description)??"",sessionName:(Zt=Ut.meta)==null?void 0:Zt.session_name});else if(Ut.type==="choice")qe.set(Ut.key,{question:((Qt=Ut.meta)==null?void 0:Qt.description)??"",options:Ut.params??[],sessionName:(Rt=Ut.meta)==null?void 0:Rt.session_name});else if(Ut.type==="permission")ct.set(Ut.key,{permissions:Ut.params??[],sessionName:(ft=Ut.meta)==null?void 0:ft.session_name});else if(Ut.type==="input"){const ns=Ut.params??((Bt=Ut.meta)==null?void 0:Bt.input_questions)??[];Xe.set(Ut.key,{questions:ns,description:(jn=Ut.meta)==null?void 0:jn.description,sessionName:(Pr=Ut.meta)==null?void 0:Pr.session_name,secret:(wi=Ut.meta)==null?void 0:wi.secret}),Pe.set(Ut.key,new Array(ns.length).fill(""))}$t(Ve),bn(qe),nt(ct),Ot(Xe),mn(Pe),dn("ready")}).catch(()=>{de||dn("error")}),()=>{de=!0}},[s,d,l,t,r]),E.useEffect(()=>s?o(d,Ee=>{const He=Ee.subject.split(".");if(He.length<3)return;const Ve=He.slice(2).join(".");let qe={};try{qe=JSON.parse(new TextDecoder().decode(Ee.data))}catch{return}const ct=qe.event_type,Xe=qe.session_id;if(ct==="input-request"&&Xe){const Pe=qe.input_questions,We=qe.session_name,Zt=qe.description,Qt=qe.secret;Pe!=null&&Pe.length&&(Ot(Rt=>{if(Rt.has(Xe))return Rt;const ft=new Map(Rt);return ft.set(Xe,{questions:Pe,description:Zt,sessionName:We,secret:Qt}),ft}),mn(Rt=>{if(Rt.has(Xe))return Rt;const ft=new Map(Rt);return ft.set(Xe,new Array(Pe.length).fill("")),ft}));return}if(ct==="input-resolved"&&Xe){Ot(Pe=>{if(!Pe.has(Xe))return Pe;const We=new Map(Pe);return We.delete(Xe),We}),mn(Pe=>{const We=new Map(Pe);return We.delete(Xe),We}),Cr(Pe=>{if(!Pe.has(Xe))return Pe;const We=new Map(Pe);return We.delete(Xe),We});return}if(ct==="confirm-request"&&Xe){const Pe=qe.description,We=qe.session_name;Pe&&$t(Zt=>{if(Zt.has(Xe))return Zt;const Qt=new Map(Zt);return Qt.set(Xe,{description:Pe,sessionName:We}),Qt});return}if(ct==="confirm-resolved"&&Xe){$t(Pe=>{if(!Pe.has(Xe))return Pe;const We=new Map(Pe);return We.delete(Xe),We});return}if(ct==="choice-request"&&Xe){const Pe=qe.description,We=qe.options,Zt=qe.session_name;Pe&&(We!=null&&We.length)&&bn(Qt=>{if(Qt.has(Xe))return Qt;const Rt=new Map(Qt);return Rt.set(Xe,{question:Pe,options:We,sessionName:Zt}),Rt});return}if(ct==="choice-resolved"&&Xe){bn(Pe=>{if(!Pe.has(Xe))return Pe;const We=new Map(Pe);return We.delete(Xe),We});return}if(ct==="permission-request"){const Pe=qe.required_permissions,We=qe.session_name;Pe!=null&&Pe.length&&nt(Zt=>{if(Zt.has(Ve))return Zt;const Qt=new Map(Zt);return Qt.set(Ve,{permissions:Pe,sessionName:We}),Qt});return}if(ct==="permission-resolved"){nt(Pe=>{if(!Pe.has(Ve))return Pe;const We=new Map(Pe);return We.delete(Ve),We});return}}):void 0,[s,d,o]);async function rt(de,Ee,He,Ve){if(!ae.has(de)){_e(qe=>new Map(qe).set(de,Ee)),Ge(qe=>{const ct=new Map(qe);return ct.delete(de),ct});try{await l("task.user_input",{id:de,value:He},{timeout:3e4}),Ve()}catch(qe){console.error("[Dashboard] Failed to send user input:",qe),Ge(ct=>new Map(ct).set(de,"Couldn't reach the host. Try again."))}finally{_e(qe=>{const ct=new Map(qe);return ct.delete(de),ct})}}}function zt(de,Ee){rt(de,Ee,[Ee],()=>{$t(He=>{const Ve=new Map(He);return Ve.delete(de),Ve})})}function Sn(de,Ee){rt(de,Ee,[Ee],()=>{bn(He=>{const Ve=new Map(He);return Ve.delete(de),Ve})})}function Kt(de,Ee){rt(de,Ee,[Ee],()=>{nt(He=>{const Ve=new Map(He);return Ve.delete(de),Ve})})}function yt(de,Ee,He){rt(de,Ee,He,()=>{Ot(Ve=>{const qe=new Map(Ve);return qe.delete(de),qe}),mn(Ve=>{const qe=new Map(Ve);return qe.delete(de),qe}),Cr(Ve=>{const qe=new Map(Ve);return qe.delete(de),qe})})}function Vt(de,Ee){if(!Ss())return;const He=`/hosts/${encodeURIComponent(d)}/runs/${encodeURIComponent(de)}`;b(Ee?`${He}/${encodeURIComponent(Ee)}`:He)}E.useEffect(()=>{if(!ee)return;let de=!1;return fetch("https://registry.npmjs.org/palmier/latest").then(Ee=>Ee.ok?Ee.json():null).then(Ee=>{!de&&(Ee!=null&&Ee.version)&&L(Ee.version)}).catch(()=>{}),()=>{de=!0}},[ee]),E.useEffect(()=>{let de=!1;for(const Ee of ce)!Ee.version||!Ee.npmPackage||fetch(`https://registry.npmjs.org/${Ee.npmPackage}/latest`).then(He=>He.ok?He.json():null).then(He=>{de||!(He!=null&&He.version)||le(Ve=>Ve[Ee.key]===He.version?Ve:{...Ve,[Ee.key]:He.version})}).catch(()=>{});return()=>{de=!0}},[ce]);const Ze=ce.find(de=>{if(!de.version)return!1;const Ee=he[de.key];return!Ee||!vu(de.version,Ee)?!1:te[de.key]!==Ee});function An(de,Ee){V(He=>({...He,[de]:Ee}))}async function pn(de){ue("agent"),N(null);try{const Ee=await l("host.updateAgent",{key:de});if(Ee.error){N(Ee.error),ue(!1);return}const He=await l("host.info");He.agents&&Ae(He.agents)}catch(Ee){N(Ee instanceof Error?Ee.message:String(Ee))}finally{ue(!1)}}E.useEffect(()=>{if(!(Q!=null&&Q.npmPackage))return;let de=!1;return fetch(`https://registry.npmjs.org/${Q.npmPackage}/latest`).then(Ee=>Ee.ok?Ee.json():null).then(Ee=>{!de&&(Ee!=null&&Ee.version)&&A(Ee.version)}).catch(()=>{}),()=>{de=!0}},[Q==null?void 0:Q.npmPackage,Q==null?void 0:Q.version]);const Kn=Q&&xe&&vu(Q.version,xe)&&z!==xe?Q:null;function we(de){W(de)}async function Ye(){ue("playwright"),N(null);try{const de=await l("host.updatePlaywrightCli");if(de.error){N(de.error),ue(!1);return}const Ee=await l("host.info");X(Ee.playwright_cli??null)}catch(de){N(de instanceof Error?de.message:String(de))}finally{ue(!1)}}const Re=!M&&!!ee&&!!B&&vu(ee,B)&&J!==B;function bt(){B&&$(B)}async function ln(){ue("daemon"),N(null);try{const de=await l("host.update");if(de.error){N(de.error),ue(!1);return}}catch{}setTimeout(()=>window.location.reload(),3e4)}const Hn=Ft.size>0||an.size>0||Be.size>0||st.size>0,ts=s&&!c;return y.jsxs("div",{className:"dashboard",children:[v&&y.jsx(Q0,{daemonVersion:ee,agents:ce,playwrightCli:Q,linkedClientToken:T,request:l,onEnabledCapabilitiesChange:Ne,onLinkedClientTokenChange:ve}),y.jsxs("div",{className:"dashboard-content",children:[y.jsxs("header",{className:"app-header",children:[y.jsxs("div",{className:"app-title-bar",children:[!v&&y.jsx(Q0,{daemonVersion:ee,agents:ce,playwrightCli:Q,linkedClientToken:T,request:l,onEnabledCapabilitiesChange:Ne,onLinkedClientTokenChange:ve}),y.jsx("h1",{className:"app-title",children:"Palmier"}),y.jsx(aC,{})]}),y.jsx("div",{className:"tab-bar",children:y.jsx(QE,{})})]}),y.jsx("main",{className:"dashboard-main",children:c?y.jsxs("div",{className:"revoked-state",children:[y.jsx("div",{className:"revoked-icon",children:y.jsxs("svg",{width:"32",height:"32",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",children:[y.jsx("rect",{x:"3",y:"11",width:"18",height:"11",rx:"2",ry:"2"}),y.jsx("path",{d:"M7 11V7a5 5 0 0 1 10 0v4"}),y.jsx("line",{x1:"12",y1:"15",x2:"12",y2:"18"})]})}),y.jsx("h2",{className:"revoked-title",children:"Client Revoked"}),y.jsx("p",{className:"revoked-description",children:"This client was revoked by the host. To reconnect, generate a new pairing code on the host machine."}),y.jsx("div",{className:"revoked-command",children:y.jsx("code",{children:"palmier pair"})}),y.jsxs("div",{className:"revoked-actions",children:[y.jsx("button",{className:"btn btn-primary",onClick:()=>{Ss()&&b("/pair")},children:"Re-pair Device"}),y.jsx("button",{className:"btn btn-secondary",onClick:()=>{e(d),b("/",{replace:!0})},children:"Remove Host"})]})]}):ts?y.jsxs(y.Fragment,{children:[S&&!R&&y.jsx(KE,{connected:s,hostId:d,request:l,subscribeEvents:o,agents:ce,hostPlatform:ke,isNotificationListener:tn&&je.has("notifications"),onViewRun:Vt,hostInfoStatus:Lt}),R?y.jsx(KO,{connected:s,hostId:d,request:l,subscribeEvents:o,taskId:x.taskId,runId:decodeURIComponent(x.runId)}):S?null:y.jsx(cC,{connected:s,hostId:d,request:l,subscribeEvents:o,agents:ce,hostPlatform:ke,filterTaskId:j,onClearFilter:()=>{Ss()&&b(`/hosts/${encodeURIComponent(d)}`)},hostInfoStatus:Lt})]}):y.jsx("div",{className:"empty-state",children:y.jsx("p",{className:"empty-state-text",children:"Connecting to host…"})})}),(M||Re)&&!I&&!q&&!Hn&&y.jsx(Zh,{title:M?"Update Required":"Update Available",message:M?`Your Palmier host${ee?` (v${ee})`:""} is too old for this version of the app. Please update to continue.`:`A new version of Palmier (v${B}) is available. You're running v${ee}.`,onUpdate:ln,onDismiss:M?void 0:bt}),!M&&!Re&&Ze&&!I&&!q&&!Hn&&y.jsx(Zh,{title:"Agent Update Available",message:`A new version of ${Ze.label} (v${he[Ze.key]}) is available. You're running v${Ze.version}.`,onUpdate:()=>pn(Ze.key),onDismiss:()=>An(Ze.key,he[Ze.key])}),!M&&!Re&&!Ze&&Kn&&xe&&!I&&!q&&!Hn&&y.jsx(Zh,{title:"Browser Automation Update Available",message:`A new version of ${Kn.label} (v${xe}) is available. You're running v${Kn.version}.`,onUpdate:Ye,onDismiss:()=>we(xe)}),I&&y.jsx("div",{className:"confirm-modal-overlay",children:y.jsxs("div",{className:"confirm-modal",children:[y.jsx("h2",{className:"confirm-modal-title",children:"Updating..."}),y.jsx("p",{className:"confirm-modal-message",children:I==="daemon"?"Installing update and restarting daemon. Please wait...":"Installing update. Please wait..."})]})}),q&&y.jsx("div",{className:"confirm-modal-overlay",children:y.jsxs("div",{className:"confirm-modal",children:[y.jsx("h2",{className:"confirm-modal-title",children:"Update Failed"}),y.jsx("p",{className:"confirm-modal-message",style:{whiteSpace:"pre-line"},children:q}),y.jsx("div",{className:"confirm-modal-actions",children:y.jsx("button",{className:"btn btn-secondary",onClick:()=>{N(null)},children:"Retry"})})]})})]}),pi.createPortal(y.jsxs(y.Fragment,{children:[[...Ft.entries()].map(([de,{description:Ee,sessionName:He}])=>y.jsx("div",{className:"confirm-modal-overlay",children:y.jsxs("div",{className:"confirm-modal",children:[y.jsx("h2",{className:"confirm-modal-title",children:"Confirmation Required"}),He&&y.jsx("p",{className:"confirm-modal-subtitle",children:He}),y.jsx("p",{className:"confirm-modal-message",children:Ee}),Me.has(de)&&y.jsx("p",{className:"form-error",children:Me.get(de)}),y.jsxs("div",{className:"confirm-modal-actions",children:[y.jsxs("button",{className:"btn btn-primary",disabled:ae.has(de),onClick:()=>zt(de,"confirmed"),children:[ae.get(de)==="confirmed"&&y.jsx("span",{className:"btn-spinner"}),"Confirm"]}),y.jsxs("button",{className:"btn btn-secondary",disabled:ae.has(de),onClick:()=>zt(de,"aborted"),children:[ae.get(de)==="aborted"&&y.jsx("span",{className:"btn-spinner btn-spinner-current"}),"Abort"]})]})]})},de)),[...an.entries()].map(([de,{question:Ee,options:He,sessionName:Ve}])=>y.jsx("div",{className:"confirm-modal-overlay",children:y.jsxs("div",{className:"confirm-modal",children:[y.jsx("h2",{className:"confirm-modal-title",children:"Question"}),Ve&&y.jsx("p",{className:"confirm-modal-subtitle",children:Ve}),y.jsx("p",{className:"confirm-modal-message",children:Ee}),Me.has(de)&&y.jsx("p",{className:"form-error",children:Me.get(de)}),y.jsx("div",{className:`confirm-modal-actions${He.length===2&&He.every(qe=>qe.length<=16)?"":" choice-options-stacked"}`,children:He.map((qe,ct)=>y.jsxs("button",{className:"btn btn-secondary",disabled:ae.has(de),onClick:()=>Sn(de,String(ct)),children:[ae.get(de)===String(ct)&&y.jsx("span",{className:"btn-spinner btn-spinner-current"}),qe]},ct))}),y.jsxs("button",{className:"permission-abort-link",disabled:ae.has(de),onClick:()=>Sn(de,"aborted"),children:[ae.get(de)==="aborted"&&y.jsx("span",{className:"btn-spinner btn-spinner-current"}),"Abort Task"]})]})},de)),[...Be.entries()].map(([de,{permissions:Ee,sessionName:He}])=>y.jsx("div",{className:"confirm-modal-overlay",children:y.jsxs("div",{className:"confirm-modal permission-modal",children:[y.jsx("h2",{className:"confirm-modal-title",children:"Permission Required"}),y.jsx("p",{className:"confirm-modal-message",children:y.jsx("strong",{children:He||de})}),y.jsx("div",{className:"permission-list",children:Ee.map((Ve,qe)=>y.jsxs("div",{className:"permission-item",children:[y.jsx("span",{className:"permission-name",children:Ve.name}),Ve.description&&y.jsx("span",{className:"permission-desc",children:Ve.description})]},qe))}),Me.has(de)&&y.jsx("p",{className:"form-error",children:Me.get(de)}),y.jsxs("div",{className:"permission-actions",children:[y.jsxs("button",{className:"btn btn-primary",disabled:ae.has(de),onClick:()=>Kt(de,"granted"),children:[ae.get(de)==="granted"&&y.jsx("span",{className:"btn-spinner"}),"Allow Once"]}),y.jsxs("button",{className:"btn btn-secondary",disabled:ae.has(de),onClick:()=>Kt(de,"granted_all"),children:[ae.get(de)==="granted_all"&&y.jsx("span",{className:"btn-spinner btn-spinner-current"}),"Allow Always"]})]}),y.jsxs("button",{className:"permission-abort-link",disabled:ae.has(de),onClick:()=>Kt(de,"aborted"),children:[ae.get(de)==="aborted"&&y.jsx("span",{className:"btn-spinner btn-spinner-current"}),"Deny & Abort Task"]})]})},de)),[...st.entries()].map(([de,{questions:Ee,description:He,sessionName:Ve,secret:qe}])=>{const ct=_t.get(de)??new Array(Ee.length).fill("");return y.jsx("div",{className:"confirm-modal-overlay",children:y.jsxs("div",{className:"confirm-modal input-modal",children:[y.jsx("h2",{className:"confirm-modal-title",children:qe?"Password Required":"Input Required"}),Ve&&y.jsx("p",{className:"confirm-modal-subtitle",children:Ve}),He&&y.jsx("p",{className:"confirm-modal-message",children:He}),y.jsx("div",{className:"input-list",children:Ee.map((Xe,Pe)=>y.jsxs("div",{className:"input-item",children:[y.jsx("label",{className:"input-label",children:Xe}),y.jsx("input",{type:qe?"password":"text",autoComplete:qe?"off":void 0,className:"input-field",value:ct[Pe]??"",onChange:We=>{mn(Zt=>{const Qt=new Map(Zt),Rt=[...Qt.get(de)??[]];return Rt[Pe]=We.target.value,Qt.set(de,Rt),Qt})},disabled:ae.has(de),autoFocus:Pe===0})]},Pe))}),qe&&y.jsxs("label",{className:"toggle-label input-save-toggle",children:[y.jsx("input",{type:"checkbox",checked:at.get(de)??!0,disabled:ae.has(de),onChange:Xe=>Cr(Pe=>new Map(Pe).set(de,Xe.target.checked))}),"Save this password"]}),Me.has(de)&&y.jsx("p",{className:"form-error",children:Me.get(de)}),y.jsx("div",{className:"input-actions",children:y.jsxs("button",{className:"btn btn-primary",disabled:ae.has(de)||ct.some(Xe=>!Xe.trim()),onClick:()=>{const Xe=qe?[...ct,at.get(de)??!0?"save":"nosave"]:ct;yt(de,"submit",Xe)},children:[ae.get(de)==="submit"&&y.jsx("span",{className:"btn-spinner"}),"Submit"]})}),y.jsxs("button",{className:"permission-abort-link",disabled:ae.has(de),onClick:()=>yt(de,"aborted",["aborted"]),children:[ae.get(de)==="aborted"&&y.jsx("span",{className:"btn-spinner btn-spinner-current"}),"Abort"]})]})},de)})]}),document.body)]})}const WO=ks("Preferences",{web:()=>Vd(()=>import("./web-Bt4bEHcd.js"),[]).then(e=>new e.PreferencesWeb)}),Al=!!window.__PALMIER_SERVE__&&(window.location.hostname==="localhost"||window.location.hostname==="127.0.0.1"),$b=Jn.isNativePlatform();function e4(){const[e,t]=E.useState(""),[r,s]=E.useState(!0),[l,o]=E.useState(!1),[c,f]=E.useState(null),{addPairedHost:d,pairedHosts:m}=Zi(),b=Gr();async function g(){const x=e.trim().toUpperCase();if(!x){f("Enter a pairing code.");return}o(!0),f(null);try{let v;if(Al){const R=await fetch("/pair",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({code:x,label:navigator.userAgent})});if(!R.ok){const M=await R.json().catch(()=>({error:"Connection failed"}));throw new Error(M.error||`HTTP ${R.status}`)}v=await R.json()}else{const R=await fetch(`${Bu}/api/config`);if(!R.ok)throw new Error("Failed to fetch server config");const M=await R.json();if(!M.natsWsUrl)throw new Error("Server has no NATS WebSocket URL configured");const P=await Dx({servers:M.natsWsUrl,authenticator:Ex(M.natsJwt,new TextEncoder().encode(M.natsNkeySeed))}),I=Ru(),ue=`pair.${x}`,q=await P.request(ue,I.encode(JSON.stringify({label:navigator.userAgent})),{timeout:1e4});v=JSON.parse(I.decode(q.data)),await P.close()}const S={hostId:v.hostId,clientToken:v.clientToken,directUrl:Al?window.location.origin:void 0,...v.hostName?{name:v.hostName}:{}};if(d(S),Jn.isNativePlatform()&&On){await WO.set({key:"hostId",value:v.hostId});try{const{token:R}=await On.getFcmToken();await fetch(`${Bu}/api/fcm/register`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({hostId:v.hostId,fcmToken:R})})}catch(R){console.warn("FCM token registration failed:",R)}}const j=`/hosts/${encodeURIComponent(v.hostId)}`;b($b&&r?`${j}/pair/setup`:j)}catch(v){const S=v instanceof Error?v.message:String(v);S.includes("timeout")||S.includes("TIMEOUT")||S.includes("503")||S.toLowerCase().includes("no responders")?f("Code not found or expired. Check the code and try again."):f(S)}finally{o(!1)}}return y.jsx("div",{className:"pair-page",children:y.jsxs("div",{className:"pair-card",children:[y.jsxs("div",{className:"pair-header",children:[y.jsx("h1",{className:"pair-title",children:Al?"Pair":"Pair with Host"}),y.jsx("p",{className:"pair-subtitle",children:Al?"Enter the pairing code shown in your terminal.":"Connect this device to a Palmier host"})]}),!Al&&y.jsxs("div",{className:"pair-instructions",children:[y.jsxs("div",{className:"pair-instruction-block",children:[y.jsx("h3",{className:"pair-instruction-heading",children:"Setting up a new host?"}),y.jsxs("ol",{className:"pair-steps",children:[y.jsxs("li",{children:["Install Palmier on your host machine.",y.jsx("span",{className:"pair-platform-label",children:"Linux / macOS:"}),y.jsx("code",{className:"pair-command",children:"curl -fsSL https://palmier.me/install.sh | bash"}),y.jsx("span",{className:"pair-platform-label",children:"Windows (PowerShell):"}),y.jsx("code",{className:"pair-command",children:"irm https://palmier.me/install.ps1 | iex"})]}),y.jsxs("li",{children:["Run the setup wizard:",y.jsx("code",{className:"pair-command",children:"palmier init"})]}),y.jsx("li",{children:"A pairing code will display automatically"})]})]}),y.jsx("div",{className:"pair-instruction-divider"}),y.jsxs("div",{className:"pair-instruction-block",children:[y.jsx("h3",{className:"pair-instruction-heading",children:"Pairing an existing host?"}),y.jsxs("ol",{className:"pair-steps",children:[y.jsxs("li",{children:["Run ",y.jsx("code",{children:"palmier pair"})," on the host machine"]}),y.jsx("li",{children:"Enter the 6-character code below"})]})]})]}),y.jsxs("div",{className:"pair-form",children:[y.jsxs("label",{className:"form-label",htmlFor:"pair-code",children:["Pairing code",y.jsx("input",{id:"pair-code",type:"text",maxLength:6,value:e,onChange:x=>t(x.target.value.toUpperCase()),placeholder:"A7K9M2",className:"form-input form-input-mono pair-code-input",autoFocus:!0,autoComplete:"off",disabled:l})]}),$b&&y.jsxs("label",{className:"pair-checkbox",children:[y.jsx("input",{type:"checkbox",checked:r,onChange:x=>s(x.target.checked),disabled:l}),y.jsxs("span",{className:"pair-checkbox-text",children:[y.jsx("span",{className:"pair-checkbox-title",children:"Link the host to this device"}),y.jsx("span",{className:"pair-checkbox-hint",children:r?"The host will use this device for SMS, contacts, calendar, location, and alarms. Only one device can be linked to the host.":"This device won't provide SMS, contacts, calendar, location, or alarms to the host. You can link it later from the menu."})]})]}),c&&y.jsx("p",{className:"pair-error",children:c}),y.jsxs("button",{className:"btn btn-primary btn-full",onClick:g,disabled:l||!e.trim(),children:[l&&y.jsx("span",{className:"btn-spinner"}),l?"Pairing...":"Pair"]}),m.length>0&&y.jsx("button",{className:"btn btn-secondary btn-full",onClick:()=>b("/"),disabled:l,children:"Cancel"}),y.jsxs("p",{className:"pair-consent",children:["By pairing, you agree to our"," ",y.jsx("a",{href:"https://www.palmier.me/terms",target:"_blank",rel:"noopener noreferrer",children:"Terms of Service"})," and"," ",y.jsx("a",{href:"https://www.palmier.me/privacy",target:"_blank",rel:"noopener noreferrer",children:"Privacy Policy"}),"."]})]})]})})}function t4(){const e=Gr(),{connected:t,request:r,activeHost:s}=xi(),{setHostLanUrl:l,pairedHosts:o}=Zi(),c=o.length<=1,[f,d]=E.useState("loading"),[m,b]=E.useState(null),[g,x]=E.useState(null);function v(){e(`/hosts/${encodeURIComponent(s.hostId)}`,{replace:!0})}E.useEffect(()=>{if(!t||f!=="loading")return;let P=!1;return r("host.info").catch(()=>({})).then(I=>{if(P)return;l(s.hostId,I.lan_url??void 0);const ue=I.linked_client_token??null;b(ue);const q=!!ue&&ue!==s.clientToken;d(q?"confirming":"linking")}),()=>{P=!0}},[t,f,s,r,l]),E.useEffect(()=>{if(f!=="linking")return;let P=!1;return(async()=>{try{if(On){const{token:I}=await On.getFcmToken();if(!I)throw new Error("Could not read FCM token");await r("device.link",{fcmToken:I})}if(P)return;c?d("wizard"):v()}catch(I){if(P)return;x(I instanceof Error?I.message:String(I)),d("linkError")}})(),()=>{P=!0}},[f]);function S(){d("linking")}function j(){v()}function R(){x(null),d("linking")}const M=f==="confirming"&&pi.createPortal(y.jsx("div",{className:"confirm-modal-overlay",onClick:j,children:y.jsxs("div",{className:"confirm-modal",onClick:P=>P.stopPropagation(),children:[y.jsx("h2",{className:"confirm-modal-title",children:"Link the host to this device?"}),y.jsx("p",{className:"confirm-modal-message",children:"Another device is already linked to this host. Only one device can be linked to the host — switching will disable those capabilities on the currently linked device."}),y.jsxs("div",{className:"confirm-modal-actions",children:[y.jsx("button",{className:"btn btn-secondary",onClick:j,children:"Cancel"}),y.jsx("button",{className:"btn btn-primary",onClick:S,children:"Link"})]})]})}),document.body);if(f==="loading"||f==="confirming"||f==="linking"||f==="linkError"){const P=c,I=f==="loading"||f==="confirming"||f==="linking";return y.jsxs("div",{className:"pair-setup",children:[y.jsxs("div",{className:"pair-setup-inner",children:[P&&y.jsx("h1",{className:"pair-setup-title",children:"Device Capabilities"}),y.jsxs("div",{className:"pair-setup-loading",children:[I&&y.jsx("span",{className:"spinner spinner-lg"}),f==="loading"&&y.jsx("span",{children:"Connecting to host…"}),f==="confirming"&&y.jsx("span",{children:"Awaiting confirmation…"}),f==="linking"&&y.jsx("span",{children:"Linking device…"}),f==="linkError"&&y.jsxs(y.Fragment,{children:[y.jsx("p",{className:"pair-error",children:g}),y.jsx("button",{className:"btn btn-primary",onClick:R,children:"Retry"}),y.jsx("button",{className:"btn btn-secondary",onClick:v,children:"Skip linking"})]})]})]}),M]})}return y.jsx("div",{className:"pair-setup",children:y.jsxs("div",{className:"pair-setup-inner",children:[y.jsx("h1",{className:"pair-setup-title",children:"Device Capabilities"}),y.jsx("p",{className:"pair-setup-description",children:"Choose what the host can use this device for. You can change these later from the menu."}),y.jsx(Ix,{}),y.jsx("div",{className:"pair-setup-actions",children:y.jsx("button",{className:"btn btn-primary btn-full",onClick:v,children:"Finish"})})]})})}function n4(){const e=Gr();return E.useEffect(()=>{if(!On)return;const t=On.addListener("deepLink",({path:r})=>e(r));return()=>{t.then(r=>r.remove())}},[e]),null}function r4(){const{pairedHosts:e,lastHostId:t}=Zi();if(e.length===0)return y.jsx(Bl,{to:"/pair",replace:!0});const r=e.find(s=>s.hostId===t)??e[0];return y.jsx(Bl,{to:`/hosts/${encodeURIComponent(r.hostId)}`,replace:!0})}function i4(){const{hostId:e}=Yu(),{pairedHosts:t,setLastHostId:r}=Zi(),s=t.find(l=>l.hostId===e)??null;return E.useEffect(()=>{s&&r(s.hostId)},[s==null?void 0:s.hostId,r]),s?y.jsx(EE,{activeHost:s,children:y.jsxs(ax,{children:[y.jsx(Rr,{index:!0,element:y.jsx(wu,{},e)}),y.jsx(Rr,{path:"tasks",element:y.jsx(wu,{},e)}),y.jsx(Rr,{path:"runs/:taskId",element:y.jsx(wu,{},e)}),y.jsx(Rr,{path:"runs/:taskId/:runId",element:y.jsx(wu,{},e)}),y.jsx(Rr,{path:"pair/setup",element:y.jsx(t4,{})}),y.jsx(Rr,{path:"*",element:y.jsx(Bl,{to:".",replace:!0})})]})},`${s.hostId}|${s.clientToken}`):y.jsx(Bl,{to:"/",replace:!0})}function s4(){return y.jsxs(X_,{children:[y.jsx(n4,{}),y.jsxs(ax,{children:[y.jsx(Rr,{path:"/",element:y.jsx(r4,{})}),y.jsx(Rr,{path:"/pair",element:y.jsx(e4,{})}),y.jsx(Rr,{path:"/hosts/:hostId/*",element:y.jsx(i4,{})}),y.jsx(Rr,{path:"*",element:y.jsx(Bl,{to:"/",replace:!0})})]})]})}gS.createRoot(document.getElementById("root")).render(y.jsx(E.StrictMode,{children:y.jsx(z_,{children:y.jsx(s4,{})})}));export{$d as W};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{W as i}from"./index-
|
|
1
|
+
import{W as i}from"./index-C09PWoQd.js";function o(){const t=window.navigator.connection||window.navigator.mozConnection||window.navigator.webkitConnection;let n="unknown";const e=t?t.type||t.effectiveType:null;if(e&&typeof e=="string")switch(e){case"bluetooth":case"cellular":n="cellular";break;case"none":n="none";break;case"ethernet":case"wifi":case"wimax":n="wifi";break;case"other":case"unknown":n="unknown";break;case"slow-2g":case"2g":case"3g":n="cellular";break;case"4g":n="wifi";break}return n}class s extends i{constructor(){super(),this.handleOnline=()=>{const e={connected:!0,connectionType:o()};this.notifyListeners("networkStatusChange",e)},this.handleOffline=()=>{const n={connected:!1,connectionType:"none"};this.notifyListeners("networkStatusChange",n)},typeof window<"u"&&(window.addEventListener("online",this.handleOnline),window.addEventListener("offline",this.handleOffline))}async getStatus(){if(!window.navigator)throw this.unavailable("Browser does not support the Network Information API");const n=window.navigator.onLine,e=o();return{connected:n,connectionType:n?e:"none"}}}const r=new s;export{r as Network,s as NetworkWeb};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{W as p}from"./index-
|
|
1
|
+
import{W as p}from"./index-C09PWoQd.js";class f extends p{constructor(){super(...arguments),this.group="CapacitorStorage"}async configure({group:e}){typeof e=="string"&&(this.group=e)}async get(e){return{value:this.impl.getItem(this.applyPrefix(e.key))}}async set(e){this.impl.setItem(this.applyPrefix(e.key),e.value)}async remove(e){this.impl.removeItem(this.applyPrefix(e.key))}async keys(){return{keys:this.rawKeys().map(t=>t.substring(this.prefix.length))}}async clear(){for(const e of this.rawKeys())this.impl.removeItem(e)}async migrate(){var e;const t=[],s=[],n="_cap_",o=Object.keys(this.impl).filter(i=>i.indexOf(n)===0);for(const i of o){const r=i.substring(n.length),a=(e=this.impl.getItem(i))!==null&&e!==void 0?e:"",{value:l}=await this.get({key:r});typeof l=="string"?s.push(r):(await this.set({key:r,value:a}),t.push(r))}return{migrated:t,existing:s}}async removeOld(){const e="_cap_",t=Object.keys(this.impl).filter(s=>s.indexOf(e)===0);for(const s of t)this.impl.removeItem(s)}get impl(){return window.localStorage}get prefix(){return this.group==="NativeStorage"?"":`${this.group}.`}rawKeys(){return Object.keys(this.impl).filter(e=>e.indexOf(this.prefix)===0)}applyPrefix(e){return this.prefix+e}}export{f as PreferencesWeb};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{W as t}from"./index-
|
|
1
|
+
import{W as t}from"./index-C09PWoQd.js";class s extends t{constructor(){super(),this.handleVisibilityChange=()=>{const e={isActive:document.hidden!==!0};this.notifyListeners("appStateChange",e),document.hidden?this.notifyListeners("pause",null):this.notifyListeners("resume",null)},document.addEventListener("visibilitychange",this.handleVisibilityChange,!1)}exitApp(){throw this.unimplemented("Not implemented on web.")}async getInfo(){throw this.unimplemented("Not implemented on web.")}async getLaunchUrl(){return{url:""}}async getState(){return{isActive:document.hidden!==!0}}async minimizeApp(){throw this.unimplemented("Not implemented on web.")}async toggleBackButtonHandler(){throw this.unimplemented("Not implemented on web.")}async getAppLanguage(){return{value:navigator.language.split("-")[0].toLowerCase()}}}export{s as AppWeb};
|
package/dist/pwa/index.html
CHANGED
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
|
9
9
|
<title>Palmier</title>
|
|
10
10
|
<meta name="description" content="Run tasks from anywhere, approve actions on the go, and let your agents use your phone’s built-in capabilities when needed." />
|
|
11
|
-
<script type="module" crossorigin src="/assets/index-
|
|
12
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
11
|
+
<script type="module" crossorigin src="/assets/index-C09PWoQd.js"></script>
|
|
12
|
+
<link rel="stylesheet" crossorigin href="/assets/index-ByB7B0d2.css">
|
|
13
13
|
<link rel="manifest" href="/manifest.webmanifest"><script id="vite-plugin-pwa:register-sw" src="/registerSW.js"></script></head>
|
|
14
14
|
<body>
|
|
15
15
|
<div id="root"></div>
|
package/dist/rpc-handler.js
CHANGED
|
@@ -14,7 +14,7 @@ import { listPasswords, deletePassword } from "./password-store.js";
|
|
|
14
14
|
import { currentVersion, performUpdate, performAgentUpdate } from "./update-checker.js";
|
|
15
15
|
import { PLAYWRIGHT_CLI_PACKAGE, PLAYWRIGHT_CLI_LABEL } from "./playwright-cli.js";
|
|
16
16
|
import { saveConfig } from "./config.js";
|
|
17
|
-
import { parseTaskOutcome, parseAgentModel, stripPalmierMarkers } from "./commands/run.js";
|
|
17
|
+
import { parseTaskOutcome, parseAgentModel, createCliModelCapture, stripPalmierMarkers } from "./commands/run.js";
|
|
18
18
|
import { resolveTaskFile, readTaskFileChunk } from "./task-files.js";
|
|
19
19
|
import { clearTaskQueue } from "./event-queues.js";
|
|
20
20
|
import { reconcileCommandRunner, stopCommandRunner } from "./command-runners.js";
|
|
@@ -456,8 +456,13 @@ export function createRpcHandler(config, nc) {
|
|
|
456
456
|
if (child.pid)
|
|
457
457
|
writeFollowupStatus(followupRunDir, { pid: child.pid, spawned_at: Date.now() });
|
|
458
458
|
const chunks = [];
|
|
459
|
+
const captureCliModel = createCliModelCapture(followupAgent);
|
|
460
|
+
let cliModel;
|
|
459
461
|
child.stdout?.on("data", (d) => chunks.push(d));
|
|
460
|
-
child.stderr?.on("data", (d) =>
|
|
462
|
+
child.stderr?.on("data", (d) => {
|
|
463
|
+
process.stderr.write(d);
|
|
464
|
+
cliModel = captureCliModel(d.toString("utf-8"));
|
|
465
|
+
});
|
|
461
466
|
onChildDone(child, async (code) => {
|
|
462
467
|
activeFollowups.delete(followupKey);
|
|
463
468
|
deleteFollowupStatus(followupRunDir);
|
|
@@ -466,7 +471,7 @@ export function createRpcHandler(config, nc) {
|
|
|
466
471
|
return;
|
|
467
472
|
const output = Buffer.concat(chunks).toString("utf-8");
|
|
468
473
|
const outcome = code !== 0 ? "failed" : parseTaskOutcome(output);
|
|
469
|
-
const agentModel = parseAgentModel(output);
|
|
474
|
+
const agentModel = cliModel ?? parseAgentModel(output);
|
|
470
475
|
appendRunMessage(followupTaskDir, params.run_id, {
|
|
471
476
|
role: "assistant",
|
|
472
477
|
time: Date.now(),
|