diffact 0.2.0 → 0.3.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/dist/cli.mjs CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- globalThis.Bun===void 0?await import(`./index-node-bKTmbwGt.mjs`):await import(`./src-Ceryd8j5.mjs`);export{};
2
+ globalThis.Bun===void 0?await import(`./index-node-OJ3iJPYj.mjs`):await import(`./src-CFIPD_RU.mjs`);export{};
@@ -1 +1 @@
1
- import{a as e,i as t,n,o as r,r as i,s as a,t as o}from"./src-CPKE75x0.mjs";import{serve as s}from"@hono/node-server";import{WebSocketServer as c}from"ws";const l=process.argv.includes(`--no-open`);new c({server:s({fetch:n.fetch,port:o})}).on(`connection`,e=>{a.info(`ws open (node)`);let t=i.open(),n={send:t=>e.send(t),close:()=>e.close(),binaryType:`arraybuffer`,readyState:1,url:``,protocol:``};e.on(`message`,e=>{let r=typeof e==`string`?e:e.toString(`utf8`);t.onMessage?.({data:r},n)}),e.on(`close`,(e,r)=>{t.onClose?.({code:e,reason:r.toString(`utf8`)},n)}),e.on(`error`,e=>{a.error({err:e},`ws error (node)`)}),t.onOpen?.({},n)});const u=`http://localhost:${o}`;a.info(`diffact server (node) listening on ${u}`),e()&&a.info(`serving static files from ${t()}`),!l&&e()&&r(u);export{};
1
+ import{a as e,i as t,n,o as r,r as i,s as a,t as o}from"./src-D1IC9k-b.mjs";import{serve as s}from"@hono/node-server";import{WebSocketServer as c}from"ws";const l=process.argv.includes(`--no-open`);new c({server:s({fetch:n.fetch,port:o})}).on(`connection`,e=>{a.info(`ws open (node)`);let t=i.open(),n={send:t=>e.send(t),close:()=>e.close(),binaryType:`arraybuffer`,readyState:1,url:``,protocol:``};e.on(`message`,e=>{let r=typeof e==`string`?e:e.toString(`utf8`);t.onMessage?.({data:r},n)}),e.on(`close`,(e,r)=>{t.onClose?.({code:e,reason:r.toString(`utf8`)},n)}),e.on(`error`,e=>{a.error({err:e},`ws error (node)`)}),t.onOpen?.({},n)});const u=`http://localhost:${o}`,d=e();a.info(`diffact server (node) listening on ${u}`),d&&a.info(`serving static files from ${t()}`),!l&&d&&r(u);export{};
@@ -0,0 +1 @@
1
+ import{n as e,r as t,t as n}from"./src-D1IC9k-b.mjs";export{};
@@ -0,0 +1,73 @@
1
+ import e,{access as t,constants as n}from"node:fs/promises";import r from"node:path";import{Hono as i}from"hono";import{execFile as a,execFileSync as o,execSync as s,spawn as c}from"node:child_process";import{chat as l,toolDefinition as u}from"@tanstack/ai";import d from"node:crypto";import f from"pino";import p from"node:fs";import m from"node:os";import{fileURLToPath as h}from"node:url";import{createOpenaiChat as ee}from"@tanstack/ai-openai";import{promisify as g}from"node:util";import{z as _}from"zod";import{AsyncLocalStorage as te}from"node:async_hooks";function v(){return typeof d.randomUUID==`function`?d.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,10)}`}function y(e){return e&&typeof e==`object`?e:null}function b(e){return typeof e==`string`?e:``}function x(e){return typeof e==`number`&&Number.isFinite(e)?e:null}function S(e,t){return b(e[t]).trim()}function ne(e,t){let n=e[t];return Array.isArray(n)?n.filter(e=>typeof e==`string`).map(e=>e.trim()).filter(Boolean):[]}const C=()=>Date.now(),w=(e,t)=>({type:`RUN_STARTED`,timestamp:C(),runId:e,model:t??void 0}),T=(e,t=`stop`,n)=>({type:`RUN_FINISHED`,timestamp:C(),runId:e,finishReason:t,usage:n}),E=(e,t)=>({type:`RUN_ERROR`,timestamp:C(),runId:e??void 0,error:{message:t}}),re=e=>({type:`TEXT_MESSAGE_START`,timestamp:C(),messageId:e,role:`assistant`}),ie=(e,t)=>({type:`TEXT_MESSAGE_CONTENT`,timestamp:C(),messageId:e,delta:t}),ae=e=>({type:`TEXT_MESSAGE_END`,timestamp:C(),messageId:e}),D=(e,t)=>({type:`TOOL_CALL_START`,timestamp:C(),toolCallId:e,toolName:t}),O=(e,t,n)=>({type:`TOOL_CALL_END`,timestamp:C(),toolCallId:e,toolName:t,input:n}),oe=e=>e===`length`||e===`content_filter`||e===`tool_calls`?e:`stop`;var se=class{#e;#t;constructor(e){this.#e={runId:e.runId,started:!1,finished:!1,messageId:null,stepId:null,thinking:``},this.#t=e.createId}start(){return this.#e.started?[]:(this.#e.started=!0,[w(this.#e.runId,null)])}handle(e){let t=b(e.type);return t?t.startsWith(`RUN_`)||t.startsWith(`TEXT_`)||t.startsWith(`TOOL_`)||t.startsWith(`STEP_`)||t===`STATE_SNAPSHOT`||t===`STATE_DELTA`||t===`CUSTOM`?(this.#r(e),[e]):this.#i(t,e):[]}finalize(){let e=[];return this.#e.messageId&&(e.push(ae(this.#e.messageId)),this.#e.messageId=null),this.#e.finished||(e.push(T(this.#e.runId)),this.#e.finished=!0),e}#n(e){return this.#e.started?[]:(this.#e.started=!0,[w(this.#e.runId,e??null)])}#r(e){switch(e.type){case`RUN_STARTED`:this.#e.started=!0;return;case`RUN_FINISHED`:case`RUN_ERROR`:this.#e.finished=!0;return;case`TEXT_MESSAGE_START`:this.#e.messageId=e.messageId;return;case`TEXT_MESSAGE_END`:this.#e.messageId=null;return;case`STEP_STARTED`:this.#e.stepId=e.stepId;return;case`STEP_FINISHED`:this.#e.stepId=e.stepId;return;default:return}}#i(e,t){let n=[],r=y(t);if(!r)return n;if(e===`content`){let e=b(r.model),t=b(r.delta)||b(r.content);return n.push(...this.#n(e||null)),this.#e.messageId||(this.#e.messageId=this.#t(),n.push(re(this.#e.messageId))),t&&n.push(ie(this.#e.messageId,t)),n}if(e===`thinking`){let e=b(r.model),t=b(r.delta)||b(r.content);return n.push(...this.#n(e||null)),t?(this.#e.stepId||(this.#e.stepId=this.#t(),n.push({type:`STEP_STARTED`,timestamp:C(),stepId:this.#e.stepId,stepType:`thinking`})),this.#e.thinking+=t,n.push({type:`STEP_FINISHED`,timestamp:C(),stepId:this.#e.stepId,delta:t,content:this.#e.thinking}),n):n}if(e===`tool_call`){let e=b(r.model);n.push(...this.#n(e||null));let t=y((y(r.toolCall)||{}).function)||{},i=b(t.name)||`tool`,a=b(t.arguments),o=this.#t();n.push(D(o,i)),a&&n.push({type:`TOOL_CALL_ARGS`,timestamp:C(),toolCallId:o,delta:a,args:a});let s;if(a)try{s=JSON.parse(a)}catch{s=a}return n.push(O(o,i,s)),n}if(e===`done`){n.push(...this.#n(null)),this.#e.messageId&&(n.push(ae(this.#e.messageId)),this.#e.messageId=null);let e=y(r.usage),t=e?{promptTokens:x(e.promptTokens)??0,completionTokens:x(e.completionTokens)??0,totalTokens:x(e.totalTokens)??0}:void 0,i=oe(b(r.finishReason));return this.#e.finished=!0,n.push(T(this.#e.runId,i,t)),n}if(e===`error`){let e=b(y(r.error)?.message)||`embedded_error`;return this.#e.finished=!0,n.push(E(this.#e.runId,e)),n}return n}};const ce=e=>{if(!e||typeof e!=`object`)return;let t=e,n=typeof t.input_tokens==`number`&&t.input_tokens||typeof t.prompt_tokens==`number`&&t.prompt_tokens||0,r=typeof t.output_tokens==`number`&&t.output_tokens||typeof t.completion_tokens==`number`&&t.completion_tokens||0;return{promptTokens:n,completionTokens:r,totalTokens:n+r}},le=e=>{let t={started:!1,finished:!1,sawEvent:!1},n=new Map,r=()=>t.started?[]:(t.started=!0,[w(e,null)]),i=i=>{let a=[],o=b(i.type);if(!o)return a;if(o===`thread.started`||o===`turn.started`)return a.push(...r()),t.sawEvent=!0,a;if(o===`turn.completed`)return a.push(...r()),t.finished=!0,a.push(T(e,`stop`,ce(i.usage))),t.sawEvent=!0,a;if(o===`error`||o===`turn.failed`){a.push(...r()),t.finished=!0;let n=b(i.error?.message||i.message);return a.push(E(e,n||`cli_exec_failed`)),t.sawEvent=!0,a}if(o===`item.started`){let e=i.item;if(!e||typeof e!=`object`)return a;let o=e;if(b(o.type)!==`command_execution`)return a;a.push(...r());let s=b(o.id),c=b(o.command),l=v();if(s&&n.set(s,{toolCallId:l,command:c}),a.push(D(l,`command_execution`)),c){let e=JSON.stringify({command:c});a.push({type:`TOOL_CALL_ARGS`,timestamp:Date.now(),toolCallId:l,delta:e,args:e})}return t.sawEvent=!0,a}if(o===`item.completed`){let e=i.item;if(!e||typeof e!=`object`)return a;let o=e,s=b(o.type);if(!s)return a;if(a.push(...r()),s===`agent_message`||s===`assistant_message`){let e=b(o.text)||b(o.content);if(!e)return a;let n=v();return a.push(re(n)),a.push(ie(n,e)),a.push(ae(n)),t.sawEvent=!0,a}if(s===`reasoning`||s===`thinking`){let e=b(o.text)||b(o.content);if(!e)return a;let n=v();return a.push({type:`STEP_STARTED`,timestamp:Date.now(),stepId:n,stepType:`thinking`}),a.push({type:`STEP_FINISHED`,timestamp:Date.now(),stepId:n,delta:e,content:e}),t.sawEvent=!0,a}if(s===`command_execution`){a.push(...r());let e=b(o.id),i=b(o.command),s=e?n.get(e):void 0,c=s?.toolCallId??v(),l=i||s?.command||``;if(!s&&(a.push(D(c,`command_execution`)),l)){let e=JSON.stringify({command:l});a.push({type:`TOOL_CALL_ARGS`,timestamp:Date.now(),toolCallId:c,delta:e,args:e})}e&&n.delete(e);let u=b(o.aggregated_output),d=b(o.status),f=typeof o.exit_code==`number`?o.exit_code:null,p=O(c,`command_execution`,l?{command:l}:void 0),m={};return l&&(m.command=l),u&&(m.aggregated_output=u),f!==null&&(m.exit_code=f),d&&(m.status=d),Object.keys(m).length&&(p.result=m),a.push(p),t.sawEvent=!0,a}if(s===`tool_call`||s===`mcp_tool_call`){let e=b(o.tool)||b(o.name)||b(o.tool_name)||`tool`,n=v();a.push(D(n,e));let r=b(o.arguments)||b(o.args)||b(o.input);r&&a.push({type:`TOOL_CALL_ARGS`,timestamp:Date.now(),toolCallId:n,delta:r,args:r});let i;if(r)try{i=JSON.parse(r)}catch{i=r}let s=O(n,e,i);return`result`in o?s.result=o.result:`output`in o&&(s.result=o.output),a.push(s),t.sawEvent=!0,a}}return a};return{handleLine:e=>{let t=e.trim();if(!t)return[];try{return i(JSON.parse(t))}catch{return[]}},finalize:n=>{if(t.finished)return[];let i=[...r()];return n===0?i.push(T(e)):i.push(E(e,`cli_exec_failed:${n}`)),i},state:t}},ue=e=>{let t={started:!1,finished:!1,sawEvent:!1},n=new Map,r=!1,i=()=>t.started?[]:(t.started=!0,[w(e,null)]),a=e=>{if(!e)return[];let t=v();return r=!0,[re(t),ie(t,e),ae(t)]},o=e=>{let t=[],r=e.content;if(typeof r==`string`&&r)return t.push(...a(r)),t;let i=Array.isArray(r)?r:r?[r]:[],o=[];for(let e of i){if(!e||typeof e!=`object`)continue;let r=e,i=b(r.type);if(i===`text`){let e=b(r.text);e&&o.push(e);continue}if(i===`tool_use`){let e=b(r.id),i=b(r.name)||`tool`,a=v(),o=r.input;if(e&&n.set(e,{toolCallId:a,name:i,input:o}),t.push(D(a,i)),o!==void 0){let e=JSON.stringify(o);t.push({type:`TOOL_CALL_ARGS`,timestamp:Date.now(),toolCallId:a,delta:e,args:e})}}}return o.length&&t.push(...a(o.join(``))),t},s=e=>{let t=[],r=e.content,i=Array.isArray(r)?r:r?[r]:[];for(let e of i){if(!e||typeof e!=`object`)continue;let r=e;if(b(r.type)!==`tool_result`)continue;let i=b(r.tool_use_id),a=i?n.get(i):void 0,o=a?.toolCallId??v(),s=a?.name??`tool`;a||t.push(D(o,s));let c=O(o,s,a?.input);`content`in r&&(c.result={content:r.content,is_error:r.is_error===!0}),t.push(c),i&&n.delete(i)}return t},c=n=>{let c=[],l=b(n.type);if(!l)return c;if(l===`result`){c.push(...i()),t.finished=!0;let o=n.subtype===`error`||n.is_error===!0,s=b(n.error?.message||n.message||n.result);return o?c.push(E(e,s||`cli_exec_failed`)):(r||c.push(...a(s)),c.push(T(e))),t.sawEvent=!0,c}if(l===`error`){c.push(...i()),t.finished=!0;let r=b(n.message);return c.push(E(e,r||`cli_exec_failed`)),t.sawEvent=!0,c}if(l===`assistant`){c.push(...i());let e=n.message;return e&&typeof e==`object`&&(c.push(...o(e)),t.sawEvent=t.sawEvent||c.length>0),c}if(l===`user`){let e=n.message;return e&&typeof e==`object`&&(c.push(...i()),c.push(...s(e)),t.sawEvent=t.sawEvent||c.length>0),c}return c};return{handleLine:e=>{let t=e.trim();if(!t)return[];try{return c(JSON.parse(t))}catch{return[]}},finalize:n=>{if(t.finished)return[];let r=[...i()];return n===0?r.push(T(e)):r.push(E(e,`cli_exec_failed:${n}`)),r},state:t}},de=e=>{let t=y(e);if(!t)return;let n=x(t.input)??0,r=x(t.output)??0;if(!(!n&&!r))return{promptTokens:n,completionTokens:r,totalTokens:n+r}},fe=e=>{let t={started:!1,finished:!1,sawEvent:!1},n=new Map,r=null,i=()=>t.started?[]:(t.started=!0,[w(e,null)]),a=()=>{if(!r)return[];let e=[ae(r)];return r=null,e},o=e=>{if(!e)return[];let n=[];return n.push(...i()),r||(r=v(),n.push(re(r))),n.push(ie(r,e)),t.sawEvent=!0,n},s=e=>{let r=[];r.push(...i());let a=b(e.tool)||b(e.name)||`tool`,o=b(e.callID)||b(e.callId)||b(e.id),s=y(e.state),c=s?.input??e.input,l=b(s?.status),u=y(s?.metadata),d=b(s?.output)||b(u?.output),f=x(u?.exit),p=b(s?.title),m=b(u?.description)||b(y(c)?.description),h=c??(m?{description:m}:void 0),ee=h===void 0?``:typeof h==`string`?h:JSON.stringify(h),g=o?n.get(o):void 0,_=g?.toolCallId??v();if(g||(o&&n.set(o,{toolCallId:_,name:a,input:c}),r.push(D(_,a)),ee&&r.push({type:`TOOL_CALL_ARGS`,timestamp:Date.now(),toolCallId:_,delta:ee,args:ee})),g&&c!==void 0&&(g.input=c),l===`completed`||l===`failed`||l===`error`||d!==``||f!==null){let e={};d&&(e.output=d),f!==null&&(e.exit=f),l&&(e.status=l),p&&(e.title=p),m&&(e.description=m);let t=O(_,a,c);Object.keys(e).length&&(t.result=e),r.push(t),o&&n.delete(o)}return t.sawEvent=!0,r},c=n=>{let r=[];r.push(...i());let o=b(n.reason);if(o===`stop`)return r.push(...a()),t.finished=!0,r.push(T(e,`stop`,de(n.tokens))),t.sawEvent=!0,r;if(o===`error`){r.push(...a()),t.finished=!0;let i=b(n.message)||b(y(n.error)?.message)||`cli_exec_failed`;return r.push(E(e,i)),t.sawEvent=!0,r}return t.sawEvent=!0,r},l=n=>{let r=[],l=b(n.type);if(!l)return r;let u=y(n.part);if(l===`text`&&u){let e=b(u.text)||b(u.content);return r.push(...o(e)),r}if(l===`step_start`)return r.push(...i()),t.sawEvent=!0,r;if(l===`tool_use`&&u)return r.push(...s(u)),r;if(l===`step_finish`&&u)return r.push(...c(u)),r;if(l===`error`){r.push(...i()),r.push(...a()),t.finished=!0;let o=b(n.message)||b(y(n.error)?.message)||`cli_exec_failed`;return r.push(E(e,o)),t.sawEvent=!0,r}return r};return{handleLine:e=>{let t=e.trim();if(!t)return[];try{return l(JSON.parse(t))}catch{return[]}},finalize:n=>{if(t.finished)return a();let r=[...i(),...a()];return n===0?r.push(T(e)):r.push(E(e,`cli_exec_failed:${n}`)),r},state:t}},k=f({level:process.env.LOG_LEVEL||`info`,base:null,timestamp:f.stdTimeFunctions.isoTime,formatters:{level:e=>({level:e.toUpperCase()})}}),pe=(e,t)=>!!(e&&typeof e==`object`&&`code`in e&&e.code===t),A=e=>pe(e,`ENOENT`);async function j(t){let n=r.resolve(t),i;try{i=await e.stat(n)}catch(e){throw A(e)?Error(`invalid_path`):e}if(!i.isDirectory())throw Error(`not_a_directory`);let a=r.join(n,`.git`);return{rootPath:n,isGit:await e.stat(a).then(()=>!0).catch(e=>{if(A(e))return!1;throw e})}}function me(e,t){let n=new Set;for(let i of t){let t=i.trim();if(!t)continue;let a=r.resolve(e,t),o=r.relative(e,a);if(!o||o.startsWith(`..`)||r.isAbsolute(o))return null;n.add(o.replace(/\\/g,`/`))}return Array.from(n.values())}const M=globalThis.Bun!==void 0,he=!M,N={name:M?`bun`:`node`,version:M?Bun.version:process.version,isBun:M,isNode:he,which(e){if(M)return Bun.which(e);try{return s(`which ${e}`,{encoding:`utf8`,stdio:[`pipe`,`pipe`,`ignore`]}).trim()||null}catch{return null}},file(e){if(M)return Bun.file(e);let t=p.statSync(e),n=r.extname(e).toLowerCase();return{stream(){let t=p.createReadStream(e);return new ReadableStream({start(e){t.on(`data`,t=>{e.enqueue(new Uint8Array(t))}),t.on(`end`,()=>{e.close()}),t.on(`error`,t=>{e.error(t)})},cancel(){t.destroy()}})},size:t.size,type:{".html":`text/html`,".css":`text/css`,".js":`application/javascript`,".json":`application/json`,".png":`image/png`,".jpg":`image/jpeg`,".jpeg":`image/jpeg`,".gif":`image/gif`,".svg":`image/svg+xml`,".txt":`text/plain`}[n]||`application/octet-stream`}},spawn(e,t={}){if(M){let n={...process.env||{},...t.env||{}},r={};for(let[e,t]of Object.entries(n))typeof t==`string`&&(r[e]=t);let i=t.onExit?(e,n,r,i)=>{t.onExit?.(e,n,r===null?null:String(r),i)}:void 0;return Bun.spawn(e,{cwd:t.cwd,env:r,onExit:i})}let n=e[0];if(!n)throw Error(`Command array must not be empty`);let r=c(n,e.slice(1),{cwd:t.cwd,env:t.env?{...process.env,...t.env}:void 0,stdio:[`pipe`,`pipe`,`pipe`]}),i=null,a=null,o=new Promise(e=>{r.on(`exit`,(n,o)=>{i=n,a=o,t.onExit?.(r,n,o,void 0),e(n??1)}),r.on(`error`,n=>{t.onExit?.(r,null,null,n),e(1)})}),s=e=>e?new ReadableStream({start(t){e.on(`data`,e=>{t.enqueue(new Uint8Array(e))}),e.on(`end`,()=>t.close()),e.on(`error`,e=>t.error(e))}}):null;return{exited:o,get exitCode(){return i},get signalCode(){return a},stdout:s(r.stdout),stderr:s(r.stderr),kill:e=>r.kill(e)}}},ge=e=>{let t=r.basename(e);return t===`bash`||t===`zsh`||t===`fish`||t===`sh`},_e=e=>{let t=e.trim();return t?t.includes(`/`)?t:N.which(t)??t:``},ve=()=>{if(process.env.SHELL)return _e(process.env.SHELL);try{let e=m.userInfo();if(e.shell)return _e(e.shell)}catch{}return``},ye=(e,t)=>ge(e)?[`-ilc`,t]:[`-ic`,t],be=(e,t,n)=>ge(e)?[n?`-ilc`:`-lc`,t]:[n?`-ic`:`-c`,t],P=(e,t)=>e.length>t?`${e.slice(0,t)}...`:e,xe=(e,t)=>{if(e==null)return null;if(typeof e==`string`)return P(e,t);try{return P(JSON.stringify(e),t)}catch{return null}},Se=e=>{let t=null,n=``,r=new Map,i=new Map,a=new Map,o=new Map,s=(r,i)=>{let a=i.trim();a&&(n=a,k.info({source:e.source,runId:t,messageId:r,length:a.length,content:P(a,600)},`stream message`))},c=(n,r)=>{let i=r.trim();i&&k.info({source:e.source,runId:t,stepId:n,length:i.length,content:P(i,600)},`stream thinking`)},l=(n,r,i,a)=>{k.info({source:e.source,runId:t,toolCallId:n,toolName:r.name,args:r.args?P(r.args,600):null,input:xe(i,600),result:xe(a,600)},`stream tool`)},u=n=>{switch(n.type){case`RUN_STARTED`:t=n.runId??t,k.info({source:e.source,runId:t,model:n.model??null},`stream run started`);return;case`RUN_FINISHED`:k.info({source:e.source,runId:t,finishReason:n.finishReason??null,usage:n.usage??null},`stream run finished`),d();return;case`RUN_ERROR`:k.warn({source:e.source,runId:t,error:n.error?.message||`run_error`},`stream run error`),d();return;case`TEXT_MESSAGE_START`:r.set(n.messageId,``);return;case`TEXT_MESSAGE_CONTENT`:{let e=n.delta||n.content||``;if(!e)return;let t=r.get(n.messageId)||``;r.set(n.messageId,`${t}${e}`);return}case`TEXT_MESSAGE_END`:{let e=r.get(n.messageId)||``;r.delete(n.messageId),i.set(n.messageId,e);return}case`TOOL_CALL_START`:a.set(n.toolCallId,{name:n.toolName,args:``});return;case`TOOL_CALL_ARGS`:{let e=a.get(n.toolCallId);if(!e)return;let t=n,r=t.args||t.delta||``;e.args=t.args?String(r):`${e.args}${r}`;return}case`TOOL_CALL_END`:{let e=a.get(n.toolCallId);if(!e)return;let t=n;l(n.toolCallId,e,t.input,t.result),a.delete(n.toolCallId);return}case`STEP_STARTED`:o.set(n.stepId,``);return;case`STEP_FINISHED`:{let e=typeof n.content==`string`&&n.content.length?n.content:n.delta||``;if(!e)return;let t=o.get(n.stepId)||``;o.set(n.stepId,e===n.content?e:`${t}${e}`);return}default:return}},d=()=>{for(let[e,t]of r.entries())s(e,t);r.clear();for(let[e,t]of i.entries())s(e,t);i.clear();for(let[e,t]of a.entries())l(e,t);a.clear();for(let[e,t]of o.entries())c(e,t);o.clear()};return{handleEvent:u,flush:d,getLastMessage:e=>n?typeof e==`number`?P(n,e):n:``}},Ce=8e3;let we=null;const Te=e=>{let t=e.indexOf(0),n=(t===-1?e:e.subarray(t+1)).toString(`utf8`).split(`\0`),r={};for(let e of n){if(!e)continue;let t=e.indexOf(`=`);t!==-1&&(r[e.slice(0,t)]=e.slice(t+1))}return r},Ee=()=>{if(we)return we;let e=ve()||`/bin/sh`,t={},n=!1;for(let r of[!0,!1]){n||=r;try{t=Te(o(e,be(e,`printf '\\0'; env -0`,r),{encoding:`buffer`}));break}catch(t){if(r){k.warn({err:t,shellPath:e},`login shell env read failed, retrying without interactive`);continue}k.warn({err:t,shellPath:e},`login shell env read failed`)}}return n&&!Object.keys(t).length&&k.warn({shellPath:e},`login shell env empty`),we={env:t,shellPath:e},we},De=()=>{let{env:e,shellPath:t}=Ee(),n={...e,...process.env};return e.PATH&&(n.PATH=e.PATH),t&&(n.SHELL||=t),n.TERM||=`xterm-256color`,n.FORCE_COLOR||=`1`,n.CLICOLOR_FORCE||=`1`,n},Oe=e=>e??`codex`,ke=(e,t)=>t||N.which(e)||e,Ae={claude:e=>[`-p`,e,`--output-format`,`stream-json`,`--verbose`],opencode:e=>[`run`,e,`--format`,`json`],codex:(e,t)=>{let n=[`exec`,`--json`,`--yolo`];return t&&n.push(`--cd`,t),n.push(e),n}},je={codex:[`resume`,`--last`],claude:[`--continue`],opencode:[`--continue`]},Me={codex:null,claude:null,opencode:`--format`},Ne=(e,t)=>{let n=Me[e],r=je[e];if(!n){t.push(...r);return}let i=t.indexOf(n);if(i===-1){t.push(...r);return}t.splice(i,0,...r)},Pe=(e,t,n,r)=>{let i=Ae[e](t,n);return r&&Ne(e,i),i},Fe=e=>{if(!Array.isArray(e)||!e.length)return``;let t=e[e.length-1]?.content;if(typeof t==`string`)return t;if(Array.isArray(t)){for(let e of t)if(e&&typeof e==`object`&&`type`in e&&e.type===`text`&&`text`in e){let t=e.text;if(typeof t==`string`)return t}}return``},Ie=(e,t=200)=>e.length>t?`${e.slice(0,t)}...`:e,Le=e=>{if(typeof e==`string`)return e;try{return JSON.stringify(e)}catch{return String(e)}},Re=e=>{if(e.type!==`TEXT_MESSAGE_CONTENT`)return``;let t=e.delta;return typeof t==`string`?t:``},ze=e=>e.length>Ce?`${e.slice(0,Ce)}...`:e;var F=class{#e;#t;#n=null;constructor(e){this.#e=e,this.#t=[...e.tools??[]]}setModel(e){this.#e.model=e}async#r(){let e=this.#e.modelProvider;if(e)try{let t=await e();if(t)return t}catch(e){k.warn({err:e},`model provider failed`)}return this.#e.model||null}chat(e){return this.#e.type===`cli`?this.#a(e):this.#i(e)}async chatOneShot(e){return this.#e.type===`cli`?this.#o(this.#a(e)):this.#s(e)}async chatStructured(e){if(this.#e.type===`cli`)throw Error(`structured_output_unsupported_for_cli`);return this.#c(e)}async*#i(e){let t=await this.#r();if(!t){k.error(`embedded agent missing model`),yield E(null,`embedded_model_missing`);return}let n=await this.#l(),r=new se({runId:v(),createId:v}),i=Se({source:`embedded`});for(let e of r.start())i.handleEvent(e),yield e;k.info({tools:this.#t.map(e=>e.name)},`embedded chat start with tools`);let a=l({adapter:t,messages:e.messages,systemPrompts:n?[n]:void 0,tools:this.#t});for await(let e of a)for(let t of r.handle(e)){let e=t.type===`TOOL_CALL_END`?await this.#u(t):t;i.handleEvent(e),yield e}for(let e of r.finalize())i.handleEvent(e),yield e;i.flush();let o=i.getLastMessage(600);k.info({reply:o||null},`embedded chat finished`)}async*#a(e){if(this.#n){yield E(null,`cli_agent_busy`);return}let t=v();this.#n={runId:t};let n=e.projectPath?(await j(e.projectPath)).rootPath:null,r=Fe(e.messages),i=e.continue===!0,a=Oe(this.#e.cliProvider),o=ke(a,this.#e.cliCommand),s=Pe(a,r,n,i),c=a===`claude`?ue(t):a===`opencode`?fe(t):le(t),l=Se({source:`cli`});k.info({runId:t,provider:a,command:o,args:s},`cli exec start`);try{let e=N.spawn([o,...s],{cwd:n??void 0,env:De()}),r=e.stdout;if(!r){yield E(t,`cli_no_stdout`);return}let i=r.getReader(),a=new TextDecoder,u=``;for(;;){let{value:e,done:t}=await i.read();if(t)break;u+=a.decode(e,{stream:!0});let n=u.indexOf(`
2
+ `);for(;n!==-1;){let e=u.slice(0,n).trim();if(u=u.slice(n+1),e){let t=c.handleLine(e);for(let e of t)l.handleEvent(e),yield e}n=u.indexOf(`
3
+ `)}}let d=u.trim();if(d){let e=c.handleLine(d);for(let t of e)l.handleEvent(t),yield t}let f=await e.exited,p=c.finalize(f);for(let e of p)l.handleEvent(e),yield e;c.state.sawEvent||k.warn({runId:t,exitCode:f},`cli exec produced no events`),k.info({runId:t,exitCode:f,finished:c.state.finished},`cli exec finished`)}catch(e){yield E(t,e instanceof Error?e.message:`cli_chat_failed`)}finally{l.flush(),this.#n=null}}async#o(e){let t=``;for await(let n of e)if(n.type===`TEXT_MESSAGE_CONTENT`){let e=n.delta;typeof e==`string`&&(t+=e)}return t.trim()}async#s(e){let t=await this.#r();if(!t)return k.error(`embedded agent missing model`),``;let n=e.systemPrompt===void 0?await this.#l():e.systemPrompt;try{let r=Fe(e.messages),i=Date.now();k.info({promptLength:r.length,systemPromptProvided:e.systemPrompt!==void 0},`embedded one-shot start`);let a=new se({runId:v(),createId:v}),o=``,s=0,c=0,u=0,d=l({adapter:t,messages:e.messages,systemPrompts:n?[n]:void 0});for await(let e of d){let t=e;t.type===`content`&&(c+=1),t.type===`error`&&(u+=1);for(let t of a.handle(e)){let e=Re(t);e&&(o+=e,s+=1),t.type===`RUN_ERROR`&&(u+=1)}}for(let e of a.finalize()){let t=Re(e);t&&(o+=t,s+=1),e.type===`RUN_ERROR`&&(u+=1)}let f=o.trim();return k.info({outputLength:f.length,durationMs:Date.now()-i,systemPromptProvided:e.systemPrompt!==void 0,rawContentChunkCount:c,normalizedTextChunkCount:s,rawRunErrorCount:u,outputPreview:f?Ie(f):``},`embedded one-shot complete`),f||k.warn({promptLength:r.length,promptPreview:r?Ie(r):``,systemPromptProvided:e.systemPrompt!==void 0},`embedded one-shot empty output`),f}catch(e){return k.warn({err:e},`embedded one-shot chat failed`),``}}async#c(e){let t=await this.#r();if(!t)throw Error(`embedded_model_missing`);let n=e.systemPrompt===void 0?await this.#l():e.systemPrompt,r=Date.now(),i=Fe(e.messages);k.info({promptLength:i.length,promptPreview:i?Ie(i):``,tools:this.#t.map(e=>e.name),systemPromptProvided:e.systemPrompt!==void 0},`embedded structured output start`);try{let a=e.messages,o=0;if(this.#t.length>0){let t=Date.now(),n=``,r=[];for await(let t of this.#i({messages:e.messages,projectPath:e.projectPath,continue:e.continue})){if(t.type===`TOOL_CALL_START`){o+=1;continue}if(t.type===`TOOL_CALL_END`){let e=t,n=typeof e.toolName==`string`?e.toolName:`unknown_tool`,i=Le(e.input??{}),a=Le(e.result??``);a.trim()&&r.push([`tool: ${n}`,`input: ${i}`,`result: ${a}`].join(`
4
+ `));continue}if(t.type!==`TEXT_MESSAGE_CONTENT`)continue;let e=Re(t);e&&(n+=e)}let s=n.trim(),c=r.join(`
5
+
6
+ `).trim(),l=ze(s),u=ze(c);k.info({durationMs:Date.now()-t,toolCallCount:o,prepassReplyLength:s.length,prepassReplyPreview:s?Ie(s):``,toolResultCount:r.length,toolResultsLength:c.length},`embedded structured output tool prepass complete`),a=[{role:`user`,content:[`Return output that strictly matches the output schema.`,`Use tool outputs as the primary source of truth.`,`Tool call count in that reply: ${o}.`,o?``:`If tool call count is 0, do not claim command output or directory contents; clearly say execution was not completed.`,``,`Original user message:`,i||`(empty)`,``,`Tool outputs:`,u||`(none)`,``,`Assistant reply after tool phase:`,l||`(none)`].filter(Boolean).join(`
7
+ `)}]}let s=await l({adapter:t,messages:a,systemPrompts:n?[n]:void 0,tools:this.#t.length>0?void 0:this.#t,outputSchema:e.outputSchema}),c=Ie(typeof s==`string`?s:JSON.stringify(s));return k.info({durationMs:Date.now()-r,systemPromptProvided:e.systemPrompt!==void 0,toolCallCount:o,resultPreview:c},`embedded structured output complete`),s}catch(e){throw k.warn({err:e},`embedded structured output failed`),e}}async#l(){let e=this.#e.systemPromptProvider;if(e)try{return await e()||null}catch(e){k.warn({err:e},`system prompt provider failed`)}return this.#e.systemPrompt||null}async#u(e){if(e.type!==`TOOL_CALL_END`)return e;let t=e;if(t.result!==void 0)return e;let n=this.#t.find(e=>e.name===t.toolName);if(!n||typeof n.execute!=`function`)return k.warn({toolName:t.toolName},`tool execute missing`),e;let r=n.execute,i=Date.now();try{let n=await r(t.input??{}),a=typeof n==`string`?n:JSON.stringify(n);return k.info({toolName:t.toolName,durationMs:Date.now()-i},`tool executed`),{...e,result:a}}catch(n){return k.warn({err:n,toolName:t.toolName},`tool execute failed`),e}}};async function Be(){let e=N.which(`gh`);if(!e)return!1;try{return await N.spawn([e,`auth`,`status`,`--hostname`,`github.com`],{}).exited===0}catch{return!1}}async function Ve(e){let t=e?await j(e).catch(()=>null):null,n=await Be();return{diffReview:!0,git:!!t?.isGit,github:n}}const He=`codex`,Ue={codex:`Codex CLI`,claude:`Claude Code`,opencode:`OpenCode`},We=[`codex`,`claude`,`opencode`],Ge=()=>We.map(e=>{let t=N.which(e);return{id:e,label:Ue[e],command:t,available:!!t}}),Ke=e=>We.includes(e),I=r.join(m.homedir(),`.diffact`),qe=r.join(I,`config.json`),Je=r.join(I,`AGENTS.md`),Ye=r.join(I,`task.jsonl`),L=r.join(I,`transcript.jsonl`),Xe=r.join(I,`transcript.index`),R=r.join(I,`MEMORY.md`),Ze=r.join(I,`VOICE.md`),Qe=r.join(I,`daily`),$e=process.env.DIFFACT_PROJECT_ROOT?r.resolve(process.env.DIFFACT_PROJECT_ROOT):r.join(m.homedir(),`workspace`),z=(()=>{let e=r.dirname(h(import.meta.url)),t=[process.env.DIFFACT_STATIC_DIR,r.join(e,`../../web/dist`),r.join(e,`../web/dist`),r.join(process.cwd(),`web/dist`)];for(let e of t){if(!e)continue;let t=r.resolve(e);if(p.existsSync(t))return t}return null})();function et(e,t){let n=r.resolve(e),i=r.resolve(t);return i===n||i.startsWith(`${n}${r.sep}`)?i:null}const tt=async(t=`config read failed`)=>{try{let t=await e.readFile(qe,`utf8`);return y(JSON.parse(t))??{}}catch(e){return A(e)||k.warn({err:e},t),{}}},nt=async t=>{await e.mkdir(I,{recursive:!0}),await e.writeFile(qe,JSON.stringify(t,null,2),{mode:384})},rt=e=>{if(!e||typeof e!=`object`)return{preferred:He};let t=e;return{preferred:typeof t.preferred==`string`&&Ke(t.preferred)?t.preferred:He}},it=async()=>rt((await tt()).cli),at=async e=>{let t=await tt();t.cli={preferred:e.preferred},await nt(t)},ot=(e,t)=>{if(e){let n=t.find(t=>t.id===e);if(n?.available)return n}return t.find(e=>e.available)??null},st=[{id:`vscode`,name:`VS Code`,commands:{darwin:[`/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code`,`/usr/local/bin/code`,`/opt/homebrew/bin/code`],linux:[`/usr/bin/code`,`/usr/local/bin/code`,`/snap/bin/code`],win32:[`C:\\Program Files\\Microsoft VS Code\\bin\\code.cmd`,`C:\\Users\\%USERNAME%\\AppData\\Local\\Programs\\Microsoft VS Code\\bin\\code.cmd`]}},{id:`cursor`,name:`Cursor`,commands:{darwin:[`/Applications/Cursor.app/Contents/Resources/app/bin/cursor`,`/usr/local/bin/cursor`],linux:[`/usr/bin/cursor`,`/usr/local/bin/cursor`,`/opt/cursor/cursor`],win32:[`C:\\Program Files\\Cursor\\cursor.exe`,`C:\\Users\\%USERNAME%\\AppData\\Local\\Programs\\Cursor\\cursor.exe`]}},{id:`zed`,name:`Zed`,commands:{darwin:[`/Applications/Zed.app/Contents/MacOS/cli`,`/usr/local/bin/zed`],linux:[`/usr/bin/zed`,`/usr/local/bin/zed`,`~/.local/bin/zed`],win32:[]}}],ct=e=>e.startsWith(`~`)?r.join(m.homedir(),e.slice(1)):process.platform===`win32`&&e.includes(`%USERNAME%`)?e.replace(`%USERNAME%`,m.userInfo().username):e,lt=async e=>{try{return await t(e,n.X_OK),!0}catch{return!1}},ut=async e=>{for(let t of e){let e=ct(t);if(await lt(e))return e}return null},dt=async()=>{let e=m.platform();return Promise.all(st.map(async t=>{let n=await ut(t.commands[e]??[]);return{id:t.id,name:t.name,command:n??``,available:!!n}}))},ft=async e=>(await dt()).find(t=>t.id===e)??null,pt=(e,t,n)=>{if(n.type===`project`)return[t];if(n.type===`file`){let i=r.join(t,n.filePath);return n.line&&n.line>0?e===`vscode`||e===`cursor`?[t,`--goto`,`${i}:${n.line}`]:[t,`${i}:${n.line}`]:[t,i]}return n.type===`diff`?[t,r.join(t,n.filePath)]:(n.type,[t])},mt=async(e,t,n={type:`project`})=>{let r=await ft(e);if(!r)return{success:!1,error:`editor_not_found`};if(!r.available)return{success:!1,error:`editor_not_installed`};let i=pt(e,t,n);try{return N.spawn([r.command,...i]),{success:!0}}catch(e){return{success:!1,error:e instanceof Error?e.message:`spawn_failed`}}},ht=`gpt-5.2`,gt=e=>{if(!e||typeof e!=`object`)return{baseUrl:``,model:ht,apiKey:``};let t=e;return{baseUrl:typeof t.baseUrl==`string`?t.baseUrl.trim():``,model:typeof t.model==`string`&&t.model.trim()?t.model.trim():ht,apiKey:typeof t.apiKey==`string`?t.apiKey.trim():``}},B=async()=>gt((await tt()).embedded),_t=async e=>{let t=await tt();t.embedded=gt(e),await nt(t)},vt=e=>!e.apiKey||!e.model?null:ee(e.model,e.apiKey,{baseURL:e.baseUrl||void 0}),yt=g(a),bt=1024*1024*20;async function xt(e,t={}){let n=N.which(`gh`);if(!n)return k.warn({cwd:e},`gh CLI not found`),{available:!1,items:[],hasMore:!1,nextCursor:null,error:`GitHub CLI (gh) not found. Please install it.`};let r=t.limit??30,i=r+1;try{let a=[`pr`,`list`,`--state`,`open`,`--limit`,String(i),`--json`,`number,title,headRefName,updatedAt,author,url`];t.search&&a.push(`--search`,t.search);let{stdout:o}=await yt(n,a,{cwd:e,maxBuffer:bt}),s=JSON.parse(o),c=Array.isArray(s)?s.map(e=>({number:Number(e.number),title:String(e.title||``),headRefName:String(e.headRefName||``),updatedAt:String(e.updatedAt||``),author:e.author&&typeof e.author==`object`&&`login`in e.author?String(e.author.login||``):void 0,url:e.url?String(e.url):void 0})):[],l=c.length>r,u=l?c.slice(0,r):c;return{available:!0,items:u,hasMore:l,nextCursor:l?String(u[u.length-1]?.number):null}}catch(t){return k.error({err:t,cwd:e},`ghListPullRequests failed`),{available:!1,items:[],hasMore:!1,nextCursor:null,error:(t&&typeof t==`object`&&`stderr`in t?String(t.stderr).trim():``)||`Failed to list pull requests`}}}async function St(e,t={}){let n=N.which(`gh`);if(!n)return{available:!1,items:[],hasMore:!1,nextCursor:null,error:`GitHub CLI (gh) not found. Please install it.`};let r=t.limit??30,i=r+1,a=t.state??`open`;try{let o=[`issue`,`list`,`--state`,a,`--limit`,String(i),`--json`,`number,title,state,updatedAt,author,url,labels`];t.search&&o.push(`--search`,t.search);let{stdout:s}=await yt(n,o,{cwd:e,maxBuffer:bt}),c=JSON.parse(s),l=Array.isArray(c)?c.map(e=>({number:Number(e.number),title:String(e.title||``),state:e.state===`CLOSED`?`closed`:`open`,updatedAt:String(e.updatedAt||``),author:e.author&&typeof e.author==`object`&&`login`in e.author?String(e.author.login||``):void 0,url:e.url?String(e.url):void 0,labels:Array.isArray(e.labels)?e.labels.map(e=>({name:String(e.name||``),color:String(e.color||``)})):[]})):[],u=l.length>r,d=u?l.slice(0,r):l;return{available:!0,items:d,hasMore:u,nextCursor:u?String(d[d.length-1]?.number):null}}catch(t){return k.error({err:t,cwd:e},`ghListIssues failed`),{available:!1,items:[],hasMore:!1,nextCursor:null,error:(t&&typeof t==`object`&&`stderr`in t?String(t.stderr).trim():``)||`Failed to list issues`}}}async function Ct(e,t){let n=N.which(`gh`);if(!n)return null;try{let{stdout:r}=await yt(n,[`issue`,`view`,String(t),`--json`,`number,title,body,state,author,url,labels,createdAt,updatedAt,comments`],{cwd:e,maxBuffer:bt}),i=JSON.parse(r);return{number:Number(i.number),title:String(i.title||``),body:String(i.body||``),state:i.state===`CLOSED`?`closed`:`open`,author:i.author&&typeof i.author==`object`&&`login`in i.author?String(i.author.login||``):void 0,url:i.url?String(i.url):void 0,labels:Array.isArray(i.labels)?i.labels.map(e=>({name:String(e.name||``),color:String(e.color||``)})):[],createdAt:String(i.createdAt||``),updatedAt:String(i.updatedAt||``),commentsCount:Array.isArray(i.comments)?i.comments.length:0}}catch(n){return k.error({err:n,cwd:e,issueNumber:t},`ghGetIssueDetail failed`),null}}const wt=g(a),V=(e,t)=>wt(`git`,t,{cwd:e,maxBuffer:20971520}),Tt=async(e,t)=>{try{return await V(e,t)}catch(e){if(e&&typeof e==`object`&&`stdout`in e){let t=e,n=e=>typeof e==`string`?e:e instanceof Buffer?e.toString(`utf8`):``;return{stdout:n(t.stdout),stderr:n(t.stderr)}}throw e}};async function Et(e,t=[],n=[]){let r=[`diff`,`--no-color`,...t];n.length&&r.push(`--`,...n);let{stdout:i}=await V(e,r);if(t.some(e=>[`--cached`,`--staged`,`--index`].includes(e)))return i;let{stdout:a}=await V(e,[`ls-files`,`--others`,`--exclude-standard`,`-z`]),o=a.split(`\0`).map(e=>e.trim()).filter(Boolean),s=n.length?o.filter(e=>n.some(t=>e===t||e.startsWith(`${t}/`))):o;if(!s.length)return i;let c=[];for(let t of s){let{stdout:n}=await Tt(e,[`diff`,`--no-color`,`--no-index`,`--`,`/dev/null`,t]);n&&c.push(n.trimEnd())}if(!c.length)return i;let l=[i.trimEnd(),...c].filter(Boolean).join(`
8
+
9
+ `);return l&&`${l}\n`}async function Dt(e,t){t.length&&await V(e,[`add`,`-A`,`--`,...t])}const Ot=e=>{if(!e||typeof e!=`object`||!(`stderr`in e))return!1;let t=e,n=typeof t.stderr==`string`?t.stderr:t.stderr instanceof Buffer?t.stderr.toString(`utf8`):``;return n.includes(`ambiguous argument 'HEAD'`)||n.includes(`bad revision 'HEAD'`)||n.includes(`unknown revision or path`)};async function kt(e,t){if(t.length)try{await V(e,[`reset`,`-q`,`HEAD`,`--`,...t])}catch(n){if(!Ot(n))throw n;await V(e,[`rm`,`-r`,`--cached`,`--`,...t])}}async function At(e,t=0,n=50){let r=Number.isFinite(t)&&t>0?Math.floor(t):0,i=Number.isFinite(n)&&n>0?Math.floor(n):50,{stdout:a}=await V(e,[`log`,`--skip=${r}`,`-n`,`${i+1}`,`--format=%H%x1f%h%x1f%an%x1f%aI%x1f%s%x1f%b%x1e`]),o=a.split(``).map(e=>e.trim()).filter(Boolean).map(e=>{let[t,n,r,i,a,o]=e.split(``);return t?{sha:t,shortSha:n||t.slice(0,7),authorName:r||``,authoredAt:i||``,subject:a||``,description:o||``}:null}).filter(e=>!!e),s=o.length>i,c=o.slice(0,i);return{items:c,hasMore:s,nextSkip:r+c.length}}async function jt(e,t){if(!t)throw Error(`invalid_commit`);let{stdout:n}=await V(e,[`show`,`--no-color`,`--no-ext-diff`,`--format=`,t]);return n}function Mt(e,t){if(!t)throw Error(`invalid_commit`);let n=c(`git`,[`show`,`--no-color`,`--no-ext-diff`,`--format=`,t],{cwd:e});return new ReadableStream({start(e){let t=t=>{e.enqueue(t)},r=t=>{e.error(t)};n.stdout.on(`data`,t),n.stdout.on(`error`,r),n.on(`error`,r),n.on(`close`,t=>{if(t&&t!==0){e.error(Error(`git_failed`));return}e.close()})},cancel(){n.kill()}})}async function Nt(e,t){if(!t)throw Error(`invalid_commit`);let{stdout:n}=await V(e,[`show`,`--name-status`,`--no-ext-diff`,`--format=`,t]);return n.split(`
10
+ `).map(e=>e.trim()).filter(Boolean).map(e=>{let[t=``,...n]=e.split(` `),r=t[0]||``,i=r===`R`||r===`C`?n[1]||n[0]||``:n[0]||``,a=r===`R`&&n[0]||``,o={path:i,status:r===`A`?`added`:r===`D`?`deleted`:r===`R`?`renamed`:r===`C`?`added`:`modified`};return a&&a!==i&&(o.previousPath=a),o}).filter(e=>e.path)}async function Pt(e,t){if(!t)throw Error(`invalid_commit`);let{stdout:n}=await V(e,[`show`,`--numstat`,`--no-ext-diff`,`--format=`,t]),r=0;for(let e of n.split(`
11
+ `)){let t=e.trim();if(!t)continue;let[n,i]=t.split(` `);if(n===`-`||i===`-`)return null;let a=Number.parseInt(n||`0`,10),o=Number.parseInt(i||`0`,10);r+=(Number.isFinite(a)?a:0)+(Number.isFinite(o)?o:0)}return r}const Ft=e=>e.split(`\0`).filter(e=>e),It=e=>{let t={name:``,path:``,type:`folder`,children:new Map};for(let n of e){let e=n.replace(/\\/g,`/`).replace(/^\/+/,``);if(!e)continue;let r=e.split(`/`).filter(e=>e),i=t,a=``;for(let[e,t]of r.entries()){let n=a?`${a}/${t}`:t,o=e===r.length-1?`file`:`folder`,s=i.children.get(t);s||(s={name:t,path:n,type:o,children:new Map},i.children.set(t,s)),i=s,a=n}}let n=e=>{if(e.type===`file`)return{name:e.name,path:e.path,type:e.type};let t=Array.from(e.children.values()).map(n);return t.sort((e,t)=>e.type===t.type?e.name.localeCompare(t.name):e.type===`folder`?-1:1),{name:e.name,path:e.path,type:e.type,children:t}};return Array.from(t.children.values()).map(n).sort((e,t)=>e.type===t.type?e.name.localeCompare(t.name):e.type===`folder`?-1:1)};async function Lt(e){let[t,n]=await Promise.all([V(e,[`ls-files`,`-z`]),V(e,[`ls-files`,`-z`,`--others`,`--exclude-standard`])]),r=new Set([...Ft(t.stdout),...Ft(n.stdout)]);return It(Array.from(r))}const Rt=async(e,t={})=>{let{stdout:n}=await V(e,[`for-each-ref`,`--sort=-committerdate`,`--format=%(refname:short) %(committerdate:iso8601)`,`refs/heads`]),r=n.split(`
12
+ `).map(e=>e.trim()).filter(Boolean).map(e=>{let[t=``,n]=e.split(` `);return{name:t,updatedAt:n||null}});if(t.filter){let e=t.filter.toLowerCase();r=r.filter(t=>t.name.toLowerCase().includes(e))}if(t.cursor){let e=r.findIndex(e=>e.name===t.cursor);e>=0&&(r=r.slice(e+1))}let i=t.limit??30;return r.slice(0,i+1)};async function zt(e,t={}){let n=t.limit??30,r=await Rt(e,t),i=r.length>n,a=i?r.slice(0,n):r,o=i?a[a.length-1]?.name??null:null,s=await Bt(e);return{current:s,defaultBranch:await Vt(e,await Rt(e,{}),s),branches:a,hasMore:i,nextCursor:o}}const Bt=async e=>{let{stdout:t}=await V(e,[`rev-parse`,`--abbrev-ref`,`HEAD`]);return t.trim()},Vt=async(e,t,n)=>{try{let{stdout:t}=await V(e,[`symbolic-ref`,`--short`,`refs/remotes/origin/HEAD`]),n=t.trim().split(`/`).pop();if(n)return n}catch{}let r=new Set(t.map(e=>e.name));return r.has(`main`)?`main`:r.has(`master`)?`master`:n&&n!==`HEAD`?n:t[0]?.name||``},Ht=async(e,t)=>{if(!t)throw Error(`invalid_branch`);try{await V(e,[`check-ref-format`,`--branch`,t])}catch{throw Error(`invalid_branch`)}},Ut=async(e,t)=>{try{return await V(e,[`show-ref`,`--verify`,`--quiet`,`refs/heads/${t}`]),!0}catch{return!1}};async function Wt(e,t){if(await Ht(e,t),!await Ut(e,t))throw Error(`branch_not_found`);await V(e,[`checkout`,t])}async function Gt(e,t){if(await Ht(e,t),await Ut(e,t))throw Error(`branch_exists`);await V(e,[`checkout`,`-b`,t])}const Kt={"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`GET,POST,PATCH,OPTIONS`,"Access-Control-Allow-Headers":`Content-Type`},qt={invalid_json:400,not_a_directory:400,project_not_found:404,project_required:400,project_not_git:400,invalid_branch:400,branch_exists:409,branch_not_found:404,invalid_path:400,app_server_spawn_failed:500};function H(e){let t=new Headers(e.headers);for(let[e,n]of Object.entries(Kt))t.set(e,n);return new Response(e.body,{status:e.status,statusText:e.statusText,headers:t})}function U(e,t){return H(new Response(JSON.stringify(t),{status:e,headers:{"Content-Type":`application/json; charset=utf-8`}}))}function Jt(e,t){return H(new Response(t,{status:e,headers:{"Content-Type":`text/plain; charset=utf-8`}}))}function Yt(e,t){return H(new Response(t,{status:e,headers:{"Content-Type":`text/plain; charset=utf-8`}}))}function Xt(){return H(new Response(null,{status:204}))}async function Zt(e){let t=await e.text();if(!t)return null;try{return JSON.parse(t)}catch{throw Error(`invalid_json`)}}function Qt(e){if(e instanceof Error){let t=qt[e.message];if(t)return U(t,{error:e.message})}return A(e)?U(400,{error:`invalid_path`}):(k.error(e,`Unhandled server error`),U(500,{error:`server_error`}))}async function $t(t){let n=t?r.resolve(t):m.homedir(),i;try{i=await e.stat(n)}catch(e){throw A(e)?Error(`invalid_path`):e}if(!i.isDirectory())throw Error(`invalid_path`);let a=(await e.readdir(n,{encoding:`utf8`,withFileTypes:!0})).filter(e=>e.isDirectory()).map(e=>({name:e.name,path:r.join(n,e.name)})).sort((e,t)=>e.name.localeCompare(t.name));return{path:n,parent:n===r.parse(n).root?null:r.dirname(n),entries:a}}const en=`You are the Diffact MANAGER.
13
+ Your job is orchestration: delegate to worker agents and synthesize results.
14
+
15
+ Hard rules:
16
+ - You are NOT a worker. Do not do deep coding, exhaustive research, or long-form writing yourself.
17
+ - Use bash for direct local command execution when needed.
18
+ - Use spawn_worker for tasks that require deeper implementation, research, or longer execution.
19
+ - If spawn_worker is unavailable or fails, explain the limitation and ask the user to enable/configure a worker provider.
20
+ - If anything is ambiguous, ask a clarifying question BEFORE spawning workers.
21
+ - For filesystem/path/command-result questions, run bash first instead of guessing.
22
+ - Never claim command output or directory contents unless a tool returned that result.
23
+ - Using a tool is not a user-facing reply. After any tool call, always send a normal chat message describing what you did and what's next.
24
+
25
+ Tools:
26
+ - bash({ command, projectPath?, timeoutMs? }): run a local shell command.
27
+ - spawn_worker({ prompt, projectPath, continue? }): delegate a concrete task to a worker.
28
+ - task_progress({}): fetch task statuses.
29
+
30
+ Working style:
31
+ - Break the user request into the minimum number of worker tasks.
32
+ - Provide each worker clear context + expected output format.
33
+ - Track dependencies; don't start dependent tasks early.
34
+ - When tasks finish, produce a concise final report with conclusions and next steps.`,tn=`# Diffact: Manager prompt additions
35
+ #
36
+ # This file is appended to the built-in manager system prompt.
37
+ # Keep it short and focused. Avoid duplicating the default prompt.`,nn=async()=>{try{let t=(await e.readFile(Je,`utf8`)).trim();return!t||t===en||t===tn?``:t}catch(t){return A(t)?(await e.mkdir(I,{recursive:!0}),await e.writeFile(Je,`${tn}\n`,{mode:384}),``):(k.warn({err:t},`manager prompt additions load failed`),``)}},rn=async()=>{let e=await nn();return e?`${en}\n\n${e}`.trim():en};let an=Promise.resolve();const W=async t=>{let n={id:v(),timestamp:new Date().toISOString(),...t};an=an.then(async()=>{await e.mkdir(I,{recursive:!0}),await e.appendFile(L,`${JSON.stringify(n)}\n`,{mode:384})}).catch(e=>{k.warn({err:e},`history append failed`)}),await an},on=e=>{let t=null,n=new Map,r=new Map,i=new Map,a=e.recordAssistantFromStream!==!1,o=async t=>{await W({source:e.source,type:`user_message`,role:`user`,content:t,meta:e.meta})},s=async(n,r)=>{await W({source:e.source,type:`assistant_message`,role:`assistant`,runId:t??void 0,messageId:n,content:r,meta:e.meta})},c=async(n,r)=>{await W({source:e.source,type:`tool_call`,runId:t??void 0,toolCallId:n,tool:{name:r.name,args:r.args||null,input:r.input,result:r.result},meta:e.meta})},l=async(n,r)=>{r.trim()&&await W({source:e.source,type:`thinking`,runId:t??void 0,stepId:n,content:r,meta:e.meta})};return{recordUserMessage:o,handleEvent:async e=>{switch(e.type){case`RUN_STARTED`:t=e.runId??null;return;case`TEXT_MESSAGE_START`:n.set(e.messageId,``);return;case`TEXT_MESSAGE_CONTENT`:{let t=e.delta||e.content||``;if(!t)return;let r=n.get(e.messageId)||``;n.set(e.messageId,`${r}${t}`);return}case`TEXT_MESSAGE_END`:{let t=n.get(e.messageId)||``;n.delete(e.messageId),a&&await s(e.messageId,t);return}case`TOOL_CALL_START`:r.set(e.toolCallId,{name:e.toolName,args:``});return;case`TOOL_CALL_ARGS`:{let t=e,n=t.args||t.delta||``,i=r.get(e.toolCallId);i&&(i.args=t.args?String(n):`${i.args}${n}`);return}case`TOOL_CALL_END`:{let t=r.get(e.toolCallId);if(t){let n=e;t.input=n.input??t.input,t.result=n.result??t.result,await c(e.toolCallId,t),r.delete(e.toolCallId)}return}case`STEP_STARTED`:i.set(e.stepId,``);return;case`STEP_FINISHED`:{let t=typeof e.content==`string`&&e.content.length?e.content:e.delta||``;if(!t)return;let n=i.get(e.stepId)||``;i.set(e.stepId,t===e.content?t:`${n}${t}`);return}default:return}},finalize:async()=>{if(a)for(let[e,t]of n.entries())await s(e,t);n.clear();for(let[e,t]of r.entries())await c(e,t);r.clear();for(let[e,t]of i.entries())await l(e,t);i.clear()}}},sn=new te,cn=(e,t)=>sn.run(e,t),ln=()=>sn.getStore()||null,un=new Set,dn=e=>(un.add(e),()=>un.delete(e)),fn=e=>{let t={workerId:e,target:ln()?.workerTarget??null};for(let e of un)try{e(t)}catch(e){k.warn({err:e},`manager worker spawned listener failed`)}},pn=[`pending`,`running`,`completed`,`failed`],mn={tasks:[],updatedAt:new Date().toISOString()},G=e=>typeof e==`string`?e.trim():``,hn=e=>typeof e==`string`&&pn.includes(e)?e:null,gn=e=>{if(!e||typeof e!=`object`)return null;let t=e,n=G(t.id),r=G(t.title);if(!n||!r)return null;let i=hn(t.status)||`pending`,a=G(t.createdAt)||new Date().toISOString();return{id:n,title:r,status:i,createdAt:a,updatedAt:G(t.updatedAt)||a,workerId:G(t.workerId)||void 0,summary:G(t.summary)||void 0,error:G(t.error)||void 0}},_n=e=>{if(!e.trim())return null;try{let t=JSON.parse(e);return gn(t&&typeof t==`object`&&`task`in t?t.task:t)}catch{return null}},vn=async()=>{try{let t=(await e.readFile(Ye,`utf8`)).split(`
38
+ `),n=[],r=new Map;for(let e of t){let t=_n(e);if(!t)continue;let i=r.get(t.id);i===void 0?(r.set(t.id,n.length),n.push(t)):n[i]=t}return{tasks:n,updatedAt:new Date().toISOString()}}catch(e){return A(e)||k.warn({err:e},`task store jsonl read failed`),null}},yn=async t=>{await e.mkdir(I,{recursive:!0});let n=t.tasks.map(e=>JSON.stringify(e)).join(`
39
+ `),r=n?`${n}\n`:``;await e.writeFile(Ye,r,{mode:384})},bn=(e,t)=>e.length>t?`${e.slice(0,t)}...`:e,xn=async()=>{let e=await vn()||{...mn},t=Promise.resolve(),n=async()=>{e.updatedAt=new Date().toISOString(),t=t.then(()=>yn(e)).catch(e=>{k.warn({err:e},`task store save failed`)}),await t},r=()=>e.tasks,i=()=>({tasks:[...e.tasks]}),a=async({title:t,status:r=`pending`,workerId:i})=>{let a=new Date().toISOString(),o={id:v(),title:t.trim()||`Untitled task`,status:r,createdAt:a,updatedAt:a,workerId:i};return e.updatedAt=a,e.tasks=[...e.tasks,o],await n(),o},o=async(t,r)=>{let i=e.tasks.findIndex(e=>e.id===t);if(i===-1)return null;let a=e.tasks[i],o=new Date().toISOString(),s={...a,...r,summary:r.summary?bn(r.summary,2e3):a.summary,error:r.error?bn(r.error,1e3):a.error,updatedAt:o},c=[...e.tasks];return c[i]=s,e.updatedAt=o,e.tasks=c,await n(),s};return{list:r,getSnapshot:i,addTask:a,updateTask:o,updateTaskByWorker:async(t,n)=>{let r=e.tasks.find(e=>e.workerId===t);return r?o(r.id,n):null}}},Sn=new Set,Cn=e=>(Sn.add(e),()=>Sn.delete(e)),wn=e=>{for(let t of Sn)try{t(e)}catch(e){k.warn({err:e},`worker event listener failed`)}},Tn=5*6e4,K=2e4,En=2e4,Dn=e=>(e.trim().split(`
40
+ `)[0]||`Worker task`).slice(0,160),On=e=>e.length>K?`${e.slice(0,K)}...`:e,kn=(e,t=240)=>e.length>t?`${e.slice(0,t)}...`:e,An=e=>{if(!e)return``;let t=e.trim();return t?t===`~`?m.homedir():t.startsWith(`~/`)?r.join(m.homedir(),t.slice(2)):t:``},jn=async e=>{if(!e)return``;let t=e.getReader(),n=new TextDecoder,r=``;for(;;){let{value:e,done:i}=await t.read();if(i)break;r.length>=K||(r+=n.decode(e,{stream:!0}).slice(0,K-r.length))}return r.length<K&&(r+=n.decode().slice(0,K-r.length)),On(r)},Mn=e=>{let{taskStore:t,workerProviders:n,getWorkerProvider:r}=e,i=_.object({id:_.string(),title:_.string(),status:_.enum(pn),createdAt:_.string(),updatedAt:_.string(),workerId:_.string().optional(),summary:_.string().optional(),error:_.string().optional()}),a=[u({name:`task_progress`,description:`Get the current task list and status.`,inputSchema:_.object({}),outputSchema:_.object({tasks:_.array(i)})}).server(async()=>(k.info(`task_progress requested`),{tasks:t.getSnapshot().tasks}))],o=u({name:`bash`,description:`Execute a local shell command and return stdout/stderr/exit code.`,inputSchema:_.object({command:_.string().min(1),projectPath:_.string().min(1).optional(),timeoutMs:_.number().int().positive().max(Tn).optional()}),outputSchema:_.object({ok:_.boolean(),cwd:_.string(),exitCode:_.number().nullable(),signal:_.string().nullable(),timedOut:_.boolean(),stdout:_.string(),stderr:_.string(),error:_.string().optional()})});a.push(o.server(async e=>{let{command:t,projectPath:n,timeoutMs:r}=e,i=An(n),a=i?(await j(i)).rootPath:process.cwd(),o=ve()||`/bin/sh`,s=ye(o,t),c=Math.min(r??6e4,Tn),l=Date.now(),u=!1,d=null,f=null,p=null;k.info({cwd:a,requestedProjectPath:i||null,shellPath:o,timeoutMs:c,commandPreview:kn(t)},`manager bash requested`);try{let e=N.spawn([o,...s],{cwd:a,env:{...process.env,SHELL:o,TERM:`xterm-256color`,FORCE_COLOR:`1`,CLICOLOR_FORCE:`1`}});d=e,f=setTimeout(()=>{u=!0,e.kill(`SIGTERM`),p=setTimeout(()=>{e.kill(`SIGKILL`)},1e3)},c);let[t,n,r]=await Promise.all([jn(e.stdout),jn(e.stderr),e.exited]);clearTimeout(f),p&&clearTimeout(p);let i=e.signalCode?String(e.signalCode):null,m=!u&&r===0;return k.info({cwd:a,shellPath:o,exitCode:e.exitCode??r??null,signal:i,timedOut:u,ok:m,stdoutLength:t.length,stderrLength:n.length,durationMs:Date.now()-l},`manager bash completed`),{ok:m,cwd:a,exitCode:e.exitCode??r??null,signal:i,timedOut:u,stdout:t,stderr:n,error:m?void 0:u?`command_timeout`:`command_failed`}}catch(e){return f&&clearTimeout(f),p&&clearTimeout(p),k.warn({err:e,cwd:a,shellPath:o,requestedProjectPath:i||null,timedOut:u,durationMs:Date.now()-l,commandPreview:kn(t)},`manager bash failed`),{ok:!1,cwd:a,exitCode:d?.exitCode??null,signal:d?.signalCode?String(d.signalCode):null,timedOut:u,stdout:``,stderr:``,error:e instanceof Error?e.message:`command_failed`}}}));let s=async()=>{if(!n||n.size===0)return null;let e=r?await r():null;if(e){let t=n.get(e);if(t)return{id:e,...t}}let t=n.entries().next().value;if(!t)return null;let[i,a]=t;return{id:i,...a}};if(n&&n.size>0){let e=u({name:`spawn_worker`,description:`Spawn a worker agent to handle a task.`,inputSchema:_.object({prompt:_.string(),projectPath:_.string().min(1),continue:_.boolean().optional()}),outputSchema:_.object({workerId:_.string(),result:_.string()})});a.push(e.server(async e=>{let{prompt:n,projectPath:r,continue:i}=e,a=await s();if(!a)return k.warn(`spawn_worker failed: no available worker`),{workerId:``,result:`No worker available. Check worker providers and retry.`};k.info({promptLength:n.length,provider:a.id,command:a.command||a.id,continue:i===!0},`spawn_worker requested`);let{id:o,agent:c}=a.pool.spawn(),l=Dn(n),u=await t.addTask({title:l,status:`running`,workerId:o}),d=on({source:`worker`,meta:{workerId:o,taskId:u.id,provider:a.id,projectPath:r}});return await d.recordUserMessage(n),k.info({workerId:o,taskId:u.id},`worker started`),fn(o),(async()=>{let e=``,s=null,l=!1,f=new Map,p=``;try{for await(let t of c.chat({messages:[{role:`user`,content:n}],projectPath:r,continue:i})){if(await d.handleEvent(t),(t.type===`RUN_FINISHED`||t.type===`RUN_ERROR`)&&(l=!0),t.type===`RUN_ERROR`){let e=t.error?.message;s=typeof e==`string`&&e.trim()?e:`worker_failed`}if(t.type===`TEXT_MESSAGE_CONTENT`){let n=t.delta;if(typeof n==`string`){let r=t,i=typeof r.messageId==`string`?r.messageId:``;if(i){let e=f.get(i)||``;e.length<En&&f.set(i,`${e}${n}`.slice(0,En))}else e.length<En&&(e=`${e}${n}`.slice(0,En))}}if(t.type===`TEXT_MESSAGE_END`){let e=t,n=typeof e.messageId==`string`?e.messageId:``;if(!n)continue;let r=(f.get(n)||``).trim();f.delete(n),r&&(p=r)}}}catch(e){s=e instanceof Error?e.message:`worker_failed`}finally{if(!p&&f.size>0){let e=Array.from(f.values()),t=e[e.length-1]?.trim()||``;t&&(p=t)}let n=(p||e).trim();await d.finalize(),a.pool.release(o),await t.updateTask(u.id,{status:s?`failed`:`completed`,summary:n,error:s||void 0}),k.info({workerId:o,taskId:u.id,error:s||null},`worker finished`),(l||s)&&wn({taskId:u.id,workerId:o,status:s?`failed`:`completed`,output:n,error:s})}})(),{workerId:o,result:`Worker ${o} started: ${l}.`}}))}else k.warn(`spawn_worker disabled: no worker providers available`);return a},Nn=e=>e.replace(/\s+/g,` `).trim(),Pn=e=>{let t=Nn(e);return t?t.length<=240?t:t.slice(0,240).trim():``},Fn=async t=>{let n=Pn(t);if(!n)return!1;let r=`- ${n}`,i=``;try{i=await e.readFile(R,`utf8`)}catch(e){if(!A(e))throw e}return new Set(i.split(/\r?\n/).map(e=>e.trim()).filter(Boolean)).has(r)?!1:(await e.appendFile(R,`${r}\n`,{mode:384}),!0)},In=async t=>{try{return(await e.readdir(Qe,{withFileTypes:!0})).filter(e=>e.isFile()&&e.name.endsWith(`.md`)).map(e=>e.name).sort((e,t)=>t.localeCompare(e)).slice(0,Math.max(1,t)).map(e=>r.join(Qe,e))}catch(e){if(A(e))return[];throw e}},Ln=async t=>{let n=await In(t),r=[];for(let t of n)try{let n=await e.readFile(t,`utf8`);r.push({file:t,content:n})}catch(e){if(A(e))continue;throw e}return r},Rn=async t=>{try{let n=(await e.readFile(L,`utf8`)).split(/\r?\n/).filter(Boolean);return n.length<=t?n.join(`
41
+ `):n.slice(-t).join(`
42
+ `)}catch(e){if(A(e))return``;throw e}},zn=e=>{try{return JSON.parse(e)}catch{return null}},Bn=async(e,t,n,r,i)=>{if(!n.length||i<=0)return[];let a=[`--json`,`--line-number`,`--no-heading`,`--color`,`never`,`--fixed-strings`,`--max-count`,String(i),t,...n],o=N.spawn([e,...a],{}),s=o.stdout;if(!s)return[];let c=[],l=s.getReader(),u=new TextDecoder,d=``;for(;;){let{value:e,done:t}=await l.read();if(t)break;d+=u.decode(e,{stream:!0});let n=d.indexOf(`
43
+ `);for(;n!==-1;){let e=d.slice(0,n).trim();if(d=d.slice(n+1),e){let t=zn(e);if(t?.type===`match`&&t.data){let e=t.data.path?.text||``,n=typeof t.data.line_number==`number`?t.data.line_number:0,a=Nn(t.data.lines?.text||``);if(e&&n>0&&a&&(c.push({source:r,file:e,line:n,text:a.slice(0,400)}),c.length>=i)){o.kill(`SIGTERM`);break}}}n=d.indexOf(`
44
+ `)}if(c.length>=i)break}let f=await o.exited;return f!==0&&f!==1&&c.length===0?[]:c.slice(0,i)},Vn=async(e,t,n,r)=>{let i=N.which(`rg`);if(!i)return null;let a=t===`all`||t===`memory`,o=t===`all`||t===`daily`,s=t===`all`||t===`transcript`,c=[];if(a&&c.length<n){let t=await Bn(i,e,[R],`memory`,n-c.length);c.push(...t)}if(o&&c.length<n){let t=await Bn(i,e,await In(r),`daily`,n-c.length);c.push(...t)}if(s&&c.length<n){let t=await Bn(i,e,[L],`transcript`,n-c.length);c.push(...t)}return c.slice(0,n)},Hn=(e,t,n,r,i)=>{let a=r.toLowerCase(),o=n.split(/\r?\n/),s=[];for(let n=0;n<o.length&&s.length<i;n+=1){let r=o[n];if(!r||!r.toLowerCase().includes(a))continue;let i=Nn(r);i&&s.push({source:e,file:t,line:n+1,text:i.slice(0,400)})}return s},Un=async(t,n,r,i,a)=>{let o=await Vn(t,n,r,i);if(o)return o;let s=n===`all`?[`memory`,`daily`,`transcript`]:[n],c=[];if(s.includes(`memory`))try{let n=await e.readFile(R,`utf8`);c.push(...Hn(`memory`,R,n,t,r))}catch(e){if(!A(e))throw e}if(s.includes(`daily`)&&c.length<r){let e=await Ln(i);for(let n of e){if(c.length>=r)break;let e=r-c.length;c.push(...Hn(`daily`,n.file,n.content,t,e))}}if(s.includes(`transcript`)&&c.length<r){let e=await Rn(a);if(e){let n=r-c.length;c.push(...Hn(`transcript`,L,e,t,n))}}return c.slice(0,r)},Wn=e=>{let t=e?.enableAppend!==!1,n=e?.enableGrep!==!1,r=Math.max(1,e?.dailyFileLimit??14),i=Math.max(100,e?.transcriptLineLimit??2e3),a=[];if(t){let e=u({name:`memory_append`,description:`Append one durable memory line to MEMORY.md.`,inputSchema:_.object({content:_.string().min(1).max(1e3)}),outputSchema:_.object({appended:_.boolean()})});a.push(e.server(async e=>{let{content:t}=e;return{appended:await Fn(t)}}))}if(n){let e=u({name:`memory_grep`,description:`Search persisted memory/history files by query string and return matching lines.`,inputSchema:_.object({query:_.string().min(1).max(200),source:_.enum([`memory`,`daily`,`transcript`,`all`]).optional(),limit:_.number().int().min(1).max(100).optional()}),outputSchema:_.object({hits:_.array(_.object({source:_.enum([`memory`,`daily`,`transcript`]),file:_.string(),line:_.number().int().positive(),text:_.string()}))})});a.push(e.server(async e=>{let{query:t,source:n,limit:a}=e;return{hits:await Un(t.trim(),n??`all`,a??20,r,i)}}))}return a},Gn=r.join(I,`memory-writer.cursor`),Kn=8e3,qn=`You are a memory summary agent.
45
+ Summarize a conversation chunk into one short line.
46
+ Keep concrete facts, preferences, tasks, and decisions.
47
+ Do not invent or speculate. No bullet, no quotes, no extra text.
48
+ Max 140 characters.`,Jn=e=>new Promise(t=>setTimeout(t,e)),Yn=async()=>{await e.mkdir(I,{recursive:!0}),await e.mkdir(Qe,{recursive:!0});try{await e.access(R)}catch(t){if(A(t)){await e.writeFile(R,`# MEMORY
49
+
50
+ `,{mode:384});return}throw t}},Xn=async()=>{try{let t=await e.readFile(Gn,`utf8`),n=JSON.parse(t);if(typeof n.byteOffset==`number`&&Number.isFinite(n.byteOffset))return{byteOffset:Math.max(0,n.byteOffset),lastId:typeof n.lastId==`string`?n.lastId:null,pending:n.pending&&typeof n.pending==`object`&&typeof n.pending.id==`string`&&typeof n.pending.timestamp==`string`&&typeof n.pending.text==`string`?{id:n.pending.id,timestamp:n.pending.timestamp,text:n.pending.text}:null}}catch(e){if(A(e))return{byteOffset:0,lastId:null,pending:null}}return{byteOffset:0,lastId:null,pending:null}},Zn=async t=>{let n=`${Gn}.tmp`;await e.writeFile(n,JSON.stringify(t),{mode:384}),await e.rename(n,Gn)},Qn=e=>{if(typeof e==`string`){let t=new Date(e);if(!Number.isNaN(t.getTime()))return t}return new Date},$n=e=>Qn(e).toISOString().slice(0,10),er=e=>Qn(e).toISOString().slice(11,16),tr=e=>{let t=e.replace(/\s+/g,` `).trim();return t?t.length<=160?t:t.slice(0,160).trim():``},nr=e=>tr(e),rr=e=>e.replace(/\s+/g,` `).trim(),ir=(e,t,n)=>{let r=rr(n);if(!r)return e;let i=`${t}: ${r}`,a=e?`${e}\n${i}`:i;return a.length<=Kn?a:a.slice(0,Kn).trim()},ar=(e,t,n,r)=>{let i=er(t),a=r===void 0?t:r;return`- [${i}] ${e} (ref: id=${n} ts=${String(a)})`},or=async(t,n)=>{let i=$n(t),a=r.join(Qe,`${i}.md`);await e.appendFile(a,`${n}\n`,{mode:384})},sr=async(t,n,r)=>{let i=`${t}\t${n}\t${typeof r==`string`?r:``}\n`;await e.appendFile(Xe,i,{mode:384})},cr=async()=>({summaryAgent:new F({type:`embedded`,model:null,modelProvider:async()=>vt(await B()),systemPrompt:qn}),workerAgent:new F({type:`embedded`,model:null,modelProvider:async()=>vt(await B()),systemPrompt:`You are a memory worker.
51
+ Review the conversation chunk and decide whether to store durable memory.
52
+ Use memory_append only for stable preferences, long-term constraints,
53
+ persistent decisions, and identity facts.
54
+ Use memory_grep when you need to check existing memory/history before writing.
55
+ Do not store transient progress, command logs, or one-off status.
56
+ After tool calls, reply with "ok".`,tools:Wn()})}),lr=async(e,t)=>{let n=`conversation:\n${t}`;return tr(await e.chatOneShot({messages:[{role:`user`,content:n}],systemPrompt:qn}))},ur=async(e,t)=>{if(!t.trim())return``;if(!e)return nr(t);try{return await lr(e,t)||nr(t)}catch(e){return k.warn({err:e},`memory writer: summarize failed`),nr(t)}},dr=async(e,t,n)=>{if(!e||!t.trim())return;let r=`summary: ${n}\nconversation:\n${t}`;try{for await(let t of e.chat({messages:[{role:`user`,content:r}]}));}catch(e){k.warn({err:e},`memory writer: memory worker failed`)}},fr=async(e,t,n)=>{let r=await ur(n.summaryAgent,e.text);r&&(await or(t,ar(r,t,e.id,e.timestamp)),await dr(n.workerAgent,e.text,r))},pr=async(e,t,n,r,i)=>{if(!e.trim())return{lastId:n,pending:r};let a;try{a=JSON.parse(e)}catch(e){return k.warn({err:e},`memory writer: invalid jsonl line`),{lastId:n,pending:r}}let o=typeof a.id==`string`?a.id:``;if(!o||o===n)return{lastId:n,pending:r};let s=typeof a.ts==`string`?a.ts:typeof a.timestamp==`string`?a.timestamp:new Date().toISOString();await sr(o,t,s);let c=typeof a.role==`string`?a.role:``,l=typeof a.content==`string`?a.content:``;return c===`user`?(r&&await fr(r,s,i),{lastId:o,pending:{id:o,timestamp:s,text:ir(``,c,l)}}):c===`assistant`&&r?{lastId:o,pending:{...r,text:ir(r.text,c,l)}}:{lastId:o,pending:r}},mr=async(t,n)=>{let r=null;try{r=await e.stat(L)}catch(e){if(A(e))return t;throw e}if(!r||r.size<=t.byteOffset)return t;let i=await e.open(L,`r`),a=r.size-t.byteOffset,o=Buffer.allocUnsafe(a),{bytesRead:s}=await i.read(o,0,a,t.byteOffset);if(await i.close(),s<=0)return t;let c=o.subarray(0,s),l=t.byteOffset,u=0,d=t.lastId,f=t.pending;for(let e=0;e<c.length;e+=1){if(c[e]!==10)continue;let t=c.subarray(u,e),r=l+u,i=await pr(t.toString(`utf8`),r,d,f,n);d=i.lastId,f=i.pending,u=e+1}let p={byteOffset:l+u,lastId:d,pending:f};return(p.byteOffset!==t.byteOffset||p.lastId!==t.lastId||JSON.stringify(p.pending)!==JSON.stringify(t.pending))&&await Zn(p),p},hr=async()=>{await Yn();let e=await cr(),t=await Xn();k.info({cursor:t},`memory writer started`);let n=!0,r=()=>{n=!1},i=(async()=>{for(;n;){try{t=await mr(t,e)}catch(e){k.warn({err:e},`memory writer loop failed`)}await Jn(1e3)}})();return{stop:async()=>{r(),await i},done:i}},gr={".html":`text/html; charset=utf-8`,".css":`text/css; charset=utf-8`,".js":`application/javascript; charset=utf-8`,".mjs":`application/javascript; charset=utf-8`,".json":`application/json; charset=utf-8`,".png":`image/png`,".jpg":`image/jpeg`,".jpeg":`image/jpeg`,".gif":`image/gif`,".svg":`image/svg+xml`,".ico":`image/x-icon`,".woff":`font/woff`,".woff2":`font/woff2`,".ttf":`font/ttf`,".eot":`application/vnd.ms-fontobject`,".webp":`image/webp`,".avif":`image/avif`,".mp4":`video/mp4`,".webm":`video/webm`,".txt":`text/plain; charset=utf-8`,".map":`application/json`},_r={avif:`image/avif`,bmp:`image/bmp`,gif:`image/gif`,ico:`image/x-icon`,jpeg:`image/jpeg`,jpg:`image/jpeg`,png:`image/png`,svg:`image/svg+xml`,webp:`image/webp`,mp4:`video/mp4`,mov:`video/quicktime`,ogv:`video/ogg`,webm:`video/webm`,mp3:`audio/mpeg`,m4a:`audio/mp4`,ogg:`audio/ogg`,wav:`audio/wav`,flac:`audio/flac`,pdf:`application/pdf`};function vr(e){return gr[r.extname(e).toLowerCase()]||`application/octet-stream`}function yr(e){return _r[r.extname(e).slice(1).toLowerCase()]||`application/octet-stream`}function br(e){let t=process.platform===`darwin`?[`open`,e]:process.platform===`win32`?[`cmd`,`/c`,`start`,``,e]:[`xdg-open`,e];N.spawn(t)}function xr(){return z!==null}function Sr(){return z}async function Cr(e){if(!z)return null;let t=e.replace(/^\/+/,``)||`index.html`,n=!r.extname(t)||t===`index.html`,i=r.join(z,`index.html`),a=et(z,r.resolve(z,t));if(!a)return null;try{return p.statSync(a).isFile()?wr(a):!r.extname(t)&&p.existsSync(i)?wr(i):null}catch{return n&&p.existsSync(i)?wr(i):null}}function wr(e){let t=N.file(e);return new Response(t.stream(),{status:200,headers:{"Content-Type":vr(e),"Content-Length":String(t.size),"Cache-Control":e.includes(`/assets/`)?`public, max-age=31536000, immutable`:`no-cache`}})}const Tr=/([_*\[\]\(\)~`>#+=|{}.!\\-])/g,q=e=>e.replace(Tr,`\\$1`),Er=e=>e.replace(/([`\\])/g,`\\$1`),J=e=>typeof e==`string`?e.trim():``,Y=e=>typeof e==`number`&&Number.isFinite(e)?e:null,Dr=e=>{let t=``,n=0;for(;n<e.length;){let r=e.indexOf("```",n),i=e.indexOf("`",n),a=r!==-1&&(i===-1||r<=i)?r:i;if(a===-1){t+=q(e.slice(n));break}if(a>n&&(t+=q(e.slice(n,a)),n=a),a===r){let i=e.indexOf(`
57
+ `,r+3);if(i===-1){t+=q(e.slice(r));break}let a=e.indexOf("```",i+1);if(a===-1){t+=q(e.slice(r));break}let o=e.slice(r+3,i),s=e.slice(i+1,a);t+="```"+o+`
58
+ `+Er(s)+"```",n=a+3;continue}let o=e.indexOf("`",i+1);if(o===-1){t+=q(e.slice(i,i+1)),n=i+1;continue}let s=e.slice(i+1,o);t+="`"+Er(s)+"`",n=o+1}return t},Or=e=>{let t=e.trim();if(!t)return``;try{let e=JSON.parse(t);if(typeof e.detail==`string`)return e.detail.trim();if(e.detail&&typeof e.detail==`object`){let t=e.detail,n=J(t.message);if(n)return n}let n=J(e.message);if(n)return n}catch{}return t.replace(/\s+/g,` `)},kr=e=>{let t=e instanceof Error?J(e.message):``,n=e&&typeof e==`object`&&`details`in e?J(e.details):``;return(e&&typeof e==`object`&&`providerMessage`in e&&typeof e.providerMessage==`string`?J(e.providerMessage):``)||Or(n)||(t&&!t.startsWith(`elevenlabs_http_`)?t:`Voice generation failed. Please retry.`)},Ar=(e,t=320)=>{let n=e.replace(/\s+/g,` `).trim();return n.length<=t?n:`${n.slice(0,t)}...`},jr=e=>{if(!e.trim())return null;let t;try{t=JSON.parse(e)}catch{return null}if(J(t.source)!==`telegram`)return null;let n=J(t.role);if(n!==`user`&&n!==`assistant`)return null;let r=J(t.type);if(r!==`user_message`&&r!==`assistant_message`)return null;let i=J(t.content);if(!i)return null;let a=t.meta&&typeof t.meta==`object`?t.meta:null,o=Y(a?.chatId);return o?{chatId:o,role:n,content:i,messageId:Y(a?.messageId)}:null},Mr=(e,t)=>{if(e.length<=t)return[e];let n=[],r=0,i=!1,a=``;for(;r<e.length;){let o=``;i&&a&&(o+=a);let s=i?3:0;for(;r<e.length;){let n=t-s;if(o.length>=n)break;if(e.startsWith("```",r)){if(i){if(o.length+3>n)break;o+="```",r+=3,i=!1,a=``,s=0;continue}let t=e.indexOf(`
59
+ `,r+3);if(t===-1){let t=e.slice(r);if(o.length+t.length>n)break;o+=t,r=e.length;continue}let c=e.slice(r,t+1);if(o.length+c.length>n)break;o+=c,r=t+1,i=!0,a=c,s=3;continue}if(o.length+1>n)break;o+=e[r],r+=1}if(!o){let o=Math.min(r+t,e.length);n.push(e.slice(r,o)),r=o,i=!1,a=``;continue}i&&(o+="```"),n.push(o)}return n.length?n:[e]},Nr=async e=>{let t=e.message.chat.id,n=e.message.from?.id,r=e.agentResult.reply.trim();if(!r){k.warn({chatId:t,messageId:e.message.message_id},`telegram reply empty`);return}let i=e.agentResult.replyMode===`voice`;if(!(e.forceVoice||i&&e.voiceEnabled)){await e.sendFormattedMessage(t,r),await e.appendAssistantMessageHistory(t,n,r);return}let a=e.startChatAction(t,`record_voice`),o=!1,s=``;try{await e.sendVoiceReply(t,r),o=!0}catch(n){s=`${kr(n)}\n\n${r}`,k.warn({err:n,chatId:t,messageId:e.message.message_id},`telegram voice reply failed`)}finally{a()}let c=e.forceVoice?`forced`:i?`manager_tool`:`text`;if(o){try{await e.sendFormattedMessage(t,r)}catch(n){k.warn({err:n,chatId:t,messageId:e.message.message_id},`telegram voice text fallback failed`)}await e.appendAssistantMessageHistory(t,n,r,{voice:!0,text:!0,voiceMode:c})}s&&(await e.sendFormattedMessage(t,s),await e.appendAssistantMessageHistory(t,n,s,{voice:!1,voiceMode:c}))},Pr=2e3,Fr=2400,Ir=`eleven_v3`,Lr=1800,Rr=8e3,zr=[`You write concise user-facing Telegram updates about tasks.`,`Return a short summary message about the current state.`,`Do not mention internal architecture, tool names, IDs, JSON, or stack traces.`,`When there is an error, summarize the cause and what happens next.`].join(`
60
+ `),Br=[`You prepare speech scripts for ElevenLabs voice synthesis.`,`Keep the meaning unchanged and wording concise.`,`Add only lightweight performance tags when helpful (for example: [pause], [laughs softly], [whispers]).`,`Return plain text only, no markdown and no explanations.`].join(`
61
+ `),Vr=[`You are the memory worker for this app.`,`Your job is supplemental context retrieval only.`,`MEMORY.md durable memory is provided separately.`,`Decide whether daily/transcript lookup is needed for this user message.`,`Use memory_grep only when it helps answer the user message.`,`If supplemental retrieval is unnecessary or empty, return exactly "none".`,`Return concise bullets only. Do not invent facts.`].join(`
62
+ `),Hr=_.object({reply:_.string(),replyMode:_.enum([`text`,`voice`])}),Ur=async()=>{let e=await nn();return e?`${zr}\n\n${e}`.trim():zr},Wr=async()=>{let[t,n,i]=await Promise.all([nn(),(async()=>{try{return(await e.readFile(r.join(process.cwd(),`AGENTS.md`),`utf8`)).trim().slice(0,Rr)}catch{return``}})(),(async()=>{try{return(await e.readFile(Ze,`utf8`)).trim().slice(0,Rr)}catch(e){return A(e)||k.warn({err:e},`telegram voice prompt load failed`),``}})()]),a=[Br];return i&&a.push(`Voice persona from VOICE.md:\n${i}`),n&&a.push(`Project AGENTS.md persona:\n${n}`),t&&a.push(`Additional AGENTS persona:\n${t}`),a.join(`
63
+
64
+ `).trim()},Gr=e=>[`Summarize this task failure for the user.`,`Keep it concise and practical.`,`Error details:`,Ar(e,2e3)].join(`
65
+ `),Kr=async(e,t)=>J(await e.chatOneShot({messages:[{role:`user`,content:t}],projectPath:null,systemPrompt:await Ur()})),qr=async e=>{let t=Date.now();k.info({promptLength:e.prompt.length},`telegram agent start`);try{let n=await cn({workerTarget:e.target},()=>e.agent.chatStructured({messages:[{role:`user`,content:e.prompt}],projectPath:null,outputSchema:Hr})),r=J(n.reply),i=n.replyMode===`voice`?`voice`:`text`;if(k.info({durationMs:Date.now()-t,outputLength:r.length,replyMode:i},`telegram agent complete`),r)return{reply:r,replyMode:i}}catch(e){k.warn({err:e},`telegram structured agent failed`)}let n=[`Write one concise status update for the user.`,`Do not mention internal architecture or tool names.`,`Latest user message: ${e.prompt.trim()||`(empty)`}`].join(`
66
+ `);return{reply:await Kr(e.agent,n),replyMode:`text`}},Jr=async e=>{let t=null;try{t=await e.json()}catch{t=null}if(!e.ok||!t||!t.ok){let n=Error(t?.description||`telegram_http_${e.status}`);throw typeof t?.error_code==`number`?n.code=t.error_code:n.code=e.status,n}return t.result},Yr=async(e,t,n)=>Jr(await fetch(`https://api.telegram.org/bot${e}/${t}`,{method:`POST`,...n})),Xr=async(e,t,n,r)=>Yr(e,t,{headers:{"Content-Type":`application/json`},body:JSON.stringify(n),signal:r}),Zr=async(e,t,n,r)=>Yr(e,t,{body:n,signal:r}),Qr=async(e,t,n,r)=>Xr(e,`getUpdates`,{offset:t?t+1:0,timeout:n,limit:50,allowed_updates:[`message`]},r),$r=async e=>{let t=e.message.chat.id,n=e.message.from?.id;if(e.command?.command===`/start`)return e.paired?(k.info({chatId:t},`telegram already paired`),await e.sendAndTrackMessage(t,n,`Already paired.`),null):(await e.sendPairingMessage(e.message,!0),null);if(e.command?.command===`/unpair`)return await e.handleUnpair(t,n),null;if(!e.paired)return await e.sendPairingMessage(e.message,!1),null;let r=e.command?.command===`/voice`,i=r?(e.command?.args||[]).join(` `).trim():e.text;return r&&!i?(await e.sendAndTrackMessage(t,n,`Usage: /voice <message>`),null):{managerInput:i,forceVoice:r}},ei=(e,t)=>{if(!e||typeof e!=`object`)return null;let n=e,r=Y(n.chatId),i=Y(n.userId),a=J(n.code);return!r||!i||t.requireCode&&!a?null:{chatId:r,userId:i,code:a,username:J(n.username)||void 0,firstName:J(n.firstName)||void 0}},ti=e=>{let t=ei(e,{requireCode:!1});if(!t)return null;let n=J(e.pairedAt)||new Date().toISOString();return{chatId:t.chatId,userId:t.userId,code:t.code,pairedAt:n,username:t.username,firstName:t.firstName}},ni=e=>{let t=ei(e,{requireCode:!0});if(!t)return null;let n=J(e.createdAt)||new Date().toISOString();return{chatId:t.chatId,userId:t.userId,code:t.code,createdAt:n,username:t.username,firstName:t.firstName}},ri=e=>!e||typeof e!=`object`||Array.isArray(e)?{}:{...e},ii=e=>{if(!e||typeof e!=`object`)return{botToken:``,elevenlabsApiKey:``,elevenlabsVoiceId:``,elevenlabsModelId:``,pending:[],paired:[],lastUpdateId:0};let t=e;return{botToken:J(t.botToken),elevenlabsApiKey:J(t.elevenlabsApiKey),elevenlabsVoiceId:J(t.elevenlabsVoiceId),elevenlabsModelId:J(t.elevenlabsModelId),pending:Array.isArray(t.pending)?t.pending.map(ni).filter(e=>!!e):[],paired:Array.isArray(t.paired)?t.paired.map(ti).filter(e=>!!e):[],lastUpdateId:Y(t.lastUpdateId)||0}},ai=async()=>ri(await tt(`config read failed`)),oi=async e=>nt(e),si=async()=>ii((await ai()).telegram),ci=async e=>{let t=await ai();t.telegram=e,await oi(t)},li=async e=>{await W({source:`telegram`,type:`assistant_message`,role:`assistant`,content:e.content,meta:{chatId:e.chatId,userId:e.userId,...e.meta||{}}})},ui=async e=>{await e.sendMessage(e.chatId,e.text),await li({chatId:e.chatId,userId:e.userId,content:e.text})},di=e=>new Promise(t=>setTimeout(t,e)),fi=()=>String(d.randomInt(1e5,999999)),pi=async(e,t=4e3)=>{if(!e)return``;let n=e.getReader(),r=new TextDecoder,i=``;for(;;){let{value:e,done:a}=await n.read();if(a)break;let o=r.decode(e,{stream:!0});i.length<t&&(i+=o.slice(0,t-i.length))}let a=r.decode();return i.length<t&&(i+=a.slice(0,t-i.length)),i.slice(0,t).trim()},mi=async t=>{let n=await e.stat(L);if(n.size<=0)return``;let r=Math.max(0,n.size-t),i=n.size-r,a=await e.open(L,`r`),o=``;try{let e=Buffer.allocUnsafe(i),{bytesRead:t}=await a.read(e,0,i,r);o=e.subarray(0,t).toString(`utf8`)}finally{await a.close()}if(r<=0)return o;let s=o.indexOf(`
67
+ `);return s>=0?o.slice(s+1):``},hi=(e,t,n)=>{if(!e.trim())return{context:`none`,count:0};let r=e.split(`
68
+ `),i=[];for(let e=r.length-1;e>=0&&i.length<12;--e){let a=jr(r[e]||``);!a||a.chatId!==t||a.role===`user`&&a.messageId===n||i.push({role:a.role,content:Ar(a.content,280)})}if(!i.length)return{context:`none`,count:0};i.reverse();let a=i.map(e=>`- ${e.role}: ${e.content}`).join(`
69
+ `);return{context:a.length>Fr?`${a.slice(0,Fr)}...`:a,count:i.length}},gi=(e,t,n,r)=>{let i=J(t)||`none`,a=J(n),o=J(r),s=[`User message:`,e,``,`Durable memory from MEMORY.md:`,i];return a&&a.toLowerCase()!==`none`&&s.push(``,`Supplemental context from daily/transcript:`,a),o&&o.toLowerCase()!==`none`&&s.push(``,`Recent conversation context from transcript (same Telegram chat):`,o),s.push(``,`Use memory and recent chat context only when relevant.`,`Current user instruction has priority.`,`Structured response requirements:`,`- reply: user-facing Telegram message text.`,`- replyMode: "voice" only when spoken delivery is clearly better; otherwise "text".`,`Prefer "text" for code, commands, logs, links, or long structured content.`),s.join(`
70
+ `)},_i=e=>{let t=e.trim();if(!t.startsWith(`/`))return null;let[n,...r]=t.split(/\s+/);if(!n)return null;let i=n.split(`@`)[0];return i?{command:i.toLowerCase(),args:r}:null},vi=async()=>{try{return(await e.readFile(R,`utf8`)).trim()||`none`}catch(e){return A(e)||k.warn({err:e},`telegram durable memory read failed`),`none`}},yi=async(e,t)=>{try{let n=hi(await mi(524288),e,t);return n.count<=0?`none`:(k.info({chatId:e,currentMessageId:t,contextMessageCount:n.count,contextLength:n.context.length,contextPreview:Ar(n.context,300)},`telegram transcript context loaded`),n.context)}catch(t){return A(t)||k.warn({err:t,chatId:e},`telegram transcript context load failed`),`none`}},bi=async(e,t)=>{let n=[`User message:`,t,``,`Decide whether extra context from daily/transcript is needed.`,`If needed, call memory_grep with source set to daily, transcript, or all.`,`Do not use source=memory in this step.`,`Return concise bullets, or exactly "none".`].join(`
71
+ `);try{let r=J(await e.chatOneShot({messages:[{role:`user`,content:n}],projectPath:null,systemPrompt:Vr}));return k.info({userMessageLength:t.length,supplementalLength:r.length,supplementalPreview:r?Ar(r,300):``},`telegram supplemental memory lookup complete`),r}catch(e){return k.warn({err:e},`telegram supplemental memory lookup failed`),``}},xi=e=>{e.pending=[],e.paired=[],e.lastUpdateId=0},Si=e=>{e.pending=[],e.paired=[]},Ci=(e,t)=>e.paired.find(e=>e.chatId===t),wi=(e,t)=>{let n=t.trim();if(!n)return null;let r=e.pending.findIndex(e=>e.code===n);if(r<0)return null;let i=e.pending[r];return i?(e.pending=e.pending.filter((e,t)=>t!==r),e.paired=e.paired.filter(e=>e.chatId!==i.chatId),e.paired=[...e.paired,{chatId:i.chatId,userId:i.userId,code:i.code,username:i.username,firstName:i.firstName,pairedAt:new Date().toISOString()}],i):null},Ti=(e,t)=>{let n=new Set([...e.pending.map(e=>e.code),...e.paired.map(e=>e.code).filter(Boolean)]),r=t();for(;n.has(r);)r=t();return r},Ei=(e,t,n)=>{let r=t.chat.id,i=e.pending.find(e=>e.chatId===r);if(i)return{pending:i,created:!1};let a=t.from,o={chatId:r,userId:a?.id??0,code:Ti(e,n),username:a?.username,firstName:a?.first_name,createdAt:new Date().toISOString()};return e.pending=[...e.pending,o],{pending:o,created:!0}},Di=(e,t)=>{let n=e.paired.filter(e=>e.chatId!==t);return n.length===e.paired.length?!1:(e.paired=n,e.pending=e.pending.filter(e=>e.chatId!==t),!0)},Oi=async e=>{let t=await e.ensurePendingPair(e.message);e.notifyPending&&e.notifyPendingPair(t);let n=`Your pairing code: ${t.code}. Ask the admin to approve it in settings.`;await e.sendAndTrackMessage(e.message.chat.id,e.message.from?.id,n)},ki=async(e,t)=>{try{k.info({chatId:e},`telegram pairing approved notify`),await t(e,`Pairing approved. You can chat now.`)}catch(e){k.warn({err:e},`telegram approve notify failed`)}},Ai=(e,t)=>{t&&(k.info({chatId:e.chatId,userId:e.userId,username:e.username,firstName:e.firstName},`telegram pairing request emitted`),t({chatId:e.chatId,userId:e.userId,username:e.username,firstName:e.firstName,createdAt:e.createdAt}))},ji=async(e,t,n,r)=>{await Xr(e,`sendMessage`,{chat_id:t,text:r?.formatted?n:Dr(n),parse_mode:`MarkdownV2`,disable_web_page_preview:!0})},Mi=async(e,t,n)=>{let r=new FormData;r.set(`chat_id`,String(t)),r.set(`voice`,new Blob([n],{type:`audio/ogg`}),`voice-message.ogg`),await Zr(e,`sendVoice`,r)},Ni=(e,t,n,r)=>{let i=!0,a=async()=>{if(!(!i||!r()))try{await Xr(e,`sendChatAction`,{chat_id:t,action:n})}catch(e){k.debug({err:e},`telegram chat action failed`)}};a();let o=setInterval(()=>{a()},4e3);return()=>{i=!1,clearInterval(o)}},Pi=async(e,t,n)=>{let r=Dr(n);for(let n of Mr(r,3900))await ji(e,t,n,{formatted:!0})},Fi=e=>{if(!e.message)return k.debug({updateId:e.update_id},`telegram update ignored`),null;let t=e.message;return t.chat.type===`private`?t:(k.info({chatId:t.chat.id,chatType:t.chat.type},`telegram message ignored (non-private)`),null)},Ii=async(e,t)=>{try{await t(e)}catch(e){k.warn({err:e},`telegram update failed`)}},Li=async e=>{let t=e.currentLastUpdateId;for(let n of e.updates){if(!e.isRunning())return;t=n.update_id,await Ii(n,e.handleUpdate)}t!==e.currentLastUpdateId&&await e.setLastUpdateId(t)},Ri=async(e,t,n)=>{if(t)return{voiceId:t,cache:n};if(n&&n.apiKey===e)return{voiceId:n.voiceId,cache:n};let r=await fetch(`https://api.elevenlabs.io/v1/voices`,{headers:{"xi-api-key":e,Accept:`application/json`}});if(!r.ok)throw Error(`elevenlabs_voice_list_http_${r.status}`);let i=J((await r.json()).voices?.[0]?.voice_id);if(!i)throw Error(`elevenlabs_voice_missing`);return{voiceId:i,cache:{apiKey:e,voiceId:i}}},zi=async(e,t)=>{let n=[`Original text:`,t,``,`Now please add appropriate ElevenLabs audio tags (in [tag] format) to the text.`,`Goal: Make the voice sound more vivid, emotional, with natural breathing that fits my character.`,`Keep the original meaning and sentence structure completely unchanged.`,`Do not remove or significantly rewrite any content.`,`Place tags naturally where they enhance emotion, tone, rhythm.`,`Do not overuse tags — keep it natural and readable.`,`Return only the final text with tags — no explanations, no quotes, no extra words`].join(`
72
+ `);try{let t=(await e.chatOneShot({messages:[{role:`user`,content:n}],projectPath:null,systemPrompt:await Wr()})).trim();if(t)return t}catch(e){k.warn({err:e},`telegram voice tagging failed`)}return t},Bi=async e=>{let t=new URL(`https://api.elevenlabs.io/v1/text-to-speech/${encodeURIComponent(e.voiceId)}`);t.searchParams.set(`output_format`,`mp3_44100_128`);let n=await fetch(t.toString(),{method:`POST`,headers:{"xi-api-key":e.apiKey,"Content-Type":`application/json`,Accept:`audio/mpeg`},body:JSON.stringify({text:e.text,model_id:e.modelId||Ir,voice_settings:{use_speaker_boost:!0,stability:.5}})});if(!n.ok){let e=(await n.text()).trim().slice(0,400),t=Or(e);k.warn({status:n.status,details:e,providerMessage:t||void 0},`telegram elevenlabs request failed`);let r=Error(`elevenlabs_http_${n.status}`);throw r.status=n.status,r.details=e,t&&(r.providerMessage=t),r}let r=new Uint8Array(await n.arrayBuffer());if(!r.byteLength)throw Error(`elevenlabs_empty_audio`);return r},Vi=async t=>{let n=N.which(`ffmpeg`);if(!n)throw Error(`ffmpeg_missing`);let i=await e.mkdtemp(r.join(m.tmpdir(),`diffact-voice-`)),a=r.join(i,`voice-input.mp3`),o=r.join(i,`voice-output.ogg`);try{await e.writeFile(a,t);let r=N.spawn([n,`-y`,`-i`,a,`-acodec`,`libopus`,`-b:a`,`32k`,`-vbr`,`off`,`-ar`,`24000`,o],{}),[i,s,c]=await Promise.all([r.exited,pi(r.stdout),pi(r.stderr)]);if(i!==0)throw k.warn({exitCode:i,stdout:s,stderr:c},`telegram ffmpeg conversion failed`),Error(`ffmpeg_convert_failed`);let l=await e.readFile(o);if(!l.byteLength)throw Error(`ffmpeg_empty_output`);return new Uint8Array(l)}finally{await e.rm(i,{recursive:!0,force:!0})}},Hi=e=>e.length>Lr?e.slice(0,Lr):e,Ui=async e=>{let t=e.text.trim();if(!t)throw Error(`voice_text_empty`);if(!e.apiKey)throw Error(`elevenlabs_not_configured`);let n=Hi(t),r=await zi(e.agent,n);k.info({inputLength:t.length,clippedLength:n.length,taggedLength:r.length},`telegram voice generation start`);let i=await Ri(e.apiKey,e.voiceId,e.voiceIdCache),a=await Vi(await Bi({apiKey:e.apiKey,voiceId:i.voiceId,modelId:e.modelId,text:r}));return await e.sendVoice(e.chatId,a),i.cache},Wi=async e=>{if(!e.running)return;let t=await e.formatMessage(e.event);try{if(t.trim()){await e.sendFormattedMessage(e.target.chatId,t),await e.appendAssistantMessageHistory(e.target.chatId,e.target.userId,t,{workerId:e.event.workerId,taskId:e.event.taskId,status:e.event.status});return}k.warn({chatId:e.target.chatId,workerId:e.event.workerId,taskId:e.event.taskId,status:e.event.status},`telegram worker completed with empty reply`)}catch(e){k.warn({err:e},`telegram worker reply failed`)}},Gi=async(e,t)=>{let n=J(e.output);if(n)return await t([`You are preparing a short status update for the user.`,`Rewrite the worker output into a concise Telegram message.`,`Do not quote or forward the worker output verbatim.`,`Extract the key result, any user action required, and next step.`,``,`worker_output:`,n].join(`
73
+ `))||`Task completed. Open Diffact to view details.`;let r=J(e.error);if(!r||r===`worker_failed`)return``;let i=await t(Gr(r));return k.info({errorLength:r.length,summaryLength:i.length,summaryPreview:i?Ar(i,300):``},`telegram worker error summary complete`),i},Ki=(e,t)=>e||Cn(e=>{t(e)}),qi=(e,t)=>e||dn(e=>{e.target&&t(e.workerId,e.target)}),Ji=(e,t,n)=>{t&&e.set(t,n)},Yi=(e,t)=>{let n=e.get(t);if(n)return e.delete(t),n};var Xi=class{#e;#t;#n;#r=!1;#i=null;#a=null;#o=Promise.resolve();#s=null;#c=new Map;#l=null;#u=null;#d=null;constructor(e,t,n){this.#e=e,this.#t=new F({type:`embedded`,model:null,modelProvider:async()=>vt(await B()),systemPrompt:Vr,tools:Wn({enableAppend:!1,enableGrep:!0})}),this.#n=t,this.#s=n?.onPairingRequest??null}getStatus(){let e=!!this.#n.botToken,t=this.#n.elevenlabsApiKey,n=this.#n.elevenlabsVoiceId,r=!!t,i=!!n,a=this.#n.elevenlabsModelId||Ir;return{enabled:e,running:this.#r,hasToken:e,tokenSuffix:e?this.#n.botToken.slice(-4):null,hasElevenLabsApiKey:r,elevenLabsApiKeySuffix:r?t.slice(-4):null,hasElevenLabsVoiceId:i,elevenLabsVoiceIdSuffix:i?n.slice(-6):null,elevenLabsModelId:a,voiceEnabled:r,pendingCount:this.#n.pending.length,paired:[...this.#n.paired]}}async setToken(e){let t=e.trim(),n=t!==this.#n.botToken;return this.#n.botToken=t,t?(n&&xi(this.#n),await this.#f(),await this.start(),this.getStatus()):(xi(this.#n),await this.#f(),await this.stop(),this.getStatus())}async clearPairings(){return Si(this.#n),await this.#f(),this.getStatus()}async setElevenLabsConfig(e){return e.apiKey!==void 0&&(this.#n.elevenlabsApiKey=e.apiKey.trim()),e.voiceId!==void 0&&(this.#n.elevenlabsVoiceId=e.voiceId.trim()),e.modelId!==void 0&&(this.#n.elevenlabsModelId=e.modelId.trim()),this.#d=null,await this.#f(),this.getStatus()}async approvePairing(e){let t=wi(this.#n,e);return t?(await this.#f(),await ki(t.chatId,(e,t)=>this.#v(e,t)),this.getStatus()):null}async start(){if(this.#r||!this.#n.botToken){this.#n.botToken||k.info(`telegram start skipped; missing bot token`);return}k.info(`telegram start`),this.#r=!0,this.#k(),this.#A(),this.#i=new AbortController,await this.#h(this.#i.signal),this.#a=this.#g(this.#i.signal)}async stop(){if(this.#r){k.info(`telegram stop`),this.#r=!1,this.#i?.abort(),this.#i=null,this.#c.clear(),this.#l?.(),this.#l=null,this.#u?.(),this.#u=null;try{await this.#a}catch{}this.#a=null}}async#f(){this.#o=this.#o.then(()=>ci(this.#n)).catch(e=>{k.warn({err:e},`telegram config save failed`)}),await this.#o}#p(e,t=`info`){t===`warn`?k.warn(e):k.info(e),this.#r=!1,this.#i?.abort(),this.#i=null}#m(){let e=this.#n.botToken;if(!e)throw Error(`telegram_disabled`);return e}async#h(e){try{let t=await Qr(this.#m(),this.#n.lastUpdateId,0,e);if(t.length){let e=t[t.length-1];e&&(this.#n.lastUpdateId=e.update_id,await this.#f())}}catch(e){k.warn({err:e},`telegram drain failed`)}}async#g(e){let t=Pr;for(;this.#r&&this.#n.botToken;)try{let n=await Qr(this.#m(),this.#n.lastUpdateId,30,e);t=Pr,n.length&&(k.info({count:n.length},`telegram updates batch`),await this.#_(n))}catch(e){if(e instanceof Error&&e.message===`telegram_disabled`){this.#p(`telegram disabled via config; stopping bot`);return}if(e instanceof Error&&e.code===401){this.#p(`telegram unauthorized; stopping bot`,`warn`);return}if(!this.#r)return;k.warn({err:e},`telegram poll failed, retry in ${t}ms`),await di(t),t=Math.min(3e4,Math.round(t*1.8))}}async#_(e){await Li({updates:e,isRunning:()=>this.#r,currentLastUpdateId:this.#n.lastUpdateId,handleUpdate:e=>this.#x(e),setLastUpdateId:async e=>{this.#n.lastUpdateId=e,await this.#f()}})}async#v(e,t,n){await ji(this.#m(),e,t,n)}async#y(e,t){await Mi(this.#m(),e,t)}#b(e,t){return Ni(this.#m(),e,t,()=>this.#r)}async#x(e){let t=Fi(e);t&&await this.#T(t)}async#S(e,t,n,r){await li({chatId:e,userId:t,content:n,meta:r})}async#C(e,t,n){await ui({chatId:e,userId:t,text:n,sendMessage:(e,t)=>this.#v(e,t)})}async#w(e,t){await Pi(this.#m(),e,t)}async#T(e){let t=J(e.text);if(!t){k.info({chatId:e.chat.id,messageId:e.message_id},`telegram message ignored (empty text)`);return}let n=e.chat.id,r=e.from?.id,i=on({source:`telegram`,meta:{chatId:n,messageId:e.message_id,userId:r,username:e.from?.username},recordAssistantFromStream:!1});await i.recordUserMessage(t);try{let i=_i(t),a=Ci(this.#n,n);k.info({chatId:n,messageId:e.message_id,userId:r,username:e.from?.username,command:i?.command,textLength:t.length,textPreview:t.length>120?`${t.slice(0,120)}...`:t},`telegram message received`);let o=await $r({message:e,text:t,command:i,paired:a,sendAndTrackMessage:(e,t,n)=>this.#C(e,t,n),sendPairingMessage:(e,t)=>Oi({message:e,notifyPending:t,ensurePendingPair:e=>this.#E(e),notifyPendingPair:e=>Ai(e,this.#s),sendAndTrackMessage:(e,t,n)=>this.#C(e,t,n)}),handleUnpair:(e,t)=>this.#D(e,t)});if(!o)return;let{managerInput:s,forceVoice:c}=o,l=gi(s,await vi(),await bi(this.#t,s),await yi(n,e.message_id)),u=this.#b(n,`typing`);await Nr({message:e,forceVoice:c,agentResult:await qr({agent:this.#e,prompt:l,target:{chatId:n,userId:r}}).finally(()=>{u()}),voiceEnabled:!!this.#n.elevenlabsApiKey,startChatAction:(e,t)=>this.#b(e,t),sendVoiceReply:(e,t)=>this.#O(e,t),sendFormattedMessage:(e,t)=>this.#w(e,t),appendAssistantMessageHistory:(e,t,n,r)=>this.#S(e,t,n,r)})}finally{await i.finalize()}}async#E(e){let t=Ei(this.#n,e,fi);return t.created?(await this.#f(),k.info({chatId:t.pending.chatId,userId:t.pending.userId,username:t.pending.username,firstName:t.pending.firstName,code:t.pending.code},`telegram pending pair created`),t.pending):(k.info({chatId:t.pending.chatId},`telegram pending pair reused`),t.pending)}async#D(e,t){if(!Di(this.#n,e)){k.info({chatId:e},`telegram unpair ignored (no pairing)`),await this.#C(e,t,`No pairing found.`);return}await this.#f(),k.info({chatId:e},`telegram unpaired`),await this.#C(e,t,`Unpaired.`)}async#O(e,t){this.#d=await Ui({agent:this.#e,chatId:e,text:t,apiKey:this.#n.elevenlabsApiKey,voiceId:this.#n.elevenlabsVoiceId,modelId:this.#n.elevenlabsModelId,voiceIdCache:this.#d,sendVoice:(e,t)=>this.#y(e,t)})}#k(){this.#l=Ki(this.#l,e=>{this.#j(e)})}#A(){this.#u=qi(this.#u,(e,t)=>{this.#k(),Ji(this.#c,e,t)})}async#j(e){let t=Yi(this.#c,e.workerId);t&&await Wi({event:e,target:t,running:this.#r,formatMessage:e=>Gi(e,e=>Kr(this.#e,e)),sendFormattedMessage:(e,t)=>this.#w(e,t),appendAssistantMessageHistory:(e,t,n,r)=>this.#S(e,t,n,r)})}};async function Zi(e,t){let n=globalThis.__diffactTelegramManager;n&&await n.stop();let r=await si(),i=new Xi(e,r,t);return globalThis.__diffactTelegramManager=i,r.botToken&&i.start(),i}var Qi=class{#e=new Map;#t=new Set;#n;constructor(e){this.#n=e,this.#r()}#r(){let{id:e}=this.#i();this.#t.add(e)}#i(){let e=this.#n(),t=v();return this.#e.set(t,e),{id:t,agent:e}}spawn(){let e=this.#t.values().next().value;if(!e)return this.#i();this.#t.delete(e);let t=this.#e.get(e);return t?{id:e,agent:t}:this.#i()}stop(e){return this.#t.delete(e),this.#e.delete(e)}get(e){return this.#e.get(e)??null}release(e){this.#e.has(e)&&this.#t.add(e)}},$i=class{#e=new Map;#t;constructor(){this.#t=setInterval(()=>this.#r(),3e4)}open(){let e=v();return{onOpen:(t,n)=>{this.#e.set(e,{id:e,socket:n,lastSeen:Date.now()})},onMessage:()=>{this.#n(e)},onClose:()=>this.#e.delete(e),onError:()=>this.#e.delete(e)}}send(e,t){let n=JSON.stringify({event:e,payload:t}),r=0;for(let e of this.#e.values())try{e.socket.send(n),r+=1}catch{this.#e.delete(e.id)}k.info({event:e,clients:this.#e.size,delivered:r},`ws send`)}#n(e){let t=this.#e.get(e);t&&(t.lastSeen=Date.now())}#r(){let e=Date.now();for(let t of this.#e.values()){if(e-t.lastSeen>45e3){try{t.socket.close()}catch{}this.#e.delete(t.id);continue}try{t.socket.send(JSON.stringify({event:`ping`}))}catch{this.#e.delete(t.id)}}}closeAll(){clearInterval(this.#t);for(let e of this.#e.values())try{e.socket.close()}catch{}this.#e.clear()}};const ea=Number.parseInt(process.env.PORT||``,10)||4312,ta=Number.parseInt(process.env.DIFFACT_INLINE_DIFF_LINES||``,10)||4e3,na=e=>new URL(e.req.url),X=async e=>{let t=await Zt(e.req.raw);return t&&typeof t==`object`?t:null},ra=e=>async t=>{let n=na(t),r=n.searchParams.get(`project`)?.trim();return r?e({c:t,url:n,project:await j(r)}):U(400,{error:`invalid_path`})},Z=e=>ra(async t=>t.project.isGit?e(t):U(400,{error:`project_not_git`})),ia=(e,t)=>{let n=r.resolve(e,t),i=r.relative(e,n);return!i||i.startsWith(`..`)||r.isAbsolute(i)?null:{resolved:n,normalizedPath:i.replace(/\\/g,`/`)}},aa=new $i,oa=await xn(),sa=Ge(),ca=new Map;for(let e of sa){if(!e.available){k.warn({provider:e.id},`worker provider missing`);continue}k.info({path:e.command,provider:e.id},`worker provider enabled`),ca.set(e.id,{pool:new Qi(()=>new F({type:`cli`,model:null,cliProvider:e.id,cliCommand:e.command})),command:e.command})}ca.size||k.warn(`worker providers missing: codex, claude, opencode; spawn_worker disabled`);const la=new F({type:`embedded`,model:null,modelProvider:async()=>vt(await B()),systemPromptProvider:rn,tools:Mn({taskStore:oa,workerProviders:ca.size?ca:null,getWorkerProvider:async()=>(await it()).preferred})}),ua=await hr().catch(e=>(k.warn({err:e},`memory writer start failed`),null)),Q=await Zi(la,{onPairingRequest:e=>{aa.send(`telegram_pairing_request`,e)}});let da=!1;const fa=async()=>{if(da)return;da=!0;let e=setTimeout(()=>{process.exit(0)},1500);e.unref?.(),await Promise.allSettled([Q.stop(),ua?ua.stop():Promise.resolve()]),clearTimeout(e),process.exit(0)};process.on(`SIGINT`,()=>{fa()}),process.on(`SIGTERM`,()=>{fa()});const $=new i,pa=N.isBun?await import(`hono/bun`):null;if(pa){let{upgradeWebSocket:e}=pa;$.get(`/api/events`,e(()=>(k.info(`ws open`),aa.open())))}$.onError((e,t)=>(k.error({err:e,path:t.req.path,method:t.req.method},`error`),Qt(e))),$.options(`*`,()=>Xt()),$.get(`/health`,()=>U(200,{status:`ok`,time:new Date().toISOString()})),$.get(`/api/capabilities`,async e=>U(200,await Ve(na(e).searchParams.get(`project`)))),$.get(`/api/cli/providers`,async()=>{let{preferred:e}=await it(),t=ot(e,sa);return U(200,{providers:sa.map(e=>({id:e.id,label:e.label,available:e.available})),preferred:e,effective:t?t.id:null})}),$.post(`/api/cli/providers`,async e=>{let t=await X(e);if(!t)return U(400,{error:`invalid_payload`});let n=S(t,`preferred`);if(!n||!Ke(n))return U(400,{error:`invalid_provider`});await at({preferred:n});let r=ot(n,sa);return U(200,{preferred:n,effective:r?r.id:null})}),$.get(`/api/embedded/config`,async()=>{let e=await B();return U(200,{baseUrl:e.baseUrl,model:e.model,apiKey:e.apiKey,hasApiKey:!!e.apiKey})}),$.post(`/api/embedded/config`,async e=>{let t=await X(e);if(!t)return U(400,{error:`invalid_payload`});let n=gt({baseUrl:S(t,`baseUrl`),model:S(t,`model`),apiKey:S(t,`apiKey`)});return await _t(n),U(200,{baseUrl:n.baseUrl,model:n.model,apiKey:n.apiKey,hasApiKey:!!n.apiKey})}),$.get(`/api/telegram/status`,()=>U(200,Q.getStatus())),$.post(`/api/telegram/token`,async e=>{let t=await X(e);if(!t||!(`token`in t))return U(400,{error:`invalid_payload`});let n=S(t,`token`);return U(200,await Q.setToken(n))}),$.post(`/api/telegram/elevenlabs`,async e=>{let t=await X(e);if(!t||!(`apiKey`in t)&&!(`voiceId`in t)&&!(`modelId`in t))return U(400,{error:`invalid_payload`});let n=`apiKey`in t?S(t,`apiKey`):void 0,r=`voiceId`in t?S(t,`voiceId`):void 0,i=`modelId`in t?S(t,`modelId`):void 0;return U(200,await Q.setElevenLabsConfig({apiKey:n,voiceId:r,modelId:i}))}),$.post(`/api/telegram/pairing/reset`,async()=>U(200,await Q.clearPairings())),$.post(`/api/telegram/pairing/approve`,async e=>{let t=await X(e);if(!t)return U(400,{error:`invalid_payload`});let n=S(t,`code`);if(!n)return U(400,{error:`invalid_code`});let r=await Q.approvePairing(n);return r?U(200,r):U(404,{error:`pairing_code_not_found`})}),$.get(`/api/editors`,async()=>U(200,{editors:await dt()})),$.post(`/api/editors/open`,async e=>{let t=await Zt(e.req.raw);if(!t||!t.editor||!t.project)return U(400,{error:`invalid_payload`});let n=t.editor;if(![`vscode`,`cursor`,`zed`].includes(n))return U(400,{error:`invalid_editor`});let r=t.target??{type:`project`},i=await mt(n,t.project,r);return i.success?U(200,{success:!0}):U(400,{error:i.error??`open_failed`})}),$.get(`/api/projects/browse`,async e=>{let t=na(e).searchParams.get(`path`)?.trim();return U(200,await $t(t||$e))}),$.post(`/api/projects/open`,async e=>{let t=await X(e);return!t||typeof t.path!=`string`?U(400,{error:`invalid_path`}):U(200,await j(t.path))}),$.get(`/api/projects/diff`,ra(async({url:e,project:t})=>{if(!t.isGit)return Jt(200,``);let n=e.searchParams.getAll(`arg`).filter(Boolean),r=e.searchParams.getAll(`path`).filter(Boolean);return Jt(200,await Et(t.rootPath,n,r))})),$.post(`/api/projects/stage`,Z(async({c:e,project:t})=>{let n=await X(e);if(!n)return U(400,{error:`invalid_payload`});let r=n.staged;if(typeof r!=`boolean`)return U(400,{error:`invalid_payload`});let i=S(n,`path`),a=ne(n,`paths`),o=a.length?a:i?[i]:[];if(!o.length)return U(400,{error:`invalid_path`});let s=me(t.rootPath,o);return!s||!s.length?U(400,{error:`invalid_path`}):(r?await Dt(t.rootPath,s):await kt(t.rootPath,s),U(200,{paths:s,staged:r}))})),$.get(`/api/projects/tree`,ra(async({project:e})=>{if(!e.isGit)return U(200,{available:!1,rootPath:e.rootPath,entries:[]});let t=await Lt(e.rootPath);return U(200,{available:!0,rootPath:e.rootPath,entries:t})})),$.get(`/api/projects/file`,Z(async({url:t,project:n})=>{let r=t.searchParams.get(`path`)?.trim();if(!r)return U(400,{error:`invalid_path`});let i=ia(n.rootPath,r);if(!i)return U(400,{error:`invalid_path`});let{resolved:a}=i,o;try{o=await e.stat(a)}catch(e){if(A(e))return U(404,{error:`invalid_path`});throw e}return o.isFile()?U(200,{path:r,contents:await e.readFile(a,`utf8`)}):U(400,{error:`invalid_path`})})),$.get(`/api/projects/file/raw`,Z(async({url:t,project:n})=>{let r=t.searchParams.get(`path`)?.trim();if(!r)return U(400,{error:`invalid_path`});let i=ia(n.rootPath,r);if(!i)return U(400,{error:`invalid_path`});let{resolved:a}=i,o;try{o=await e.stat(a)}catch(e){if(A(e))return U(404,{error:`invalid_path`});throw e}if(!o.isFile())return U(400,{error:`invalid_path`});let s=N.file(a);return H(new Response(s.stream(),{status:200,headers:{"Content-Type":yr(a),"Content-Disposition":`inline`}}))})),$.get(`/api/projects/history`,Z(async({url:e,project:t})=>{let n=e.searchParams.get(`limit`),r=e.searchParams.get(`skip`),i=n?Number.parseInt(n,10):30,a=r?Number.parseInt(r,10):0,o=Number.isFinite(i)&&i>0?Math.min(200,i):30,s=Number.isFinite(a)&&a>0?a:0;return U(200,await At(t.rootPath,s,o))})),$.get(`/api/projects/commits/:sha/diff`,Z(async({c:e,project:t})=>{let n=e.req.param(`sha`)?.trim();if(!n)return U(400,{error:`invalid_commit`});let r=null;try{r=await Pt(t.rootPath,n)}catch(e){if(pe(e,`ERR_CHILD_PROCESS_STDIO_MAXBUFFER`))r=null;else throw e}return r===null||r>ta?Yt(200,Mt(t.rootPath,n)):Jt(200,await jt(t.rootPath,n))})),$.get(`/api/projects/commits/:sha/files`,Z(async({c:e,project:t})=>{let n=e.req.param(`sha`)?.trim();return n?U(200,await Nt(t.rootPath,n)):U(400,{error:`invalid_commit`})})),$.get(`/api/projects/branches`,Z(async({url:e,project:t})=>{let n=e.searchParams.get(`cursor`)?.trim()||null,r=e.searchParams.get(`filter`)?.trim()||null,i=e.searchParams.get(`limit`),a=i?Number.parseInt(i,10):void 0;return U(200,await zt(t.rootPath,{limit:a,cursor:n,filter:r}))})),$.post(`/api/projects/branches`,Z(async({c:e,project:t})=>{let n=await X(e),r=n?S(n,`name`):``;return r?(await Gt(t.rootPath,r),U(201,{name:r})):U(400,{error:`invalid_branch`})})),$.post(`/api/projects/branches/checkout`,Z(async({c:e,project:t})=>{let n=await X(e),r=n?S(n,`name`):``;return r?(await Wt(t.rootPath,r),U(200,{name:r})):U(400,{error:`invalid_branch`})})),$.get(`/api/projects/pull-requests`,Z(async({url:e,project:t})=>{let n=e.searchParams.get(`cursor`)?.trim()||null,r=e.searchParams.get(`search`)?.trim()||null,i=e.searchParams.get(`limit`),a=i?Number.parseInt(i,10):void 0;return U(200,await xt(t.rootPath,{limit:a,cursor:n,search:r}))})),$.get(`/api/projects/issues`,Z(async({url:e,project:t})=>{let n=e.searchParams.get(`cursor`)?.trim()||null,r=e.searchParams.get(`search`)?.trim()||null,i=e.searchParams.get(`state`)?.trim(),a=e.searchParams.get(`limit`),o=a?Number.parseInt(a,10):void 0;return U(200,await St(t.rootPath,{limit:o,cursor:n,search:r,state:i||`open`}))})),$.get(`/api/projects/issues/:number`,Z(async({c:e,project:t})=>{let n=Number.parseInt(e.req.param(`number`)||``,10);if(Number.isNaN(n))return U(400,{error:`invalid_issue_number`});let r=await Ct(t.rootPath,n);return r?U(200,r):U(404,{error:`issue_not_found`})})),$.get(`*`,async e=>{let t=new URL(e.req.url).pathname;return await Cr(t)||Jt(404,`Not found`)});const ma=process.argv.includes(`--no-open`);if(N.isBun&&pa){let{websocket:e}=pa;Bun.serve({port:ea,fetch:$.fetch,websocket:e});let t=`http://localhost:${ea}`;k.info(`diffact server listening on ${t}`),xr()&&k.info(`serving static files from ${Sr()}`),!ma&&xr()&&br(t)}export{xr as a,Sr as i,$ as n,br as o,aa as r,k as s,ea as t};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "diffact",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "A browser-based review deck for your AI agents",
5
5
  "type": "module",
6
6
  "bin": {
@@ -14,8 +14,8 @@
14
14
  "lint": "biome check --write server web",
15
15
  "typecheck:server": "tsc -p server/tsconfig.json --noEmit",
16
16
  "typecheck:web": "tsc -p web/tsconfig.json --noEmit",
17
- "start:server": "bun server/src/index.ts",
18
- "start:node": "node --experimental-strip-types server/src/index-node.ts",
17
+ "start:server": "bun server/src/index.ts --no-open",
18
+ "start:node": "node --experimental-strip-types server/src/index-node.ts --no-open",
19
19
  "dev:server": "bun --hot server/src/index.ts --no-open",
20
20
  "dev:web": "vite --config web/vite.config.ts",
21
21
  "build": "bun run build:web && bun run build:server",
@@ -31,11 +31,12 @@
31
31
  "@radix-ui/react-popover": "1.1.15",
32
32
  "@radix-ui/react-tooltip": "1.2.8",
33
33
  "@tailwindcss/vite": "4.1.18",
34
+ "@tanstack/ai": "0.3.0",
35
+ "@tanstack/ai-openai": "0.3.0",
36
+ "@tanstack/ai-react": "0.3.0",
34
37
  "@tanstack/react-query": "5.90.20",
35
38
  "@tanstack/react-virtual": "3.13.18",
36
- "@xterm/xterm": "6.0.0",
37
39
  "hono": "4.11.6",
38
- "node-pty": "1.1.0",
39
40
  "pino": "10.3.0",
40
41
  "react": "19.2.4",
41
42
  "react-dom": "19.2.4",
@@ -1,2 +1,2 @@
1
- import{r as n,N as h,c as x,j as r,a as f,b as u}from"./index-BlaXWu6U.js";var k=u("block","before:content-[counter(line)]","before:inline-block","before:[counter-increment:line]","before:w-6","before:mr-4","before:text-[13px]","before:text-right","before:text-muted-foreground/50","before:font-mono","before:select-none"),p=n.memo(({children:a,result:e,language:o,className:c,...m})=>{let i=n.useMemo(()=>({backgroundColor:e.bg,color:e.fg}),[e.bg,e.fg]);return r.jsx("pre",{className:u(c,"p-4 text-sm dark:bg-(--shiki-dark-bg)!"),"data-language":o,"data-streamdown":"code-block-body",style:i,...m,children:r.jsx("code",{className:"[counter-increment:line_0] [counter-reset:line]",children:e.tokens.map((d,s)=>r.jsx("span",{className:k,children:d.map((t,l)=>r.jsx("span",{className:"dark:bg-(--shiki-dark-bg)! dark:text-(--shiki-dark)!",style:{color:t.color,backgroundColor:t.bgColor,...t.htmlStyle},...t.htmlAttrs,children:t.content},l))},s))})})},(a,e)=>a.result===e.result&&a.language===e.language&&a.className===e.className),j=({className:a,language:e,style:o,...c})=>r.jsx("div",{className:u("my-4 w-full overflow-hidden rounded-xl border border-border",a),"data-language":e,"data-streamdown":"code-block",style:{contentVisibility:"auto",containIntrinsicSize:"auto 200px",...o},...c}),N=({language:a,children:e})=>r.jsxs("div",{className:"flex items-center justify-between bg-muted/80 p-3 text-muted-foreground text-xs","data-language":a,"data-streamdown":"code-block-header",children:[r.jsx("span",{className:"ml-1 font-mono lowercase",children:a}),r.jsx("div",{className:"flex items-center gap-2",children:e})]}),y=({code:a,language:e,className:o,children:c,...m})=>{let{shikiTheme:i}=n.useContext(h),d=x(),s=n.useMemo(()=>({bg:"transparent",fg:"inherit",tokens:a.split(`
1
+ import{r as n,N as h,c as x,j as r,a as f,b as u}from"./index-DIRXMKEj.js";var k=u("block","before:content-[counter(line)]","before:inline-block","before:[counter-increment:line]","before:w-6","before:mr-4","before:text-[13px]","before:text-right","before:text-muted-foreground/50","before:font-mono","before:select-none"),p=n.memo(({children:a,result:e,language:o,className:c,...m})=>{let i=n.useMemo(()=>({backgroundColor:e.bg,color:e.fg}),[e.bg,e.fg]);return r.jsx("pre",{className:u(c,"p-4 text-sm dark:bg-(--shiki-dark-bg)!"),"data-language":o,"data-streamdown":"code-block-body",style:i,...m,children:r.jsx("code",{className:"[counter-increment:line_0] [counter-reset:line]",children:e.tokens.map((d,s)=>r.jsx("span",{className:k,children:d.map((t,l)=>r.jsx("span",{className:"dark:bg-(--shiki-dark-bg)! dark:text-(--shiki-dark)!",style:{color:t.color,backgroundColor:t.bgColor,...t.htmlStyle},...t.htmlAttrs,children:t.content},l))},s))})})},(a,e)=>a.result===e.result&&a.language===e.language&&a.className===e.className),j=({className:a,language:e,style:o,...c})=>r.jsx("div",{className:u("my-4 w-full overflow-hidden rounded-xl border border-border",a),"data-language":e,"data-streamdown":"code-block",style:{contentVisibility:"auto",containIntrinsicSize:"auto 200px",...o},...c}),N=({language:a,children:e})=>r.jsxs("div",{className:"flex items-center justify-between bg-muted/80 p-3 text-muted-foreground text-xs","data-language":a,"data-streamdown":"code-block-header",children:[r.jsx("span",{className:"ml-1 font-mono lowercase",children:a}),r.jsx("div",{className:"flex items-center gap-2",children:e})]}),y=({code:a,language:e,className:o,children:c,...m})=>{let{shikiTheme:i}=n.useContext(h),d=x(),s=n.useMemo(()=>({bg:"transparent",fg:"inherit",tokens:a.split(`
2
2
  `).map(g=>[{content:g,color:"inherit",bgColor:"transparent",htmlStyle:{},offset:0}])}),[a]),[t,l]=n.useState(s);return n.useEffect(()=>{if(!d){l(s);return}let g=d.highlight({code:a,language:e,themes:i},b=>{l(b)});if(g){l(g);return}l(s)},[a,e,i,d,s]),r.jsx(f.Provider,{value:{code:a},children:r.jsxs(j,{language:e,children:[r.jsx(N,{language:e,children:c}),r.jsx(p,{className:o,language:e,result:t,...m})]})})};export{y as CodeBlock};