@x-otto/shared 0.1.0-alpha.7 → 0.1.0-alpha.9

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/index.d.ts CHANGED
@@ -833,6 +833,12 @@ declare function acquireFileLock(dir: string, key: string, options?: FileLockOpt
833
833
  * (会误删偷锁者的新锁),仅记录诊断日志。
834
834
  */
835
835
  declare function releaseFileLock(dir: string, key: string, options?: Pick<FileLockOptions, 'prefix'>): Promise<void>;
836
+ /**
837
+ * B1(评审建议优化):当前进程是否仍持有指定锁(token 实核,非本地缓存)。
838
+ * 供"挂起恢复后覆盖写"防护:进程被 SIGSTOP/GC stall 超过陈旧阈值 → 锁被另一进程
839
+ * stale-takeover 偷走 → 恢复后本函数返回 false,调用方应放弃覆盖写、走读盘恢复。
840
+ */
841
+ declare function isFileLockHeldByMe(dir: string, key: string, options?: Pick<FileLockOptions, 'prefix'>): Promise<boolean>;
836
842
  /**
837
843
  * 等待另一进程持有的锁释放,超时返回 false(调用方应走自己的兜底路径,如重读磁盘或
838
844
  * 降级为无锁执行)。超时阈值应与陈旧锁清理阈值相等,保证两者协调一致。
@@ -852,5 +858,5 @@ declare function releaseFileLockSync(dir: string, key: string, options?: Pick<Fi
852
858
  */
853
859
  declare function waitForFileLockReleaseSync(dir: string, key: string, options?: Pick<FileLockOptions, 'timeoutMs' | 'prefix'>): boolean;
854
860
  //#endregion
855
- export { API_IMAGE_DIMENSION_LIMIT_PX, AgentError, CLAUDE_TO_OTTO_TOOL, CodedError, type CommandCheckResult, DEFAULT_FILE_LOCK_TIMEOUT_MS, type DeepPartial, type DeepReadonly, type DisposeFn, EventBus, type EventListener, type Events, type FileLockOptions, type FuzzySearchOptions, type HighlightRange, type HttpRequestOptions, type HttpResponse, type HttpTransport, InvariantError, LARGE_FILE_BYTE_THRESHOLD, type LogLevel, type Logger, type LoggerOptions, type LoggerSink, type LoopbackCallback, type LoopbackServer, type LoopbackServerOptions, McpError, NetworkError, OAuthError, PROVIDER_IMAGE_INLINE_MAX_BYTES, type PageRenderer, type ParsedFrontmatter, type PkcePair, ProviderError, type ProxyConfig, type ProxyProbeErrorKind, type ProxyProbeResult, type RankedMatch, type ReadCappedResult, type SafeDisposeOptions, type SearchableItem, type SseEvent, type SubsequenceResult, type TcpConnectProbe, type TruncateOptions, type TruncatedResult, type TruncationMeta, TypedEventEmitter, acquireFileLock, acquireFileLockSync, attachLogListener, buildAllowedEnv, checkShellCommand, createDispatcher, createLogger, createPkcePair, createProjectOverflowLogPath, createTempLoggerPath, defaultLoggerSink, defaultProxyConfig, exists, formatBytes, generateChallenge, generateState, generateVerifier, getDefaultProxy, getHomeDir, getProjectDir, getThirdPartyToolBinaryDir, getThirdPartyToolDir, headerGet, installGlobalProxyDispatcher, invariant, isDirectory, isFile, isIntranetReachable, isStartupTraceEnabled, isTransportInitialized, isUrlReachable, lockPath, mapClaudeAgentToolNames, mapClaudeToolName, markStartupPhase, matchSubsequence, matchesGlobPattern, mime, mkdirp, normalizePath, openBrowser, ottoToClaudeToolName, parseFrontmatterFields, parseFrontmatterList, parseJsonc, positionsToHighlightRanges, probeImageDimensions, probeProxy, rankCandidates, rankLabeledItems, rankNamedItems, readFileCapped, releaseFileLock, releaseFileLockSync, resetIntranetReachabilityCache, safeDispose, safeDisposeOf, safeStringify, scoreSubsequence, setDefaultProxy, setLogLevel, splitFrontmatter, startLoopbackServer, stream, sweepStaleProjectOverflowLogs, sweepStaleTempLogs, toTruncationMeta, traceStartupPhase, traceStartupPhaseSync, truncateHead, truncateLine, truncateTail, waitForFileLockRelease, waitForFileLockReleaseSync };
861
+ export { API_IMAGE_DIMENSION_LIMIT_PX, AgentError, CLAUDE_TO_OTTO_TOOL, CodedError, type CommandCheckResult, DEFAULT_FILE_LOCK_TIMEOUT_MS, type DeepPartial, type DeepReadonly, type DisposeFn, EventBus, type EventListener, type Events, type FileLockOptions, type FuzzySearchOptions, type HighlightRange, type HttpRequestOptions, type HttpResponse, type HttpTransport, InvariantError, LARGE_FILE_BYTE_THRESHOLD, type LogLevel, type Logger, type LoggerOptions, type LoggerSink, type LoopbackCallback, type LoopbackServer, type LoopbackServerOptions, McpError, NetworkError, OAuthError, PROVIDER_IMAGE_INLINE_MAX_BYTES, type PageRenderer, type ParsedFrontmatter, type PkcePair, ProviderError, type ProxyConfig, type ProxyProbeErrorKind, type ProxyProbeResult, type RankedMatch, type ReadCappedResult, type SafeDisposeOptions, type SearchableItem, type SseEvent, type SubsequenceResult, type TcpConnectProbe, type TruncateOptions, type TruncatedResult, type TruncationMeta, TypedEventEmitter, acquireFileLock, acquireFileLockSync, attachLogListener, buildAllowedEnv, checkShellCommand, createDispatcher, createLogger, createPkcePair, createProjectOverflowLogPath, createTempLoggerPath, defaultLoggerSink, defaultProxyConfig, exists, formatBytes, generateChallenge, generateState, generateVerifier, getDefaultProxy, getHomeDir, getProjectDir, getThirdPartyToolBinaryDir, getThirdPartyToolDir, headerGet, installGlobalProxyDispatcher, invariant, isDirectory, isFile, isFileLockHeldByMe, isIntranetReachable, isStartupTraceEnabled, isTransportInitialized, isUrlReachable, lockPath, mapClaudeAgentToolNames, mapClaudeToolName, markStartupPhase, matchSubsequence, matchesGlobPattern, mime, mkdirp, normalizePath, openBrowser, ottoToClaudeToolName, parseFrontmatterFields, parseFrontmatterList, parseJsonc, positionsToHighlightRanges, probeImageDimensions, probeProxy, rankCandidates, rankLabeledItems, rankNamedItems, readFileCapped, releaseFileLock, releaseFileLockSync, resetIntranetReachabilityCache, safeDispose, safeDisposeOf, safeStringify, scoreSubsequence, setDefaultProxy, setLogLevel, splitFrontmatter, startLoopbackServer, stream, sweepStaleProjectOverflowLogs, sweepStaleTempLogs, toTruncationMeta, traceStartupPhase, traceStartupPhaseSync, truncateHead, truncateLine, truncateTail, waitForFileLockRelease, waitForFileLockReleaseSync };
856
862
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import{createRequire as e}from"node:module";import t from"pino";import{LOG_FILE as n,LOG_LEVEL as r,OTTO_HOME as i,OTTO_PROJECT_DIR as a,normalizePath as o,resolveIntranetProbeUrls as s}from"@x-otto/env";import{PassThrough as c}from"node:stream";import{chmod as l,mkdir as u,open as d,readFile as f,readdir as p,stat as m,unlink as h,utimes as ee}from"node:fs/promises";import{lookup as te}from"mime-types";import{join as g,resolve as _}from"node:path";import{tmpdir as ne}from"node:os";import{createHash as re,randomBytes as ie,randomUUID as v}from"node:crypto";import{parse as ae,printParseErrorCode as oe}from"jsonc-parser";import se from"safe-stable-stringify";import{createParser as ce}from"eventsource-parser";import{EnvHttpProxyAgent as le,ProxyAgent as ue,getGlobalDispatcher as de,setGlobalDispatcher as fe}from"undici";import{createServer as pe}from"node:http";import{spawn as me}from"node:child_process";import{connect as he}from"node:net";import{chmodSync as ge,closeSync as _e,mkdirSync as ve,openSync as ye,readFileSync as be,statSync as xe,unlinkSync as Se,writeSync as Ce}from"node:fs";var y=class extends Error{code;cause;status;headers;errorType;pluginSource;abortKind;constructor(e,t){super(e,{cause:t.cause}),this.name=new.target.name,this.code=t.code,this.cause=t.cause,this.status=t.status,this.headers=t.headers,this.errorType=t.errorType,this.pluginSource=t.pluginSource,this.abortKind=t.abortKind}},b=class extends y{},we=class extends y{},x=class extends y{},Te=class extends y{},Ee=class extends y{};const{setPrototypeOf:De=function(e,t){return e.__proto__=t,e}}=Object;var Oe=class e extends Error{framesToPop=1;name=`Invariant Violation`;constructor(t=`Invariant Violation`){super(typeof t==`number`?`Invariant Violation: ${t}`:t),De(this,e.prototype)}};function S(e,t){if(typeof e==`function`)S(e(),t);else if(!e)throw new Oe(t)}var ke=class{listeners={};on(e,t){let n=this.listeners[e];return n||(n=new Set,this.listeners[e]=n),n.add(t),()=>this.off(e,t)}off(e,t){this.listeners[e]?.delete(t)}emit(e,...t){let n=this.listeners[e];if(n)for(let e of[...n])e(...t)}once(e,t){let n=((...r)=>{this.off(e,n),t(...r)});return this.on(e,n)}removeAllListeners(e){if(e!==void 0)delete this.listeners[e];else for(let e of Object.keys(this.listeners))delete this.listeners[e]}listenerCount(e){return this.listeners[e]?.size??0}},Ae=class extends ke{publish(e){let t=(e,...t)=>this.emit(e,...t);for(let[n,r]of Object.entries(e)){let e=r??[];t(n,...e),t(`*`,n,...e)}}subscribe(e,t,n=!1){return n?this.once(e,t):this.on(e,t)}subscribeAll(e){return this.subscribe(`*`,e)}};const je=new Set([`trace`,`debug`,`info`,`warn`,`error`,`fatal`]);function C(e){return je.has(e)?e:`info`}const Me=(()=>{try{return e(import.meta.url)}catch{return}})();function Ne(){if(!Me)return!1;try{return Me.resolve(`pino-pretty`),!0}catch{return!1}}function Pe(e){return e===`stdout`?1:e===`stderr`?2:e}function Fe(){return process.env.OTTO_LOG_STDERR===`0`}function Ie(){return process.env.OTTO_LOG_FILE||`${process.env.HOME||process.env.USERPROFILE||`.`}/.otto/logs/otto.log`}function Le(e,t){let n=Ne(),r=Fe(),i={target:n?`pino-pretty`:`pino/file`,options:n?{colorize:!0,destination:2}:{destination:2},level:t};if(!e||e===`stdout`||e===`stderr`)return r?[{target:`pino/file`,options:{destination:Ie(),mkdir:!0},level:t}]:[i];let a={target:`pino/file`,options:{destination:Pe(e),mkdir:!0},level:t};return r?[a]:[a,i]}const w=new c,Re=new Ae;w.on(`data`,e=>{try{Re.publish({log:[JSON.parse(e.toString())]})}catch(t){console.warn(`Failed to parse log chunk for listener:`,e.toString(),t)}});function ze(e){return Re.subscribe(`log`,e)}let T=null,E=C(r);const D=new Set;function Be(e){if(je.has(e)){E=e,T&&(T.level=e);for(let t of D)t.level=e}}function Ve(){return O!==null}let O=null;function He(e,n){return globalThis.__miniv8_wasm===void 0?{write(r){O??=t.transport({targets:Le(e,n)}),O.write(r)}}:{write:e=>{w.write(e)}}}function k(e,n){return T??=t({level:e},t.multistream([{level:e,stream:w},{level:e,stream:He(n,e)}])),E=C(T.level),T}function A(e,t){k(t?.level??C(r),t?.destination??n),S(T,`Root logger is not initialized`);let i=T.child({name:e},{level:t?.level??E});return D.add(i),i}const Ue={log(e,t,r){k(E,n),S(T,`Root logger is not initialized`),T[e](r??{},t)},child(e){let t=A(e);return{log(e,n,r){t[e](r??{},n)},child(e){let n=t.child({name:e});return{log(e,t,r){n[e](r??{},t)},child(e){let n=t.child({name:e});return{log(e,t,r){n[e](r??{},t)},child:()=>{throw Error(`LoggerSink.child depth limit`)},setLevel(e){n.level=e}}},setLevel(e){n.level=e}}},setLevel(e){t.level=e}}},setLevel(e){Be(e)}},We=10*1024*1024;async function Ge(e){return te(e)||`application/octet-stream`}async function Ke(e){await u(e,{recursive:!0})}async function qe(e){try{return await m(e),!0}catch(e){if(e.code===`ENOENT`)return!1;throw e}}async function Je(e){return(await m(e)).isDirectory()}async function Ye(e){return(await m(e)).isFile()}async function Xe(e,t=We){let n=await m(e);if(n.size<=t)return{content:await f(e,`utf-8`),truncated:!1,totalBytes:n.size};let r=await d(e,`r`);try{let e=Buffer.alloc(t),{bytesRead:i}=await r.read(e,0,t,0);return{content:e.subarray(0,i).toString(`utf-8`),truncated:!0,totalBytes:n.size}}finally{await r.close()}}function Ze(e){let{content:t,...n}=e;return n}function Qe(e){return e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}KB`:`${(e/(1024*1024)).toFixed(1)}MB`}function j(e){let t=e.outputBytes??Buffer.byteLength(e.content,`utf-8`),n=e.outputLines??e.content.split(`
2
- `).length;return{content:e.content,truncated:e.truncated,truncatedBy:e.truncatedBy,totalLines:e.totalLines,totalBytes:e.totalBytes,outputLines:n,outputBytes:t,lastLinePartial:e.lastLinePartial,firstLineExceedsLimit:e.firstLineExceedsLimit,options:e.options}}function $e(e,t){let{maxLines:n,maxBytes:r}=t,i=Buffer.byteLength(e,`utf-8`),a=e.split(`
3
- `),o=a.length;if(a.length<=n&&i<=r)return j({content:e,truncated:!1,truncatedBy:`lines`,totalLines:o,totalBytes:i,lastLinePartial:!1,firstLineExceedsLimit:!1,options:{maxLines:n,maxBytes:r},outputLines:o,outputBytes:i});if(n===0)return j({content:``,truncated:!0,truncatedBy:`lines`,totalLines:o,totalBytes:i,lastLinePartial:!1,firstLineExceedsLimit:!1,options:{maxLines:n,maxBytes:r},outputLines:0,outputBytes:0});if(Buffer.byteLength(a[0],`utf-8`)>r)return j({content:``,truncated:!0,truncatedBy:`bytes`,totalLines:o,totalBytes:i,lastLinePartial:!1,firstLineExceedsLimit:!0,options:{maxLines:n,maxBytes:r},outputLines:0,outputBytes:0});let s=[],c=0,l=`lines`;for(let e=0;e<a.length&&e<n;e++){let t=a[e],n=Buffer.byteLength(t,`utf-8`)+(s.length>0?1:0);if(c+n>r){l=`bytes`;break}s.push(t),c+=n}return s.length>=n&&c<=r&&(l=`lines`),j({content:s.join(`
4
- `),truncated:!0,truncatedBy:l,totalLines:o,totalBytes:i,lastLinePartial:!1,firstLineExceedsLimit:!1,options:{maxLines:n,maxBytes:r},outputLines:s.length,outputBytes:c})}function et(e,t){let{maxLines:n,maxBytes:r}=t,i=Buffer.byteLength(e,`utf-8`),a=e.split(`
5
- `),o=a.length;if(o<=n&&i<=r)return j({content:e,truncated:!1,truncatedBy:`lines`,totalLines:o,totalBytes:i,lastLinePartial:!1,firstLineExceedsLimit:!1,options:{maxLines:n,maxBytes:r},outputLines:o,outputBytes:i});if(n===0)return j({content:``,truncated:!0,truncatedBy:`lines`,totalLines:o,totalBytes:i,lastLinePartial:!1,firstLineExceedsLimit:!1,options:{maxLines:n,maxBytes:r},outputLines:0,outputBytes:0});let s=[],c=0,l=`lines`,u=!1;for(let e=a.length-1;e>=0&&s.length<n;e--){let t=a[e],n=Buffer.byteLength(t,`utf-8`)+(s.length>0?1:0);if(c+n>r){if(l=`bytes`,s.length===0){let e=tt(t,r);e.length>0&&(s.unshift(e),c=Buffer.byteLength(e,`utf-8`),u=!0)}break}s.unshift(t),c+=n}return s.length>=n&&c<=r&&(l=`lines`),j({content:s.join(`
6
- `),truncated:!0,truncatedBy:l,totalLines:o,totalBytes:i,lastLinePartial:u,firstLineExceedsLimit:!1,options:{maxLines:n,maxBytes:r},outputLines:s.length,outputBytes:c})}function tt(e,t){let n=Buffer.from(e,`utf-8`);if(n.length<=t)return e;let r=n.length-t;for(;r<n.length;){let e=n[r];if(e===void 0||(e&192)!=128)break;r++}return n.subarray(r).toString(`utf-8`)}function nt(e,t){return e.length<=t?{text:e,wasTruncated:!1}:{text:`${e.slice(0,t)}... [truncated]`,wasTruncated:!0}}function M(){return a}function rt(){return i}function it(){return _(rt(),`tools`)}function at(e,t=``){return _(it(),...t?[e,t]:[e])}const N=`otto-coding-`,P=`.log`;function ot(){let e=v();return g(ne(),`${N}${e}${P}`)}function st(){let e=v();return g(M(),`tool-results`,`bash`,`${N}${e}${P}`)}async function ct(e,t){return ut(ne(),e,t)}async function lt(e,t){return ut(g(M(),`tool-results`,`bash`),e,t)}async function ut(e,t,n){let r;try{r=await p(e)}catch{return 0}let i=r.filter(e=>e.startsWith(N)&&e.endsWith(P)),a=0;return await Promise.all(i.map(async r=>{let i=g(e,r);try{n-(await m(i)).mtimeMs>t&&(await h(i),a++)}catch{}})),a}function dt(e){let t=[],n=ae(e,t,{allowTrailingComma:!0,disallowComments:!1,allowEmptyContent:!1});if(t.length>0){let e=t[0],n=e?oe(e.error):`UnknownError`;throw Error(`Invalid JSONC: ${n}`)}return n}function ft(e,t){return se(e,void 0,t)??`null`}function pt(e,t){let n=``;for(let t=0;t<e.length;t++){let r=e[t];r===`*`?e[t+1]===`*`?(n+=`.*`,t++):n+=`[^/]*`:r===`?`?n+=`.`:n+=r.replace(/[.+^${}()|[\]\\]/g,`\\$&`)}return RegExp(`^${n}$`,`i`).test(t)}let F;function mt(e){F=e||void 0}function I(){return F}function L(e){let t=e||F;if(t)try{return new ue({uri:t})}catch{return}}let R;function z(e){if(R===void 0&&(R=de()),!e){fe(R);return}try{fe(new le({httpProxy:e,httpsProxy:e,noProxy:`localhost,127.0.0.1,[::1]`}))}catch{}}const ht={getUrl(){return I()},installGlobal(){z(F)},uninstallGlobal(){z(void 0)}},gt={kind:`idle`},_t={kind:`wallclock`};function vt(e,t){return e?t.idleTimeout:t.firstTokenIdleTimeout}function yt(e){let t=e.idleTimeout??12e4,n=e.firstTokenIdleTimeout??Math.max(t,9e5),r=e.timeout??3e5;return{timeout:Math.max(r,n+6e4),idleTimeout:t,firstTokenIdleTimeout:n}}function bt(e){let t=e.signal.reason;return typeof t==`object`&&t&&`kind`in t?t.kind:`external`}async function*xt(e){let{url:t,method:n=`POST`,headers:r={},body:i,signal:a}=e,{timeout:o,idleTimeout:s,firstTokenIdleTimeout:c}=yt(e),l=new AbortController,u=a?AbortSignal.any([a,l.signal]):l.signal,d=setTimeout(()=>l.abort(_t),o),f,p=!1,m=()=>{f&&clearTimeout(f),f=setTimeout(()=>l.abort(gt),vt(p,{idleTimeout:s,firstTokenIdleTimeout:c}))},h;try{let a=L(e.proxy),o={method:n,headers:{"content-type":`application/json`,accept:`text/event-stream`,...r},body:i?typeof i==`string`?i:JSON.stringify(i):void 0,signal:u},s=await fetch(t,a?{...o,dispatcher:a}:o);if(!s.ok){let e=await s.text(),t=`BAD_RESPONSE`;s.status===429?t=`RATE_LIMIT`:s.status===529?t=`OVERLOADED`:s.status>=500?t=`SERVER_ERROR`:s.status>=400&&(t=`REQUEST_ERROR`);let n;try{let t=JSON.parse(e)?.error;n=t?.code??t?.type}catch{}throw new b(`Http request failed ${s.status}: ${e}`,{code:t,status:s.status,headers:s.headers,errorType:n})}if(e.onResponse?.(s.headers),!s.body)throw new b(`Response body is empty`,{code:`BAD_RESPONSE`});h=s.body.getReader();let c=new TextDecoder,l=[],d=ce({onEvent(e){l.push({event:e.event||void 0,data:e.data,id:e.id||void 0})}});for(m();;){let{done:e,value:t}=await h.read();if(e)break;for(m(),d.feed(c.decode(t,{stream:!0}));l.length>0;){let e=l.shift();e&&(p||(p=!0,m()),yield e)}}for(d.feed(c.decode());l.length>0;){let e=l.shift();e&&(p||(p=!0,m()),yield e)}}catch(e){throw e instanceof b?e:l.signal.aborted||e instanceof DOMException&&e.name===`AbortError`?new b(`Stream aborted or timed out`,{code:`TIMEOUT`,cause:e instanceof Error?e:Error(String(e)),abortKind:bt(l)}):new b(`Stream request failed`,{code:`NETWORK_ERROR`,cause:e instanceof Error?e:Error(String(e))})}finally{clearTimeout(d),f&&clearTimeout(f),h&&h.cancel().catch(()=>{})}}async function St(e,t=5e3){let n=Date.now(),r=new AbortController,i=setTimeout(()=>r.abort(),t);try{let t=await fetch(e,{method:`GET`,signal:r.signal});return{ok:!0,latencyMs:Date.now()-n,status:t.status}}catch(e){let t=Date.now()-n;if(r.signal.aborted)return{ok:!1,latencyMs:t,errorKind:`timeout`,errorMessage:`timeout`};let i=e instanceof Error?e.message:String(e);return{ok:!1,latencyMs:t,errorKind:Ct(e),errorMessage:i}}finally{clearTimeout(i)}}function Ct(e){switch(e?.cause?.code??e?.code){case`ECONNREFUSED`:case`ECONNRESET`:case`EHOSTUNREACH`:case`ENETUNREACH`:return`proxy-unreachable`;case`ENOTFOUND`:case`EAI_AGAIN`:return`target-unreachable`;case`UND_ERR_CONNECT_TIMEOUT`:case`UND_ERR_HEADERS_TIMEOUT`:case`ETIMEDOUT`:return`timeout`;default:return`unknown`}}function wt(e,t){if(e==null)return;if(typeof e.get==`function`)return e.get(t)??void 0;let n=e;for(let e of Object.keys(n))if(e.toLowerCase()===t){let t=n[e];return typeof t==`string`?t:void 0}}const Tt=[{description:`递归强制删除`,substring:`rm -rf`},{description:`递归强制删除(长格式)`,substring:`rm -r -f`},{description:`递归强制删除(长格式 2)`,substring:`rm --recursive --force`},{description:`删除根目录`,substring:`rm -rf /`},{description:`权限提升`,substring:`sudo rm`},{description:`权限提升`,substring:`sudo `},{description:`chmod 777`,substring:`chmod 777`},{description:`chmod -R 777`,substring:`chmod -R 777`},{description:`chmod 777 递归`,substring:`chmod -R`},{description:`curl 管道 shell 执行`,regex:/curl\s+\S+\s*\|\s*(ba)?sh/},{description:`wget 管道 shell 执行`,regex:/wget\s+\S+\s*-\s*O\s*-\s*\|\s*(ba)?sh/},{description:`fork bomb`,regex:/:\s*\(\s*\)\s*\{\s*:\s*\|\s*:?\s*&\s*\}\s*;?\s*:/},{description:`覆盖关键系统文件`,regex:/>\s*\/(etc|boot|sys|proc|dev)\//},{description:`mkfs 格式化`,substring:`mkfs.`},{description:`dd 覆写磁盘`,regex:/dd\s+if=.*of=\/dev\//}];function Et(e){let t=e.trim();if(!t)return{safe:!0};for(let e of Tt)if(e.substring!==void 0&&t.includes(e.substring)||e.regex!==void 0&&e.regex.test(t))return{safe:!1,reason:e.description};return{safe:!0}}function Dt(e){let t=new Map,n=[`LC_`,`OTTO_`,`npm_`],r=new Set([`PATH`,`HOME`,`USER`,`SHELL`,`TMPDIR`,`TEMP`,`TMP`,`LANG`,`NODE_PATH`,`NODE_ENV`,`TERM`,`COLORTERM`,`TERM_PROGRAM`,`SSH_AUTH_SOCK`,`DISPLAY`,`WAYLAND_DISPLAY`,`XDG_RUNTIME_DIR`,`XDG_SESSION_TYPE`]);for(let[e,i]of Object.entries(process.env)){if(!i)continue;if(r.has(e)){t.set(e,i);continue}let a=e.toLowerCase();a.includes(`api_key`)||a.includes(`token`)||a.includes(`secret`)||a.includes(`password`)||a.includes(`passwd`)||a.includes(`credential`)||a.includes(`auth`)||n.some(t=>e.startsWith(t))&&t.set(e,i)}if(e)for(let[n,r]of Object.entries(e))r===void 0?t.delete(n):t.set(n,r);return Object.fromEntries(t)}const B={Bash:`bash`,Read:`read`,Write:`write`,Edit:`edit`,MultiEdit:`edit`,Grep:`grep`,Glob:`find`,WebFetch:`web_fetch`,WebSearch:`web_search`,Task:`task_delegate`,TodoWrite:`write_todos`};function Ot(e){return B[e]}const kt=Object.fromEntries(Object.entries(B).reverse().map(([e,t])=>[t,e]));function At(e){return kt[e]??e}function jt(e){return e.map(e=>B[e]??e)}function V(e){return e.toString(`base64url`)}function Mt(){return V(ie(32))}function H(e){return V(re(`sha256`).update(e).digest())}function Nt(){let e=Mt();return{verifier:e,challenge:H(e),method:`S256`}}function Pt(){return V(ie(16))}const Ft={renderSuccess(e,t,n){return`<!DOCTYPE html><html><body><h1>${U(e)}</h1><p>${U(t)}</p><p>${U(n)}</p></body></html>`},renderError(e,t,n){return`<!DOCTYPE html><html><body><h1>Error</h1><p>${U(e)}</p><p>${U(t)}</p><p>${U(n)}</p></body></html>`}};function U(e){return e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`).replace(/'/g,`&#39;`)}const It=[1455,1457];function W(e,t,n){let r=Buffer.from(n,`utf-8`);e.writeHead(t,{"Content-Type":`text/html; charset=utf-8`,"Content-Length":String(r.length),Connection:`close`}),e.end(r)}function Lt(e,t,n){return new Promise((r,i)=>{if(n.length===0){i(new x(`No loopback port specified.`,{code:`OAUTH_LOOPBACK_PORT_UNAVAILABLE`}));return}let a=0,o=()=>{e.removeListener(`error`,l),e.removeListener(`listening`,c)},s=()=>{let r=n[a++];e.listen(r,t)},c=()=>{o();let t=e.address();r(typeof t==`object`&&t?t.port:n[a-1])},l=e=>{if(e.code===`EADDRINUSE`||e.code===`EACCES`){if(a<n.length){s();return}o(),i(new x(`No available loopback port among: ${n.join(`, `)}`,{code:`OAUTH_LOOPBACK_PORT_UNAVAILABLE`}));return}o(),i(e)};e.on(`error`,l),e.on(`listening`,c),s()})}function Rt(e,t){e.value||(e.value=!0,t())}async function zt(e={}){let{ports:t=It,callbackPath:n=`/auth/callback`,expectedState:r,host:i=`127.0.0.1`,signal:a,pageRenderer:o=Ft}=e;if(a?.aborted)throw new x(`Login cancelled`,{code:`OAUTH_CANCELLED`});let s,c,l={value:!1},u=new Promise((e,t)=>{s=t=>Rt(l,()=>e(t)),c=e=>Rt(l,()=>t(e))});u.catch(()=>{});let d=0,f=()=>`http://${i}:${d}`,p=pe((e,t)=>{let i;try{i=new URL(e.url??`/`,f())}catch{W(t,400,o.renderError(`Login failed`,`Invalid request URL`,`Otto Auth`)),c(new x(`Invalid callback URL`,{code:`OAUTH_INVALID_REQUEST`}));return}if(i.pathname!==n){W(t,404,o.renderError(`Login failed`,`Not found`,`Otto Auth`));return}let a=i.searchParams.get(`error`);if(a){let e=i.searchParams.get(`error_description`)??``;W(t,400,o.renderError(`Login failed`,e||a,`Otto Auth`)),c(new x(`Authorization failed: ${a}${e?`: ${e}`:``}`,{code:`OAUTH_AUTHORIZE_FAILED`}));return}let l=i.searchParams.get(`code`);if(!l){W(t,400,o.renderError(`Login failed`,`Missing authorization code.`,`Otto Auth`)),c(new x(`Callback missing authorization code.`,{code:`OAUTH_AUTHORIZE_FAILED`}));return}let u=i.searchParams.get(`state`)??void 0;if(r!==void 0&&u!==r){W(t,400,o.renderError(`Login failed`,`State mismatch.`,`Otto Auth`)),c(new x(`OAuth state mismatch (possible CSRF).`,{code:`OAUTH_STATE_MISMATCH`}));return}W(t,200,o.renderSuccess(`Login complete`,`You can close this window and return to the terminal.`,`Otto Auth`)),s({code:l,state:u})});d=await Lt(p,i,t);let m=!1,h=()=>new Promise(e=>{if(m){e();return}m=!0,c(new x(`Login cancelled (server closed)`,{code:`OAUTH_CANCELLED`})),p.close(()=>e()),p.closeAllConnections?.()});return a&&a.addEventListener(`abort`,()=>{c(new x(`Login cancelled`,{code:`OAUTH_CANCELLED`})),h()},{once:!0}),{port:d,redirectUri:`${f()}${n}`,waitForCallback:()=>u,close:h}}function Bt(e){try{new URL(e)}catch{return!1}try{let t=process.platform,n=t===`darwin`?[`open`,[e]]:t===`win32`?[`cmd`,[`/c`,`start`,``,e]]:[`xdg-open`,[e]];return me(n[0],[...n[1]],{detached:!0,stdio:`ignore`}).unref(),!0}catch{return!1}}const Vt=/^---\s*\n([\s\S]*?)\n---\s*\n?([\s\S]*)$/;function Ht(e){let t=Vt.exec(e);return t?{fields:Ut(t[1]??``),body:(t[2]??``).trim()}:null}function Ut(e){let t=new Map;for(let n of e.split(`
7
- `)){let e=n.indexOf(`:`);if(e<=0)continue;let r=n.slice(0,e).trim().toLowerCase().replaceAll(`_`,``),i=n.slice(e+1).trim().replace(/^["']|["']$/g,``);r&&i&&t.set(r,i)}return t}function Wt(e){if(!e)return;let t=(e.startsWith(`[`)&&e.endsWith(`]`)?e.slice(1,-1):e).split(`,`).map(e=>e.trim().replace(/^["']|["']$/g,``)).filter(e=>e!==``);return t.length>0?t:void 0}const Gt=8e3,Kt=5*1024*1024,qt=Buffer.from([137,80,78,71,13,10,26,10]),Jt=Buffer.from(`GIF8`,`ascii`);function Yt(e,t){if(!(!e||e.length===0)&&!(e.length>7340032))try{return Xt(Buffer.from(e.slice(0,128),`base64`),e,t)}catch{return}}function Xt(e,t,n){let r=n.toLowerCase();if(r.includes(`png`))return Zt(e);if(r.includes(`jpeg`)||r.includes(`jpg`))return Qt(Buffer.from(t,`base64`));if(r.includes(`gif`))return $t(e);if(r.includes(`webp`))return en(e);if(e.length>=8&&e.subarray(0,8).equals(qt))return Zt(e);if(e.length>=2&&e.readUInt16BE(0)===65496)return Qt(Buffer.from(t,`base64`));if(e.length>=4&&e.subarray(0,4).equals(Jt))return $t(e);if(e.length>=12&&e.readUInt32BE(0)===1380533830&&e.readUInt32BE(8)===1464156752)return en(e)}function Zt(e){if(!(e.length<24)&&e.subarray(0,8).equals(qt))try{return e.toString(`ascii`,12,16)===`IHDR`?{width:e.readUInt32BE(16),height:e.readUInt32BE(20)}:void 0}catch{return}}function Qt(e){if(!(e.length<2))try{let t=2,n=0;for(;t<e.length-1;){if(n++,n>1e5)return;let r=e.readUInt16BE(t);if(r===65497||(r&65280)!=65280)return;let i=r&255;if(i>=192&&i<=195||i>=197&&i<=199||i>=201&&i<=203||i>=205&&i<=207){if(t+9>e.length||e.readUInt16BE(t+2)<8)return;let n=e.readUInt16BE(t+5);return{width:e.readUInt16BE(t+7),height:n}}if(i===216||i===217){t+=2;continue}if(t+4>e.length)return;let a=e.readUInt16BE(t+2);if(a<2)return;t+=2+a}return}catch{return}}function $t(e){if(!(e.length<10)&&e.subarray(0,4).equals(Jt))try{return{width:e.readUInt16LE(6),height:e.readUInt16LE(8)}}catch{return}}function en(e){if(!(e.length<16)&&!(e.readUInt32BE(0)!==1380533830||e.readUInt32BE(8)!==1464156752))try{let t=e.toString(`ascii`,12,16);return t===`VP8X`?tn(e):t===`VP8 `?nn(e):t===`VP8L`?rn(e):void 0}catch{return}}function tn(e){if(!(e.length<30))return{width:(e[24]|e[25]<<8|e[26]<<16)+1,height:(e[27]|e[28]<<8|e[29]<<16)+1}}function nn(e){if(e.length<30)return;let t=e.readUInt16LE(26)&16383,n=e.readUInt16LE(28)&16383;if(!(t===0||n===0))return{width:t,height:n}}function rn(e){if(e.length<25||e[20]!==47)return;let t=e.readUInt32LE(21);return{width:(t&16383)+1,height:(t>>14&16383)+1}}function an(e,t,n){return new Promise(r=>{let i=he({host:e,port:t}),a=!1,o=e=>{a||(a=!0,i.destroy(),r(e))};setTimeout(()=>o(!1),n).unref?.(),i.setTimeout(n),i.once(`connect`,()=>o(!0)),i.once(`error`,()=>o(!1)),i.once(`timeout`,()=>o(!1))})}const G=new Map;async function on(e,t={}){let n,r;try{let t=new URL(e);if(t.protocol!==`http:`&&t.protocol!==`https:`)return!1;n=t.hostname,r=t.port?Number(t.port):t.protocol===`https:`?443:80}catch{return!1}let i=`${n}:${r}`,a=Date.now();if(!t.force){let e=G.get(i);if(e&&a-e.at<3e5)return e.reachable}let o=await(t.connect??an)(n,r,t.timeoutMs??2e3);return G.set(i,{reachable:o,at:Date.now()}),o}async function sn(e=!1,t=[],n){let r=[...s(),...t];if(r.length===0)return!1;for(let t of r)if(await on(t,{force:e,...n?{connect:n}:{}}))return!0;return!1}function cn(){G.clear()}async function ln(e,t={}){if(e===void 0)return!0;try{return await e(),!0}catch(e){return t.logger?.warn({...t.context,err:e instanceof Error?e.message:String(e)},t.label??`dispose failed`),!1}}async function un(e,t={}){let n=e?.dispose;return typeof n==`function`?ln(()=>n.call(e),t):!0}const K=process.env.OTTO_STARTUP_TRACE===`1`,dn=K?performance.now():0;function fn(e){if(!K)return;let t=performance.now()-dn;process.stderr.write(`[startup] ${e}: ${t.toFixed(1)}ms\n`)}async function pn(e,t){if(!K)return t();let n=performance.now();try{return await t()}finally{let t=performance.now()-n;process.stderr.write(`[startup] ${e}: ${t.toFixed(1)}ms\n`)}}function mn(e,t){if(!K)return t();let n=performance.now();try{return t()}finally{let t=performance.now()-n;process.stderr.write(`[startup] ${e}: ${t.toFixed(1)}ms\n`)}}function hn(){return K}const gn=/[/\-_\s.]/;function _n(e){return e!==void 0&&gn.test(e)}function q(e,t){if(e.length===0)return{score:0,positions:[]};if(t.length===0)return null;let n=e.toLowerCase(),r=t.toLowerCase(),i=0,a=0,o=[],s=-2;for(let e=0;e<r.length&&a<n.length;e++)r[e]===n[a]&&(s===e-1?i+=24:(i+=16,s>=0&&(i-=(e-s-1)*3)),e===0?i+=12:_n(r[e-1])&&(i+=8),o.push(e),s=e,a++);return a<n.length?null:(i-=Math.max(0,r.length-n.length)*.5,{score:i,positions:o})}function vn(e,t){return q(e,t)?.score??-1}function yn(e){if(e.length===0)return[];let t=[],n=e[0],r=n+1;for(let i=1;i<e.length;i++){let a=e[i];a===r?r++:(t.push({start:n,end:r}),n=a,r=a+1)}return t.push({start:n,end:r}),t}function bn(e,t,n){let r=q(e,t);for(let t of n??[]){let n=q(e,t);n&&(!r||n.score>r.score)&&(r=n)}return r}function J(e,t,n={}){let r=n.maxResults??50,i=n.matchEmpty??!0,a=t.trim();if(a===``)return i?e.slice(0,r).map(e=>({item:e,score:0,highlightRanges:[]})):[];let o=[];for(let t of e){let e=bn(a,t.text,t.aliases);if(!e)continue;let n=q(a,t.text);o.push({item:t,score:e.score,highlightRanges:yn(n?.positions??[])})}return o.sort((e,t)=>t.score-e.score||(e.item.sortKey??e.item.text).localeCompare(t.item.sortKey??t.item.text)),o.slice(0,r)}function xn(e,t,n){return J(e.map(e=>({text:e.name,aliases:e.description?[e.description]:void 0,payload:e,sortKey:e.sortKey})),t,n).map(e=>e.item.payload)}function Sn(e,t,n){return J(e.map(e=>({text:e.searchText??e.label,aliases:[e.group,e.detail,e.value].filter(e=>!!e),payload:e})),t,{maxResults:n?.maxResults??e.length,matchEmpty:n?.matchEmpty}).map(e=>e.item.payload)}const Y=A(`@x-otto/shared:file-lock`),Cn=15e3;function wn(e){return Math.floor(e/3)}const X=new Map,Z=new Map;function Q(e,t,n=`file-lock`){return g(e,`.${n}-${t}.lock`)}function Tn(e,t){En(e);let n=setInterval(()=>{let t=new Date;ee(e,t,t).catch(()=>{})},wn(t));n.unref?.(),X.set(e,n)}function En(e){let t=X.get(e);t&&(clearInterval(t),X.delete(e))}async function Dn(e,t,n={}){let r=n.timeoutMs??15e3,i=Q(e,t,n.prefix),a=async(n=!1)=>{try{let e=await d(i,`wx`),t=v();await e.writeFile(t),await e.close(),Z.set(i,t);try{await l(i,384)}catch{}return Tn(i,r),!0}catch(r){if(r.code===`EEXIST`)return!1;if(r.code===`ENOENT`&&!n){try{await u(e,{recursive:!0})}catch(e){return Y.warn(`Failed to create lock directory for ${t}: ${e.message}`),!1}return await a(!0)}return Y.warn(`Failed to acquire file lock for ${t}: ${r.message}`),!1}};if(await a())return!0;try{let e=await m(i);if(Date.now()-e.mtimeMs>r)return await h(i).catch(()=>{}),await a()}catch{return await a()}return!1}async function On(e,t,n={}){let r=Q(e,t,n.prefix);En(r);let i=Z.get(r);if(Z.delete(r),i!==void 0)try{if(await f(r,`utf-8`)!==i){Y.warn(`File lock ownership drifted for ${t} — another process stole this lock (likely stale-lock takeover during a heartbeat gap). Skipping unlink to avoid deleting the new owner's lock.`);return}}catch{}await h(r).catch(()=>{})}async function kn(e,t,n={}){let r=n.timeoutMs??15e3,i=Q(e,t,n.prefix),a=Date.now()+r;for(;Date.now()<a;){try{await m(i)}catch{return!0}await new Promise(e=>setTimeout(e,100))}return!1}const $=new Map;function An(e,t,n={}){let r=n.timeoutMs??15e3,i=Q(e,t,n.prefix),a=(n=!1)=>{let r;try{r=ye(i,`wx`)}catch(r){let i=r.code;if(i===`EEXIST`)return!1;if(i===`ENOENT`&&!n){try{ve(e,{recursive:!0})}catch(e){return Y.warn(`Failed to create lock directory for ${t}: ${e.message}`),!1}return a(!0)}return Y.warn(`Failed to acquire file lock for ${t}: ${r.message}`),!1}let o=v();try{Ce(r,o)}finally{_e(r)}$.set(i,o);try{ge(i,384)}catch{}return!0};if(a())return!0;try{let e=xe(i);if(Date.now()-e.mtimeMs>r){try{Se(i)}catch{}return a()}}catch{return a()}return!1}function jn(e,t,n={}){let r=Q(e,t,n.prefix),i=$.get(r);if($.delete(r),i!==void 0)try{if(be(r,`utf-8`)!==i){Y.warn(`File lock ownership drifted for ${t} — another process stole this lock. Skipping unlink to avoid deleting the new owner's lock.`);return}}catch{}try{Se(r)}catch{}}function Mn(e,t,n={}){let r=n.timeoutMs??15e3,i=Q(e,t,n.prefix),a=Date.now()+r,o=new Int32Array(new SharedArrayBuffer(4));for(;Date.now()<a;){try{xe(i)}catch{return!0}Atomics.wait(o,0,0,100)}return!1}export{Gt as API_IMAGE_DIMENSION_LIMIT_PX,Te as AgentError,B as CLAUDE_TO_OTTO_TOOL,y as CodedError,Cn as DEFAULT_FILE_LOCK_TIMEOUT_MS,Ae as EventBus,Oe as InvariantError,We as LARGE_FILE_BYTE_THRESHOLD,Ee as McpError,b as NetworkError,x as OAuthError,Kt as PROVIDER_IMAGE_INLINE_MAX_BYTES,we as ProviderError,ke as TypedEventEmitter,Dn as acquireFileLock,An as acquireFileLockSync,ze as attachLogListener,Dt as buildAllowedEnv,Et as checkShellCommand,L as createDispatcher,A as createLogger,Nt as createPkcePair,st as createProjectOverflowLogPath,ot as createTempLoggerPath,Ue as defaultLoggerSink,ht as defaultProxyConfig,qe as exists,Qe as formatBytes,H as generateChallenge,Pt as generateState,Mt as generateVerifier,I as getDefaultProxy,rt as getHomeDir,M as getProjectDir,at as getThirdPartyToolBinaryDir,it as getThirdPartyToolDir,wt as headerGet,z as installGlobalProxyDispatcher,S as invariant,Je as isDirectory,Ye as isFile,sn as isIntranetReachable,hn as isStartupTraceEnabled,Ve as isTransportInitialized,on as isUrlReachable,Q as lockPath,jt as mapClaudeAgentToolNames,Ot as mapClaudeToolName,fn as markStartupPhase,q as matchSubsequence,pt as matchesGlobPattern,Ge as mime,Ke as mkdirp,o as normalizePath,Bt as openBrowser,At as ottoToClaudeToolName,Ut as parseFrontmatterFields,Wt as parseFrontmatterList,dt as parseJsonc,yn as positionsToHighlightRanges,Yt as probeImageDimensions,St as probeProxy,J as rankCandidates,Sn as rankLabeledItems,xn as rankNamedItems,Xe as readFileCapped,On as releaseFileLock,jn as releaseFileLockSync,cn as resetIntranetReachabilityCache,ln as safeDispose,un as safeDisposeOf,ft as safeStringify,vn as scoreSubsequence,mt as setDefaultProxy,Be as setLogLevel,Ht as splitFrontmatter,zt as startLoopbackServer,xt as stream,lt as sweepStaleProjectOverflowLogs,ct as sweepStaleTempLogs,Ze as toTruncationMeta,pn as traceStartupPhase,mn as traceStartupPhaseSync,$e as truncateHead,nt as truncateLine,et as truncateTail,kn as waitForFileLockRelease,Mn as waitForFileLockReleaseSync};
1
+ import{createRequire as e}from"node:module";import t from"pino";import{LOG_FILE as n,LOG_LEVEL as r,OTTO_HOME as i,OTTO_PROJECT_DIR as a,normalizePath as o,resolveIntranetProbeUrls as s}from"@x-otto/env";import{PassThrough as c}from"node:stream";import{chmod as l,mkdir as u,open as d,readFile as f,readdir as p,stat as m,unlink as h,utimes as ee}from"node:fs/promises";import{lookup as te}from"mime-types";import{join as g,resolve as _}from"node:path";import{tmpdir as ne}from"node:os";import{createHash as re,randomBytes as ie,randomUUID as v}from"node:crypto";import{parse as ae,printParseErrorCode as oe}from"jsonc-parser";import se from"safe-stable-stringify";import{createParser as ce}from"eventsource-parser";import{EnvHttpProxyAgent as le,ProxyAgent as ue,getGlobalDispatcher as de,setGlobalDispatcher as y}from"undici";import{createServer as fe}from"node:http";import{spawn as pe}from"node:child_process";import{connect as me}from"node:net";import{chmodSync as he,closeSync as ge,mkdirSync as _e,openSync as ve,readFileSync as ye,statSync as be,unlinkSync as xe,writeSync as Se}from"node:fs";var b=class extends Error{code;cause;status;headers;errorType;pluginSource;abortKind;constructor(e,t){super(e,{cause:t.cause}),this.name=new.target.name,this.code=t.code,this.cause=t.cause,this.status=t.status,this.headers=t.headers,this.errorType=t.errorType,this.pluginSource=t.pluginSource,this.abortKind=t.abortKind}},x=class extends b{},Ce=class extends b{},S=class extends b{},we=class extends b{},Te=class extends b{};const{setPrototypeOf:Ee=function(e,t){return e.__proto__=t,e}}=Object;var De=class e extends Error{framesToPop=1;name=`Invariant Violation`;constructor(t=`Invariant Violation`){super(typeof t==`number`?`Invariant Violation: ${t}`:t),Ee(this,e.prototype)}};function C(e,t){if(typeof e==`function`)C(e(),t);else if(!e)throw new De(t)}var Oe=class{listeners={};on(e,t){let n=this.listeners[e];return n||(n=new Set,this.listeners[e]=n),n.add(t),()=>this.off(e,t)}off(e,t){this.listeners[e]?.delete(t)}emit(e,...t){let n=this.listeners[e];if(n)for(let e of[...n])e(...t)}once(e,t){let n=((...r)=>{this.off(e,n),t(...r)});return this.on(e,n)}removeAllListeners(e){if(e!==void 0)delete this.listeners[e];else for(let e of Object.keys(this.listeners))delete this.listeners[e]}listenerCount(e){return this.listeners[e]?.size??0}},ke=class extends Oe{publish(e){let t=(e,...t)=>this.emit(e,...t);for(let[n,r]of Object.entries(e)){let e=r??[];t(n,...e),t(`*`,n,...e)}}subscribe(e,t,n=!1){return n?this.once(e,t):this.on(e,t)}subscribeAll(e){return this.subscribe(`*`,e)}};const Ae=new Set([`trace`,`debug`,`info`,`warn`,`error`,`fatal`]);function w(e){return Ae.has(e)?e:`info`}const je=(()=>{try{return e(import.meta.url)}catch{return}})();function Me(){if(!je)return!1;try{return je.resolve(`pino-pretty`),!0}catch{return!1}}function Ne(e){return e===`stdout`?1:e===`stderr`?2:e}function Pe(){return process.env.OTTO_LOG_STDERR===`0`}function Fe(){return process.env.OTTO_LOG_FILE||`${process.env.HOME||process.env.USERPROFILE||`.`}/.otto/logs/otto.log`}function Ie(e,t){let n=Me(),r=Pe(),i={target:n?`pino-pretty`:`pino/file`,options:n?{colorize:!0,destination:2}:{destination:2},level:t};if(!e||e===`stdout`||e===`stderr`)return r?[{target:`pino/file`,options:{destination:Fe(),mkdir:!0},level:t}]:[i];let a={target:`pino/file`,options:{destination:Ne(e),mkdir:!0},level:t};return r?[a]:[a,i]}const T=new c,Le=new ke;T.on(`data`,e=>{try{Le.publish({log:[JSON.parse(e.toString())]})}catch(t){console.warn(`Failed to parse log chunk for listener:`,e.toString(),t)}});function Re(e){return Le.subscribe(`log`,e)}let E=null,D=w(r);const ze=new Set;function O(e){if(Ae.has(e)){D=e,E&&(E.level=e);for(let t of ze)t.level=e}}function Be(){return k!==null}let k=null;function Ve(e,n){return globalThis.__miniv8_wasm===void 0?{write(r){k??=t.transport({targets:Ie(e,n)}),k.write(r)}}:{write:e=>{T.write(e)}}}function He(e,n){return E??=t({level:e},t.multistream([{level:e,stream:T},{level:e,stream:Ve(n,e)}])),D=w(E.level),E}function A(e,t){He(t?.level??w(r),t?.destination??n),C(E,`Root logger is not initialized`);let i=E.child({name:e},{level:t?.level??D});return ze.add(i),i}const Ue={log(e,t,r){He(D,n),C(E,`Root logger is not initialized`),E[e](r??{},t)},child(e){let t=A(e);return{log(e,n,r){t[e](r??{},n)},child(e){let n=t.child({name:e});return{log(e,t,r){n[e](r??{},t)},child(e){let n=t.child({name:e});return{log(e,t,r){n[e](r??{},t)},child:()=>{throw Error(`LoggerSink.child depth limit`)},setLevel(e){n.level=e}}},setLevel(e){n.level=e}}},setLevel(e){t.level=e}}},setLevel(e){O(e)}},j=10*1024*1024;async function We(e){return te(e)||`application/octet-stream`}async function Ge(e){await u(e,{recursive:!0})}async function Ke(e){try{return await m(e),!0}catch(e){if(e.code===`ENOENT`)return!1;throw e}}async function qe(e){return(await m(e)).isDirectory()}async function Je(e){return(await m(e)).isFile()}async function Ye(e,t=j){let n=await m(e);if(n.size<=t)return{content:await f(e,`utf-8`),truncated:!1,totalBytes:n.size};let r=await d(e,`r`);try{let e=Buffer.alloc(t),{bytesRead:i}=await r.read(e,0,t,0);return{content:e.subarray(0,i).toString(`utf-8`),truncated:!0,totalBytes:n.size}}finally{await r.close()}}function Xe(e){let{content:t,...n}=e;return n}function Ze(e){return e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}KB`:`${(e/(1024*1024)).toFixed(1)}MB`}function M(e){let t=e.outputBytes??Buffer.byteLength(e.content,`utf-8`),n=e.outputLines??e.content.split(`
2
+ `).length;return{content:e.content,truncated:e.truncated,truncatedBy:e.truncatedBy,totalLines:e.totalLines,totalBytes:e.totalBytes,outputLines:n,outputBytes:t,lastLinePartial:e.lastLinePartial,firstLineExceedsLimit:e.firstLineExceedsLimit,options:e.options}}function Qe(e,t){let{maxLines:n,maxBytes:r}=t,i=Buffer.byteLength(e,`utf-8`),a=e.split(`
3
+ `),o=a.length;if(a.length<=n&&i<=r)return M({content:e,truncated:!1,truncatedBy:`lines`,totalLines:o,totalBytes:i,lastLinePartial:!1,firstLineExceedsLimit:!1,options:{maxLines:n,maxBytes:r},outputLines:o,outputBytes:i});if(n===0)return M({content:``,truncated:!0,truncatedBy:`lines`,totalLines:o,totalBytes:i,lastLinePartial:!1,firstLineExceedsLimit:!1,options:{maxLines:n,maxBytes:r},outputLines:0,outputBytes:0});if(Buffer.byteLength(a[0],`utf-8`)>r)return M({content:``,truncated:!0,truncatedBy:`bytes`,totalLines:o,totalBytes:i,lastLinePartial:!1,firstLineExceedsLimit:!0,options:{maxLines:n,maxBytes:r},outputLines:0,outputBytes:0});let s=[],c=0,l=`lines`;for(let e=0;e<a.length&&e<n;e++){let t=a[e],n=Buffer.byteLength(t,`utf-8`)+(s.length>0?1:0);if(c+n>r){l=`bytes`;break}s.push(t),c+=n}return s.length>=n&&c<=r&&(l=`lines`),M({content:s.join(`
4
+ `),truncated:!0,truncatedBy:l,totalLines:o,totalBytes:i,lastLinePartial:!1,firstLineExceedsLimit:!1,options:{maxLines:n,maxBytes:r},outputLines:s.length,outputBytes:c})}function $e(e,t){let{maxLines:n,maxBytes:r}=t,i=Buffer.byteLength(e,`utf-8`),a=e.split(`
5
+ `),o=a.length;if(o<=n&&i<=r)return M({content:e,truncated:!1,truncatedBy:`lines`,totalLines:o,totalBytes:i,lastLinePartial:!1,firstLineExceedsLimit:!1,options:{maxLines:n,maxBytes:r},outputLines:o,outputBytes:i});if(n===0)return M({content:``,truncated:!0,truncatedBy:`lines`,totalLines:o,totalBytes:i,lastLinePartial:!1,firstLineExceedsLimit:!1,options:{maxLines:n,maxBytes:r},outputLines:0,outputBytes:0});let s=[],c=0,l=`lines`,u=!1;for(let e=a.length-1;e>=0&&s.length<n;e--){let t=a[e],n=Buffer.byteLength(t,`utf-8`)+(s.length>0?1:0);if(c+n>r){if(l=`bytes`,s.length===0){let e=et(t,r);e.length>0&&(s.unshift(e),c=Buffer.byteLength(e,`utf-8`),u=!0)}break}s.unshift(t),c+=n}return s.length>=n&&c<=r&&(l=`lines`),M({content:s.join(`
6
+ `),truncated:!0,truncatedBy:l,totalLines:o,totalBytes:i,lastLinePartial:u,firstLineExceedsLimit:!1,options:{maxLines:n,maxBytes:r},outputLines:s.length,outputBytes:c})}function et(e,t){let n=Buffer.from(e,`utf-8`);if(n.length<=t)return e;let r=n.length-t;for(;r<n.length;){let e=n[r];if(e===void 0||(e&192)!=128)break;r++}return n.subarray(r).toString(`utf-8`)}function tt(e,t){return e.length<=t?{text:e,wasTruncated:!1}:{text:`${e.slice(0,t)}... [truncated]`,wasTruncated:!0}}function N(){return a}function nt(){return i}function rt(){return _(nt(),`tools`)}function it(e,t=``){return _(rt(),...t?[e,t]:[e])}const P=`otto-coding-`,F=`.log`;function at(){let e=v();return g(ne(),`${P}${e}${F}`)}function ot(){let e=v();return g(N(),`tool-results`,`bash`,`${P}${e}${F}`)}async function st(e,t){return lt(ne(),e,t)}async function ct(e,t){return lt(g(N(),`tool-results`,`bash`),e,t)}async function lt(e,t,n){let r;try{r=await p(e)}catch{return 0}let i=r.filter(e=>e.startsWith(P)&&e.endsWith(F)),a=0;return await Promise.all(i.map(async r=>{let i=g(e,r);try{n-(await m(i)).mtimeMs>t&&(await h(i),a++)}catch{}})),a}function ut(e){let t=[],n=ae(e,t,{allowTrailingComma:!0,disallowComments:!1,allowEmptyContent:!1});if(t.length>0){let e=t[0],n=e?oe(e.error):`UnknownError`;throw Error(`Invalid JSONC: ${n}`)}return n}function dt(e,t){return se(e,void 0,t)??`null`}function ft(e,t){let n=``;for(let t=0;t<e.length;t++){let r=e[t];r===`*`?e[t+1]===`*`?(n+=`.*`,t++):n+=`[^/]*`:r===`?`?n+=`.`:n+=r.replace(/[.+^${}()|[\]\\]/g,`\\$&`)}return RegExp(`^${n}$`,`i`).test(t)}let I;function pt(e){I=e||void 0}function L(){return I}function R(e){let t=e||I;if(t)try{return new ue({uri:t})}catch{return}}let z;function B(e){if(z===void 0&&(z=de()),!e){y(z);return}try{y(new le({httpProxy:e,httpsProxy:e,noProxy:`localhost,127.0.0.1,[::1]`}))}catch{}}const mt={getUrl(){return L()},installGlobal(){B(I)},uninstallGlobal(){B(void 0)}},ht={kind:`idle`},gt={kind:`wallclock`};function _t(e,t){return e?t.idleTimeout:t.firstTokenIdleTimeout}function vt(e){let t=e.idleTimeout??12e4,n=e.firstTokenIdleTimeout??Math.max(t,9e5),r=e.timeout??3e5;return{timeout:Math.max(r,n+6e4),idleTimeout:t,firstTokenIdleTimeout:n}}function yt(e){let t=e.signal.reason;return typeof t==`object`&&t&&`kind`in t?t.kind:`external`}async function*bt(e){let{url:t,method:n=`POST`,headers:r={},body:i,signal:a}=e,{timeout:o,idleTimeout:s,firstTokenIdleTimeout:c}=vt(e),l=new AbortController,u=a?AbortSignal.any([a,l.signal]):l.signal,d=setTimeout(()=>l.abort(gt),o),f,p=!1,m=()=>{f&&clearTimeout(f),f=setTimeout(()=>l.abort(ht),_t(p,{idleTimeout:s,firstTokenIdleTimeout:c}))},h;try{let a=R(e.proxy),o={method:n,headers:{"content-type":`application/json`,accept:`text/event-stream`,...r},body:i?typeof i==`string`?i:JSON.stringify(i):void 0,signal:u},s=await fetch(t,a?{...o,dispatcher:a}:o);if(!s.ok){let e=await s.text(),t=`BAD_RESPONSE`;s.status===429?t=`RATE_LIMIT`:s.status===529?t=`OVERLOADED`:s.status>=500?t=`SERVER_ERROR`:s.status>=400&&(t=`REQUEST_ERROR`);let n;try{let t=JSON.parse(e)?.error;n=t?.code??t?.type}catch{}throw new x(`Http request failed ${s.status}: ${e}`,{code:t,status:s.status,headers:s.headers,errorType:n})}if(e.onResponse?.(s.headers),!s.body)throw new x(`Response body is empty`,{code:`BAD_RESPONSE`});h=s.body.getReader();let c=new TextDecoder,l=[],d=ce({onEvent(e){l.push({event:e.event||void 0,data:e.data,id:e.id||void 0})}});for(m();;){let{done:e,value:t}=await h.read();if(e)break;for(m(),d.feed(c.decode(t,{stream:!0}));l.length>0;){let e=l.shift();e&&(p||(p=!0,m()),yield e)}}for(d.feed(c.decode());l.length>0;){let e=l.shift();e&&(p||(p=!0,m()),yield e)}}catch(e){throw e instanceof x?e:l.signal.aborted||e instanceof DOMException&&e.name===`AbortError`?new x(`Stream aborted or timed out`,{code:`TIMEOUT`,cause:e instanceof Error?e:Error(String(e)),abortKind:yt(l)}):new x(`Stream request failed`,{code:`NETWORK_ERROR`,cause:e instanceof Error?e:Error(String(e))})}finally{clearTimeout(d),f&&clearTimeout(f),h&&h.cancel().catch(()=>{})}}async function xt(e,t=5e3){let n=Date.now(),r=new AbortController,i=setTimeout(()=>r.abort(),t);try{let t=await fetch(e,{method:`GET`,signal:r.signal});return{ok:!0,latencyMs:Date.now()-n,status:t.status}}catch(e){let t=Date.now()-n;if(r.signal.aborted)return{ok:!1,latencyMs:t,errorKind:`timeout`,errorMessage:`timeout`};let i=e instanceof Error?e.message:String(e);return{ok:!1,latencyMs:t,errorKind:St(e),errorMessage:i}}finally{clearTimeout(i)}}function St(e){switch(e?.cause?.code??e?.code){case`ECONNREFUSED`:case`ECONNRESET`:case`EHOSTUNREACH`:case`ENETUNREACH`:return`proxy-unreachable`;case`ENOTFOUND`:case`EAI_AGAIN`:return`target-unreachable`;case`UND_ERR_CONNECT_TIMEOUT`:case`UND_ERR_HEADERS_TIMEOUT`:case`ETIMEDOUT`:return`timeout`;default:return`unknown`}}function Ct(e,t){if(e==null)return;if(typeof e.get==`function`)return e.get(t)??void 0;let n=e;for(let e of Object.keys(n))if(e.toLowerCase()===t){let t=n[e];return typeof t==`string`?t:void 0}}const wt=[{description:`递归强制删除`,substring:`rm -rf`},{description:`递归强制删除(长格式)`,substring:`rm -r -f`},{description:`递归强制删除(长格式 2)`,substring:`rm --recursive --force`},{description:`删除根目录`,substring:`rm -rf /`},{description:`权限提升`,substring:`sudo rm`},{description:`权限提升`,substring:`sudo `},{description:`chmod 777`,substring:`chmod 777`},{description:`chmod -R 777`,substring:`chmod -R 777`},{description:`chmod 777 递归`,substring:`chmod -R`},{description:`curl 管道 shell 执行`,regex:/curl\s+\S+\s*\|\s*(ba)?sh/},{description:`wget 管道 shell 执行`,regex:/wget\s+\S+\s*-\s*O\s*-\s*\|\s*(ba)?sh/},{description:`fork bomb`,regex:/:\s*\(\s*\)\s*\{\s*:\s*\|\s*:?\s*&\s*\}\s*;?\s*:/},{description:`覆盖关键系统文件`,regex:/>\s*\/(etc|boot|sys|proc|dev)\//},{description:`mkfs 格式化`,substring:`mkfs.`},{description:`dd 覆写磁盘`,regex:/dd\s+if=.*of=\/dev\//}];function Tt(e){let t=e.trim();if(!t)return{safe:!0};for(let e of wt)if(e.substring!==void 0&&t.includes(e.substring)||e.regex!==void 0&&e.regex.test(t))return{safe:!1,reason:e.description};return{safe:!0}}function Et(e){let t=new Map,n=[`LC_`,`OTTO_`,`npm_`],r=new Set([`PATH`,`HOME`,`USER`,`SHELL`,`TMPDIR`,`TEMP`,`TMP`,`LANG`,`NODE_PATH`,`NODE_ENV`,`TERM`,`COLORTERM`,`TERM_PROGRAM`,`SSH_AUTH_SOCK`,`DISPLAY`,`WAYLAND_DISPLAY`,`XDG_RUNTIME_DIR`,`XDG_SESSION_TYPE`]);for(let[e,i]of Object.entries(process.env)){if(!i)continue;if(r.has(e)){t.set(e,i);continue}let a=e.toLowerCase();a.includes(`api_key`)||a.includes(`token`)||a.includes(`secret`)||a.includes(`password`)||a.includes(`passwd`)||a.includes(`credential`)||a.includes(`auth`)||n.some(t=>e.startsWith(t))&&t.set(e,i)}if(e)for(let[n,r]of Object.entries(e))r===void 0?t.delete(n):t.set(n,r);return Object.fromEntries(t)}const V={Bash:`bash`,Read:`read`,Write:`write`,Edit:`edit`,MultiEdit:`edit`,Grep:`grep`,Glob:`find`,WebFetch:`web_fetch`,WebSearch:`web_search`,Task:`task_delegate`,TodoWrite:`write_todos`};function Dt(e){return V[e]}const Ot=Object.fromEntries(Object.entries(V).reverse().map(([e,t])=>[t,e]));function kt(e){return Ot[e]??e}function At(e){return e.map(e=>V[e]??e)}function H(e){return e.toString(`base64url`)}function jt(){return H(ie(32))}function Mt(e){return H(re(`sha256`).update(e).digest())}function Nt(){let e=jt();return{verifier:e,challenge:Mt(e),method:`S256`}}function Pt(){return H(ie(16))}const Ft={renderSuccess(e,t,n){return`<!DOCTYPE html><html><body><h1>${U(e)}</h1><p>${U(t)}</p><p>${U(n)}</p></body></html>`},renderError(e,t,n){return`<!DOCTYPE html><html><body><h1>Error</h1><p>${U(e)}</p><p>${U(t)}</p><p>${U(n)}</p></body></html>`}};function U(e){return e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`).replace(/'/g,`&#39;`)}const It=[1455,1457];function W(e,t,n){let r=Buffer.from(n,`utf-8`);e.writeHead(t,{"Content-Type":`text/html; charset=utf-8`,"Content-Length":String(r.length),Connection:`close`}),e.end(r)}function Lt(e,t,n){return new Promise((r,i)=>{if(n.length===0){i(new S(`No loopback port specified.`,{code:`OAUTH_LOOPBACK_PORT_UNAVAILABLE`}));return}let a=0,o=()=>{e.removeListener(`error`,l),e.removeListener(`listening`,c)},s=()=>{let r=n[a++];e.listen(r,t)},c=()=>{o();let t=e.address();r(typeof t==`object`&&t?t.port:n[a-1])},l=e=>{if(e.code===`EADDRINUSE`||e.code===`EACCES`){if(a<n.length){s();return}o(),i(new S(`No available loopback port among: ${n.join(`, `)}`,{code:`OAUTH_LOOPBACK_PORT_UNAVAILABLE`}));return}o(),i(e)};e.on(`error`,l),e.on(`listening`,c),s()})}function Rt(e,t){e.value||(e.value=!0,t())}async function zt(e={}){let{ports:t=It,callbackPath:n=`/auth/callback`,expectedState:r,host:i=`127.0.0.1`,signal:a,pageRenderer:o=Ft}=e;if(a?.aborted)throw new S(`Login cancelled`,{code:`OAUTH_CANCELLED`});let s,c,l={value:!1},u=new Promise((e,t)=>{s=t=>Rt(l,()=>e(t)),c=e=>Rt(l,()=>t(e))});u.catch(()=>{});let d=0,f=()=>`http://${i}:${d}`,p=fe((e,t)=>{let i;try{i=new URL(e.url??`/`,f())}catch{W(t,400,o.renderError(`Login failed`,`Invalid request URL`,`Otto Auth`)),c(new S(`Invalid callback URL`,{code:`OAUTH_INVALID_REQUEST`}));return}if(i.pathname!==n){W(t,404,o.renderError(`Login failed`,`Not found`,`Otto Auth`));return}let a=i.searchParams.get(`error`);if(a){let e=i.searchParams.get(`error_description`)??``;W(t,400,o.renderError(`Login failed`,e||a,`Otto Auth`)),c(new S(`Authorization failed: ${a}${e?`: ${e}`:``}`,{code:`OAUTH_AUTHORIZE_FAILED`}));return}let l=i.searchParams.get(`code`);if(!l){W(t,400,o.renderError(`Login failed`,`Missing authorization code.`,`Otto Auth`)),c(new S(`Callback missing authorization code.`,{code:`OAUTH_AUTHORIZE_FAILED`}));return}let u=i.searchParams.get(`state`)??void 0;if(r!==void 0&&u!==r){W(t,400,o.renderError(`Login failed`,`State mismatch.`,`Otto Auth`)),c(new S(`OAuth state mismatch (possible CSRF).`,{code:`OAUTH_STATE_MISMATCH`}));return}W(t,200,o.renderSuccess(`Login complete`,`You can close this window and return to the terminal.`,`Otto Auth`)),s({code:l,state:u})});d=await Lt(p,i,t);let m=!1,h=()=>new Promise(e=>{if(m){e();return}m=!0,c(new S(`Login cancelled (server closed)`,{code:`OAUTH_CANCELLED`})),p.close(()=>e()),p.closeAllConnections?.()});return a&&a.addEventListener(`abort`,()=>{c(new S(`Login cancelled`,{code:`OAUTH_CANCELLED`})),h()},{once:!0}),{port:d,redirectUri:`${f()}${n}`,waitForCallback:()=>u,close:h}}function Bt(e){try{new URL(e)}catch{return!1}try{let t=process.platform,n=t===`darwin`?[`open`,[e]]:t===`win32`?[`cmd`,[`/c`,`start`,``,e]]:[`xdg-open`,[e]];return pe(n[0],[...n[1]],{detached:!0,stdio:`ignore`}).unref(),!0}catch{return!1}}const Vt=/^---\s*\n([\s\S]*?)\n---\s*\n?([\s\S]*)$/;function Ht(e){let t=Vt.exec(e);return t?{fields:Ut(t[1]??``),body:(t[2]??``).trim()}:null}function Ut(e){let t=new Map;for(let n of e.split(`
7
+ `)){let e=n.indexOf(`:`);if(e<=0)continue;let r=n.slice(0,e).trim().toLowerCase().replaceAll(`_`,``),i=n.slice(e+1).trim().replace(/^["']|["']$/g,``);r&&i&&t.set(r,i)}return t}function Wt(e){if(!e)return;let t=(e.startsWith(`[`)&&e.endsWith(`]`)?e.slice(1,-1):e).split(`,`).map(e=>e.trim().replace(/^["']|["']$/g,``)).filter(e=>e!==``);return t.length>0?t:void 0}const Gt=8e3,Kt=5*1024*1024,qt=Buffer.from([137,80,78,71,13,10,26,10]),Jt=Buffer.from(`GIF8`,`ascii`);function Yt(e,t){if(!(!e||e.length===0)&&!(e.length>7340032))try{return Xt(Buffer.from(e.slice(0,128),`base64`),e,t)}catch{return}}function Xt(e,t,n){let r=n.toLowerCase();if(r.includes(`png`))return Zt(e);if(r.includes(`jpeg`)||r.includes(`jpg`))return Qt(Buffer.from(t,`base64`));if(r.includes(`gif`))return $t(e);if(r.includes(`webp`))return en(e);if(e.length>=8&&e.subarray(0,8).equals(qt))return Zt(e);if(e.length>=2&&e.readUInt16BE(0)===65496)return Qt(Buffer.from(t,`base64`));if(e.length>=4&&e.subarray(0,4).equals(Jt))return $t(e);if(e.length>=12&&e.readUInt32BE(0)===1380533830&&e.readUInt32BE(8)===1464156752)return en(e)}function Zt(e){if(!(e.length<24)&&e.subarray(0,8).equals(qt))try{return e.toString(`ascii`,12,16)===`IHDR`?{width:e.readUInt32BE(16),height:e.readUInt32BE(20)}:void 0}catch{return}}function Qt(e){if(!(e.length<2))try{let t=2,n=0;for(;t<e.length-1;){if(n++,n>1e5)return;let r=e.readUInt16BE(t);if(r===65497||(r&65280)!=65280)return;let i=r&255;if(i>=192&&i<=195||i>=197&&i<=199||i>=201&&i<=203||i>=205&&i<=207){if(t+9>e.length||e.readUInt16BE(t+2)<8)return;let n=e.readUInt16BE(t+5);return{width:e.readUInt16BE(t+7),height:n}}if(i===216||i===217){t+=2;continue}if(t+4>e.length)return;let a=e.readUInt16BE(t+2);if(a<2)return;t+=2+a}return}catch{return}}function $t(e){if(!(e.length<10)&&e.subarray(0,4).equals(Jt))try{return{width:e.readUInt16LE(6),height:e.readUInt16LE(8)}}catch{return}}function en(e){if(!(e.length<16)&&!(e.readUInt32BE(0)!==1380533830||e.readUInt32BE(8)!==1464156752))try{let t=e.toString(`ascii`,12,16);return t===`VP8X`?tn(e):t===`VP8 `?nn(e):t===`VP8L`?rn(e):void 0}catch{return}}function tn(e){if(!(e.length<30))return{width:(e[24]|e[25]<<8|e[26]<<16)+1,height:(e[27]|e[28]<<8|e[29]<<16)+1}}function nn(e){if(e.length<30)return;let t=e.readUInt16LE(26)&16383,n=e.readUInt16LE(28)&16383;if(!(t===0||n===0))return{width:t,height:n}}function rn(e){if(e.length<25||e[20]!==47)return;let t=e.readUInt32LE(21);return{width:(t&16383)+1,height:(t>>14&16383)+1}}function an(e,t,n){return new Promise(r=>{let i=me({host:e,port:t}),a=!1,o=e=>{a||(a=!0,i.destroy(),r(e))};setTimeout(()=>o(!1),n).unref?.(),i.setTimeout(n),i.once(`connect`,()=>o(!0)),i.once(`error`,()=>o(!1)),i.once(`timeout`,()=>o(!1))})}const G=new Map;async function on(e,t={}){let n,r;try{let t=new URL(e);if(t.protocol!==`http:`&&t.protocol!==`https:`)return!1;n=t.hostname,r=t.port?Number(t.port):t.protocol===`https:`?443:80}catch{return!1}let i=`${n}:${r}`,a=Date.now();if(!t.force){let e=G.get(i);if(e&&a-e.at<3e5)return e.reachable}let o=await(t.connect??an)(n,r,t.timeoutMs??2e3);return G.set(i,{reachable:o,at:Date.now()}),o}async function sn(e=!1,t=[],n){let r=[...s(),...t];if(r.length===0)return!1;for(let t of r)if(await on(t,{force:e,...n?{connect:n}:{}}))return!0;return!1}function cn(){G.clear()}async function ln(e,t={}){if(e===void 0)return!0;try{return await e(),!0}catch(e){return t.logger?.warn({...t.context,err:e instanceof Error?e.message:String(e)},t.label??`dispose failed`),!1}}async function un(e,t={}){let n=e?.dispose;return typeof n==`function`?ln(()=>n.call(e),t):!0}const K=process.env.OTTO_STARTUP_TRACE===`1`,dn=K?performance.now():0;function fn(e){if(!K)return;let t=performance.now()-dn;process.stderr.write(`[startup] ${e}: ${t.toFixed(1)}ms\n`)}async function pn(e,t){if(!K)return t();let n=performance.now();try{return await t()}finally{let t=performance.now()-n;process.stderr.write(`[startup] ${e}: ${t.toFixed(1)}ms\n`)}}function mn(e,t){if(!K)return t();let n=performance.now();try{return t()}finally{let t=performance.now()-n;process.stderr.write(`[startup] ${e}: ${t.toFixed(1)}ms\n`)}}function hn(){return K}const gn=/[/\-_\s.]/;function _n(e){return e!==void 0&&gn.test(e)}function q(e,t){if(e.length===0)return{score:0,positions:[]};if(t.length===0)return null;let n=e.toLowerCase(),r=t.toLowerCase(),i=0,a=0,o=[],s=-2;for(let e=0;e<r.length&&a<n.length;e++)r[e]===n[a]&&(s===e-1?i+=24:(i+=16,s>=0&&(i-=(e-s-1)*3)),e===0?i+=12:_n(r[e-1])&&(i+=8),o.push(e),s=e,a++);return a<n.length?null:(i-=Math.max(0,r.length-n.length)*.5,{score:i,positions:o})}function vn(e,t){return q(e,t)?.score??-1}function yn(e){if(e.length===0)return[];let t=[],n=e[0],r=n+1;for(let i=1;i<e.length;i++){let a=e[i];a===r?r++:(t.push({start:n,end:r}),n=a,r=a+1)}return t.push({start:n,end:r}),t}function bn(e,t,n){let r=q(e,t);for(let t of n??[]){let n=q(e,t);n&&(!r||n.score>r.score)&&(r=n)}return r}function J(e,t,n={}){let r=n.maxResults??50,i=n.matchEmpty??!0,a=t.trim();if(a===``)return i?e.slice(0,r).map(e=>({item:e,score:0,highlightRanges:[]})):[];let o=[];for(let t of e){let e=bn(a,t.text,t.aliases);if(!e)continue;let n=q(a,t.text);o.push({item:t,score:e.score,highlightRanges:yn(n?.positions??[])})}return o.sort((e,t)=>t.score-e.score||(e.item.sortKey??e.item.text).localeCompare(t.item.sortKey??t.item.text)),o.slice(0,r)}function xn(e,t,n){return J(e.map(e=>({text:e.name,aliases:e.description?[e.description]:void 0,payload:e,sortKey:e.sortKey})),t,n).map(e=>e.item.payload)}function Sn(e,t,n){return J(e.map(e=>({text:e.searchText??e.label,aliases:[e.group,e.detail,e.value].filter(e=>!!e),payload:e})),t,{maxResults:n?.maxResults??e.length,matchEmpty:n?.matchEmpty}).map(e=>e.item.payload)}const Y=A(`@x-otto/shared:file-lock`),Cn=15e3;function wn(e){return Math.floor(e/3)}const X=new Map,Z=new Map;function Q(e,t,n=`file-lock`){return g(e,`.${n}-${t}.lock`)}function Tn(e,t){En(e);let n=setInterval(()=>{let t=new Date;ee(e,t,t).catch(()=>{})},wn(t));n.unref?.(),X.set(e,n)}function En(e){let t=X.get(e);t&&(clearInterval(t),X.delete(e))}async function Dn(e,t,n={}){let r=n.timeoutMs??15e3,i=Q(e,t,n.prefix),a=async(n=!1)=>{try{let e=await d(i,`wx`),t=v();await e.writeFile(t),await e.close(),Z.set(i,t);try{await l(i,384)}catch{}return Tn(i,r),!0}catch(r){if(r.code===`EEXIST`)return!1;if(r.code===`ENOENT`&&!n){try{await u(e,{recursive:!0})}catch(e){return Y.warn(`Failed to create lock directory for ${t}: ${e.message}`),!1}return await a(!0)}return Y.warn(`Failed to acquire file lock for ${t}: ${r.message}`),!1}};if(await a())return!0;try{let e=await m(i);if(Date.now()-e.mtimeMs>r)return await h(i).catch(()=>{}),await a()}catch{return await a()}return!1}async function On(e,t,n={}){let r=Q(e,t,n.prefix);En(r);let i=Z.get(r);if(Z.delete(r),i!==void 0)try{if(await f(r,`utf-8`)!==i){Y.warn(`File lock ownership drifted for ${t} — another process stole this lock (likely stale-lock takeover during a heartbeat gap). Skipping unlink to avoid deleting the new owner's lock.`);return}}catch{}await h(r).catch(()=>{})}async function kn(e,t,n={}){let r=Q(e,t,n.prefix),i=Z.get(r);if(i===void 0)return!1;try{return await f(r,`utf-8`)===i}catch{return!1}}async function An(e,t,n={}){let r=n.timeoutMs??15e3,i=Q(e,t,n.prefix),a=Date.now()+r;for(;Date.now()<a;){try{await m(i)}catch{return!0}await new Promise(e=>setTimeout(e,100))}return!1}const $=new Map;function jn(e,t,n={}){let r=n.timeoutMs??15e3,i=Q(e,t,n.prefix),a=(n=!1)=>{let r;try{r=ve(i,`wx`)}catch(r){let i=r.code;if(i===`EEXIST`)return!1;if(i===`ENOENT`&&!n){try{_e(e,{recursive:!0})}catch(e){return Y.warn(`Failed to create lock directory for ${t}: ${e.message}`),!1}return a(!0)}return Y.warn(`Failed to acquire file lock for ${t}: ${r.message}`),!1}let o=v();try{Se(r,o)}finally{ge(r)}$.set(i,o);try{he(i,384)}catch{}return!0};if(a())return!0;try{let e=be(i);if(Date.now()-e.mtimeMs>r){try{xe(i)}catch{}return a()}}catch{return a()}return!1}function Mn(e,t,n={}){let r=Q(e,t,n.prefix),i=$.get(r);if($.delete(r),i!==void 0)try{if(ye(r,`utf-8`)!==i){Y.warn(`File lock ownership drifted for ${t} — another process stole this lock. Skipping unlink to avoid deleting the new owner's lock.`);return}}catch{}try{xe(r)}catch{}}function Nn(e,t,n={}){let r=n.timeoutMs??15e3,i=Q(e,t,n.prefix),a=Date.now()+r,o=new Int32Array(new SharedArrayBuffer(4));for(;Date.now()<a;){try{be(i)}catch{return!0}Atomics.wait(o,0,0,100)}return!1}export{Gt as API_IMAGE_DIMENSION_LIMIT_PX,we as AgentError,V as CLAUDE_TO_OTTO_TOOL,b as CodedError,Cn as DEFAULT_FILE_LOCK_TIMEOUT_MS,ke as EventBus,De as InvariantError,j as LARGE_FILE_BYTE_THRESHOLD,Te as McpError,x as NetworkError,S as OAuthError,Kt as PROVIDER_IMAGE_INLINE_MAX_BYTES,Ce as ProviderError,Oe as TypedEventEmitter,Dn as acquireFileLock,jn as acquireFileLockSync,Re as attachLogListener,Et as buildAllowedEnv,Tt as checkShellCommand,R as createDispatcher,A as createLogger,Nt as createPkcePair,ot as createProjectOverflowLogPath,at as createTempLoggerPath,Ue as defaultLoggerSink,mt as defaultProxyConfig,Ke as exists,Ze as formatBytes,Mt as generateChallenge,Pt as generateState,jt as generateVerifier,L as getDefaultProxy,nt as getHomeDir,N as getProjectDir,it as getThirdPartyToolBinaryDir,rt as getThirdPartyToolDir,Ct as headerGet,B as installGlobalProxyDispatcher,C as invariant,qe as isDirectory,Je as isFile,kn as isFileLockHeldByMe,sn as isIntranetReachable,hn as isStartupTraceEnabled,Be as isTransportInitialized,on as isUrlReachable,Q as lockPath,At as mapClaudeAgentToolNames,Dt as mapClaudeToolName,fn as markStartupPhase,q as matchSubsequence,ft as matchesGlobPattern,We as mime,Ge as mkdirp,o as normalizePath,Bt as openBrowser,kt as ottoToClaudeToolName,Ut as parseFrontmatterFields,Wt as parseFrontmatterList,ut as parseJsonc,yn as positionsToHighlightRanges,Yt as probeImageDimensions,xt as probeProxy,J as rankCandidates,Sn as rankLabeledItems,xn as rankNamedItems,Ye as readFileCapped,On as releaseFileLock,Mn as releaseFileLockSync,cn as resetIntranetReachabilityCache,ln as safeDispose,un as safeDisposeOf,dt as safeStringify,vn as scoreSubsequence,pt as setDefaultProxy,O as setLogLevel,Ht as splitFrontmatter,zt as startLoopbackServer,bt as stream,ct as sweepStaleProjectOverflowLogs,st as sweepStaleTempLogs,Xe as toTruncationMeta,pn as traceStartupPhase,mn as traceStartupPhaseSync,Qe as truncateHead,tt as truncateLine,$e as truncateTail,An as waitForFileLockRelease,Nn as waitForFileLockReleaseSync};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@x-otto/shared",
3
- "version": "0.1.0-alpha.7",
3
+ "version": "0.1.0-alpha.9",
4
4
  "files": [
5
5
  "dist"
6
6
  ],
@@ -27,7 +27,7 @@
27
27
  "safe-stable-stringify": "2.5.0",
28
28
  "undici": "8.7.0",
29
29
  "uuid": "13.0.0",
30
- "@x-otto/env": "0.1.0-alpha.7"
30
+ "@x-otto/env": "0.1.0-alpha.9"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@types/mime-types": "3.0.1"