palmier 0.9.9 → 0.9.10

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.
@@ -2,7 +2,7 @@ import * as fs from "fs";
2
2
  import * as path from "path";
3
3
  import { execFileSync } from "child_process";
4
4
  import { CONFIG_DIR, loadConfig } from "../config.js";
5
- import { getTaskDir, readTaskStatus } from "../task.js";
5
+ import { getTaskDir, readTaskStatus, parseTaskFile } from "../task.js";
6
6
  const TASK_PREFIX = "\\Palmier\\PalmierTask-";
7
7
  const DAEMON_TASK_NAME = "PalmierDaemon";
8
8
  const DOW_NAMES = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"];
@@ -72,6 +72,52 @@ export function buildTaskXml(tr, triggers, foreground) {
72
72
  function schtasksTaskName(taskId) {
73
73
  return `${TASK_PREFIX}${taskId}`;
74
74
  }
75
+ function querySchtasksStatus(tn) {
76
+ try {
77
+ const out = execFileSync("schtasks", ["/query", "/tn", tn, "/v", "/fo", "LIST"], {
78
+ encoding: "utf-8", windowsHide: true, stdio: ["ignore", "pipe", "pipe"],
79
+ });
80
+ const status = out.match(/^\s*Status:\s*(.+?)\s*$/im)?.[1] ?? "";
81
+ const lastResult = out.match(/^\s*Last Result:\s*(.+?)\s*$/im)?.[1] ?? "";
82
+ return { status, lastResult };
83
+ }
84
+ catch {
85
+ return undefined;
86
+ }
87
+ }
88
+ /** Map common Last Result HRESULTs to a human-readable cause. */
89
+ function explainLastResult(lastResult, foreground) {
90
+ const code = lastResult.trim();
91
+ // Decimal forms emitted by schtasks: 267011 = 0x41303 SCHED_S_TASK_HAS_NOT_RUN.
92
+ if (code === "267011" || /0x0*41303/i.test(code)) {
93
+ return foreground
94
+ ? "Foreground mode requires an active Windows session, but no user is logged in. Sign in to Windows and try again, or disable foreground mode for this task."
95
+ : "Task Scheduler reported the task did not run. Check that the daemon has permission to launch it.";
96
+ }
97
+ if (code === "0" || code === "0x0")
98
+ return undefined;
99
+ return `Task Scheduler reported Last Result=${code}.`;
100
+ }
101
+ /**
102
+ * 2s after `schtasks /run`, confirm the action actually launched. Some failure
103
+ * modes — most notably foreground tasks with no interactive session — make
104
+ * /run return success while the action is silently skipped (Status stays
105
+ * "Ready", Last Result stays at 0x41303). If the run process has already
106
+ * written status.json by then, it clearly launched; skip the Scheduler query.
107
+ */
108
+ async function verifyTaskLaunched(tn, taskDir, startTime, foreground) {
109
+ await new Promise((r) => setTimeout(r, 2000));
110
+ const status = readTaskStatus(taskDir);
111
+ if (status && status.time_stamp >= startTime)
112
+ return;
113
+ const last = querySchtasksStatus(tn);
114
+ if (last && /running/i.test(last.status))
115
+ return;
116
+ const explained = explainLastResult(last?.lastResult ?? "", foreground);
117
+ if (explained)
118
+ throw new Error(explained);
119
+ throw new Error(`Task Scheduler did not launch the task within 2s (status=${last?.status || "unknown"}, last_result=${last?.lastResult || "unknown"}).`);
120
+ }
75
121
  export class WindowsPlatform {
76
122
  installDaemon(config) {
77
123
  const script = process.argv[1] || "palmier";
@@ -218,6 +264,13 @@ export class WindowsPlatform {
218
264
  }
219
265
  async startTask(taskId) {
220
266
  const tn = schtasksTaskName(taskId);
267
+ const taskDir = getTaskDir(loadConfig().projectRoot, taskId);
268
+ let foreground = false;
269
+ try {
270
+ foreground = !!parseTaskFile(taskDir).frontmatter.foreground_mode;
271
+ }
272
+ catch { /* fall through; verifyTaskLaunched still detects most failures */ }
273
+ const startTime = Date.now();
221
274
  try {
222
275
  execFileSync("schtasks", ["/run", "/tn", tn], { encoding: "utf-8", windowsHide: true });
223
276
  }
@@ -225,6 +278,7 @@ export class WindowsPlatform {
225
278
  const e = err;
226
279
  throw new Error(`Failed to start task via schtasks: ${e.stderr || e.message}`);
227
280
  }
281
+ await verifyTaskLaunched(tn, taskDir, startTime, foreground);
228
282
  }
229
283
  async stopTask(taskId) {
230
284
  // schtasks /end leaves agent children orphaned, so kill the process tree
@@ -84,7 +84,7 @@ ${d}`),g(S);return}f(null,T),s.strategy===xr.Count&&(m--,m===0&&g()),s.strategy=
84
84
 
85
85
  ${f.stack}`),d.unsubscribe(),c.reject(m)):(m=hx(y),m?(f&&(m.stack+=`
86
86
 
87
- ${f.stack}`),c.reject(m)):c.resolve(y))}});return d.requestSubject=t,this.protocol.publish(t,r,{reply:u,headers:s.headers}),c}else{const u=new px(this.protocol.muxSubscriptions,t,s,l);this.protocol.request(u);try{this.publish(t,r,{reply:`${this.protocol.muxSubscriptions.baseInbox}${u.token}`,headers:s.headers})}catch(f){u.cancel(f)}const c=Promise.race([u.timer,u.deferred]);return c.catch(()=>{u.cancel()}),c}}flush(){return this.isClosed()?Promise.reject(Te.errorForCode(Se.ConnectionClosed)):this.protocol.flush()}drain(){return this.isClosed()?Promise.reject(Te.errorForCode(Se.ConnectionClosed)):this.isDraining()?Promise.reject(Te.errorForCode(Se.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 an;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 Dk(this,t);if(t.checkAPI!==!1)try{await r.getAccountInfo()}catch(s){const l=s;throw l.code===Se.NoResponders&&(l.code=Se.JetStreamNotEnabled),l}return r}jetstream(t={}){return new Bd(this,t)}getServerVersion(){const t=this.info;return t?ms(t.version):void 0}async rtt(){if(!this.protocol._closed&&!this.protocol.connected)throw Te.errorForCode(Se.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 Bk(this)),this._services}reconnect(){return this.isClosed()?Promise.reject(Te.errorForCode(Se.ConnectionClosed)):this.isDraining()?Promise.reject(Te.errorForCode(Se.ConnectionDraining)):this.protocol.reconnect()}}class Bk{constructor(t){C(this,"nc");this.nc=t}add(t){try{return new Yl(this.nc,t).start()}catch(r){return Promise.reject(r)}}client(t,r){return new yk(this.nc,t,r)}}class Pk{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(zu)||"PUT"}get length(){const t=this.sm.header.get(En.MessageSizeHdr)||"";return t!==""?parseInt(t,10):this.sm.data.length}json(){return this.sm.json()}string(){return this.sm.string()}}class Hk{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(Md(this.sm.info.timestampNanos))}get revision(){return this.sm.seq}get operation(){var t;return((t=this.sm.headers)==null?void 0:t.get(zu))||"PUT"}get delta(){return this.sm.info.pending}get length(){var r;const t=((r=this.sm.headers)==null?void 0:r.get(En.MessageSizeHdr))||"";return t!==""?parseInt(t,10):this.sm.data.length}json(){return this.sm.json()}string(){return this.sm.string()}}class jx extends y2{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=ni(this.js.nc.options.inboxPrefix);this.js.nc._resub(this.sub,s);const u=this.info;u.config.name=Pi.next(),u.ordered_consumer_sequence.delivery_seq=0,u.flow_control.heartbeat_count=0,u.flow_control.fc_count=0,u.flow_control.consumer_restarts++,u.deliver=s,u.config.deliver_subject=s,u.config.deliver_policy=Vt.StartSequence,u.config.opt_start_seq=r;const c={};c.stream_name=this.info.stream,c.config=u.config;const f=`${u.api.prefix}.CONSUMER.CREATE.${u.stream}`;this.js._request(f,c,{retries:-1}).then(d=>{const m=d,y=this.sub.info;y.last=m,this.info.config=m.config,this.info.name=m.name}).catch(d=>{const m=new Te(`unable to recreate ordered consumer ${u.stream} at seq ${r}`,Se.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(Md(r))}_setupHbMonitoring(r,s=0){const l={cancelAfter:0,maxOut:2};s&&(l.cancelAfter=s);const u=this.sub,c=f=>{var y,g,x,w;const d=Q_(409,`${or.IdleHeartbeatMissed}: ${f}`,this.sub.subject);if(!((y=this.info)==null?void 0:y.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),(w=this.monitor)==null||w.restart(),!1}return!u.noIterator};this.monitor=new Ld(r,c,l)}_checkHbOrderConsumer(r){const s=r.headers.get(En.ConsumerStalledHdr);s!==""&&this.js.nc.publish(s);const l=parseInt(r.headers.get(En.LastConsumerSeqHdr),10),u=this.info.ordered_consumer_sequence;return this.info.flow_control.heartbeat_count++,l!==u.delivery_seq&&this._resetOrderedConsumer(u.stream_seq+1),!1}_checkOrderedConsumer(r){const s=this.info.ordered_consumer_sequence,l=r.info.streamSequence,u=r.info.deliverySequence;return u!=s.delivery_seq+1?(this._resetOrderedConsumer(s.stream_seq+1),!1):(s.delivery_seq=u,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}`,u=await r.api._request(l);return r.last=u,u}}class qk extends jx{constructor(t,r,s){super(t,r,s)}pull(t={batch:1}){const{stream:r,config:s,name:l}=this.sub.info,u=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(mt.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=Ut(f));let d=0;if(t.idle_heartbeat&&t.idle_heartbeat>0&&(d=t.idle_heartbeat,c.idle_heartbeat=Ut(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,y=`${m.prefix}.CONSUMER.MSG.NEXT.${r}.${u}`,g=this.sub.subject;m.nc.publish(y,m.jc.encode(c),{reply:g})}}}function Ik(e,t){return e?$k(t):Fk(t)}function Fk(e){return(t,r)=>t?[t,null]:(t=ua(r),t?[t,null]:[null,Pl(r,e)])}function $k(e){return(t,r)=>{if(t)return[t,null];const s=ua(r);return s!==null?[Tx(s),null]:[null,Pl(r,e)]}}function Tx(e){if(e!==null)switch(e.code){case Se.JetStream404NoMessages:case Se.JetStream408RequestTimeout:return null;case Se.JetStream409:return Z_(e)?e:null;default:return e}return null}function Yk(e){e&&e.ack()}function Gk(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 Vk{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=Gk(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]===xl[0]&&t[1]===xl[1]&&t[2]===xl[2]&&t[3]===xl[3]}async ackAck(t){var s;t=t||{},t.timeout=t.timeout||this.timeout;const r=Bt();if(this.didAck)r.resolve(!1);else if(this.didAck=!0,this.msg.reply){const u=this.msg.publisher,c=!((s=u.options)!=null&&s.noAsyncTraces),f=new px(u.muxSubscriptions,this.msg.reply,{timeout:t.timeout},c);u.request(f);try{u.publish(this.msg.reply,M0,{reply:`${u.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(M0)}nak(t){let r=Ak;t&&(r=Nu().encode(`-NAK ${JSON.stringify({delay:Ut(t)})}`)),this.doAck(r)}working(){this.doAck(xl)}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=Ut(r.expires));const l=vr().encode(s),u=ga.concat(jk,Nk,l),c=t?{reply:t}:void 0;this.msg.respond(u,c)}term(t=""){let r=Tk;(t==null?void 0:t.length)>0&&(r=Nu().encode(`+TERM ${t}`)),this.doAck(r)}json(){return this.msg.json()}string(){return this.msg.string()}}const Jk="1.30.3",Xk="nats.ws";class Kk{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=Jk,this.lang=Xk,this.connected=!1,this.done=!1,this.socketClosed=!1,this.encrypted=!1,this.peeked=!1,this.yields=[],this.signal=Bt(),this.closedNotification=Bt()}async connect(t,r){const s=Bt();if(r.tls)return s.reject(new Te("tls",Se.InvalidOption)),s;this.options=r;const l=t.src;if(r.wsFactory){const{socket:u,encrypted:c}=await r.wsFactory(t.src,r);this.socket=u,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=u=>{if(this.isDiscarded())return;if(this.yields.push(new Uint8Array(u.data)),this.peeked){this.signal.resolve();return}const c=ga.concat(...this.yields),f=_2(c);if(f!==""){const d=uk.exec(f);if(!d){r.debug&&console.error("!!!",cu(c)),s.reject(new Error("unexpected response from server"));return}try{const m=JSON.parse(d[1]);lk(m,this.options),this.peeked=!0,this.connected=!0,this.signal.resolve(),s.resolve()}catch(m){s.reject(m);return}}},this.socket.onclose=u=>{if(this.isDiscarded())return;this.socketClosed=!0;let c;this.done||(u.wasClean||(c=new Error(u.reason)),this._closed(c))},this.socket.onerror=u=>{if(this.isDiscarded())return;const c=u,f=new Te(c.message,Se.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 Sa(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(`> ${cu(t[r])}`),yield t[r];if(this.done)break;this.yields.length===0&&(t.length=0,this.yields=t,this.signal=Bt())}}isEncrypted(){return this.connected&&this.encrypted}send(t){if(!this.isDiscarded())try{this.socket.send(t.buffer),this.options.debug&&console.info(`< ${cu(t)}`);return}catch(r){this.options.debug&&console.error(`!!! ${cu(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 Qk(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 u,c;const f=s.hostname,d=s.pathname,m=s.search||"";switch(l){case"http:":case"ws:":case"nats:":c=s.port||"80",u="ws:";break;case"https:":case"wss:":case"tls:":c=s.port||"443",u="wss:";break;default:c=s.port||t===!0?"443":"80",u=t===!0?"wss:":"ws:";break}return`${u}//${f}:${c}${d}${m}`}function Nx(e={}){return b2({defaultPort:443,urlParseFn:Qk,factory:()=>new Kk}),Pd.connect(e)}/*! Capacitor: https://capacitorjs.com/ - MIT License */var ya;(function(e){e.Unimplemented="UNIMPLEMENTED",e.Unavailable="UNAVAILABLE"})(ya||(ya={}));class Ah extends Error{constructor(t,r,s){super(t),this.message=t,this.code=r,this.data=s}}const Zk=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"},Wk=e=>{const t=e.CapacitorCustomPlatform||null,r=e.Capacitor||{},s=r.Plugins=r.Plugins||{},l=()=>t!==null?t.name:Zk(e),u=()=>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(w=>w.name===g)},d=g=>e.console.error(g),m=new Map,y=(g,x={})=>{const w=m.get(g);if(w)return console.warn(`Capacitor plugin "${g}" already registered. Cannot register plugins twice.`),w.proxy;const S=l(),T=f(g);let z;const D=async()=>(!z&&S in x?z=typeof x[S]=="function"?z=await x[S]():z=x[S]:t!==null&&!z&&"web"in x&&(z=typeof x.web=="function"?z=await x.web():z=x.web),z),H=($,q)=>{var R,G;if(T){const J=T==null?void 0:T.methods.find(fe=>q===fe.name);if(J)return J.rtype==="promise"?fe=>r.nativePromise(g,q.toString(),fe):(fe,ie)=>r.nativeCallback(g,q.toString(),fe,ie);if($)return(R=$[q])===null||R===void 0?void 0:R.bind($)}else{if($)return(G=$[q])===null||G===void 0?void 0:G.bind($);throw new Ah(`"${g}" plugin is not implemented on ${S}`,ya.Unimplemented)}},F=$=>{let q;const R=(...G)=>{const J=D().then(fe=>{const ie=H(fe,$);if(ie){const ee=ie(...G);return q=ee==null?void 0:ee.remove,ee}else throw new Ah(`"${g}.${$}()" is not implemented on ${S}`,ya.Unimplemented)});return $==="addListener"&&(J.remove=async()=>q()),J};return R.toString=()=>`${$.toString()}() { [capacitor code] }`,Object.defineProperty(R,"name",{value:$,writable:!1,configurable:!1}),R},oe=F("addListener"),B=F("removeListener"),L=($,q)=>{const R=oe({eventName:$},q),G=async()=>{const fe=await R;B({eventName:$,callbackId:fe},q)},J=new Promise(fe=>R.then(()=>fe({remove:G})));return J.remove=async()=>{console.warn("Using addListener() without 'await' is deprecated."),await G()},J},W=new Proxy({},{get($,q){switch(q){case"$$typeof":return;case"toJSON":return()=>({});case"addListener":return T?L:oe;case"removeListener":return B;default:return F(q)}}});return s[g]=W,m.set(g,{name:g,proxy:W,platforms:new Set([...Object.keys(x),...T?[S]:[]])}),W};return r.convertFileSrc||(r.convertFileSrc=g=>g),r.getPlatform=l,r.handleError=d,r.isNativePlatform=u,r.isPluginAvailable=c,r.registerPlugin=y,r.Exception=Ah,r.DEBUG=!!r.DEBUG,r.isLoggingEnabled=!!r.isLoggingEnabled,r},eE=e=>e.Capacitor=Wk(e),Xn=eE(typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{}),ys=Xn.registerPlugin;class Hd{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 u=this.windowListeners[t];u&&!u.registered&&this.addWindowListener(u),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 u=this.retainedEventArguments[t];u||(u=[]),u.push(r),this.retainedEventArguments[t]=u}return}l.forEach(u=>u(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 Xn.Exception(t,ya.Unimplemented)}unavailable(t="not available"){return new Xn.Exception(t,ya.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 L0=e=>encodeURIComponent(e).replace(/%(2[346B]|5E|60|7C)/g,decodeURIComponent).replace(/[()]/g,escape),z0=e=>e.replace(/(%[\dA-F]{2})+/gi,decodeURIComponent);class tE extends Hd{async getCookies(){const t=document.cookie,r={};return t.split(";").forEach(s=>{if(s.length<=0)return;let[l,u]=s.replace(/=/,"CAP_COOKIE").split("CAP_COOKIE");l=z0(l).trim(),u=z0(u).trim(),r[l]=u}),r}async setCookie(t){try{const r=L0(t.key),s=L0(t.value),l=t.expires?`; expires=${t.expires.replace("expires=","")}`:"",u=(t.path||"/").replace("path=",""),c=t.url!=null&&t.url.length>0?`domain=${t.url}`:"";document.cookie=`${r}=${s||""}${l}; path=${u}; ${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)}}}ys("CapacitorCookies",{web:()=>new tE});const nE=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)}),rE=(e={})=>{const t=Object.keys(e);return Object.keys(e).map(l=>l.toLocaleLowerCase()).reduce((l,u,c)=>(l[u]=e[t[c]],l),{})},iE=(e,t=!0)=>e?Object.entries(e).reduce((s,l)=>{const[u,c]=l;let f,d;return Array.isArray(c)?(d="",c.forEach(m=>{f=t?encodeURIComponent(m):m,d+=`${u}=${f}&`}),d.slice(0,-1)):(f=t?encodeURIComponent(c):c,d=`${u}=${f}`),`${s}&${d}`},"").substr(1):null,sE=(e,t={})=>{const r=Object.assign({method:e.method||"GET",headers:e.headers},t),l=rE(e.headers)["content-type"]||"";if(typeof e.data=="string")r.body=e.data;else if(l.includes("application/x-www-form-urlencoded")){const u=new URLSearchParams;for(const[c,f]of Object.entries(e.data||{}))u.set(c,f);r.body=u.toString()}else if(l.includes("multipart/form-data")||e.data instanceof FormData){const u=new FormData;if(e.data instanceof FormData)e.data.forEach((f,d)=>{u.append(d,f)});else for(const f of Object.keys(e.data))u.append(f,e.data[f]);r.body=u;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 aE extends Hd{async request(t){const r=sE(t,t.webFetchExtra),s=iE(t.params,t.shouldEncodeUrlParams),l=s?`${t.url}?${s}`:t.url,u=await fetch(l,r),c=u.headers.get("content-type")||"";let{responseType:f="text"}=u.ok?t:{};c.includes("application/json")&&(f="json");let d,m;switch(f){case"arraybuffer":case"blob":m=await u.blob(),d=await nE(m);break;case"json":d=await u.json();break;case"document":case"text":default:d=await u.text()}const y={};return u.headers.forEach((g,x)=>{y[x]=g}),{data:d,headers:y,status:u.status,url:u.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"}))}}ys("CapacitorHttp",{web:()=>new aE});var U0;(function(e){e.Dark="DARK",e.Light="LIGHT",e.Default="DEFAULT"})(U0||(U0={}));var B0;(function(e){e.StatusBar="StatusBar",e.NavigationBar="NavigationBar"})(B0||(B0={}));class lE extends Hd{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")}}ys("SystemBars",{web:()=>new lE});const oE="modulepreload",uE=function(e){return"/"+e},P0={},qd=function(t,r,s){let l=Promise.resolve();if(r&&r.length>0){let c=function(m){return Promise.all(m.map(y=>Promise.resolve(y).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=uE(m),m in P0)return;P0[m]=!0;const y=m.endsWith(".css"),g=y?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${m}"]${g}`))return;const x=document.createElement("link");if(x.rel=y?"stylesheet":oE,y||(x.as="script"),x.crossOrigin="",x.href=m,d&&x.setAttribute("nonce",d),document.head.appendChild(x),y)return new Promise((w,S)=>{x.addEventListener("load",w),x.addEventListener("error",()=>S(new Error(`Unable to preload CSS for ${m}`)))})}))}function u(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"&&u(f.reason);return t().catch(u)})},fd=ys("App",{web:()=>qd(()=>import("./web-DSL9bja4.js"),[]).then(e=>new e.AppWeb)}),cE=ys("Network",{web:()=>qd(()=>import("./web-CYs_8c0k.js"),[]).then(e=>new e.NetworkWeb)}),Uu=Xn.isNativePlatform()?"https://app.palmier.me":"";async function Ox(e,t,r,s){const l=`${Uu}${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 fE(e,t,r){return Ox("POST",e,t)}function hE(e,t){return Ox("GET",e,void 0)}const H0=Xn.isNativePlatform(),Rx=j.createContext(null),dE=2e3,jh=6e3,mE=1500,pE=6e4;function gE({children:e,activeHost:t}){const[r,s]=j.useState(null),[l,u]=j.useState(!1),c=j.useRef(null),[f,d]=j.useState(!1),[m,y]=j.useState(!1),[g,x]=j.useState(!1),[w,S]=j.useState(!1),T=j.useRef(Nu()),z=j.useRef(new Set),D=j.useRef(0),H=!!t.directUrl,F=H0&&!H&&!!t.lanUrl&&w,oe=m||g?"disconnected":H?f?"direct":"connecting":l?F?"lan":"nats":"connecting",B=oe!=="connecting"&&oe!=="disconnected";j.useEffect(()=>{y(!1),x(!1)},[t.hostId,t.clientToken]),j.useEffect(()=>{if(!H0||H||!t.lanUrl){S(!1);return}let $=!1;const q=t.lanUrl,R=t.hostId;async function G(){console.log("[HOST/LAN] probing",q);try{const ee=await fetch(`${q}/health`,{signal:AbortSignal.timeout(mE)});if($)return;if(!ee.ok){console.log("[HOST/LAN] probe got non-ok:",ee.status),S(!1);return}const P=await ee.json(),X=P.hostId===R;X?console.log("[HOST/LAN] reachable"):console.log("[HOST/LAN] hostId mismatch — got:",P.hostId,"expected:",R),S(X)}catch(ee){$||(console.log("[HOST/LAN] probe failed:",ee instanceof Error?ee.message:ee),S(!1))}}G();const J=window.setInterval(G,pE),fe=fd.addListener("appStateChange",ee=>{ee.isActive&&G()}),ie=cE.addListener("networkStatusChange",()=>G());return()=>{$=!0,clearInterval(J),fe.then(ee=>ee.remove()),ie.then(ee=>ee.remove())}},[t.hostId,t.lanUrl,H]),j.useEffect(()=>{if(H){c.current&&(c.current.close().catch(()=>{}),c.current=null,s(null),u(!1));return}let $=!1,q=1e3;const R=3e4;async function G(){for(;!$;)try{const J=await fetch(`${Uu}/api/nats-credentials/${t.hostId}`);if($)return;if(J.status===401||J.status===403||J.status===404){console.error("[NATS] Host not found or rejected by relay:",J.status),x(!0);return}if(!J.ok)throw new Error(`credentials fetch ${J.status}`);const fe=await J.json();if(!fe.natsWsUrl){console.error("[NATS] Relay returned empty natsWsUrl — treating as terminal"),x(!0);return}if($)return;console.log("[NATS] Connecting to",fe.natsWsUrl);const ie=await Nx({servers:fe.natsWsUrl,authenticator:wx(fe.natsJwt,new TextEncoder().encode(fe.natsNkeySeed)),pingInterval:3e4,maxPingOut:2});if($){ie.close().catch(()=>{});return}if(console.log("[NATS] Connected"),c.current=ie,s(ie),u(!0),q=1e3,await ie.closed(),$)return;console.log("[NATS] Connection closed, will reconnect"),c.current=null,s(null),u(!1)}catch(J){if($)return;console.warn(`[NATS] Connect failed, retrying in ${q}ms:`,J),u(!1),await new Promise(fe=>setTimeout(fe,q)),q=Math.min(q*2,R)}}return G(),()=>{$=!0,c.current&&(c.current.close().catch(()=>{}),c.current=null,s(null),u(!1))}},[H,t]),j.useEffect(()=>{if(H)return;const $=fd.addListener("appStateChange",q=>{if(!q.isActive||!c.current)return;const R=c.current;Promise.race([R.flush(),new Promise((G,J)=>setTimeout(()=>J(new Error("ping timeout")),2e3))]).catch(()=>{console.log("[NATS] Resume probe failed — cycling conn"),R.close().catch(()=>{})})});return()=>{$.then(q=>q.remove())}},[H]),j.useEffect(()=>{if(!H){d(!1);return}const $=new AbortController;async function q(){var fe;const G=new AbortController,J=setTimeout(()=>G.abort(),dE);$.signal.addEventListener("abort",()=>G.abort());try{const ie=await fetch(`${t.directUrl}/events`,{headers:{Authorization:`Bearer ${t.clientToken}`},signal:G.signal});return clearTimeout(J),ie.ok?((fe=ie.body)==null?void 0:fe.getReader())??null:null}catch{return clearTimeout(J),null}}async function R(G){d(!0),console.log("[HOST] SSE connected to",t.directUrl),D.current=Date.now();function J(){setTimeout(()=>{$.signal.aborted||Date.now()-D.current<jh||(console.log("[HOST] Heartbeat timeout — no data for",jh/1e3,"s"),$.abort(),d(!1),console.log("[HOST] Direct host unreachable"))},jh)}J();const fe=new TextDecoder;let ie="";try{for(;;){const{done:ee,value:P}=await G.read();if(ee)break;ie+=fe.decode(P,{stream:!0}),D.current=Date.now(),J();const X=ie.split(`
87
+ ${f.stack}`),c.reject(m)):c.resolve(y))}});return d.requestSubject=t,this.protocol.publish(t,r,{reply:u,headers:s.headers}),c}else{const u=new px(this.protocol.muxSubscriptions,t,s,l);this.protocol.request(u);try{this.publish(t,r,{reply:`${this.protocol.muxSubscriptions.baseInbox}${u.token}`,headers:s.headers})}catch(f){u.cancel(f)}const c=Promise.race([u.timer,u.deferred]);return c.catch(()=>{u.cancel()}),c}}flush(){return this.isClosed()?Promise.reject(Te.errorForCode(Se.ConnectionClosed)):this.protocol.flush()}drain(){return this.isClosed()?Promise.reject(Te.errorForCode(Se.ConnectionClosed)):this.isDraining()?Promise.reject(Te.errorForCode(Se.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 an;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 Dk(this,t);if(t.checkAPI!==!1)try{await r.getAccountInfo()}catch(s){const l=s;throw l.code===Se.NoResponders&&(l.code=Se.JetStreamNotEnabled),l}return r}jetstream(t={}){return new Bd(this,t)}getServerVersion(){const t=this.info;return t?ms(t.version):void 0}async rtt(){if(!this.protocol._closed&&!this.protocol.connected)throw Te.errorForCode(Se.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 Bk(this)),this._services}reconnect(){return this.isClosed()?Promise.reject(Te.errorForCode(Se.ConnectionClosed)):this.isDraining()?Promise.reject(Te.errorForCode(Se.ConnectionDraining)):this.protocol.reconnect()}}class Bk{constructor(t){C(this,"nc");this.nc=t}add(t){try{return new Yl(this.nc,t).start()}catch(r){return Promise.reject(r)}}client(t,r){return new yk(this.nc,t,r)}}class Pk{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(zu)||"PUT"}get length(){const t=this.sm.header.get(En.MessageSizeHdr)||"";return t!==""?parseInt(t,10):this.sm.data.length}json(){return this.sm.json()}string(){return this.sm.string()}}class Hk{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(Md(this.sm.info.timestampNanos))}get revision(){return this.sm.seq}get operation(){var t;return((t=this.sm.headers)==null?void 0:t.get(zu))||"PUT"}get delta(){return this.sm.info.pending}get length(){var r;const t=((r=this.sm.headers)==null?void 0:r.get(En.MessageSizeHdr))||"";return t!==""?parseInt(t,10):this.sm.data.length}json(){return this.sm.json()}string(){return this.sm.string()}}class jx extends y2{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=ni(this.js.nc.options.inboxPrefix);this.js.nc._resub(this.sub,s);const u=this.info;u.config.name=Pi.next(),u.ordered_consumer_sequence.delivery_seq=0,u.flow_control.heartbeat_count=0,u.flow_control.fc_count=0,u.flow_control.consumer_restarts++,u.deliver=s,u.config.deliver_subject=s,u.config.deliver_policy=Vt.StartSequence,u.config.opt_start_seq=r;const c={};c.stream_name=this.info.stream,c.config=u.config;const f=`${u.api.prefix}.CONSUMER.CREATE.${u.stream}`;this.js._request(f,c,{retries:-1}).then(d=>{const m=d,y=this.sub.info;y.last=m,this.info.config=m.config,this.info.name=m.name}).catch(d=>{const m=new Te(`unable to recreate ordered consumer ${u.stream} at seq ${r}`,Se.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(Md(r))}_setupHbMonitoring(r,s=0){const l={cancelAfter:0,maxOut:2};s&&(l.cancelAfter=s);const u=this.sub,c=f=>{var y,g,x,w;const d=Q_(409,`${or.IdleHeartbeatMissed}: ${f}`,this.sub.subject);if(!((y=this.info)==null?void 0:y.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),(w=this.monitor)==null||w.restart(),!1}return!u.noIterator};this.monitor=new Ld(r,c,l)}_checkHbOrderConsumer(r){const s=r.headers.get(En.ConsumerStalledHdr);s!==""&&this.js.nc.publish(s);const l=parseInt(r.headers.get(En.LastConsumerSeqHdr),10),u=this.info.ordered_consumer_sequence;return this.info.flow_control.heartbeat_count++,l!==u.delivery_seq&&this._resetOrderedConsumer(u.stream_seq+1),!1}_checkOrderedConsumer(r){const s=this.info.ordered_consumer_sequence,l=r.info.streamSequence,u=r.info.deliverySequence;return u!=s.delivery_seq+1?(this._resetOrderedConsumer(s.stream_seq+1),!1):(s.delivery_seq=u,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}`,u=await r.api._request(l);return r.last=u,u}}class qk extends jx{constructor(t,r,s){super(t,r,s)}pull(t={batch:1}){const{stream:r,config:s,name:l}=this.sub.info,u=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(mt.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=Ut(f));let d=0;if(t.idle_heartbeat&&t.idle_heartbeat>0&&(d=t.idle_heartbeat,c.idle_heartbeat=Ut(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,y=`${m.prefix}.CONSUMER.MSG.NEXT.${r}.${u}`,g=this.sub.subject;m.nc.publish(y,m.jc.encode(c),{reply:g})}}}function Ik(e,t){return e?$k(t):Fk(t)}function Fk(e){return(t,r)=>t?[t,null]:(t=ua(r),t?[t,null]:[null,Pl(r,e)])}function $k(e){return(t,r)=>{if(t)return[t,null];const s=ua(r);return s!==null?[Tx(s),null]:[null,Pl(r,e)]}}function Tx(e){if(e!==null)switch(e.code){case Se.JetStream404NoMessages:case Se.JetStream408RequestTimeout:return null;case Se.JetStream409:return Z_(e)?e:null;default:return e}return null}function Yk(e){e&&e.ack()}function Gk(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 Vk{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=Gk(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]===xl[0]&&t[1]===xl[1]&&t[2]===xl[2]&&t[3]===xl[3]}async ackAck(t){var s;t=t||{},t.timeout=t.timeout||this.timeout;const r=Bt();if(this.didAck)r.resolve(!1);else if(this.didAck=!0,this.msg.reply){const u=this.msg.publisher,c=!((s=u.options)!=null&&s.noAsyncTraces),f=new px(u.muxSubscriptions,this.msg.reply,{timeout:t.timeout},c);u.request(f);try{u.publish(this.msg.reply,M0,{reply:`${u.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(M0)}nak(t){let r=Ak;t&&(r=Nu().encode(`-NAK ${JSON.stringify({delay:Ut(t)})}`)),this.doAck(r)}working(){this.doAck(xl)}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=Ut(r.expires));const l=vr().encode(s),u=ga.concat(jk,Nk,l),c=t?{reply:t}:void 0;this.msg.respond(u,c)}term(t=""){let r=Tk;(t==null?void 0:t.length)>0&&(r=Nu().encode(`+TERM ${t}`)),this.doAck(r)}json(){return this.msg.json()}string(){return this.msg.string()}}const Jk="1.30.3",Xk="nats.ws";class Kk{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=Jk,this.lang=Xk,this.connected=!1,this.done=!1,this.socketClosed=!1,this.encrypted=!1,this.peeked=!1,this.yields=[],this.signal=Bt(),this.closedNotification=Bt()}async connect(t,r){const s=Bt();if(r.tls)return s.reject(new Te("tls",Se.InvalidOption)),s;this.options=r;const l=t.src;if(r.wsFactory){const{socket:u,encrypted:c}=await r.wsFactory(t.src,r);this.socket=u,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=u=>{if(this.isDiscarded())return;if(this.yields.push(new Uint8Array(u.data)),this.peeked){this.signal.resolve();return}const c=ga.concat(...this.yields),f=_2(c);if(f!==""){const d=uk.exec(f);if(!d){r.debug&&console.error("!!!",cu(c)),s.reject(new Error("unexpected response from server"));return}try{const m=JSON.parse(d[1]);lk(m,this.options),this.peeked=!0,this.connected=!0,this.signal.resolve(),s.resolve()}catch(m){s.reject(m);return}}},this.socket.onclose=u=>{if(this.isDiscarded())return;this.socketClosed=!0;let c;this.done||(u.wasClean||(c=new Error(u.reason)),this._closed(c))},this.socket.onerror=u=>{if(this.isDiscarded())return;const c=u,f=new Te(c.message,Se.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 Sa(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(`> ${cu(t[r])}`),yield t[r];if(this.done)break;this.yields.length===0&&(t.length=0,this.yields=t,this.signal=Bt())}}isEncrypted(){return this.connected&&this.encrypted}send(t){if(!this.isDiscarded())try{this.socket.send(t.buffer),this.options.debug&&console.info(`< ${cu(t)}`);return}catch(r){this.options.debug&&console.error(`!!! ${cu(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 Qk(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 u,c;const f=s.hostname,d=s.pathname,m=s.search||"";switch(l){case"http:":case"ws:":case"nats:":c=s.port||"80",u="ws:";break;case"https:":case"wss:":case"tls:":c=s.port||"443",u="wss:";break;default:c=s.port||t===!0?"443":"80",u=t===!0?"wss:":"ws:";break}return`${u}//${f}:${c}${d}${m}`}function Nx(e={}){return b2({defaultPort:443,urlParseFn:Qk,factory:()=>new Kk}),Pd.connect(e)}/*! Capacitor: https://capacitorjs.com/ - MIT License */var ya;(function(e){e.Unimplemented="UNIMPLEMENTED",e.Unavailable="UNAVAILABLE"})(ya||(ya={}));class Ah extends Error{constructor(t,r,s){super(t),this.message=t,this.code=r,this.data=s}}const Zk=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"},Wk=e=>{const t=e.CapacitorCustomPlatform||null,r=e.Capacitor||{},s=r.Plugins=r.Plugins||{},l=()=>t!==null?t.name:Zk(e),u=()=>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(w=>w.name===g)},d=g=>e.console.error(g),m=new Map,y=(g,x={})=>{const w=m.get(g);if(w)return console.warn(`Capacitor plugin "${g}" already registered. Cannot register plugins twice.`),w.proxy;const S=l(),T=f(g);let z;const D=async()=>(!z&&S in x?z=typeof x[S]=="function"?z=await x[S]():z=x[S]:t!==null&&!z&&"web"in x&&(z=typeof x.web=="function"?z=await x.web():z=x.web),z),H=($,q)=>{var R,G;if(T){const J=T==null?void 0:T.methods.find(fe=>q===fe.name);if(J)return J.rtype==="promise"?fe=>r.nativePromise(g,q.toString(),fe):(fe,ie)=>r.nativeCallback(g,q.toString(),fe,ie);if($)return(R=$[q])===null||R===void 0?void 0:R.bind($)}else{if($)return(G=$[q])===null||G===void 0?void 0:G.bind($);throw new Ah(`"${g}" plugin is not implemented on ${S}`,ya.Unimplemented)}},F=$=>{let q;const R=(...G)=>{const J=D().then(fe=>{const ie=H(fe,$);if(ie){const ee=ie(...G);return q=ee==null?void 0:ee.remove,ee}else throw new Ah(`"${g}.${$}()" is not implemented on ${S}`,ya.Unimplemented)});return $==="addListener"&&(J.remove=async()=>q()),J};return R.toString=()=>`${$.toString()}() { [capacitor code] }`,Object.defineProperty(R,"name",{value:$,writable:!1,configurable:!1}),R},oe=F("addListener"),B=F("removeListener"),L=($,q)=>{const R=oe({eventName:$},q),G=async()=>{const fe=await R;B({eventName:$,callbackId:fe},q)},J=new Promise(fe=>R.then(()=>fe({remove:G})));return J.remove=async()=>{console.warn("Using addListener() without 'await' is deprecated."),await G()},J},W=new Proxy({},{get($,q){switch(q){case"$$typeof":return;case"toJSON":return()=>({});case"addListener":return T?L:oe;case"removeListener":return B;default:return F(q)}}});return s[g]=W,m.set(g,{name:g,proxy:W,platforms:new Set([...Object.keys(x),...T?[S]:[]])}),W};return r.convertFileSrc||(r.convertFileSrc=g=>g),r.getPlatform=l,r.handleError=d,r.isNativePlatform=u,r.isPluginAvailable=c,r.registerPlugin=y,r.Exception=Ah,r.DEBUG=!!r.DEBUG,r.isLoggingEnabled=!!r.isLoggingEnabled,r},eE=e=>e.Capacitor=Wk(e),Xn=eE(typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{}),ys=Xn.registerPlugin;class Hd{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 u=this.windowListeners[t];u&&!u.registered&&this.addWindowListener(u),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 u=this.retainedEventArguments[t];u||(u=[]),u.push(r),this.retainedEventArguments[t]=u}return}l.forEach(u=>u(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 Xn.Exception(t,ya.Unimplemented)}unavailable(t="not available"){return new Xn.Exception(t,ya.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 L0=e=>encodeURIComponent(e).replace(/%(2[346B]|5E|60|7C)/g,decodeURIComponent).replace(/[()]/g,escape),z0=e=>e.replace(/(%[\dA-F]{2})+/gi,decodeURIComponent);class tE extends Hd{async getCookies(){const t=document.cookie,r={};return t.split(";").forEach(s=>{if(s.length<=0)return;let[l,u]=s.replace(/=/,"CAP_COOKIE").split("CAP_COOKIE");l=z0(l).trim(),u=z0(u).trim(),r[l]=u}),r}async setCookie(t){try{const r=L0(t.key),s=L0(t.value),l=t.expires?`; expires=${t.expires.replace("expires=","")}`:"",u=(t.path||"/").replace("path=",""),c=t.url!=null&&t.url.length>0?`domain=${t.url}`:"";document.cookie=`${r}=${s||""}${l}; path=${u}; ${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)}}}ys("CapacitorCookies",{web:()=>new tE});const nE=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)}),rE=(e={})=>{const t=Object.keys(e);return Object.keys(e).map(l=>l.toLocaleLowerCase()).reduce((l,u,c)=>(l[u]=e[t[c]],l),{})},iE=(e,t=!0)=>e?Object.entries(e).reduce((s,l)=>{const[u,c]=l;let f,d;return Array.isArray(c)?(d="",c.forEach(m=>{f=t?encodeURIComponent(m):m,d+=`${u}=${f}&`}),d.slice(0,-1)):(f=t?encodeURIComponent(c):c,d=`${u}=${f}`),`${s}&${d}`},"").substr(1):null,sE=(e,t={})=>{const r=Object.assign({method:e.method||"GET",headers:e.headers},t),l=rE(e.headers)["content-type"]||"";if(typeof e.data=="string")r.body=e.data;else if(l.includes("application/x-www-form-urlencoded")){const u=new URLSearchParams;for(const[c,f]of Object.entries(e.data||{}))u.set(c,f);r.body=u.toString()}else if(l.includes("multipart/form-data")||e.data instanceof FormData){const u=new FormData;if(e.data instanceof FormData)e.data.forEach((f,d)=>{u.append(d,f)});else for(const f of Object.keys(e.data))u.append(f,e.data[f]);r.body=u;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 aE extends Hd{async request(t){const r=sE(t,t.webFetchExtra),s=iE(t.params,t.shouldEncodeUrlParams),l=s?`${t.url}?${s}`:t.url,u=await fetch(l,r),c=u.headers.get("content-type")||"";let{responseType:f="text"}=u.ok?t:{};c.includes("application/json")&&(f="json");let d,m;switch(f){case"arraybuffer":case"blob":m=await u.blob(),d=await nE(m);break;case"json":d=await u.json();break;case"document":case"text":default:d=await u.text()}const y={};return u.headers.forEach((g,x)=>{y[x]=g}),{data:d,headers:y,status:u.status,url:u.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"}))}}ys("CapacitorHttp",{web:()=>new aE});var U0;(function(e){e.Dark="DARK",e.Light="LIGHT",e.Default="DEFAULT"})(U0||(U0={}));var B0;(function(e){e.StatusBar="StatusBar",e.NavigationBar="NavigationBar"})(B0||(B0={}));class lE extends Hd{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")}}ys("SystemBars",{web:()=>new lE});const oE="modulepreload",uE=function(e){return"/"+e},P0={},qd=function(t,r,s){let l=Promise.resolve();if(r&&r.length>0){let c=function(m){return Promise.all(m.map(y=>Promise.resolve(y).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=uE(m),m in P0)return;P0[m]=!0;const y=m.endsWith(".css"),g=y?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${m}"]${g}`))return;const x=document.createElement("link");if(x.rel=y?"stylesheet":oE,y||(x.as="script"),x.crossOrigin="",x.href=m,d&&x.setAttribute("nonce",d),document.head.appendChild(x),y)return new Promise((w,S)=>{x.addEventListener("load",w),x.addEventListener("error",()=>S(new Error(`Unable to preload CSS for ${m}`)))})}))}function u(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"&&u(f.reason);return t().catch(u)})},fd=ys("App",{web:()=>qd(()=>import("./web-CSpTDg3Y.js"),[]).then(e=>new e.AppWeb)}),cE=ys("Network",{web:()=>qd(()=>import("./web-DgnrddCL.js"),[]).then(e=>new e.NetworkWeb)}),Uu=Xn.isNativePlatform()?"https://app.palmier.me":"";async function Ox(e,t,r,s){const l=`${Uu}${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 fE(e,t,r){return Ox("POST",e,t)}function hE(e,t){return Ox("GET",e,void 0)}const H0=Xn.isNativePlatform(),Rx=j.createContext(null),dE=2e3,jh=6e3,mE=1500,pE=6e4;function gE({children:e,activeHost:t}){const[r,s]=j.useState(null),[l,u]=j.useState(!1),c=j.useRef(null),[f,d]=j.useState(!1),[m,y]=j.useState(!1),[g,x]=j.useState(!1),[w,S]=j.useState(!1),T=j.useRef(Nu()),z=j.useRef(new Set),D=j.useRef(0),H=!!t.directUrl,F=H0&&!H&&!!t.lanUrl&&w,oe=m||g?"disconnected":H?f?"direct":"connecting":l?F?"lan":"nats":"connecting",B=oe!=="connecting"&&oe!=="disconnected";j.useEffect(()=>{y(!1),x(!1)},[t.hostId,t.clientToken]),j.useEffect(()=>{if(!H0||H||!t.lanUrl){S(!1);return}let $=!1;const q=t.lanUrl,R=t.hostId;async function G(){console.log("[HOST/LAN] probing",q);try{const ee=await fetch(`${q}/health`,{signal:AbortSignal.timeout(mE)});if($)return;if(!ee.ok){console.log("[HOST/LAN] probe got non-ok:",ee.status),S(!1);return}const P=await ee.json(),X=P.hostId===R;X?console.log("[HOST/LAN] reachable"):console.log("[HOST/LAN] hostId mismatch — got:",P.hostId,"expected:",R),S(X)}catch(ee){$||(console.log("[HOST/LAN] probe failed:",ee instanceof Error?ee.message:ee),S(!1))}}G();const J=window.setInterval(G,pE),fe=fd.addListener("appStateChange",ee=>{ee.isActive&&G()}),ie=cE.addListener("networkStatusChange",()=>G());return()=>{$=!0,clearInterval(J),fe.then(ee=>ee.remove()),ie.then(ee=>ee.remove())}},[t.hostId,t.lanUrl,H]),j.useEffect(()=>{if(H){c.current&&(c.current.close().catch(()=>{}),c.current=null,s(null),u(!1));return}let $=!1,q=1e3;const R=3e4;async function G(){for(;!$;)try{const J=await fetch(`${Uu}/api/nats-credentials/${t.hostId}`);if($)return;if(J.status===401||J.status===403||J.status===404){console.error("[NATS] Host not found or rejected by relay:",J.status),x(!0);return}if(!J.ok)throw new Error(`credentials fetch ${J.status}`);const fe=await J.json();if(!fe.natsWsUrl){console.error("[NATS] Relay returned empty natsWsUrl — treating as terminal"),x(!0);return}if($)return;console.log("[NATS] Connecting to",fe.natsWsUrl);const ie=await Nx({servers:fe.natsWsUrl,authenticator:wx(fe.natsJwt,new TextEncoder().encode(fe.natsNkeySeed)),pingInterval:3e4,maxPingOut:2});if($){ie.close().catch(()=>{});return}if(console.log("[NATS] Connected"),c.current=ie,s(ie),u(!0),q=1e3,await ie.closed(),$)return;console.log("[NATS] Connection closed, will reconnect"),c.current=null,s(null),u(!1)}catch(J){if($)return;console.warn(`[NATS] Connect failed, retrying in ${q}ms:`,J),u(!1),await new Promise(fe=>setTimeout(fe,q)),q=Math.min(q*2,R)}}return G(),()=>{$=!0,c.current&&(c.current.close().catch(()=>{}),c.current=null,s(null),u(!1))}},[H,t]),j.useEffect(()=>{if(H)return;const $=fd.addListener("appStateChange",q=>{if(!q.isActive||!c.current)return;const R=c.current;Promise.race([R.flush(),new Promise((G,J)=>setTimeout(()=>J(new Error("ping timeout")),2e3))]).catch(()=>{console.log("[NATS] Resume probe failed — cycling conn"),R.close().catch(()=>{})})});return()=>{$.then(q=>q.remove())}},[H]),j.useEffect(()=>{if(!H){d(!1);return}const $=new AbortController;async function q(){var fe;const G=new AbortController,J=setTimeout(()=>G.abort(),dE);$.signal.addEventListener("abort",()=>G.abort());try{const ie=await fetch(`${t.directUrl}/events`,{headers:{Authorization:`Bearer ${t.clientToken}`},signal:G.signal});return clearTimeout(J),ie.ok?((fe=ie.body)==null?void 0:fe.getReader())??null:null}catch{return clearTimeout(J),null}}async function R(G){d(!0),console.log("[HOST] SSE connected to",t.directUrl),D.current=Date.now();function J(){setTimeout(()=>{$.signal.aborted||Date.now()-D.current<jh||(console.log("[HOST] Heartbeat timeout — no data for",jh/1e3,"s"),$.abort(),d(!1),console.log("[HOST] Direct host unreachable"))},jh)}J();const fe=new TextDecoder;let ie="";try{for(;;){const{done:ee,value:P}=await G.read();if(ee)break;ie+=fe.decode(P,{stream:!0}),D.current=Date.now(),J();const X=ie.split(`
88
88
  `);ie=X.pop()??"";for(const ae of X)if(ae.startsWith("data: ")){const pe=ae.slice(6);try{const M=JSON.parse(pe);if(M.task_id&&M.event_type){const E=`host-event.${t.hostId}.${M.task_id}`;for(const K of z.current)K({subject:E,data:T.current.encode(pe)})}}catch{}}}}catch{}}return(async()=>{const G=await q();G&&await R(G)})(),()=>{$.abort(),d(!1)}},[t,H]);const L=j.useCallback(async($,q,R)=>{function G(ie){ie&&typeof ie=="object"&&ie.error==="Unauthorized"&&y(!0)}async function J(ie,ee){console.log(`[HOST/${ee}] → ${$}`,q??"");const P=await fetch(`${ie}/rpc/${$}`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t.clientToken}`},body:q!=null?JSON.stringify(q):void 0,signal:R!=null&&R.timeout?AbortSignal.timeout(R.timeout):void 0});if(P.status===401)throw y(!0),new Error("Unauthorized");const X=await P.json();return G(X),console.log(`[HOST/${ee}] ← ${$}`,X),X}async function fe(){if(!c.current)throw new Error("Not connected");const ie=`host.${t.hostId}.rpc.${$}`,ee={...q??{},clientToken:t.clientToken},P=T.current.encode(JSON.stringify(ee));console.log(`[HOST/NATS] → ${$}`,q??"");const X=await c.current.request(ie,P,{timeout:(R==null?void 0:R.timeout)??1e4}),ae=JSON.parse(T.current.decode(X.data));return G(ae),console.log(`[HOST/NATS] ← ${$}`,ae),ae}if(H)return J(t.directUrl,"HTTP");if(F&&t.lanUrl)try{return await J(t.lanUrl,"LAN")}catch(ie){if(ie instanceof Error&&ie.message==="Unauthorized")throw ie;console.log("[HOST/LAN] failed, falling back to NATS:",ie),S(!1)}return fe()},[t,H,F]),W=j.useCallback(($,q)=>{if(H)return z.current.add(q),()=>{z.current.delete(q)};if(c.current){const R=c.current.subscribe(`host-event.${$}.>`);let G=!1;return(async()=>{try{for await(const J of R){if(G)break;q({subject:J.subject,data:J.data})}}catch{}})(),()=>{G=!0,R.unsubscribe()}}return()=>{}},[t,H]);return b.jsx(Rx.Provider,{value:{connected:B,mode:oe,nc:r,request:L,subscribeEvents:W,activeHost:t,unauthorized:m},children:e})}function si(){const e=j.useContext(Rx);if(!e)throw new Error("useHostConnection must be used within HostConnectionProvider");return e}const mn=Xn.isNativePlatform()?ys("Device"):null;function yE(e,t){const r=new Date(e),s=new Date,l=r.toLocaleTimeString(void 0,{hour:"numeric",minute:"2-digit",timeZone:t}),u={year:"numeric",month:"2-digit",day:"2-digit",timeZone:t};return r.toLocaleDateString(void 0,u)===s.toLocaleDateString(void 0,u)?l:`${r.toLocaleDateString(void 0,{month:"short",day:"numeric",timeZone:t})} ${l}`}function Id(){const{activeHost:e}=si(),t=e.timezone;return j.useCallback(r=>yE(r,t),[t])}function bE(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(u=>u.type===s))==null?void 0:l.value)??""};return{date:`${r("year")}-${r("month")}-${r("day")}`,time:`${r("hour")}:${r("minute")}`}}const Mx={};function xE(e){for(const t of e)Mx[t.key]=t.label}function hd(e){return Mx[e]??e}const vE=()=>window.matchMedia("(max-width: 600px)").matches;function wE({task:e,lastEvent:t,onEdit:r,onDelete:s,onViewRun:l}){var P;const{request:u,activeHost:c}=si(),f=Id(),d=c.timezone,[m,y]=j.useState(!1),[g,x]=j.useState(!1),[w,S]=j.useState(!1),T=j.useRef(null),z=(t==null?void 0:t.running_state)==="started",D=(((P=e.schedule_values)==null?void 0:P.length)??0)>0,H=e.schedule_type==="on_new_notification"||e.schedule_type==="on_new_sms",oe=!!e.schedule_enabled&&!!e.schedule_type&&(D||H)?z?"var(--color-success)":(t==null?void 0:t.running_state)==="failed"?"var(--color-error)":"var(--color-success)":"var(--color-text-secondary)";j.useEffect(()=>{if(!g)return;function X(ae){T.current&&!T.current.contains(ae.target)&&x(!1)}return document.addEventListener("mousedown",X),()=>document.removeEventListener("mousedown",X)},[g]);function B(){vE()?S(!0):x(X=>!X)}function L(){x(!1),S(!1)}async function W(){if(L(),!!confirm("Abort this task?")){y(!0);try{await u("task.abort",{id:e.id})}catch(X){console.error("Abort failed:",X)}finally{y(!1)}}}async function $(){L();try{const X=await u("task.run",{id:e.id});l(e.id,X.run_id)}catch(X){console.error("Run failed:",X)}}async function q(){if(L(),!!confirm("Delete this task? Results and reports will be kept."))try{await u("task.delete",{id:e.id}),s(e.id)}catch(X){console.error("Delete failed:",X)}}const R={started:"Started",finished:"Finished",aborted:"Aborted",failed:"Failed"};function G(X,ae){if(X==="specific_times"){const Ge=new Date(ae);return{kind:"specific_times",detail:isNaN(Ge.getTime())?ae:`${Ge.toLocaleDateString(void 0,{month:"short",day:"numeric",year:"numeric",timeZone:d})} at ${Ge.toLocaleTimeString(void 0,{hour:"numeric",minute:"2-digit",timeZone:d})}`}}const pe=ae.split(" ");if(pe.length!==5)return{kind:"unknown",detail:ae};const[M,E,K,,A]=pe,be=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"];if(E==="*")return{kind:"hourly",detail:""};const je=Number(E),_e=Number(M),Me=je===0?12:je>12?je-12:je,Ie=je>=12?"PM":"AM",ke=`${Me}:${String(_e).padStart(2,"0")} ${Ie}`;return A!=="*"?{kind:"weekly",detail:`${be[Number(A)]??A} at ${ke}`}:K!=="*"?{kind:"monthly",detail:`day ${K} at ${ke}`}:{kind:"daily",detail:ke}}function J(X,ae){const pe=G(X,ae);return pe.kind==="hourly"?"Every hour":pe.kind==="specific_times"?`Once on ${pe.detail}`:`${pe.kind.charAt(0).toUpperCase()+pe.kind.slice(1)}: ${pe.detail}`}function fe(X,ae){if(!X)return"";if(X==="on_new_notification")return"On new notification";if(X==="on_new_sms")return"On new SMS";if(!ae||ae.length===0)return"";if(ae.length===1)return J(X,ae[0]);const pe=ae.map(E=>G(X,E));if(new Set(pe.map(E=>E.kind)).size===1){const E=pe[0].kind;if(E==="hourly")return"Every hour";const K=pe.map(A=>A.detail);return`${E.charAt(0).toUpperCase()+E.slice(1)}: ${K.join(", ")}`}return ae.map(E=>J(X,E)).join(", ")}const ie=fe(e.schedule_type,e.schedule_values),ee=b.jsxs(b.Fragment,{children:[b.jsxs("button",{onClick:()=>{L(),r(e)},children:[b.jsx("span",{className:"menu-icon",children:"✎"}),"Edit"]}),b.jsxs("button",{onClick:()=>{L(),l(e.id)},children:[b.jsx("span",{className:"menu-icon",children:"📄"}),"View All Runs"]}),z?b.jsxs("button",{className:"menu-item-danger",onClick:W,disabled:m,children:[b.jsx("span",{className:"menu-icon",children:"◼"}),"Abort"]}):b.jsxs(b.Fragment,{children:[b.jsxs("button",{onClick:$,children:[b.jsx("span",{className:"menu-icon",children:"▶"}),"Run Now"]}),b.jsxs("button",{className:"menu-item-danger",onClick:q,children:[b.jsx("span",{className:"menu-icon",children:"🗑"}),"Delete"]})]})]});return b.jsxs(b.Fragment,{children:[b.jsxs("div",{className:"task-card",onClick:()=>l(e.id,"latest"),children:[b.jsxs("div",{className:"task-card-header",children:[b.jsxs("div",{className:"task-card-title-row",children:[z?b.jsx("span",{className:"status-spinner",children:b.jsx("span",{})}):b.jsx("span",{className:"status-dot",style:{backgroundColor:oe}}),b.jsx("h3",{className:"task-card-name",children:e.name||e.user_prompt})]}),b.jsx("div",{className:"task-card-actions",onClick:X=>X.stopPropagation(),children:b.jsxs("div",{className:"task-card-menu",ref:T,children:[b.jsx("button",{className:"task-card-menu-btn",onClick:B,"aria-label":"Task actions",children:"⋮"}),g&&b.jsx("div",{className:"task-card-menu-dropdown",children:ee})]})})]}),b.jsxs("div",{className:"task-card-meta",children:[e.agent&&b.jsx("span",{className:"task-card-agent",children:hd(e.agent)}),t&&R[t.running_state]&&b.jsxs("span",{className:"task-card-last-event",children:[R[t.running_state]," ",f(t.time_stamp)]}),e.schedule_type&&(D||H)&&b.jsx("span",{className:"task-card-triggers",children:e.schedule_enabled?ie:"Schedule disabled"})]})]}),w&&ds.createPortal(b.jsx("div",{className:"bottom-sheet-overlay",onClick:()=>S(!1),children:b.jsxs("div",{className:"bottom-sheet",onClick:X=>X.stopPropagation(),children:[b.jsx("div",{className:"bottom-sheet-handle"}),b.jsx("div",{className:"bottom-sheet-title",children:e.name||e.user_prompt}),b.jsx("div",{className:"bottom-sheet-actions",children:ee})]})}),document.body)]})}function SE({permissions:e}){return b.jsxs("div",{className:"permissions-dialog",children:[b.jsx("h2",{children:"Granted Permissions"}),b.jsx("div",{className:"permissions-dialog-scroll",children:e&&e.length>0?b.jsx("div",{className:"permissions-section",children:b.jsx("ul",{className:"permissions-list",children:e.map((t,r)=>b.jsxs("li",{className:"permission-item",children:[b.jsx("span",{className:"permission-tool",children:t.name}),b.jsx("span",{className:"permission-desc",children:t.description})]},r))})}):b.jsx("p",{className:"permissions-empty",children:"No permissions have been granted for this task."})}),b.jsx("div",{className:"permissions-dialog-actions",children:b.jsx("button",{className:"btn btn-secondary",onClick:()=>history.back(),children:"Back"})})]})}const ra=[];function _E(){const e=ra.pop();e&&(e.pushed.current=!1,e.close())}let q0=!1;function kE(){q0||(q0=!0,window.addEventListener("popstate",_E))}function dd(e,t){const r=j.useRef(!1),s=j.useRef(t);s.current=t;const l=j.useCallback(()=>s.current(),[]),u=j.useRef({close:l,pushed:r});u.current.close=l,j.useEffect(()=>{if(e&&!r.current)kE(),history.pushState({modal:!0},""),ra.push(u.current),r.current=!0;else if(!e&&r.current){r.current=!1;const c=ra.indexOf(u.current);c!==-1&&ra.splice(c,1),history.back()}},[e,l]),j.useEffect(()=>{const c=u.current;return()=>{if(r.current){r.current=!1;const f=ra.indexOf(c);f!==-1&&ra.splice(f,1),history.back()}}},[])}const EE=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],CE=["specific_times","hourly","daily","weekly","monthly"];function mu(e){return CE.includes(e)}function AE(e){return e==="on_new_notification"||e==="on_new_sms"}function ti(e="daily"){return{schedule:e,time:"00:00",dayOfWeek:"1",dayOfMonth:"1",onceDate:"",onceTime:"00:00"}}function jE(e){const t=e.split(" ");if(t.length!==5)return ti();const[r,s,l,,u]=t;if(s==="*")return ti("hourly");const c=`${s.padStart(2,"0")}:${r.padStart(2,"0")}`;return u!=="*"?{...ti("weekly"),time:c,dayOfWeek:u}:l!=="*"?{...ti("monthly"),time:c,dayOfMonth:l}:{...ti("daily"),time:c}}function Dx(e,t){if(e==="specific_times"){const[r,s]=t.split("T");return{...ti("specific_times"),onceDate:r??"",onceTime:(s??"09:00").slice(0,5)}}return jE(t)}function TE(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 NE(e){return e.schedule==="specific_times"?e.onceDate?`${e.onceDate}T${e.onceTime}`:null:TE(e)}function Th(e){return e==="specific_times"?"specific_times":e==="on_new_notification"?"on_new_notification":e==="on_new_sms"?"on_new_sms":"crons"}function Nh(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?Dx(t,r).schedule:"ondemand"}function OE({initial:e,agents:t,hostPlatform:r,isNotificationListener:s,onSaved:l,onRun:u,onCancel:c}){var dt;const{request:f,activeHost:d}=si(),{setHostLastAgent:m}=qi(),y=()=>{var Re;const xe=d.lastAgent,qe=t.map(At=>At.key);return xe&&qe.includes(xe)?xe:((Re=t[0])==null?void 0:Re.key)??""},[g,x]=j.useState((e==null?void 0:e.user_prompt)??""),[w,S]=j.useState((e==null?void 0:e.agent)??y()),T=!!((dt=e==null?void 0:e.permissions)!=null&&dt.length),[z,D]=j.useState(!1),H=j.useCallback(()=>D(!1),[]);dd(z,H);const[F,oe]=j.useState(null),[B,L]=j.useState(()=>Nh(e)),[W,$]=j.useState(()=>{const xe=e==null?void 0:e.schedule_type,qe=e==null?void 0:e.schedule_values;if(qe&&(xe==="crons"||xe==="specific_times"))return qe.map(At=>Dx(xe,At));const Re=Nh(e);return mu(Re)?[ti(Re)]:[]}),[q,R]=j.useState((e==null?void 0:e.requires_confirmation)??!1),[G,J]=j.useState(e!=null&&e.schedule_type?e.schedule_enabled??!0:!0),[fe,ie]=j.useState((e==null?void 0:e.yolo_mode)??!1),[ee,P]=j.useState((e==null?void 0:e.foreground_mode)??!1),[X,ae]=j.useState((e==null?void 0:e.command)??""),[pe,M]=j.useState(!1),E=(e==null?void 0:e.schedule_type)==="on_new_notification"&&e.schedule_values&&e.schedule_values.length>0?e.schedule_values[0]:"",[K,A]=j.useState(E),[be,je]=j.useState([]),[_e,Me]=j.useState(!1),[Ie,ke]=j.useState(!1),[Ge,Ft]=j.useState(""),ze=j.useCallback(()=>ke(!1),[]);dd(Ie,ze),j.useEffect(()=>{if(B!=="on_new_notification"||!s||!Xn.isNativePlatform()||!mn)return;let xe=!1;return Me(!0),mn.getInstalledApps().then(({apps:qe})=>{if(xe)return;const Re="com.palmier.app",At=qe.filter(Lt=>Lt.packageName!==Re).sort((Lt,xn)=>(Lt.appName||Lt.packageName).localeCompare(xn.appName||xn.packageName));je(At)}).catch(()=>{}).finally(()=>{xe||Me(!1)}),()=>{xe=!0}},[B,s]);const Ae=(e==null?void 0:e.schedule_type)==="on_new_sms"&&e.schedule_values&&e.schedule_values.length>0?e.schedule_values[0]:"",[Le,nt]=j.useState(Ae),Ve=j.useRef(null),Je=mu(B),We=B==="command",Fe=AE(B),et=t.find(xe=>xe.key===w),ft=!!(et!=null&&et.supportsYolo);j.useEffect(()=>{!ft&&fe&&ie(!1)},[ft,fe]);const ht=!!e,Wt=Nh(e),$e=!ht||g!==((e==null?void 0:e.user_prompt)??"")||w!==((e==null?void 0:e.agent)??"")||B!==Wt||q!==((e==null?void 0:e.requires_confirmation)??!1)||G!==(e!=null&&e.schedule_type?e.schedule_enabled??!0:!0)||fe!==((e==null?void 0:e.yolo_mode)??!1)||ee!==((e==null?void 0:e.foreground_mode)??!1)||We&&X!==((e==null?void 0:e.command)??"")||Je&&(JSON.stringify(bn())!==JSON.stringify((e==null?void 0:e.schedule_values)??[])||Th(B)!==((e==null?void 0:e.schedule_type)??void 0))||Fe&&B!==(e==null?void 0:e.schedule_type)||B==="on_new_notification"&&K.trim()!==E.trim()||B==="on_new_sms"&&Le.trim()!==Ae.trim(),yn=bE(d.timezone),ce=Je&&W.some(xe=>xe.schedule==="specific_times"&&(!xe.onceDate||xe.onceDate<yn.date||xe.onceDate===yn.date&&(xe.onceTime??"")<=yn.time)),we=$e&&!!g.trim()&&!ce&&(!We||!!X.trim())&&(!Je||W.length>0);function Ue(xe,qe){$(Re=>Re.map((At,Lt)=>Lt===xe?{...At,...qe}:At))}function Ke(xe){$(qe=>qe.filter((Re,At)=>At!==xe))}function ut(){mu(B)&&$(xe=>[...xe,xe.length>0?{...xe[xe.length-1]}:ti(B)])}function ln(xe){L(xe),mu(xe)?$([ti(xe)]):($([]),R(!1)),xe==="command"?setTimeout(()=>{var qe;return(qe=Ve.current)==null?void 0:qe.focus()},0):ae(""),xe!=="on_new_notification"&&A(E),xe!=="on_new_sms"&&nt(Ae)}function bn(){return W.flatMap(xe=>{const qe=NE(xe);return qe?[qe]:[]})}function en(){return fe?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 xt(){M(!0),oe(null);try{const xe=Je?bn():B==="on_new_notification"&&K.trim()?[K.trim()]:B==="on_new_sms"&&Le.trim()?[Le.trim()]:[],qe=Je||Fe?Th(B):null,Re={user_prompt:g,agent:w,schedule_type:qe,schedule_values:xe.length>0?xe:null,schedule_enabled:B==="ondemand"?!0:G,requires_confirmation:Je?q:!1,yolo_mode:fe,foreground_mode:ee,command:We?X:""};ht&&(Re.id=e.id);const Lt=await f(ht?"task.update":"task.create",Re,{timeout:45e3});if(Lt.error){oe(Lt.error);return}if(ht||m(d.hostId,w),We&&!ht){l(Lt);try{const xn=await f("task.run",{id:Lt.id});xn.run_id?u(Lt.id,xn.run_id):xn.error||u(Lt.id)}catch{}return}l(Lt)}catch(xe){oe(xe instanceof Error?xe.message:String(xe))}finally{M(!1)}}const $t=ht?"Save":We?"Run":(Je||Fe)&&G?"Schedule":"Save";return b.jsxs("div",{className:"task-form-overlay",children:[b.jsx("div",{className:"task-form",children:z?b.jsx(SE,{permissions:e==null?void 0:e.permissions}):b.jsxs(b.Fragment,{children:[b.jsx("div",{className:"task-form-header",children:b.jsx("h2",{children:e?"Edit Task":"New Task"})}),F&&b.jsx("div",{className:"form-error",children:F}),b.jsx("textarea",{autoFocus:!e,className:"form-textarea",value:g,onChange:xe=>x(xe.target.value),placeholder:We?"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:pe}),b.jsxs("div",{className:"plan-actions",children:[b.jsxs("div",{className:"agent-picker-section-inline",children:[b.jsx("span",{className:"agent-picker-label",children:"Run with"}),b.jsx("select",{className:"form-select form-select-sm",value:w,onChange:xe=>S(xe.target.value),disabled:pe,children:t.map(xe=>b.jsx("option",{value:xe.key,children:xe.label},xe.key))})]}),ft&&b.jsxs("label",{className:"yolo-inline",style:{marginLeft:"auto"},children:[b.jsx("input",{type:"checkbox",checked:fe,onChange:xe=>ie(xe.target.checked),disabled:pe}),"Yolo"]}),ft&&fe&&b.jsx("p",{className:"yolo-warning",children:"The agent will auto-approve all tool calls without asking for permission."}),T&&b.jsx("div",{className:"granted-permissions-row",children:b.jsx("button",{className:"btn btn-link",onClick:()=>D(!0),children:"Granted Permissions"})})]}),b.jsx("div",{className:"toggles-group",children:b.jsxs("div",{className:"schedule-section",children:[b.jsxs("h3",{className:"schedule-section-title",children:["Schedule ",b.jsx("span",{className:"schedule-section-hint",children:"based on host time"})]}),b.jsxs("select",{className:"form-select",value:B,onChange:xe=>ln(xe.target.value),disabled:pe,children:[b.jsx("option",{value:"ondemand",children:"On Demand"}),b.jsx("option",{value:"specific_times",children:"Specific Times"}),b.jsx("option",{value:"hourly",children:"Hourly"}),b.jsx("option",{value:"daily",children:"Daily"}),b.jsx("option",{value:"weekly",children:"Weekly"}),b.jsx("option",{value:"monthly",children:"Monthly"}),b.jsx("option",{value:"on_new_notification",children:"On New Notification"}),b.jsx("option",{value:"on_new_sms",children:"On New SMS"}),b.jsx("option",{value:"command",children:"Command-triggered"})]}),Fe&&b.jsxs("div",{className:"schedule-reactive",children:[b.jsxs("p",{className:"command-help-text",children:[B==="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 ",B==="on_new_notification"?"notification":"SMS","”."]}),B==="on_new_notification"&&(()=>{const xe=be.find(Re=>Re.packageName===K),qe=(xe==null?void 0:xe.appName)||K;return b.jsxs(b.Fragment,{children:[s?K.trim()?b.jsxs("div",{className:"app-filter-selected",children:[b.jsx("span",{className:"app-filter-selected-name",children:qe}),(xe==null?void 0:xe.appName)&&b.jsx("span",{className:"app-filter-selected-pkg",children:xe.packageName}),b.jsx("button",{type:"button",className:"app-filter-selected-clear",onClick:()=>A(""),"aria-label":"Clear app filter",disabled:pe,children:"✕"})]}):b.jsx("button",{type:"button",className:"btn btn-link app-filter-trigger",onClick:()=>{Ft(""),ke(!0)},disabled:pe,children:"Select app"}):b.jsx("input",{className:"form-input",type:"text",value:K,onChange:Re=>A(Re.target.value),placeholder:"App (optional), e.g. com.google.android.gm",disabled:pe}),b.jsx("p",{className:"command-help-text app-filter-help",children:K.trim()?`Only notifications from ${qe} will trigger this task.`:"Every notification from your device triggers this task."})]})})(),B==="on_new_sms"&&b.jsxs(b.Fragment,{children:[b.jsx("input",{className:"form-input",type:"text",value:Le,onChange:xe=>nt(xe.target.value),placeholder:"From (optional), e.g. +1 555-1234)",disabled:pe}),b.jsx("p",{className:"command-help-text app-filter-help",children:Le.trim()?`Only SMS from ${Le.trim()} will trigger this task. Formatting (spaces, dashes, parens) is ignored.`:"Every SMS that arrives on your device triggers this task."})]})]}),We&&b.jsxs("div",{className:"schedule-reactive",children:[b.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."}),b.jsx("input",{ref:Ve,className:"form-input form-input-mono",type:"text",value:X,onChange:xe=>ae(xe.target.value),placeholder:"gws gmail +watch --project my-project",disabled:pe})]}),Je&&B!=="hourly"&&b.jsxs(b.Fragment,{children:[W.map((xe,qe)=>b.jsxs("div",{className:"trigger-row-card",children:[b.jsxs("div",{className:"trigger-row-content",children:[B==="daily"&&b.jsx("input",{className:"form-input",type:"time",value:xe.time,onChange:Re=>Ue(qe,{time:Re.target.value})}),B==="weekly"&&b.jsxs("div",{className:"trigger-row-top",children:[b.jsx("select",{className:"form-select",value:xe.dayOfWeek,onChange:Re=>Ue(qe,{dayOfWeek:Re.target.value}),children:EE.map((Re,At)=>b.jsx("option",{value:String(At),children:Re},At))}),b.jsx("input",{className:"form-input",type:"time",value:xe.time,onChange:Re=>Ue(qe,{time:Re.target.value})})]}),B==="monthly"&&b.jsxs("div",{className:"trigger-row-top",children:[b.jsx("select",{className:"form-select",value:xe.dayOfMonth,onChange:Re=>Ue(qe,{dayOfMonth:Re.target.value}),children:Array.from({length:28},(Re,At)=>At+1).map(Re=>b.jsxs("option",{value:String(Re),children:["Day ",Re]},Re))}),b.jsx("input",{className:"form-input",type:"time",value:xe.time,onChange:Re=>Ue(qe,{time:Re.target.value})})]}),B==="specific_times"&&b.jsxs("div",{className:"trigger-row-top",children:[b.jsx("input",{className:"form-input",type:"date",value:xe.onceDate,min:yn.date,onChange:Re=>Ue(qe,{onceDate:Re.target.value})}),b.jsx("input",{className:"form-input",type:"time",value:xe.onceTime,min:xe.onceDate===yn.date?yn.time:void 0,onChange:Re=>Ue(qe,{onceTime:Re.target.value})})]})]}),W.length>1&&b.jsx("button",{className:"trigger-remove-btn",onClick:()=>Ke(qe),title:"Remove trigger",children:"×"})]},qe)),b.jsx("button",{className:"trigger-add-btn",onClick:ut,children:"+ Add"})]}),r==="win32"&&b.jsxs("label",{className:"toggle-label",children:[b.jsx("input",{type:"checkbox",checked:ee,onChange:xe=>P(xe.target.checked),disabled:pe}),"Run in the foreground (host must login to Windows)"]}),Je&&b.jsxs("label",{className:"toggle-label",children:[b.jsx("input",{type:"checkbox",checked:q,onChange:xe=>R(xe.target.checked),disabled:pe}),"Confirm before each run"]}),B!=="ondemand"&&b.jsxs("label",{className:"toggle-label",children:[b.jsx("input",{type:"checkbox",checked:G,onChange:xe=>J(xe.target.checked),disabled:pe}),"Enabled"]})]})}),!fe&&et&&!et.supportsPermissions&&b.jsxs("div",{className:"form-warning",children:["Palmier does not support runtime permission granting for ",et.label,". The task may fail if required permissions are not pre-configured."]}),b.jsxs("div",{className:"form-actions",children:[b.jsxs("button",{className:"btn btn-primary",onClick:()=>en()&&xt(),disabled:!we||pe,children:[pe&&b.jsx("span",{className:"btn-spinner"}),$t]}),b.jsx("button",{className:"btn btn-secondary",onClick:()=>{$e&&g.trim()&&!confirm("You have unsaved changes. Discard?")||c()},style:{marginLeft:"auto"},children:"Cancel"})]})]})}),Ie&&(()=>{const xe=Ge.trim().toLowerCase(),qe=xe?be.filter(Re=>Re.packageName.toLowerCase().includes(xe)||Re.appName.toLowerCase().includes(xe)):be;return b.jsx("div",{className:"app-filter-overlay",onClick:ze,children:b.jsxs("div",{className:"app-filter-dialog",onClick:Re=>Re.stopPropagation(),children:[b.jsxs("div",{className:"app-filter-header",children:[b.jsx("h2",{children:"Select app"}),b.jsx("button",{className:"app-filter-close",onClick:ze,"aria-label":"Close",children:b.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",children:b.jsx("path",{d:"M4 4L12 12M12 4L4 12",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})})})]}),b.jsx("input",{className:"form-input app-filter-search",type:"text",value:Ge,onChange:Re=>Ft(Re.target.value),onKeyDown:Re=>{Re.key==="Enter"&&Ge.trim()&&(A(Ge.trim()),ze())},placeholder:"Search or type a package name",autoFocus:!0}),b.jsxs("ul",{className:"app-filter-list",children:[_e&&be.length===0?Array.from({length:6}).map((Re,At)=>b.jsx("li",{className:"app-filter-row app-filter-skeleton",children:b.jsx("div",{className:"app-filter-skeleton-bar"})},`sk-${At}`)):qe.length===0&&!Ge.trim()?b.jsx("li",{className:"app-filter-empty",children:"No apps"}):qe.map(Re=>b.jsx("li",{className:"app-filter-row",onClick:()=>{A(Re.packageName),ze()},children:b.jsxs("div",{className:"app-filter-row-labels",children:[b.jsx("div",{className:"app-filter-row-name",children:Re.appName||Re.packageName}),Re.appName&&b.jsx("div",{className:"app-filter-row-pkg",children:Re.packageName})]})},Re.packageName)),Ge.trim()&&b.jsx("li",{className:"app-filter-row",onClick:()=>{A(Ge.trim()),ze()},children:b.jsx("div",{className:"app-filter-row-labels",children:b.jsx("div",{className:"app-filter-row-name",children:Ge.trim()})})})]})]})})})()]})}function Lx({pullDistance:e,refreshing:t,threshold:r}){const s=e>0||t,l=e>=r;return b.jsx("div",{className:"pull-to-refresh",style:{transform:`translateY(${e}px)`,opacity:s?Math.min(1,e/30):0},"aria-hidden":!s,children:b.jsx("div",{className:"pull-to-refresh-badge",children:t?b.jsx("div",{className:"spinner"}):b.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:[b.jsx("line",{x1:"12",y1:"5",x2:"12",y2:"19"}),b.jsx("polyline",{points:"19 12 12 19 5 12"})]})})})}function zx({onRefresh:e,threshold:t=70,maxPull:r=110,enabled:s=!0}){const[l,u]=j.useState(0),[c,f]=j.useState(!1),d=j.useRef(null),m=j.useRef(!1),y=j.useRef(0),g=j.useRef(!1),x=j.useRef(e);return j.useEffect(()=>{x.current=e}),j.useEffect(()=>{if(!s)return;const w=z=>{if(g.current||window.scrollY>0){d.current=null;return}if(RE(z.target)){d.current=null;return}d.current=z.touches[0].clientY,m.current=!1,y.current=0},S=z=>{if(g.current||d.current==null)return;const D=z.touches[0].clientY-d.current;if(D<=0){m.current=!1,y.current=0,u(0);return}m.current=!0;const H=Math.min(r,D*.5);y.current=H,u(H),z.cancelable&&z.preventDefault()},T=()=>{if(!m.current){d.current=null,u(0);return}const z=y.current;d.current=null,m.current=!1,y.current=0,z>=t?(g.current=!0,f(!0),u(t),Promise.resolve(x.current()).catch(()=>{}).finally(()=>{g.current=!1,f(!1),u(0)})):u(0)};return window.addEventListener("touchstart",w,{passive:!0}),window.addEventListener("touchmove",S,{passive:!1}),window.addEventListener("touchend",T,{passive:!0}),window.addEventListener("touchcancel",T,{passive:!0}),()=>{window.removeEventListener("touchstart",w),window.removeEventListener("touchmove",S),window.removeEventListener("touchend",T),window.removeEventListener("touchcancel",T)}},[s,t,r]),{pullDistance:l,refreshing:c,threshold:t}}function RE(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 ME({connected:e,hostId:t,request:r,subscribeEvents:s,agents:l,hostPlatform:u,isNotificationListener:c,onViewRun:f}){const[d,m]=j.useState([]),[y,g]=j.useState(!1),[x,w]=j.useState(null),[S,T]=j.useState(new Map),[z,D]=j.useState(!1),[H,F]=j.useState(void 0),oe=j.useCallback(()=>{D(!1),F(void 0)},[]),B=j.useCallback(async()=>{if(e){g(!0),w(null);try{const R=(await r("task.list")).tasks??[],G=new Map;for(const J of R)J.status&&G.set(J.id,J.status);T(G),m(R)}catch(q){const R=q instanceof Error?q.message:String(q);R==="Not connected"||R.includes("503")||R.toLowerCase().includes("no responders")?w(null):w(R),m([])}finally{g(!1)}}},[e,t,r]);j.useEffect(()=>{e?B():(m([]),g(!1))},[e,t,B]);const L=zx({onRefresh:B,enabled:e});j.useEffect(()=>!e||!t?void 0:s(t,async R=>{const G=R.subject.split(".");if(G.length<3)return;const J=G.slice(2).join(".");let fe={};try{fe=JSON.parse(new TextDecoder().decode(R.data))}catch{return}const ie=fe.event_type;if(!(ie!=="running-state"&&ie!=="permission-resolved"))try{const ee=await r("task.status",{id:J},{timeout:5e3});if(ee.error)return;T(P=>{const X=new Map(P);return X.set(J,ee),X})}catch{}}),[e,t,s,r]);function W(q){m(R=>{const G=R.findIndex(J=>J.id===q.id);if(G>=0){const J=[...R];return J[G]=q,J}return[q,...R]}),D(!1),F(void 0)}function $(q){m(R=>R.filter(G=>G.id!==q)),T(R=>{const G=new Map(R);return G.delete(q),G})}return b.jsxs(b.Fragment,{children:[b.jsx(Lx,{pullDistance:L.pullDistance,refreshing:L.refreshing,threshold:L.threshold}),x&&b.jsxs("div",{className:"form-error",children:[x,x.toLowerCase().includes("failed to fetch")&&b.jsxs(b.Fragment,{children:[" ",b.jsx("a",{href:"#",onClick:q=>{q.preventDefault(),window.location.reload()},children:"Reload"})]})]}),y&&!d.length?b.jsx("div",{className:"task-list",children:[0,1,2].map(q=>b.jsxs("div",{className:"task-card",style:{pointerEvents:"none"},children:[b.jsx("div",{className:"task-card-header",children:b.jsxs("div",{className:"task-card-title-row",children:[b.jsx("div",{className:"skeleton-line",style:{width:10,height:10,borderRadius:"50%"}}),b.jsx("div",{className:"skeleton-line",style:{width:`${60+q*12}%`}})]})}),b.jsxs("div",{className:"task-card-meta",children:[b.jsx("div",{className:"skeleton-line",style:{width:"30%"}}),b.jsx("div",{className:"skeleton-line",style:{width:"25%"}})]})]},q))}):d.length===0?b.jsxs("div",{className:"empty-state",children:[b.jsx("p",{className:"empty-state-text",children:"No tasks yet"}),b.jsx("p",{className:"empty-state-hint",children:"Tap the + button to create your first task."})]}):b.jsx("div",{className:"task-list",children:d.map(q=>b.jsx(wE,{task:q,lastEvent:S.get(q.id),onEdit:async R=>{try{const G=await r("task.get",{id:R.id});F(G.error?R:G)}catch{F(R)}D(!0)},onDelete:$,onViewRun:f},q.id))}),b.jsx("button",{className:"fab",onClick:()=>{F(void 0),D(!0)},"aria-label":"New task",title:"New task",children:b.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",children:[b.jsx("line",{x1:"12",y1:"5",x2:"12",y2:"19"}),b.jsx("line",{x1:"5",y1:"12",x2:"19",y2:"12"})]})}),z&&b.jsx(OE,{initial:H,agents:l,hostPlatform:u,isNotificationListener:c,onSaved:W,onRun:f,onCancel:oe})]})}let ha=null;function I0(e){ha&&(e.preventDefault(),e.returnValue="")}function Oh(e){const t=!!ha;ha=e;const r=!!ha;r&&!t?window.addEventListener("beforeunload",I0):!r&&t&&window.removeEventListener("beforeunload",I0)}function ps(){return ha?window.confirm(ha):!0}function DE(){const e=Mr(),t=cr(),{hostId:r}=$u(),s=t.pathname.endsWith("/tasks"),l=!s;function u(c){ps()&&r&&e(`/hosts/${encodeURIComponent(r)}${c}`)}return b.jsxs(b.Fragment,{children:[b.jsxs("button",{className:`tab-btn ${l?"tab-btn-active":""}`,onClick:()=>u(""),children:[b.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:b.jsx("path",{d:"M2 8H4.5L6 4L8 12L10 6L11.5 8H14"})}),"Sessions"]}),b.jsxs("button",{className:`tab-btn ${s?"tab-btn-active":""}`,onClick:()=>u("/tasks"),children:[b.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:[b.jsx("rect",{x:"2",y:"2",width:"12",height:"12",rx:"2"}),b.jsx("path",{d:"M5.5 8L7 9.5L10.5 6"})]}),"Tasks"]})]})}function Ux(e){const[t,r]=j.useState(()=>window.matchMedia(e).matches);return j.useEffect(()=>{const s=window.matchMedia(e),l=u=>r(u.matches);return s.addEventListener("change",l),r(s.matches),()=>s.removeEventListener("change",l)},[e]),t}const ku=Xn.isNativePlatform(),LE=["Device","Data","Messaging"],zE=[{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 UE(){if(!ku||!mn)return new Set;try{const{capabilities:e}=await mn.getCapabilityStatus();return new Set(e.filter(t=>t.enabled).map(t=>t.name))}catch{return new Set}}function Bx({onChange:e,confirmDisable:t=!1}){const[r,s]=j.useState(new Map),[l,u]=j.useState(null),[c,f]=j.useState(null),d=j.useCallback(async()=>{if(!(!ku||!mn))try{const{capabilities:S}=await mn.getCapabilityStatus(),T=new Map;for(const z of S)T.set(z.name,z);s(T),e==null||e(new Set(S.filter(z=>z.enabled).map(z=>z.name)))}catch(S){console.error("Failed to read capability status:",S)}},[e]);j.useEffect(()=>{d()},[d]),j.useEffect(()=>{if(!ku)return;const S=fd.addListener("resume",d);return()=>{S.then(T=>T.remove())}},[d]);async function m(S,T){if(mn){u(S.capability);try{const z=await mn.setCapabilityEnabled({capability:S.capability,enabled:T});!z.enabled&&z.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(z){console.error(`Failed to toggle ${S.capability}:`,z)}finally{u(null)}}}function y(S){const T=r.get(S.capability);if(T){if(T.enabled&&t){f(S);return}m(S,!T.enabled)}}function g(){const S=c;S&&(f(null),m(S,!1))}if(!ku)return null;const x=LE.map(S=>({group:S,items:zE.filter(T=>{const z=r.get(T.capability);return T.group===S&&(z==null?void 0:z.supported)})})).filter(S=>S.items.length>0);if(x.length===0)return b.jsx("div",{className:"capability-toggles-loading",children:b.jsx("span",{className:"spinner"})});const w=c&&ds.createPortal(b.jsx("div",{className:"confirm-modal-overlay",onClick:()=>f(null),children:b.jsxs("div",{className:"confirm-modal",onClick:S=>S.stopPropagation(),children:[b.jsxs("h2",{className:"confirm-modal-title",children:["Disable ",c.label,"?"]}),b.jsxs("p",{className:"confirm-modal-message",children:["All hosts linked to this device will no longer be able to use ",c.label,"."]}),b.jsxs("div",{className:"confirm-modal-actions",children:[b.jsx("button",{className:"btn btn-secondary",onClick:()=>f(null),children:"Cancel"}),b.jsx("button",{className:"btn btn-danger",onClick:g,children:"Disable"})]})]})}),document.body);return b.jsxs(b.Fragment,{children:[x.map(({group:S,items:T},z)=>b.jsx("div",{className:z>0?"drawer-toggle-group drawer-toggle-group-divided":"drawer-toggle-group",children:T.map(D=>{const H=r.get(D.capability),F=!!(H!=null&&H.enabled);return b.jsxs("label",{className:"drawer-toggle",children:[b.jsx("span",{className:"drawer-toggle-label",children:D.label}),b.jsx("button",{className:`toggle-switch ${F?"toggle-switch-on":""}`,onClick:()=>y(D),disabled:l===D.capability,role:"switch","aria-checked":F,children:b.jsx("span",{className:"toggle-switch-thumb"})})]},D.capability)})},S)),w]})}const F0=!!window.__PALMIER_SERVE__&&(window.location.hostname==="localhost"||window.location.hostname==="127.0.0.1"),BE=Xn.isNativePlatform();function $0({daemonVersion:e,linkedClientToken:t,request:r,onEnabledCapabilitiesChange:s,onLinkedClientTokenChange:l}){var ze;const{pairedHosts:u,removePairedHost:c,renamePairedHost:f}=qi(),{activeHost:d}=si(),m=Mr(),y=cr(),x=$u().hostId??null,w=d.clientToken||null,S=!!w&&t===w,T=Ux("(min-width: 768px)"),[z,D]=j.useState(!1),[H,F]=j.useState(()=>Date.now());j.useEffect(()=>{const Ae=()=>F(Date.now()),Le=6e4-Date.now()%6e4,nt=setTimeout(()=>{Ae();const Ve=setInterval(Ae,6e4);nt._iv=Ve},Le);return()=>{const Ve=nt._iv;Ve&&clearInterval(Ve),clearTimeout(nt)}},[]);const oe=d.timezone?new Date(H).toLocaleString(void 0,{month:"short",day:"numeric",hour:"numeric",minute:"2-digit",timeZone:d.timezone}):"";async function B(){if(!(!mn||!r||!w)){D(!0);try{const{token:Ae}=await mn.getFcmToken();if(!Ae)return;await r("device.link",{fcmToken:Ae}),l==null||l(w)}catch(Ae){console.error("Failed to make this the linked device:",Ae)}finally{D(!1)}}}async function L(Ae){const Le=Ae===x;if(Le&&r)try{await r("clients.revoke_self")}catch{}c(Ae),X(null),Le&&m("/",{replace:!0})}function W(Ae){const nt=y.pathname.endsWith("/tasks")?"/tasks":"";m(`/hosts/${encodeURIComponent(Ae)}${nt}`)}const[$,q]=j.useState(!1),[R,G]=j.useState(!1),[J,fe]=j.useState(null),[ie,ee]=j.useState(""),[P,X]=j.useState(null),[ae,pe]=j.useState(!1),M=j.useRef(null),E=j.useRef(null),K=j.useCallback(()=>{G(!0)},[]);function A(){R&&(q(!1),G(!1))}function be(){G(!1),q(!0)}function je(Ae,Le){fe(Ae),ee(Le)}function _e(){J&&ie.trim()&&f(J,ie.trim()),fe(null),ee("")}function Me(){fe(null),ee("")}j.useEffect(()=>{J&&E.current&&(E.current.focus(),E.current.select())},[J]),j.useEffect(()=>{if(!$||R)return;function Ae(Le){Le.key==="Escape"&&K()}return document.addEventListener("keydown",Ae),()=>{document.removeEventListener("keydown",Ae)}},[$,R,K]);const Ie=b.jsxs(b.Fragment,{children:[!T&&b.jsx("button",{className:"drawer-close-btn",onClick:K,"aria-label":"Close menu",children:b.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",children:b.jsx("path",{d:"M4 4L12 12M12 4L4 12",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})})}),!F0&&u.length>0&&b.jsxs("div",{className:"drawer-section",children:[b.jsx("h3",{className:"drawer-section-label",children:"Hosts"}),b.jsx("div",{className:"host-picker-inline",children:b.jsx("div",{className:"host-picker-list",role:"listbox",children:u.map(Ae=>{const Le=Ae.hostId===x,nt=J===Ae.hostId,Ve=Ae.name||Ae.hostId.slice(0,8);return b.jsx("div",{className:"host-picker-item-wrapper",children:b.jsxs("div",{className:`host-picker-item ${Le?"host-picker-item-active":""}`,onClick:()=>{if(!nt&&!Le){if(!ps())return;W(Ae.hostId),T||K()}},role:"option","aria-selected":Le,children:[nt?b.jsx("input",{ref:E,className:"form-input host-picker-rename-input",type:"text",value:ie,onChange:Je=>ee(Je.target.value),onKeyDown:Je=>{Je.key==="Enter"&&_e(),Je.key==="Escape"&&Me()},onBlur:_e,onClick:Je=>Je.stopPropagation()}):b.jsx("span",{className:"host-picker-item-name",children:Ve}),b.jsxs("div",{className:"host-picker-item-actions",children:[Le&&!nt&&b.jsx("button",{className:"host-picker-edit-btn",onClick:Je=>{Je.stopPropagation(),je(Ae.hostId,Ve)},"aria-label":"Rename host",children:b.jsx("svg",{width:"13",height:"13",viewBox:"0 0 13 13",fill:"none",children:b.jsx("path",{d:"M9.5 1.5L11.5 3.5M1.5 11.5L2 9L9 2L11 4L4 11L1.5 11.5Z",stroke:"currentColor",strokeWidth:"1.2",strokeLinecap:"round",strokeLinejoin:"round"})})}),!Le&&b.jsx("button",{className:"host-picker-delete-btn",onClick:Je=>{Je.stopPropagation(),X(Ae.hostId)},"aria-label":`Unpair ${Ve}`,children:b.jsx("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",children:b.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"})})})]})]})},Ae.hostId)})})})]}),!F0&&b.jsxs(b.Fragment,{children:[b.jsx("div",{className:"drawer-divider"}),b.jsx("div",{className:"drawer-section",children:b.jsx("button",{className:"btn btn-primary btn-full",onClick:()=>{ps()&&(m("/pair"),T||K())},children:"Add New Host"})})]}),BE&&r&&b.jsxs(b.Fragment,{children:[b.jsx("div",{className:"drawer-divider"}),b.jsxs("div",{className:"drawer-section",children:[b.jsx("h3",{className:"drawer-section-label",children:"Device Capabilities"}),S?b.jsx(Bx,{onChange:s,confirmDisable:!0}):b.jsxs(b.Fragment,{children:[b.jsx("p",{className:"drawer-section-hint",children:"This device isn't the linked device for the host, so it can't provide capabilities (SMS, contacts, location, etc.)."}),b.jsx("button",{className:"btn btn-secondary btn-full",onClick:()=>{t&&t!==w?pe(!0):B()},disabled:z,children:z?"Linking…":"Link the host to this device"})]})]})]}),b.jsxs("div",{className:"drawer-footer",children:[d.timezone&&b.jsxs("div",{className:"drawer-host-time",children:["Host time: ",oe," · ",d.timezone]}),e&&b.jsxs("div",{className:"drawer-version",children:["Host version: v",e]}),b.jsxs("div",{className:"drawer-legal",children:[b.jsx("a",{href:"https://www.palmier.me/terms",target:"_blank",rel:"noopener noreferrer",children:"Terms"}),b.jsx("span",{className:"drawer-legal-sep",children:"·"}),b.jsx("a",{href:"https://www.palmier.me/privacy",target:"_blank",rel:"noopener noreferrer",children:"Privacy"})]})]})]}),ke=!!P&&P===x&&S,Ge=P&&ds.createPortal(b.jsx("div",{className:"confirm-modal-overlay",onClick:()=>X(null),children:b.jsxs("div",{className:"confirm-modal",onClick:Ae=>Ae.stopPropagation(),children:[b.jsx("h2",{className:"confirm-modal-title",children:"Remove host?"}),b.jsxs("p",{className:"confirm-modal-message",children:['"',((ze=u.find(Ae=>Ae.hostId===P))==null?void 0:ze.name)||P.slice(0,8),'" will be ',ke?"removed and unlinked":"removed",".",ke&&b.jsx(b.Fragment,{children:" This device is currently linked to the host — unlinking will revoke its access to all device capabilities (SMS, contacts, location, etc.) until another device is linked."})]}),b.jsxs("div",{className:"confirm-modal-actions",children:[b.jsx("button",{className:"btn btn-secondary",onClick:()=>X(null),children:"Cancel"}),b.jsx("button",{className:"btn btn-danger",onClick:()=>L(P),children:"Remove"})]})]})}),document.body),Ft=ae&&ds.createPortal(b.jsx("div",{className:"confirm-modal-overlay",onClick:()=>pe(!1),children:b.jsxs("div",{className:"confirm-modal",onClick:Ae=>Ae.stopPropagation(),children:[b.jsx("h2",{className:"confirm-modal-title",children:"Link the host to this device?"}),b.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."}),b.jsxs("div",{className:"confirm-modal-actions",children:[b.jsx("button",{className:"btn btn-secondary",onClick:()=>pe(!1),children:"Cancel"}),b.jsx("button",{className:"btn btn-primary",onClick:()=>{pe(!1),B()},children:"Link"})]})]})}),document.body);return T?b.jsxs(b.Fragment,{children:[b.jsx("div",{className:"drawer-panel drawer-panel-desktop",ref:M,children:Ie}),Ge,Ft]}):b.jsxs(b.Fragment,{children:[b.jsx("button",{className:"hamburger-btn",onClick:be,"aria-label":"Open menu",children:b.jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"none",children:b.jsx("path",{d:"M3 5H17M3 10H17M3 15H17",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})})}),$&&ds.createPortal(b.jsx("div",{className:`drawer-overlay ${R?"drawer-overlay-closing":""}`,onClick:K,onAnimationEnd:A,children:b.jsx("div",{className:`drawer-panel ${R?"drawer-panel-closing":""}`,ref:M,onClick:Ae=>Ae.stopPropagation(),children:Ie})}),document.body),Ge,Ft]})}const PE=Xn.isNativePlatform(),Fd={width:16,height:16,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};function HE(){return b.jsxs("svg",{...Fd,"aria-hidden":"true",children:[b.jsx("path",{d:"M3 11 L12 3 L21 11"}),b.jsx("path",{d:"M5 9.5 V21 H19 V9.5"})]})}function Y0(){return b.jsxs("svg",{...Fd,"aria-hidden":"true",children:[b.jsx("circle",{cx:"12",cy:"12",r:"10"}),b.jsx("line",{x1:"2",y1:"12",x2:"22",y2:"12"}),b.jsx("path",{d:"M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"})]})}function qE(){return b.jsxs("svg",{...Fd,"aria-hidden":"true",children:[b.jsx("path",{d:"M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"}),b.jsx("line",{x1:"12",y1:"9",x2:"12",y2:"13"}),b.jsx("line",{x1:"12",y1:"17",x2:"12.01",y2:"17"})]})}function IE(){const{mode:e}=si(),[t,r]=j.useState(!1),s=j.useRef(null);if(j.useEffect(()=>{if(!t)return;function f(m){var y;(y=s.current)!=null&&y.contains(m.target)||r(!1)}document.addEventListener("pointerdown",f);const d=window.setTimeout(()=>r(!1),3e3);return()=>{document.removeEventListener("pointerdown",f),clearTimeout(d)}},[t]),e==="direct")return null;let l,u,c;switch(e){case"lan":l=b.jsx(HE,{}),u="Connected via LAN",c="lan";break;case"nats":l=b.jsx(Y0,{}),u=PE?"Connected via relay":"Connected",c="relay";break;case"disconnected":l=b.jsx(qE,{}),u="Disconnected",c="disconnected";break;case"connecting":default:l=b.jsx(Y0,{}),u="Connecting…",c="connecting";break}return b.jsxs("div",{ref:s,className:`conn-status conn-status--${c}`,children:[b.jsx("button",{type:"button",className:"conn-status-btn","aria-label":u,onClick:()=>r(f=>!f),children:l}),b.jsx("div",{className:`conn-status-popover ${t?"conn-status-popover--open":""}`,role:"tooltip",children:u})]})}function G0(e,t){var s;const r=e.map(l=>l.key);return t&&r.includes(t)?t:((s=e[0])==null?void 0:s.key)??""}function FE({agents:e,hostPlatform:t,onStarted:r}){const{request:s,activeHost:l}=si(),{setHostLastAgent:u}=qi(),[c,f]=j.useState(""),[d,m]=j.useState(()=>G0(e,l.lastAgent)),[y,g]=j.useState(!1),[x,w]=j.useState(!1),[S,T]=j.useState(null);j.useEffect(()=>{e.length&&(e.find(L=>L.key===d)||m(G0(e,l.lastAgent)))},[e,d,l.lastAgent]),j.useEffect(()=>{const L=c.trim().length>0;return Oh(L?"Your session draft will be lost. Continue?":null),()=>Oh(null)},[c]);const z=e.find(L=>L.key===d),D=!!(z!=null&&z.supportsYolo);j.useEffect(()=>{!D&&y&&g(!1)},[D,y]);const H=!!c.trim()&&!!d&&!x;function F(){return y?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.
@@ -117,4 +117,4 @@ Are you sure you want to continue?`):!0}async function oe(){if(!(!H||!F())){w(!0
117
117
  `))+1))}const c="#".repeat(l),f=r.enter("headingAtx"),d=r.enter("phrasing");u.move(c+" ");let m=r.containerPhrasing(e,{before:"# ",after:`
118
118
  `,...u.current()});return/^[\t ]/.test(m)&&(m=ql(m.charCodeAt(0))+m.slice(1)),m=m?c+" "+m:c,r.options.closeAtx&&(m+=" "+c),d(),f(),m}C1.peek=r3;function C1(e){return e.value||""}function r3(){return"<"}A1.peek=i3;function A1(e,t,r,s){const l=sm(r),u=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${u}`),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 i3(){return"!"}j1.peek=s3;function j1(e,t,r,s){const l=e.referenceType,u=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 y=r.stack;r.stack=[],c=r.enter("reference");const g=r.safe(r.associationId(e),{before:d,after:"]",...f.current()});return c(),r.stack=y,u(),l==="full"||!m||m!==g?d+=f.move(g+"]"):l==="shortcut"?d=d.slice(0,-1):d+=f.move("]"),d}function s3(){return"!"}T1.peek=a3;function T1(e,t,r){let s=e.value||"",l="`",u=-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+" ");++u<r.unsafe.length;){const c=r.unsafe[u],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 a3(){return"`"}function N1(e,t){const r=Kd(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))}O1.peek=l3;function O1(e,t,r,s){const l=sm(r),u=l==='"'?"Quote":"Apostrophe",c=r.createTracker(s);let f,d;if(N1(e,r)){const y=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=y,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${u}`),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 N1(e,r)?"<":"["}R1.peek=o3;function R1(e,t,r,s){const l=e.referenceType,u=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 y=r.stack;r.stack=[],c=r.enter("reference");const g=r.safe(r.associationId(e),{before:d,after:"]",...f.current()});return c(),r.stack=y,u(),l==="full"||!m||m!==g?d+=f.move(g+"]"):l==="shortcut"?d=d.slice(0,-1):d+=f.move("]"),d}function o3(){return"["}function am(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=am(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 c3(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 M1(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 f3(e,t,r,s){const l=r.enter("list"),u=r.bulletCurrent;let c=e.ordered?c3(r):am(r);const f=e.ordered?c==="."?")":".":u3(r);let d=t&&r.bulletLastUsed?c===r.bulletLastUsed:!1;if(!e.ordered){const y=e.children?e.children[0]:void 0;if((c==="*"||c==="-")&&y&&(!y.children||!y.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),M1(r)===c&&y){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=u,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 d3(e,t,r,s){const l=h3(r);let u=r.bulletCurrent||am(r);t&&t.type==="list"&&t.ordered&&(u=(typeof t.start=="number"&&t.start>-1?t.start:1)+(r.options.incrementListMarker===!1?0:t.children.indexOf(e))+u);let c=u.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(u+" ".repeat(c-u.length)),f.shift(c);const d=r.enter("listItem"),m=r.indentLines(r.containerFlow(e,f.current()),y);return d(),m;function y(g,x,w){return x?(w?"":" ".repeat(c))+g:(w?u:u+" ".repeat(c-u.length))+g}}function m3(e,t,r,s){const l=r.enter("paragraph"),u=r.enter("phrasing"),c=r.containerPhrasing(e,s);return u(),l(),c}const p3=ec(["break","delete","emphasis","footnote","footnoteReference","image","imageReference","inlineCode","inlineMath","link","linkReference","mdxJsxTextElement","mdxTextExpression","strong","text","textDirective"]);function g3(e,t,r,s){return(e.children.some(function(c){return p3(c)})?r.containerPhrasing:r.containerFlow).call(r,e,s)}function y3(e){const t=e.options.strong||"*";if(t!=="*"&&t!=="_")throw new Error("Cannot serialize strong with `"+t+"` for `options.strong`, expected `*`, or `_`");return t}D1.peek=b3;function D1(e,t,r,s){const l=y3(r),u=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),y=qu(s.before.charCodeAt(s.before.length-1),m,l);y.inside&&(d=ql(m)+d.slice(1));const g=d.charCodeAt(d.length-1),x=qu(s.after.charCodeAt(0),g,l);x.inside&&(d=d.slice(0,-1)+ql(g));const w=c.move(l+l);return u(),r.attentionEncodeSurroundingInfo={after:x.outside,before:y.outside},f+d+w}function b3(e,t,r){return r.options.strong||"*"}function x3(e,t,r,s){return r.safe(e.value,s)}function v3(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 w3(e,t,r){const s=(M1(r)+(r.options.ruleSpaces?" ":"")).repeat(v3(r));return r.options.ruleSpaces?s.slice(0,-1):s}const L1={blockquote:$N,break:Db,code:KN,definition:ZN,emphasis:E1,hardBreak:Db,heading:n3,html:C1,image:A1,imageReference:j1,inlineCode:T1,link:O1,linkReference:R1,list:f3,listItem:d3,paragraph:m3,root:g3,strong:D1,text:x3,thematicBreak:w3};function S3(){return{enter:{table:_3,tableData:Lb,tableHeader:Lb,tableRow:E3},exit:{codeText:C3,table:k3,tableData:Jh,tableHeader:Jh,tableRow:Jh}}}function _3(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 k3(e){this.exit(e),this.data.inTable=void 0}function E3(e){this.enter({type:"tableRow",children:[]},e)}function Jh(e){this.exit(e)}function Lb(e){this.enter({type:"tableCell",children:[]},e)}function C3(e){let t=this.resume();this.data.inTable&&(t=t.replace(/\\([\\|])/g,A3));const r=this.stack[this.stack.length-1];r.type,r.value=t,this.exit(e)}function A3(e,t){return t==="|"?t:e}function j3(e){const t=e||{},r=t.tableCellPadding,s=t.tablePipeAlign,l=t.stringLength,u=r?" ":"|";return{unsafe:[{character:"\r",inConstruct:"tableCell"},{character:`
119
119
  `,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(w,S,T,z){return m(y(w,T,z),w.align)}function f(w,S,T,z){const D=g(w,T,z),H=m([D]);return H.slice(0,H.indexOf(`
120
- `))}function d(w,S,T,z){const D=T.enter("tableCell"),H=T.enter("phrasing"),F=T.containerPhrasing(w,{...z,before:u,after:u});return H(),D(),F}function m(w,S){return IN(w,{align:S,alignDelimiters:s,padding:r,stringLength:l})}function y(w,S,T){const z=w.children;let D=-1;const H=[],F=S.enter("table");for(;++D<z.length;)H[D]=g(z[D],S,T);return F(),H}function g(w,S,T){const z=w.children;let D=-1;const H=[],F=S.enter("tableRow");for(;++D<z.length;)H[D]=d(z[D],w,S,T);return F(),H}function x(w,S,T){let z=L1.inlineCode(w,S,T);return T.stack.includes("tableCell")&&(z=z.replace(/\|/g,"\\$&")),z}}function T3(){return{exit:{taskListCheckValueChecked:zb,taskListCheckValueUnchecked:zb,paragraph:O3}}}function N3(){return{unsafe:[{atBreak:!0,character:"-",after:"[:|-]"}],handlers:{listItem:R3}}}function zb(e){const t=this.stack[this.stack.length-2];t.type,t.checked=e.type==="taskListCheckValueChecked"}function O3(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 u=-1,c;for(;++u<l.length;){const f=l[u];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 R3(e,t,r,s){const l=e.children[0],u=typeof e.checked=="boolean"&&l&&l.type==="paragraph",c="["+(e.checked?"x":" ")+"] ",f=r.createTracker(s);u&&f.move(c);let d=L1.listItem(e,t,r,{...s,...f.current()});return u&&(d=d.replace(/^(?:[*+-]|\d+\.)([\r\n]| {1,3})/,m)),d;function m(y){return y+c}}function M3(){return[fN(),RN(),zN(),S3(),T3()]}function D3(e){return{extensions:[hN(),MN(e),UN(),j3(e),N3()]}}const L3={tokenize:q3,partial:!0},z1={tokenize:I3,partial:!0},U1={tokenize:F3,partial:!0},B1={tokenize:$3,partial:!0},z3={tokenize:Y3,partial:!0},P1={name:"wwwAutolink",tokenize:P3,previous:q1},H1={name:"protocolAutolink",tokenize:H3,previous:I1},ai={name:"emailAutolink",tokenize:B3,previous:F1},Dr={};function U3(){return{text:Dr}}let hs=48;for(;hs<123;)Dr[hs]=ai,hs++,hs===58?hs=65:hs===91&&(hs=97);Dr[43]=ai;Dr[45]=ai;Dr[46]=ai;Dr[95]=ai;Dr[72]=[ai,H1];Dr[104]=[ai,H1];Dr[87]=[ai,P1];Dr[119]=[ai,P1];function B3(e,t,r){const s=this;let l,u;return c;function c(g){return!kd(g)||!F1.call(s,s.previous)||lm(s.events)?r(g):(e.enter("literalAutolink"),e.enter("literalAutolinkEmail"),f(g))}function f(g){return kd(g)?(e.consume(g),f):g===64?(e.consume(g),d):r(g)}function d(g){return g===46?e.check(z3,y,m)(g):g===45||g===95||pn(g)?(u=!0,e.consume(g),d):y(g)}function m(g){return e.consume(g),l=!0,d}function y(g){return u&&l&&kn(s.previous)?(e.exit("literalAutolinkEmail"),e.exit("literalAutolink"),t(g)):r(g)}}function P3(e,t,r){const s=this;return l;function l(c){return c!==87&&c!==119||!q1.call(s,s.previous)||lm(s.events)?r(c):(e.enter("literalAutolink"),e.enter("literalAutolinkWww"),e.check(L3,e.attempt(z1,e.attempt(U1,u),r),r)(c))}function u(c){return e.exit("literalAutolinkWww"),e.exit("literalAutolink"),t(c)}}function H3(e,t,r){const s=this;let l="",u=!1;return c;function c(g){return(g===72||g===104)&&I1.call(s,s.previous)&&!lm(s.events)?(e.enter("literalAutolink"),e.enter("literalAutolinkHttp"),l+=String.fromCodePoint(g),e.consume(g),f):r(g)}function f(g){if(kn(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),u?m:(u=!0,d)):r(g)}function m(g){return g===null||Bu(g)||Nt(g)||gs(g)||Qu(g)?r(g):e.attempt(z1,e.attempt(U1,y),r)(g)}function y(g){return e.exit("literalAutolinkHttp"),e.exit("literalAutolink"),t(g)}}function q3(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),u):r(c)}function u(c){return c===null?r(c):t(c)}}function I3(e,t,r){let s,l,u;return c;function c(m){return m===46||m===95?e.check(B1,d,f)(m):m===null||Nt(m)||gs(m)||m!==45&&Qu(m)?d(m):(u=!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||!u?r(m):t(m)}}function F3(e,t){let r=0,s=0;return l;function l(c){return c===40?(r++,e.consume(c),l):c===41&&s<r?u(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(B1,t,u)(c):c===null||Nt(c)||gs(c)?t(c):(e.consume(c),l)}function u(c){return c===41&&s++,e.consume(c),l}}function $3(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),u):f===93?(e.consume(f),l):f===60||f===null||Nt(f)||gs(f)?t(f):r(f)}function l(f){return f===null||f===40||f===91||Nt(f)||gs(f)?t(f):s(f)}function u(f){return kn(f)?c(f):r(f)}function c(f){return f===59?(e.consume(f),s):kn(f)?(e.consume(f),c):r(f)}}function Y3(e,t,r){return s;function s(u){return e.consume(u),l}function l(u){return pn(u)?r(u):t(u)}}function q1(e){return e===null||e===40||e===42||e===95||e===91||e===93||e===126||Nt(e)}function I1(e){return!kn(e)}function F1(e){return!(e===47||kd(e))}function kd(e){return e===43||e===45||e===46||e===95||pn(e)}function lm(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 G3={tokenize:eO,partial:!0};function V3(){return{document:{91:{name:"gfmFootnoteDefinition",tokenize:Q3,continuation:{tokenize:Z3},exit:W3}},text:{91:{name:"gfmFootnoteCall",tokenize:K3},93:{name:"gfmPotentialFootnoteCall",add:"after",tokenize:J3,resolveTo:X3}}}}function J3(e,t,r){const s=this;let l=s.events.length;const u=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=wr(s.sliceSerialize({start:c.end,end:s.now()}));return m.codePointAt(0)!==94||!u.includes(m.slice(1))?r(d):(e.enter("gfmFootnoteCallLabelMarker"),e.consume(d),e.exit("gfmFootnoteCallLabelMarker"),t(d))}}function X3(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 u={type:"gfmFootnoteCallString",start:Object.assign({},l.end),end:Object.assign({},e[e.length-1][1].start)},c={type:"chunkString",contentType:"string",start:Object.assign({},u.start),end:Object.assign({},u.end)},f=[e[r+1],e[r+2],["enter",s,t],e[r+3],e[r+4],["enter",l,t],["exit",l,t],["enter",u,t],["enter",c,t],["exit",c,t],["exit",u,t],e[e.length-2],e[e.length-1],["exit",s,t]];return e.splice(r,e.length-r+1,...f),e}function K3(e,t,r){const s=this,l=s.parser.gfmFootnotes||(s.parser.gfmFootnotes=[]);let u=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(u>999||g===93&&!c||g===null||g===91||Nt(g))return r(g);if(g===93){e.exit("chunkString");const x=e.exit("gfmFootnoteCallString");return l.includes(wr(s.sliceSerialize(x)))?(e.enter("gfmFootnoteCallLabelMarker"),e.consume(g),e.exit("gfmFootnoteCallLabelMarker"),e.exit("gfmFootnoteCall"),t):r(g)}return Nt(g)||(c=!0),u++,e.consume(g),g===92?y:m}function y(g){return g===91||g===92||g===93?(e.consume(g),u++,m):m(g)}}function Q3(e,t,r){const s=this,l=s.parser.gfmFootnotes||(s.parser.gfmFootnotes=[]);let u,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",y):r(S)}function y(S){if(c>999||S===93&&!f||S===null||S===91||Nt(S))return r(S);if(S===93){e.exit("chunkString");const T=e.exit("gfmFootnoteDefinitionLabelString");return u=wr(s.sliceSerialize(T)),e.enter("gfmFootnoteDefinitionLabelMarker"),e.consume(S),e.exit("gfmFootnoteDefinitionLabelMarker"),e.exit("gfmFootnoteDefinitionLabel"),x}return Nt(S)||(f=!0),c++,e.consume(S),S===92?g:y}function g(S){return S===91||S===92||S===93?(e.consume(S),c++,y):y(S)}function x(S){return S===58?(e.enter("definitionMarker"),e.consume(S),e.exit("definitionMarker"),l.includes(u)||l.push(u),ct(e,w,"gfmFootnoteDefinitionWhitespace")):r(S)}function w(S){return t(S)}}function Z3(e,t,r){return e.check(Vl,t,e.attempt(G3,t,r))}function W3(e){e.exit("gfmFootnoteDefinition")}function eO(e,t,r){const s=this;return ct(e,l,"gfmFootnoteDefinitionIndent",5);function l(u){const c=s.events[s.events.length-1];return c&&c[1].type==="gfmFootnoteDefinitionIndent"&&c[2].sliceSerialize(c[1],!0).length===4?t(u):r(u)}}function tO(e){let r=(e||{}).singleTilde;const s={name:"strikethrough",tokenize:u,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 y={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",y,f],["enter",c[m][1],f],["exit",c[m][1],f],["enter",g,f]],w=f.parser.constructs.insideSpan.null;w&&Vn(x,x.length,0,Zu(w,c.slice(m+1,d),f)),Vn(x,x.length,0,[["exit",g,f],["enter",c[d][1],f],["exit",c[d][1],f],["exit",y,f]]),Vn(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 u(c,f,d){const m=this.previous,y=this.events;let g=0;return x;function x(S){return m===126&&y[y.length-1][1].type!=="characterEscape"?d(S):(c.enter("strikethroughSequenceTemporary"),w(S))}function w(S){const T=ba(m);if(S===126)return g>1?d(S):(c.consume(S),g++,w);if(g<2&&!r)return d(S);const z=c.exit("strikethroughSequenceTemporary"),D=ba(S);return z._open=!D||D===2&&!!T,z._close=!T||T===2&&!!D,f(S)}}}class nO{constructor(){this.map=[]}add(t,r,s){rO(this,t,r,s)}consume(t){if(this.map.sort(function(u,c){return u[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 u of l)t.push(u);l=s.pop()}this.map.length=0}}function rO(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 iO(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 u=s.length-1;s[u]=s[u]==="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 sO(){return{flow:{null:{name:"table",tokenize:aO,resolveAll:lO}}}}function aO(e,t,r){const s=this;let l=0,u=0,c;return f;function f(R){let G=s.events.length-1;for(;G>-1;){const ie=s.events[G][1].type;if(ie==="lineEnding"||ie==="linePrefix")G--;else break}const J=G>-1?s.events[G][1].type:null,fe=J==="tableHead"||J==="tableRow"?L:d;return fe===L&&s.parser.lazy[s.now().line]?r(R):fe(R)}function d(R){return e.enter("tableHead"),e.enter("tableRow"),m(R)}function m(R){return R===124||(c=!0,u+=1),y(R)}function y(R){return R===null?r(R):Pe(R)?u>1?(u=0,s.interrupt=!0,e.exit("tableRow"),e.enter("lineEnding"),e.consume(R),e.exit("lineEnding"),w):r(R):st(R)?ct(e,y,"whitespace")(R):(u+=1,c&&(c=!1,l+=1),R===124?(e.enter("tableCellDivider"),e.consume(R),e.exit("tableCellDivider"),c=!0,y):(e.enter("data"),g(R)))}function g(R){return R===null||R===124||Nt(R)?(e.exit("data"),y(R)):(e.consume(R),R===92?x:g)}function x(R){return R===92||R===124?(e.consume(R),g):g(R)}function w(R){return s.interrupt=!1,s.parser.lazy[s.now().line]?r(R):(e.enter("tableDelimiterRow"),c=!1,st(R)?ct(e,S,"linePrefix",s.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(R):S(R))}function S(R){return R===45||R===58?z(R):R===124?(c=!0,e.enter("tableCellDivider"),e.consume(R),e.exit("tableCellDivider"),T):B(R)}function T(R){return st(R)?ct(e,z,"whitespace")(R):z(R)}function z(R){return R===58?(u+=1,c=!0,e.enter("tableDelimiterMarker"),e.consume(R),e.exit("tableDelimiterMarker"),D):R===45?(u+=1,D(R)):R===null||Pe(R)?oe(R):B(R)}function D(R){return R===45?(e.enter("tableDelimiterFiller"),H(R)):B(R)}function H(R){return R===45?(e.consume(R),H):R===58?(c=!0,e.exit("tableDelimiterFiller"),e.enter("tableDelimiterMarker"),e.consume(R),e.exit("tableDelimiterMarker"),F):(e.exit("tableDelimiterFiller"),F(R))}function F(R){return st(R)?ct(e,oe,"whitespace")(R):oe(R)}function oe(R){return R===124?S(R):R===null||Pe(R)?!c||l!==u?B(R):(e.exit("tableDelimiterRow"),e.exit("tableHead"),t(R)):B(R)}function B(R){return r(R)}function L(R){return e.enter("tableRow"),W(R)}function W(R){return R===124?(e.enter("tableCellDivider"),e.consume(R),e.exit("tableCellDivider"),W):R===null||Pe(R)?(e.exit("tableRow"),t(R)):st(R)?ct(e,W,"whitespace")(R):(e.enter("data"),$(R))}function $(R){return R===null||R===124||Nt(R)?(e.exit("data"),W(R)):(e.consume(R),R===92?q:$)}function q(R){return R===92||R===124?(e.consume(R),$):$(R)}}function lO(e,t){let r=-1,s=!0,l=0,u=[0,0,0,0],c=[0,0,0,0],f=!1,d=0,m,y,g;const x=new nO;for(;++r<e.length;){const w=e[r],S=w[1];w[0]==="enter"?S.type==="tableHead"?(f=!1,d!==0&&(Ub(x,t,d,m,y),y=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,u=[0,0,0,0],c=[0,r+1,0,0],f&&(f=!1,y={type:"tableBody",start:Object.assign({},S.start),end:Object.assign({},S.end)},x.add(r,0,[["enter",y,t]])),l=S.type==="tableDelimiterRow"?2:y?3:1):l&&(S.type==="data"||S.type==="tableDelimiterMarker"||S.type==="tableDelimiterFiller")?(s=!1,c[2]===0&&(u[1]!==0&&(c[0]=c[1],g=bu(x,t,u,l,void 0,g),u=[0,0,0,0]),c[2]=r)):S.type==="tableCellDivider"&&(s?s=!1:(u[1]!==0&&(c[0]=c[1],g=bu(x,t,u,l,void 0,g)),u=c,c=[u[1],r,0,0])):S.type==="tableHead"?(f=!0,d=r):S.type==="tableRow"||S.type==="tableDelimiterRow"?(d=r,u[1]!==0?(c[0]=c[1],g=bu(x,t,u,l,r,g)):c[1]!==0&&(g=bu(x,t,c,l,r,g)),l=0):l&&(S.type==="data"||S.type==="tableDelimiterMarker"||S.type==="tableDelimiterFiller")&&(c[3]=r)}for(d!==0&&Ub(x,t,d,m,y),x.consume(t.events),r=-1;++r<t.events.length;){const w=t.events[r];w[0]==="enter"&&w[1].type==="table"&&(w[1]._align=iO(t.events,r))}return e}function bu(e,t,r,s,l,u){const c=s===1?"tableHeader":s===2?"tableDelimiter":"tableData",f="tableContent";r[0]!==0&&(u.end=Object.assign({},ia(t.events,r[0])),e.add(r[0],0,[["exit",u,t]]));const d=ia(t.events,r[1]);if(u={type:c,start:Object.assign({},d),end:Object.assign({},d)},e.add(r[1],0,[["enter",u,t]]),r[2]!==0){const m=ia(t.events,r[2]),y=ia(t.events,r[3]),g={type:f,start:Object.assign({},m),end:Object.assign({},y)};if(e.add(r[2],0,[["enter",g,t]]),s!==2){const x=t.events[r[2]],w=t.events[r[3]];if(x[1].end=Object.assign({},w[1].end),x[1].type="chunkText",x[1].contentType="text",r[3]>r[2]+1){const S=r[2]+1,T=r[3]-r[2]-1;e.add(S,T,[])}}e.add(r[3]+1,0,[["exit",g,t]])}return l!==void 0&&(u.end=Object.assign({},ia(t.events,l)),e.add(l,0,[["exit",u,t]]),u=void 0),u}function Ub(e,t,r,s,l){const u=[],c=ia(t.events,r);l&&(l.end=Object.assign({},c),u.push(["exit",l,t])),s.end=Object.assign({},c),u.push(["exit",s,t]),e.add(r+1,0,u)}function ia(e,t){const r=e[t],s=r[0]==="enter"?"start":"end";return r[1][s]}const oO={name:"tasklistCheck",tokenize:cO};function uO(){return{text:{91:oO}}}function cO(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"),u)}function u(d){return Nt(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 Pe(d)?t(d):st(d)?e.check({tokenize:fO},t,r)(d):r(d)}}function fO(e,t,r){return ct(e,s,"whitespace");function s(l){return l===null?r(l):t(l)}}function hO(e){return Wx([U3(),V3(),tO(e),sO(),uO()])}const dO={};function Bb(e){const t=this,r=e||dO,s=t.data(),l=s.micromarkExtensions||(s.micromarkExtensions=[]),u=s.fromMarkdownExtensions||(s.fromMarkdownExtensions=[]),c=s.toMarkdownExtensions||(s.toMarkdownExtensions=[]);l.push(hO(r)),u.push(M3()),c.push(D3(r))}function mO(e){v1(e,[/\r?\n|\r/g,pO])}function pO(){return{type:"break"}}function Pb(){return function(e){mO(e)}}function gO({connected:e,hostId:t,request:r,subscribeEvents:s,taskId:l,runId:u}){const c=Mr(),f=Id(),[d,m]=j.useState(!0),[y,g]=j.useState([]),[x,w]=j.useState(),[S,T]=j.useState(),z=x==="started"||x==="monitoring",D=x==="followup",H=x==="started"||x==="followup",[F,oe]=j.useState(null);dd(F!==null,()=>oe(null));const[B,L]=j.useState(!1),[W,$]=j.useState(""),[q,R]=j.useState(!1),G=j.useRef(null),J=j.useRef(null),fe=j.useRef(null),[ie,ee]=j.useState(u==="latest"?void 0:u),P=u==="latest"&&ie===null;j.useEffect(()=>{if(u!=="latest"){ee(u);return}e&&(ee(void 0),r("taskrun.list",{task_id:l,limit:1}).then(E=>{var K,A;return ee(((A=(K=E.entries)==null?void 0:K[0])==null?void 0:A.run_id)??null)}).catch(()=>ee(null)))},[u,l,e,r]);async function X(){if(ie)try{const E=await r("task.result",{id:l,run_id:ie});if(E.error){console.error("No result:",E.error),c(t?`/hosts/${encodeURIComponent(t)}`:"/",{replace:!0});return}g(E.messages??[]),w(E.running_state),T(E.agent)}catch(E){console.error("Failed to load result:",E),c(t?`/hosts/${encodeURIComponent(t)}`:"/",{replace:!0})}finally{m(!1)}}async function ae(E){var K;if(ie)try{const be=(K=(await r("task.reports",{id:l,run_id:ie,report_files:[E]})).reports)==null?void 0:K[0];be!=null&&be.data_url?oe({file:E,data_url:be.data_url}):oe({file:E,content:(be==null?void 0:be.content)??"Report not found."})}catch{oe({file:E,content:"Failed to load report."})}}j.useEffect(()=>{!e||!ie||(m(!0),X())},[e,l,ie]),j.useEffect(()=>!e||!t||!ie?void 0:s(t,async K=>{try{const A=JSON.parse(new TextDecoder().decode(K.data));if(A.event_type!=="running-state"&&A.event_type!=="result-updated"||K.subject.split(".").pop()!==l||A.event_type==="result-updated"&&A.run_id&&A.run_id!==ie)return;X()}catch{}}),[e,t,l,ie,s,r]),j.useEffect(()=>{G.current&&(G.current.scrollTop=G.current.scrollHeight)},[y]),j.useEffect(()=>{d||P||!ie||fe.current!==ie&&(fe.current=ie,requestAnimationFrame(()=>{G.current&&(G.current.scrollTop=G.current.scrollHeight),window.scrollTo({top:document.documentElement.scrollHeight,behavior:"auto"})}))},[d,P,ie]);function pe(E){if(E==="input")return"User Input";if(E==="permission")return"Permission";if(E==="confirmation")return"Confirmation"}function M(E){return E==="started"?"Task started":E==="finished"?"Task finished":E==="failed"?"Task failed":E==="error"?"Command failed":E==="aborted"?"Task aborted":E==="confirmation"?"Task confirmed":E==="stopped"?"Follow-up stopped":E??""}return b.jsxs("div",{className:"run-detail",children:[b.jsxs("button",{className:"run-detail-back",onClick:()=>c(-1),children:[b.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:b.jsx("path",{d:"M15 18l-6-6 6-6"})}),"Back"]}),P?b.jsxs("div",{className:"empty-state",children:[b.jsx("p",{className:"empty-state-text",children:"No runs yet"}),b.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?b.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"var(--space-sm)",padding:"var(--space-sm) 0"},children:[b.jsx("div",{className:"skeleton-line",style:{width:"40%"}}),b.jsx("div",{className:"skeleton-line",style:{width:"55%"}}),b.jsx("div",{className:"skeleton-line",style:{width:"100%",height:"8rem",marginTop:"var(--space-sm)"}})]}):b.jsxs(b.Fragment,{children:[b.jsxs("div",{className:"chat-thread",ref:G,children:[y.map((E,K)=>{const A=H&&E.role==="assistant"&&!y.slice(K+1).some(be=>be.role==="assistant"||be.role==="user");return E.role==="status"&&E.type==="monitoring"?null:E.role==="status"?b.jsxs("div",{className:`chat-status${E.type==="error"?" chat-status--error":""}`,children:[b.jsxs("div",{children:[M(E.type),E.time>0&&b.jsx("span",{className:"chat-status-time",children:f(E.time)})]}),E.content&&b.jsx("pre",{className:"chat-status-detail",children:E.content})]},K):b.jsxs("div",{className:`chat-message chat-message--${E.role}`,children:[E.role==="assistant"&&S&&b.jsx("div",{className:"chat-message-agent",children:hd(S)}),b.jsxs("div",{className:"chat-message-content",children:[b.jsx(Nb,{remarkPlugins:[Bb,Pb],children:E.content}),A&&b.jsxs("div",{className:"chat-typing-indicator",children:[b.jsx("span",{}),b.jsx("span",{}),b.jsx("span",{})]})]}),E.attachments&&E.attachments.length>0&&b.jsx("div",{className:"chat-message-attachments",children:E.attachments.map(be=>b.jsx("button",{className:"chat-attachment-chip",onClick:()=>ae(be),children:be},be))}),b.jsxs("div",{className:"chat-message-meta",children:[pe(E.type)&&b.jsx("span",{className:"chat-message-type",children:pe(E.type)}),E.time>0&&b.jsx("span",{children:f(E.time)})]})]},K)}),H&&(()=>{const E=y.filter(K=>K.role!=="status");return E.length===0||E[E.length-1].role!=="assistant"})()&&b.jsxs("div",{className:"chat-message chat-message--assistant",children:[S&&b.jsx("div",{className:"chat-message-agent",children:hd(S)}),b.jsxs("div",{className:"chat-typing-indicator",children:[b.jsx("span",{}),b.jsx("span",{}),b.jsx("span",{})]})]}),x==="monitoring"&&b.jsxs("div",{className:"chat-monitoring-indicator",children:[b.jsx("span",{className:"chat-monitoring-dot"}),"Monitoring command output"]})]}),z?b.jsx("div",{className:"chat-abort-bar",children:b.jsx("button",{className:"btn btn-secondary chat-abort-btn",disabled:B,onClick:async()=>{if(confirm("Abort this task?")){L(!0);try{await r("task.abort",{id:l})}catch(E){console.error("Abort failed:",E)}finally{L(!1)}}},children:B?"Aborting...":"Abort Task"})}):D?b.jsx("div",{className:"chat-input-bar",children:b.jsx("button",{className:"btn btn-secondary chat-stop-btn",disabled:B,onClick:async()=>{L(!0);try{await r("task.stop_followup",{id:l,run_id:ie})}catch(E){console.error("Stop failed:",E)}finally{L(!1)}},children:b.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"currentColor",children:b.jsx("rect",{x:"6",y:"6",width:"12",height:"12",rx:"2"})})})}):b.jsxs("form",{className:"chat-input-bar",onSubmit:async E=>{E.preventDefault();const K=W.trim();if(!(!K||q)){R(!0);try{await r("task.followup",{id:l,run_id:ie,message:K}),$("")}catch(A){console.error("Follow-up failed:",A)}finally{R(!1)}}},children:[b.jsx("input",{ref:J,className:"chat-input",type:"text",placeholder:"Follow-up message",value:W,onChange:E=>$(E.target.value),disabled:q}),b.jsx("button",{className:"btn btn-primary chat-send-btn",type:"submit",disabled:!W.trim()||q,children:b.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[b.jsx("line",{x1:"22",y1:"2",x2:"11",y2:"13"}),b.jsx("polygon",{points:"22 2 15 22 11 13 2 9 22 2"})]})})]})]}),F&&b.jsx("div",{className:"report-dialog-overlay",onClick:()=>oe(null),children:b.jsxs("div",{className:"report-dialog",onClick:E=>E.stopPropagation(),children:[b.jsxs("div",{className:"report-dialog-header",children:[b.jsx("span",{className:"report-dialog-title",children:F.file}),b.jsx("button",{className:"report-dialog-close",onClick:()=>oe(null),"aria-label":"Close",children:b.jsxs("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[b.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),b.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})})]}),b.jsx("div",{className:"report-dialog-body",children:F.data_url?b.jsx("img",{src:F.data_url,alt:F.file,style:{maxWidth:"100%",height:"auto"}}):b.jsx(Nb,{remarkPlugins:[Bb,Pb],components:{a:({...E})=>b.jsx("a",{...E,target:"_blank",rel:"noopener noreferrer"})},children:F.content??""})})]})})]})}function yO(){const{activeHost:e}=si(),t=j.useRef(null);j.useEffect(()=>{if(Xn.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 u=await l.pushManager.getSubscription();if(!u){const{publicKey:f}=await hE("/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}u=await l.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:f})}const c=u.toJSON();await fE("/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 bO="0.9.8";function xO(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 xu(){const{removePairedHost:e,setHostLanUrl:t,setHostTimezone:r}=qi(),{connected:s,request:l,subscribeEvents:u,unauthorized:c,activeHost:f}=si(),d=f.hostId,m=f.clientToken||null,y=Mr(),g=cr(),x=$u(),w=Ux("(min-width: 768px)"),S=g.pathname.endsWith("/tasks"),T=x.runId?void 0:x.taskId,z=!!(x.taskId&&x.runId),[D,H]=j.useState(!1),[F,oe]=j.useState(!1),[B,L]=j.useState(null),[W,$]=j.useState(null),[q,R]=j.useState(null),[G,J]=j.useState(new Set),[fe,ie]=j.useState([]),[ee,P]=j.useState(),X=!!m&&q===m,[ae,pe]=j.useState(new Map),[M,E]=j.useState(new Map),[K,A]=j.useState(new Map),[be,je]=j.useState(new Map);yO(),j.useEffect(()=>{window.scrollTo(0,0)},[d]),j.useEffect(()=>{let ze=!1;return UE().then(Ae=>{ze||J(Ae)}),()=>{ze=!0}},[]),j.useEffect(()=>{s&&l("host.info").then(ze=>{var We,Fe,et,ft,ht,Wt;ie(ze.agents??[]),P(ze.host_platform),R(ze.linked_client_token??null),xE(ze.agents??[]);const Ae=ze.version??null;$(Ae),H(!!Ae&&xO(Ae,bO)),t(d,ze.lan_url??void 0),r(d,ze.host_timezone);const Le=new Map,nt=new Map,Ve=new Map,Je=new Map;for(const $e of ze.pending_prompts??[])if($e.type==="confirmation")Le.set($e.key,{description:((We=$e.meta)==null?void 0:We.description)??"",sessionName:(Fe=$e.meta)==null?void 0:Fe.session_name});else if($e.type==="permission")nt.set($e.key,{permissions:$e.params??[],sessionName:(et=$e.meta)==null?void 0:et.session_name});else if($e.type==="input"){const yn=$e.params??((ft=$e.meta)==null?void 0:ft.input_questions)??[];Ve.set($e.key,{questions:yn,description:(ht=$e.meta)==null?void 0:ht.description,sessionName:(Wt=$e.meta)==null?void 0:Wt.session_name}),Je.set($e.key,new Array(yn.length).fill(""))}pe(Le),E(nt),A(Ve),je(Je)}).catch(()=>{})},[s,d,l,t,r]),j.useEffect(()=>s?u(d,Ae=>{const Le=Ae.subject.split(".");if(Le.length<3)return;const nt=Le.slice(2).join(".");let Ve={};try{Ve=JSON.parse(new TextDecoder().decode(Ae.data))}catch{return}const Je=Ve.event_type,We=Ve.session_id;if(Je==="input-request"&&We){const Fe=Ve.input_questions,et=Ve.session_name,ft=Ve.description;Fe!=null&&Fe.length&&(A(ht=>{if(ht.has(We))return ht;const Wt=new Map(ht);return Wt.set(We,{questions:Fe,description:ft,sessionName:et}),Wt}),je(ht=>{if(ht.has(We))return ht;const Wt=new Map(ht);return Wt.set(We,new Array(Fe.length).fill("")),Wt}));return}if(Je==="input-resolved"&&We){A(Fe=>{if(!Fe.has(We))return Fe;const et=new Map(Fe);return et.delete(We),et}),je(Fe=>{const et=new Map(Fe);return et.delete(We),et});return}if(Je==="confirm-request"&&We){const Fe=Ve.description,et=Ve.session_name;Fe&&pe(ft=>{if(ft.has(We))return ft;const ht=new Map(ft);return ht.set(We,{description:Fe,sessionName:et}),ht});return}if(Je==="confirm-resolved"&&We){pe(Fe=>{if(!Fe.has(We))return Fe;const et=new Map(Fe);return et.delete(We),et});return}if(Je==="permission-request"){const Fe=Ve.required_permissions,et=Ve.session_name;Fe!=null&&Fe.length&&E(ft=>{if(ft.has(nt))return ft;const ht=new Map(ft);return ht.set(nt,{permissions:Fe,sessionName:et}),ht});return}if(Je==="permission-resolved"){E(Fe=>{if(!Fe.has(nt))return Fe;const et=new Map(Fe);return et.delete(nt),et});return}}):void 0,[s,d,u]);async function _e(ze,Ae){try{await l("task.user_input",{id:ze,value:[Ae]})}catch(Le){console.error("[Dashboard] Failed to respond to confirmation:",Le)}}async function Me(ze,Ae){try{await l("task.user_input",{id:ze,value:[Ae]})}catch(Le){console.error("[Dashboard] Failed to respond to permission request:",Le)}}async function Ie(ze,Ae){try{await l("task.user_input",{id:ze,value:Ae})}catch(Le){console.error("[Dashboard] Failed to respond to input request:",Le)}}function ke(ze,Ae){if(!ps())return;const Le=`/hosts/${encodeURIComponent(d)}/runs/${encodeURIComponent(ze)}`;y(Ae?`${Le}/${encodeURIComponent(Ae)}`:Le)}async function Ge(){oe(!0),L(null);try{const ze=await l("host.update");if(ze.error){L(ze.error),oe(!1);return}}catch{}setTimeout(()=>window.location.reload(),15e3)}const Ft=s&&!c;return b.jsxs("div",{className:"dashboard",children:[w&&b.jsx($0,{daemonVersion:W,linkedClientToken:q,request:l,onEnabledCapabilitiesChange:J,onLinkedClientTokenChange:R}),b.jsxs("div",{className:"dashboard-content",children:[b.jsxs("header",{className:"app-header",children:[b.jsxs("div",{className:"app-title-bar",children:[!w&&b.jsx($0,{daemonVersion:W,linkedClientToken:q,request:l,onEnabledCapabilitiesChange:J,onLinkedClientTokenChange:R}),b.jsx("h1",{className:"app-title",children:"Palmier"}),b.jsx(IE,{})]}),b.jsx("div",{className:"tab-bar",children:b.jsx(DE,{})})]}),b.jsx("main",{className:"dashboard-main",children:c?b.jsxs("div",{className:"revoked-state",children:[b.jsx("div",{className:"revoked-icon",children:b.jsxs("svg",{width:"32",height:"32",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",children:[b.jsx("rect",{x:"3",y:"11",width:"18",height:"11",rx:"2",ry:"2"}),b.jsx("path",{d:"M7 11V7a5 5 0 0 1 10 0v4"}),b.jsx("line",{x1:"12",y1:"15",x2:"12",y2:"18"})]})}),b.jsx("h2",{className:"revoked-title",children:"Client Revoked"}),b.jsx("p",{className:"revoked-description",children:"This client was revoked by the host. To reconnect, generate a new pairing code on the host machine."}),b.jsx("div",{className:"revoked-command",children:b.jsx("code",{children:"palmier pair"})}),b.jsxs("div",{className:"revoked-actions",children:[b.jsx("button",{className:"btn btn-primary",onClick:()=>{ps()&&y("/pair")},children:"Re-pair Device"}),b.jsx("button",{className:"btn btn-secondary",onClick:()=>{e(d),y("/",{replace:!0})},children:"Remove Host"})]})]}):Ft?b.jsxs(b.Fragment,{children:[S&&!z&&b.jsx(ME,{connected:s,hostId:d,request:l,subscribeEvents:u,agents:fe,hostPlatform:ee,isNotificationListener:X&&G.has("notifications"),onViewRun:ke}),z?b.jsx(gO,{connected:s,hostId:d,request:l,subscribeEvents:u,taskId:x.taskId,runId:decodeURIComponent(x.runId)}):S?null:b.jsx(GE,{connected:s,hostId:d,request:l,subscribeEvents:u,agents:fe,hostPlatform:ee,filterTaskId:T,onClearFilter:()=>{ps()&&y(`/hosts/${encodeURIComponent(d)}`)}})]}):b.jsx("div",{className:"empty-state",children:b.jsx("p",{children:"Connecting to host..."})})}),D&&!F&&!B&&b.jsx("div",{className:"confirm-modal-overlay",children:b.jsxs("div",{className:"confirm-modal",children:[b.jsx("h2",{className:"confirm-modal-title",children:"Update Required"}),b.jsxs("p",{className:"confirm-modal-message",children:["Your Palmier host",W?` (v${W})`:""," is too old for this version of the app. Please update to continue."]}),b.jsx("div",{className:"confirm-modal-actions",children:b.jsx("button",{className:"btn btn-primary",onClick:Ge,children:"Update Now"})})]})}),F&&b.jsx("div",{className:"confirm-modal-overlay",children:b.jsxs("div",{className:"confirm-modal",children:[b.jsx("h2",{className:"confirm-modal-title",children:"Updating..."}),b.jsx("p",{className:"confirm-modal-message",children:"Installing update and restarting daemon. Please wait..."})]})}),B&&b.jsx("div",{className:"confirm-modal-overlay",children:b.jsxs("div",{className:"confirm-modal",children:[b.jsx("h2",{className:"confirm-modal-title",children:"Update Failed"}),b.jsx("p",{className:"confirm-modal-message",style:{whiteSpace:"pre-line"},children:B}),b.jsx("div",{className:"confirm-modal-actions",children:b.jsx("button",{className:"btn btn-secondary",onClick:()=>{L(null)},children:"Retry"})})]})})]}),ds.createPortal(b.jsxs(b.Fragment,{children:[[...ae.entries()].map(([ze,{description:Ae,sessionName:Le}])=>b.jsx("div",{className:"confirm-modal-overlay",children:b.jsxs("div",{className:"confirm-modal",children:[b.jsx("h2",{className:"confirm-modal-title",children:"Confirmation Required"}),Le&&b.jsx("p",{className:"confirm-modal-subtitle",children:Le}),b.jsx("p",{className:"confirm-modal-message",children:Ae}),b.jsxs("div",{className:"confirm-modal-actions",children:[b.jsx("button",{className:"btn btn-primary",onClick:()=>_e(ze,"confirmed"),children:"Confirm"}),b.jsx("button",{className:"btn btn-secondary",onClick:()=>_e(ze,"aborted"),children:"Abort"})]})]})},ze)),[...M.entries()].map(([ze,{permissions:Ae,sessionName:Le}])=>b.jsx("div",{className:"confirm-modal-overlay",children:b.jsxs("div",{className:"confirm-modal permission-modal",children:[b.jsx("h2",{className:"confirm-modal-title",children:"Permission Required"}),b.jsx("p",{className:"confirm-modal-message",children:b.jsx("strong",{children:Le||ze})}),b.jsx("div",{className:"permission-list",children:Ae.map((nt,Ve)=>b.jsxs("div",{className:"permission-item",children:[b.jsx("span",{className:"permission-name",children:nt.name}),nt.description&&b.jsx("span",{className:"permission-desc",children:nt.description})]},Ve))}),b.jsxs("div",{className:"permission-actions",children:[b.jsx("button",{className:"btn btn-primary",onClick:()=>Me(ze,"granted"),children:"Allow Once"}),b.jsx("button",{className:"btn btn-secondary",onClick:()=>Me(ze,"granted_all"),children:"Allow Always"})]}),b.jsx("button",{className:"permission-abort-link",onClick:()=>Me(ze,"aborted"),children:"Deny & Abort Task"})]})},ze)),[...K.entries()].map(([ze,{questions:Ae,description:Le,sessionName:nt}])=>{const Ve=be.get(ze)??new Array(Ae.length).fill("");return b.jsx("div",{className:"confirm-modal-overlay",children:b.jsxs("div",{className:"confirm-modal input-modal",children:[b.jsx("h2",{className:"confirm-modal-title",children:"Input Required"}),nt&&b.jsx("p",{className:"confirm-modal-subtitle",children:nt}),Le&&b.jsx("p",{className:"confirm-modal-message",children:Le}),b.jsx("div",{className:"input-list",children:Ae.map((Je,We)=>b.jsxs("div",{className:"input-item",children:[b.jsx("label",{className:"input-label",children:Je}),b.jsx("input",{type:"text",className:"input-field",value:Ve[We]??"",onChange:Fe=>{je(et=>{const ft=new Map(et),ht=[...ft.get(ze)??[]];return ht[We]=Fe.target.value,ft.set(ze,ht),ft})},autoFocus:We===0})]},We))}),b.jsx("div",{className:"input-actions",children:b.jsx("button",{className:"btn btn-primary",disabled:Ve.some(Je=>!Je.trim()),onClick:()=>Ie(ze,Ve),children:"Submit"})}),b.jsx("button",{className:"permission-abort-link",onClick:()=>Ie(ze,["aborted"]),children:"Cancel"})]})},ze)})]}),document.body)]})}const vO=ys("Preferences",{web:()=>qd(()=>import("./web-DAcCX19l.js"),[]).then(e=>new e.PreferencesWeb)}),kl=!!window.__PALMIER_SERVE__&&(window.location.hostname==="localhost"||window.location.hostname==="127.0.0.1"),Hb=Xn.isNativePlatform();function wO(){const[e,t]=j.useState(""),[r,s]=j.useState(!0),[l,u]=j.useState(!1),[c,f]=j.useState(null),{addPairedHost:d}=qi(),m=Mr();async function y(){const g=e.trim().toUpperCase();if(!g){f("Enter a pairing code.");return}u(!0),f(null);try{let x;if(kl){const T=await fetch("/pair",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({code:g,label:navigator.userAgent})});if(!T.ok){const z=await T.json().catch(()=>({error:"Connection failed"}));throw new Error(z.error||`HTTP ${T.status}`)}x=await T.json()}else{const T=await fetch(`${Uu}/api/config`);if(!T.ok)throw new Error("Failed to fetch server config");const z=await T.json();if(!z.natsWsUrl)throw new Error("Server has no NATS WebSocket URL configured");const D=await Nx({servers:z.natsWsUrl,authenticator:wx(z.natsJwt,new TextEncoder().encode(z.natsNkeySeed))}),H=Nu(),F=`pair.${g}`,oe=await D.request(F,H.encode(JSON.stringify({label:navigator.userAgent})),{timeout:1e4});x=JSON.parse(H.decode(oe.data)),await D.close()}const w={hostId:x.hostId,clientToken:x.clientToken,directUrl:kl?window.location.origin:void 0,...x.hostName?{name:x.hostName}:{}};if(d(w),Xn.isNativePlatform()&&mn){await vO.set({key:"hostId",value:x.hostId});try{const{token:T}=await mn.getFcmToken();await fetch(`${Uu}/api/fcm/register`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({hostId:x.hostId,fcmToken:T})})}catch(T){console.warn("FCM token registration failed:",T)}}const S=`/hosts/${encodeURIComponent(x.hostId)}`;m(Hb&&r?`${S}/pair/setup`:S)}catch(x){const w=x instanceof Error?x.message:String(x);w.includes("timeout")||w.includes("TIMEOUT")||w.includes("503")||w.toLowerCase().includes("no responders")?f("Code not found or expired. Check the code and try again."):f(w)}finally{u(!1)}}return b.jsx("div",{className:"pair-page",children:b.jsxs("div",{className:"pair-card",children:[b.jsxs("div",{className:"pair-header",children:[b.jsx("h1",{className:"pair-title",children:kl?"Pair":"Pair with Host"}),b.jsx("p",{className:"pair-subtitle",children:kl?"Enter the pairing code shown in your terminal.":"Connect this device to a Palmier host"})]}),!kl&&b.jsxs("div",{className:"pair-instructions",children:[b.jsxs("div",{className:"pair-instruction-block",children:[b.jsx("h3",{className:"pair-instruction-heading",children:"Setting up a new host?"}),b.jsxs("ol",{className:"pair-steps",children:[b.jsxs("li",{children:["Install at least one agent CLI (e.g., ",b.jsx("a",{href:"https://www.palmier.me/agents",target:"_blank",rel:"noopener noreferrer",children:"Claude Code, Gemini CLI, Codex CLI"}),")"]}),b.jsxs("li",{children:["Install Palmier on your host machine.",b.jsx("span",{className:"pair-platform-label",children:"Linux / macOS:"}),b.jsx("code",{className:"pair-command",children:"curl -fsSL https://palmier.me/install.sh | bash"}),b.jsx("span",{className:"pair-platform-label",children:"Windows (PowerShell):"}),b.jsx("code",{className:"pair-command",children:"irm https://palmier.me/install.ps1 | iex"})]}),b.jsxs("li",{children:["Run the setup wizard:",b.jsx("code",{className:"pair-command",children:"palmier init"})]}),b.jsx("li",{children:"A pairing code will display automatically"})]})]}),b.jsx("div",{className:"pair-instruction-divider"}),b.jsxs("div",{className:"pair-instruction-block",children:[b.jsx("h3",{className:"pair-instruction-heading",children:"Pairing an existing host?"}),b.jsxs("ol",{className:"pair-steps",children:[b.jsxs("li",{children:["Run ",b.jsx("code",{children:"palmier pair"})," on the host machine"]}),b.jsx("li",{children:"Enter the 6-character code below"})]})]})]}),b.jsxs("div",{className:"pair-form",children:[b.jsxs("label",{className:"form-label",htmlFor:"pair-code",children:["Pairing code",b.jsx("input",{id:"pair-code",type:"text",maxLength:6,value:e,onChange:g=>t(g.target.value.toUpperCase()),placeholder:"A7K9M2",className:"form-input form-input-mono pair-code-input",autoFocus:!0,autoComplete:"off",disabled:l})]}),Hb&&b.jsxs("label",{className:"pair-checkbox",children:[b.jsx("input",{type:"checkbox",checked:r,onChange:g=>s(g.target.checked),disabled:l}),b.jsxs("span",{className:"pair-checkbox-text",children:[b.jsx("span",{className:"pair-checkbox-title",children:"Link the host to this device"}),b.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&&b.jsx("p",{className:"pair-error",children:c}),b.jsxs("button",{className:"btn btn-primary btn-full",onClick:y,disabled:l||!e.trim(),children:[l&&b.jsx("span",{className:"btn-spinner"}),l?"Pairing...":"Pair"]}),b.jsx("button",{className:"btn btn-secondary btn-full",onClick:()=>m("/"),disabled:l,children:"Cancel"}),b.jsxs("p",{className:"pair-consent",children:["By pairing, you agree to our"," ",b.jsx("a",{href:"https://www.palmier.me/terms",target:"_blank",rel:"noopener noreferrer",children:"Terms of Service"})," and"," ",b.jsx("a",{href:"https://www.palmier.me/privacy",target:"_blank",rel:"noopener noreferrer",children:"Privacy Policy"}),"."]})]})]})})}function SO(){const e=Mr(),{connected:t,request:r,activeHost:s}=si(),{setHostLanUrl:l,pairedHosts:u}=qi(),c=u.length<=1,[f,d]=j.useState("loading"),[m,y]=j.useState(null),[g,x]=j.useState(null);function w(){e(`/hosts/${encodeURIComponent(s.hostId)}`,{replace:!0})}j.useEffect(()=>{if(!t||f!=="loading")return;let H=!1;return r("host.info").catch(()=>({})).then(F=>{if(H)return;l(s.hostId,F.lan_url??void 0);const oe=F.linked_client_token??null;y(oe);const B=!!oe&&oe!==s.clientToken;d(B?"confirming":"linking")}),()=>{H=!0}},[t,f,s,r,l]),j.useEffect(()=>{if(f!=="linking")return;let H=!1;return(async()=>{try{if(mn){const{token:F}=await mn.getFcmToken();if(!F)throw new Error("Could not read FCM token");await r("device.link",{fcmToken:F})}if(H)return;c?d("wizard"):w()}catch(F){if(H)return;x(F instanceof Error?F.message:String(F)),d("linkError")}})(),()=>{H=!0}},[f]);function S(){d("linking")}function T(){w()}function z(){x(null),d("linking")}const D=f==="confirming"&&ds.createPortal(b.jsx("div",{className:"confirm-modal-overlay",onClick:T,children:b.jsxs("div",{className:"confirm-modal",onClick:H=>H.stopPropagation(),children:[b.jsx("h2",{className:"confirm-modal-title",children:"Link the host to this device?"}),b.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."}),b.jsxs("div",{className:"confirm-modal-actions",children:[b.jsx("button",{className:"btn btn-secondary",onClick:T,children:"Cancel"}),b.jsx("button",{className:"btn btn-primary",onClick:S,children:"Link"})]})]})}),document.body);if(f==="loading"||f==="confirming"||f==="linking"||f==="linkError"){const H=c,F=f==="loading"||f==="confirming"||f==="linking";return b.jsxs("div",{className:"pair-setup",children:[b.jsxs("div",{className:"pair-setup-inner",children:[H&&b.jsx("h1",{className:"pair-setup-title",children:"Device Capabilities"}),b.jsxs("div",{className:"pair-setup-loading",children:[F&&b.jsx("span",{className:"spinner spinner-lg"}),f==="loading"&&b.jsx("span",{children:"Connecting to host…"}),f==="confirming"&&b.jsx("span",{children:"Awaiting confirmation…"}),f==="linking"&&b.jsx("span",{children:"Linking device…"}),f==="linkError"&&b.jsxs(b.Fragment,{children:[b.jsx("p",{className:"pair-error",children:g}),b.jsx("button",{className:"btn btn-primary",onClick:z,children:"Retry"}),b.jsx("button",{className:"btn btn-secondary",onClick:w,children:"Skip linking"})]})]})]}),D]})}return b.jsx("div",{className:"pair-setup",children:b.jsxs("div",{className:"pair-setup-inner",children:[b.jsx("h1",{className:"pair-setup-title",children:"Device Capabilities"}),b.jsx("p",{className:"pair-setup-description",children:"Choose what the host can use this device for. You can change these later from the menu."}),b.jsx(Bx,{}),b.jsx("div",{className:"pair-setup-actions",children:b.jsx("button",{className:"btn btn-primary btn-full",onClick:w,children:"Finish"})})]})})}function _O(){const e=Mr();return j.useEffect(()=>{if(!mn)return;const t=mn.addListener("deepLink",({path:r})=>e(r));return()=>{t.then(r=>r.remove())}},[e]),null}function kO(){const{pairedHosts:e}=qi();return e.length===0?b.jsx(Ll,{to:"/pair",replace:!0}):b.jsx(Ll,{to:`/hosts/${encodeURIComponent(e[0].hostId)}`,replace:!0})}function EO(){const{hostId:e}=$u(),{pairedHosts:t}=qi(),r=t.find(s=>s.hostId===e)??null;return r?b.jsx(gE,{activeHost:r,children:b.jsxs(nx,{children:[b.jsx(br,{index:!0,element:b.jsx(xu,{})}),b.jsx(br,{path:"tasks",element:b.jsx(xu,{})}),b.jsx(br,{path:"runs/:taskId",element:b.jsx(xu,{})}),b.jsx(br,{path:"runs/:taskId/:runId",element:b.jsx(xu,{})}),b.jsx(br,{path:"pair/setup",element:b.jsx(SO,{})}),b.jsx(br,{path:"*",element:b.jsx(Ll,{to:".",replace:!0})})]})}):b.jsx(Ll,{to:"/",replace:!0})}function CO(){return b.jsxs(H_,{children:[b.jsx(_O,{}),b.jsxs(nx,{children:[b.jsx(br,{path:"/",element:b.jsx(kO,{})}),b.jsx(br,{path:"/pair",element:b.jsx(wO,{})}),b.jsx(br,{path:"/hosts/:hostId/*",element:b.jsx(EO,{})}),b.jsx(br,{path:"*",element:b.jsx(Ll,{to:"/",replace:!0})})]})]})}lS.createRoot(document.getElementById("root")).render(b.jsx(j.StrictMode,{children:b.jsx(A_,{children:b.jsx(CO,{})})}));export{Hd as W};
120
+ `))}function d(w,S,T,z){const D=T.enter("tableCell"),H=T.enter("phrasing"),F=T.containerPhrasing(w,{...z,before:u,after:u});return H(),D(),F}function m(w,S){return IN(w,{align:S,alignDelimiters:s,padding:r,stringLength:l})}function y(w,S,T){const z=w.children;let D=-1;const H=[],F=S.enter("table");for(;++D<z.length;)H[D]=g(z[D],S,T);return F(),H}function g(w,S,T){const z=w.children;let D=-1;const H=[],F=S.enter("tableRow");for(;++D<z.length;)H[D]=d(z[D],w,S,T);return F(),H}function x(w,S,T){let z=L1.inlineCode(w,S,T);return T.stack.includes("tableCell")&&(z=z.replace(/\|/g,"\\$&")),z}}function T3(){return{exit:{taskListCheckValueChecked:zb,taskListCheckValueUnchecked:zb,paragraph:O3}}}function N3(){return{unsafe:[{atBreak:!0,character:"-",after:"[:|-]"}],handlers:{listItem:R3}}}function zb(e){const t=this.stack[this.stack.length-2];t.type,t.checked=e.type==="taskListCheckValueChecked"}function O3(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 u=-1,c;for(;++u<l.length;){const f=l[u];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 R3(e,t,r,s){const l=e.children[0],u=typeof e.checked=="boolean"&&l&&l.type==="paragraph",c="["+(e.checked?"x":" ")+"] ",f=r.createTracker(s);u&&f.move(c);let d=L1.listItem(e,t,r,{...s,...f.current()});return u&&(d=d.replace(/^(?:[*+-]|\d+\.)([\r\n]| {1,3})/,m)),d;function m(y){return y+c}}function M3(){return[fN(),RN(),zN(),S3(),T3()]}function D3(e){return{extensions:[hN(),MN(e),UN(),j3(e),N3()]}}const L3={tokenize:q3,partial:!0},z1={tokenize:I3,partial:!0},U1={tokenize:F3,partial:!0},B1={tokenize:$3,partial:!0},z3={tokenize:Y3,partial:!0},P1={name:"wwwAutolink",tokenize:P3,previous:q1},H1={name:"protocolAutolink",tokenize:H3,previous:I1},ai={name:"emailAutolink",tokenize:B3,previous:F1},Dr={};function U3(){return{text:Dr}}let hs=48;for(;hs<123;)Dr[hs]=ai,hs++,hs===58?hs=65:hs===91&&(hs=97);Dr[43]=ai;Dr[45]=ai;Dr[46]=ai;Dr[95]=ai;Dr[72]=[ai,H1];Dr[104]=[ai,H1];Dr[87]=[ai,P1];Dr[119]=[ai,P1];function B3(e,t,r){const s=this;let l,u;return c;function c(g){return!kd(g)||!F1.call(s,s.previous)||lm(s.events)?r(g):(e.enter("literalAutolink"),e.enter("literalAutolinkEmail"),f(g))}function f(g){return kd(g)?(e.consume(g),f):g===64?(e.consume(g),d):r(g)}function d(g){return g===46?e.check(z3,y,m)(g):g===45||g===95||pn(g)?(u=!0,e.consume(g),d):y(g)}function m(g){return e.consume(g),l=!0,d}function y(g){return u&&l&&kn(s.previous)?(e.exit("literalAutolinkEmail"),e.exit("literalAutolink"),t(g)):r(g)}}function P3(e,t,r){const s=this;return l;function l(c){return c!==87&&c!==119||!q1.call(s,s.previous)||lm(s.events)?r(c):(e.enter("literalAutolink"),e.enter("literalAutolinkWww"),e.check(L3,e.attempt(z1,e.attempt(U1,u),r),r)(c))}function u(c){return e.exit("literalAutolinkWww"),e.exit("literalAutolink"),t(c)}}function H3(e,t,r){const s=this;let l="",u=!1;return c;function c(g){return(g===72||g===104)&&I1.call(s,s.previous)&&!lm(s.events)?(e.enter("literalAutolink"),e.enter("literalAutolinkHttp"),l+=String.fromCodePoint(g),e.consume(g),f):r(g)}function f(g){if(kn(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),u?m:(u=!0,d)):r(g)}function m(g){return g===null||Bu(g)||Nt(g)||gs(g)||Qu(g)?r(g):e.attempt(z1,e.attempt(U1,y),r)(g)}function y(g){return e.exit("literalAutolinkHttp"),e.exit("literalAutolink"),t(g)}}function q3(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),u):r(c)}function u(c){return c===null?r(c):t(c)}}function I3(e,t,r){let s,l,u;return c;function c(m){return m===46||m===95?e.check(B1,d,f)(m):m===null||Nt(m)||gs(m)||m!==45&&Qu(m)?d(m):(u=!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||!u?r(m):t(m)}}function F3(e,t){let r=0,s=0;return l;function l(c){return c===40?(r++,e.consume(c),l):c===41&&s<r?u(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(B1,t,u)(c):c===null||Nt(c)||gs(c)?t(c):(e.consume(c),l)}function u(c){return c===41&&s++,e.consume(c),l}}function $3(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),u):f===93?(e.consume(f),l):f===60||f===null||Nt(f)||gs(f)?t(f):r(f)}function l(f){return f===null||f===40||f===91||Nt(f)||gs(f)?t(f):s(f)}function u(f){return kn(f)?c(f):r(f)}function c(f){return f===59?(e.consume(f),s):kn(f)?(e.consume(f),c):r(f)}}function Y3(e,t,r){return s;function s(u){return e.consume(u),l}function l(u){return pn(u)?r(u):t(u)}}function q1(e){return e===null||e===40||e===42||e===95||e===91||e===93||e===126||Nt(e)}function I1(e){return!kn(e)}function F1(e){return!(e===47||kd(e))}function kd(e){return e===43||e===45||e===46||e===95||pn(e)}function lm(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 G3={tokenize:eO,partial:!0};function V3(){return{document:{91:{name:"gfmFootnoteDefinition",tokenize:Q3,continuation:{tokenize:Z3},exit:W3}},text:{91:{name:"gfmFootnoteCall",tokenize:K3},93:{name:"gfmPotentialFootnoteCall",add:"after",tokenize:J3,resolveTo:X3}}}}function J3(e,t,r){const s=this;let l=s.events.length;const u=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=wr(s.sliceSerialize({start:c.end,end:s.now()}));return m.codePointAt(0)!==94||!u.includes(m.slice(1))?r(d):(e.enter("gfmFootnoteCallLabelMarker"),e.consume(d),e.exit("gfmFootnoteCallLabelMarker"),t(d))}}function X3(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 u={type:"gfmFootnoteCallString",start:Object.assign({},l.end),end:Object.assign({},e[e.length-1][1].start)},c={type:"chunkString",contentType:"string",start:Object.assign({},u.start),end:Object.assign({},u.end)},f=[e[r+1],e[r+2],["enter",s,t],e[r+3],e[r+4],["enter",l,t],["exit",l,t],["enter",u,t],["enter",c,t],["exit",c,t],["exit",u,t],e[e.length-2],e[e.length-1],["exit",s,t]];return e.splice(r,e.length-r+1,...f),e}function K3(e,t,r){const s=this,l=s.parser.gfmFootnotes||(s.parser.gfmFootnotes=[]);let u=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(u>999||g===93&&!c||g===null||g===91||Nt(g))return r(g);if(g===93){e.exit("chunkString");const x=e.exit("gfmFootnoteCallString");return l.includes(wr(s.sliceSerialize(x)))?(e.enter("gfmFootnoteCallLabelMarker"),e.consume(g),e.exit("gfmFootnoteCallLabelMarker"),e.exit("gfmFootnoteCall"),t):r(g)}return Nt(g)||(c=!0),u++,e.consume(g),g===92?y:m}function y(g){return g===91||g===92||g===93?(e.consume(g),u++,m):m(g)}}function Q3(e,t,r){const s=this,l=s.parser.gfmFootnotes||(s.parser.gfmFootnotes=[]);let u,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",y):r(S)}function y(S){if(c>999||S===93&&!f||S===null||S===91||Nt(S))return r(S);if(S===93){e.exit("chunkString");const T=e.exit("gfmFootnoteDefinitionLabelString");return u=wr(s.sliceSerialize(T)),e.enter("gfmFootnoteDefinitionLabelMarker"),e.consume(S),e.exit("gfmFootnoteDefinitionLabelMarker"),e.exit("gfmFootnoteDefinitionLabel"),x}return Nt(S)||(f=!0),c++,e.consume(S),S===92?g:y}function g(S){return S===91||S===92||S===93?(e.consume(S),c++,y):y(S)}function x(S){return S===58?(e.enter("definitionMarker"),e.consume(S),e.exit("definitionMarker"),l.includes(u)||l.push(u),ct(e,w,"gfmFootnoteDefinitionWhitespace")):r(S)}function w(S){return t(S)}}function Z3(e,t,r){return e.check(Vl,t,e.attempt(G3,t,r))}function W3(e){e.exit("gfmFootnoteDefinition")}function eO(e,t,r){const s=this;return ct(e,l,"gfmFootnoteDefinitionIndent",5);function l(u){const c=s.events[s.events.length-1];return c&&c[1].type==="gfmFootnoteDefinitionIndent"&&c[2].sliceSerialize(c[1],!0).length===4?t(u):r(u)}}function tO(e){let r=(e||{}).singleTilde;const s={name:"strikethrough",tokenize:u,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 y={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",y,f],["enter",c[m][1],f],["exit",c[m][1],f],["enter",g,f]],w=f.parser.constructs.insideSpan.null;w&&Vn(x,x.length,0,Zu(w,c.slice(m+1,d),f)),Vn(x,x.length,0,[["exit",g,f],["enter",c[d][1],f],["exit",c[d][1],f],["exit",y,f]]),Vn(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 u(c,f,d){const m=this.previous,y=this.events;let g=0;return x;function x(S){return m===126&&y[y.length-1][1].type!=="characterEscape"?d(S):(c.enter("strikethroughSequenceTemporary"),w(S))}function w(S){const T=ba(m);if(S===126)return g>1?d(S):(c.consume(S),g++,w);if(g<2&&!r)return d(S);const z=c.exit("strikethroughSequenceTemporary"),D=ba(S);return z._open=!D||D===2&&!!T,z._close=!T||T===2&&!!D,f(S)}}}class nO{constructor(){this.map=[]}add(t,r,s){rO(this,t,r,s)}consume(t){if(this.map.sort(function(u,c){return u[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 u of l)t.push(u);l=s.pop()}this.map.length=0}}function rO(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 iO(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 u=s.length-1;s[u]=s[u]==="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 sO(){return{flow:{null:{name:"table",tokenize:aO,resolveAll:lO}}}}function aO(e,t,r){const s=this;let l=0,u=0,c;return f;function f(R){let G=s.events.length-1;for(;G>-1;){const ie=s.events[G][1].type;if(ie==="lineEnding"||ie==="linePrefix")G--;else break}const J=G>-1?s.events[G][1].type:null,fe=J==="tableHead"||J==="tableRow"?L:d;return fe===L&&s.parser.lazy[s.now().line]?r(R):fe(R)}function d(R){return e.enter("tableHead"),e.enter("tableRow"),m(R)}function m(R){return R===124||(c=!0,u+=1),y(R)}function y(R){return R===null?r(R):Pe(R)?u>1?(u=0,s.interrupt=!0,e.exit("tableRow"),e.enter("lineEnding"),e.consume(R),e.exit("lineEnding"),w):r(R):st(R)?ct(e,y,"whitespace")(R):(u+=1,c&&(c=!1,l+=1),R===124?(e.enter("tableCellDivider"),e.consume(R),e.exit("tableCellDivider"),c=!0,y):(e.enter("data"),g(R)))}function g(R){return R===null||R===124||Nt(R)?(e.exit("data"),y(R)):(e.consume(R),R===92?x:g)}function x(R){return R===92||R===124?(e.consume(R),g):g(R)}function w(R){return s.interrupt=!1,s.parser.lazy[s.now().line]?r(R):(e.enter("tableDelimiterRow"),c=!1,st(R)?ct(e,S,"linePrefix",s.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(R):S(R))}function S(R){return R===45||R===58?z(R):R===124?(c=!0,e.enter("tableCellDivider"),e.consume(R),e.exit("tableCellDivider"),T):B(R)}function T(R){return st(R)?ct(e,z,"whitespace")(R):z(R)}function z(R){return R===58?(u+=1,c=!0,e.enter("tableDelimiterMarker"),e.consume(R),e.exit("tableDelimiterMarker"),D):R===45?(u+=1,D(R)):R===null||Pe(R)?oe(R):B(R)}function D(R){return R===45?(e.enter("tableDelimiterFiller"),H(R)):B(R)}function H(R){return R===45?(e.consume(R),H):R===58?(c=!0,e.exit("tableDelimiterFiller"),e.enter("tableDelimiterMarker"),e.consume(R),e.exit("tableDelimiterMarker"),F):(e.exit("tableDelimiterFiller"),F(R))}function F(R){return st(R)?ct(e,oe,"whitespace")(R):oe(R)}function oe(R){return R===124?S(R):R===null||Pe(R)?!c||l!==u?B(R):(e.exit("tableDelimiterRow"),e.exit("tableHead"),t(R)):B(R)}function B(R){return r(R)}function L(R){return e.enter("tableRow"),W(R)}function W(R){return R===124?(e.enter("tableCellDivider"),e.consume(R),e.exit("tableCellDivider"),W):R===null||Pe(R)?(e.exit("tableRow"),t(R)):st(R)?ct(e,W,"whitespace")(R):(e.enter("data"),$(R))}function $(R){return R===null||R===124||Nt(R)?(e.exit("data"),W(R)):(e.consume(R),R===92?q:$)}function q(R){return R===92||R===124?(e.consume(R),$):$(R)}}function lO(e,t){let r=-1,s=!0,l=0,u=[0,0,0,0],c=[0,0,0,0],f=!1,d=0,m,y,g;const x=new nO;for(;++r<e.length;){const w=e[r],S=w[1];w[0]==="enter"?S.type==="tableHead"?(f=!1,d!==0&&(Ub(x,t,d,m,y),y=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,u=[0,0,0,0],c=[0,r+1,0,0],f&&(f=!1,y={type:"tableBody",start:Object.assign({},S.start),end:Object.assign({},S.end)},x.add(r,0,[["enter",y,t]])),l=S.type==="tableDelimiterRow"?2:y?3:1):l&&(S.type==="data"||S.type==="tableDelimiterMarker"||S.type==="tableDelimiterFiller")?(s=!1,c[2]===0&&(u[1]!==0&&(c[0]=c[1],g=bu(x,t,u,l,void 0,g),u=[0,0,0,0]),c[2]=r)):S.type==="tableCellDivider"&&(s?s=!1:(u[1]!==0&&(c[0]=c[1],g=bu(x,t,u,l,void 0,g)),u=c,c=[u[1],r,0,0])):S.type==="tableHead"?(f=!0,d=r):S.type==="tableRow"||S.type==="tableDelimiterRow"?(d=r,u[1]!==0?(c[0]=c[1],g=bu(x,t,u,l,r,g)):c[1]!==0&&(g=bu(x,t,c,l,r,g)),l=0):l&&(S.type==="data"||S.type==="tableDelimiterMarker"||S.type==="tableDelimiterFiller")&&(c[3]=r)}for(d!==0&&Ub(x,t,d,m,y),x.consume(t.events),r=-1;++r<t.events.length;){const w=t.events[r];w[0]==="enter"&&w[1].type==="table"&&(w[1]._align=iO(t.events,r))}return e}function bu(e,t,r,s,l,u){const c=s===1?"tableHeader":s===2?"tableDelimiter":"tableData",f="tableContent";r[0]!==0&&(u.end=Object.assign({},ia(t.events,r[0])),e.add(r[0],0,[["exit",u,t]]));const d=ia(t.events,r[1]);if(u={type:c,start:Object.assign({},d),end:Object.assign({},d)},e.add(r[1],0,[["enter",u,t]]),r[2]!==0){const m=ia(t.events,r[2]),y=ia(t.events,r[3]),g={type:f,start:Object.assign({},m),end:Object.assign({},y)};if(e.add(r[2],0,[["enter",g,t]]),s!==2){const x=t.events[r[2]],w=t.events[r[3]];if(x[1].end=Object.assign({},w[1].end),x[1].type="chunkText",x[1].contentType="text",r[3]>r[2]+1){const S=r[2]+1,T=r[3]-r[2]-1;e.add(S,T,[])}}e.add(r[3]+1,0,[["exit",g,t]])}return l!==void 0&&(u.end=Object.assign({},ia(t.events,l)),e.add(l,0,[["exit",u,t]]),u=void 0),u}function Ub(e,t,r,s,l){const u=[],c=ia(t.events,r);l&&(l.end=Object.assign({},c),u.push(["exit",l,t])),s.end=Object.assign({},c),u.push(["exit",s,t]),e.add(r+1,0,u)}function ia(e,t){const r=e[t],s=r[0]==="enter"?"start":"end";return r[1][s]}const oO={name:"tasklistCheck",tokenize:cO};function uO(){return{text:{91:oO}}}function cO(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"),u)}function u(d){return Nt(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 Pe(d)?t(d):st(d)?e.check({tokenize:fO},t,r)(d):r(d)}}function fO(e,t,r){return ct(e,s,"whitespace");function s(l){return l===null?r(l):t(l)}}function hO(e){return Wx([U3(),V3(),tO(e),sO(),uO()])}const dO={};function Bb(e){const t=this,r=e||dO,s=t.data(),l=s.micromarkExtensions||(s.micromarkExtensions=[]),u=s.fromMarkdownExtensions||(s.fromMarkdownExtensions=[]),c=s.toMarkdownExtensions||(s.toMarkdownExtensions=[]);l.push(hO(r)),u.push(M3()),c.push(D3(r))}function mO(e){v1(e,[/\r?\n|\r/g,pO])}function pO(){return{type:"break"}}function Pb(){return function(e){mO(e)}}function gO({connected:e,hostId:t,request:r,subscribeEvents:s,taskId:l,runId:u}){const c=Mr(),f=Id(),[d,m]=j.useState(!0),[y,g]=j.useState([]),[x,w]=j.useState(),[S,T]=j.useState(),z=x==="started"||x==="monitoring",D=x==="followup",H=x==="started"||x==="followup",[F,oe]=j.useState(null);dd(F!==null,()=>oe(null));const[B,L]=j.useState(!1),[W,$]=j.useState(""),[q,R]=j.useState(!1),G=j.useRef(null),J=j.useRef(null),fe=j.useRef(null),[ie,ee]=j.useState(u==="latest"?void 0:u),P=u==="latest"&&ie===null;j.useEffect(()=>{if(u!=="latest"){ee(u);return}e&&(ee(void 0),r("taskrun.list",{task_id:l,limit:1}).then(E=>{var K,A;return ee(((A=(K=E.entries)==null?void 0:K[0])==null?void 0:A.run_id)??null)}).catch(()=>ee(null)))},[u,l,e,r]);async function X(){if(ie)try{const E=await r("task.result",{id:l,run_id:ie});if(E.error){console.error("No result:",E.error),c(t?`/hosts/${encodeURIComponent(t)}`:"/",{replace:!0});return}g(E.messages??[]),w(E.running_state),T(E.agent)}catch(E){console.error("Failed to load result:",E),c(t?`/hosts/${encodeURIComponent(t)}`:"/",{replace:!0})}finally{m(!1)}}async function ae(E){var K;if(ie)try{const be=(K=(await r("task.reports",{id:l,run_id:ie,report_files:[E]})).reports)==null?void 0:K[0];be!=null&&be.data_url?oe({file:E,data_url:be.data_url}):oe({file:E,content:(be==null?void 0:be.content)??"Report not found."})}catch{oe({file:E,content:"Failed to load report."})}}j.useEffect(()=>{!e||!ie||(m(!0),X())},[e,l,ie]),j.useEffect(()=>!e||!t||!ie?void 0:s(t,async K=>{try{const A=JSON.parse(new TextDecoder().decode(K.data));if(A.event_type!=="running-state"&&A.event_type!=="result-updated"||K.subject.split(".").pop()!==l||A.event_type==="result-updated"&&A.run_id&&A.run_id!==ie)return;X()}catch{}}),[e,t,l,ie,s,r]),j.useEffect(()=>{G.current&&(G.current.scrollTop=G.current.scrollHeight)},[y]),j.useEffect(()=>{d||P||!ie||fe.current!==ie&&(fe.current=ie,requestAnimationFrame(()=>{G.current&&(G.current.scrollTop=G.current.scrollHeight),window.scrollTo({top:document.documentElement.scrollHeight,behavior:"auto"})}))},[d,P,ie]);function pe(E){if(E==="input")return"User Input";if(E==="permission")return"Permission";if(E==="confirmation")return"Confirmation"}function M(E){return E==="started"?"Task started":E==="finished"?"Task finished":E==="failed"?"Task failed":E==="error"?"Command failed":E==="aborted"?"Task aborted":E==="confirmation"?"Task confirmed":E==="stopped"?"Follow-up stopped":E??""}return b.jsxs("div",{className:"run-detail",children:[b.jsxs("button",{className:"run-detail-back",onClick:()=>c(-1),children:[b.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:b.jsx("path",{d:"M15 18l-6-6 6-6"})}),"Back"]}),P?b.jsxs("div",{className:"empty-state",children:[b.jsx("p",{className:"empty-state-text",children:"No runs yet"}),b.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?b.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"var(--space-sm)",padding:"var(--space-sm) 0"},children:[b.jsx("div",{className:"skeleton-line",style:{width:"40%"}}),b.jsx("div",{className:"skeleton-line",style:{width:"55%"}}),b.jsx("div",{className:"skeleton-line",style:{width:"100%",height:"8rem",marginTop:"var(--space-sm)"}})]}):b.jsxs(b.Fragment,{children:[b.jsxs("div",{className:"chat-thread",ref:G,children:[y.map((E,K)=>{const A=H&&E.role==="assistant"&&!y.slice(K+1).some(be=>be.role==="assistant"||be.role==="user");return E.role==="status"&&E.type==="monitoring"?null:E.role==="status"?b.jsxs("div",{className:`chat-status${E.type==="error"?" chat-status--error":""}`,children:[b.jsxs("div",{children:[M(E.type),E.time>0&&b.jsx("span",{className:"chat-status-time",children:f(E.time)})]}),E.content&&b.jsx("pre",{className:"chat-status-detail",children:E.content})]},K):b.jsxs("div",{className:`chat-message chat-message--${E.role}${E.role==="assistant"&&E.stream==="stderr"?" chat-message--stderr":""}`,children:[E.role==="assistant"&&S&&b.jsx("div",{className:"chat-message-agent",children:hd(S)}),b.jsxs("div",{className:"chat-message-content",children:[b.jsx(Nb,{remarkPlugins:[Bb,Pb],children:E.content}),A&&b.jsxs("div",{className:"chat-typing-indicator",children:[b.jsx("span",{}),b.jsx("span",{}),b.jsx("span",{})]})]}),E.attachments&&E.attachments.length>0&&b.jsx("div",{className:"chat-message-attachments",children:E.attachments.map(be=>b.jsx("button",{className:"chat-attachment-chip",onClick:()=>ae(be),children:be},be))}),b.jsxs("div",{className:"chat-message-meta",children:[pe(E.type)&&b.jsx("span",{className:"chat-message-type",children:pe(E.type)}),E.time>0&&b.jsx("span",{children:f(E.time)})]})]},K)}),H&&(()=>{const E=y.filter(K=>K.role!=="status");return E.length===0||E[E.length-1].role!=="assistant"})()&&b.jsxs("div",{className:"chat-message chat-message--assistant",children:[S&&b.jsx("div",{className:"chat-message-agent",children:hd(S)}),b.jsxs("div",{className:"chat-typing-indicator",children:[b.jsx("span",{}),b.jsx("span",{}),b.jsx("span",{})]})]}),x==="monitoring"&&b.jsxs("div",{className:"chat-monitoring-indicator",children:[b.jsx("span",{className:"chat-monitoring-dot"}),"Monitoring command output"]})]}),z?b.jsx("div",{className:"chat-abort-bar",children:b.jsx("button",{className:"btn btn-secondary chat-abort-btn",disabled:B,onClick:async()=>{if(confirm("Abort this task?")){L(!0);try{await r("task.abort",{id:l})}catch(E){console.error("Abort failed:",E)}finally{L(!1)}}},children:B?"Aborting...":"Abort Task"})}):D?b.jsx("div",{className:"chat-input-bar",children:b.jsx("button",{className:"btn btn-secondary chat-stop-btn",disabled:B,onClick:async()=>{L(!0);try{await r("task.stop_followup",{id:l,run_id:ie})}catch(E){console.error("Stop failed:",E)}finally{L(!1)}},children:b.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"currentColor",children:b.jsx("rect",{x:"6",y:"6",width:"12",height:"12",rx:"2"})})})}):b.jsxs("form",{className:"chat-input-bar",onSubmit:async E=>{E.preventDefault();const K=W.trim();if(!(!K||q)){R(!0);try{await r("task.followup",{id:l,run_id:ie,message:K}),$("")}catch(A){console.error("Follow-up failed:",A)}finally{R(!1)}}},children:[b.jsx("input",{ref:J,className:"chat-input",type:"text",placeholder:"Follow-up message",value:W,onChange:E=>$(E.target.value),disabled:q}),b.jsx("button",{className:"btn btn-primary chat-send-btn",type:"submit",disabled:!W.trim()||q,children:b.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[b.jsx("line",{x1:"22",y1:"2",x2:"11",y2:"13"}),b.jsx("polygon",{points:"22 2 15 22 11 13 2 9 22 2"})]})})]})]}),F&&b.jsx("div",{className:"report-dialog-overlay",onClick:()=>oe(null),children:b.jsxs("div",{className:"report-dialog",onClick:E=>E.stopPropagation(),children:[b.jsxs("div",{className:"report-dialog-header",children:[b.jsx("span",{className:"report-dialog-title",children:F.file}),b.jsx("button",{className:"report-dialog-close",onClick:()=>oe(null),"aria-label":"Close",children:b.jsxs("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[b.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),b.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})})]}),b.jsx("div",{className:"report-dialog-body",children:F.data_url?b.jsx("img",{src:F.data_url,alt:F.file,style:{maxWidth:"100%",height:"auto"}}):b.jsx(Nb,{remarkPlugins:[Bb,Pb],components:{a:({...E})=>b.jsx("a",{...E,target:"_blank",rel:"noopener noreferrer"})},children:F.content??""})})]})})]})}function yO(){const{activeHost:e}=si(),t=j.useRef(null);j.useEffect(()=>{if(Xn.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 u=await l.pushManager.getSubscription();if(!u){const{publicKey:f}=await hE("/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}u=await l.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:f})}const c=u.toJSON();await fE("/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 bO="0.9.9";function xO(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 xu(){const{removePairedHost:e,setHostLanUrl:t,setHostTimezone:r}=qi(),{connected:s,request:l,subscribeEvents:u,unauthorized:c,activeHost:f}=si(),d=f.hostId,m=f.clientToken||null,y=Mr(),g=cr(),x=$u(),w=Ux("(min-width: 768px)"),S=g.pathname.endsWith("/tasks"),T=x.runId?void 0:x.taskId,z=!!(x.taskId&&x.runId),[D,H]=j.useState(!1),[F,oe]=j.useState(!1),[B,L]=j.useState(null),[W,$]=j.useState(null),[q,R]=j.useState(null),[G,J]=j.useState(new Set),[fe,ie]=j.useState([]),[ee,P]=j.useState(),X=!!m&&q===m,[ae,pe]=j.useState(new Map),[M,E]=j.useState(new Map),[K,A]=j.useState(new Map),[be,je]=j.useState(new Map);yO(),j.useEffect(()=>{window.scrollTo(0,0)},[d]),j.useEffect(()=>{let ze=!1;return UE().then(Ae=>{ze||J(Ae)}),()=>{ze=!0}},[]),j.useEffect(()=>{s&&l("host.info").then(ze=>{var We,Fe,et,ft,ht,Wt;ie(ze.agents??[]),P(ze.host_platform),R(ze.linked_client_token??null),xE(ze.agents??[]);const Ae=ze.version??null;$(Ae),H(!!Ae&&xO(Ae,bO)),t(d,ze.lan_url??void 0),r(d,ze.host_timezone);const Le=new Map,nt=new Map,Ve=new Map,Je=new Map;for(const $e of ze.pending_prompts??[])if($e.type==="confirmation")Le.set($e.key,{description:((We=$e.meta)==null?void 0:We.description)??"",sessionName:(Fe=$e.meta)==null?void 0:Fe.session_name});else if($e.type==="permission")nt.set($e.key,{permissions:$e.params??[],sessionName:(et=$e.meta)==null?void 0:et.session_name});else if($e.type==="input"){const yn=$e.params??((ft=$e.meta)==null?void 0:ft.input_questions)??[];Ve.set($e.key,{questions:yn,description:(ht=$e.meta)==null?void 0:ht.description,sessionName:(Wt=$e.meta)==null?void 0:Wt.session_name}),Je.set($e.key,new Array(yn.length).fill(""))}pe(Le),E(nt),A(Ve),je(Je)}).catch(()=>{})},[s,d,l,t,r]),j.useEffect(()=>s?u(d,Ae=>{const Le=Ae.subject.split(".");if(Le.length<3)return;const nt=Le.slice(2).join(".");let Ve={};try{Ve=JSON.parse(new TextDecoder().decode(Ae.data))}catch{return}const Je=Ve.event_type,We=Ve.session_id;if(Je==="input-request"&&We){const Fe=Ve.input_questions,et=Ve.session_name,ft=Ve.description;Fe!=null&&Fe.length&&(A(ht=>{if(ht.has(We))return ht;const Wt=new Map(ht);return Wt.set(We,{questions:Fe,description:ft,sessionName:et}),Wt}),je(ht=>{if(ht.has(We))return ht;const Wt=new Map(ht);return Wt.set(We,new Array(Fe.length).fill("")),Wt}));return}if(Je==="input-resolved"&&We){A(Fe=>{if(!Fe.has(We))return Fe;const et=new Map(Fe);return et.delete(We),et}),je(Fe=>{const et=new Map(Fe);return et.delete(We),et});return}if(Je==="confirm-request"&&We){const Fe=Ve.description,et=Ve.session_name;Fe&&pe(ft=>{if(ft.has(We))return ft;const ht=new Map(ft);return ht.set(We,{description:Fe,sessionName:et}),ht});return}if(Je==="confirm-resolved"&&We){pe(Fe=>{if(!Fe.has(We))return Fe;const et=new Map(Fe);return et.delete(We),et});return}if(Je==="permission-request"){const Fe=Ve.required_permissions,et=Ve.session_name;Fe!=null&&Fe.length&&E(ft=>{if(ft.has(nt))return ft;const ht=new Map(ft);return ht.set(nt,{permissions:Fe,sessionName:et}),ht});return}if(Je==="permission-resolved"){E(Fe=>{if(!Fe.has(nt))return Fe;const et=new Map(Fe);return et.delete(nt),et});return}}):void 0,[s,d,u]);async function _e(ze,Ae){try{await l("task.user_input",{id:ze,value:[Ae]})}catch(Le){console.error("[Dashboard] Failed to respond to confirmation:",Le)}}async function Me(ze,Ae){try{await l("task.user_input",{id:ze,value:[Ae]})}catch(Le){console.error("[Dashboard] Failed to respond to permission request:",Le)}}async function Ie(ze,Ae){try{await l("task.user_input",{id:ze,value:Ae})}catch(Le){console.error("[Dashboard] Failed to respond to input request:",Le)}}function ke(ze,Ae){if(!ps())return;const Le=`/hosts/${encodeURIComponent(d)}/runs/${encodeURIComponent(ze)}`;y(Ae?`${Le}/${encodeURIComponent(Ae)}`:Le)}async function Ge(){oe(!0),L(null);try{const ze=await l("host.update");if(ze.error){L(ze.error),oe(!1);return}}catch{}setTimeout(()=>window.location.reload(),15e3)}const Ft=s&&!c;return b.jsxs("div",{className:"dashboard",children:[w&&b.jsx($0,{daemonVersion:W,linkedClientToken:q,request:l,onEnabledCapabilitiesChange:J,onLinkedClientTokenChange:R}),b.jsxs("div",{className:"dashboard-content",children:[b.jsxs("header",{className:"app-header",children:[b.jsxs("div",{className:"app-title-bar",children:[!w&&b.jsx($0,{daemonVersion:W,linkedClientToken:q,request:l,onEnabledCapabilitiesChange:J,onLinkedClientTokenChange:R}),b.jsx("h1",{className:"app-title",children:"Palmier"}),b.jsx(IE,{})]}),b.jsx("div",{className:"tab-bar",children:b.jsx(DE,{})})]}),b.jsx("main",{className:"dashboard-main",children:c?b.jsxs("div",{className:"revoked-state",children:[b.jsx("div",{className:"revoked-icon",children:b.jsxs("svg",{width:"32",height:"32",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",children:[b.jsx("rect",{x:"3",y:"11",width:"18",height:"11",rx:"2",ry:"2"}),b.jsx("path",{d:"M7 11V7a5 5 0 0 1 10 0v4"}),b.jsx("line",{x1:"12",y1:"15",x2:"12",y2:"18"})]})}),b.jsx("h2",{className:"revoked-title",children:"Client Revoked"}),b.jsx("p",{className:"revoked-description",children:"This client was revoked by the host. To reconnect, generate a new pairing code on the host machine."}),b.jsx("div",{className:"revoked-command",children:b.jsx("code",{children:"palmier pair"})}),b.jsxs("div",{className:"revoked-actions",children:[b.jsx("button",{className:"btn btn-primary",onClick:()=>{ps()&&y("/pair")},children:"Re-pair Device"}),b.jsx("button",{className:"btn btn-secondary",onClick:()=>{e(d),y("/",{replace:!0})},children:"Remove Host"})]})]}):Ft?b.jsxs(b.Fragment,{children:[S&&!z&&b.jsx(ME,{connected:s,hostId:d,request:l,subscribeEvents:u,agents:fe,hostPlatform:ee,isNotificationListener:X&&G.has("notifications"),onViewRun:ke}),z?b.jsx(gO,{connected:s,hostId:d,request:l,subscribeEvents:u,taskId:x.taskId,runId:decodeURIComponent(x.runId)}):S?null:b.jsx(GE,{connected:s,hostId:d,request:l,subscribeEvents:u,agents:fe,hostPlatform:ee,filterTaskId:T,onClearFilter:()=>{ps()&&y(`/hosts/${encodeURIComponent(d)}`)}})]}):b.jsx("div",{className:"empty-state",children:b.jsx("p",{children:"Connecting to host..."})})}),D&&!F&&!B&&b.jsx("div",{className:"confirm-modal-overlay",children:b.jsxs("div",{className:"confirm-modal",children:[b.jsx("h2",{className:"confirm-modal-title",children:"Update Required"}),b.jsxs("p",{className:"confirm-modal-message",children:["Your Palmier host",W?` (v${W})`:""," is too old for this version of the app. Please update to continue."]}),b.jsx("div",{className:"confirm-modal-actions",children:b.jsx("button",{className:"btn btn-primary",onClick:Ge,children:"Update Now"})})]})}),F&&b.jsx("div",{className:"confirm-modal-overlay",children:b.jsxs("div",{className:"confirm-modal",children:[b.jsx("h2",{className:"confirm-modal-title",children:"Updating..."}),b.jsx("p",{className:"confirm-modal-message",children:"Installing update and restarting daemon. Please wait..."})]})}),B&&b.jsx("div",{className:"confirm-modal-overlay",children:b.jsxs("div",{className:"confirm-modal",children:[b.jsx("h2",{className:"confirm-modal-title",children:"Update Failed"}),b.jsx("p",{className:"confirm-modal-message",style:{whiteSpace:"pre-line"},children:B}),b.jsx("div",{className:"confirm-modal-actions",children:b.jsx("button",{className:"btn btn-secondary",onClick:()=>{L(null)},children:"Retry"})})]})})]}),ds.createPortal(b.jsxs(b.Fragment,{children:[[...ae.entries()].map(([ze,{description:Ae,sessionName:Le}])=>b.jsx("div",{className:"confirm-modal-overlay",children:b.jsxs("div",{className:"confirm-modal",children:[b.jsx("h2",{className:"confirm-modal-title",children:"Confirmation Required"}),Le&&b.jsx("p",{className:"confirm-modal-subtitle",children:Le}),b.jsx("p",{className:"confirm-modal-message",children:Ae}),b.jsxs("div",{className:"confirm-modal-actions",children:[b.jsx("button",{className:"btn btn-primary",onClick:()=>_e(ze,"confirmed"),children:"Confirm"}),b.jsx("button",{className:"btn btn-secondary",onClick:()=>_e(ze,"aborted"),children:"Abort"})]})]})},ze)),[...M.entries()].map(([ze,{permissions:Ae,sessionName:Le}])=>b.jsx("div",{className:"confirm-modal-overlay",children:b.jsxs("div",{className:"confirm-modal permission-modal",children:[b.jsx("h2",{className:"confirm-modal-title",children:"Permission Required"}),b.jsx("p",{className:"confirm-modal-message",children:b.jsx("strong",{children:Le||ze})}),b.jsx("div",{className:"permission-list",children:Ae.map((nt,Ve)=>b.jsxs("div",{className:"permission-item",children:[b.jsx("span",{className:"permission-name",children:nt.name}),nt.description&&b.jsx("span",{className:"permission-desc",children:nt.description})]},Ve))}),b.jsxs("div",{className:"permission-actions",children:[b.jsx("button",{className:"btn btn-primary",onClick:()=>Me(ze,"granted"),children:"Allow Once"}),b.jsx("button",{className:"btn btn-secondary",onClick:()=>Me(ze,"granted_all"),children:"Allow Always"})]}),b.jsx("button",{className:"permission-abort-link",onClick:()=>Me(ze,"aborted"),children:"Deny & Abort Task"})]})},ze)),[...K.entries()].map(([ze,{questions:Ae,description:Le,sessionName:nt}])=>{const Ve=be.get(ze)??new Array(Ae.length).fill("");return b.jsx("div",{className:"confirm-modal-overlay",children:b.jsxs("div",{className:"confirm-modal input-modal",children:[b.jsx("h2",{className:"confirm-modal-title",children:"Input Required"}),nt&&b.jsx("p",{className:"confirm-modal-subtitle",children:nt}),Le&&b.jsx("p",{className:"confirm-modal-message",children:Le}),b.jsx("div",{className:"input-list",children:Ae.map((Je,We)=>b.jsxs("div",{className:"input-item",children:[b.jsx("label",{className:"input-label",children:Je}),b.jsx("input",{type:"text",className:"input-field",value:Ve[We]??"",onChange:Fe=>{je(et=>{const ft=new Map(et),ht=[...ft.get(ze)??[]];return ht[We]=Fe.target.value,ft.set(ze,ht),ft})},autoFocus:We===0})]},We))}),b.jsx("div",{className:"input-actions",children:b.jsx("button",{className:"btn btn-primary",disabled:Ve.some(Je=>!Je.trim()),onClick:()=>Ie(ze,Ve),children:"Submit"})}),b.jsx("button",{className:"permission-abort-link",onClick:()=>Ie(ze,["aborted"]),children:"Cancel"})]})},ze)})]}),document.body)]})}const vO=ys("Preferences",{web:()=>qd(()=>import("./web-BxTN9Su1.js"),[]).then(e=>new e.PreferencesWeb)}),kl=!!window.__PALMIER_SERVE__&&(window.location.hostname==="localhost"||window.location.hostname==="127.0.0.1"),Hb=Xn.isNativePlatform();function wO(){const[e,t]=j.useState(""),[r,s]=j.useState(!0),[l,u]=j.useState(!1),[c,f]=j.useState(null),{addPairedHost:d}=qi(),m=Mr();async function y(){const g=e.trim().toUpperCase();if(!g){f("Enter a pairing code.");return}u(!0),f(null);try{let x;if(kl){const T=await fetch("/pair",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({code:g,label:navigator.userAgent})});if(!T.ok){const z=await T.json().catch(()=>({error:"Connection failed"}));throw new Error(z.error||`HTTP ${T.status}`)}x=await T.json()}else{const T=await fetch(`${Uu}/api/config`);if(!T.ok)throw new Error("Failed to fetch server config");const z=await T.json();if(!z.natsWsUrl)throw new Error("Server has no NATS WebSocket URL configured");const D=await Nx({servers:z.natsWsUrl,authenticator:wx(z.natsJwt,new TextEncoder().encode(z.natsNkeySeed))}),H=Nu(),F=`pair.${g}`,oe=await D.request(F,H.encode(JSON.stringify({label:navigator.userAgent})),{timeout:1e4});x=JSON.parse(H.decode(oe.data)),await D.close()}const w={hostId:x.hostId,clientToken:x.clientToken,directUrl:kl?window.location.origin:void 0,...x.hostName?{name:x.hostName}:{}};if(d(w),Xn.isNativePlatform()&&mn){await vO.set({key:"hostId",value:x.hostId});try{const{token:T}=await mn.getFcmToken();await fetch(`${Uu}/api/fcm/register`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({hostId:x.hostId,fcmToken:T})})}catch(T){console.warn("FCM token registration failed:",T)}}const S=`/hosts/${encodeURIComponent(x.hostId)}`;m(Hb&&r?`${S}/pair/setup`:S)}catch(x){const w=x instanceof Error?x.message:String(x);w.includes("timeout")||w.includes("TIMEOUT")||w.includes("503")||w.toLowerCase().includes("no responders")?f("Code not found or expired. Check the code and try again."):f(w)}finally{u(!1)}}return b.jsx("div",{className:"pair-page",children:b.jsxs("div",{className:"pair-card",children:[b.jsxs("div",{className:"pair-header",children:[b.jsx("h1",{className:"pair-title",children:kl?"Pair":"Pair with Host"}),b.jsx("p",{className:"pair-subtitle",children:kl?"Enter the pairing code shown in your terminal.":"Connect this device to a Palmier host"})]}),!kl&&b.jsxs("div",{className:"pair-instructions",children:[b.jsxs("div",{className:"pair-instruction-block",children:[b.jsx("h3",{className:"pair-instruction-heading",children:"Setting up a new host?"}),b.jsxs("ol",{className:"pair-steps",children:[b.jsxs("li",{children:["Install at least one agent CLI (e.g., ",b.jsx("a",{href:"https://www.palmier.me/agents",target:"_blank",rel:"noopener noreferrer",children:"Claude Code, Gemini CLI, Codex CLI"}),")"]}),b.jsxs("li",{children:["Install Palmier on your host machine.",b.jsx("span",{className:"pair-platform-label",children:"Linux / macOS:"}),b.jsx("code",{className:"pair-command",children:"curl -fsSL https://palmier.me/install.sh | bash"}),b.jsx("span",{className:"pair-platform-label",children:"Windows (PowerShell):"}),b.jsx("code",{className:"pair-command",children:"irm https://palmier.me/install.ps1 | iex"})]}),b.jsxs("li",{children:["Run the setup wizard:",b.jsx("code",{className:"pair-command",children:"palmier init"})]}),b.jsx("li",{children:"A pairing code will display automatically"})]})]}),b.jsx("div",{className:"pair-instruction-divider"}),b.jsxs("div",{className:"pair-instruction-block",children:[b.jsx("h3",{className:"pair-instruction-heading",children:"Pairing an existing host?"}),b.jsxs("ol",{className:"pair-steps",children:[b.jsxs("li",{children:["Run ",b.jsx("code",{children:"palmier pair"})," on the host machine"]}),b.jsx("li",{children:"Enter the 6-character code below"})]})]})]}),b.jsxs("div",{className:"pair-form",children:[b.jsxs("label",{className:"form-label",htmlFor:"pair-code",children:["Pairing code",b.jsx("input",{id:"pair-code",type:"text",maxLength:6,value:e,onChange:g=>t(g.target.value.toUpperCase()),placeholder:"A7K9M2",className:"form-input form-input-mono pair-code-input",autoFocus:!0,autoComplete:"off",disabled:l})]}),Hb&&b.jsxs("label",{className:"pair-checkbox",children:[b.jsx("input",{type:"checkbox",checked:r,onChange:g=>s(g.target.checked),disabled:l}),b.jsxs("span",{className:"pair-checkbox-text",children:[b.jsx("span",{className:"pair-checkbox-title",children:"Link the host to this device"}),b.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&&b.jsx("p",{className:"pair-error",children:c}),b.jsxs("button",{className:"btn btn-primary btn-full",onClick:y,disabled:l||!e.trim(),children:[l&&b.jsx("span",{className:"btn-spinner"}),l?"Pairing...":"Pair"]}),b.jsx("button",{className:"btn btn-secondary btn-full",onClick:()=>m("/"),disabled:l,children:"Cancel"}),b.jsxs("p",{className:"pair-consent",children:["By pairing, you agree to our"," ",b.jsx("a",{href:"https://www.palmier.me/terms",target:"_blank",rel:"noopener noreferrer",children:"Terms of Service"})," and"," ",b.jsx("a",{href:"https://www.palmier.me/privacy",target:"_blank",rel:"noopener noreferrer",children:"Privacy Policy"}),"."]})]})]})})}function SO(){const e=Mr(),{connected:t,request:r,activeHost:s}=si(),{setHostLanUrl:l,pairedHosts:u}=qi(),c=u.length<=1,[f,d]=j.useState("loading"),[m,y]=j.useState(null),[g,x]=j.useState(null);function w(){e(`/hosts/${encodeURIComponent(s.hostId)}`,{replace:!0})}j.useEffect(()=>{if(!t||f!=="loading")return;let H=!1;return r("host.info").catch(()=>({})).then(F=>{if(H)return;l(s.hostId,F.lan_url??void 0);const oe=F.linked_client_token??null;y(oe);const B=!!oe&&oe!==s.clientToken;d(B?"confirming":"linking")}),()=>{H=!0}},[t,f,s,r,l]),j.useEffect(()=>{if(f!=="linking")return;let H=!1;return(async()=>{try{if(mn){const{token:F}=await mn.getFcmToken();if(!F)throw new Error("Could not read FCM token");await r("device.link",{fcmToken:F})}if(H)return;c?d("wizard"):w()}catch(F){if(H)return;x(F instanceof Error?F.message:String(F)),d("linkError")}})(),()=>{H=!0}},[f]);function S(){d("linking")}function T(){w()}function z(){x(null),d("linking")}const D=f==="confirming"&&ds.createPortal(b.jsx("div",{className:"confirm-modal-overlay",onClick:T,children:b.jsxs("div",{className:"confirm-modal",onClick:H=>H.stopPropagation(),children:[b.jsx("h2",{className:"confirm-modal-title",children:"Link the host to this device?"}),b.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."}),b.jsxs("div",{className:"confirm-modal-actions",children:[b.jsx("button",{className:"btn btn-secondary",onClick:T,children:"Cancel"}),b.jsx("button",{className:"btn btn-primary",onClick:S,children:"Link"})]})]})}),document.body);if(f==="loading"||f==="confirming"||f==="linking"||f==="linkError"){const H=c,F=f==="loading"||f==="confirming"||f==="linking";return b.jsxs("div",{className:"pair-setup",children:[b.jsxs("div",{className:"pair-setup-inner",children:[H&&b.jsx("h1",{className:"pair-setup-title",children:"Device Capabilities"}),b.jsxs("div",{className:"pair-setup-loading",children:[F&&b.jsx("span",{className:"spinner spinner-lg"}),f==="loading"&&b.jsx("span",{children:"Connecting to host…"}),f==="confirming"&&b.jsx("span",{children:"Awaiting confirmation…"}),f==="linking"&&b.jsx("span",{children:"Linking device…"}),f==="linkError"&&b.jsxs(b.Fragment,{children:[b.jsx("p",{className:"pair-error",children:g}),b.jsx("button",{className:"btn btn-primary",onClick:z,children:"Retry"}),b.jsx("button",{className:"btn btn-secondary",onClick:w,children:"Skip linking"})]})]})]}),D]})}return b.jsx("div",{className:"pair-setup",children:b.jsxs("div",{className:"pair-setup-inner",children:[b.jsx("h1",{className:"pair-setup-title",children:"Device Capabilities"}),b.jsx("p",{className:"pair-setup-description",children:"Choose what the host can use this device for. You can change these later from the menu."}),b.jsx(Bx,{}),b.jsx("div",{className:"pair-setup-actions",children:b.jsx("button",{className:"btn btn-primary btn-full",onClick:w,children:"Finish"})})]})})}function _O(){const e=Mr();return j.useEffect(()=>{if(!mn)return;const t=mn.addListener("deepLink",({path:r})=>e(r));return()=>{t.then(r=>r.remove())}},[e]),null}function kO(){const{pairedHosts:e}=qi();return e.length===0?b.jsx(Ll,{to:"/pair",replace:!0}):b.jsx(Ll,{to:`/hosts/${encodeURIComponent(e[0].hostId)}`,replace:!0})}function EO(){const{hostId:e}=$u(),{pairedHosts:t}=qi(),r=t.find(s=>s.hostId===e)??null;return r?b.jsx(gE,{activeHost:r,children:b.jsxs(nx,{children:[b.jsx(br,{index:!0,element:b.jsx(xu,{})}),b.jsx(br,{path:"tasks",element:b.jsx(xu,{})}),b.jsx(br,{path:"runs/:taskId",element:b.jsx(xu,{})}),b.jsx(br,{path:"runs/:taskId/:runId",element:b.jsx(xu,{})}),b.jsx(br,{path:"pair/setup",element:b.jsx(SO,{})}),b.jsx(br,{path:"*",element:b.jsx(Ll,{to:".",replace:!0})})]})}):b.jsx(Ll,{to:"/",replace:!0})}function CO(){return b.jsxs(H_,{children:[b.jsx(_O,{}),b.jsxs(nx,{children:[b.jsx(br,{path:"/",element:b.jsx(kO,{})}),b.jsx(br,{path:"/pair",element:b.jsx(wO,{})}),b.jsx(br,{path:"/hosts/:hostId/*",element:b.jsx(EO,{})}),b.jsx(br,{path:"*",element:b.jsx(Ll,{to:"/",replace:!0})})]})]})}lS.createRoot(document.getElementById("root")).render(b.jsx(j.StrictMode,{children:b.jsx(A_,{children:b.jsx(CO,{})})}));export{Hd as W};
@@ -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-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}.agent-picker-label{font-size:.8125rem;color:var(--color-text-secondary);white-space:nowrap}.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;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 .agent-picker-label{font-size:.8rem;color:var(--color-text-secondary);white-space:nowrap}.agent-picker-section-inline .form-select{width:auto;min-width:0;font-size:.8rem;padding:4px 8px}.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{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}.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{opacity:1;text-decoration:underline}.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-actions{display:flex;gap:var(--space-sm)}.input-actions .btn{flex:1;padding:10px var(--space-md);font-size:.875rem}.host-picker-inline{border:1px solid var(--color-border);border-radius:var(--radius-md);overflow:hidden}.host-picker-list{max-height:240px;overflow-y:auto;padding:var(--space-xs) 0}.host-picker-item-wrapper{position:relative}.host-picker-item{display:flex;align-items:center;gap:8px;width:100%;padding:8px 12px;border:none;background:none;cursor:pointer;font-family:var(--font-sans);font-size:.8125rem;color:var(--color-text);text-align:left;transition:background var(--transition-fast);-webkit-tap-highlight-color:transparent}.host-picker-item:hover{background:var(--color-border-subtle)}.host-picker-item-active,.host-picker-item-active:hover{background:var(--color-primary-subtle)}.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:24px;height:24px;border:none;background:none;cursor:pointer;color:var(--color-muted);border-radius:4px;flex-shrink:0;transition:all var(--transition-fast)}.host-picker-edit-btn:hover{color:var(--color-primary);background:var(--color-primary-subtle)}.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:24px;height:24px;border:none;background:none;cursor:pointer;color:var(--color-muted);border-radius:4px;flex-shrink:0;transition:all var(--transition-fast)}.host-picker-delete-btn:hover{color:var(--color-error);background:var(--color-error-bg)}.hamburger-btn{display:flex;align-items:center;justify-content:center;width:40px;height:40px;padding:0;border:none;background:none;color:var(--color-text);cursor:pointer;border-radius:var(--radius-sm);transition:background var(--transition-fast)}.hamburger-btn:hover{background:var(--color-primary-subtle)}.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:280px;max-width:80vw;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}.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-label{font-size:.6875rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--color-muted);margin-bottom:var(--space-sm)}.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)}.drawer-version{font-size:.75rem;color:var(--color-muted)}.drawer-host-time{font-size:.75rem;color:var(--color-muted);margin-bottom:var(--space-xs)}.drawer-legal{font-size:.75rem;color:var(--color-muted);margin-top:var(--space-xs)}.drawer-legal a{color:var(--color-muted);text-decoration:none}.drawer-legal a:hover{text-decoration:underline}.drawer-legal-sep{margin:0 var(--space-xs)}.drawer-divider{height:1px;background:var(--color-border);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}.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-back{display:inline-flex;align-items:center;gap:var(--space-xs);border:none;background:none;cursor:pointer;padding:0;color:var(--color-text-secondary);font-size:.8125rem}.run-detail-back:hover{color:var(--color-text)}.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-agent{font-size:.6875rem;font-weight:500;color:var(--color-text-tertiary);margin-bottom:var(--space-xs)}.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-monitoring-indicator{display:flex;align-items:center;justify-content:center;gap:var(--space-xs);font-size:.6875rem;color:var(--color-muted);padding:var(--space-md) 0}.chat-monitoring-dot{width:6px;height:6px;border-radius:50%;background:var(--color-muted);animation:monitoring-pulse 1.5s ease-in-out infinite}@keyframes monitoring-pulse{0%,to{opacity:.3}50%{opacity:1}}.chat-abort-bar{display:flex;justify-content:center;padding:var(--space-sm) 0;flex-shrink:0}.chat-abort-btn{color:var(--color-error);border-color:var(--color-error)}.chat-abort-btn:hover:not(:disabled){background:var(--color-error-bg)}.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}.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-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-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}.agent-picker-label{font-size:.8125rem;color:var(--color-text-secondary);white-space:nowrap}.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;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 .agent-picker-label{font-size:.8rem;color:var(--color-text-secondary);white-space:nowrap}.agent-picker-section-inline .form-select{width:auto;min-width:0;font-size:.8rem;padding:4px 8px}.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{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}.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{opacity:1;text-decoration:underline}.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-actions{display:flex;gap:var(--space-sm)}.input-actions .btn{flex:1;padding:10px var(--space-md);font-size:.875rem}.host-picker-inline{border:1px solid var(--color-border);border-radius:var(--radius-md);overflow:hidden}.host-picker-list{max-height:240px;overflow-y:auto;padding:var(--space-xs) 0}.host-picker-item-wrapper{position:relative}.host-picker-item{display:flex;align-items:center;gap:8px;width:100%;padding:8px 12px;border:none;background:none;cursor:pointer;font-family:var(--font-sans);font-size:.8125rem;color:var(--color-text);text-align:left;transition:background var(--transition-fast);-webkit-tap-highlight-color:transparent}.host-picker-item:hover{background:var(--color-border-subtle)}.host-picker-item-active,.host-picker-item-active:hover{background:var(--color-primary-subtle)}.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:24px;height:24px;border:none;background:none;cursor:pointer;color:var(--color-muted);border-radius:4px;flex-shrink:0;transition:all var(--transition-fast)}.host-picker-edit-btn:hover{color:var(--color-primary);background:var(--color-primary-subtle)}.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:24px;height:24px;border:none;background:none;cursor:pointer;color:var(--color-muted);border-radius:4px;flex-shrink:0;transition:all var(--transition-fast)}.host-picker-delete-btn:hover{color:var(--color-error);background:var(--color-error-bg)}.hamburger-btn{display:flex;align-items:center;justify-content:center;width:40px;height:40px;padding:0;border:none;background:none;color:var(--color-text);cursor:pointer;border-radius:var(--radius-sm);transition:background var(--transition-fast)}.hamburger-btn:hover{background:var(--color-primary-subtle)}.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:280px;max-width:80vw;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}.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-label{font-size:.6875rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--color-muted);margin-bottom:var(--space-sm)}.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)}.drawer-version{font-size:.75rem;color:var(--color-muted)}.drawer-host-time{font-size:.75rem;color:var(--color-muted);margin-bottom:var(--space-xs)}.drawer-legal{font-size:.75rem;color:var(--color-muted);margin-top:var(--space-xs)}.drawer-legal a{color:var(--color-muted);text-decoration:none}.drawer-legal a:hover{text-decoration:underline}.drawer-legal-sep{margin:0 var(--space-xs)}.drawer-divider{height:1px;background:var(--color-border);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}.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-back{display:inline-flex;align-items:center;gap:var(--space-xs);border:none;background:none;cursor:pointer;padding:0;color:var(--color-text-secondary);font-size:.8125rem}.run-detail-back:hover{color:var(--color-text)}.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--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-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-monitoring-indicator{display:flex;align-items:center;justify-content:center;gap:var(--space-xs);font-size:.6875rem;color:var(--color-muted);padding:var(--space-md) 0}.chat-monitoring-dot{width:6px;height:6px;border-radius:50%;background:var(--color-muted);animation:monitoring-pulse 1.5s ease-in-out infinite}@keyframes monitoring-pulse{0%,to{opacity:.3}50%{opacity:1}}.chat-abort-bar{display:flex;justify-content:center;padding:var(--space-sm) 0;flex-shrink:0}.chat-abort-btn{color:var(--color-error);border-color:var(--color-error)}.chat-abort-btn:hover:not(:disabled){background:var(--color-error-bg)}.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}.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-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 +1 @@
1
- import{W as p}from"./index-dvjO6dHB.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
+ import{W as p}from"./index-Bb-_PDBL.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-dvjO6dHB.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};
1
+ import{W as t}from"./index-Bb-_PDBL.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};
@@ -1 +1 @@
1
- import{W as i}from"./index-dvjO6dHB.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
+ import{W as i}from"./index-Bb-_PDBL.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};
@@ -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-dvjO6dHB.js"></script>
12
- <link rel="stylesheet" crossorigin href="/assets/index-D1bIhEbd.css">
11
+ <script type="module" crossorigin src="/assets/index-Bb-_PDBL.js"></script>
12
+ <link rel="stylesheet" crossorigin href="/assets/index-C0lQMYcG.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>
@@ -107,6 +107,18 @@ async function generateName(projectRoot, userPrompt, agentName) {
107
107
  }
108
108
  /** Active follow-up child processes, keyed by "taskId:runId". */
109
109
  const activeFollowups = new Map();
110
+ /**
111
+ * The run process never started, so write a `started` + `failed` status pair
112
+ * directly to TASKRUN.md (run.ts normally does this) and notify clients.
113
+ */
114
+ async function recordStartFailure(taskDir, taskId, runId, detail, ctx) {
115
+ const now = Date.now();
116
+ appendRunMessage(taskDir, runId, { role: "status", time: now, content: "", type: "started" });
117
+ appendRunMessage(taskDir, runId, { role: "status", time: now, content: detail, type: "failed" });
118
+ if (ctx?.nc) {
119
+ await publishHostEvent(ctx.nc, ctx.hostId, taskId, { event_type: "result-updated", run_id: runId });
120
+ }
121
+ }
110
122
  export function createRpcHandler(config, nc) {
111
123
  function flattenTask(task) {
112
124
  const taskDir = getTaskDir(config.projectRoot, task.frontmatter.id);
@@ -265,28 +277,40 @@ export function createRpcHandler(config, nc) {
265
277
  appendHistory(config.projectRoot, { task_id: id, run_id: runId });
266
278
  const platform = getPlatform();
267
279
  platform.installTaskTimer(config, task);
268
- await platform.startTask(id);
280
+ try {
281
+ await platform.startTask(id);
282
+ }
283
+ catch (err) {
284
+ const e = err;
285
+ const detail = (e.stderr || e.message || String(err)).trim();
286
+ await recordStartFailure(taskDir, id, runId, detail, { nc, hostId: config.hostId });
287
+ return { error: `Failed to start task: ${detail}` };
288
+ }
269
289
  return { ok: true, task_id: id, run_id: runId };
270
290
  }
271
291
  case "task.run": {
272
292
  const params = request.params;
293
+ const runTaskDir = getTaskDir(config.projectRoot, params.id);
294
+ let taskRunId;
273
295
  try {
274
- const runTaskDir = getTaskDir(config.projectRoot, params.id);
275
296
  const platform = getPlatform();
276
297
  if (platform.isTaskRunning(params.id)) {
277
298
  console.log(`[task.run] Task ${params.id} is already running, killing stale process`);
278
299
  await platform.stopTask(params.id);
279
300
  }
280
301
  const runTask = parseTaskFile(runTaskDir);
281
- const taskRunId = createRunDir(runTaskDir, runTask.frontmatter.name, Date.now(), runTask.frontmatter.agent);
302
+ taskRunId = createRunDir(runTaskDir, runTask.frontmatter.name, Date.now(), runTask.frontmatter.agent);
282
303
  appendHistory(config.projectRoot, { task_id: params.id, run_id: taskRunId });
283
304
  await platform.startTask(params.id);
284
305
  return { ok: true, task_id: params.id, run_id: taskRunId };
285
306
  }
286
307
  catch (err) {
287
308
  const e = err;
288
- console.error(`task.run failed for ${params.id}: ${e.stderr || e.message}`);
289
- return { error: `Failed to start task: ${e.stderr || e.message}` };
309
+ const detail = (e.stderr || e.message || String(err)).trim();
310
+ console.error(`task.run failed for ${params.id}: ${detail}`);
311
+ if (taskRunId)
312
+ await recordStartFailure(runTaskDir, params.id, taskRunId, detail, { nc, hostId: config.hostId });
313
+ return { error: `Failed to start task: ${detail}` };
290
314
  }
291
315
  }
292
316
  case "task.followup": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "palmier",
3
- "version": "0.9.9",
3
+ "version": "0.9.10",
4
4
  "description": "Palmier host CLI - provisions, executes tasks, and serves NATS RPC",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Hongxu Cai",