palmier 0.6.1 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DISCLAIMER.md +2 -2
- package/dist/agents/agent-instructions.md +1 -1
- package/dist/agents/agent.d.ts +2 -0
- package/dist/agents/agent.js +21 -0
- package/dist/agents/aider.d.ts +9 -0
- package/dist/agents/aider.js +32 -0
- package/dist/agents/cursor.d.ts +9 -0
- package/dist/agents/cursor.js +35 -0
- package/dist/agents/deepagents.d.ts +9 -0
- package/dist/agents/deepagents.js +35 -0
- package/dist/agents/droid.d.ts +9 -0
- package/dist/agents/droid.js +32 -0
- package/dist/agents/goose.d.ts +9 -0
- package/dist/agents/goose.js +32 -0
- package/dist/agents/opencode.d.ts +9 -0
- package/dist/agents/opencode.js +35 -0
- package/dist/agents/openhands.d.ts +9 -0
- package/dist/agents/openhands.js +35 -0
- package/dist/commands/run.js +2 -2
- package/dist/pwa/assets/{index-C7Ib48wG.js → index-ByhOhTz1.js} +1 -1
- package/dist/pwa/index.html +2 -2
- package/dist/pwa/manifest.webmanifest +1 -1
- package/dist/pwa/service-worker.js +1 -1
- package/dist/rpc-handler.js +4 -3
- package/dist/transports/http-transport.js +3 -1
- package/package.json +1 -1
- package/palmier-server/pwa/index.html +1 -1
- package/palmier-server/pwa/src/constants.ts +1 -1
- package/palmier-server/pwa/src/service-worker.ts +3 -3
- package/palmier-server/pwa/vite.config.ts +1 -1
- package/palmier-server/server/src/index.ts +2 -0
- package/palmier-server/spec.md +1 -1
- package/src/agents/agent-instructions.md +1 -1
- package/src/agents/agent.ts +23 -0
- package/src/agents/aider.ts +37 -0
- package/src/agents/cursor.ts +38 -0
- package/src/agents/deepagents.ts +38 -0
- package/src/agents/droid.ts +37 -0
- package/src/agents/goose.ts +35 -0
- package/src/agents/opencode.ts +38 -0
- package/src/agents/openhands.ts +38 -0
- package/src/commands/run.ts +2 -2
- package/src/rpc-handler.ts +4 -3
- package/src/transports/http-transport.ts +3 -2
|
@@ -115,4 +115,4 @@ ${f.stack}`),c.reject(d)):c.resolve(y))}});return m.requestSubject=n,this.protoc
|
|
|
115
115
|
`,inConstruct:"tableCell"},{atBreak:!0,character:"|",after:"[ :-]"},{character:"|",inConstruct:"tableCell"},{atBreak:!0,character:":",after:"-"},{atBreak:!0,character:"-",after:"[:|-]"}],handlers:{inlineCode:x,table:c,tableCell:m,tableRow:f}};function c(v,C,D,q){return d(y(v,D,q),v.align)}function f(v,C,D,q){const M=g(v,D,q),G=d([M]);return G.slice(0,G.indexOf(`
|
|
116
116
|
`))}function m(v,C,D,q){const M=D.enter("tableCell"),G=D.enter("phrasing"),V=D.containerPhrasing(v,{...q,before:u,after:u});return G(),M(),V}function d(v,C){return ZT(v,{align:C,alignDelimiters:a,padding:r,stringLength:l})}function y(v,C,D){const q=v.children;let M=-1;const G=[],V=C.enter("table");for(;++M<q.length;)G[M]=g(q[M],C,D);return V(),G}function g(v,C,D){const q=v.children;let M=-1;const G=[],V=C.enter("tableRow");for(;++M<q.length;)G[M]=m(q[M],v,C,D);return V(),G}function x(v,C,D){let q=H1.inlineCode(v,C,D);return D.stack.includes("tableCell")&&(q=q.replace(/\|/g,"\\$&")),q}}function BO(){return{exit:{taskListCheckValueChecked:X0,taskListCheckValueUnchecked:X0,paragraph:HO}}}function qO(){return{unsafe:[{atBreak:!0,character:"-",after:"[:|-]"}],handlers:{listItem:PO}}}function X0(t){const n=this.stack[this.stack.length-2];n.type,n.checked=t.type==="taskListCheckValueChecked"}function HO(t){const n=this.stack[this.stack.length-2];if(n&&n.type==="listItem"&&typeof n.checked=="boolean"){const r=this.stack[this.stack.length-1];r.type;const a=r.children[0];if(a&&a.type==="text"){const l=n.children;let u=-1,c;for(;++u<l.length;){const f=l[u];if(f.type==="paragraph"){c=f;break}}c===r&&(a.value=a.value.slice(1),a.value.length===0?r.children.shift():r.position&&a.position&&typeof a.position.start.offset=="number"&&(a.position.start.column++,a.position.start.offset++,r.position.start=Object.assign({},a.position.start)))}}this.exit(t)}function PO(t,n,r,a){const l=t.children[0],u=typeof t.checked=="boolean"&&l&&l.type==="paragraph",c="["+(t.checked?"x":" ")+"] ",f=r.createTracker(a);u&&f.move(c);let m=H1.listItem(t,n,r,{...a,...f.current()});return u&&(m=m.replace(/^(?:[*+-]|\d+\.)([\r\n]| {1,3})/,d)),m;function d(y){return y+c}}function IO(){return[vT(),PT(),GT(),NO(),BO()]}function FO(t){return{extensions:[ST(),IT(t),YT(),UO(t),qO()]}}const $O={tokenize:QO,partial:!0},P1={tokenize:ZO,partial:!0},I1={tokenize:KO,partial:!0},F1={tokenize:WO,partial:!0},GO={tokenize:ej,partial:!0},$1={name:"wwwAutolink",tokenize:JO,previous:Y1},G1={name:"protocolAutolink",tokenize:XO,previous:V1},$r={name:"emailAutolink",tokenize:VO,previous:J1},xr={};function YO(){return{text:xr}}let Xi=48;for(;Xi<123;)xr[Xi]=$r,Xi++,Xi===58?Xi=65:Xi===91&&(Xi=97);xr[43]=$r;xr[45]=$r;xr[46]=$r;xr[95]=$r;xr[72]=[$r,G1];xr[104]=[$r,G1];xr[87]=[$r,$1];xr[119]=[$r,$1];function VO(t,n,r){const a=this;let l,u;return c;function c(g){return!ed(g)||!J1.call(a,a.previous)||zd(a.events)?r(g):(t.enter("literalAutolink"),t.enter("literalAutolinkEmail"),f(g))}function f(g){return ed(g)?(t.consume(g),f):g===64?(t.consume(g),m):r(g)}function m(g){return g===46?t.check(GO,y,d)(g):g===45||g===95||Kt(g)?(u=!0,t.consume(g),m):y(g)}function d(g){return t.consume(g),l=!0,m}function y(g){return u&&l&&sn(a.previous)?(t.exit("literalAutolinkEmail"),t.exit("literalAutolink"),n(g)):r(g)}}function JO(t,n,r){const a=this;return l;function l(c){return c!==87&&c!==119||!Y1.call(a,a.previous)||zd(a.events)?r(c):(t.enter("literalAutolink"),t.enter("literalAutolinkWww"),t.check($O,t.attempt(P1,t.attempt(I1,u),r),r)(c))}function u(c){return t.exit("literalAutolinkWww"),t.exit("literalAutolink"),n(c)}}function XO(t,n,r){const a=this;let l="",u=!1;return c;function c(g){return(g===72||g===104)&&V1.call(a,a.previous)&&!zd(a.events)?(t.enter("literalAutolink"),t.enter("literalAutolinkHttp"),l+=String.fromCodePoint(g),t.consume(g),f):r(g)}function f(g){if(sn(g)&&l.length<5)return l+=String.fromCodePoint(g),t.consume(g),f;if(g===58){const x=l.toLowerCase();if(x==="http"||x==="https")return t.consume(g),m}return r(g)}function m(g){return g===47?(t.consume(g),u?d:(u=!0,m)):r(g)}function d(g){return g===null||Su(g)||gt(g)||Wi(g)||Nu(g)?r(g):t.attempt(P1,t.attempt(I1,y),r)(g)}function y(g){return t.exit("literalAutolinkHttp"),t.exit("literalAutolink"),n(g)}}function QO(t,n,r){let a=0;return l;function l(c){return(c===87||c===119)&&a<3?(a++,t.consume(c),l):c===46&&a===3?(t.consume(c),u):r(c)}function u(c){return c===null?r(c):n(c)}}function ZO(t,n,r){let a,l,u;return c;function c(d){return d===46||d===95?t.check(F1,m,f)(d):d===null||gt(d)||Wi(d)||d!==45&&Nu(d)?m(d):(u=!0,t.consume(d),c)}function f(d){return d===95?a=!0:(l=a,a=void 0),t.consume(d),c}function m(d){return l||a||!u?r(d):n(d)}}function KO(t,n){let r=0,a=0;return l;function l(c){return c===40?(r++,t.consume(c),l):c===41&&a<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?t.check(F1,n,u)(c):c===null||gt(c)||Wi(c)?n(c):(t.consume(c),l)}function u(c){return c===41&&a++,t.consume(c),l}}function WO(t,n,r){return a;function a(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?(t.consume(f),a):f===38?(t.consume(f),u):f===93?(t.consume(f),l):f===60||f===null||gt(f)||Wi(f)?n(f):r(f)}function l(f){return f===null||f===40||f===91||gt(f)||Wi(f)?n(f):a(f)}function u(f){return sn(f)?c(f):r(f)}function c(f){return f===59?(t.consume(f),a):sn(f)?(t.consume(f),c):r(f)}}function ej(t,n,r){return a;function a(u){return t.consume(u),l}function l(u){return Kt(u)?r(u):n(u)}}function Y1(t){return t===null||t===40||t===42||t===95||t===91||t===93||t===126||gt(t)}function V1(t){return!sn(t)}function J1(t){return!(t===47||ed(t))}function ed(t){return t===43||t===45||t===46||t===95||Kt(t)}function zd(t){let n=t.length,r=!1;for(;n--;){const a=t[n][1];if((a.type==="labelLink"||a.type==="labelImage")&&!a._balanced){r=!0;break}if(a._gfmAutolinkLiteralWalkedInto){r=!1;break}}return t.length>0&&!r&&(t[t.length-1][1]._gfmAutolinkLiteralWalkedInto=!0),r}const tj={tokenize:uj,partial:!0};function nj(){return{document:{91:{name:"gfmFootnoteDefinition",tokenize:sj,continuation:{tokenize:lj},exit:oj}},text:{91:{name:"gfmFootnoteCall",tokenize:aj},93:{name:"gfmPotentialFootnoteCall",add:"after",tokenize:rj,resolveTo:ij}}}}function rj(t,n,r){const a=this;let l=a.events.length;const u=a.parser.gfmFootnotes||(a.parser.gfmFootnotes=[]);let c;for(;l--;){const m=a.events[l][1];if(m.type==="labelImage"){c=m;break}if(m.type==="gfmFootnoteCall"||m.type==="labelLink"||m.type==="label"||m.type==="image"||m.type==="link")break}return f;function f(m){if(!c||!c._balanced)return r(m);const d=sr(a.sliceSerialize({start:c.end,end:a.now()}));return d.codePointAt(0)!==94||!u.includes(d.slice(1))?r(m):(t.enter("gfmFootnoteCallLabelMarker"),t.consume(m),t.exit("gfmFootnoteCallLabelMarker"),n(m))}}function ij(t,n){let r=t.length;for(;r--;)if(t[r][1].type==="labelImage"&&t[r][0]==="enter"){t[r][1];break}t[r+1][1].type="data",t[r+3][1].type="gfmFootnoteCallLabelMarker";const a={type:"gfmFootnoteCall",start:Object.assign({},t[r+3][1].start),end:Object.assign({},t[t.length-1][1].end)},l={type:"gfmFootnoteCallMarker",start:Object.assign({},t[r+3][1].end),end:Object.assign({},t[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({},t[t.length-1][1].start)},c={type:"chunkString",contentType:"string",start:Object.assign({},u.start),end:Object.assign({},u.end)},f=[t[r+1],t[r+2],["enter",a,n],t[r+3],t[r+4],["enter",l,n],["exit",l,n],["enter",u,n],["enter",c,n],["exit",c,n],["exit",u,n],t[t.length-2],t[t.length-1],["exit",a,n]];return t.splice(r,t.length-r+1,...f),t}function aj(t,n,r){const a=this,l=a.parser.gfmFootnotes||(a.parser.gfmFootnotes=[]);let u=0,c;return f;function f(g){return t.enter("gfmFootnoteCall"),t.enter("gfmFootnoteCallLabelMarker"),t.consume(g),t.exit("gfmFootnoteCallLabelMarker"),m}function m(g){return g!==94?r(g):(t.enter("gfmFootnoteCallMarker"),t.consume(g),t.exit("gfmFootnoteCallMarker"),t.enter("gfmFootnoteCallString"),t.enter("chunkString").contentType="string",d)}function d(g){if(u>999||g===93&&!c||g===null||g===91||gt(g))return r(g);if(g===93){t.exit("chunkString");const x=t.exit("gfmFootnoteCallString");return l.includes(sr(a.sliceSerialize(x)))?(t.enter("gfmFootnoteCallLabelMarker"),t.consume(g),t.exit("gfmFootnoteCallLabelMarker"),t.exit("gfmFootnoteCall"),n):r(g)}return gt(g)||(c=!0),u++,t.consume(g),g===92?y:d}function y(g){return g===91||g===92||g===93?(t.consume(g),u++,d):d(g)}}function sj(t,n,r){const a=this,l=a.parser.gfmFootnotes||(a.parser.gfmFootnotes=[]);let u,c=0,f;return m;function m(C){return t.enter("gfmFootnoteDefinition")._container=!0,t.enter("gfmFootnoteDefinitionLabel"),t.enter("gfmFootnoteDefinitionLabelMarker"),t.consume(C),t.exit("gfmFootnoteDefinitionLabelMarker"),d}function d(C){return C===94?(t.enter("gfmFootnoteDefinitionMarker"),t.consume(C),t.exit("gfmFootnoteDefinitionMarker"),t.enter("gfmFootnoteDefinitionLabelString"),t.enter("chunkString").contentType="string",y):r(C)}function y(C){if(c>999||C===93&&!f||C===null||C===91||gt(C))return r(C);if(C===93){t.exit("chunkString");const D=t.exit("gfmFootnoteDefinitionLabelString");return u=sr(a.sliceSerialize(D)),t.enter("gfmFootnoteDefinitionLabelMarker"),t.consume(C),t.exit("gfmFootnoteDefinitionLabelMarker"),t.exit("gfmFootnoteDefinitionLabel"),x}return gt(C)||(f=!0),c++,t.consume(C),C===92?g:y}function g(C){return C===91||C===92||C===93?(t.consume(C),c++,y):y(C)}function x(C){return C===58?(t.enter("definitionMarker"),t.consume(C),t.exit("definitionMarker"),l.includes(u)||l.push(u),tt(t,v,"gfmFootnoteDefinitionWhitespace")):r(C)}function v(C){return n(C)}}function lj(t,n,r){return t.check(Rl,n,t.attempt(tj,n,r))}function oj(t){t.exit("gfmFootnoteDefinition")}function uj(t,n,r){const a=this;return tt(t,l,"gfmFootnoteDefinitionIndent",5);function l(u){const c=a.events[a.events.length-1];return c&&c[1].type==="gfmFootnoteDefinitionIndent"&&c[2].sliceSerialize(c[1],!0).length===4?n(u):r(u)}}function cj(t){let r=(t||{}).singleTilde;const a={name:"strikethrough",tokenize:u,resolveAll:l};return r==null&&(r=!0),{text:{126:a},insideSpan:{null:[a]},attentionMarkers:{null:[126]}};function l(c,f){let m=-1;for(;++m<c.length;)if(c[m][0]==="enter"&&c[m][1].type==="strikethroughSequenceTemporary"&&c[m][1]._close){let d=m;for(;d--;)if(c[d][0]==="exit"&&c[d][1].type==="strikethroughSequenceTemporary"&&c[d][1]._open&&c[m][1].end.offset-c[m][1].start.offset===c[d][1].end.offset-c[d][1].start.offset){c[m][1].type="strikethroughSequence",c[d][1].type="strikethroughSequence";const y={type:"strikethrough",start:Object.assign({},c[d][1].start),end:Object.assign({},c[m][1].end)},g={type:"strikethroughText",start:Object.assign({},c[d][1].end),end:Object.assign({},c[m][1].start)},x=[["enter",y,f],["enter",c[d][1],f],["exit",c[d][1],f],["enter",g,f]],v=f.parser.constructs.insideSpan.null;v&&jn(x,x.length,0,Ru(v,c.slice(d+1,m),f)),jn(x,x.length,0,[["exit",g,f],["enter",c[m][1],f],["exit",c[m][1],f],["exit",y,f]]),jn(c,d-1,m-d+3,x),m=d+x.length-2;break}}for(m=-1;++m<c.length;)c[m][1].type==="strikethroughSequenceTemporary"&&(c[m][1].type="data");return c}function u(c,f,m){const d=this.previous,y=this.events;let g=0;return x;function x(C){return d===126&&y[y.length-1][1].type!=="characterEscape"?m(C):(c.enter("strikethroughSequenceTemporary"),v(C))}function v(C){const D=ns(d);if(C===126)return g>1?m(C):(c.consume(C),g++,v);if(g<2&&!r)return m(C);const q=c.exit("strikethroughSequenceTemporary"),M=ns(C);return q._open=!M||M===2&&!!D,q._close=!D||D===2&&!!M,f(C)}}}class fj{constructor(){this.map=[]}add(n,r,a){hj(this,n,r,a)}consume(n){if(this.map.sort(function(u,c){return u[0]-c[0]}),this.map.length===0)return;let r=this.map.length;const a=[];for(;r>0;)r-=1,a.push(n.slice(this.map[r][0]+this.map[r][1]),this.map[r][2]),n.length=this.map[r][0];a.push(n.slice()),n.length=0;let l=a.pop();for(;l;){for(const u of l)n.push(u);l=a.pop()}this.map.length=0}}function hj(t,n,r,a){let l=0;if(!(r===0&&a.length===0)){for(;l<t.map.length;){if(t.map[l][0]===n){t.map[l][1]+=r,t.map[l][2].push(...a);return}l+=1}t.map.push([n,r,a])}}function dj(t,n){let r=!1;const a=[];for(;n<t.length;){const l=t[n];if(r){if(l[0]==="enter")l[1].type==="tableContent"&&a.push(t[n+1][1].type==="tableDelimiterMarker"?"left":"none");else if(l[1].type==="tableContent"){if(t[n-1][1].type==="tableDelimiterMarker"){const u=a.length-1;a[u]=a[u]==="left"?"center":"right"}}else if(l[1].type==="tableDelimiterRow")break}else l[0]==="enter"&&l[1].type==="tableDelimiterRow"&&(r=!0);n+=1}return a}function mj(){return{flow:{null:{name:"table",tokenize:pj,resolveAll:gj}}}}function pj(t,n,r){const a=this;let l=0,u=0,c;return f;function f(z){let ie=a.events.length-1;for(;ie>-1;){const he=a.events[ie][1].type;if(he==="lineEnding"||he==="linePrefix")ie--;else break}const K=ie>-1?a.events[ie][1].type:null,ge=K==="tableHead"||K==="tableRow"?O:m;return ge===O&&a.parser.lazy[a.now().line]?r(z):ge(z)}function m(z){return t.enter("tableHead"),t.enter("tableRow"),d(z)}function d(z){return z===124||(c=!0,u+=1),y(z)}function y(z){return z===null?r(z):Ue(z)?u>1?(u=0,a.interrupt=!0,t.exit("tableRow"),t.enter("lineEnding"),t.consume(z),t.exit("lineEnding"),v):r(z):Ze(z)?tt(t,y,"whitespace")(z):(u+=1,c&&(c=!1,l+=1),z===124?(t.enter("tableCellDivider"),t.consume(z),t.exit("tableCellDivider"),c=!0,y):(t.enter("data"),g(z)))}function g(z){return z===null||z===124||gt(z)?(t.exit("data"),y(z)):(t.consume(z),z===92?x:g)}function x(z){return z===92||z===124?(t.consume(z),g):g(z)}function v(z){return a.interrupt=!1,a.parser.lazy[a.now().line]?r(z):(t.enter("tableDelimiterRow"),c=!1,Ze(z)?tt(t,C,"linePrefix",a.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(z):C(z))}function C(z){return z===45||z===58?q(z):z===124?(c=!0,t.enter("tableCellDivider"),t.consume(z),t.exit("tableCellDivider"),D):j(z)}function D(z){return Ze(z)?tt(t,q,"whitespace")(z):q(z)}function q(z){return z===58?(u+=1,c=!0,t.enter("tableDelimiterMarker"),t.consume(z),t.exit("tableDelimiterMarker"),M):z===45?(u+=1,M(z)):z===null||Ue(z)?le(z):j(z)}function M(z){return z===45?(t.enter("tableDelimiterFiller"),G(z)):j(z)}function G(z){return z===45?(t.consume(z),G):z===58?(c=!0,t.exit("tableDelimiterFiller"),t.enter("tableDelimiterMarker"),t.consume(z),t.exit("tableDelimiterMarker"),V):(t.exit("tableDelimiterFiller"),V(z))}function V(z){return Ze(z)?tt(t,le,"whitespace")(z):le(z)}function le(z){return z===124?C(z):z===null||Ue(z)?!c||l!==u?j(z):(t.exit("tableDelimiterRow"),t.exit("tableHead"),n(z)):j(z)}function j(z){return r(z)}function O(z){return t.enter("tableRow"),J(z)}function J(z){return z===124?(t.enter("tableCellDivider"),t.consume(z),t.exit("tableCellDivider"),J):z===null||Ue(z)?(t.exit("tableRow"),n(z)):Ze(z)?tt(t,J,"whitespace")(z):(t.enter("data"),F(z))}function F(z){return z===null||z===124||gt(z)?(t.exit("data"),J(z)):(t.consume(z),z===92?X:F)}function X(z){return z===92||z===124?(t.consume(z),F):F(z)}}function gj(t,n){let r=-1,a=!0,l=0,u=[0,0,0,0],c=[0,0,0,0],f=!1,m=0,d,y,g;const x=new fj;for(;++r<t.length;){const v=t[r],C=v[1];v[0]==="enter"?C.type==="tableHead"?(f=!1,m!==0&&(Q0(x,n,m,d,y),y=void 0,m=0),d={type:"table",start:Object.assign({},C.start),end:Object.assign({},C.end)},x.add(r,0,[["enter",d,n]])):C.type==="tableRow"||C.type==="tableDelimiterRow"?(a=!0,g=void 0,u=[0,0,0,0],c=[0,r+1,0,0],f&&(f=!1,y={type:"tableBody",start:Object.assign({},C.start),end:Object.assign({},C.end)},x.add(r,0,[["enter",y,n]])),l=C.type==="tableDelimiterRow"?2:y?3:1):l&&(C.type==="data"||C.type==="tableDelimiterMarker"||C.type==="tableDelimiterFiller")?(a=!1,c[2]===0&&(u[1]!==0&&(c[0]=c[1],g=nu(x,n,u,l,void 0,g),u=[0,0,0,0]),c[2]=r)):C.type==="tableCellDivider"&&(a?a=!1:(u[1]!==0&&(c[0]=c[1],g=nu(x,n,u,l,void 0,g)),u=c,c=[u[1],r,0,0])):C.type==="tableHead"?(f=!0,m=r):C.type==="tableRow"||C.type==="tableDelimiterRow"?(m=r,u[1]!==0?(c[0]=c[1],g=nu(x,n,u,l,r,g)):c[1]!==0&&(g=nu(x,n,c,l,r,g)),l=0):l&&(C.type==="data"||C.type==="tableDelimiterMarker"||C.type==="tableDelimiterFiller")&&(c[3]=r)}for(m!==0&&Q0(x,n,m,d,y),x.consume(n.events),r=-1;++r<n.events.length;){const v=n.events[r];v[0]==="enter"&&v[1].type==="table"&&(v[1]._align=dj(n.events,r))}return t}function nu(t,n,r,a,l,u){const c=a===1?"tableHeader":a===2?"tableDelimiter":"tableData",f="tableContent";r[0]!==0&&(u.end=Object.assign({},$a(n.events,r[0])),t.add(r[0],0,[["exit",u,n]]));const m=$a(n.events,r[1]);if(u={type:c,start:Object.assign({},m),end:Object.assign({},m)},t.add(r[1],0,[["enter",u,n]]),r[2]!==0){const d=$a(n.events,r[2]),y=$a(n.events,r[3]),g={type:f,start:Object.assign({},d),end:Object.assign({},y)};if(t.add(r[2],0,[["enter",g,n]]),a!==2){const x=n.events[r[2]],v=n.events[r[3]];if(x[1].end=Object.assign({},v[1].end),x[1].type="chunkText",x[1].contentType="text",r[3]>r[2]+1){const C=r[2]+1,D=r[3]-r[2]-1;t.add(C,D,[])}}t.add(r[3]+1,0,[["exit",g,n]])}return l!==void 0&&(u.end=Object.assign({},$a(n.events,l)),t.add(l,0,[["exit",u,n]]),u=void 0),u}function Q0(t,n,r,a,l){const u=[],c=$a(n.events,r);l&&(l.end=Object.assign({},c),u.push(["exit",l,n])),a.end=Object.assign({},c),u.push(["exit",a,n]),t.add(r+1,0,u)}function $a(t,n){const r=t[n],a=r[0]==="enter"?"start":"end";return r[1][a]}const yj={name:"tasklistCheck",tokenize:xj};function bj(){return{text:{91:yj}}}function xj(t,n,r){const a=this;return l;function l(m){return a.previous!==null||!a._gfmTasklistFirstContentOfListItem?r(m):(t.enter("taskListCheck"),t.enter("taskListCheckMarker"),t.consume(m),t.exit("taskListCheckMarker"),u)}function u(m){return gt(m)?(t.enter("taskListCheckValueUnchecked"),t.consume(m),t.exit("taskListCheckValueUnchecked"),c):m===88||m===120?(t.enter("taskListCheckValueChecked"),t.consume(m),t.exit("taskListCheckValueChecked"),c):r(m)}function c(m){return m===93?(t.enter("taskListCheckMarker"),t.consume(m),t.exit("taskListCheckMarker"),t.exit("taskListCheck"),f):r(m)}function f(m){return Ue(m)?n(m):Ze(m)?t.check({tokenize:vj},n,r)(m):r(m)}}function vj(t,n,r){return tt(t,a,"whitespace");function a(l){return l===null?r(l):n(l)}}function Sj(t){return i1([YO(),nj(),cj(t),mj(),bj()])}const _j={};function td(t){const n=this,r=t||_j,a=n.data(),l=a.micromarkExtensions||(a.micromarkExtensions=[]),u=a.fromMarkdownExtensions||(a.fromMarkdownExtensions=[]),c=a.toMarkdownExtensions||(a.toMarkdownExtensions=[]);l.push(Sj(r)),u.push(IO()),c.push(FO(r))}function wj({body:t,permissions:n}){return S.jsxs("div",{className:"plan-dialog",children:[S.jsx("h2",{children:"Task Execution Plan"}),S.jsxs("div",{className:"plan-dialog-scroll",children:[t?S.jsx("div",{className:"plan-preview",children:S.jsx(Wh,{remarkPlugins:[td],children:t})}):S.jsx("p",{className:"plan-empty",children:"No execution plan generated for this task. Your task description will be used directly."}),n&&n.length>0&&S.jsxs("div",{className:"permissions-section",children:[S.jsx("h3",{children:"Granted Permissions"}),S.jsx("ul",{className:"permissions-list",children:n.map((r,a)=>S.jsxs("li",{className:"permission-item",children:[S.jsx("span",{className:"permission-tool",children:r.name}),S.jsx("span",{className:"permission-desc",children:r.description})]},a))})]})]}),S.jsx("div",{className:"plan-dialog-actions",children:S.jsx("button",{className:"btn btn-secondary",onClick:()=>history.back(),children:"Back"})})]})}const Ga=[];function Ej(){const t=Ga.pop();t&&(t.pushed.current=!1,t.close())}let Z0=!1;function kj(){Z0||(Z0=!0,window.addEventListener("popstate",Ej))}function Cj(t,n){const r=U.useRef(!1),a=U.useRef(n);a.current=n;const l=U.useCallback(()=>a.current(),[]),u=U.useRef({close:l,pushed:r});u.current.close=l,U.useEffect(()=>{if(t&&!r.current)kj(),history.pushState({modal:!0},""),Ga.push(u.current),r.current=!0;else if(!t&&r.current){r.current=!1;const c=Ga.indexOf(u.current);c!==-1&&Ga.splice(c,1),history.back()}},[t,l]),U.useEffect(()=>{const c=u.current;return()=>{if(r.current){r.current=!1;const f=Ga.indexOf(c);f!==-1&&Ga.splice(f,1),history.back()}}},[])}const Aj=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];function Qi(t="daily"){return{schedule:t,time:"00:00",dayOfWeek:"1",dayOfMonth:"1",onceDate:"",onceTime:"00:00"}}function Tj(t){const n=t.split(" ");if(n.length!==5)return Qi();const[r,a,l,,u]=n;if(a==="*")return Qi("hourly");const c=`${a.padStart(2,"0")}:${r.padStart(2,"0")}`;return u!=="*"?{...Qi("weekly"),time:c,dayOfWeek:u}:l!=="*"?{...Qi("monthly"),time:c,dayOfMonth:l}:{...Qi("daily"),time:c}}function Oj(t){if(t.type==="once"){const[n,r]=t.value.split("T");return{...Qi("once"),onceDate:n??"",onceTime:(r??"09:00").slice(0,5)}}return Tj(t.value)}function jj(t){const[n,r]=t.time.split(":").map(Number);switch(t.schedule){case"hourly":return"0 * * * *";case"daily":return`${r} ${n} * * *`;case"weekly":return`${r} ${n} * * ${t.dayOfWeek}`;case"monthly":return`${r} ${n} ${t.dayOfMonth} * *`;default:return"0 * * * *"}}function Nj(t){return t.schedule==="once"?t.onceDate?{type:"once",value:`${t.onceDate}T${t.onceTime}`}:null:{type:"cron",value:jj(t)}}function Rj({initial:t,agents:n,hostPlatform:r,onSaved:a,onRun:l,onCancel:u}){var Rn;const{request:c}=yd(),f=()=>{var He;const ve=localStorage.getItem("palmier:lastAgent"),Pe=n.map(_t=>_t.key);return ve&&Pe.includes(ve)?ve:((He=n[0])==null?void 0:He.key)??""},[m,d]=U.useState((t==null?void 0:t.user_prompt)??""),[y,g]=U.useState((t==null?void 0:t.agent)??f()),[x]=U.useState((t==null?void 0:t.body)??""),v=!!t&&m!==(t.user_prompt??""),C=!!t&&y!==(t.agent??""),D=v||C,q=!!t&&(!!x||!!((Rn=t.permissions)!=null&&Rn.length))&&!D,[M,G]=U.useState(!1),V=U.useCallback(()=>G(!1),[]);Cj(M,V);const[le,j]=U.useState(null),[O,J]=U.useState(()=>((t==null?void 0:t.triggers)??[]).map(Oj)),[F,X]=U.useState((t==null?void 0:t.triggers_enabled)??!1),[z,ie]=U.useState((t==null?void 0:t.requires_confirmation)??!1),[K,ge]=U.useState((t==null?void 0:t.yolo_mode)??!1),[he,I]=U.useState((t==null?void 0:t.foreground_mode)??!1),[H,te]=U.useState(null),me=H!==null,[Ae,N]=U.useState(!!(t!=null&&t.command)),[L,Y]=U.useState((t==null?void 0:t.command)??""),E=U.useRef(null),se=!!t,we=!se||m!==((t==null?void 0:t.user_prompt)??"")||y!==((t==null?void 0:t.agent)??"")||F!==((t==null?void 0:t.triggers_enabled)??!0)||z!==((t==null?void 0:t.requires_confirmation)??!1)||K!==((t==null?void 0:t.yolo_mode)??!1)||he!==((t==null?void 0:t.foreground_mode)??!1)||Ae!==!!(t!=null&&t.command)||Ae&&L!==((t==null?void 0:t.command)??"")||JSON.stringify(Le())!==JSON.stringify((t==null?void 0:t.triggers)??[]),xe=F&&O.some(ve=>ve.schedule==="once"&&(!ve.onceDate||new Date(`${ve.onceDate}T${ve.onceTime}`)<=new Date)),Oe=we&&!!m.trim()&&!xe&&(!Ae||!!L.trim());function ze(ve,Pe){J(He=>He.map((_t,Mn)=>Mn===ve?{..._t,...Pe}:_t))}function Ce(ve){J(Pe=>{const He=Pe.filter((_t,Mn)=>Mn!==ve);return He.length===0&&(X(!1),ie(!1)),He})}function Me(){J(ve=>[...ve,Qi(ve.length>0?ve[ve.length-1].schedule:void 0)])}function Le(){return O.flatMap(ve=>{const Pe=Nj(ve);return Pe?[Pe]:[]})}function Fe(){return K?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
117
|
|
|
118
|
-
Are you sure you want to continue?`):!0}async function gn(){te("save"),j(null);try{const ve=se?"task.update":"task.create",Pe={user_prompt:m,agent:y,triggers:Le(),triggers_enabled:F,requires_confirmation:z,yolo_mode:K,foreground_mode:he,command:Ae?L:""};se&&(Pe.id=t.id);const He=await c(ve,Pe,{timeout:13e4});return He.error?(j(He.error),null):(se||localStorage.setItem("palmier:lastAgent",y),a(He),He)}catch(ve){return j(ve instanceof Error?ve.message:String(ve)),null}finally{te(null)}}async function Xt(){te("run"),j(null);try{const Pe=await c("task.run_oneoff",{user_prompt:m,agent:y,requires_confirmation:z,yolo_mode:K,foreground_mode:he,command:Ae?L:""});if(Pe.error){j(Pe.error);return}localStorage.setItem("palmier:lastAgent",y),l(Pe.task_id,Pe.run_id),u()}catch(ve){j(ve instanceof Error?ve.message:String(ve))}finally{te(null)}}return S.jsx("div",{className:"task-form-overlay",children:S.jsx("div",{className:"task-form",children:M?S.jsx(wj,{body:x,permissions:t==null?void 0:t.permissions}):S.jsxs(S.Fragment,{children:[S.jsx("div",{className:"task-form-header",children:S.jsx("h2",{children:t?"Edit Task":"New Task"})}),le&&S.jsx("div",{className:"form-error",children:le}),S.jsx("textarea",{autoFocus:!t,className:"form-textarea",value:m,onChange:ve=>d(ve.target.value),placeholder:Ae?"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:me}),S.jsxs("div",{className:"plan-actions",children:[q&&S.jsx("button",{className:"btn btn-link",onClick:()=>G(!0),children:"Execution Plan"}),S.jsxs("div",{className:"agent-picker-section-inline",style:{marginLeft:"auto"},children:[S.jsx("span",{className:"agent-picker-label",children:"Run with"}),S.jsx("select",{className:"form-select form-select-sm",value:y,onChange:ve=>g(ve.target.value),children:n.map(ve=>S.jsx("option",{value:ve.key,children:ve.label},ve.key))})]})]}),S.jsxs("div",{className:"toggles-group",children:[S.jsxs("div",{className:`command-section${Ae?" command-section-active":""}`,children:[S.jsxs("label",{className:"toggle-label",children:[S.jsx("input",{type:"checkbox",checked:Ae,onChange:ve=>{N(ve.target.checked),ve.target.checked?setTimeout(()=>{var Pe;return(Pe=E.current)==null?void 0:Pe.focus()},0):Y("")},disabled:me}),"Reactive"]}),Ae&&S.jsxs(S.Fragment,{children:[S.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."}),S.jsx("input",{ref:E,className:"form-input form-input-mono",type:"text",value:L,onChange:ve=>Y(ve.target.value),placeholder:"gws gmail +watch --project my-project",disabled:me})]})]}),r==="win32"&&S.jsxs("label",{className:"toggle-label",children:[S.jsx("input",{type:"checkbox",checked:he,onChange:ve=>I(ve.target.checked),disabled:me}),"Run in the foreground (host must login to Windows)"]}),S.jsxs("label",{className:"toggle-label",children:[S.jsx("input",{type:"checkbox",checked:K,onChange:ve=>ge(ve.target.checked),disabled:me}),"Yolo mode"]}),K&&S.jsx("p",{className:"command-help-text",children:"The agent will auto-approve all tool calls without asking for permission."}),S.jsxs("div",{className:"triggers-section",children:[S.jsxs("label",{className:"toggle-label",children:[S.jsx("input",{type:"checkbox",checked:F,onChange:ve=>{ve.target.checked?(X(!0),O.length===0&&Me()):(X(!1),ie(!1),J(Pe=>{const He=Pe.filter(_t=>_t.schedule==="once"?_t.onceDate&&new Date(`${_t.onceDate}T${_t.onceTime}`)>new Date:!0);return He.length===1&&He[0].schedule==="daily"&&He[0].time==="00:00"?[]:He}))},disabled:me}),"Add schedules"]}),S.jsxs("div",{className:`triggers-section-body${F?"":" disabled"}`,children:[O.map((ve,Pe)=>S.jsxs("div",{className:"trigger-row-card",children:[S.jsxs("div",{className:"trigger-row-content",children:[S.jsxs("div",{className:"trigger-row-top",children:[S.jsxs("select",{className:"form-select",value:ve.schedule,disabled:!F,onChange:He=>ze(Pe,{schedule:He.target.value}),children:[S.jsx("option",{value:"once",children:"Specific Time"}),S.jsx("option",{value:"hourly",children:"Hourly"}),S.jsx("option",{value:"daily",children:"Daily"}),S.jsx("option",{value:"weekly",children:"Weekly"}),S.jsx("option",{value:"monthly",children:"Monthly"})]}),ve.schedule==="daily"&&S.jsx("input",{className:"form-input",type:"time",value:ve.time,disabled:!F,onChange:He=>ze(Pe,{time:He.target.value})}),ve.schedule==="weekly"&&S.jsxs(S.Fragment,{children:[S.jsx("select",{className:"form-select",value:ve.dayOfWeek,disabled:!F,onChange:He=>ze(Pe,{dayOfWeek:He.target.value}),children:Aj.map((He,_t)=>S.jsx("option",{value:String(_t),children:He},_t))}),S.jsx("input",{className:"form-input",type:"time",value:ve.time,disabled:!F,onChange:He=>ze(Pe,{time:He.target.value})})]})]}),ve.schedule==="monthly"&&S.jsxs("div",{className:"trigger-details",children:[S.jsx("select",{className:"form-select",value:ve.dayOfMonth,disabled:!F,onChange:He=>ze(Pe,{dayOfMonth:He.target.value}),children:Array.from({length:28},(He,_t)=>_t+1).map(He=>S.jsxs("option",{value:String(He),children:["Day ",He]},He))}),S.jsx("input",{className:"form-input",type:"time",value:ve.time,disabled:!F,onChange:He=>ze(Pe,{time:He.target.value})})]}),ve.schedule==="once"&&S.jsxs("div",{className:"trigger-details",children:[S.jsx("input",{className:"form-input",type:"date",value:ve.onceDate,min:new Date().toISOString().split("T")[0],disabled:!F,onChange:He=>ze(Pe,{onceDate:He.target.value})}),S.jsx("input",{className:"form-input",type:"time",value:ve.onceTime,min:ve.onceDate===new Date().toISOString().split("T")[0]?new Date().toTimeString().slice(0,5):void 0,disabled:!F,onChange:He=>ze(Pe,{onceTime:He.target.value})})]})]}),S.jsx("button",{className:"trigger-remove-btn",onClick:()=>Ce(Pe),disabled:!F,title:"Remove trigger",children:"×"})]},Pe)),O.length>0&&S.jsx("button",{className:"trigger-add-btn",onClick:Me,disabled:!F,children:"+ Add Schedule"})]})]}),F&&O.length>0&&S.jsxs("label",{className:"toggle-label",children:[S.jsx("input",{type:"checkbox",checked:z,onChange:ve=>ie(ve.target.checked),disabled:me}),"Confirm before each run"]})]}),!K&&(()=>{const ve=n.find(Pe=>Pe.key===y);return(ve==null?void 0:ve.supportsPermissions)===!1&&S.jsxs("div",{className:"form-warning",children:["Palmier does not support runtime permission granting for ",ve.label,". The task may fail if required permissions are not pre-configured."]})})(),S.jsxs("div",{className:"form-actions",children:[(()=>{const ve=O.length>0,Pe=!!m.trim()&&(!Ae||!!L.trim());return se?we?S.jsxs("button",{className:"btn btn-primary",onClick:()=>Fe()&&gn(),disabled:!Oe||me,children:[H==="save"&&S.jsx("span",{className:"btn-spinner"}),"Save"]}):S.jsx("button",{className:"btn btn-primary",disabled:!0,children:"Save"}):ve?S.jsxs("button",{className:"btn btn-primary",onClick:()=>Fe()&&gn(),disabled:!Oe||me,children:[H==="save"&&S.jsx("span",{className:"btn-spinner"}),"Schedule"]}):S.jsxs(S.Fragment,{children:[S.jsxs("button",{className:"btn btn-primary",onClick:()=>Fe()&&Xt(),disabled:!Pe||me,children:[H==="run"&&S.jsx("span",{className:"btn-spinner"}),"Run"]}),S.jsx("button",{className:"btn btn-secondary",onClick:()=>Fe()&&gn(),disabled:!Oe||me,children:"Save"})]})})(),S.jsx("button",{className:"btn btn-secondary",onClick:()=>{we&&m.trim()&&!confirm("You have unsaved changes. Discard?")||u()},style:{marginLeft:"auto"},children:"Cancel"})]})]})})})}const Mj="0.5.7";function Dj(t,n){if(t.includes("-"))return!1;const r=t.split(".").map(Number),a=n.split(".").map(Number);for(let l=0;l<3;l++){if((r[l]??0)<(a[l]??0))return!0;if((r[l]??0)>(a[l]??0))return!1}return!1}function zj({connected:t,hostId:n,request:r,subscribeEvents:a,onViewRun:l,onUpdateRequired:u,onVersion:c}){const[f,m]=U.useState([]),[d,y]=U.useState(!1),[g,x]=U.useState(null),[v,C]=U.useState(new Map),[D,q]=U.useState(new Set),[M,G]=U.useState(new Map),[V,le]=U.useState(new Map),[j,O]=U.useState(new Map),[J,F]=U.useState(!1),[X,z]=U.useState(void 0),[ie,K]=U.useState([]),[ge,he]=U.useState(),I=U.useCallback(()=>{F(!1),z(void 0)},[]),H=U.useCallback(async()=>{var Y,E;if(t){y(!0),x(null);try{const se=await r("task.list"),we=se.tasks??[],xe=new Map,Oe=new Set,ze=new Map,Ce=new Map,Me=new Map;for(const Fe of we)Fe.status&&(xe.set(Fe.id,Fe.status),Fe.status.pending_confirmation&&Oe.add(Fe.id),(Y=Fe.status.pending_permission)!=null&&Y.length&&ze.set(Fe.id,Fe.status.pending_permission),(E=Fe.status.pending_input)!=null&&E.length&&(Ce.set(Fe.id,Fe.status.pending_input),Me.set(Fe.id,new Array(Fe.status.pending_input.length).fill(""))));C(xe),q(Oe),G(ze),le(Ce),O(Me),m(we),K(se.agents??[]),he(se.host_platform),W2(se.agents??[]);const Le=se.version??null;c==null||c(Le),u==null||u(!!Le&&Dj(Le,Mj))}catch(se){const we=se instanceof Error?se.message:String(se);we==="Not connected"||we.includes("503")||we.toLowerCase().includes("no responders")?x(null):x(we),m([])}finally{y(!1)}}},[t,n,r]);U.useEffect(()=>{t?H():(m([]),y(!1))},[t,n,H]),U.useEffect(()=>{if(!t||!n)return;const Y={decode:se=>new TextDecoder().decode(se)};return a(n,async se=>{var ze,Ce;const we=se.subject.split(".");if(we.length<3)return;const xe=we.slice(2).join(".");let Oe;try{Oe=JSON.parse(Y.decode(se.data)).event_type}catch{return}if(Oe==="confirm-resolved"){q(Me=>{if(!Me.has(xe))return Me;const Le=new Set(Me);return Le.delete(xe),Le});return}if(Oe==="permission-resolved"){G(Me=>{if(!Me.has(xe))return Me;const Le=new Map(Me);return Le.delete(xe),Le});return}if(Oe==="input-resolved"){le(Me=>{if(!Me.has(xe))return Me;const Le=new Map(Me);return Le.delete(xe),Le}),O(Me=>{const Le=new Map(Me);return Le.delete(xe),Le});return}try{const Me=await r("task.status",{id:xe},{timeout:5e3});if(Me.error)return;C(Le=>{const Fe=new Map(Le);return Fe.set(xe,Me),Fe}),Me.pending_confirmation&&q(Le=>{if(Le.has(xe))return Le;const Fe=new Set(Le);return Fe.add(xe),Fe}),(ze=Me.pending_permission)!=null&&ze.length&&G(Le=>{if(Le.has(xe))return Le;const Fe=new Map(Le);return Fe.set(xe,Me.pending_permission),Fe}),(Ce=Me.pending_input)!=null&&Ce.length&&(le(Le=>{if(Le.has(xe))return Le;const Fe=new Map(Le);return Fe.set(xe,Me.pending_input),Fe}),O(Le=>{if(Le.has(xe))return Le;const Fe=new Map(Le);return Fe.set(xe,new Array(Me.pending_input.length).fill("")),Fe}))}catch{}})},[t,n,a,r]);async function te(Y,E){try{await r("task.user_input",{id:Y,value:[E]})}catch(se){console.error("[TaskListView] Failed to respond to confirmation:",se)}}async function me(Y,E){try{await r("task.user_input",{id:Y,value:[E]})}catch(se){console.error("[TaskListView] Failed to respond to permission request:",se)}}async function Ae(Y,E){try{await r("task.user_input",{id:Y,value:E})}catch(se){console.error("[TaskListView] Failed to respond to input request:",se)}}function N(Y){m(E=>{const se=E.findIndex(we=>we.id===Y.id);if(se>=0){const we=[...E];return we[se]=Y,we}return[Y,...E]}),F(!1),z(void 0)}function L(Y){m(E=>E.filter(se=>se.id!==Y)),C(E=>{const se=new Map(E);return se.delete(Y),se}),le(E=>{const se=new Map(E);return se.delete(Y),se}),O(E=>{const se=new Map(E);return se.delete(Y),se})}return S.jsxs(S.Fragment,{children:[g&&S.jsxs("div",{className:"form-error",children:[g,g.toLowerCase().includes("failed to fetch")&&S.jsxs(S.Fragment,{children:[" ",S.jsx("a",{href:"#",onClick:Y=>{Y.preventDefault(),window.location.reload()},children:"Reload"})]})]}),S.jsx("div",{className:"new-task-input-card",onClick:()=>{z(void 0),F(!0)},role:"button",tabIndex:0,onKeyDown:Y=>{(Y.key==="Enter"||Y.key===" ")&&(z(void 0),F(!0))},children:S.jsx("span",{className:"new-task-placeholder",children:"Describe your new task..."})}),d&&!f.length?S.jsx("div",{className:"task-list",children:[0,1,2].map(Y=>S.jsxs("div",{className:"task-card",style:{pointerEvents:"none"},children:[S.jsx("div",{className:"task-card-header",children:S.jsxs("div",{className:"task-card-title-row",children:[S.jsx("div",{className:"skeleton-line",style:{width:10,height:10,borderRadius:"50%"}}),S.jsx("div",{className:"skeleton-line",style:{width:`${60+Y*12}%`}})]})}),S.jsxs("div",{className:"task-card-meta",children:[S.jsx("div",{className:"skeleton-line",style:{width:"30%"}}),S.jsx("div",{className:"skeleton-line",style:{width:"25%"}})]})]},Y))}):S.jsx("div",{className:"task-list",children:f.map(Y=>S.jsx(tE,{task:Y,lastEvent:v.get(Y.id),onEdit:async E=>{try{const se=await r("task.get",{id:E.id});z(se.error?E:se)}catch{z(E)}F(!0)},onDelete:L,onViewRun:l},Y.id))}),J&&S.jsx(Rj,{initial:X,agents:ie,hostPlatform:ge,onSaved:N,onRun:l,onCancel:I}),cu.createPortal(S.jsxs(S.Fragment,{children:[[...D].map(Y=>{const E=f.find(se=>se.id===Y);return S.jsx("div",{className:"confirm-modal-overlay",children:S.jsxs("div",{className:"confirm-modal",children:[S.jsx("h2",{className:"confirm-modal-title",children:"Task Confirmation"}),S.jsxs("p",{className:"confirm-modal-message",children:['Run task "',S.jsx("strong",{children:(E==null?void 0:E.name)||(E==null?void 0:E.user_prompt)||Y}),'"?']}),S.jsxs("div",{className:"confirm-modal-actions",children:[S.jsx("button",{className:"btn btn-primary",onClick:()=>te(Y,"confirmed"),children:"Confirm"}),S.jsx("button",{className:"btn btn-secondary",onClick:()=>te(Y,"aborted"),children:"Abort"})]})]})},Y)}),[...M.entries()].map(([Y,E])=>{const se=f.find(we=>we.id===Y);return S.jsx("div",{className:"confirm-modal-overlay",children:S.jsxs("div",{className:"confirm-modal permission-modal",children:[S.jsx("h2",{className:"confirm-modal-title",children:"Permission Required"}),S.jsx("p",{className:"confirm-modal-message",children:S.jsx("strong",{children:(se==null?void 0:se.name)||(se==null?void 0:se.user_prompt)||Y})}),S.jsx("div",{className:"permission-list",children:E.map((we,xe)=>S.jsxs("div",{className:"permission-item",children:[S.jsx("span",{className:"permission-name",children:we.name}),we.description&&S.jsx("span",{className:"permission-desc",children:we.description})]},xe))}),S.jsxs("div",{className:"permission-actions",children:[S.jsx("button",{className:"btn btn-primary",onClick:()=>me(Y,"granted"),children:"Allow Once"}),S.jsx("button",{className:"btn btn-secondary",onClick:()=>me(Y,"granted_all"),children:"Allow Always"})]}),S.jsx("button",{className:"permission-abort-link",onClick:()=>me(Y,"aborted"),children:"Deny & Abort Task"})]})},Y)}),[...V.entries()].map(([Y,E])=>{const se=f.find(xe=>xe.id===Y),we=j.get(Y)??new Array(E.length).fill("");return S.jsx("div",{className:"confirm-modal-overlay",children:S.jsxs("div",{className:"confirm-modal input-modal",children:[S.jsx("h2",{className:"confirm-modal-title",children:"Input Required"}),S.jsx("p",{className:"confirm-modal-message",children:S.jsx("strong",{children:(se==null?void 0:se.name)||(se==null?void 0:se.user_prompt)||Y})}),S.jsx("div",{className:"input-list",children:E.map((xe,Oe)=>S.jsxs("div",{className:"input-item",children:[S.jsx("label",{className:"input-label",children:xe}),S.jsx("input",{type:"text",className:"input-field",value:we[Oe]??"",onChange:ze=>{O(Ce=>{const Me=new Map(Ce),Le=[...Me.get(Y)??[]];return Le[Oe]=ze.target.value,Me.set(Y,Le),Me})},autoFocus:Oe===0})]},Oe))}),S.jsx("div",{className:"input-actions",children:S.jsx("button",{className:"btn btn-primary",disabled:we.some(xe=>!xe.trim()),onClick:()=>Ae(Y,we),children:"Submit"})}),S.jsx("button",{className:"permission-abort-link",onClick:()=>Ae(Y,["aborted"]),children:"Cancel & Abort Task"})]})},Y)})]}),document.body)]})}function Lj(){const t=ea(),r=br().pathname.startsWith("/runs");return S.jsxs(S.Fragment,{children:[S.jsxs("button",{className:`tab-btn ${r?"":"tab-btn-active"}`,onClick:()=>t("/"),children:[S.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:[S.jsx("rect",{x:"2",y:"2",width:"12",height:"12",rx:"2"}),S.jsx("path",{d:"M5.5 8L7 9.5L10.5 6"})]}),"Tasks"]}),S.jsxs("button",{className:`tab-btn ${r?"tab-btn-active":""}`,onClick:()=>t("/runs"),children:[S.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:S.jsx("path",{d:"M2 8H4.5L6 4L8 12L10 6L11.5 8H14"})}),"Runs"]})]})}function X1(t){const[n,r]=U.useState(()=>window.matchMedia(t).matches);return U.useEffect(()=>{const a=window.matchMedia(t),l=u=>r(u.matches);return a.addEventListener("change",l),r(a.matches),()=>a.removeEventListener("change",l)},[t]),n}const K0=!!window.__PALMIER_SERVE__;function W0({daemonVersion:t}){var K;const{pairedHosts:n,activeHostId:r,setActiveHostId:a,removePairedHost:l,renamePairedHost:u}=Tl(),c=ea(),f=X1("(min-width: 768px)"),[m,d]=U.useState(!1),[y,g]=U.useState(!1),[x,v]=U.useState(null),[C,D]=U.useState(""),[q,M]=U.useState(null),G=U.useRef(null),V=U.useRef(null),le=U.useCallback(()=>{g(!0)},[]);function j(){y&&(d(!1),g(!1))}function O(){g(!1),d(!0)}function J(ge,he){v(ge),D(he)}function F(){x&&C.trim()&&u(x,C.trim()),v(null),D("")}function X(){v(null),D("")}U.useEffect(()=>{x&&V.current&&(V.current.focus(),V.current.select())},[x]),U.useEffect(()=>{if(!m||y)return;function ge(he){he.key==="Escape"&&le()}return document.addEventListener("keydown",ge),()=>{document.removeEventListener("keydown",ge)}},[m,y,le]);const z=S.jsxs(S.Fragment,{children:[S.jsxs("div",{className:"drawer-header",children:[S.jsx("span",{className:"drawer-title",children:"Palmier"}),!f&&S.jsx("button",{className:"drawer-close-btn",onClick:le,"aria-label":"Close menu",children:S.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",children:S.jsx("path",{d:"M4 4L12 12M12 4L4 12",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})})})]}),!K0&&n.length>0&&S.jsxs("div",{className:"drawer-section",children:[S.jsx("h3",{className:"drawer-section-label",children:"Hosts"}),S.jsx("div",{className:"host-picker-inline",children:S.jsx("div",{className:"host-picker-list",role:"listbox",children:n.map(ge=>{const he=ge.hostId===r,I=x===ge.hostId,H=ge.name||ge.hostId.slice(0,8);return S.jsx("div",{className:"host-picker-item-wrapper",children:S.jsxs("div",{className:`host-picker-item ${he?"host-picker-item-active":""}`,onClick:()=>{I||he||(a(ge.hostId),f||le())},role:"option","aria-selected":he,children:[I?S.jsx("input",{ref:V,className:"form-input host-picker-rename-input",type:"text",value:C,onChange:te=>D(te.target.value),onKeyDown:te=>{te.key==="Enter"&&F(),te.key==="Escape"&&X()},onBlur:F,onClick:te=>te.stopPropagation()}):S.jsx("span",{className:"host-picker-item-name",children:H}),S.jsxs("div",{className:"host-picker-item-actions",children:[he&&!I&&S.jsx("button",{className:"host-picker-edit-btn",onClick:te=>{te.stopPropagation(),J(ge.hostId,H)},"aria-label":"Rename host",children:S.jsx("svg",{width:"13",height:"13",viewBox:"0 0 13 13",fill:"none",children:S.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"})})}),!he&&S.jsx("button",{className:"host-picker-delete-btn",onClick:te=>{te.stopPropagation(),M(ge.hostId)},"aria-label":`Unpair ${H}`,children:S.jsx("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",children:S.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"})})})]})]})},ge.hostId)})})})]}),!K0&&S.jsxs(S.Fragment,{children:[S.jsx("div",{className:"drawer-divider"}),S.jsx("div",{className:"drawer-section",children:S.jsx("button",{className:"btn btn-primary btn-full",onClick:()=>{c("/pair"),f||le()},children:"Pair New Host"})})]}),S.jsxs("div",{className:"drawer-footer",children:[t&&S.jsxs("div",{className:"drawer-version",children:["Palmier v",t]}),S.jsxs("div",{className:"drawer-legal",children:[S.jsx("a",{href:"https://www.palmier.me/terms",target:"_blank",rel:"noopener noreferrer",children:"Terms"}),S.jsx("span",{className:"drawer-legal-sep",children:"·"}),S.jsx("a",{href:"https://www.palmier.me/privacy",target:"_blank",rel:"noopener noreferrer",children:"Privacy"})]})]})]}),ie=q&&cu.createPortal(S.jsx("div",{className:"confirm-modal-overlay",onClick:()=>M(null),children:S.jsxs("div",{className:"confirm-modal",onClick:ge=>ge.stopPropagation(),children:[S.jsx("h2",{className:"confirm-modal-title",children:"Delete host?"}),S.jsxs("p",{className:"confirm-modal-message",children:['"',((K=n.find(ge=>ge.hostId===q))==null?void 0:K.name)||q.slice(0,8),'" will be unpaired from this device.']}),S.jsxs("div",{className:"confirm-modal-actions",children:[S.jsx("button",{className:"btn btn-secondary",onClick:()=>M(null),children:"Cancel"}),S.jsx("button",{className:"btn btn-danger",onClick:()=>{l(q),M(null)},children:"Delete"})]})]})}),document.body);return f?S.jsxs(S.Fragment,{children:[S.jsx("div",{className:"drawer-panel drawer-panel-desktop",ref:G,children:z}),ie]}):S.jsxs(S.Fragment,{children:[S.jsx("button",{className:"hamburger-btn",onClick:O,"aria-label":"Open menu",children:S.jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"none",children:S.jsx("path",{d:"M3 5H17M3 10H17M3 15H17",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})})}),m&&cu.createPortal(S.jsx("div",{className:`drawer-overlay ${y?"drawer-overlay-closing":""}`,onClick:le,onAnimationEnd:j,children:S.jsx("div",{className:`drawer-panel ${y?"drawer-panel-closing":""}`,ref:G,onClick:ge=>ge.stopPropagation(),children:z})}),document.body),ie]})}const Uj=10;function Bj({connected:t,hostId:n,request:r,subscribeEvents:a,filterTaskId:l,onClearFilter:u}){const[c,f]=U.useState([]),[m,d]=U.useState(0),[y,g]=U.useState(!1),[x,v]=U.useState(!1),C=ea(),D=U.useRef(null),q=U.useCallback(j=>{const O={offset:j,limit:Uj};return l&&(O.task_id=l),O},[l]),M=U.useCallback(async(j,O)=>{if(t){O?v(!0):g(!0);try{const J=await r("taskrun.list",q(j)),F=J.entries??[];d(J.total??0),f(O?X=>{const z=new Set(X.map(K=>`${K.task_id}:${K.run_id}`)),ie=F.filter(K=>!z.has(`${K.task_id}:${K.run_id}`));return[...X,...ie]}:F)}catch(J){J instanceof Error&&J.message==="Not connected"||console.error("Failed to load runs:",J)}finally{g(!1),v(!1)}}},[t,r,q]);U.useEffect(()=>{t?(f([]),d(0),M(0,!1)):(f([]),d(0))},[t,n,M,l]),U.useEffect(()=>!t||!n?void 0:a(n,async O=>{try{const J=JSON.parse(new TextDecoder().decode(O.data));if(J.event_type==="running-state"&&J.running_state&&["monitoring","started","finished","failed","aborted"].includes(J.running_state)){const F=await r("taskrun.list",q(0)),X=F.entries??[];d(F.total??0),f(z=>{const ie=new Map(X.map(I=>[`${I.task_id}:${I.run_id}`,I])),K=z.map(I=>{const H=`${I.task_id}:${I.run_id}`;return ie.get(H)??I}),ge=new Set(K.map(I=>`${I.task_id}:${I.run_id}`));return[...X.filter(I=>!ge.has(`${I.task_id}:${I.run_id}`)),...K]})}}catch{}}),[t,n,a,r]),U.useEffect(()=>{const j=D.current;if(!j)return;const O=new IntersectionObserver(J=>{J[0].isIntersecting&&!x&&c.length<m&&M(c.length,!0)},{threshold:.1});return O.observe(j),()=>O.disconnect()},[c.length,m,x,M]);function G(j,O){if(!j||!O)return"";const J=Math.round((O-j)/1e3);if(J<60)return`${J}s`;const F=Math.floor(J/60),X=J%60;return`${F}m ${X}s`}const V={monitoring:"Monitoring",started:"Running",finished:"Finished",failed:"Failed",aborted:"Aborted"};function le(j){if(j==="failed")return"var(--color-error)";if(j==="aborted")return"var(--color-warning, #d97706)"}return y&&c.length===0&&t?S.jsx("div",{className:"task-list",children:[0,1,2].map(j=>S.jsxs("div",{className:"task-card",style:{pointerEvents:"none"},children:[S.jsx("div",{className:"task-card-header",children:S.jsx("div",{className:"task-card-title-row",children:S.jsx("div",{className:"skeleton-line",style:{width:`${70+j*10}%`}})})}),S.jsx("div",{className:"task-card-meta",children:S.jsx("div",{className:"skeleton-line",style:{width:"45%"}})})]},j))}):!t||y&&c.length===0?S.jsx("div",{className:"runs-view",children:S.jsxs("div",{className:"empty-state",children:[S.jsx("p",{className:"empty-state-text",children:"Runs"}),S.jsx("p",{className:"empty-state-hint",children:"Run history will appear here"})]})}):c.length===0?S.jsxs(S.Fragment,{children:[l&&u&&S.jsx("div",{style:{marginBottom:"var(--space-sm)"},children:S.jsxs("span",{className:"runs-filter-chip",children:["Filtered by task",S.jsx("button",{onClick:u,"aria-label":"Clear filter",children:"×"})]})}),S.jsx("div",{className:"runs-view",children:S.jsxs("div",{className:"empty-state",children:[S.jsx("p",{className:"empty-state-text",children:"No runs yet"}),S.jsx("p",{className:"empty-state-hint",children:l?"This task hasn't been executed yet. Run it from the task menu or wait for its next trigger.":"Run history will appear here."})]})})]}):S.jsxs(S.Fragment,{children:[l&&u&&S.jsx("div",{style:{marginBottom:"var(--space-sm)"},children:S.jsxs("span",{className:"runs-filter-chip",children:["Filtered by task",S.jsx("button",{onClick:u,"aria-label":"Clear filter",children:"×"})]})}),S.jsxs("div",{className:"task-list",children:[c.map((j,O)=>S.jsxs("div",{className:"runs-card",onClick:()=>!j.error&&C(`/runs/${j.task_id}/${encodeURIComponent(j.run_id)}`),children:[S.jsxs("div",{className:"runs-card-body",children:[S.jsx("h3",{className:"runs-card-name",children:j.task_name||j.task_id}),S.jsxs("div",{className:"runs-card-meta",children:[S.jsx("span",{style:{color:le(j.running_state)},children:V[j.running_state??""]??j.running_state}),j.end_time&&S.jsx("span",{children:vu(j.end_time)}),j.start_time&&j.end_time&&S.jsx("span",{style:{color:"var(--color-muted)"},children:G(j.start_time,j.end_time)}),j.error&&S.jsx("span",{style:{color:"var(--color-muted)"},children:j.error})]})]}),S.jsx("span",{className:"runs-card-chevron",children:"›"})]},`${j.task_id}-${j.run_id}-${O}`)),S.jsx("div",{ref:D,style:{height:1}}),x&&S.jsx("div",{className:"loading-state",style:{padding:"var(--space-md)"},children:S.jsx("div",{className:"spinner"})})]})]})}function qj(t){k1(t,[/\r?\n|\r/g,Hj])}function Hj(){return{type:"break"}}function eb(){return function(t){qj(t)}}function Pj({connected:t,hostId:n,request:r,subscribeEvents:a,taskId:l,runId:u}){const c=ea(),[f,m]=U.useState(!0),[d,y]=U.useState([]),[g,x]=U.useState(),[v,C]=U.useState(),D=g==="started"||g==="monitoring",q=g==="followup",M=g==="started"||g==="followup",[G,V]=U.useState(null),[le,j]=U.useState(!1),[O,J]=U.useState(""),[F,X]=U.useState(!1),z=U.useRef(null);async function ie(){try{const I=await r("task.result",{id:l,run_id:u});if(I.error){console.error("No result:",I.error),c("/runs",{replace:!0});return}y(I.messages??[]),x(I.running_state),C(I.agent)}catch(I){console.error("Failed to load result:",I),c("/runs",{replace:!0})}finally{m(!1)}}async function K(I){var H;try{const me=(H=(await r("task.reports",{id:l,run_id:u,report_files:[I]})).reports)==null?void 0:H[0];me!=null&&me.data_url?V({file:I,data_url:me.data_url}):V({file:I,content:(me==null?void 0:me.content)??"Report not found."})}catch{V({file:I,content:"Failed to load report."})}}U.useEffect(()=>{t&&(m(!0),ie())},[t,l,u]),U.useEffect(()=>!t||!n?void 0:a(n,async H=>{try{const te=JSON.parse(new TextDecoder().decode(H.data));if(te.event_type!=="running-state"&&te.event_type!=="result-updated"||H.subject.split(".").pop()!==l||te.event_type==="result-updated"&&te.run_id&&te.run_id!==u)return;ie()}catch{}}),[t,n,l,a,r]),U.useEffect(()=>{z.current&&(z.current.scrollTop=z.current.scrollHeight)},[d]);function ge(I){if(I==="input")return"User Input";if(I==="permission")return"Permission";if(I==="confirmation")return"Confirmation"}function he(I){return I==="started"?"Task started":I==="finished"?"Task finished":I==="failed"?"Task failed":I==="aborted"?"Task aborted":I==="confirmation"?"Task confirmed":I==="stopped"?"Follow-up stopped":I??""}return S.jsxs("div",{className:"run-detail",children:[S.jsxs("button",{className:"run-detail-back",onClick:()=>c(-1),children:[S.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:S.jsx("path",{d:"M15 18l-6-6 6-6"})}),"Back"]}),f?S.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"var(--space-sm)",padding:"var(--space-sm) 0"},children:[S.jsx("div",{className:"skeleton-line",style:{width:"40%"}}),S.jsx("div",{className:"skeleton-line",style:{width:"55%"}}),S.jsx("div",{className:"skeleton-line",style:{width:"100%",height:"8rem",marginTop:"var(--space-sm)"}})]}):S.jsxs(S.Fragment,{children:[S.jsxs("div",{className:"chat-thread",ref:z,children:[d.map((I,H)=>{const te=M&&I.role==="assistant"&&!d.slice(H+1).some(me=>me.role==="assistant"||me.role==="user");return I.role==="status"&&I.type==="monitoring"?null:I.role==="status"?S.jsxs("div",{className:"chat-status",children:[he(I.type),I.time>0&&S.jsx("span",{className:"chat-status-time",children:vu(I.time)})]},H):S.jsxs("div",{className:`chat-message chat-message--${I.role}`,children:[I.role==="assistant"&&v&&S.jsx("div",{className:"chat-message-agent",children:Ih(v)}),S.jsxs("div",{className:"chat-message-content",children:[S.jsx(Wh,{remarkPlugins:[td,eb],children:I.content}),te&&S.jsxs("div",{className:"chat-typing-indicator",children:[S.jsx("span",{}),S.jsx("span",{}),S.jsx("span",{})]})]}),I.attachments&&I.attachments.length>0&&S.jsx("div",{className:"chat-message-attachments",children:I.attachments.map(me=>S.jsx("button",{className:"chat-attachment-chip",onClick:()=>K(me),children:me},me))}),S.jsxs("div",{className:"chat-message-meta",children:[ge(I.type)&&S.jsx("span",{className:"chat-message-type",children:ge(I.type)}),I.time>0&&S.jsx("span",{children:vu(I.time)})]})]},H)}),M&&(()=>{const I=d.filter(H=>H.role!=="status");return I.length===0||I[I.length-1].role!=="assistant"})()&&S.jsxs("div",{className:"chat-message chat-message--assistant",children:[v&&S.jsx("div",{className:"chat-message-agent",children:Ih(v)}),S.jsxs("div",{className:"chat-typing-indicator",children:[S.jsx("span",{}),S.jsx("span",{}),S.jsx("span",{})]})]}),g==="monitoring"&&S.jsxs("div",{className:"chat-monitoring-indicator",children:[S.jsx("span",{className:"chat-monitoring-dot"}),"Monitoring command output"]})]}),D?S.jsx("div",{className:"chat-abort-bar",children:S.jsx("button",{className:"btn btn-secondary chat-abort-btn",disabled:le,onClick:async()=>{if(confirm("Abort this task?")){j(!0);try{await r("task.abort",{id:l})}catch(I){console.error("Abort failed:",I)}finally{j(!1)}}},children:le?"Aborting...":"Abort Task"})}):q?S.jsx("div",{className:"chat-input-bar",children:S.jsx("button",{className:"btn btn-secondary chat-stop-btn",disabled:le,onClick:async()=>{j(!0);try{await r("task.stop_followup",{id:l,run_id:u})}catch(I){console.error("Stop failed:",I)}finally{j(!1)}},children:S.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"currentColor",children:S.jsx("rect",{x:"6",y:"6",width:"12",height:"12",rx:"2"})})})}):S.jsxs("form",{className:"chat-input-bar",onSubmit:async I=>{I.preventDefault();const H=O.trim();if(!(!H||F)){X(!0);try{await r("task.followup",{id:l,run_id:u,message:H}),J("")}catch(te){console.error("Follow-up failed:",te)}finally{X(!1)}}},children:[S.jsx("input",{className:"chat-input",type:"text",placeholder:"Follow-up message",value:O,onChange:I=>J(I.target.value),disabled:F}),S.jsx("button",{className:"btn btn-primary chat-send-btn",type:"submit",disabled:!O.trim()||F,children:S.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[S.jsx("line",{x1:"22",y1:"2",x2:"11",y2:"13"}),S.jsx("polygon",{points:"22 2 15 22 11 13 2 9 22 2"})]})})]})]}),G&&S.jsx("div",{className:"report-dialog-overlay",onClick:()=>V(null),children:S.jsxs("div",{className:"report-dialog",onClick:I=>I.stopPropagation(),children:[S.jsxs("div",{className:"report-dialog-header",children:[S.jsx("span",{className:"report-dialog-title",children:G.file}),S.jsx("button",{className:"report-dialog-close",onClick:()=>V(null),"aria-label":"Close",children:S.jsxs("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[S.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),S.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})})]}),S.jsx("div",{className:"report-dialog-body",children:G.data_url?S.jsx("img",{src:G.data_url,alt:G.file,style:{maxWidth:"100%",height:"auto"}}):S.jsx(Wh,{remarkPlugins:[td,eb],components:{a:({...I})=>S.jsx("a",{...I,target:"_blank",rel:"noopener noreferrer"})},children:G.content??""})})]})})]})}async function Q1(t,n,r,a){console.log(`[API] ${t} ${n}`);const u=await fetch(n,{method:t,headers:{"Content-Type":"application/json"},body:r!=null?JSON.stringify(r):void 0});if(!u.ok){const c=await u.text();let f;try{const m=JSON.parse(c);f=m.error??m.message??c}catch{f=c}throw console.error(`[API] ${t} ${n} failed:`,u.status,f),new Error(f||`Request failed with status ${u.status}`)}return console.log(`[API] ${t} ${n} ->`,u.status),u.json()}function Ij(t,n,r){return Q1("POST",t,n)}function Fj(t,n){return Q1("GET",t,void 0)}function $j(){const{getActiveHost:t}=Tl(),n=t(),r=U.useRef(null);U.useEffect(()=>{if(!n||n.directUrl||r.current===n.hostId)return;async function a(){var l;try{if(!("serviceWorker"in navigator)||!("PushManager"in window)){console.warn("[Push] Push notifications not supported");return}const u=await navigator.serviceWorker.ready;(l=u.active)==null||l.postMessage({type:"set-host-id",hostId:n.hostId});let c=await u.pushManager.getSubscription();if(!c){const{publicKey:m}=await Fj("/api/push/vapid-key");if(!m){console.warn("[Push] No VAPID public key configured on server");return}if(await Notification.requestPermission()!=="granted"){console.log("[Push] Permission denied");return}c=await u.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:m})}const f=c.toJSON();await Ij("/api/push/subscribe",{hostId:n.hostId,endpoint:f.endpoint,keys:{p256dh:f.keys.p256dh,auth:f.keys.auth}}),r.current=n.hostId}catch(u){console.error("[Push] Subscription failed:",u)}}a()},[n])}function ru(){const{pairedHosts:t,activeHostId:n,removePairedHost:r}=Tl(),{connected:a,request:l,subscribeEvents:u,unauthorized:c}=yd(),f=ea(),m=br(),d=KS(),y=X1("(min-width: 768px)"),g=m.pathname.startsWith("/runs"),x=d.runId?void 0:d.taskId,[v,C]=U.useState(null),D=d.runId,q=D==="latest";U.useEffect(()=>{if(!q||!d.taskId||!a){C(null);return}l("taskrun.list",{task_id:d.taskId,limit:1}).then(I=>{var te,me;const H=(me=(te=I.entries)==null?void 0:te[0])==null?void 0:me.run_id;C(H??null)}).catch(()=>C(null))},[q,d.taskId,a]);const M=q?v:D,G=!!(d.taskId&&M&&M!=="latest"),[V,le]=U.useState(!1),[j,O]=U.useState(!1),[J,F]=U.useState(null),[X,z]=U.useState(null);$j(),U.useEffect(()=>{window.scrollTo(0,0)},[n]);function ie(I,H){f(H?`/runs/${encodeURIComponent(I)}/${encodeURIComponent(H)}`:`/runs/${encodeURIComponent(I)}`)}async function K(){O(!0),F(null);try{const I=await l("host.update");if(I.error){F(I.error),O(!1);return}}catch{}setTimeout(()=>window.location.reload(),1e4)}const ge=t.length>0,he=ge&&a&&n&&!c;return S.jsxs("div",{className:"dashboard",children:[y&&S.jsx(W0,{daemonVersion:X}),S.jsxs("div",{className:"dashboard-content",children:[S.jsxs("div",{className:"tab-bar",children:[!y&&S.jsx(W0,{daemonVersion:X}),S.jsx(Lj,{})]}),S.jsx("main",{className:"dashboard-main",children:c?S.jsxs("div",{className:"revoked-state",children:[S.jsx("div",{className:"revoked-icon",children:S.jsxs("svg",{width:"32",height:"32",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",children:[S.jsx("rect",{x:"3",y:"11",width:"18",height:"11",rx:"2",ry:"2"}),S.jsx("path",{d:"M7 11V7a5 5 0 0 1 10 0v4"}),S.jsx("line",{x1:"12",y1:"15",x2:"12",y2:"18"})]})}),S.jsx("h2",{className:"revoked-title",children:"Client Revoked"}),S.jsx("p",{className:"revoked-description",children:"This client was revoked by the host. To reconnect, generate a new pairing code on the host machine."}),S.jsx("div",{className:"revoked-command",children:S.jsx("code",{children:"palmier pair"})}),S.jsxs("div",{className:"revoked-actions",children:[S.jsx("button",{className:"btn btn-primary",onClick:()=>f("/pair"),children:"Re-pair Device"}),S.jsx("button",{className:"btn btn-secondary",onClick:()=>{n&&r(n)},children:"Remove Host"})]})]}):he?S.jsxs(S.Fragment,{children:[S.jsx("div",{style:{display:g?"none":"contents"},children:S.jsx(zj,{connected:a,hostId:n,request:l,subscribeEvents:u,onViewRun:ie,onUpdateRequired:le,onVersion:z})}),G?S.jsx(Pj,{connected:a,hostId:n,request:l,subscribeEvents:u,taskId:d.taskId,runId:decodeURIComponent(M)}):g?S.jsx(Bj,{connected:a,hostId:n,request:l,subscribeEvents:u,filterTaskId:x,onClearFilter:()=>f("/runs")}):null]}):S.jsxs("div",{className:"empty-state",children:[S.jsx("p",{children:ge?"Connecting to host...":"No hosts paired yet."}),!ge&&S.jsx("button",{className:"btn btn-primary",onClick:()=>f("/pair"),children:"Pair Host"})]})}),V&&!j&&!J&&S.jsx("div",{className:"confirm-modal-overlay",children:S.jsxs("div",{className:"confirm-modal",children:[S.jsx("h2",{className:"confirm-modal-title",children:"Update Required"}),S.jsxs("p",{className:"confirm-modal-message",children:["Your Palmier host",X?` (v${X})`:""," is too old for this version of the app. Please update to continue."]}),S.jsx("div",{className:"confirm-modal-actions",children:S.jsx("button",{className:"btn btn-primary",onClick:K,children:"Update Now"})})]})}),j&&S.jsx("div",{className:"confirm-modal-overlay",children:S.jsxs("div",{className:"confirm-modal",children:[S.jsx("h2",{className:"confirm-modal-title",children:"Updating..."}),S.jsx("p",{className:"confirm-modal-message",children:"Installing update and restarting daemon. Please wait..."})]})}),J&&S.jsx("div",{className:"confirm-modal-overlay",children:S.jsxs("div",{className:"confirm-modal",children:[S.jsx("h2",{className:"confirm-modal-title",children:"Update Failed"}),S.jsx("p",{className:"confirm-modal-message",style:{whiteSpace:"pre-line"},children:J}),S.jsx("div",{className:"confirm-modal-actions",children:S.jsx("button",{className:"btn btn-secondary",onClick:()=>{F(null)},children:"Retry"})})]})})]})]})}const ol=!!window.__PALMIER_SERVE__;function Gj(){const[t,n]=U.useState(""),[r,a]=U.useState(!1),[l,u]=U.useState(null),{addPairedHost:c}=Tl(),f=ea();async function m(){const d=t.trim().toUpperCase();if(!d){u("Enter a pairing code.");return}a(!0),u(null);try{let y;if(ol){const x=await fetch("/pair",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({code:d,label:navigator.userAgent})});if(!x.ok){const v=await x.json().catch(()=>({error:"Connection failed"}));throw new Error(v.error||`HTTP ${x.status}`)}y=await x.json()}else{const x=await fetch("/api/config");if(!x.ok)throw new Error("Failed to fetch server config");const v=await x.json();if(!v.natsWsUrl)throw new Error("Server has no NATS WebSocket URL configured");const C=await Pb({servers:v.natsWsUrl,token:v.natsToken}),D=mu(),q=`pair.${d}`,M=await C.request(q,D.encode(JSON.stringify({label:navigator.userAgent})),{timeout:1e4});y=JSON.parse(D.decode(M.data)),await C.close()}const g={hostId:y.hostId,clientToken:y.clientToken,directUrl:ol?window.location.origin:void 0};c(g),f("/")}catch(y){const g=y instanceof Error?y.message:String(y);g.includes("timeout")||g.includes("TIMEOUT")||g.includes("503")||g.toLowerCase().includes("no responders")?u("Code not found or expired. Check the code and try again."):u(g)}finally{a(!1)}}return S.jsx("div",{className:"pair-page",children:S.jsxs("div",{className:"pair-card",children:[S.jsxs("div",{className:"pair-header",children:[S.jsx("h1",{className:"pair-title",children:ol?"Pair":"Pair with Host"}),S.jsx("p",{className:"pair-subtitle",children:ol?"Enter the pairing code shown in your terminal.":"Connect this device to a Palmier host"})]}),!ol&&S.jsxs("div",{className:"pair-instructions",children:[S.jsxs("div",{className:"pair-instruction-block",children:[S.jsx("h3",{className:"pair-instruction-heading",children:"Setting up a new host?"}),S.jsxs("ol",{className:"pair-steps",children:[S.jsxs("li",{children:["Install at least one agent CLI (e.g., ",S.jsx("a",{href:"https://www.palmier.me/agents",target:"_blank",rel:"noopener noreferrer",children:"Claude Code, Gemini CLI, Codex CLI"}),")"]}),S.jsxs("li",{children:["Install Palmier on your host machine:",S.jsx("code",{className:"pair-command",children:"npm install -g palmier"})]}),S.jsxs("li",{children:["Run the setup wizard:",S.jsx("code",{className:"pair-command",children:"palmier init"})]}),S.jsx("li",{children:"A pairing code will display automatically"})]})]}),S.jsx("div",{className:"pair-instruction-divider"}),S.jsxs("div",{className:"pair-instruction-block",children:[S.jsx("h3",{className:"pair-instruction-heading",children:"Pairing an existing host?"}),S.jsxs("ol",{className:"pair-steps",children:[S.jsxs("li",{children:["Run ",S.jsx("code",{children:"palmier pair"})," on the host machine"]}),S.jsx("li",{children:"Enter the 6-character code below"})]})]})]}),S.jsxs("div",{className:"pair-form",children:[S.jsxs("label",{className:"form-label",htmlFor:"pair-code",children:["Pairing code",S.jsx("input",{id:"pair-code",type:"text",maxLength:6,value:t,onChange:d=>n(d.target.value.toUpperCase()),placeholder:"A7K9M2",className:"form-input form-input-mono pair-code-input",autoFocus:!0,autoComplete:"off",disabled:r})]}),l&&S.jsx("p",{className:"pair-error",children:l}),S.jsxs("button",{className:"btn btn-primary btn-full",onClick:m,disabled:r||!t.trim(),children:[r&&S.jsx("span",{className:"btn-spinner"}),r?"Pairing...":"Pair"]}),S.jsx("button",{className:"btn btn-secondary btn-full",onClick:()=>f("/"),disabled:r,children:"Cancel"}),S.jsxs("p",{className:"pair-consent",children:["By pairing, you agree to our"," ",S.jsx("a",{href:"https://www.palmier.me/terms",target:"_blank",rel:"noopener noreferrer",children:"Terms of Service"})," and"," ",S.jsx("a",{href:"https://www.palmier.me/privacy",target:"_blank",rel:"noopener noreferrer",children:"Privacy Policy"}),"."]})]})]})})}function Yj(){return S.jsx(Z_,{children:S.jsx(K2,{children:S.jsxs(d_,{children:[S.jsx(Fa,{path:"/",element:S.jsx(ru,{})}),S.jsx(Fa,{path:"/runs",element:S.jsx(ru,{})}),S.jsx(Fa,{path:"/runs/:taskId",element:S.jsx(ru,{})}),S.jsx(Fa,{path:"/runs/:taskId/:runId",element:S.jsx(ru,{})}),S.jsx(Fa,{path:"/pair",element:S.jsx(Gj,{})})]})})})}pS.createRoot(document.getElementById("root")).render(S.jsx(U.StrictMode,{children:S.jsx(U_,{children:S.jsx(Yj,{})})}))});export default Vj();
|
|
118
|
+
Are you sure you want to continue?`):!0}async function gn(){te("save"),j(null);try{const ve=se?"task.update":"task.create",Pe={user_prompt:m,agent:y,triggers:Le(),triggers_enabled:F,requires_confirmation:z,yolo_mode:K,foreground_mode:he,command:Ae?L:""};se&&(Pe.id=t.id);const He=await c(ve,Pe,{timeout:13e4});return He.error?(j(He.error),null):(se||localStorage.setItem("palmier:lastAgent",y),a(He),He)}catch(ve){return j(ve instanceof Error?ve.message:String(ve)),null}finally{te(null)}}async function Xt(){te("run"),j(null);try{const Pe=await c("task.run_oneoff",{user_prompt:m,agent:y,requires_confirmation:z,yolo_mode:K,foreground_mode:he,command:Ae?L:""});if(Pe.error){j(Pe.error);return}localStorage.setItem("palmier:lastAgent",y),l(Pe.task_id,Pe.run_id),u()}catch(ve){j(ve instanceof Error?ve.message:String(ve))}finally{te(null)}}return S.jsx("div",{className:"task-form-overlay",children:S.jsx("div",{className:"task-form",children:M?S.jsx(wj,{body:x,permissions:t==null?void 0:t.permissions}):S.jsxs(S.Fragment,{children:[S.jsx("div",{className:"task-form-header",children:S.jsx("h2",{children:t?"Edit Task":"New Task"})}),le&&S.jsx("div",{className:"form-error",children:le}),S.jsx("textarea",{autoFocus:!t,className:"form-textarea",value:m,onChange:ve=>d(ve.target.value),placeholder:Ae?"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:me}),S.jsxs("div",{className:"plan-actions",children:[q&&S.jsx("button",{className:"btn btn-link",onClick:()=>G(!0),children:"Execution Plan"}),S.jsxs("div",{className:"agent-picker-section-inline",style:{marginLeft:"auto"},children:[S.jsx("span",{className:"agent-picker-label",children:"Run with"}),S.jsx("select",{className:"form-select form-select-sm",value:y,onChange:ve=>g(ve.target.value),children:n.map(ve=>S.jsx("option",{value:ve.key,children:ve.label},ve.key))})]})]}),S.jsxs("div",{className:"toggles-group",children:[S.jsxs("div",{className:`command-section${Ae?" command-section-active":""}`,children:[S.jsxs("label",{className:"toggle-label",children:[S.jsx("input",{type:"checkbox",checked:Ae,onChange:ve=>{N(ve.target.checked),ve.target.checked?setTimeout(()=>{var Pe;return(Pe=E.current)==null?void 0:Pe.focus()},0):Y("")},disabled:me}),"Reactive"]}),Ae&&S.jsxs(S.Fragment,{children:[S.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."}),S.jsx("input",{ref:E,className:"form-input form-input-mono",type:"text",value:L,onChange:ve=>Y(ve.target.value),placeholder:"gws gmail +watch --project my-project",disabled:me})]})]}),r==="win32"&&S.jsxs("label",{className:"toggle-label",children:[S.jsx("input",{type:"checkbox",checked:he,onChange:ve=>I(ve.target.checked),disabled:me}),"Run in the foreground (host must login to Windows)"]}),S.jsxs("label",{className:"toggle-label",children:[S.jsx("input",{type:"checkbox",checked:K,onChange:ve=>ge(ve.target.checked),disabled:me}),"Yolo mode"]}),K&&S.jsx("p",{className:"command-help-text",children:"The agent will auto-approve all tool calls without asking for permission."}),S.jsxs("div",{className:"triggers-section",children:[S.jsxs("label",{className:"toggle-label",children:[S.jsx("input",{type:"checkbox",checked:F,onChange:ve=>{ve.target.checked?(X(!0),O.length===0&&Me()):(X(!1),ie(!1),J(Pe=>{const He=Pe.filter(_t=>_t.schedule==="once"?_t.onceDate&&new Date(`${_t.onceDate}T${_t.onceTime}`)>new Date:!0);return He.length===1&&He[0].schedule==="daily"&&He[0].time==="00:00"?[]:He}))},disabled:me}),"Add schedules"]}),S.jsxs("div",{className:`triggers-section-body${F?"":" disabled"}`,children:[O.map((ve,Pe)=>S.jsxs("div",{className:"trigger-row-card",children:[S.jsxs("div",{className:"trigger-row-content",children:[S.jsxs("div",{className:"trigger-row-top",children:[S.jsxs("select",{className:"form-select",value:ve.schedule,disabled:!F,onChange:He=>ze(Pe,{schedule:He.target.value}),children:[S.jsx("option",{value:"once",children:"Specific Time"}),S.jsx("option",{value:"hourly",children:"Hourly"}),S.jsx("option",{value:"daily",children:"Daily"}),S.jsx("option",{value:"weekly",children:"Weekly"}),S.jsx("option",{value:"monthly",children:"Monthly"})]}),ve.schedule==="daily"&&S.jsx("input",{className:"form-input",type:"time",value:ve.time,disabled:!F,onChange:He=>ze(Pe,{time:He.target.value})}),ve.schedule==="weekly"&&S.jsxs(S.Fragment,{children:[S.jsx("select",{className:"form-select",value:ve.dayOfWeek,disabled:!F,onChange:He=>ze(Pe,{dayOfWeek:He.target.value}),children:Aj.map((He,_t)=>S.jsx("option",{value:String(_t),children:He},_t))}),S.jsx("input",{className:"form-input",type:"time",value:ve.time,disabled:!F,onChange:He=>ze(Pe,{time:He.target.value})})]})]}),ve.schedule==="monthly"&&S.jsxs("div",{className:"trigger-details",children:[S.jsx("select",{className:"form-select",value:ve.dayOfMonth,disabled:!F,onChange:He=>ze(Pe,{dayOfMonth:He.target.value}),children:Array.from({length:28},(He,_t)=>_t+1).map(He=>S.jsxs("option",{value:String(He),children:["Day ",He]},He))}),S.jsx("input",{className:"form-input",type:"time",value:ve.time,disabled:!F,onChange:He=>ze(Pe,{time:He.target.value})})]}),ve.schedule==="once"&&S.jsxs("div",{className:"trigger-details",children:[S.jsx("input",{className:"form-input",type:"date",value:ve.onceDate,min:new Date().toISOString().split("T")[0],disabled:!F,onChange:He=>ze(Pe,{onceDate:He.target.value})}),S.jsx("input",{className:"form-input",type:"time",value:ve.onceTime,min:ve.onceDate===new Date().toISOString().split("T")[0]?new Date().toTimeString().slice(0,5):void 0,disabled:!F,onChange:He=>ze(Pe,{onceTime:He.target.value})})]})]}),S.jsx("button",{className:"trigger-remove-btn",onClick:()=>Ce(Pe),disabled:!F,title:"Remove trigger",children:"×"})]},Pe)),O.length>0&&S.jsx("button",{className:"trigger-add-btn",onClick:Me,disabled:!F,children:"+ Add Schedule"})]})]}),F&&O.length>0&&S.jsxs("label",{className:"toggle-label",children:[S.jsx("input",{type:"checkbox",checked:z,onChange:ve=>ie(ve.target.checked),disabled:me}),"Confirm before each run"]})]}),!K&&(()=>{const ve=n.find(Pe=>Pe.key===y);return(ve==null?void 0:ve.supportsPermissions)===!1&&S.jsxs("div",{className:"form-warning",children:["Palmier does not support runtime permission granting for ",ve.label,". The task may fail if required permissions are not pre-configured."]})})(),S.jsxs("div",{className:"form-actions",children:[(()=>{const ve=O.length>0,Pe=!!m.trim()&&(!Ae||!!L.trim());return se?we?S.jsxs("button",{className:"btn btn-primary",onClick:()=>Fe()&&gn(),disabled:!Oe||me,children:[H==="save"&&S.jsx("span",{className:"btn-spinner"}),"Save"]}):S.jsx("button",{className:"btn btn-primary",disabled:!0,children:"Save"}):ve?S.jsxs("button",{className:"btn btn-primary",onClick:()=>Fe()&&gn(),disabled:!Oe||me,children:[H==="save"&&S.jsx("span",{className:"btn-spinner"}),"Schedule"]}):S.jsxs(S.Fragment,{children:[S.jsxs("button",{className:"btn btn-primary",onClick:()=>Fe()&&Xt(),disabled:!Pe||me,children:[H==="run"&&S.jsx("span",{className:"btn-spinner"}),"Run"]}),S.jsx("button",{className:"btn btn-secondary",onClick:()=>Fe()&&gn(),disabled:!Oe||me,children:"Save"})]})})(),S.jsx("button",{className:"btn btn-secondary",onClick:()=>{we&&m.trim()&&!confirm("You have unsaved changes. Discard?")||u()},style:{marginLeft:"auto"},children:"Cancel"})]})]})})})}const Mj="0.6.1";function Dj(t,n){if(t.includes("-"))return!1;const r=t.split(".").map(Number),a=n.split(".").map(Number);for(let l=0;l<3;l++){if((r[l]??0)<(a[l]??0))return!0;if((r[l]??0)>(a[l]??0))return!1}return!1}function zj({connected:t,hostId:n,request:r,subscribeEvents:a,onViewRun:l,onUpdateRequired:u,onVersion:c}){const[f,m]=U.useState([]),[d,y]=U.useState(!1),[g,x]=U.useState(null),[v,C]=U.useState(new Map),[D,q]=U.useState(new Set),[M,G]=U.useState(new Map),[V,le]=U.useState(new Map),[j,O]=U.useState(new Map),[J,F]=U.useState(!1),[X,z]=U.useState(void 0),[ie,K]=U.useState([]),[ge,he]=U.useState(),I=U.useCallback(()=>{F(!1),z(void 0)},[]),H=U.useCallback(async()=>{var Y,E;if(t){y(!0),x(null);try{const se=await r("task.list"),we=se.tasks??[],xe=new Map,Oe=new Set,ze=new Map,Ce=new Map,Me=new Map;for(const Fe of we)Fe.status&&(xe.set(Fe.id,Fe.status),Fe.status.pending_confirmation&&Oe.add(Fe.id),(Y=Fe.status.pending_permission)!=null&&Y.length&&ze.set(Fe.id,Fe.status.pending_permission),(E=Fe.status.pending_input)!=null&&E.length&&(Ce.set(Fe.id,Fe.status.pending_input),Me.set(Fe.id,new Array(Fe.status.pending_input.length).fill(""))));C(xe),q(Oe),G(ze),le(Ce),O(Me),m(we),K(se.agents??[]),he(se.host_platform),W2(se.agents??[]);const Le=se.version??null;c==null||c(Le),u==null||u(!!Le&&Dj(Le,Mj))}catch(se){const we=se instanceof Error?se.message:String(se);we==="Not connected"||we.includes("503")||we.toLowerCase().includes("no responders")?x(null):x(we),m([])}finally{y(!1)}}},[t,n,r]);U.useEffect(()=>{t?H():(m([]),y(!1))},[t,n,H]),U.useEffect(()=>{if(!t||!n)return;const Y={decode:se=>new TextDecoder().decode(se)};return a(n,async se=>{var ze,Ce;const we=se.subject.split(".");if(we.length<3)return;const xe=we.slice(2).join(".");let Oe;try{Oe=JSON.parse(Y.decode(se.data)).event_type}catch{return}if(Oe==="confirm-resolved"){q(Me=>{if(!Me.has(xe))return Me;const Le=new Set(Me);return Le.delete(xe),Le});return}if(Oe==="permission-resolved"){G(Me=>{if(!Me.has(xe))return Me;const Le=new Map(Me);return Le.delete(xe),Le});return}if(Oe==="input-resolved"){le(Me=>{if(!Me.has(xe))return Me;const Le=new Map(Me);return Le.delete(xe),Le}),O(Me=>{const Le=new Map(Me);return Le.delete(xe),Le});return}try{const Me=await r("task.status",{id:xe},{timeout:5e3});if(Me.error)return;C(Le=>{const Fe=new Map(Le);return Fe.set(xe,Me),Fe}),Me.pending_confirmation&&q(Le=>{if(Le.has(xe))return Le;const Fe=new Set(Le);return Fe.add(xe),Fe}),(ze=Me.pending_permission)!=null&&ze.length&&G(Le=>{if(Le.has(xe))return Le;const Fe=new Map(Le);return Fe.set(xe,Me.pending_permission),Fe}),(Ce=Me.pending_input)!=null&&Ce.length&&(le(Le=>{if(Le.has(xe))return Le;const Fe=new Map(Le);return Fe.set(xe,Me.pending_input),Fe}),O(Le=>{if(Le.has(xe))return Le;const Fe=new Map(Le);return Fe.set(xe,new Array(Me.pending_input.length).fill("")),Fe}))}catch{}})},[t,n,a,r]);async function te(Y,E){try{await r("task.user_input",{id:Y,value:[E]})}catch(se){console.error("[TaskListView] Failed to respond to confirmation:",se)}}async function me(Y,E){try{await r("task.user_input",{id:Y,value:[E]})}catch(se){console.error("[TaskListView] Failed to respond to permission request:",se)}}async function Ae(Y,E){try{await r("task.user_input",{id:Y,value:E})}catch(se){console.error("[TaskListView] Failed to respond to input request:",se)}}function N(Y){m(E=>{const se=E.findIndex(we=>we.id===Y.id);if(se>=0){const we=[...E];return we[se]=Y,we}return[Y,...E]}),F(!1),z(void 0)}function L(Y){m(E=>E.filter(se=>se.id!==Y)),C(E=>{const se=new Map(E);return se.delete(Y),se}),le(E=>{const se=new Map(E);return se.delete(Y),se}),O(E=>{const se=new Map(E);return se.delete(Y),se})}return S.jsxs(S.Fragment,{children:[g&&S.jsxs("div",{className:"form-error",children:[g,g.toLowerCase().includes("failed to fetch")&&S.jsxs(S.Fragment,{children:[" ",S.jsx("a",{href:"#",onClick:Y=>{Y.preventDefault(),window.location.reload()},children:"Reload"})]})]}),S.jsx("div",{className:"new-task-input-card",onClick:()=>{z(void 0),F(!0)},role:"button",tabIndex:0,onKeyDown:Y=>{(Y.key==="Enter"||Y.key===" ")&&(z(void 0),F(!0))},children:S.jsx("span",{className:"new-task-placeholder",children:"Describe your new task..."})}),d&&!f.length?S.jsx("div",{className:"task-list",children:[0,1,2].map(Y=>S.jsxs("div",{className:"task-card",style:{pointerEvents:"none"},children:[S.jsx("div",{className:"task-card-header",children:S.jsxs("div",{className:"task-card-title-row",children:[S.jsx("div",{className:"skeleton-line",style:{width:10,height:10,borderRadius:"50%"}}),S.jsx("div",{className:"skeleton-line",style:{width:`${60+Y*12}%`}})]})}),S.jsxs("div",{className:"task-card-meta",children:[S.jsx("div",{className:"skeleton-line",style:{width:"30%"}}),S.jsx("div",{className:"skeleton-line",style:{width:"25%"}})]})]},Y))}):S.jsx("div",{className:"task-list",children:f.map(Y=>S.jsx(tE,{task:Y,lastEvent:v.get(Y.id),onEdit:async E=>{try{const se=await r("task.get",{id:E.id});z(se.error?E:se)}catch{z(E)}F(!0)},onDelete:L,onViewRun:l},Y.id))}),J&&S.jsx(Rj,{initial:X,agents:ie,hostPlatform:ge,onSaved:N,onRun:l,onCancel:I}),cu.createPortal(S.jsxs(S.Fragment,{children:[[...D].map(Y=>{const E=f.find(se=>se.id===Y);return S.jsx("div",{className:"confirm-modal-overlay",children:S.jsxs("div",{className:"confirm-modal",children:[S.jsx("h2",{className:"confirm-modal-title",children:"Task Confirmation"}),S.jsxs("p",{className:"confirm-modal-message",children:['Run task "',S.jsx("strong",{children:(E==null?void 0:E.name)||(E==null?void 0:E.user_prompt)||Y}),'"?']}),S.jsxs("div",{className:"confirm-modal-actions",children:[S.jsx("button",{className:"btn btn-primary",onClick:()=>te(Y,"confirmed"),children:"Confirm"}),S.jsx("button",{className:"btn btn-secondary",onClick:()=>te(Y,"aborted"),children:"Abort"})]})]})},Y)}),[...M.entries()].map(([Y,E])=>{const se=f.find(we=>we.id===Y);return S.jsx("div",{className:"confirm-modal-overlay",children:S.jsxs("div",{className:"confirm-modal permission-modal",children:[S.jsx("h2",{className:"confirm-modal-title",children:"Permission Required"}),S.jsx("p",{className:"confirm-modal-message",children:S.jsx("strong",{children:(se==null?void 0:se.name)||(se==null?void 0:se.user_prompt)||Y})}),S.jsx("div",{className:"permission-list",children:E.map((we,xe)=>S.jsxs("div",{className:"permission-item",children:[S.jsx("span",{className:"permission-name",children:we.name}),we.description&&S.jsx("span",{className:"permission-desc",children:we.description})]},xe))}),S.jsxs("div",{className:"permission-actions",children:[S.jsx("button",{className:"btn btn-primary",onClick:()=>me(Y,"granted"),children:"Allow Once"}),S.jsx("button",{className:"btn btn-secondary",onClick:()=>me(Y,"granted_all"),children:"Allow Always"})]}),S.jsx("button",{className:"permission-abort-link",onClick:()=>me(Y,"aborted"),children:"Deny & Abort Task"})]})},Y)}),[...V.entries()].map(([Y,E])=>{const se=f.find(xe=>xe.id===Y),we=j.get(Y)??new Array(E.length).fill("");return S.jsx("div",{className:"confirm-modal-overlay",children:S.jsxs("div",{className:"confirm-modal input-modal",children:[S.jsx("h2",{className:"confirm-modal-title",children:"Input Required"}),S.jsx("p",{className:"confirm-modal-message",children:S.jsx("strong",{children:(se==null?void 0:se.name)||(se==null?void 0:se.user_prompt)||Y})}),S.jsx("div",{className:"input-list",children:E.map((xe,Oe)=>S.jsxs("div",{className:"input-item",children:[S.jsx("label",{className:"input-label",children:xe}),S.jsx("input",{type:"text",className:"input-field",value:we[Oe]??"",onChange:ze=>{O(Ce=>{const Me=new Map(Ce),Le=[...Me.get(Y)??[]];return Le[Oe]=ze.target.value,Me.set(Y,Le),Me})},autoFocus:Oe===0})]},Oe))}),S.jsx("div",{className:"input-actions",children:S.jsx("button",{className:"btn btn-primary",disabled:we.some(xe=>!xe.trim()),onClick:()=>Ae(Y,we),children:"Submit"})}),S.jsx("button",{className:"permission-abort-link",onClick:()=>Ae(Y,["aborted"]),children:"Cancel & Abort Task"})]})},Y)})]}),document.body)]})}function Lj(){const t=ea(),r=br().pathname.startsWith("/runs");return S.jsxs(S.Fragment,{children:[S.jsxs("button",{className:`tab-btn ${r?"":"tab-btn-active"}`,onClick:()=>t("/"),children:[S.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:[S.jsx("rect",{x:"2",y:"2",width:"12",height:"12",rx:"2"}),S.jsx("path",{d:"M5.5 8L7 9.5L10.5 6"})]}),"Tasks"]}),S.jsxs("button",{className:`tab-btn ${r?"tab-btn-active":""}`,onClick:()=>t("/runs"),children:[S.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:S.jsx("path",{d:"M2 8H4.5L6 4L8 12L10 6L11.5 8H14"})}),"Runs"]})]})}function X1(t){const[n,r]=U.useState(()=>window.matchMedia(t).matches);return U.useEffect(()=>{const a=window.matchMedia(t),l=u=>r(u.matches);return a.addEventListener("change",l),r(a.matches),()=>a.removeEventListener("change",l)},[t]),n}const K0=!!window.__PALMIER_SERVE__;function W0({daemonVersion:t}){var K;const{pairedHosts:n,activeHostId:r,setActiveHostId:a,removePairedHost:l,renamePairedHost:u}=Tl(),c=ea(),f=X1("(min-width: 768px)"),[m,d]=U.useState(!1),[y,g]=U.useState(!1),[x,v]=U.useState(null),[C,D]=U.useState(""),[q,M]=U.useState(null),G=U.useRef(null),V=U.useRef(null),le=U.useCallback(()=>{g(!0)},[]);function j(){y&&(d(!1),g(!1))}function O(){g(!1),d(!0)}function J(ge,he){v(ge),D(he)}function F(){x&&C.trim()&&u(x,C.trim()),v(null),D("")}function X(){v(null),D("")}U.useEffect(()=>{x&&V.current&&(V.current.focus(),V.current.select())},[x]),U.useEffect(()=>{if(!m||y)return;function ge(he){he.key==="Escape"&&le()}return document.addEventListener("keydown",ge),()=>{document.removeEventListener("keydown",ge)}},[m,y,le]);const z=S.jsxs(S.Fragment,{children:[S.jsxs("div",{className:"drawer-header",children:[S.jsx("span",{className:"drawer-title",children:"Palmier"}),!f&&S.jsx("button",{className:"drawer-close-btn",onClick:le,"aria-label":"Close menu",children:S.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",children:S.jsx("path",{d:"M4 4L12 12M12 4L4 12",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})})})]}),!K0&&n.length>0&&S.jsxs("div",{className:"drawer-section",children:[S.jsx("h3",{className:"drawer-section-label",children:"Hosts"}),S.jsx("div",{className:"host-picker-inline",children:S.jsx("div",{className:"host-picker-list",role:"listbox",children:n.map(ge=>{const he=ge.hostId===r,I=x===ge.hostId,H=ge.name||ge.hostId.slice(0,8);return S.jsx("div",{className:"host-picker-item-wrapper",children:S.jsxs("div",{className:`host-picker-item ${he?"host-picker-item-active":""}`,onClick:()=>{I||he||(a(ge.hostId),f||le())},role:"option","aria-selected":he,children:[I?S.jsx("input",{ref:V,className:"form-input host-picker-rename-input",type:"text",value:C,onChange:te=>D(te.target.value),onKeyDown:te=>{te.key==="Enter"&&F(),te.key==="Escape"&&X()},onBlur:F,onClick:te=>te.stopPropagation()}):S.jsx("span",{className:"host-picker-item-name",children:H}),S.jsxs("div",{className:"host-picker-item-actions",children:[he&&!I&&S.jsx("button",{className:"host-picker-edit-btn",onClick:te=>{te.stopPropagation(),J(ge.hostId,H)},"aria-label":"Rename host",children:S.jsx("svg",{width:"13",height:"13",viewBox:"0 0 13 13",fill:"none",children:S.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"})})}),!he&&S.jsx("button",{className:"host-picker-delete-btn",onClick:te=>{te.stopPropagation(),M(ge.hostId)},"aria-label":`Unpair ${H}`,children:S.jsx("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",children:S.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"})})})]})]})},ge.hostId)})})})]}),!K0&&S.jsxs(S.Fragment,{children:[S.jsx("div",{className:"drawer-divider"}),S.jsx("div",{className:"drawer-section",children:S.jsx("button",{className:"btn btn-primary btn-full",onClick:()=>{c("/pair"),f||le()},children:"Pair New Host"})})]}),S.jsxs("div",{className:"drawer-footer",children:[t&&S.jsxs("div",{className:"drawer-version",children:["Palmier v",t]}),S.jsxs("div",{className:"drawer-legal",children:[S.jsx("a",{href:"https://www.palmier.me/terms",target:"_blank",rel:"noopener noreferrer",children:"Terms"}),S.jsx("span",{className:"drawer-legal-sep",children:"·"}),S.jsx("a",{href:"https://www.palmier.me/privacy",target:"_blank",rel:"noopener noreferrer",children:"Privacy"})]})]})]}),ie=q&&cu.createPortal(S.jsx("div",{className:"confirm-modal-overlay",onClick:()=>M(null),children:S.jsxs("div",{className:"confirm-modal",onClick:ge=>ge.stopPropagation(),children:[S.jsx("h2",{className:"confirm-modal-title",children:"Delete host?"}),S.jsxs("p",{className:"confirm-modal-message",children:['"',((K=n.find(ge=>ge.hostId===q))==null?void 0:K.name)||q.slice(0,8),'" will be unpaired from this device.']}),S.jsxs("div",{className:"confirm-modal-actions",children:[S.jsx("button",{className:"btn btn-secondary",onClick:()=>M(null),children:"Cancel"}),S.jsx("button",{className:"btn btn-danger",onClick:()=>{l(q),M(null)},children:"Delete"})]})]})}),document.body);return f?S.jsxs(S.Fragment,{children:[S.jsx("div",{className:"drawer-panel drawer-panel-desktop",ref:G,children:z}),ie]}):S.jsxs(S.Fragment,{children:[S.jsx("button",{className:"hamburger-btn",onClick:O,"aria-label":"Open menu",children:S.jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"none",children:S.jsx("path",{d:"M3 5H17M3 10H17M3 15H17",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})})}),m&&cu.createPortal(S.jsx("div",{className:`drawer-overlay ${y?"drawer-overlay-closing":""}`,onClick:le,onAnimationEnd:j,children:S.jsx("div",{className:`drawer-panel ${y?"drawer-panel-closing":""}`,ref:G,onClick:ge=>ge.stopPropagation(),children:z})}),document.body),ie]})}const Uj=10;function Bj({connected:t,hostId:n,request:r,subscribeEvents:a,filterTaskId:l,onClearFilter:u}){const[c,f]=U.useState([]),[m,d]=U.useState(0),[y,g]=U.useState(!1),[x,v]=U.useState(!1),C=ea(),D=U.useRef(null),q=U.useCallback(j=>{const O={offset:j,limit:Uj};return l&&(O.task_id=l),O},[l]),M=U.useCallback(async(j,O)=>{if(t){O?v(!0):g(!0);try{const J=await r("taskrun.list",q(j)),F=J.entries??[];d(J.total??0),f(O?X=>{const z=new Set(X.map(K=>`${K.task_id}:${K.run_id}`)),ie=F.filter(K=>!z.has(`${K.task_id}:${K.run_id}`));return[...X,...ie]}:F)}catch(J){J instanceof Error&&J.message==="Not connected"||console.error("Failed to load runs:",J)}finally{g(!1),v(!1)}}},[t,r,q]);U.useEffect(()=>{t?(f([]),d(0),M(0,!1)):(f([]),d(0))},[t,n,M,l]),U.useEffect(()=>!t||!n?void 0:a(n,async O=>{try{const J=JSON.parse(new TextDecoder().decode(O.data));if(J.event_type==="running-state"&&J.running_state&&["monitoring","started","finished","failed","aborted"].includes(J.running_state)){const F=await r("taskrun.list",q(0)),X=F.entries??[];d(F.total??0),f(z=>{const ie=new Map(X.map(I=>[`${I.task_id}:${I.run_id}`,I])),K=z.map(I=>{const H=`${I.task_id}:${I.run_id}`;return ie.get(H)??I}),ge=new Set(K.map(I=>`${I.task_id}:${I.run_id}`));return[...X.filter(I=>!ge.has(`${I.task_id}:${I.run_id}`)),...K]})}}catch{}}),[t,n,a,r]),U.useEffect(()=>{const j=D.current;if(!j)return;const O=new IntersectionObserver(J=>{J[0].isIntersecting&&!x&&c.length<m&&M(c.length,!0)},{threshold:.1});return O.observe(j),()=>O.disconnect()},[c.length,m,x,M]);function G(j,O){if(!j||!O)return"";const J=Math.round((O-j)/1e3);if(J<60)return`${J}s`;const F=Math.floor(J/60),X=J%60;return`${F}m ${X}s`}const V={monitoring:"Monitoring",started:"Running",finished:"Finished",failed:"Failed",aborted:"Aborted"};function le(j){if(j==="failed")return"var(--color-error)";if(j==="aborted")return"var(--color-warning, #d97706)"}return y&&c.length===0&&t?S.jsx("div",{className:"task-list",children:[0,1,2].map(j=>S.jsxs("div",{className:"task-card",style:{pointerEvents:"none"},children:[S.jsx("div",{className:"task-card-header",children:S.jsx("div",{className:"task-card-title-row",children:S.jsx("div",{className:"skeleton-line",style:{width:`${70+j*10}%`}})})}),S.jsx("div",{className:"task-card-meta",children:S.jsx("div",{className:"skeleton-line",style:{width:"45%"}})})]},j))}):!t||y&&c.length===0?S.jsx("div",{className:"runs-view",children:S.jsxs("div",{className:"empty-state",children:[S.jsx("p",{className:"empty-state-text",children:"Runs"}),S.jsx("p",{className:"empty-state-hint",children:"Run history will appear here"})]})}):c.length===0?S.jsxs(S.Fragment,{children:[l&&u&&S.jsx("div",{style:{marginBottom:"var(--space-sm)"},children:S.jsxs("span",{className:"runs-filter-chip",children:["Filtered by task",S.jsx("button",{onClick:u,"aria-label":"Clear filter",children:"×"})]})}),S.jsx("div",{className:"runs-view",children:S.jsxs("div",{className:"empty-state",children:[S.jsx("p",{className:"empty-state-text",children:"No runs yet"}),S.jsx("p",{className:"empty-state-hint",children:l?"This task hasn't been executed yet. Run it from the task menu or wait for its next trigger.":"Run history will appear here."})]})})]}):S.jsxs(S.Fragment,{children:[l&&u&&S.jsx("div",{style:{marginBottom:"var(--space-sm)"},children:S.jsxs("span",{className:"runs-filter-chip",children:["Filtered by task",S.jsx("button",{onClick:u,"aria-label":"Clear filter",children:"×"})]})}),S.jsxs("div",{className:"task-list",children:[c.map((j,O)=>S.jsxs("div",{className:"runs-card",onClick:()=>!j.error&&C(`/runs/${j.task_id}/${encodeURIComponent(j.run_id)}`),children:[S.jsxs("div",{className:"runs-card-body",children:[S.jsx("h3",{className:"runs-card-name",children:j.task_name||j.task_id}),S.jsxs("div",{className:"runs-card-meta",children:[S.jsx("span",{style:{color:le(j.running_state)},children:V[j.running_state??""]??j.running_state}),j.end_time&&S.jsx("span",{children:vu(j.end_time)}),j.start_time&&j.end_time&&S.jsx("span",{style:{color:"var(--color-muted)"},children:G(j.start_time,j.end_time)}),j.error&&S.jsx("span",{style:{color:"var(--color-muted)"},children:j.error})]})]}),S.jsx("span",{className:"runs-card-chevron",children:"›"})]},`${j.task_id}-${j.run_id}-${O}`)),S.jsx("div",{ref:D,style:{height:1}}),x&&S.jsx("div",{className:"loading-state",style:{padding:"var(--space-md)"},children:S.jsx("div",{className:"spinner"})})]})]})}function qj(t){k1(t,[/\r?\n|\r/g,Hj])}function Hj(){return{type:"break"}}function eb(){return function(t){qj(t)}}function Pj({connected:t,hostId:n,request:r,subscribeEvents:a,taskId:l,runId:u}){const c=ea(),[f,m]=U.useState(!0),[d,y]=U.useState([]),[g,x]=U.useState(),[v,C]=U.useState(),D=g==="started"||g==="monitoring",q=g==="followup",M=g==="started"||g==="followup",[G,V]=U.useState(null),[le,j]=U.useState(!1),[O,J]=U.useState(""),[F,X]=U.useState(!1),z=U.useRef(null);async function ie(){try{const I=await r("task.result",{id:l,run_id:u});if(I.error){console.error("No result:",I.error),c("/runs",{replace:!0});return}y(I.messages??[]),x(I.running_state),C(I.agent)}catch(I){console.error("Failed to load result:",I),c("/runs",{replace:!0})}finally{m(!1)}}async function K(I){var H;try{const me=(H=(await r("task.reports",{id:l,run_id:u,report_files:[I]})).reports)==null?void 0:H[0];me!=null&&me.data_url?V({file:I,data_url:me.data_url}):V({file:I,content:(me==null?void 0:me.content)??"Report not found."})}catch{V({file:I,content:"Failed to load report."})}}U.useEffect(()=>{t&&(m(!0),ie())},[t,l,u]),U.useEffect(()=>!t||!n?void 0:a(n,async H=>{try{const te=JSON.parse(new TextDecoder().decode(H.data));if(te.event_type!=="running-state"&&te.event_type!=="result-updated"||H.subject.split(".").pop()!==l||te.event_type==="result-updated"&&te.run_id&&te.run_id!==u)return;ie()}catch{}}),[t,n,l,a,r]),U.useEffect(()=>{z.current&&(z.current.scrollTop=z.current.scrollHeight)},[d]);function ge(I){if(I==="input")return"User Input";if(I==="permission")return"Permission";if(I==="confirmation")return"Confirmation"}function he(I){return I==="started"?"Task started":I==="finished"?"Task finished":I==="failed"?"Task failed":I==="aborted"?"Task aborted":I==="confirmation"?"Task confirmed":I==="stopped"?"Follow-up stopped":I??""}return S.jsxs("div",{className:"run-detail",children:[S.jsxs("button",{className:"run-detail-back",onClick:()=>c(-1),children:[S.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:S.jsx("path",{d:"M15 18l-6-6 6-6"})}),"Back"]}),f?S.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"var(--space-sm)",padding:"var(--space-sm) 0"},children:[S.jsx("div",{className:"skeleton-line",style:{width:"40%"}}),S.jsx("div",{className:"skeleton-line",style:{width:"55%"}}),S.jsx("div",{className:"skeleton-line",style:{width:"100%",height:"8rem",marginTop:"var(--space-sm)"}})]}):S.jsxs(S.Fragment,{children:[S.jsxs("div",{className:"chat-thread",ref:z,children:[d.map((I,H)=>{const te=M&&I.role==="assistant"&&!d.slice(H+1).some(me=>me.role==="assistant"||me.role==="user");return I.role==="status"&&I.type==="monitoring"?null:I.role==="status"?S.jsxs("div",{className:"chat-status",children:[he(I.type),I.time>0&&S.jsx("span",{className:"chat-status-time",children:vu(I.time)})]},H):S.jsxs("div",{className:`chat-message chat-message--${I.role}`,children:[I.role==="assistant"&&v&&S.jsx("div",{className:"chat-message-agent",children:Ih(v)}),S.jsxs("div",{className:"chat-message-content",children:[S.jsx(Wh,{remarkPlugins:[td,eb],children:I.content}),te&&S.jsxs("div",{className:"chat-typing-indicator",children:[S.jsx("span",{}),S.jsx("span",{}),S.jsx("span",{})]})]}),I.attachments&&I.attachments.length>0&&S.jsx("div",{className:"chat-message-attachments",children:I.attachments.map(me=>S.jsx("button",{className:"chat-attachment-chip",onClick:()=>K(me),children:me},me))}),S.jsxs("div",{className:"chat-message-meta",children:[ge(I.type)&&S.jsx("span",{className:"chat-message-type",children:ge(I.type)}),I.time>0&&S.jsx("span",{children:vu(I.time)})]})]},H)}),M&&(()=>{const I=d.filter(H=>H.role!=="status");return I.length===0||I[I.length-1].role!=="assistant"})()&&S.jsxs("div",{className:"chat-message chat-message--assistant",children:[v&&S.jsx("div",{className:"chat-message-agent",children:Ih(v)}),S.jsxs("div",{className:"chat-typing-indicator",children:[S.jsx("span",{}),S.jsx("span",{}),S.jsx("span",{})]})]}),g==="monitoring"&&S.jsxs("div",{className:"chat-monitoring-indicator",children:[S.jsx("span",{className:"chat-monitoring-dot"}),"Monitoring command output"]})]}),D?S.jsx("div",{className:"chat-abort-bar",children:S.jsx("button",{className:"btn btn-secondary chat-abort-btn",disabled:le,onClick:async()=>{if(confirm("Abort this task?")){j(!0);try{await r("task.abort",{id:l})}catch(I){console.error("Abort failed:",I)}finally{j(!1)}}},children:le?"Aborting...":"Abort Task"})}):q?S.jsx("div",{className:"chat-input-bar",children:S.jsx("button",{className:"btn btn-secondary chat-stop-btn",disabled:le,onClick:async()=>{j(!0);try{await r("task.stop_followup",{id:l,run_id:u})}catch(I){console.error("Stop failed:",I)}finally{j(!1)}},children:S.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"currentColor",children:S.jsx("rect",{x:"6",y:"6",width:"12",height:"12",rx:"2"})})})}):S.jsxs("form",{className:"chat-input-bar",onSubmit:async I=>{I.preventDefault();const H=O.trim();if(!(!H||F)){X(!0);try{await r("task.followup",{id:l,run_id:u,message:H}),J("")}catch(te){console.error("Follow-up failed:",te)}finally{X(!1)}}},children:[S.jsx("input",{className:"chat-input",type:"text",placeholder:"Follow-up message",value:O,onChange:I=>J(I.target.value),disabled:F}),S.jsx("button",{className:"btn btn-primary chat-send-btn",type:"submit",disabled:!O.trim()||F,children:S.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[S.jsx("line",{x1:"22",y1:"2",x2:"11",y2:"13"}),S.jsx("polygon",{points:"22 2 15 22 11 13 2 9 22 2"})]})})]})]}),G&&S.jsx("div",{className:"report-dialog-overlay",onClick:()=>V(null),children:S.jsxs("div",{className:"report-dialog",onClick:I=>I.stopPropagation(),children:[S.jsxs("div",{className:"report-dialog-header",children:[S.jsx("span",{className:"report-dialog-title",children:G.file}),S.jsx("button",{className:"report-dialog-close",onClick:()=>V(null),"aria-label":"Close",children:S.jsxs("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[S.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),S.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})})]}),S.jsx("div",{className:"report-dialog-body",children:G.data_url?S.jsx("img",{src:G.data_url,alt:G.file,style:{maxWidth:"100%",height:"auto"}}):S.jsx(Wh,{remarkPlugins:[td,eb],components:{a:({...I})=>S.jsx("a",{...I,target:"_blank",rel:"noopener noreferrer"})},children:G.content??""})})]})})]})}async function Q1(t,n,r,a){console.log(`[API] ${t} ${n}`);const u=await fetch(n,{method:t,headers:{"Content-Type":"application/json"},body:r!=null?JSON.stringify(r):void 0});if(!u.ok){const c=await u.text();let f;try{const m=JSON.parse(c);f=m.error??m.message??c}catch{f=c}throw console.error(`[API] ${t} ${n} failed:`,u.status,f),new Error(f||`Request failed with status ${u.status}`)}return console.log(`[API] ${t} ${n} ->`,u.status),u.json()}function Ij(t,n,r){return Q1("POST",t,n)}function Fj(t,n){return Q1("GET",t,void 0)}function $j(){const{getActiveHost:t}=Tl(),n=t(),r=U.useRef(null);U.useEffect(()=>{if(!n||n.directUrl||r.current===n.hostId)return;async function a(){var l;try{if(!("serviceWorker"in navigator)||!("PushManager"in window)){console.warn("[Push] Push notifications not supported");return}const u=await navigator.serviceWorker.ready;(l=u.active)==null||l.postMessage({type:"set-host-id",hostId:n.hostId});let c=await u.pushManager.getSubscription();if(!c){const{publicKey:m}=await Fj("/api/push/vapid-key");if(!m){console.warn("[Push] No VAPID public key configured on server");return}if(await Notification.requestPermission()!=="granted"){console.log("[Push] Permission denied");return}c=await u.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:m})}const f=c.toJSON();await Ij("/api/push/subscribe",{hostId:n.hostId,endpoint:f.endpoint,keys:{p256dh:f.keys.p256dh,auth:f.keys.auth}}),r.current=n.hostId}catch(u){console.error("[Push] Subscription failed:",u)}}a()},[n])}function ru(){const{pairedHosts:t,activeHostId:n,removePairedHost:r}=Tl(),{connected:a,request:l,subscribeEvents:u,unauthorized:c}=yd(),f=ea(),m=br(),d=KS(),y=X1("(min-width: 768px)"),g=m.pathname.startsWith("/runs"),x=d.runId?void 0:d.taskId,[v,C]=U.useState(null),D=d.runId,q=D==="latest";U.useEffect(()=>{if(!q||!d.taskId||!a){C(null);return}l("taskrun.list",{task_id:d.taskId,limit:1}).then(I=>{var te,me;const H=(me=(te=I.entries)==null?void 0:te[0])==null?void 0:me.run_id;C(H??null)}).catch(()=>C(null))},[q,d.taskId,a]);const M=q?v:D,G=!!(d.taskId&&M&&M!=="latest"),[V,le]=U.useState(!1),[j,O]=U.useState(!1),[J,F]=U.useState(null),[X,z]=U.useState(null);$j(),U.useEffect(()=>{window.scrollTo(0,0)},[n]);function ie(I,H){f(H?`/runs/${encodeURIComponent(I)}/${encodeURIComponent(H)}`:`/runs/${encodeURIComponent(I)}`)}async function K(){O(!0),F(null);try{const I=await l("host.update");if(I.error){F(I.error),O(!1);return}}catch{}setTimeout(()=>window.location.reload(),1e4)}const ge=t.length>0,he=ge&&a&&n&&!c;return S.jsxs("div",{className:"dashboard",children:[y&&S.jsx(W0,{daemonVersion:X}),S.jsxs("div",{className:"dashboard-content",children:[S.jsxs("div",{className:"tab-bar",children:[!y&&S.jsx(W0,{daemonVersion:X}),S.jsx(Lj,{})]}),S.jsx("main",{className:"dashboard-main",children:c?S.jsxs("div",{className:"revoked-state",children:[S.jsx("div",{className:"revoked-icon",children:S.jsxs("svg",{width:"32",height:"32",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",children:[S.jsx("rect",{x:"3",y:"11",width:"18",height:"11",rx:"2",ry:"2"}),S.jsx("path",{d:"M7 11V7a5 5 0 0 1 10 0v4"}),S.jsx("line",{x1:"12",y1:"15",x2:"12",y2:"18"})]})}),S.jsx("h2",{className:"revoked-title",children:"Client Revoked"}),S.jsx("p",{className:"revoked-description",children:"This client was revoked by the host. To reconnect, generate a new pairing code on the host machine."}),S.jsx("div",{className:"revoked-command",children:S.jsx("code",{children:"palmier pair"})}),S.jsxs("div",{className:"revoked-actions",children:[S.jsx("button",{className:"btn btn-primary",onClick:()=>f("/pair"),children:"Re-pair Device"}),S.jsx("button",{className:"btn btn-secondary",onClick:()=>{n&&r(n)},children:"Remove Host"})]})]}):he?S.jsxs(S.Fragment,{children:[S.jsx("div",{style:{display:g?"none":"contents"},children:S.jsx(zj,{connected:a,hostId:n,request:l,subscribeEvents:u,onViewRun:ie,onUpdateRequired:le,onVersion:z})}),G?S.jsx(Pj,{connected:a,hostId:n,request:l,subscribeEvents:u,taskId:d.taskId,runId:decodeURIComponent(M)}):g?S.jsx(Bj,{connected:a,hostId:n,request:l,subscribeEvents:u,filterTaskId:x,onClearFilter:()=>f("/runs")}):null]}):S.jsxs("div",{className:"empty-state",children:[S.jsx("p",{children:ge?"Connecting to host...":"No hosts paired yet."}),!ge&&S.jsx("button",{className:"btn btn-primary",onClick:()=>f("/pair"),children:"Pair Host"})]})}),V&&!j&&!J&&S.jsx("div",{className:"confirm-modal-overlay",children:S.jsxs("div",{className:"confirm-modal",children:[S.jsx("h2",{className:"confirm-modal-title",children:"Update Required"}),S.jsxs("p",{className:"confirm-modal-message",children:["Your Palmier host",X?` (v${X})`:""," is too old for this version of the app. Please update to continue."]}),S.jsx("div",{className:"confirm-modal-actions",children:S.jsx("button",{className:"btn btn-primary",onClick:K,children:"Update Now"})})]})}),j&&S.jsx("div",{className:"confirm-modal-overlay",children:S.jsxs("div",{className:"confirm-modal",children:[S.jsx("h2",{className:"confirm-modal-title",children:"Updating..."}),S.jsx("p",{className:"confirm-modal-message",children:"Installing update and restarting daemon. Please wait..."})]})}),J&&S.jsx("div",{className:"confirm-modal-overlay",children:S.jsxs("div",{className:"confirm-modal",children:[S.jsx("h2",{className:"confirm-modal-title",children:"Update Failed"}),S.jsx("p",{className:"confirm-modal-message",style:{whiteSpace:"pre-line"},children:J}),S.jsx("div",{className:"confirm-modal-actions",children:S.jsx("button",{className:"btn btn-secondary",onClick:()=>{F(null)},children:"Retry"})})]})})]})]})}const ol=!!window.__PALMIER_SERVE__;function Gj(){const[t,n]=U.useState(""),[r,a]=U.useState(!1),[l,u]=U.useState(null),{addPairedHost:c}=Tl(),f=ea();async function m(){const d=t.trim().toUpperCase();if(!d){u("Enter a pairing code.");return}a(!0),u(null);try{let y;if(ol){const x=await fetch("/pair",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({code:d,label:navigator.userAgent})});if(!x.ok){const v=await x.json().catch(()=>({error:"Connection failed"}));throw new Error(v.error||`HTTP ${x.status}`)}y=await x.json()}else{const x=await fetch("/api/config");if(!x.ok)throw new Error("Failed to fetch server config");const v=await x.json();if(!v.natsWsUrl)throw new Error("Server has no NATS WebSocket URL configured");const C=await Pb({servers:v.natsWsUrl,token:v.natsToken}),D=mu(),q=`pair.${d}`,M=await C.request(q,D.encode(JSON.stringify({label:navigator.userAgent})),{timeout:1e4});y=JSON.parse(D.decode(M.data)),await C.close()}const g={hostId:y.hostId,clientToken:y.clientToken,directUrl:ol?window.location.origin:void 0};c(g),f("/")}catch(y){const g=y instanceof Error?y.message:String(y);g.includes("timeout")||g.includes("TIMEOUT")||g.includes("503")||g.toLowerCase().includes("no responders")?u("Code not found or expired. Check the code and try again."):u(g)}finally{a(!1)}}return S.jsx("div",{className:"pair-page",children:S.jsxs("div",{className:"pair-card",children:[S.jsxs("div",{className:"pair-header",children:[S.jsx("h1",{className:"pair-title",children:ol?"Pair":"Pair with Host"}),S.jsx("p",{className:"pair-subtitle",children:ol?"Enter the pairing code shown in your terminal.":"Connect this device to a Palmier host"})]}),!ol&&S.jsxs("div",{className:"pair-instructions",children:[S.jsxs("div",{className:"pair-instruction-block",children:[S.jsx("h3",{className:"pair-instruction-heading",children:"Setting up a new host?"}),S.jsxs("ol",{className:"pair-steps",children:[S.jsxs("li",{children:["Install at least one agent CLI (e.g., ",S.jsx("a",{href:"https://www.palmier.me/agents",target:"_blank",rel:"noopener noreferrer",children:"Claude Code, Gemini CLI, Codex CLI"}),")"]}),S.jsxs("li",{children:["Install Palmier on your host machine:",S.jsx("code",{className:"pair-command",children:"npm install -g palmier"})]}),S.jsxs("li",{children:["Run the setup wizard:",S.jsx("code",{className:"pair-command",children:"palmier init"})]}),S.jsx("li",{children:"A pairing code will display automatically"})]})]}),S.jsx("div",{className:"pair-instruction-divider"}),S.jsxs("div",{className:"pair-instruction-block",children:[S.jsx("h3",{className:"pair-instruction-heading",children:"Pairing an existing host?"}),S.jsxs("ol",{className:"pair-steps",children:[S.jsxs("li",{children:["Run ",S.jsx("code",{children:"palmier pair"})," on the host machine"]}),S.jsx("li",{children:"Enter the 6-character code below"})]})]})]}),S.jsxs("div",{className:"pair-form",children:[S.jsxs("label",{className:"form-label",htmlFor:"pair-code",children:["Pairing code",S.jsx("input",{id:"pair-code",type:"text",maxLength:6,value:t,onChange:d=>n(d.target.value.toUpperCase()),placeholder:"A7K9M2",className:"form-input form-input-mono pair-code-input",autoFocus:!0,autoComplete:"off",disabled:r})]}),l&&S.jsx("p",{className:"pair-error",children:l}),S.jsxs("button",{className:"btn btn-primary btn-full",onClick:m,disabled:r||!t.trim(),children:[r&&S.jsx("span",{className:"btn-spinner"}),r?"Pairing...":"Pair"]}),S.jsx("button",{className:"btn btn-secondary btn-full",onClick:()=>f("/"),disabled:r,children:"Cancel"}),S.jsxs("p",{className:"pair-consent",children:["By pairing, you agree to our"," ",S.jsx("a",{href:"https://www.palmier.me/terms",target:"_blank",rel:"noopener noreferrer",children:"Terms of Service"})," and"," ",S.jsx("a",{href:"https://www.palmier.me/privacy",target:"_blank",rel:"noopener noreferrer",children:"Privacy Policy"}),"."]})]})]})})}function Yj(){return S.jsx(Z_,{children:S.jsx(K2,{children:S.jsxs(d_,{children:[S.jsx(Fa,{path:"/",element:S.jsx(ru,{})}),S.jsx(Fa,{path:"/runs",element:S.jsx(ru,{})}),S.jsx(Fa,{path:"/runs/:taskId",element:S.jsx(ru,{})}),S.jsx(Fa,{path:"/runs/:taskId/:runId",element:S.jsx(ru,{})}),S.jsx(Fa,{path:"/pair",element:S.jsx(Gj,{})})]})})})}pS.createRoot(document.getElementById("root")).render(S.jsx(U.StrictMode,{children:S.jsx(U_,{children:S.jsx(Yj,{})})}))});export default Vj();
|
package/dist/pwa/index.html
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
|
8
8
|
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
|
9
9
|
<title>Palmier</title>
|
|
10
|
-
<meta name="description" content="
|
|
11
|
-
<script type="module" crossorigin src="/assets/index-
|
|
10
|
+
<meta name="description" content="Control AI agents running on your machine from any device. Schedule tasks, monitor runs, and stay in control." />
|
|
11
|
+
<script type="module" crossorigin src="/assets/index-ByhOhTz1.js"></script>
|
|
12
12
|
<link rel="stylesheet" crossorigin href="/assets/index-_AmC1Rkn.css">
|
|
13
13
|
<link rel="manifest" href="/manifest.webmanifest"><script id="vite-plugin-pwa:register-sw" src="/registerSW.js"></script></head>
|
|
14
14
|
<body>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"Palmier","short_name":"Palmier","description":"
|
|
1
|
+
{"name":"Palmier","short_name":"Palmier","description":"Control AI agents running on your machine from any device. Schedule tasks, monitor runs, and stay in control.","start_url":"/","display":"standalone","background_color":"#ffffff","theme_color":"#2E5CE5","lang":"en","scope":"/","icons":[{"src":"pwa-192x192.png","sizes":"192x192","type":"image/png"},{"src":"pwa-512x512.png","sizes":"512x512","type":"image/png"}]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
try{self["workbox:core:7.3.0"]&&_()}catch{}const x=(a,...e)=>{let t=a;return e.length>0&&(t+=` :: ${JSON.stringify(e)}`),t},N=x;class l extends Error{constructor(e,t){const s=N(e,t);super(s),this.name=e,this.details=t}}const f={googleAnalytics:"googleAnalytics",precache:"precache-v2",prefix:"workbox",runtime:"runtime",suffix:typeof registration<"u"?registration.scope:""},U=a=>[f.prefix,a,f.suffix].filter(e=>e&&e.length>0).join("-"),I=a=>{for(const e of Object.keys(f))a(e)},L={updateDetails:a=>{I(e=>{typeof a[e]=="string"&&(f[e]=a[e])})},getGoogleAnalyticsName:a=>a||U(f.googleAnalytics),getPrecacheName:a=>a||U(f.precache),getPrefix:()=>f.prefix,getRuntimeName:a=>a||U(f.runtime),getSuffix:()=>f.suffix};function P(a,e){const t=e();return a.waitUntil(t),t}try{self["workbox:precaching:7.3.0"]&&_()}catch{}const E="__WB_REVISION__";function O(a){if(!a)throw new l("add-to-cache-list-unexpected-type",{entry:a});if(typeof a=="string"){const i=new URL(a,location.href);return{cacheKey:i.href,url:i.href}}const{revision:e,url:t}=a;if(!t)throw new l("add-to-cache-list-unexpected-type",{entry:a});if(!e){const i=new URL(t,location.href);return{cacheKey:i.href,url:i.href}}const s=new URL(t,location.href),n=new URL(t,location.href);return s.searchParams.set(E,e),{cacheKey:s.href,url:n.href}}class A{constructor(){this.updatedURLs=[],this.notUpdatedURLs=[],this.handlerWillStart=async({request:e,state:t})=>{t&&(t.originalRequest=e)},this.cachedResponseWillBeUsed=async({event:e,state:t,cachedResponse:s})=>{if(e.type==="install"&&t&&t.originalRequest&&t.originalRequest instanceof Request){const n=t.originalRequest.url;s?this.notUpdatedURLs.push(n):this.updatedURLs.push(n)}return s}}}class M{constructor({precacheController:e}){this.cacheKeyWillBeUsed=async({request:t,params:s})=>{const n=(s==null?void 0:s.cacheKey)||this._precacheController.getCacheKeyForURL(t.url);return n?new Request(n,{headers:t.headers}):t},this._precacheController=e}}let y;function W(){if(y===void 0){const a=new Response("");if("body"in a)try{new Response(a.body),y=!0}catch{y=!1}y=!1}return y}async function q(a,e){let t=null;if(a.url&&(t=new URL(a.url).origin),t!==self.location.origin)throw new l("cross-origin-copy-response",{origin:t});const s=a.clone(),i={headers:new Headers(s.headers),status:s.status,statusText:s.statusText},r=W()?s.body:await s.blob();return new Response(r,i)}const S=a=>new URL(String(a),location.href).href.replace(new RegExp(`^${location.origin}`),"");function K(a,e){const t=new URL(a);for(const s of e)t.searchParams.delete(s);return t.href}async function j(a,e,t,s){const n=K(e.url,t);if(e.url===n)return a.match(e,s);const i=Object.assign(Object.assign({},s),{ignoreSearch:!0}),r=await a.keys(e,i);for(const c of r){const o=K(c.url,t);if(n===o)return a.match(c,s)}}class D{constructor(){this.promise=new Promise((e,t)=>{this.resolve=e,this.reject=t})}}const H=new Set;async function F(){for(const a of H)await a()}function B(a){return new Promise(e=>setTimeout(e,a))}try{self["workbox:strategies:7.3.0"]&&_()}catch{}function R(a){return typeof a=="string"?new Request(a):a}class ${constructor(e,t){this._cacheKeys={},Object.assign(this,t),this.event=t.event,this._strategy=e,this._handlerDeferred=new D,this._extendLifetimePromises=[],this._plugins=[...e.plugins],this._pluginStateMap=new Map;for(const s of this._plugins)this._pluginStateMap.set(s,{});this.event.waitUntil(this._handlerDeferred.promise)}async fetch(e){const{event:t}=this;let s=R(e);if(s.mode==="navigate"&&t instanceof FetchEvent&&t.preloadResponse){const r=await t.preloadResponse;if(r)return r}const n=this.hasCallback("fetchDidFail")?s.clone():null;try{for(const r of this.iterateCallbacks("requestWillFetch"))s=await r({request:s.clone(),event:t})}catch(r){if(r instanceof Error)throw new l("plugin-error-request-will-fetch",{thrownErrorMessage:r.message})}const i=s.clone();try{let r;r=await fetch(s,s.mode==="navigate"?void 0:this._strategy.fetchOptions);for(const c of this.iterateCallbacks("fetchDidSucceed"))r=await c({event:t,request:i,response:r});return r}catch(r){throw n&&await this.runCallbacks("fetchDidFail",{error:r,event:t,originalRequest:n.clone(),request:i.clone()}),r}}async fetchAndCachePut(e){const t=await this.fetch(e),s=t.clone();return this.waitUntil(this.cachePut(e,s)),t}async cacheMatch(e){const t=R(e);let s;const{cacheName:n,matchOptions:i}=this._strategy,r=await this.getCacheKey(t,"read"),c=Object.assign(Object.assign({},i),{cacheName:n});s=await caches.match(r,c);for(const o of this.iterateCallbacks("cachedResponseWillBeUsed"))s=await o({cacheName:n,matchOptions:i,cachedResponse:s,request:r,event:this.event})||void 0;return s}async cachePut(e,t){const s=R(e);await B(0);const n=await this.getCacheKey(s,"write");if(!t)throw new l("cache-put-with-no-response",{url:S(n.url)});const i=await this._ensureResponseSafeToCache(t);if(!i)return!1;const{cacheName:r,matchOptions:c}=this._strategy,o=await self.caches.open(r),h=this.hasCallback("cacheDidUpdate"),p=h?await j(o,n.clone(),["__WB_REVISION__"],c):null;try{await o.put(n,h?i.clone():i)}catch(u){if(u instanceof Error)throw u.name==="QuotaExceededError"&&await F(),u}for(const u of this.iterateCallbacks("cacheDidUpdate"))await u({cacheName:r,oldResponse:p,newResponse:i.clone(),request:n,event:this.event});return!0}async getCacheKey(e,t){const s=`${e.url} | ${t}`;if(!this._cacheKeys[s]){let n=e;for(const i of this.iterateCallbacks("cacheKeyWillBeUsed"))n=R(await i({mode:t,request:n,event:this.event,params:this.params}));this._cacheKeys[s]=n}return this._cacheKeys[s]}hasCallback(e){for(const t of this._strategy.plugins)if(e in t)return!0;return!1}async runCallbacks(e,t){for(const s of this.iterateCallbacks(e))await s(t)}*iterateCallbacks(e){for(const t of this._strategy.plugins)if(typeof t[e]=="function"){const s=this._pluginStateMap.get(t);yield i=>{const r=Object.assign(Object.assign({},i),{state:s});return t[e](r)}}}waitUntil(e){return this._extendLifetimePromises.push(e),e}async doneWaiting(){for(;this._extendLifetimePromises.length;){const e=this._extendLifetimePromises.splice(0),s=(await Promise.allSettled(e)).find(n=>n.status==="rejected");if(s)throw s.reason}}destroy(){this._handlerDeferred.resolve(null)}async _ensureResponseSafeToCache(e){let t=e,s=!1;for(const n of this.iterateCallbacks("cacheWillUpdate"))if(t=await n({request:this.request,response:t,event:this.event})||void 0,s=!0,!t)break;return s||t&&t.status!==200&&(t=void 0),t}}class V{constructor(e={}){this.cacheName=L.getRuntimeName(e.cacheName),this.plugins=e.plugins||[],this.fetchOptions=e.fetchOptions,this.matchOptions=e.matchOptions}handle(e){const[t]=this.handleAll(e);return t}handleAll(e){e instanceof FetchEvent&&(e={event:e,request:e.request});const t=e.event,s=typeof e.request=="string"?new Request(e.request):e.request,n="params"in e?e.params:void 0,i=new $(this,{event:t,request:s,params:n}),r=this._getResponse(i,s,t),c=this._awaitComplete(r,i,s,t);return[r,c]}async _getResponse(e,t,s){await e.runCallbacks("handlerWillStart",{event:s,request:t});let n;try{if(n=await this._handle(t,e),!n||n.type==="error")throw new l("no-response",{url:t.url})}catch(i){if(i instanceof Error){for(const r of e.iterateCallbacks("handlerDidError"))if(n=await r({error:i,event:s,request:t}),n)break}if(!n)throw i}for(const i of e.iterateCallbacks("handlerWillRespond"))n=await i({event:s,request:t,response:n});return n}async _awaitComplete(e,t,s,n){let i,r;try{i=await e}catch{}try{await t.runCallbacks("handlerDidRespond",{event:n,request:s,response:i}),await t.doneWaiting()}catch(c){c instanceof Error&&(r=c)}if(await t.runCallbacks("handlerDidComplete",{event:n,request:s,response:i,error:r}),t.destroy(),r)throw r}}class d extends V{constructor(e={}){e.cacheName=L.getPrecacheName(e.cacheName),super(e),this._fallbackToNetwork=e.fallbackToNetwork!==!1,this.plugins.push(d.copyRedirectedCacheableResponsesPlugin)}async _handle(e,t){const s=await t.cacheMatch(e);return s||(t.event&&t.event.type==="install"?await this._handleInstall(e,t):await this._handleFetch(e,t))}async _handleFetch(e,t){let s;const n=t.params||{};if(this._fallbackToNetwork){const i=n.integrity,r=e.integrity,c=!r||r===i;s=await t.fetch(new Request(e,{integrity:e.mode!=="no-cors"?r||i:void 0})),i&&c&&e.mode!=="no-cors"&&(this._useDefaultCacheabilityPluginIfNeeded(),await t.cachePut(e,s.clone()))}else throw new l("missing-precache-entry",{cacheName:this.cacheName,url:e.url});return s}async _handleInstall(e,t){this._useDefaultCacheabilityPluginIfNeeded();const s=await t.fetch(e);if(!await t.cachePut(e,s.clone()))throw new l("bad-precaching-response",{url:e.url,status:s.status});return s}_useDefaultCacheabilityPluginIfNeeded(){let e=null,t=0;for(const[s,n]of this.plugins.entries())n!==d.copyRedirectedCacheableResponsesPlugin&&(n===d.defaultPrecacheCacheabilityPlugin&&(e=s),n.cacheWillUpdate&&t++);t===0?this.plugins.push(d.defaultPrecacheCacheabilityPlugin):t>1&&e!==null&&this.plugins.splice(e,1)}}d.defaultPrecacheCacheabilityPlugin={async cacheWillUpdate({response:a}){return!a||a.status>=400?null:a}};d.copyRedirectedCacheableResponsesPlugin={async cacheWillUpdate({response:a}){return a.redirected?await q(a):a}};class G{constructor({cacheName:e,plugins:t=[],fallbackToNetwork:s=!0}={}){this._urlsToCacheKeys=new Map,this._urlsToCacheModes=new Map,this._cacheKeysToIntegrities=new Map,this._strategy=new d({cacheName:L.getPrecacheName(e),plugins:[...t,new M({precacheController:this})],fallbackToNetwork:s}),this.install=this.install.bind(this),this.activate=this.activate.bind(this)}get strategy(){return this._strategy}precache(e){this.addToCacheList(e),this._installAndActiveListenersAdded||(self.addEventListener("install",this.install),self.addEventListener("activate",this.activate),this._installAndActiveListenersAdded=!0)}addToCacheList(e){const t=[];for(const s of e){typeof s=="string"?t.push(s):s&&s.revision===void 0&&t.push(s.url);const{cacheKey:n,url:i}=O(s),r=typeof s!="string"&&s.revision?"reload":"default";if(this._urlsToCacheKeys.has(i)&&this._urlsToCacheKeys.get(i)!==n)throw new l("add-to-cache-list-conflicting-entries",{firstEntry:this._urlsToCacheKeys.get(i),secondEntry:n});if(typeof s!="string"&&s.integrity){if(this._cacheKeysToIntegrities.has(n)&&this._cacheKeysToIntegrities.get(n)!==s.integrity)throw new l("add-to-cache-list-conflicting-integrities",{url:i});this._cacheKeysToIntegrities.set(n,s.integrity)}if(this._urlsToCacheKeys.set(i,n),this._urlsToCacheModes.set(i,r),t.length>0){const c=`Workbox is precaching URLs without revision info: ${t.join(", ")}
|
|
2
|
-
This is generally NOT safe. Learn more at https://bit.ly/wb-precache`;console.warn(c)}}}install(e){return P(e,async()=>{const t=new A;this.strategy.plugins.push(t);for(const[i,r]of this._urlsToCacheKeys){const c=this._cacheKeysToIntegrities.get(r),o=this._urlsToCacheModes.get(i),h=new Request(i,{integrity:c,cache:o,credentials:"same-origin"});await Promise.all(this.strategy.handleAll({params:{cacheKey:r},request:h,event:e}))}const{updatedURLs:s,notUpdatedURLs:n}=t;return{updatedURLs:s,notUpdatedURLs:n}})}activate(e){return P(e,async()=>{const t=await self.caches.open(this.strategy.cacheName),s=await t.keys(),n=new Set(this._urlsToCacheKeys.values()),i=[];for(const r of s)n.has(r.url)||(await t.delete(r),i.push(r.url));return{deletedURLs:i}})}getURLsToCacheKeys(){return this._urlsToCacheKeys}getCachedURLs(){return[...this._urlsToCacheKeys.keys()]}getCacheKeyForURL(e){const t=new URL(e,location.href);return this._urlsToCacheKeys.get(t.href)}getIntegrityForCacheKey(e){return this._cacheKeysToIntegrities.get(e)}async matchPrecache(e){const t=e instanceof Request?e.url:e,s=this.getCacheKeyForURL(t);if(s)return(await self.caches.open(this.strategy.cacheName)).match(s)}createHandlerBoundToURL(e){const t=this.getCacheKeyForURL(e);if(!t)throw new l("non-precached-url",{url:e});return s=>(s.request=new Request(e),s.params=Object.assign({cacheKey:t},s.params),this.strategy.handle(s))}}let k;const v=()=>(k||(k=new G),k);try{self["workbox:routing:7.3.0"]&&_()}catch{}const T="GET",C=a=>a&&typeof a=="object"?a:{handle:a};class m{constructor(e,t,s=T){this.handler=C(t),this.match=e,this.method=s}setCatchHandler(e){this.catchHandler=C(e)}}class J extends m{constructor(e,t,s){const n=({url:i})=>{const r=e.exec(i.href);if(r&&!(i.origin!==location.origin&&r.index!==0))return r.slice(1)};super(n,t,s)}}class Q{constructor(){this._routes=new Map,this._defaultHandlerMap=new Map}get routes(){return this._routes}addFetchListener(){self.addEventListener("fetch",(e=>{const{request:t}=e,s=this.handleRequest({request:t,event:e});s&&e.respondWith(s)}))}addCacheListener(){self.addEventListener("message",(e=>{if(e.data&&e.data.type==="CACHE_URLS"){const{payload:t}=e.data,s=Promise.all(t.urlsToCache.map(n=>{typeof n=="string"&&(n=[n]);const i=new Request(...n);return this.handleRequest({request:i,event:e})}));e.waitUntil(s),e.ports&&e.ports[0]&&s.then(()=>e.ports[0].postMessage(!0))}}))}handleRequest({request:e,event:t}){const s=new URL(e.url,location.href);if(!s.protocol.startsWith("http"))return;const n=s.origin===location.origin,{params:i,route:r}=this.findMatchingRoute({event:t,request:e,sameOrigin:n,url:s});let c=r&&r.handler;const o=e.method;if(!c&&this._defaultHandlerMap.has(o)&&(c=this._defaultHandlerMap.get(o)),!c)return;let h;try{h=c.handle({url:s,request:e,event:t,params:i})}catch(u){h=Promise.reject(u)}const p=r&&r.catchHandler;return h instanceof Promise&&(this._catchHandler||p)&&(h=h.catch(async u=>{if(p)try{return await p.handle({url:s,request:e,event:t,params:i})}catch(g){g instanceof Error&&(u=g)}if(this._catchHandler)return this._catchHandler.handle({url:s,request:e,event:t});throw u})),h}findMatchingRoute({url:e,sameOrigin:t,request:s,event:n}){const i=this._routes.get(s.method)||[];for(const r of i){let c;const o=r.match({url:e,sameOrigin:t,request:s,event:n});if(o)return c=o,(Array.isArray(c)&&c.length===0||o.constructor===Object&&Object.keys(o).length===0||typeof o=="boolean")&&(c=void 0),{route:r,params:c}}return{}}setDefaultHandler(e,t=T){this._defaultHandlerMap.set(t,C(e))}setCatchHandler(e){this._catchHandler=C(e)}registerRoute(e){this._routes.has(e.method)||this._routes.set(e.method,[]),this._routes.get(e.method).push(e)}unregisterRoute(e){if(!this._routes.has(e.method))throw new l("unregister-route-but-not-found-with-method",{method:e.method});const t=this._routes.get(e.method).indexOf(e);if(t>-1)this._routes.get(e.method).splice(t,1);else throw new l("unregister-route-route-not-registered")}}let w;const z=()=>(w||(w=new Q,w.addFetchListener(),w.addCacheListener()),w);function X(a,e,t){let s;if(typeof a=="string"){const i=new URL(a,location.href),r=({url:c})=>c.href===i.href;s=new m(r,e,t)}else if(a instanceof RegExp)s=new J(a,e,t);else if(typeof a=="function")s=new m(a,e,t);else if(a instanceof m)s=a;else throw new l("unsupported-route-type",{moduleName:"workbox-routing",funcName:"registerRoute",paramName:"capture"});return z().registerRoute(s),s}function Y(a,e=[]){for(const t of[...a.searchParams.keys()])e.some(s=>s.test(t))&&a.searchParams.delete(t);return a}function*Z(a,{ignoreURLParametersMatching:e=[/^utm_/,/^fbclid$/],directoryIndex:t="index.html",cleanURLs:s=!0,urlManipulation:n}={}){const i=new URL(a,location.href);i.hash="",yield i.href;const r=Y(i,e);if(yield r.href,t&&r.pathname.endsWith("/")){const c=new URL(r.href);c.pathname+=t,yield c.href}if(s){const c=new URL(r.href);c.pathname+=".html",yield c.href}if(n){const c=n({url:i});for(const o of c)yield o.href}}class ee extends m{constructor(e,t){const s=({request:n})=>{const i=e.getURLsToCacheKeys();for(const r of Z(n.url,t)){const c=i.get(r);if(c){const o=e.getIntegrityForCacheKey(c);return{cacheKey:c,integrity:o}}}};super(s,e.strategy)}}function te(a){const e=v(),t=new ee(e,a);X(t)}function se(a){v().precache(a)}function ae(a,e){se(a),te(e)}ae([{"revision":"38013143dc2183340ede8bc1c5124507","url":"registerSW.js"},{"revision":"
|
|
2
|
+
This is generally NOT safe. Learn more at https://bit.ly/wb-precache`;console.warn(c)}}}install(e){return P(e,async()=>{const t=new A;this.strategy.plugins.push(t);for(const[i,r]of this._urlsToCacheKeys){const c=this._cacheKeysToIntegrities.get(r),o=this._urlsToCacheModes.get(i),h=new Request(i,{integrity:c,cache:o,credentials:"same-origin"});await Promise.all(this.strategy.handleAll({params:{cacheKey:r},request:h,event:e}))}const{updatedURLs:s,notUpdatedURLs:n}=t;return{updatedURLs:s,notUpdatedURLs:n}})}activate(e){return P(e,async()=>{const t=await self.caches.open(this.strategy.cacheName),s=await t.keys(),n=new Set(this._urlsToCacheKeys.values()),i=[];for(const r of s)n.has(r.url)||(await t.delete(r),i.push(r.url));return{deletedURLs:i}})}getURLsToCacheKeys(){return this._urlsToCacheKeys}getCachedURLs(){return[...this._urlsToCacheKeys.keys()]}getCacheKeyForURL(e){const t=new URL(e,location.href);return this._urlsToCacheKeys.get(t.href)}getIntegrityForCacheKey(e){return this._cacheKeysToIntegrities.get(e)}async matchPrecache(e){const t=e instanceof Request?e.url:e,s=this.getCacheKeyForURL(t);if(s)return(await self.caches.open(this.strategy.cacheName)).match(s)}createHandlerBoundToURL(e){const t=this.getCacheKeyForURL(e);if(!t)throw new l("non-precached-url",{url:e});return s=>(s.request=new Request(e),s.params=Object.assign({cacheKey:t},s.params),this.strategy.handle(s))}}let k;const v=()=>(k||(k=new G),k);try{self["workbox:routing:7.3.0"]&&_()}catch{}const T="GET",C=a=>a&&typeof a=="object"?a:{handle:a};class m{constructor(e,t,s=T){this.handler=C(t),this.match=e,this.method=s}setCatchHandler(e){this.catchHandler=C(e)}}class J extends m{constructor(e,t,s){const n=({url:i})=>{const r=e.exec(i.href);if(r&&!(i.origin!==location.origin&&r.index!==0))return r.slice(1)};super(n,t,s)}}class Q{constructor(){this._routes=new Map,this._defaultHandlerMap=new Map}get routes(){return this._routes}addFetchListener(){self.addEventListener("fetch",(e=>{const{request:t}=e,s=this.handleRequest({request:t,event:e});s&&e.respondWith(s)}))}addCacheListener(){self.addEventListener("message",(e=>{if(e.data&&e.data.type==="CACHE_URLS"){const{payload:t}=e.data,s=Promise.all(t.urlsToCache.map(n=>{typeof n=="string"&&(n=[n]);const i=new Request(...n);return this.handleRequest({request:i,event:e})}));e.waitUntil(s),e.ports&&e.ports[0]&&s.then(()=>e.ports[0].postMessage(!0))}}))}handleRequest({request:e,event:t}){const s=new URL(e.url,location.href);if(!s.protocol.startsWith("http"))return;const n=s.origin===location.origin,{params:i,route:r}=this.findMatchingRoute({event:t,request:e,sameOrigin:n,url:s});let c=r&&r.handler;const o=e.method;if(!c&&this._defaultHandlerMap.has(o)&&(c=this._defaultHandlerMap.get(o)),!c)return;let h;try{h=c.handle({url:s,request:e,event:t,params:i})}catch(u){h=Promise.reject(u)}const p=r&&r.catchHandler;return h instanceof Promise&&(this._catchHandler||p)&&(h=h.catch(async u=>{if(p)try{return await p.handle({url:s,request:e,event:t,params:i})}catch(g){g instanceof Error&&(u=g)}if(this._catchHandler)return this._catchHandler.handle({url:s,request:e,event:t});throw u})),h}findMatchingRoute({url:e,sameOrigin:t,request:s,event:n}){const i=this._routes.get(s.method)||[];for(const r of i){let c;const o=r.match({url:e,sameOrigin:t,request:s,event:n});if(o)return c=o,(Array.isArray(c)&&c.length===0||o.constructor===Object&&Object.keys(o).length===0||typeof o=="boolean")&&(c=void 0),{route:r,params:c}}return{}}setDefaultHandler(e,t=T){this._defaultHandlerMap.set(t,C(e))}setCatchHandler(e){this._catchHandler=C(e)}registerRoute(e){this._routes.has(e.method)||this._routes.set(e.method,[]),this._routes.get(e.method).push(e)}unregisterRoute(e){if(!this._routes.has(e.method))throw new l("unregister-route-but-not-found-with-method",{method:e.method});const t=this._routes.get(e.method).indexOf(e);if(t>-1)this._routes.get(e.method).splice(t,1);else throw new l("unregister-route-route-not-registered")}}let w;const z=()=>(w||(w=new Q,w.addFetchListener(),w.addCacheListener()),w);function X(a,e,t){let s;if(typeof a=="string"){const i=new URL(a,location.href),r=({url:c})=>c.href===i.href;s=new m(r,e,t)}else if(a instanceof RegExp)s=new J(a,e,t);else if(typeof a=="function")s=new m(a,e,t);else if(a instanceof m)s=a;else throw new l("unsupported-route-type",{moduleName:"workbox-routing",funcName:"registerRoute",paramName:"capture"});return z().registerRoute(s),s}function Y(a,e=[]){for(const t of[...a.searchParams.keys()])e.some(s=>s.test(t))&&a.searchParams.delete(t);return a}function*Z(a,{ignoreURLParametersMatching:e=[/^utm_/,/^fbclid$/],directoryIndex:t="index.html",cleanURLs:s=!0,urlManipulation:n}={}){const i=new URL(a,location.href);i.hash="",yield i.href;const r=Y(i,e);if(yield r.href,t&&r.pathname.endsWith("/")){const c=new URL(r.href);c.pathname+=t,yield c.href}if(s){const c=new URL(r.href);c.pathname+=".html",yield c.href}if(n){const c=n({url:i});for(const o of c)yield o.href}}class ee extends m{constructor(e,t){const s=({request:n})=>{const i=e.getURLsToCacheKeys();for(const r of Z(n.url,t)){const c=i.get(r);if(c){const o=e.getIntegrityForCacheKey(c);return{cacheKey:c,integrity:o}}}};super(s,e.strategy)}}function te(a){const e=v(),t=new ee(e,a);X(t)}function se(a){v().precache(a)}function ae(a,e){se(a),te(e)}ae([{"revision":"38013143dc2183340ede8bc1c5124507","url":"registerSW.js"},{"revision":"72e61c45190fd9b0bf0c835996fed5c6","url":"index.html"},{"revision":null,"url":"assets/index-_AmC1Rkn.css"},{"revision":null,"url":"assets/index-ByhOhTz1.js"},{"revision":"fcc457fce855ad0df7178e0786c0d4ef","url":"apple-touch-icon.png"},{"revision":"276650c30bc4effc7d649ec66519aab6","url":"favicon.ico"},{"revision":"2e46512b835c05e17787059909305f22","url":"pwa-192x192.png"},{"revision":"ec5652b5834b4711337743e80e506a41","url":"pwa-512x512.png"},{"revision":"9f51698004b9cc4d787c75695b74de9d","url":"manifest.webmanifest"}]);const ne="/api/push/respond";self.addEventListener("message",a=>{});self.addEventListener("push",a=>{var r;if(!a.data)return;let e;try{e=a.data.json()}catch{e={title:"Palmier",body:a.data.text()}}const t=e.type??((r=e.data)==null?void 0:r.type);if(t==="confirm-dismiss"||t==="permission-dismiss"||t==="input-dismiss"){const c=e.data??e,o=c.task_id,h=c.host_id;a.waitUntil(self.registration.getNotifications().then(p=>{var u,g;for(const b of p)((u=b.data)==null?void 0:u.task_id)===o&&((g=b.data)==null?void 0:g.host_id)===h&&b.close()}));return}const s=e.title??"Palmier";let n=e.body??"";!n&&t==="confirm"&&(n="A task requires confirmation to run."),!n&&t==="permission"&&(n="A task needs additional permissions to continue."),!n&&t==="input"&&(n="A task needs your input to continue.");const i={body:n,icon:"/pwa-192x192.png",badge:"/pwa-192x192.png",data:e.data??e,vibrate:[100,50,100]};t==="confirm"&&(i.actions=[{action:"confirm",title:"Confirm"},{action:"abort",title:"Abort"}]),a.waitUntil(self.registration.showNotification(s,i))});self.addEventListener("notificationclick",a=>{const e=a.notification;e.close();const t=e.data??{},s=a.action;if(s&&t.type==="confirm"&&t.task_id&&t.host_id){const n=s==="confirm"?"confirmed":"aborted";a.waitUntil(fetch(ne,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({type:t.type,task_id:t.task_id,host_id:t.host_id,response:n})}).catch(i=>{console.error("Failed to send push response:",i)}))}else{const n=t.task_id,i=t.run_id,r=n&&i?`/runs/${encodeURIComponent(n)}/${encodeURIComponent(i)}`:n?`/runs/${encodeURIComponent(n)}/latest`:"/";a.waitUntil(self.clients.matchAll({type:"window",includeUncontrolled:!0}).then(c=>{for(const o of c)if(o.url.includes(self.location.origin)&&"focus"in o)return o.navigate(r),o.focus();return self.clients.openWindow(r)}))}});self.addEventListener("install",()=>{self.skipWaiting()});self.addEventListener("activate",a=>{a.waitUntil(self.clients.claim())});
|
package/dist/rpc-handler.js
CHANGED
|
@@ -103,12 +103,13 @@ function parseAttr(attrs, name) {
|
|
|
103
103
|
async function generatePlan(projectRoot, userPrompt, agentName) {
|
|
104
104
|
const fullPrompt = PLAN_GENERATION_PROMPT + userPrompt;
|
|
105
105
|
const planAgent = getAgent(agentName);
|
|
106
|
-
const { command, args, stdin } = planAgent.getPlanGenerationCommandLine(fullPrompt);
|
|
106
|
+
const { command, args, stdin, env: agentEnv } = planAgent.getPlanGenerationCommandLine(fullPrompt);
|
|
107
107
|
console.log(`[generatePlan] Running: ${command} ${args.join(" ")}`);
|
|
108
108
|
const { output } = await spawnCommand(command, args, {
|
|
109
109
|
cwd: projectRoot,
|
|
110
110
|
timeout: 120_000,
|
|
111
111
|
stdin,
|
|
112
|
+
...(agentEnv ? { env: agentEnv } : {}),
|
|
112
113
|
});
|
|
113
114
|
let name = "";
|
|
114
115
|
const trimmed = output.trim();
|
|
@@ -355,12 +356,12 @@ export function createRpcHandler(config, nc) {
|
|
|
355
356
|
await publishHostEvent(nc, config.hostId, params.id, { event_type: "result-updated", run_id: params.run_id });
|
|
356
357
|
// Fire-and-forget: invoke agent inline as a child of the serve process
|
|
357
358
|
const followupAgent = getAgent(followupTask.frontmatter.agent);
|
|
358
|
-
const { command: cmd, args: cmdArgs, stdin } = followupAgent.getTaskRunCommandLine(followupTask, params.message, followupTask.frontmatter.yolo_mode ? "yolo" : followupTask.frontmatter.permissions);
|
|
359
|
+
const { command: cmd, args: cmdArgs, stdin, env: followupAgentEnv } = followupAgent.getTaskRunCommandLine(followupTask, params.message, followupTask.frontmatter.yolo_mode ? "yolo" : followupTask.frontmatter.permissions);
|
|
359
360
|
// Spawn directly via crossSpawn so we can track and kill the child
|
|
360
361
|
const child = crossSpawn(cmd, cmdArgs, {
|
|
361
362
|
cwd: followupRunDir,
|
|
362
363
|
stdio: [stdin != null ? "pipe" : "ignore", "pipe", "pipe"],
|
|
363
|
-
env: { ...process.env, PALMIER_TASK_ID: params.id },
|
|
364
|
+
env: { ...process.env, ...followupAgentEnv, PALMIER_TASK_ID: params.id },
|
|
364
365
|
windowsHide: true,
|
|
365
366
|
});
|
|
366
367
|
if (stdin != null)
|
|
@@ -204,13 +204,15 @@ export async function startHttpTransport(config, handleRpc, port, nc, pairingCod
|
|
|
204
204
|
}
|
|
205
205
|
try {
|
|
206
206
|
const body = await readBody(req);
|
|
207
|
-
const { title, body: notifBody } = JSON.parse(body);
|
|
207
|
+
const { taskId: notifTaskId, title, body: notifBody } = JSON.parse(body);
|
|
208
208
|
if (!title || !notifBody) {
|
|
209
209
|
sendJson(res, 400, { error: "title and body are required" });
|
|
210
210
|
return;
|
|
211
211
|
}
|
|
212
212
|
const sc = StringCodec();
|
|
213
213
|
const payload = { hostId: config.hostId, title, body: notifBody };
|
|
214
|
+
if (notifTaskId)
|
|
215
|
+
payload.task_id = notifTaskId;
|
|
214
216
|
const subject = `host.${config.hostId}.push.send`;
|
|
215
217
|
const reply = await nc.request(subject, sc.encode(JSON.stringify(payload)), { timeout: 15_000 });
|
|
216
218
|
const result = JSON.parse(sc.decode(reply.data));
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
|
8
8
|
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
|
9
9
|
<title>Palmier</title>
|
|
10
|
-
<meta name="description" content="
|
|
10
|
+
<meta name="description" content="Control AI agents running on your machine from any device. Schedule tasks, monitor runs, and stay in control." />
|
|
11
11
|
</head>
|
|
12
12
|
<body>
|
|
13
13
|
<div id="root"></div>
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** Bump when a breaking host change is made. */
|
|
2
|
-
export const MIN_HOST_VERSION = "0.
|
|
2
|
+
export const MIN_HOST_VERSION = "0.6.1";
|
|
@@ -107,10 +107,10 @@ self.addEventListener("notificationclick", (event) => {
|
|
|
107
107
|
// For task-complete/fail notifications, deep-link to the result view.
|
|
108
108
|
const taskId = data.task_id;
|
|
109
109
|
const runId = data.run_id;
|
|
110
|
-
const targetUrl = taskId && runId
|
|
110
|
+
const targetUrl = taskId && runId
|
|
111
111
|
? `/runs/${encodeURIComponent(taskId)}/${encodeURIComponent(runId)}`
|
|
112
|
-
: taskId
|
|
113
|
-
? `/runs/${encodeURIComponent(taskId)}`
|
|
112
|
+
: taskId
|
|
113
|
+
? `/runs/${encodeURIComponent(taskId)}/latest`
|
|
114
114
|
: "/";
|
|
115
115
|
|
|
116
116
|
event.waitUntil(
|
|
@@ -24,7 +24,7 @@ export default defineConfig({
|
|
|
24
24
|
manifest: {
|
|
25
25
|
name: "Palmier",
|
|
26
26
|
short_name: "Palmier",
|
|
27
|
-
description: "
|
|
27
|
+
description: "Control AI agents running on your machine from any device. Schedule tasks, monitor runs, and stay in control.",
|
|
28
28
|
start_url: "/",
|
|
29
29
|
display: "standalone",
|
|
30
30
|
background_color: "#ffffff",
|
|
@@ -132,6 +132,7 @@ async function main(): Promise<void> {
|
|
|
132
132
|
hostId: string;
|
|
133
133
|
title: string;
|
|
134
134
|
body: string;
|
|
135
|
+
task_id?: string;
|
|
135
136
|
};
|
|
136
137
|
|
|
137
138
|
// Validate hostId in subject matches payload
|
|
@@ -148,6 +149,7 @@ async function main(): Promise<void> {
|
|
|
148
149
|
type: "notification",
|
|
149
150
|
title: data.title,
|
|
150
151
|
body: data.body,
|
|
152
|
+
...(data.task_id ? { task_id: data.task_id } : {}),
|
|
151
153
|
});
|
|
152
154
|
|
|
153
155
|
if (msg.reply) {
|
package/palmier-server/spec.md
CHANGED
|
@@ -57,7 +57,7 @@ The daemon automatically recovers existing tasks by reinstalling their system ti
|
|
|
57
57
|
The `serve` daemon always starts an HTTP server on the configured port. Three access modes are available:
|
|
58
58
|
|
|
59
59
|
**Local mode** (always available):
|
|
60
|
-
- HTTP server binds to `127.0.0.1:<port>`. The PWA is accessible at `http://localhost:<port>` without pairing or internet. The serve daemon injects `window.__PALMIER_SERVE__=true` into the
|
|
60
|
+
- HTTP server binds to `127.0.0.1:<port>`. The PWA is accessible at `http://localhost:<port>` without pairing or internet. The PWA is bundled with the host package. The serve daemon injects `window.__PALMIER_SERVE__=true` into the HTML; the PWA detects this and auto-connects.
|
|
61
61
|
|
|
62
62
|
**LAN mode** (enabled during init):
|
|
63
63
|
- HTTP server binds to `0.0.0.0:<port>`, making the PWA accessible from the local network at `http://<host-ip>:<port>`. Non-localhost access requires pairing via a pairing code. Push notifications are not available.
|
|
@@ -28,7 +28,7 @@ The request blocks until the user responds. Response: `{"values":["answer1","ans
|
|
|
28
28
|
|
|
29
29
|
**Sending push notifications** — To notify the user, POST to `/notify` with:
|
|
30
30
|
```json
|
|
31
|
-
{"title":"...","body":"..."}
|
|
31
|
+
{"taskId":"{{TASK_ID}}","title":"...","body":"..."}
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
---
|