@lelouchhe/webagent 0.8.0 → 0.10.0
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/README.md +43 -15
- package/config.toml +7 -27
- package/dist/index.html +21 -5
- package/dist/js/app.INIQQEGD.js +5 -0
- package/dist/js/chunk.3CLGCUHW.js +1 -0
- package/dist/js/{chunk.CT5WBNGZ.js → chunk.7WADDFJZ.js} +50 -49
- package/dist/js/chunk.AOTG3PL7.js +20 -0
- package/dist/js/{login.2WA6DTGM.js → login.WMURU4NI.js} +1 -1
- package/dist/js/viewer.RHZMFYWJ.js +1 -0
- package/dist/login.html +2 -2
- package/dist/share-viewer.html +6 -6
- package/dist/{styles.00etlpgs.css → styles.01aj0l37.css} +186 -4
- package/dist/sw.js +6 -6
- package/lib/agent-key.js +6 -0
- package/lib/attachment-dispatch.js +60 -31
- package/lib/attachment-interceptor.js +7 -7
- package/lib/attachment-labels.js +1 -1
- package/lib/attachments.js +69 -7
- package/lib/auth-middleware.js +11 -4
- package/lib/auth.js +2 -2
- package/lib/bridge.js +209 -90
- package/lib/client-registry.js +12 -12
- package/lib/config.js +2 -31
- package/lib/event-handler.js +166 -85
- package/lib/files/limits.js +15 -0
- package/lib/files/paths.js +155 -0
- package/lib/files/routes.js +232 -0
- package/lib/home-path.js +35 -0
- package/lib/http-status.js +1 -0
- package/lib/mcp/capability.js +74 -0
- package/lib/mcp/server.js +148 -0
- package/lib/mcp/task-history.js +245 -0
- package/lib/mcp/task-host.js +253 -0
- package/lib/mcp/tools.js +168 -0
- package/lib/mode-bucket.js +1 -1
- package/lib/push-service.js +33 -35
- package/lib/routes.js +1022 -475
- package/lib/server.js +84 -34
- package/lib/share/routes.js +97 -85
- package/lib/shared/task-reference.js +20 -0
- package/lib/sse-manager.js +8 -8
- package/lib/store.js +992 -284
- package/lib/task-collaboration.js +15 -0
- package/lib/task-manager.js +1409 -0
- package/lib/task-path.js +131 -0
- package/lib/{session-state.js → task-state.js} +90 -38
- package/lib/task-tree-lock.js +74 -0
- package/lib/{sessions-anchor.js → tasks-anchor.js} +8 -7
- package/lib/tokens.js +1 -1
- package/lib/types.js +2 -2
- package/package.json +8 -1
- package/dist/js/app.XBFXH37R.js +0 -2
- package/dist/js/chunk.UMQMOGWO.js +0 -1
- package/dist/js/viewer.CVWXSKJM.js +0 -1
- package/lib/session-manager.js +0 -613
- package/lib/title-service.js +0 -95
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import"./chunk.AJZBJBMO.js";var C=class{diff(e,t,i={}){let r;typeof i=="function"?(r=i,i={}):"callback"in i&&(r=i.callback);let l=this.castInput(e,i),o=this.castInput(t,i),m=this.removeEmpty(this.tokenize(l,i)),d=this.removeEmpty(this.tokenize(o,i));return this.diffWithOptionsObj(m,d,i,r)}diffWithOptionsObj(e,t,i,r){var l;let o=u=>{if(u=this.postProcess(u,i),r){setTimeout(function(){r(u)},0);return}else return u},m=t.length,d=e.length,w=1,g=m+d;i.maxEditLength!=null&&(g=Math.min(g,i.maxEditLength));let x=(l=i.timeout)!==null&&l!==void 0?l:1/0,F=Date.now()+x,y=[{oldPos:-1,lastComponent:void 0}],f=this.extractCommon(y[0],t,e,0,i);if(y[0].oldPos+1>=d&&f+1>=m)return o(this.buildValues(y[0].lastComponent,t,e));let s=-1/0,c=1/0,h=()=>{for(let u=Math.max(s,-w);u<=Math.min(c,w);u+=2){let a,p=y[u-1],v=y[u+1];p&&(y[u-1]=void 0);let W=!1;if(v){let b=v.oldPos-u;W=v&&0<=b&&b<m}let N=p&&p.oldPos+1<d;if(!W&&!N){y[u]=void 0;continue}if(!N||W&&p.oldPos<v.oldPos?a=this.addToPath(v,!0,!1,0,i):a=this.addToPath(p,!1,!0,1,i),f=this.extractCommon(a,t,e,u,i),a.oldPos+1>=d&&f+1>=m)return o(this.buildValues(a.lastComponent,t,e))||!0;y[u]=a,a.oldPos+1>=d&&(c=Math.min(c,u-1)),f+1>=m&&(s=Math.max(s,u+1))}w++};if(r)(function u(){setTimeout(function(){if(w>g||Date.now()>F)return r(void 0);h()||u()},0)})();else for(;w<=g&&Date.now()<=F;){let u=h();if(u)return u}}addToPath(e,t,i,r,l){let o=e.lastComponent;return o&&!l.oneChangePerToken&&o.added===t&&o.removed===i?{oldPos:e.oldPos+r,lastComponent:{count:o.count+1,added:t,removed:i,previousComponent:o.previousComponent}}:{oldPos:e.oldPos+r,lastComponent:{count:1,added:t,removed:i,previousComponent:o}}}extractCommon(e,t,i,r,l){let o=t.length,m=i.length,d=e.oldPos,w=d-r,g=0;for(;w+1<o&&d+1<m&&this.equals(i[d+1],t[w+1],l);)w++,d++,g++,l.oneChangePerToken&&(e.lastComponent={count:1,previousComponent:e.lastComponent,added:!1,removed:!1});return g&&!l.oneChangePerToken&&(e.lastComponent={count:g,previousComponent:e.lastComponent,added:!1,removed:!1}),e.oldPos=d,w}equals(e,t,i){return i.comparator?i.comparator(e,t):e===t||!!i.ignoreCase&&e.toLowerCase()===t.toLowerCase()}removeEmpty(e){let t=[];for(let i=0;i<e.length;i++)e[i]&&t.push(e[i]);return t}castInput(e,t){return e}tokenize(e,t){return Array.from(e)}join(e){return e.join("")}postProcess(e,t){return e}get useLongestToken(){return!1}buildValues(e,t,i){let r=[],l;for(;e;)r.push(e),l=e.previousComponent,delete e.previousComponent,e=l;r.reverse();let o=r.length,m=0,d=0,w=0;for(;m<o;m++){let g=r[m];if(g.removed)g.value=this.join(i.slice(w,w+g.count)),w+=g.count;else{if(!g.added&&this.useLongestToken){let x=t.slice(d,d+g.count);x=x.map(function(F,y){let f=i[w+y];return f.length>F.length?f:F}),g.value=this.join(x)}else g.value=this.join(t.slice(d,d+g.count));d+=g.count,g.added||(w+=g.count)}}return r}};var R=class extends C{},oe=new R;function be(n,e,t){return oe.diff(n,e,t)}function _(n,e){let t;for(t=0;t<n.length&&t<e.length;t++)if(n[t]!=e[t])return n.slice(0,t);return n.slice(0,t)}function $(n,e){let t;if(!n||!e||n[n.length-1]!=e[e.length-1])return"";for(t=0;t<n.length&&t<e.length;t++)if(n[n.length-(t+1)]!=e[e.length-(t+1)])return n.slice(-t);return n.slice(-t)}function M(n,e,t){if(n.slice(0,e.length)!=e)throw Error(`string ${JSON.stringify(n)} doesn't start with prefix ${JSON.stringify(e)}; this is a bug`);return t+n.slice(e.length)}function H(n,e,t){if(!e)return n+t;if(n.slice(-e.length)!=e)throw Error(`string ${JSON.stringify(n)} doesn't end with suffix ${JSON.stringify(e)}; this is a bug`);return n.slice(0,-e.length)+t}function S(n,e){return M(n,e,"")}function D(n,e){return H(n,e,"")}function U(n,e){return e.slice(0,Ee(n,e))}function Ee(n,e){let t=0;n.length>e.length&&(t=n.length-e.length);let i=e.length;n.length<e.length&&(i=n.length);let r=Array(i),l=0;r[0]=0;for(let o=1;o<i;o++){for(e[o]==e[l]?r[o]=r[l]:r[o]=l;l>0&&e[o]!=e[l];)l=r[l];e[o]==e[l]&&l++}l=0;for(let o=t;o<n.length;o++){for(;l>0&&n[o]!=e[l];)l=r[l];n[o]==e[l]&&l++}return l}function se(n){return n.includes(`\r
|
|
2
|
+
`)&&!n.startsWith(`
|
|
3
|
+
`)&&!n.match(/[^\r]\n/)}function fe(n){return!n.includes(`\r
|
|
4
|
+
`)&&n.includes(`
|
|
5
|
+
`)}function q(n,e){let t=[];for(let i of Array.from(e.segment(n))){let r=i.segment;t.length&&/\s/.test(t[t.length-1])&&/\s/.test(r)?t[t.length-1]+=r:t.push(r)}return t}function P(n,e){if(e)return L(n,e)[1];let t;for(t=n.length-1;t>=0&&n[t].match(/\s/);t--);return n.substring(t+1)}function O(n,e){if(e)return L(n,e)[0];let t=n.match(/^\s*/);return t?t[0]:""}function L(n,e){if(!e)return[O(n),P(n)];if(e.resolvedOptions().granularity!="word")throw new Error('The segmenter passed must have a granularity of "word"');let t=q(n,e),i=t[0],r=t[t.length-1],l=/\s/.test(i)?i:"",o=/\s/.test(r)?r:"";return[l,o]}var T="a-zA-Z0-9_\\u{AD}\\u{C0}-\\u{D6}\\u{D8}-\\u{F6}\\u{F8}-\\u{2C6}\\u{2C8}-\\u{2D7}\\u{2DE}-\\u{2FF}\\u{1E00}-\\u{1EFF}",Oe=new RegExp(`[${T}]+|\\s+|[^${T}]`,"ug"),G=class extends C{equals(e,t,i){return i.ignoreCase&&(e=e.toLowerCase(),t=t.toLowerCase()),e.trim()===t.trim()}tokenize(e,t={}){let i;if(t.intlSegmenter){let o=t.intlSegmenter;if(o.resolvedOptions().granularity!="word")throw new Error('The segmenter passed must have a granularity of "word"');i=q(e,o)}else i=e.match(Oe)||[];let r=[],l=null;return i.forEach(o=>{/\s/.test(o)?l==null?r.push(o):r.push(r.pop()+o):l!=null&&/\s/.test(l)?r[r.length-1]==l?r.push(r.pop()+o):r.push(l+o):r.push(o),l=o}),r}join(e){return e.map((t,i)=>i==0?t:t.replace(/^\s+/,"")).join("")}postProcess(e,t){if(!e||t.oneChangePerToken)return e;let i=null,r=null,l=null;return e.forEach(o=>{o.added?r=o:o.removed?l=o:((r||l)&&ue(i,l,r,o,t.intlSegmenter),i=o,r=null,l=null)}),(r||l)&&ue(i,l,r,null,t.intlSegmenter),e}},ae=new G;function ke(n,e,t){return t?.ignoreWhitespace!=null&&!t.ignoreWhitespace?ce(n,e,t):ae.diff(n,e,t)}function ue(n,e,t,i,r){if(e&&t){let[l,o]=L(e.value,r),[m,d]=L(t.value,r);if(n){let w=_(l,m);n.value=H(n.value,m,w),e.value=S(e.value,w),t.value=S(t.value,w)}if(i){let w=$(o,d);i.value=M(i.value,d,w),e.value=D(e.value,w),t.value=D(t.value,w)}}else if(t){if(n){let l=O(t.value,r);t.value=t.value.substring(l.length)}if(i){let l=O(i.value,r);i.value=i.value.substring(l.length)}}else if(n&&i){let l=O(i.value,r),[o,m]=L(e.value,r),d=_(l,o);e.value=S(e.value,d);let w=$(S(l,d),m);e.value=D(e.value,w),i.value=M(i.value,l,w),n.value=H(n.value,l,l.slice(0,l.length-w.length))}else if(i){let l=O(i.value,r),o=P(e.value,r),m=U(o,l);e.value=D(e.value,m)}else if(n){let l=P(n.value,r),o=O(e.value,r),m=U(l,o);e.value=S(e.value,m)}}var J=class extends C{tokenize(e){let t=new RegExp(`(\\r?\\n)|[${T}]+|[^\\S\\n\\r]+|[^${T}]`,"ug");return e.match(t)||[]}},de=new J;function ce(n,e,t){return de.diff(n,e,t)}function me(n,e){if(typeof n=="function")e.callback=n;else if(n)for(let t in n)Object.prototype.hasOwnProperty.call(n,t)&&(e[t]=n[t]);return e}var V=class extends C{constructor(){super(...arguments),this.tokenize=Q}equals(e,t,i){return i.ignoreWhitespace?((!i.newlineIsToken||!e.includes(`
|
|
6
|
+
`))&&(e=e.trim()),(!i.newlineIsToken||!t.includes(`
|
|
7
|
+
`))&&(t=t.trim())):i.ignoreNewlineAtEof&&!i.newlineIsToken&&(e.endsWith(`
|
|
8
|
+
`)&&(e=e.slice(0,-1)),t.endsWith(`
|
|
9
|
+
`)&&(t=t.slice(0,-1))),super.equals(e,t,i)}},B=new V;function A(n,e,t){return B.diff(n,e,t)}function Se(n,e,t){return t=me(t,{ignoreWhitespace:!0}),B.diff(n,e,t)}function Q(n,e){e.stripTrailingCr&&(n=n.replace(/\r\n/g,`
|
|
10
|
+
`));let t=[],i=n.split(/(\n|\r\n)/);i[i.length-1]||i.pop();for(let r=0;r<i.length;r++){let l=i[r];r%2&&!e.newlineIsToken?t[t.length-1]+=l:t.push(l)}return t}function Le(n){return n=="."||n=="!"||n=="?"}var X=class extends C{tokenize(e){var t;let i=[],r=0;for(let l=0;l<e.length;l++){if(l==e.length-1){i.push(e.slice(r));break}if(Le(e[l])&&e[l+1].match(/\s/)){for(i.push(e.slice(r,l+1)),l=r=l+1;!((t=e[l+1])===null||t===void 0)&&t.match(/\s/);)l++;i.push(e.slice(r,l+1)),r=l+1}}return i}},he=new X;function De(n,e,t){return he.diff(n,e,t)}var Y=class extends C{tokenize(e){return e.split(/([{}:;,]|\s+)/)}},ge=new Y;function Me(n,e,t){return ge.diff(n,e,t)}var Z=class extends C{constructor(){super(...arguments),this.tokenize=Q}get useLongestToken(){return!0}castInput(e,t){let{undefinedReplacement:i,stringifyReplacer:r=(l,o)=>typeof o>"u"?i:o}=t;return typeof e=="string"?e:JSON.stringify(I(e,null,null,r),null," ")}equals(e,t,i){return super.equals(e.replace(/,([\r\n])/g,"$1"),t.replace(/,([\r\n])/g,"$1"),i)}},pe=new Z;function He(n,e,t){return pe.diff(n,e,t)}function I(n,e,t,i,r){e=e||[],t=t||[],i&&(n=i(r===void 0?"":r,n));let l;for(l=0;l<e.length;l+=1)if(e[l]===n)return t[l];let o;if(Object.prototype.toString.call(n)==="[object Array]"){for(e.push(n),o=new Array(n.length),t.push(o),l=0;l<n.length;l+=1)o[l]=I(n[l],e,t,i,String(l));return e.pop(),t.pop(),o}if(n&&n.toJSON&&(n=n.toJSON()),typeof n=="object"&&n!==null){e.push(n),o={},t.push(o);let m=[],d;for(d in n)Object.prototype.hasOwnProperty.call(n,d)&&m.push(d);for(m.sort(),l=0;l<m.length;l+=1)d=m[l],o[d]=I(n[d],e,t,i,d);e.pop(),t.pop()}else o=n;return o}var K=class extends C{tokenize(e){return e.slice()}join(e){return e}removeEmpty(e){return e}},we=new K;function Pe(n,e,t){return we.diff(n,e,t)}function ee(n){return Array.isArray(n)?n.map(e=>ee(e)):Object.assign(Object.assign({},n),{hunks:n.hunks.map(e=>Object.assign(Object.assign({},e),{lines:e.lines.map((t,i)=>{var r;return t.startsWith("\\")||t.endsWith("\r")||!((r=e.lines[i+1])===null||r===void 0)&&r.startsWith("\\")?t:t+"\r"})}))})}function ne(n){return Array.isArray(n)?n.map(e=>ne(e)):Object.assign(Object.assign({},n),{hunks:n.hunks.map(e=>Object.assign(Object.assign({},e),{lines:e.lines.map(t=>t.endsWith("\r")?t.substring(0,t.length-1):t)}))})}function xe(n){return Array.isArray(n)||(n=[n]),!n.some(e=>e.hunks.some(t=>t.lines.some(i=>!i.startsWith("\\")&&i.endsWith("\r"))))}function ve(n){return Array.isArray(n)||(n=[n]),n.some(e=>e.hunks.some(t=>t.lines.some(i=>i.endsWith("\r"))))&&n.every(e=>e.hunks.every(t=>t.lines.every((i,r)=>{var l;return i.startsWith("\\")||i.endsWith("\r")||((l=t.lines[r+1])===null||l===void 0?void 0:l.startsWith("\\"))})))}function z(n){let e=n.split(/\n/),t=[],i=0;function r(f){return/^diff --git /.test(f)}function l(f){return r(f)||/^Index:\s/.test(f)||/^diff(?: -r \w+)+\s/.test(f)}function o(f){return/^(---|\+\+\+)\s/.test(f)}function m(f){return/^@@\s/.test(f)}function d(){var f;let s={};s.hunks=[],t.push(s);let c=!1;for(;i<e.length;){let h=e[i];if(o(h)||m(h))break;if(r(h)){if(c)return;c=!0,s.isGit=!0;let u=w(h);for(u&&(s.oldFileName=u.oldFileName,s.newFileName=u.newFileName),i++;i<e.length;){let a=e[i];if(o(a)||m(a)||l(a))break;let p=/^rename from (.*)/.exec(a);p&&(s.oldFileName="a/"+g(p[1]),s.isRename=!0);let v=/^rename to (.*)/.exec(a);v&&(s.newFileName="b/"+g(v[1]),s.isRename=!0);let W=/^copy from (.*)/.exec(a);W&&(s.oldFileName="a/"+g(W[1]),s.isCopy=!0);let N=/^copy to (.*)/.exec(a);N&&(s.newFileName="b/"+g(N[1]),s.isCopy=!0);let b=/^new file mode (\d+)/.exec(a);b&&(s.isCreate=!0,s.newMode=b[1]);let k=/^deleted file mode (\d+)/.exec(a);k&&(s.isDelete=!0,s.oldMode=k[1]);let re=/^old mode (\d+)/.exec(a);re&&(s.oldMode=re[1]);let le=/^new mode (\d+)/.exec(a);le&&(s.newMode=le[1]),/^Binary files /.test(a)&&(s.isBinary=!0),i++}continue}else if(l(h)){if(c)return;c=!0;let u=/^(?:Index:|diff(?: -r \w+)+)\s+/.exec(h);u&&(s.index=h.substring(u[0].length).trim())}i++}if(F(s),F(s),s.oldFileName===void 0!=(s.newFileName===void 0))throw new Error("Missing "+(s.oldFileName!==void 0?'"+++ ..."':'"--- ..."')+" file header for "+((f=s.oldFileName)!==null&&f!==void 0?f:s.newFileName));for(;i<e.length;){let h=e[i];if(l(h)||o(h)||/^===================================================================/.test(h))break;m(h)?s.hunks.push(y()):i++}}function w(f){let s=f.substring(11);if(s.startsWith('"')){let h=x(s);if(h===null)return null;let u=s.substring(h.rawLength+1),a;if(u.startsWith('"')){let p=x(u);if(p===null)return null;a=p.fileName}else a=u;return{oldFileName:h.fileName,newFileName:a}}let c=s.indexOf('"');if(c>0){let h=s.substring(0,c-1),u=x(s.substring(c));return u===null?null:{oldFileName:h,newFileName:u.fileName}}if(s.startsWith("a/")){let h=[],u=0;for(;u=s.indexOf(" b/",u+1),u!==-1;)h.push(u);if(h.length>0){let a=h[Math.floor(h.length/2)];return{oldFileName:s.substring(0,a),newFileName:s.substring(a+1)}}}return null}function g(f){if(f.startsWith('"')){let s=x(f);if(s)return s.fileName}return f}function x(f){if(!f.startsWith('"'))return null;let s="",c=1;for(;c<f.length;){if(f[c]==='"')return{fileName:s,rawLength:c+1};if(f[c]==="\\"&&c+1<f.length)switch(c++,f[c]){case"a":s+="\x07";break;case"b":s+="\b";break;case"f":s+="\f";break;case"n":s+=`
|
|
11
|
+
`;break;case"r":s+="\r";break;case"t":s+=" ";break;case"v":s+="\v";break;case"\\":s+="\\";break;case'"':s+='"';break;case"0":case"1":case"2":case"3":case"4":case"5":case"6":case"7":{if(c+2>=f.length||f[c+1]<"0"||f[c+1]>"7"||f[c+2]<"0"||f[c+2]>"7")return null;let h=[parseInt(f.substring(c,c+3),8)];for(c+=3;f[c]==="\\"&&f[c+1]>="0"&&f[c+1]<="7";){if(c+3>=f.length||f[c+2]<"0"||f[c+2]>"7"||f[c+3]<"0"||f[c+3]>"7")return null;h.push(parseInt(f.substring(c+1,c+4),8)),c+=4}s+=new TextDecoder("utf-8").decode(new Uint8Array(h));continue}default:return null}else s+=f[c];c++}return null}function F(f){let s=/^(---|\+\+\+)\s+/.exec(e[i]);if(s){let c=s[1],h=e[i].substring(3).trim().split(" ",2),u=(h[1]||"").trim(),a=h[0];a.startsWith('"')?a=g(a):a=a.replace(/\\\\/g,"\\"),c==="---"?(f.oldFileName=a,f.oldHeader=u):(f.newFileName=a,f.newHeader=u),i++}}function y(){var f;let s=i,c=e[i++],h=c.split(/@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/),u={oldStart:+h[1],oldLines:typeof h[2]>"u"?1:+h[2],newStart:+h[3],newLines:typeof h[4]>"u"?1:+h[4],lines:[]};u.oldLines===0&&(u.oldStart+=1),u.newLines===0&&(u.newStart+=1);let a=0,p=0;for(;i<e.length&&(p<u.oldLines||a<u.newLines||!((f=e[i])===null||f===void 0)&&f.startsWith("\\"));i++){let v=e[i].length==0&&i!=e.length-1?" ":e[i][0];if(v==="+"||v==="-"||v===" "||v==="\\")u.lines.push(e[i]),v==="+"?a++:v==="-"?p++:v===" "&&(a++,p++);else throw new Error(`Hunk at line ${s+1} contained invalid line ${e[i]}`)}if(!a&&u.newLines===1&&(u.newLines=0),!p&&u.oldLines===1&&(u.oldLines=0),a!==u.newLines)throw new Error("Added line count did not match for hunk at line "+(s+1));if(p!==u.oldLines)throw new Error("Removed line count did not match for hunk at line "+(s+1));if(i<e.length&&e[i]&&/^[+ -]/.test(e[i])&&!o(e[i]))throw new Error("Hunk at line "+(s+1)+" has more lines than expected (expected "+u.oldLines+" old lines and "+u.newLines+" new lines)");return u}for(;i<e.length;)d();return t}function ye(n,e,t){let i=!0,r=!1,l=!1,o=1;return function m(){if(i&&!l){if(r?o++:i=!1,n+o<=t)return n+o;l=!0}if(!r)return l||(i=!0),e<=n-o?n-o++:(r=!0,m())}}function Fe(n,e,t={}){let i;if(typeof e=="string"?i=z(e):Array.isArray(e)?i=e:i=[e],i.length>1)throw new Error("applyPatch only works with a single input.");return Te(n,i[0],t)}function Te(n,e,t={}){(t.autoConvertLineEndings||t.autoConvertLineEndings==null)&&(se(n)&&xe(e)?e=ee(e):fe(n)&&ve(e)&&(e=ne(e)));let i=n.split(`
|
|
12
|
+
`),r=e.hunks,l=t.compareLine||((f,s,c,h)=>s===h),o=t.fuzzFactor||0,m=0;if(o<0||!Number.isInteger(o))throw new Error("fuzzFactor must be a non-negative integer");if(!r.length)return n;let d="",w=!1,g=!1;for(let f=0;f<r[r.length-1].lines.length;f++){let s=r[r.length-1].lines[f];s[0]=="\\"&&(d[0]=="+"?w=!0:d[0]=="-"&&(g=!0)),d=s}if(w){if(g){if(!o&&i[i.length-1]=="")return!1}else if(i[i.length-1]=="")i.pop();else if(!o)return!1}else if(g){if(i[i.length-1]!="")i.push("");else if(!o)return!1}function x(f,s,c,h=0,u=!0,a=[],p=0){let v=0,W=!1;for(;h<f.length;h++){let N=f[h],b=N.length>0?N[0]:" ",k=N.length>0?N.substr(1):N;if(b==="-")if(l(s+1,i[s],b,k))s++,v=0;else return!c||i[s]==null?null:(a[p]=i[s],x(f,s+1,c-1,h,!1,a,p+1));if(b==="+"){if(!u)return null;a[p]=k,p++,v=0,W=!0}if(b===" ")if(v++,a[p]=i[s],l(s+1,i[s],b,k))p++,u=!0,W=!1,s++;else return W||!c?null:i[s]&&(x(f,s+1,c-1,h+1,!1,a,p+1)||x(f,s+1,c-1,h,!1,a,p+1))||x(f,s,c-1,h+1,!1,a,p)}return p-=v,s-=v,a.length=p,{patchedLines:a,oldLineLastI:s-1}}let F=[],y=0;for(let f=0;f<r.length;f++){let s=r[f],c,h=i.length-s.oldLines+o,u;for(let a=0;a<=o;a++){u=s.oldStart+y-1;let p=ye(u,m,h);for(;u!==void 0&&(c=x(s.lines,u,a),!c);u=p());if(c)break}if(!c)return!1;for(let a=m;a<u;a++)F.push(i[a]);for(let a=0;a<c.patchedLines.length;a++){let p=c.patchedLines[a];F.push(p)}m=c.oldLineLastI+1,y=u+1-s.oldStart}for(let f=m;f<i.length;f++)F.push(i[f]);return F.join(`
|
|
13
|
+
`)}function Ae(n,e){let t=typeof n=="string"?z(n):n,i=0;function r(){let l=t[i++];if(!l)return e.complete();e.loadFile(l,function(o,m){if(o)return e.complete(o);let d=Fe(m,l,e);e.patched(l,d,function(w){if(w)return e.complete(w);r()})})}r()}function Ce(n){return n===void 0||n==="/dev/null"?n:n.startsWith("a/")?"b/"+n.slice(2):n.startsWith("b/")?"a/"+n.slice(2):n}function Ne(n){if(Array.isArray(n))return n.map(t=>Ne(t)).reverse();let e=Object.assign(Object.assign({},n),{oldFileName:n.isGit?Ce(n.newFileName):n.newFileName,oldHeader:n.newHeader,newFileName:n.isGit?Ce(n.oldFileName):n.oldFileName,newHeader:n.oldHeader,oldMode:n.newMode,newMode:n.oldMode,isCreate:n.isDelete,isDelete:n.isCreate,hunks:n.hunks.map(t=>({oldLines:t.newLines,oldStart:t.newStart,newLines:t.oldLines,newStart:t.oldStart,lines:t.lines.map(i=>i.startsWith("-")?`+${i.slice(1)}`:i.startsWith("+")?`-${i.slice(1)}`:i)}))});return n.isCopy&&(e.newFileName="/dev/null",e.newHeader=void 0,e.isDelete=!0,delete e.isCreate,delete e.isCopy,delete e.isRename,e.hunks=[]),e}function Ie(n){for(let e=0;e<n.length;e++)if(n[e]<" "||n[e]>"~"||n[e]==='"'||n[e]==="\\")return!0;return!1}function E(n){if(!Ie(n))return n;let e='"',t=new TextEncoder().encode(n),i=0;for(;i<t.length;){let r=t[i];r===7?e+="\\a":r===8?e+="\\b":r===9?e+="\\t":r===10?e+="\\n":r===11?e+="\\v":r===12?e+="\\f":r===13?e+="\\r":r===34?e+='\\"':r===92?e+="\\\\":r>=32&&r<=126?e+=String.fromCharCode(r):e+="\\"+r.toString(8).padStart(3,"0"),i++}return e+='"',e}var te={includeIndex:!0,includeUnderline:!0,includeFileHeaders:!0},ze={includeIndex:!1,includeUnderline:!1,includeFileHeaders:!0},je={includeIndex:!1,includeUnderline:!1,includeFileHeaders:!1};function ie(n,e,t,i,r,l,o){let m;o?typeof o=="function"?m={callback:o}:m=o:m={},typeof m.context>"u"&&(m.context=4);let d=m.context;if(m.newlineIsToken)throw new Error("newlineIsToken may not be used with patch-generation functions, only with diffing functions");if(m.callback){let{callback:g}=m;A(t,i,Object.assign(Object.assign({},m),{callback:x=>{let F=w(x);g(F)}}))}else return w(A(t,i,m));function w(g){if(!g)return;g.push({value:"",lines:[]});function x(u){return u.map(function(a){return" "+a})}let F=[],y=0,f=0,s=[],c=1,h=1;for(let u=0;u<g.length;u++){let a=g[u],p=a.lines||_e(a.value);if(a.lines=p,a.added||a.removed){if(!y){let v=g[u-1];y=c,f=h,v&&(s=d>0?x(v.lines.slice(-d)):[],y-=s.length,f-=s.length)}for(let v of p)s.push((a.added?"+":"-")+v);a.added?h+=p.length:c+=p.length}else{if(y)if(p.length<=d*2&&u<g.length-2)for(let v of x(p))s.push(v);else{let v=Math.min(p.length,d);for(let N of x(p.slice(0,v)))s.push(N);let W={oldStart:y,oldLines:c-y+v,newStart:f,newLines:h-f+v,lines:s};F.push(W),y=0,f=0,s=[]}c+=p.length,h+=p.length}}for(let u of F)for(let a=0;a<u.lines.length;a++)u.lines[a].endsWith(`
|
|
14
|
+
`)?u.lines[a]=u.lines[a].slice(0,-1):(u.lines.splice(a+1,0,"\"),a++);return{oldFileName:n,newFileName:e,oldHeader:r,newHeader:l,hunks:F}}}function j(n,e){var t,i,r,l,o,m;if(e||(e=te),Array.isArray(n)){if(n.length>1&&!e.includeFileHeaders&&!n.every(g=>g.isGit))throw new Error("Cannot omit file headers on a multi-file patch. (The result would be unparseable; how would a tool trying to apply the patch know which changes are to which file?)");return n.map(g=>j(g,e)).join(`
|
|
15
|
+
`)}let d=[];if(n.isGit){if(e=te,!n.oldFileName)throw new Error("oldFileName must be specified for Git patches");if(!n.newFileName)throw new Error("newFileName must be specified for Git patches");let g=n.oldFileName,x=n.newFileName;n.isCreate&&g==="/dev/null"?g=x.replace(/^b\//,"a/"):n.isDelete&&x==="/dev/null"&&(x=g.replace(/^a\//,"b/")),d.push("diff --git "+E(g)+" "+E(x)),n.isDelete&&d.push("deleted file mode "+((t=n.oldMode)!==null&&t!==void 0?t:"100644")),n.isCreate&&d.push("new file mode "+((i=n.newMode)!==null&&i!==void 0?i:"100644")),n.oldMode&&n.newMode&&!n.isDelete&&!n.isCreate&&(d.push("old mode "+n.oldMode),d.push("new mode "+n.newMode)),n.isRename&&(d.push("rename from "+E(((r=n.oldFileName)!==null&&r!==void 0?r:"").replace(/^a\//,""))),d.push("rename to "+E(((l=n.newFileName)!==null&&l!==void 0?l:"").replace(/^b\//,"")))),n.isCopy&&(d.push("copy from "+E(((o=n.oldFileName)!==null&&o!==void 0?o:"").replace(/^a\//,""))),d.push("copy to "+E(((m=n.newFileName)!==null&&m!==void 0?m:"").replace(/^b\//,""))))}else e.includeIndex&&n.oldFileName==n.newFileName&&n.oldFileName!==void 0&&d.push("Index: "+n.oldFileName),e.includeUnderline&&d.push("===================================================================");let w=n.hunks.length>0;e.includeFileHeaders&&n.oldFileName!==void 0&&n.newFileName!==void 0&&(!n.isGit||w)&&(d.push("--- "+E(n.oldFileName)+(n.oldHeader?" "+n.oldHeader:"")),d.push("+++ "+E(n.newFileName)+(n.newHeader?" "+n.newHeader:"")));for(let g=0;g<n.hunks.length;g++){let x=n.hunks[g],F=x.oldLines===0?x.oldStart-1:x.oldStart,y=x.newLines===0?x.newStart-1:x.newStart;d.push("@@ -"+F+","+x.oldLines+" +"+y+","+x.newLines+" @@");for(let f of x.lines)d.push(f)}return d.join(`
|
|
16
|
+
`)+`
|
|
17
|
+
`}function We(n,e,t,i,r,l,o){if(typeof o=="function"&&(o={callback:o}),o?.callback){let{callback:m}=o;ie(n,e,t,i,r,l,Object.assign(Object.assign({},o),{callback:d=>{m(d?j(d,o.headerOptions):void 0)}}))}else{let m=ie(n,e,t,i,r,l,o);return m?j(m,o?.headerOptions):void 0}}function Re(n,e,t,i,r,l){return We(n,n,e,t,i,r,l)}function _e(n){let e=n.endsWith(`
|
|
18
|
+
`),t=n.split(`
|
|
19
|
+
`).map(i=>i+`
|
|
20
|
+
`);return e?t.pop():t.push(t.pop().slice(0,-1)),t}function $e(n){let e=[],t,i;for(let r=0;r<n.length;r++)t=n[r],t.added?i=1:t.removed?i=-1:i=0,e.push([i,t.value]);return e}function Ue(n){let e=[];for(let t=0;t<n.length;t++){let i=n[t];i.added?e.push("<ins>"):i.removed&&e.push("<del>"),e.push(qe(i.value)),i.added?e.push("</ins>"):i.removed&&e.push("</del>")}return e.join("")}function qe(n){let e=n;return e=e.replace(/&/g,"&"),e=e.replace(/</g,"<"),e=e.replace(/>/g,">"),e=e.replace(/"/g,"""),e}export{C as Diff,ze as FILE_HEADERS_ONLY,te as INCLUDE_HEADERS,je as OMIT_HEADERS,Fe as applyPatch,Ae as applyPatches,we as arrayDiff,I as canonicalize,oe as characterDiff,$e as convertChangesToDMP,Ue as convertChangesToXML,Re as createPatch,We as createTwoFilesPatch,ge as cssDiff,Pe as diffArrays,be as diffChars,Me as diffCss,He as diffJson,A as diffLines,De as diffSentences,Se as diffTrimmedLines,ke as diffWords,ce as diffWordsWithSpace,j as formatPatch,pe as jsonDiff,B as lineDiff,z as parsePatch,Ne as reversePatch,he as sentenceDiff,ie as structuredPatch,ae as wordDiff,de as wordsWithSpaceDiff};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{b as r,c as i}from"./chunk.
|
|
1
|
+
import{b as r,c as i}from"./chunk.3CLGCUHW.js";import"./chunk.AJZBJBMO.js";localStorage.getItem(r)&&location.replace("/");var s=document.getElementById("login-form"),n=document.getElementById("token-input"),o=document.getElementById("error"),t=document.getElementById("submit-btn");function u(e){o&&(o.textContent=e,o.style.display=e?"block":"none")}s&&n&&t&&(s.addEventListener("submit",e=>{e.preventDefault(),u(""),t.disabled=!0,t.textContent="Verifying\u2026",(async()=>{try{let l=await i(n.value);l.ok?location.replace("/"):u(l.error)}finally{t.disabled=!1,t.textContent="Sign in"}})()}),n.focus());
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{c as g,e as h,n as y,p as T,q as C}from"./chunk.7WADDFJZ.js";import{a as p}from"./chunk.3CLGCUHW.js";import"./chunk.AJZBJBMO.js";var $=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];function f(t){return String(t).padStart(2,"0")}function E(t,n){if(!t)return"";let r=new Date(t),i=r.getTime();if(isNaN(i))return"";let l=Math.floor((n.getTime()-i)/1e3);if(l<60)return"just now";let c=Math.floor(l/60);if(c<60)return`${c}m ago`;let o=Math.floor(c/60);if(o<24)return`${o}h ago`;let e=Math.floor(o/24);if(e<7)return`${e}d ago`;let m=r.getUTCFullYear()===n.getUTCFullYear(),s=$[r.getUTCMonth()],a=r.getUTCDate();return m?`${s} ${a}`:`${s} ${a}, ${r.getUTCFullYear()}`}function _(t){if(!t)return"";let n=new Date(t);return isNaN(n.getTime())?"":`${n.getUTCFullYear()}-${f(n.getUTCMonth()+1)}-${f(n.getUTCDate())} ${f(n.getUTCHours())}:${f(n.getUTCMinutes())} UTC`}function S(t){let n=/^\/api\/v1\/tasks\/[^/]+\/attachments\/([A-Za-z0-9._-]+)(?:\?.*)?$/;return r=>{let i=n.exec(r);return i?`/s/${encodeURIComponent(t)}/attachments/${i[1]}`:r}}function w(t){if(typeof t.data=="string")try{return JSON.parse(t.data)}catch{return{}}return t.data}function x(t,n,r,i){if(t.type!=="assistant_message"||n?.type!=="assistant_message"||t.seq!==n.seq+1||!r?.classList.contains("assistant"))return!1;let l=(r.getAttribute("data-raw")??"")+(typeof i.text=="string"?i.text:"");return r.setAttribute("data-raw",l),C(r,l,void 0,!0),g(r),!0}function v(t,n,r){let i=new Set;for(let s of t)if(s.type==="permission_response")try{let a=JSON.parse(s.data);typeof a.requestId=="string"&&i.add(a.requestId)}catch{}let l=new Map,c=new Map,o=null,e=null,m={rewriteAttachmentSrc:S(r),enhanceMarkdown:g,findToolCallEl:s=>l.get(s)??null,findPermissionEl:s=>c.get(s)??null,findBashEl:()=>o,isPermissionResolved:s=>i.has(s),finalAnswerToolText:null};for(let s=0;s<t.length;s++){let a=t[s];if(!y(a.type))continue;let u=w(a),A=s>0?t[s-1]:null,M=n.lastElementChild;if(x(a,A,M,u)){e=null;continue}m.finalAnswerToolText=a.type==="assistant_message"?e:null;let d=T(a.type,u,m);d?(n.appendChild(d),a.type==="tool_call"&&typeof u.id=="string"?l.set(u.id,d):a.type==="permission_request"&&typeof u.requestId=="string"?c.set(u.requestId,d):a.type==="bash_command"&&(o=d)):a.type==="bash_result"&&(o=null),a.type==="tool_call_update"?e=h(typeof u.status=="string"?u.status:"",Array.isArray(u.content)?u.content:void 0):e=null}}async function k(){try{let e=localStorage.getItem("theme")??"auto";document.documentElement.setAttribute("data-theme",e)}catch{}let t=/^\/s\/([A-Za-z0-9_-]{24})(?:[/?#]|$)/.exec(location.pathname);if(!t){document.body.textContent="invalid share URL";return}let n=t[1],r=document.getElementById("task-info"),i=document.getElementById("messages"),l=document.querySelector(".share-footer-author"),c=document.querySelector(".share-footer-meta");if(!i)return;let o;try{let e=await fetch(`/api/v1/shared/${encodeURIComponent(n)}/events`,{headers:{Accept:"application/json"},credentials:"omit"});if(e.status===p.GONE){document.body.innerHTML="<div class='share-gone'>\u6B64\u94FE\u63A5\u5DF2\u64A4\u9500\u6216\u8FC7\u671F\u3002</div>";return}if(!e.ok){document.body.textContent=`error ${e.status}`;return}o=await e.json()}catch(e){document.body.textContent=`failed to load: ${String(e)}`;return}if(document.title=o.share.task_title?`${o.share.task_title} \u2014 shared`:"shared task",r&&(r.textContent=o.share.task_title??"(untitled)"),l){let e=o.share.display_name??"";l.textContent=e?`by ${e}`:""}if(v(o.events,i,n),c){let e=o.share.shared_at??o.share.created_at;c.textContent=E(e,new Date),c instanceof HTMLElement&&(c.title=_(e))}}k();
|
package/dist/login.html
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
media="(prefers-color-scheme: light)"
|
|
18
18
|
/>
|
|
19
19
|
<script src="/theme-init.js"></script>
|
|
20
|
-
<link rel="stylesheet" href="/styles.
|
|
20
|
+
<link rel="stylesheet" href="/styles.01aj0l37.css" />
|
|
21
21
|
</head>
|
|
22
22
|
<body class="login-page">
|
|
23
23
|
<div class="login-card">
|
|
@@ -44,6 +44,6 @@
|
|
|
44
44
|
<code>webagent --create-token <name></code> on the server.
|
|
45
45
|
</p>
|
|
46
46
|
</div>
|
|
47
|
-
<script type="module" src="/js/login.
|
|
47
|
+
<script type="module" src="/js/login.WMURU4NI.js"></script>
|
|
48
48
|
</body>
|
|
49
49
|
</html>
|
package/dist/share-viewer.html
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="utf-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
-
<title>shared
|
|
6
|
+
<title>shared task — >_</title>
|
|
7
7
|
<link rel="icon" href="/icons/icon.svg" type="image/svg+xml" />
|
|
8
8
|
<meta
|
|
9
9
|
name="theme-color"
|
|
@@ -16,10 +16,10 @@
|
|
|
16
16
|
media="(prefers-color-scheme: light)"
|
|
17
17
|
/>
|
|
18
18
|
<meta name="robots" content="noindex, nofollow" />
|
|
19
|
-
<link rel="stylesheet" href="/s/_/styles.
|
|
19
|
+
<link rel="stylesheet" href="/s/_/styles.01aj0l37.css" />
|
|
20
20
|
<link rel="stylesheet" href="/s/_/share-viewer.00gubshk.css" />
|
|
21
|
-
<link rel="modulepreload" href="/s/_/chunk.
|
|
22
|
-
<link rel="modulepreload" href="/s/_/chunk.
|
|
21
|
+
<link rel="modulepreload" href="/s/_/chunk.7WADDFJZ.js">
|
|
22
|
+
<link rel="modulepreload" href="/s/_/chunk.3CLGCUHW.js">
|
|
23
23
|
<link rel="modulepreload" href="/s/_/chunk.AJZBJBMO.js">
|
|
24
24
|
</head>
|
|
25
25
|
<body class="share-viewer">
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
<span class="logo">>_</span>
|
|
29
29
|
<span class="share-badge">shared</span>
|
|
30
30
|
</div>
|
|
31
|
-
<span id="
|
|
31
|
+
<span id="task-info" class="status"></span>
|
|
32
32
|
<div class="header-side header-right">
|
|
33
33
|
<button id="theme-btn" title="Toggle theme">◑</button>
|
|
34
34
|
</div>
|
|
@@ -49,6 +49,6 @@
|
|
|
49
49
|
>
|
|
50
50
|
</div>
|
|
51
51
|
</footer>
|
|
52
|
-
<script type="module" src="/s/_/viewer.
|
|
52
|
+
<script type="module" src="/s/_/viewer.RHZMFYWJ.js"></script>
|
|
53
53
|
</body>
|
|
54
54
|
</html>
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
--text: #c9d1d9;
|
|
6
6
|
--text-dim: #6e7681;
|
|
7
7
|
--accent: #58a6ff;
|
|
8
|
+
--system-accent: #bc8cff;
|
|
8
9
|
--green: #3fb950;
|
|
9
10
|
--yellow: #d29922;
|
|
10
11
|
--red: #f85149;
|
|
@@ -25,6 +26,7 @@
|
|
|
25
26
|
--text: #1f2328;
|
|
26
27
|
--text-dim: #656d76;
|
|
27
28
|
--accent: #0969da;
|
|
29
|
+
--system-accent: #8250df;
|
|
28
30
|
--green: #1a7f37;
|
|
29
31
|
--yellow: #9a6700;
|
|
30
32
|
--red: #cf222e;
|
|
@@ -43,6 +45,7 @@
|
|
|
43
45
|
--text: #1f2328;
|
|
44
46
|
--text-dim: #656d76;
|
|
45
47
|
--accent: #0969da;
|
|
48
|
+
--system-accent: #8250df;
|
|
46
49
|
--green: #1a7f37;
|
|
47
50
|
--yellow: #9a6700;
|
|
48
51
|
--red: #cf222e;
|
|
@@ -157,7 +160,7 @@ body {
|
|
|
157
160
|
opacity: 1;
|
|
158
161
|
}
|
|
159
162
|
}
|
|
160
|
-
#
|
|
163
|
+
#task-info {
|
|
161
164
|
overflow: hidden;
|
|
162
165
|
text-overflow: ellipsis;
|
|
163
166
|
white-space: nowrap;
|
|
@@ -165,7 +168,8 @@ body {
|
|
|
165
168
|
width: 100%;
|
|
166
169
|
text-align: center;
|
|
167
170
|
}
|
|
168
|
-
#theme-btn
|
|
171
|
+
#theme-btn,
|
|
172
|
+
#file-viewer-close {
|
|
169
173
|
background: transparent;
|
|
170
174
|
border: none;
|
|
171
175
|
color: var(--text-dim);
|
|
@@ -174,7 +178,8 @@ body {
|
|
|
174
178
|
font-family: inherit;
|
|
175
179
|
padding: 2px 6px;
|
|
176
180
|
}
|
|
177
|
-
#theme-btn:hover
|
|
181
|
+
#theme-btn:hover,
|
|
182
|
+
#file-viewer-close:hover {
|
|
178
183
|
color: var(--text);
|
|
179
184
|
}
|
|
180
185
|
@media (max-width: 640px) {
|
|
@@ -189,7 +194,7 @@ body {
|
|
|
189
194
|
.header-right {
|
|
190
195
|
margin-left: auto;
|
|
191
196
|
}
|
|
192
|
-
#
|
|
197
|
+
#task-info {
|
|
193
198
|
flex: 1 1 auto;
|
|
194
199
|
text-align: left;
|
|
195
200
|
}
|
|
@@ -426,6 +431,20 @@ body {
|
|
|
426
431
|
color: var(--text-dim);
|
|
427
432
|
white-space: pre-wrap;
|
|
428
433
|
}
|
|
434
|
+
.system-msg.expandable {
|
|
435
|
+
padding-top: 4px;
|
|
436
|
+
padding-bottom: 4px;
|
|
437
|
+
border-left: 2px solid var(--system-accent);
|
|
438
|
+
}
|
|
439
|
+
.system-msg.expandable summary {
|
|
440
|
+
cursor: pointer;
|
|
441
|
+
color: var(--system-accent);
|
|
442
|
+
}
|
|
443
|
+
.system-msg-body {
|
|
444
|
+
margin: 4px 0 2px 16px;
|
|
445
|
+
color: var(--text);
|
|
446
|
+
white-space: pre-wrap;
|
|
447
|
+
}
|
|
429
448
|
.system-msg a {
|
|
430
449
|
color: var(--accent);
|
|
431
450
|
text-decoration: underline;
|
|
@@ -748,7 +767,25 @@ body {
|
|
|
748
767
|
#status-bar::before {
|
|
749
768
|
content: "\200b";
|
|
750
769
|
}
|
|
770
|
+
#status-bar .status-model {
|
|
771
|
+
flex: 0 0 auto;
|
|
772
|
+
}
|
|
773
|
+
#status-bar .status-separator,
|
|
774
|
+
#status-bar .status-usage {
|
|
775
|
+
flex: 0 0 auto;
|
|
776
|
+
}
|
|
751
777
|
#status-bar .status-cwd {
|
|
778
|
+
display: flex;
|
|
779
|
+
flex: 1 1 auto;
|
|
780
|
+
min-width: 0;
|
|
781
|
+
overflow: hidden;
|
|
782
|
+
}
|
|
783
|
+
#status-bar .status-cwd-prefix {
|
|
784
|
+
flex: 0 0 auto;
|
|
785
|
+
}
|
|
786
|
+
#status-bar .status-cwd-tail {
|
|
787
|
+
flex: 1 1 auto;
|
|
788
|
+
min-width: 0;
|
|
752
789
|
overflow: hidden;
|
|
753
790
|
text-overflow: ellipsis;
|
|
754
791
|
direction: rtl;
|
|
@@ -990,6 +1027,151 @@ body {
|
|
|
990
1027
|
cursor: default;
|
|
991
1028
|
}
|
|
992
1029
|
|
|
1030
|
+
/* Read-only file viewer */
|
|
1031
|
+
#file-viewer[hidden] {
|
|
1032
|
+
display: none;
|
|
1033
|
+
}
|
|
1034
|
+
#file-viewer {
|
|
1035
|
+
position: fixed;
|
|
1036
|
+
inset: 0;
|
|
1037
|
+
z-index: 100;
|
|
1038
|
+
min-width: 0;
|
|
1039
|
+
background: var(--bg);
|
|
1040
|
+
color: var(--text);
|
|
1041
|
+
display: flex;
|
|
1042
|
+
flex-direction: column;
|
|
1043
|
+
}
|
|
1044
|
+
body.file-viewer-open {
|
|
1045
|
+
overflow: hidden;
|
|
1046
|
+
}
|
|
1047
|
+
.file-viewer-header {
|
|
1048
|
+
min-height: 41px;
|
|
1049
|
+
padding: 6px 16px;
|
|
1050
|
+
background: var(--surface);
|
|
1051
|
+
border-bottom: 1px solid var(--border);
|
|
1052
|
+
display: flex;
|
|
1053
|
+
align-items: center;
|
|
1054
|
+
gap: 12px;
|
|
1055
|
+
font-size: 15px;
|
|
1056
|
+
}
|
|
1057
|
+
#file-viewer-path {
|
|
1058
|
+
min-width: 0;
|
|
1059
|
+
flex: 1;
|
|
1060
|
+
overflow: hidden;
|
|
1061
|
+
text-overflow: ellipsis;
|
|
1062
|
+
white-space: nowrap;
|
|
1063
|
+
direction: ltr;
|
|
1064
|
+
text-align: left;
|
|
1065
|
+
color: var(--text-dim);
|
|
1066
|
+
font-size: inherit;
|
|
1067
|
+
}
|
|
1068
|
+
#file-viewer-close {
|
|
1069
|
+
flex: 0 0 auto;
|
|
1070
|
+
}
|
|
1071
|
+
#file-viewer-notice {
|
|
1072
|
+
flex: 0 0 auto;
|
|
1073
|
+
padding: 6px 14px;
|
|
1074
|
+
border-bottom: 1px solid var(--border);
|
|
1075
|
+
color: var(--yellow);
|
|
1076
|
+
font-size: 13px;
|
|
1077
|
+
}
|
|
1078
|
+
#file-viewer-notice[hidden] {
|
|
1079
|
+
display: none;
|
|
1080
|
+
}
|
|
1081
|
+
#file-viewer-content {
|
|
1082
|
+
flex: 1 1 auto;
|
|
1083
|
+
min-height: 0;
|
|
1084
|
+
overflow: auto;
|
|
1085
|
+
padding-bottom: env(safe-area-inset-bottom);
|
|
1086
|
+
}
|
|
1087
|
+
.file-viewer-markdown {
|
|
1088
|
+
width: 100%;
|
|
1089
|
+
min-height: 100%;
|
|
1090
|
+
}
|
|
1091
|
+
.file-viewer-image {
|
|
1092
|
+
display: block;
|
|
1093
|
+
max-width: 100%;
|
|
1094
|
+
max-height: 100%;
|
|
1095
|
+
margin: auto;
|
|
1096
|
+
padding: 12px;
|
|
1097
|
+
object-fit: contain;
|
|
1098
|
+
}
|
|
1099
|
+
.file-viewer-code-scroll {
|
|
1100
|
+
min-height: 100%;
|
|
1101
|
+
min-width: max-content;
|
|
1102
|
+
}
|
|
1103
|
+
.file-viewer-code-grid {
|
|
1104
|
+
display: grid;
|
|
1105
|
+
grid-template-columns: max-content minmax(max-content, 1fr);
|
|
1106
|
+
width: max-content;
|
|
1107
|
+
min-width: 100%;
|
|
1108
|
+
min-height: 100%;
|
|
1109
|
+
}
|
|
1110
|
+
.file-viewer-line-numbers,
|
|
1111
|
+
.file-viewer-code {
|
|
1112
|
+
margin: 0;
|
|
1113
|
+
padding: 10px 12px;
|
|
1114
|
+
border: 0;
|
|
1115
|
+
border-radius: 0;
|
|
1116
|
+
background: var(--bg);
|
|
1117
|
+
color: var(--text);
|
|
1118
|
+
font:
|
|
1119
|
+
14px/1.55 "SF Mono",
|
|
1120
|
+
"Fira Code",
|
|
1121
|
+
monospace;
|
|
1122
|
+
white-space: pre;
|
|
1123
|
+
}
|
|
1124
|
+
.file-viewer-line-numbers {
|
|
1125
|
+
position: sticky;
|
|
1126
|
+
left: 0;
|
|
1127
|
+
z-index: 1;
|
|
1128
|
+
padding-right: 8px;
|
|
1129
|
+
background: var(--surface);
|
|
1130
|
+
border-right: 1px solid var(--border);
|
|
1131
|
+
color: var(--text-dim);
|
|
1132
|
+
text-align: right;
|
|
1133
|
+
user-select: none;
|
|
1134
|
+
}
|
|
1135
|
+
.file-viewer-code {
|
|
1136
|
+
padding-left: 12px;
|
|
1137
|
+
}
|
|
1138
|
+
.file-viewer-code code,
|
|
1139
|
+
.file-viewer-code code.hljs {
|
|
1140
|
+
padding: 0;
|
|
1141
|
+
background: transparent;
|
|
1142
|
+
font: inherit;
|
|
1143
|
+
}
|
|
1144
|
+
.file-viewer-binary-meta {
|
|
1145
|
+
padding: 18px 14px 10px;
|
|
1146
|
+
color: var(--text-dim);
|
|
1147
|
+
overflow-wrap: anywhere;
|
|
1148
|
+
}
|
|
1149
|
+
.file-viewer-download {
|
|
1150
|
+
display: inline-flex;
|
|
1151
|
+
min-height: 44px;
|
|
1152
|
+
margin: 0 14px;
|
|
1153
|
+
padding: 8px 12px;
|
|
1154
|
+
border: 1px solid var(--border);
|
|
1155
|
+
border-radius: var(--radius);
|
|
1156
|
+
align-items: center;
|
|
1157
|
+
color: var(--accent);
|
|
1158
|
+
text-decoration: none;
|
|
1159
|
+
}
|
|
1160
|
+
.file-viewer-download:hover,
|
|
1161
|
+
.file-viewer-download:focus-visible {
|
|
1162
|
+
border-color: var(--accent);
|
|
1163
|
+
}
|
|
1164
|
+
@media (min-width: 1024px) {
|
|
1165
|
+
body.file-viewer-open {
|
|
1166
|
+
padding-right: min(55vw, 800px);
|
|
1167
|
+
}
|
|
1168
|
+
#file-viewer {
|
|
1169
|
+
left: auto;
|
|
1170
|
+
width: min(55vw, 800px);
|
|
1171
|
+
border-left: 1px solid var(--border);
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1174
|
+
|
|
993
1175
|
/* Image attach */
|
|
994
1176
|
#attach-preview {
|
|
995
1177
|
display: none;
|
package/dist/sw.js
CHANGED
|
@@ -31,7 +31,7 @@ self.addEventListener("push", (e) => {
|
|
|
31
31
|
|
|
32
32
|
// Backward-compat: older payloads had no `kind`. Treat as notify.
|
|
33
33
|
const { title, body, tag, data } = payload;
|
|
34
|
-
const finalTag = tag || data?.
|
|
34
|
+
const finalTag = tag || data?.taskId || "default";
|
|
35
35
|
e.waitUntil(showNotify(title, body, finalTag, data));
|
|
36
36
|
});
|
|
37
37
|
|
|
@@ -79,15 +79,15 @@ self.addEventListener("notificationclick", (e) => {
|
|
|
79
79
|
e.notification.close();
|
|
80
80
|
|
|
81
81
|
const data = e.notification.data || {};
|
|
82
|
-
const
|
|
82
|
+
const taskId = data.taskId;
|
|
83
83
|
const messageId = data.messageId;
|
|
84
|
-
const target =
|
|
85
|
-
? { type: "navigate",
|
|
84
|
+
const target = taskId
|
|
85
|
+
? { type: "navigate", taskId }
|
|
86
86
|
: messageId
|
|
87
87
|
? { type: "navigate", messageId }
|
|
88
88
|
: { type: "navigate" };
|
|
89
|
-
const targetUrl =
|
|
90
|
-
? `/#${encodeURIComponent(
|
|
89
|
+
const targetUrl = taskId
|
|
90
|
+
? `/#${encodeURIComponent(taskId)}`
|
|
91
91
|
: messageId
|
|
92
92
|
? `/?message=${encodeURIComponent(messageId)}`
|
|
93
93
|
: "/";
|
package/lib/agent-key.js
ADDED
|
@@ -1,33 +1,38 @@
|
|
|
1
1
|
import { readFile, realpath } from "node:fs/promises";
|
|
2
2
|
import { pathToFileURL } from "node:url";
|
|
3
|
-
import {
|
|
3
|
+
import { isUpstreamImageMime } from "./attachments.js";
|
|
4
|
+
import { isInsideTaskAttachments } from "./tasks-anchor.js";
|
|
4
5
|
const NOOP_LOGGER = { warn: () => { } };
|
|
5
6
|
/**
|
|
6
|
-
* Builds the ACP prompt
|
|
7
|
+
* Builds the ACP prompt blocks for one client-supplied attachment. Returns
|
|
7
8
|
* a fallback text block on any failure (DB miss, disk miss, anchor breach,
|
|
8
|
-
* cross-
|
|
9
|
+
* cross-task reference) so the prompt turn never gets stuck in a retry
|
|
9
10
|
* loop just because one image vanished.
|
|
10
11
|
*
|
|
11
12
|
* Trust boundary (decision 10 in uploads-plan v2.6): client only supplies
|
|
12
13
|
* `attachmentId`. Everything else (realpath, anchor, MIME for read) comes
|
|
13
|
-
* from the server-side row
|
|
14
|
+
* from the server-side row — including whether the payload is an image and
|
|
15
|
+
* whether its mime is one the upstream model accepts. A client cannot
|
|
16
|
+
* change the wire format by mislabelling the attachment.
|
|
14
17
|
*/
|
|
15
18
|
export class AttachmentDispatcher {
|
|
16
19
|
store;
|
|
17
|
-
|
|
20
|
+
tasksAnchor;
|
|
18
21
|
logger;
|
|
19
|
-
constructor(store,
|
|
22
|
+
constructor(store, tasksAnchor, logger = NOOP_LOGGER) {
|
|
20
23
|
this.store = store;
|
|
21
|
-
this.
|
|
24
|
+
this.tasksAnchor = tasksAnchor;
|
|
22
25
|
this.logger = logger;
|
|
23
26
|
}
|
|
24
|
-
async dispatch(
|
|
27
|
+
async dispatch(taskId, ref) {
|
|
25
28
|
const fallback = (reason) => {
|
|
26
|
-
this.logger.warn(`[attachments] dispatch fallback (${reason}) for ${
|
|
27
|
-
return
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
this.logger.warn(`[attachments] dispatch fallback (${reason}) for ${taskId}/${ref.attachmentId}`);
|
|
30
|
+
return [
|
|
31
|
+
{
|
|
32
|
+
type: "text",
|
|
33
|
+
text: `[attachment removed: ${ref.displayName}]`,
|
|
34
|
+
},
|
|
35
|
+
];
|
|
31
36
|
};
|
|
32
37
|
// Reject any client trying to smuggle a uri / data / path. The shape
|
|
33
38
|
// of AttachmentRef already forbids these statically; this guard is a
|
|
@@ -38,18 +43,18 @@ export class AttachmentDispatcher {
|
|
|
38
43
|
typeof wider.path === "string") {
|
|
39
44
|
return fallback("client_supplied_external_field");
|
|
40
45
|
}
|
|
41
|
-
const row = this.store.getAttachment(
|
|
46
|
+
const row = this.store.getAttachment(taskId, ref.attachmentId);
|
|
42
47
|
if (!row)
|
|
43
48
|
return fallback("row_not_found");
|
|
44
|
-
// Cross-
|
|
45
|
-
// store.getAttachment scopes by
|
|
49
|
+
// Cross-task reference — the row exists but for a DIFFERENT task.
|
|
50
|
+
// store.getAttachment scopes by task_id so this should already be
|
|
46
51
|
// caught by row_not_found, but assert defensively.
|
|
47
|
-
if (row.
|
|
48
|
-
return fallback("
|
|
52
|
+
if (row.task_id !== taskId) {
|
|
53
|
+
return fallback("cross_task");
|
|
49
54
|
}
|
|
50
55
|
// Anchor check on the stored realpath. If the file was moved out from
|
|
51
56
|
// under us, or a future bug let an attacker inject a row with a path
|
|
52
|
-
// outside
|
|
57
|
+
// outside TASKS_ANCHOR/<sid>/attachments/, we MUST refuse to dispatch
|
|
53
58
|
// it as a `file://` URI — the agent would happily read it.
|
|
54
59
|
let resolvedPath;
|
|
55
60
|
try {
|
|
@@ -58,24 +63,48 @@ export class AttachmentDispatcher {
|
|
|
58
63
|
catch {
|
|
59
64
|
return fallback("realpath_failed");
|
|
60
65
|
}
|
|
61
|
-
if (!
|
|
66
|
+
if (!isInsideTaskAttachments(this.tasksAnchor, taskId, resolvedPath)) {
|
|
62
67
|
return fallback("path_outside_anchor");
|
|
63
68
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
69
|
+
// Storage truth, not the client's `ref.kind`: the browser guesses the
|
|
70
|
+
// mime from the file extension / OS registry (renaming IMG_1040.HEIC to
|
|
71
|
+
// .jpg makes it claim image/jpeg), while `row.kind` is what the sniff on
|
|
72
|
+
// upload produced.
|
|
73
|
+
if (row.kind === "image") {
|
|
74
|
+
if (isUpstreamImageMime(row.mime)) {
|
|
75
|
+
try {
|
|
76
|
+
const buf = await readFile(resolvedPath);
|
|
77
|
+
return [
|
|
78
|
+
{
|
|
79
|
+
type: "image",
|
|
80
|
+
data: buf.toString("base64"),
|
|
81
|
+
mimeType: row.mime,
|
|
82
|
+
},
|
|
83
|
+
];
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return fallback("read_failed");
|
|
87
|
+
}
|
|
75
88
|
}
|
|
89
|
+
// Image container the upstream model rejects (heic/heif/avif/bmp/
|
|
90
|
+
// tiff and other `image/*` containers — note an SVG sniffs as text,
|
|
91
|
+
// so it never reaches this branch). Sending it as an image block
|
|
92
|
+
// poisons the session history: the provider 400s on every later turn
|
|
93
|
+
// too. Degrade to a file link plus a hint instead.
|
|
94
|
+
this.logger.warn(`[attachments] image downgraded to resource_link (mime=${row.mime}) for ${taskId}/${ref.attachmentId}`);
|
|
95
|
+
return [
|
|
96
|
+
{
|
|
97
|
+
type: "text",
|
|
98
|
+
text: `[attachment ${row.name} (${row.mime}) cannot be read as an inline image by the model; convert it to png or jpeg to make it readable]`,
|
|
99
|
+
},
|
|
100
|
+
this.resourceLink(row, resolvedPath),
|
|
101
|
+
];
|
|
76
102
|
}
|
|
77
103
|
// kind === "file" → ACP resource_link with file:// URI built from the
|
|
78
104
|
// realpath (NOT from any client-supplied string).
|
|
105
|
+
return [this.resourceLink(row, resolvedPath)];
|
|
106
|
+
}
|
|
107
|
+
resourceLink(row, resolvedPath) {
|
|
79
108
|
return {
|
|
80
109
|
type: "resource_link",
|
|
81
110
|
uri: pathToFileURL(resolvedPath).toString(),
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
//
|
|
3
3
|
// Plan §1.4 (uploads-plan v2.6, lines 105-183). When an agent requests
|
|
4
4
|
// permission to *read* a path that we know is one of the user-uploaded
|
|
5
|
-
//
|
|
5
|
+
// task attachments, auto-approve with `allow_once`. Any deviation
|
|
6
6
|
// from the strict allowlist falls through to the user prompt.
|
|
7
7
|
//
|
|
8
8
|
// Defenses (mirrored from the plan):
|
|
9
9
|
// F1 kind === "read" only
|
|
10
|
-
// F2 every locations[].path realpath ∈
|
|
10
|
+
// F2 every locations[].path realpath ∈ task attachment realpaths
|
|
11
11
|
// F4 schema gate — locations must exist; if rawInput has known path
|
|
12
12
|
// keys they must also realpath into the attachment set; if it has
|
|
13
13
|
// none, allow but bump schemaDrift counter so we notice when the
|
|
@@ -67,7 +67,7 @@ async function checkRawInputPaths(raw, attachmentRealpaths, miss) {
|
|
|
67
67
|
}
|
|
68
68
|
/**
|
|
69
69
|
* Returns true iff the request matches the strict
|
|
70
|
-
* "agent reading a known
|
|
70
|
+
* "agent reading a known task attachment" pattern.
|
|
71
71
|
*
|
|
72
72
|
* Returning false does NOT deny the user prompt — it just declines to
|
|
73
73
|
* auto-approve, so the normal permission UI continues to render.
|
|
@@ -79,7 +79,7 @@ export async function shouldAutoApproveAttachmentRead(ev, deps) {
|
|
|
79
79
|
counters.fellThrough++;
|
|
80
80
|
log.debug?.("attachment auto-allow miss", {
|
|
81
81
|
reason,
|
|
82
|
-
|
|
82
|
+
taskId: ev.taskId,
|
|
83
83
|
toolKind: ev.toolKind,
|
|
84
84
|
toolName: ev.toolName,
|
|
85
85
|
});
|
|
@@ -96,11 +96,11 @@ export async function shouldAutoApproveAttachmentRead(ev, deps) {
|
|
|
96
96
|
}
|
|
97
97
|
let attachmentRealpaths;
|
|
98
98
|
try {
|
|
99
|
-
attachmentRealpaths = new Set(deps.listAttachmentRealpaths(ev.
|
|
99
|
+
attachmentRealpaths = new Set(deps.listAttachmentRealpaths(ev.taskId));
|
|
100
100
|
}
|
|
101
101
|
catch (e) {
|
|
102
102
|
log.warn?.("attachment interceptor db error", {
|
|
103
|
-
|
|
103
|
+
taskId: ev.taskId,
|
|
104
104
|
error: e.message,
|
|
105
105
|
});
|
|
106
106
|
return miss("db_error");
|
|
@@ -121,7 +121,7 @@ export async function shouldAutoApproveAttachmentRead(ev, deps) {
|
|
|
121
121
|
}
|
|
122
122
|
counters.autoAllowed++;
|
|
123
123
|
log.info?.("attachment auto-allowed", {
|
|
124
|
-
|
|
124
|
+
taskId: ev.taskId,
|
|
125
125
|
toolKind: ev.toolKind,
|
|
126
126
|
toolName: ev.toolName,
|
|
127
127
|
locations: ev.locations.map((l) => l.path),
|
package/lib/attachment-labels.js
CHANGED
|
@@ -109,7 +109,7 @@ export function enrichStoredEventDataForDisplay(type, data, map) {
|
|
|
109
109
|
return data;
|
|
110
110
|
}
|
|
111
111
|
// Synthesize a minimal event shape so we can reuse the object-level
|
|
112
|
-
// enricher. `
|
|
112
|
+
// enricher. `taskId` etc. don't matter to enrich logic.
|
|
113
113
|
const ev = { type, ...parsed };
|
|
114
114
|
const out = enrichEventForDisplay(ev, map);
|
|
115
115
|
if (out === ev)
|