@quantiya/codevibe-codex-plugin 2.0.105 → 2.0.106
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -46
- package/dist/native-launch.js +9 -5
- package/dist/server.js +61 -61
- package/node_modules/@quantiya/codevibe-core/dist/companion-mode/codex-native-state.d.ts +414 -21
- package/node_modules/@quantiya/codevibe-core/dist/index.d.ts +1 -1
- package/node_modules/@quantiya/codevibe-core/dist/index.js +502 -502
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/cli.js +3 -2
- package/node_modules/@quantiya/codevibe-core/package.json +2 -2
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
## Why CodeVibe for Codex CLI
|
|
12
12
|
|
|
13
|
-
- **🚀 Real-time sync** — every prompt, response, shell command, and file patch shows up on your phone
|
|
13
|
+
- **🚀 Real-time sync** — every prompt, response, shell command, and file patch shows up on your phone
|
|
14
14
|
- **✅ Approve from anywhere** — review full file diffs and approve or reject file edits from your phone
|
|
15
15
|
- **🧠 Reasoning visibility** — see Codex's thinking/reasoning alongside its output
|
|
16
16
|
- **🎙️ Voice prompts** — dictate your next prompt with speech-to-text
|
|
@@ -48,47 +48,46 @@ install the unified `codevibe --agent` interface yet.
|
|
|
48
48
|
|
|
49
49
|
## How it works
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
Each live Codex process appears as its own session on your phone, so you can run multiple concurrent Codex sessions side-by-side with Claude and Antigravity.
|
|
51
|
+
CodeVibe connects your terminal and mobile companion to the same native Codex
|
|
52
|
+
app-server. Mobile text, image inputs, questions and approvals use structured
|
|
53
|
+
native requests and receipts. tmux keeps the terminal session available across
|
|
54
|
+
detach; mobile responses do not use terminal keystrokes or prompt-text parsing.
|
|
55
|
+
The launcher leaves your Codex hooks and configuration alone.
|
|
56
|
+
|
|
57
|
+
CodeVibe checks the native capabilities it needs instead of requiring one exact
|
|
58
|
+
Codex version. Missing capabilities produce an update message. Compatible newer
|
|
59
|
+
versions have no upper version ceiling.
|
|
60
|
+
|
|
61
|
+
The observer binds the native thread's exact rollout path, watches new records,
|
|
62
|
+
and sends the encrypted timeline to your phone. Desktop prompts with inline
|
|
63
|
+
images retain their text and an image indicator; that indicator is not an
|
|
64
|
+
uploaded desktop-image thumbnail. Images sent from mobile are downloaded and
|
|
65
|
+
submitted to Codex as native image inputs.
|
|
66
|
+
|
|
67
|
+
Command approvals preserve the offered order and scope, including command-prefix
|
|
68
|
+
or session permission when offered. Choosing a prefix grants the native rule
|
|
69
|
+
shown on the card; it is broader than approving one command.
|
|
70
|
+
|
|
71
|
+
Resume an explicit native thread with:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
codevibe --agent codex -- resume <native-session-id>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Cold resume has a separate two-minute startup budget, progress every five
|
|
78
|
+
seconds, and Ctrl+C cancellation. Native history remains owned by Codex. If plain
|
|
79
|
+
Codex cannot load a session, increasing CodeVibe's timeout does not repair that
|
|
80
|
+
history. CodeVibe does not rewrite or delete it.
|
|
81
|
+
|
|
82
|
+
Each live Codex process appears as its own mobile session alongside Claude and
|
|
83
|
+
Antigravity.
|
|
85
84
|
|
|
86
85
|
## What gets synced
|
|
87
86
|
|
|
88
87
|
| Direction | What |
|
|
89
88
|
|---|---|
|
|
90
|
-
| **Desktop → Mobile** | User prompts, assistant responses,
|
|
91
|
-
| **Mobile → Desktop** | Text
|
|
89
|
+
| **Desktop → Mobile** | User prompts and image indicators, assistant responses, reasoning, tool activity, file diffs and approval cards |
|
|
90
|
+
| **Mobile → Desktop** | Text and image inputs, question answers and exact native approval decisions |
|
|
92
91
|
|
|
93
92
|
## CLI commands
|
|
94
93
|
|
|
@@ -102,17 +101,17 @@ codevibe logout # Sign out
|
|
|
102
101
|
|
|
103
102
|
## Troubleshooting
|
|
104
103
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
# Verify session logs exist
|
|
110
|
-
ls -la ~/.codex/sessions/$(date +%Y)/$(date +%m)/$(date +%d)/
|
|
104
|
+
Keep the startup error and the output of `codex --version`. If required native
|
|
105
|
+
capabilities are missing, update Codex using your usual installer and retry.
|
|
106
|
+
Other startup errors are reported separately from missing capabilities.
|
|
111
107
|
|
|
112
|
-
|
|
113
|
-
|
|
108
|
+
While running, the observer log is inside this launch's private
|
|
109
|
+
`/tmp/cvcd-<launch>/tmp/codevibe-codex-mcp.log` directory. Clean exit removes the
|
|
110
|
+
private runtime. Resume failures should also be checked with plain
|
|
111
|
+
`codex resume <native-session-id>` before changing any stored history.
|
|
114
112
|
|
|
115
|
-
|
|
113
|
+
```bash
|
|
114
|
+
codevibe status
|
|
116
115
|
codevibe update
|
|
117
116
|
```
|
|
118
117
|
|
package/dist/native-launch.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`).slice(1)){for(let[l,u]of[["server.js","server"],["index.js","core"],["native-launch.js","native-launch"]]){let f="/dist/"+l+":",N=s.lastIndexOf(f);if(N<0)continue;let E=s.slice(N+f.length).split(")")[0].trim().split(":");if(E.length===2&&E.every(h=>h.length>0&&[...h].every(m=>"0123456789".includes(m)))){let[h,m]=E.map(Number);h>0&&h<1e5&&m>0&&m<1e7&&(a={module:u,line:h,column:m})}if(a)break}if(a)break}return new v("NATIVE_HANDLER_FAILED",void 0,void 0,{method:t,errorName:n&&r.includes(n.name)?n.name:"Error",causeCode:d,site:a})}var Y=class{constructor(e){this.options=e;this.socket=null;this.pending=new Map;this.handlers=new Set;this.accepting=!1;this.intentionalClose=!1;this.initialized=!1;this.requestPrefix="codevibe-"+(0,Se.randomUUID)()+"-";this.sequence=0;this.instanceId=e.instanceId,this.endpoint={socketPath:e.socketPath,socketIdentity:{...e.socketIdentity},...e.alias?{alias:{...e.alias}}:{}}}async assertSocket(){this.options.assertOwner();let e=this.endpoint.socketPath;if(!D.isAbsolute(e)||D.normalize(e)!==e||e.includes(":")||e.includes("\0"))throw new v("NATIVE_SOCKET_UNSAFE");let t=await O.promises.lstat(D.dirname(e)),n=await O.promises.lstat(e),r=typeof process.getuid=="function"?process.getuid():void 0,o={rootDirectory:t.isDirectory(),rootNotSymlink:!t.isSymbolicLink(),rootPrivate:(t.mode&63)===0,ownerMatches:r===void 0||t.uid===r&&n.uid===r,socketType:n.isSocket(),socketNotSymlink:!n.isSymbolicLink(),socketIdentityMatches:n.dev===this.endpoint.socketIdentity.dev&&n.ino===this.endpoint.socketIdentity.ino};if(Object.values(o).some(a=>!a))throw new v("NATIVE_SOCKET_UNSAFE",void 0,o);let d=this.endpoint.alias;if(d){let a=await O.promises.lstat(D.dirname(d.path)),s=await O.promises.lstat(d.path);if(!a.isDirectory()||a.isSymbolicLink()||(a.mode&63)!==0||a.dev!==d.rootDev||a.ino!==d.rootIno||!s.isSymbolicLink()||s.dev!==d.dev||s.ino!==d.ino||r!==void 0&&(a.uid!==r||s.uid!==r)||await O.promises.readlink(d.path)!==d.target||await O.promises.realpath(d.path)!==e)throw new v("NATIVE_SOCKET_UNSAFE",void 0,{originalAliasMatches:!1})}this.options.assertOwner()}async connect(){try{await this.connectOnce()}catch(e){throw await this.close(),e}}async connectOnce(){if(this.socket||this.intentionalClose)throw new v("NATIVE_DISCONNECTED");await this.assertSocket();let e=new te.default("ws+unix://"+this.endpoint.socketPath+":/");this.socket=e,this.accepting=!0,e.on("message",t=>this.receive(t.toString())),e.on("error",()=>this.fail(new v("NATIVE_DISCONNECTED"))),e.on("close",()=>{this.initialized=!1,this.accepting=!1,this.rejectPending(),this.intentionalClose||this.report(new v("NATIVE_DISCONNECTED"))}),await new Promise((t,n)=>{let r=setTimeout(()=>{a(new v("NATIVE_RPC_TIMEOUT",void 0,{webSocketOpenTimedOut:!0})),e.terminate()},2e3),o=()=>a(),d=()=>a(new v("NATIVE_DISCONNECTED")),a=s=>{clearTimeout(r),e.off("open",o),e.off("error",d),e.off("close",d),s?n(s):t()};e.once("open",o),e.once("error",d),e.once("close",d)}),await this.assertSocket(),await this.request("initialize",{clientInfo:{name:"codevibe-codex",version:this.options.pluginVersion},capabilities:{experimentalApi:!0,requestAttestation:!1}},2e3),await this.notify("initialized"),this.initialized=!0}report(e){try{Promise.resolve(this.options.onFailure(e)).catch(()=>{})}catch{}}rejectPending(){for(let e of this.pending.values())clearTimeout(e.timer),e.reject(new v("NATIVE_DISCONNECTED"));this.pending.clear()}fail(e){this.accepting=!1,this.initialized=!1,this.rejectPending(),this.intentionalClose||this.report(e),this.socket?.terminate()}receive(e){if(!this.accepting)return;let t;try{let r=JSON.parse(e);if(!r||typeof r!="object"||Array.isArray(r))throw Error();t=r}catch{this.fail(new v("NATIVE_PROTOCOL_INVALID"));return}if(typeof t.method=="string"){if(t.id!==void 0&&typeof t.id!="string"&&typeof t.id!="number"){this.fail(new v("NATIVE_PROTOCOL_INVALID"));return}let r;try{this.options.assertOwner(),r=this.options.onMessage(t)}catch(d){this.report(be(t.method,d));return}let o=Promise.resolve(r).catch(d=>this.report(be(t.method,d)));this.handlers.add(o),o.then(()=>this.handlers.delete(o));return}if(typeof t.id!="string")return;let n=this.pending.get(t.id);if(n)if(this.pending.delete(t.id),clearTimeout(n.timer),t.error!==void 0){let r=t.error?.code;n.reject(new v("NATIVE_RPC_REJECTED",typeof r=="number"?r:void 0))}else Object.prototype.hasOwnProperty.call(t,"result")?n.resolve(t.result):n.reject(new v("NATIVE_PROTOCOL_INVALID"))}async write(e){this.options.assertOwner();let t=this.socket;if(!t||t.readyState!==te.default.OPEN||!this.accepting)throw new v("NATIVE_DISCONNECTED");await new Promise((n,r)=>t.send(JSON.stringify(e),o=>o?r(new v("NATIVE_DISCONNECTED")):n())),this.options.assertOwner()}async request(e,t,n=1e4){if(!this.initialized&&e!=="initialize")throw new v("NATIVE_DISCONNECTED");if(!Number.isFinite(n)||n<=0||n>1e4)throw new v("NATIVE_PROTOCOL_INVALID");let r=this.requestPrefix+ ++this.sequence,d=new Promise((s,l)=>{let u=setTimeout(()=>{this.pending.delete(r),l(new v("NATIVE_RPC_TIMEOUT",void 0,{initializeTimedOut:e==="initialize",threadResumeTimedOut:e==="thread/resume",otherRpcTimedOut:e!=="initialize"&&e!=="thread/resume"}))},n);this.pending.set(r,{resolve:s,reject:l,timer:u})}).then(s=>({value:s}),s=>({error:s}));try{await this.write({id:r,method:e,params:t})}catch(s){let l=this.pending.get(r);throw l&&(clearTimeout(l.timer),this.pending.delete(r),l.reject(new v("NATIVE_DISCONNECTED"))),await d,s}let a=await d;if("error"in a)throw a.error;return a.value}async notify(e,t){await this.write({method:e,...t===void 0?{}:{params:t}})}async respond(e,t){if(!this.initialized)throw new v("NATIVE_DISCONNECTED");await this.write({id:e,result:t})}async close(){this.intentionalClose=!0,this.accepting=!1,this.initialized=!1,this.rejectPending();let e=this.socket;e&&e.readyState!==te.default.CLOSED&&await new Promise(t=>{let n=setTimeout(()=>{e.terminate(),t()},2e3);e.once("close",()=>{clearTimeout(n),t()}),e.close()}),await this.joinHandlers(),this.socket=null}async joinHandlers(){await Promise.allSettled([...this.handlers])}};var j=require("node:fs"),R=H(require("node:path")),Pe=H(require("node:os")),pe=require("node:util");var A=class extends Error{constructor(t){super(t);this.code=t;this.name="NativeRuntimeError"}},z=()=>{throw new A("NATIVE_LAUNCH_AUTHORITY_INVALID")};function ie(i){return!i||typeof i!="object"||Array.isArray(i)?z():i}function lt(i,e){return Object.keys(i).sort().join(",")===e.sort().join(",")}function Re(i){return typeof i=="number"&&Number.isSafeInteger(i)&&i>0}function De(i){try{process.kill(i,0)}catch{z()}}async function ke(i,e){if(!R.isAbsolute(i)||R.normalize(i)!==i||R.basename(i)!=="launch.json")return z();let t=typeof process.getuid=="function"?process.getuid():void 0,n=await j.promises.open(i,j.constants.O_RDONLY|j.constants.O_NOFOLLOW),r,o;try{let a=await n.stat();if(!a.isFile()||a.nlink!==1||(a.mode&63)!==0||a.size>2*1024*1024||t!==void 0&&a.uid!==t)return z();let s=ie(JSON.parse(await n.readFile("utf8")));if(!lt(s,["version","instanceId","root","launcher","server","endpoint","plan"])||s.version!==1||s.instanceId!==e||typeof e!="string"||!e.length||!Re(s.launcher?.pid)||s.launcher.host!==Pe.hostname()||!Re(s.server?.pid)||s.root?.path!==R.dirname(i)||!Number.isSafeInteger(s.root.dev)||!Number.isSafeInteger(s.root.ino)||s.root.uid!==t||!R.isAbsolute(s.endpoint?.socketPath??"")||!Number.isSafeInteger(s.endpoint?.socketIdentity?.dev)||!Number.isSafeInteger(s.endpoint?.socketIdentity?.ino)||!R.isAbsolute(s.plan?.workingDirectory??"")||s.plan.resumeThreadId!==null&&typeof s.plan.resumeThreadId!="string")return z();let l=await n.stat();if(a.dev!==l.dev||a.ino!==l.ino||a.size!==l.size||a.mtimeMs!==l.mtimeMs)return z();r=s,o={dev:a.dev,ino:a.ino,size:a.size,mtimeMs:a.mtimeMs}}finally{await n.close()}let d=()=>{let a=(0,j.lstatSync)(r.root.path),s=(0,j.lstatSync)(i);if(!a.isDirectory()||a.isSymbolicLink()||(a.mode&63)!==0||a.dev!==r.root.dev||a.ino!==r.root.ino||a.uid!==r.root.uid||!s.isFile()||s.isSymbolicLink()||s.nlink!==1||(s.mode&63)!==0||s.dev!==o.dev||s.ino!==o.ino||s.size!==o.size||s.mtimeMs!==o.mtimeMs||s.uid!==r.root.uid)return z();De(r.launcher.pid),De(r.server.pid)};return d(),{record:JSON.parse(JSON.stringify(r)),assertCurrent:d}}function ue(i){let e=ie(i);if(typeof e.id!="string"||!e.id.length)throw new A("NATIVE_ROOT_INVALID_ID");if(e.sessionId!==e.id||e.parentThreadId!=null)throw new A("NATIVE_ROOT_INVALID_SESSION");if(e.ephemeral!==!1)throw new A("NATIVE_ROOT_INVALID_PERSISTENCE");if(typeof e.cwd!="string"||!R.isAbsolute(e.cwd))throw new A("NATIVE_ROOT_INVALID_CWD");if(!Number.isFinite(e.createdAt)||e.createdAt<0)throw new A("NATIVE_ROOT_INVALID_TIMESTAMP");if(e.path!==null&&(typeof e.path!="string"||!R.isAbsolute(e.path)))throw new A("NATIVE_ROOT_INVALID_PATH");if(typeof e.cliVersion!="string")throw new A("NATIVE_ROOT_INVALID_VERSION");if(typeof e.modelProvider!="string")throw new A("NATIVE_ROOT_INVALID_PROVIDER");return{id:e.id,sessionId:e.sessionId,cwd:e.cwd,createdAt:e.createdAt,path:e.path,cliVersion:e.cliVersion,modelProvider:e.modelProvider}}var ne=class{constructor(e){this.options=e;this.root=null;this.ready=!1;this.generation=0;this.bindingDepth=0;this.binding=Promise.resolve();this.closed=!1;this.refreshPending=null;this.pendingControls=new Map;this.pendingFiles=new Map;this.client=new Y({...e.authority.record.endpoint,instanceId:e.authority.record.instanceId,pluginVersion:e.pluginVersion,assertOwner:e.authority.assertCurrent,onMessage:t=>this.observe(t),onFailure:t=>t.handlerFailure?e.onFailure(t.code,t.handlerFailure):e.onFailure(t.code)})}get thread(){return this.root?{...this.root}:null}controlFacts(){return JSON.parse(JSON.stringify([...this.pendingFiles.values(),...this.pendingControls.values()]))}isCurrentControl(e){let t=e.id===void 0?void 0:this.pendingControls.get(e.id);return!this.closed&&!!t&&t.method===e.method&&(0,pe.isDeepStrictEqual)(t.params,e.params)}hasPendingControl(){return this.pendingControls.size>0}async start(){await this.client.connect();let e=this.options.authority.record.plan.resumeThreadId??this.options.recoveryThreadId;e&&await this.bind(await this.readMetadata(e))}bind(e){let t=this.options.authority.record.plan.resumeThreadId??this.options.recoveryThreadId;if(!this.root&&t&&e.id!==t)return Promise.reject(new A("NATIVE_ROOT_INVALID"));if(this.root&&e.id===this.root.id&&e.cwd!==this.root.cwd)return Promise.reject(new A("NATIVE_ROOT_INVALID"));if(this.root&&(0,pe.isDeepStrictEqual)(this.root,e)&&(this.ready||this.bindingDepth>0))return this.binding;(!this.root||this.root.id!==e.id)&&(this.generation++,this.ready=!1,this.pendingControls.clear(),this.pendingFiles.clear());let n=this.generation;this.root={...e},this.bindingDepth++;let r=this.binding.then(async()=>{if(this.closed)throw new A("NATIVE_BINDING_FAILED");await this.options.onRoot({...e}),n===this.generation&&!this.closed&&(this.ready=!0)});return this.binding=r.catch(()=>{}),r.then(()=>{this.bindingDepth--},()=>{this.bindingDepth--}),r}observe(e){if(this.closed)return;let t=e.params;if(e.method==="thread/started"){let r=t?.thread;return r?.ephemeral===!0||r?.parentThreadId!=null||r?.sessionId!==r?.id?void 0:this.bind(ue(r))}if(!this.root||t?.threadId!==this.root.id)return;if(e.id!==void 0&&this.pendingControls.set(e.id,JSON.parse(JSON.stringify(e))),e.method==="serverRequest/resolved"&&this.pendingControls.delete(t.requestId),["item/started","item/completed"].includes(e.method)&&t.item?.type==="fileChange"&&this.pendingFiles.set(t.item.id,JSON.parse(JSON.stringify(e))),e.method==="item/completed"&&["commandExecution","fileChange"].includes(t.item?.type)){for(let[r,o]of this.pendingControls){let d=o.params;d.turnId===t.turnId&&d.itemId===t.item.id&&this.pendingControls.delete(r)}this.pendingFiles.delete(t.item.id)}if(!this.ready&&this.bindingDepth===0&&e.method==="turn/started"&&this.bind(this.root).catch(()=>{}),["item/agentMessage/delta","item/reasoning/textDelta","item/commandExecution/outputDelta"].includes(e.method))return;if(this.ready)return this.options.onMessage(e);let n=this.generation;return this.binding.then(()=>{if(!this.ready||this.closed||n!==this.generation)throw new A("NATIVE_BINDING_FAILED");return this.options.onMessage(e)})}async readMetadata(e){let t=await this.client.request("thread/resume",{threadId:e,excludeTurns:!0},2e3),n=ue(ie(t).thread);if(n.id!==e)throw new A("NATIVE_ROOT_INVALID");return n}refreshMetadata(){if(this.refreshPending)return this.refreshPending;if(!this.root||this.closed)return Promise.resolve(null);let e=this.root.id,t=(async()=>{let n=Date.now()+2e3;for(let r=0;r<10&&Date.now()<n;r++)try{let o=await this.client.request("thread/resume",{threadId:e,excludeTurns:!0},Math.max(1,n-Date.now())),d=ue(ie(o).thread);if(d.id!==e||this.root?.id!==e||this.closed)throw new A("NATIVE_ROOT_INVALID");return await this.bind(d),d}catch(o){if(!(o instanceof v)||o.code!=="NATIVE_RPC_REJECTED"||![-32600,-32601].includes(o.rpcCode??0))throw o;r<9&&Date.now()<n&&await new Promise(d=>setTimeout(d,Math.min(100,n-Date.now())))}return null})();return this.refreshPending=t,t.then(()=>{this.refreshPending=null},()=>{this.refreshPending=null}),t}async close(){this.closed=!0,await this.client.close(),await this.binding,await this.refreshPending?.catch(()=>{})}};var xe=require("node:crypto"),re=require("node:util"),Le=2*1024*1024,oe=i=>JSON.parse(JSON.stringify(i)),Me=i=>(0,xe.createHash)("sha256").update(JSON.stringify(i)).digest("hex");function _(i){if(!i||typeof i!="object"||Array.isArray(i))throw Error("NATIVE_RECEIPT_INVALID");return i}function G(i){return typeof i=="string"&&i.length>0&&i.length<=512}function Ue(i){return G(i)||typeof i=="number"&&Number.isSafeInteger(i)&&i>=0}function Fe(i){return{nativeInstanceId:i.nativeInstanceId,request:i.request,resolved:i.resolved,completed:i.completed,turnCompleted:i.turnCompleted}}function ut(i,e){let t=_(i);if(Buffer.byteLength(JSON.stringify(t))>Le||Object.keys(t).sort().join(",")!=="completed,digest,nativeInstanceId,request,resolved,turnCompleted"||t.nativeInstanceId!==e||!G(e))throw Error("NATIVE_RECEIPT_INVALID");let n=_(t.request),r=_(t.resolved),o=_(t.completed),d=_(t.turnCompleted),a=_(n.params),s=_(r.params),l=_(o.params),u=_(d.params),f=_(l.item),N=_(u.turn),E=n.method==="item/commandExecution/requestApproval"?"commandExecution":n.method==="item/fileChange/requestApproval"?"fileChange":null;if(!E||!Ue(n.id)||![a.threadId,a.turnId,a.itemId].every(G)||r.method!=="serverRequest/resolved"||s.threadId!==a.threadId||s.requestId!==n.id||o.method!=="item/completed"||l.threadId!==a.threadId||l.turnId!==a.turnId||f.id!==a.itemId||f.type!==E||!["completed","failed","declined"].includes(f.status)||d.method!=="turn/completed"||u.threadId!==a.threadId||N.id!==a.turnId||!["completed","failed","interrupted"].includes(N.status))throw Error("NATIVE_RECEIPT_INVALID");let h=Fe(t);if(t.digest!==Me(h))throw Error("NATIVE_RECEIPT_INVALID");return{...oe(h),digest:t.digest}}var se=class{constructor(e){this.instanceId=e;this.rows=new Map;this.unavailable=!1;if(!G(e))throw Error("NATIVE_RECEIPT_INVALID")}invalidate(){this.unavailable=!0}get isUnavailable(){return this.unavailable}key(e,t){return JSON.stringify([e,t])}observe(e){if(!this.unavailable)try{let t=oe(e),n=_(t.params);if(!G(n.threadId)||!["item/commandExecution/requestApproval","item/fileChange/requestApproval","serverRequest/resolved","turn/completed"].includes(t.method)&&!(t.method==="item/completed"&&["commandExecution","fileChange"].includes(n.item?.type)))return;let r=new Map(oe([...this.rows]));if(t.id!==void 0&&["item/commandExecution/requestApproval","item/fileChange/requestApproval"].includes(t.method)){if(!Ue(t.id)||!G(n.turnId)||!G(n.itemId))throw Error("NATIVE_RECEIPT_INVALID");let o=this.key(n.threadId,t.id),d=r.get(o);if(d){if(d.request.method!==t.method||!(0,re.isDeepStrictEqual)(d.request.params,t.params))throw Error("NATIVE_RECEIPT_COLLISION");return}r.set(o,{request:t,resolved:null,completed:null,turnCompleted:null})}else for(let o of r.values()){let d=_(o.request.params);if(d.threadId===n.threadId){if(t.method==="serverRequest/resolved"&&n.requestId===o.request.id&&!o.resolved&&(o.resolved=t),t.method==="item/completed"&&n.turnId===d.turnId&&n.item?.id===d.itemId&&n.item.type===(o.request.method==="item/commandExecution/requestApproval"?"commandExecution":"fileChange")){let a=oe(t);if(delete _(_(a.params).item).aggregatedOutput,o.completed&&!(0,re.isDeepStrictEqual)(_(o.completed.params).item,_(a.params).item))throw Error("NATIVE_RECEIPT_COLLISION");o.completed??=a}if(t.method==="turn/completed"&&n.turn?.id===d.turnId){let a={method:t.method,params:{threadId:n.threadId,turn:{id:n.turn.id,status:n.turn.status}}};if(o.turnCompleted&&!(0,re.isDeepStrictEqual)(o.turnCompleted,a))throw Error("NATIVE_RECEIPT_COLLISION");o.turnCompleted??=a}}}if(Buffer.byteLength(JSON.stringify([...r]))>Le)throw Error("NATIVE_RECEIPT_WINDOW_FULL");this.rows=r}catch{this.invalidate()}}receipts(){if(this.unavailable)throw Error("NATIVE_RECEIPTS_UNAVAILABLE");return[...this.rows.values()].flatMap(e=>{if(!e.resolved||!e.completed||!e.turnCompleted)return[];let t=Fe({nativeInstanceId:this.instanceId,request:e.request,resolved:e.resolved,completed:e.completed,turnCompleted:e.turnCompleted});return[ut({...t,digest:Me(t)},this.instanceId)]})}acknowledge(e){let t=this.receipts().find(n=>n.digest===e);if(!t)throw Error("NATIVE_RECEIPT_ACK_INVALID");this.rows.delete(this.key(_(t.request.params).threadId,t.request.id))}},ae=class{constructor(e){this.window=e;this.current=null;this.sent=new Set;this.warned=!1;this.ready=!1}attach(e){this.current=e,this.sent.clear(),this.warned=!1,this.ready=!1}close(){this.current=null,this.sent.clear(),this.ready=!1}handle(e,t){let n=t;if(!n||!["CODEVIBE_NATIVE_RECEIPTS_POLL","CODEVIBE_NATIVE_RECEIPT_ACK"].includes(String(n.type)))return!1;if(e!==this.current||n.instanceId!==this.window.instanceId||e.connected!==!0)return!0;if(n.type==="CODEVIBE_NATIVE_RECEIPTS_POLL")this.ready=!0,this.flush();else if(typeof n.digest=="string"&&this.sent.has(n.digest)&&typeof n.consumed=="boolean"){if(n.consumed)try{this.window.acknowledge(n.digest)}catch{this.window.invalidate()}this.sent.delete(n.digest)}return!0}flush(){let e=this.current;if(!(!this.ready||!e||e.connected!==!0)){if(this.window.isUnavailable){this.warned||(this.warned=!0,this.send(e,{type:"CODEVIBE_NATIVE_RECEIPTS_UNAVAILABLE",instanceId:this.window.instanceId}));return}try{for(let t of this.window.receipts())this.sent.has(t.digest)||(this.sent.add(t.digest),this.send(e,{type:"CODEVIBE_NATIVE_RECEIPT",instanceId:this.window.instanceId,receipt:t}))}catch{this.window.invalidate(),this.flush()}}}send(e,t){try{e.send(t,n=>{n&&this.current===e&&this.window.invalidate()})}catch{this.current===e&&this.window.invalidate()}}};var ht=i=>new Promise(e=>setTimeout(e,i)),Xe=1e4;async function he(i,e,t=n=>console.error("CodeVibe: native startup failed",n)){let n=Date.now();try{return await e()}catch(r){try{t({stage:i,elapsedMs:Date.now()-n,code:r instanceof v?r.code:"NATIVE_STARTUP_FAILED",...r instanceof v&&r.diagnostic?{diagnostic:r.diagnostic}:{}})}catch{}throw r}}var C=i=>!i.pid||i.exitCode!==null||i.signalCode!==null;async function q(i,e){return C(i)?!0:new Promise(t=>{let n=setTimeout(()=>o(!1),e);n.unref();let r=()=>o(!0),o=d=>{clearTimeout(n),i.off("close",r),t(d)};i.once("close",r)})}async function He(i,e,t){for(let n of(e.PATH??"").split(y.delimiter).filter(Boolean)){let r=y.resolve(t,n,i);try{await c.promises.access(r,c.constants.X_OK);let o=await c.promises.realpath(r);if((await c.promises.stat(o)).isFile())return o}catch{}}throw Error(i==="codex"?"Codex executable not found;install Codex,then retry.":"tmux executable not found;install tmux,then retry.")}var me=(i,e)=>He("codex",i,e);function fe(i){let e={...i};return delete e.CODEVIBE_CODEX_TMUX_SESSION,delete e.CODEVIBE_CODEX_PRIMARY_COMPANION,delete e.QUORUM_REVIEWER_SUBPROCESS,e}async function ve(i,e=process.env){let t=e.TMUX?.split(",")[0];if(!t||!y.isAbsolute(t)||!process.stdin.isTTY||!process.stdout.isTTY)throw Error("Native Companion requires its terminal launcher.");let n=await c.promises.mkdtemp(y.join(await c.promises.realpath("/tmp"),"cvcd-")),r=await c.promises.lstat(n),o=(0,B.randomUUID)(),d={root:n,dev:r.dev,ino:r.ino,uid:r.uid,instanceId:o,pid:process.pid};await c.promises.writeFile(n+"/OWNER.json",JSON.stringify(d),{flag:"wx",mode:384});let a=await c.promises.open(n+"/lifecycle.jsonl","wx",384),s=(p,b={})=>a.appendFile(JSON.stringify({utc:new Date().toISOString(),kind:p,...b})+`
|
|
3
|
-
`);await s("RESOURCE",d);let l,u,f,N,E,h=new se(o),m=new ae(h),g=null,w=!1,Q=0,M=!1,J=null,P=[],Z=async()=>{let p=await c.promises.lstat(n);if(!p.isDirectory()||p.isSymbolicLink()||p.dev!==r.dev||p.ino!==r.ino||p.uid!==r.uid||JSON.parse(await c.promises.readFile(n+"/OWNER.json","utf8")).instanceId!==o)throw Error("NATIVE_LAUNCH_ROOT_CHANGED")};try{let p=await me(e,process.cwd()),b=fe(e),S=(0,x.spawn)(p,["--version"],{env:b,stdio:["ignore","pipe","pipe"]});P.push(S),S.on("error",()=>{}),await s("VERSION_PROCESS",{pid:S.pid,executable:p});let X="",W="";if(S.stdout.on("data",T=>{X=(X+T.toString()).slice(0,1025)}),S.stderr.on("data",T=>{W=(W+T.toString()).slice(0,65537)}),!await q(S,1e4)||S.exitCode!==0||X.length>1024||W.length>64*1024)throw Error("NATIVE_VERSION_UNAVAILABLE");let I=Ce(X,i,process.cwd(),n+"/native.sock");I.workingDirectory=await c.promises.realpath(I.workingDirectory),g=I.resumeThreadId;let Ee=(0,B.createHash)("sha256").update(await c.promises.readFile(p)).digest("hex");await s("PLAN",{nativeVersion:X.trim(),cli:p,cliSha256:Ee,argvSha256:(0,B.createHash)("sha256").update(JSON.stringify(i)).digest("hex")}),await c.promises.mkdir(n+"/tmp",{mode:448});let Ie={...b,TMPDIR:n+"/tmp"},Ne=(0,c.openSync)(n+"/native.log","wx",384);l=(0,x.spawn)(p,I.appServerArgs,{cwd:I.workingDirectory,env:Ie,detached:!0,stdio:["pipe","ignore",Ne]}),l.on("error",()=>{}),(0,c.closeSync)(Ne),P.push(l),await s("NATIVE_SERVER",{pid:l.pid});let Qe=Date.now()+2e3,we=!1;for(;Date.now()<Qe&&!C(l);){try{await c.promises.lstat(n+"/native.sock"),we=!0;break}catch(T){if(T.code!=="ENOENT")throw T}await ht(20)}if(!we||!l.pid)throw Error("NATIVE_LISTENER_UNAVAILABLE");let de=await Ve(n+"/native.sock",r);if(J=de.socketPath,I.resumeThreadId){N=new Y({...de,instanceId:o,pluginVersion:"launcher",assertOwner:()=>{if(!l||C(l))throw Error("NATIVE_OWNER_ENDED")},onMessage:()=>{},onFailure:()=>{}}),await he("connect",()=>N.connect());let T=await he("resume",()=>N.request("thread/resume",{threadId:I.resumeThreadId,excludeTurns:!0,...I.policy,...I.model!==null?{model:I.model}:{},...I.cwdOverride?{cwd:I.workingDirectory}:{}},Xe));if(T?.thread?.id!==I.resumeThreadId||I.policy.approvalPolicy&&T.approvalPolicy!==I.policy.approvalPolicy||I.policy.sandbox&&T.sandbox?.type!=={"read-only":"readOnly","workspace-write":"workspaceWrite","danger-full-access":"dangerFullAccess"}[I.policy.sandbox])throw Error("NATIVE_RESUME_POLICY_MISMATCH");await N.close(),N=void 0}let Ze={version:1,instanceId:o,root:{path:n,dev:r.dev,ino:r.ino,uid:r.uid},launcher:{pid:process.pid,host:Be.hostname()},server:{pid:l.pid},endpoint:de,plan:I};await c.promises.writeFile(n+"/launch.json",JSON.stringify(Ze),{flag:"wx",mode:384});try{let T=await ke(n+"/launch.json",o);E=new ne({authority:T,pluginVersion:"launcher-receipts",onRoot:async k=>{g=k.id},onMessage:async k=>{h.observe(k),m.flush(),k.method==="thread/status/changed"&&await E.refreshMetadata()},onFailure:()=>{h.invalidate(),m.flush()}}),await E.start()}catch{h.invalidate(),await E?.close().catch(()=>{}),E=void 0,console.error("CodeVibe: native receipt recovery unavailable;desktop Codex remains independent.")}let ge=T=>{let k=(0,c.openSync)(n+"/observer.log","a",384),V=(0,x.fork)(y.join(__dirname,"server.js"),[],{cwd:I.workingDirectory,detached:!0,stdio:["ignore",k,k,"ipc"],env:{...b,TMPDIR:n+"/tmp",CODEX_WORKING_DIRECTORY:I.workingDirectory,CODEVIBE_CODEX_TMUX_SESSION:"native-"+o,CODEVIBE_CODEX_NATIVE_DESCRIPTOR:n+"/launch.json",CODEVIBE_CODEX_NATIVE_INSTANCE:o,CODEVIBE_CODEX_DAEMON_RECOVERY:T?"1":"0",CODEVIBE_CODEX_NATIVE_THREAD:T?g??"":""}});(0,c.closeSync)(k),P.push(V),s("OBSERVER",{pid:V.pid,recovery:T}).catch(()=>{}),m.attach(V),V.on("error",()=>{});let Ae,$e=new Promise(ce=>{Ae=ce});return V.on("message",ce=>{let U=ce;U?.instanceId===o&&(m.handle(V,U)||V===f&&(U.type==="CODEVIBE_NATIVE_READY"&&(Ae(),m.handle(V,{type:"CODEVIBE_NATIVE_RECEIPTS_POLL",instanceId:o})),U.type==="CODEVIBE_NATIVE_BOUND"&&typeof U.threadId=="string"&&(g=U.threadId),U.type==="CODEVIBE_NATIVE_OBSERVER_DEGRADED"&&!C(V)&&V.kill("SIGTERM"),U.type==="CODEVIBE_NATIVE_MOBILE_END"&&u&&!C(u)&&u.kill("SIGTERM")))}),V.on("exit",()=>{if(!w&&u&&!C(u))if(g&&Q++===0)try{f=ge(!0).child}catch{console.error("CodeVibe: mobile observer restart failed;desktop remains available.")}else console.error("CodeVibe: mobile sync unavailable;desktop Codex remains available.")}),{child:V,initialized:$e}},ye=ge(!1);if(f=ye.child,await Promise.race([ye.initialized,q(f,1e4)]),C(f)&&console.error("CodeVibe: mobile sync unavailable;desktop Codex remains available."),await Z(),(0,B.createHash)("sha256").update(await c.promises.readFile(p)).digest("hex")!==Ee)throw Error("NATIVE_EXECUTABLE_CHANGED");u=(0,x.spawn)(p,I.tuiArgs,{cwd:I.workingDirectory,env:Ie,stdio:"inherit"}),P.push(u);let Te=new Promise((T,k)=>{u.once("error",k),u.once("close",()=>T())});Te.catch(()=>{}),await s("FRONTEND",{pid:u.pid});let _e=()=>{},$=()=>{u&&!C(u)&&u.kill("SIGTERM")};if(process.on("SIGINT",_e),process.on("SIGTERM",$),process.on("SIGHUP",$),await Te,process.off("SIGINT",_e),process.off("SIGTERM",$),process.off("SIGHUP",$),w=!0,await s("FRONTEND_ENDED",{code:u.exitCode,signal:u.signalCode}),f&&!C(f)&&f.connected&&f.send({type:"CODEVIBE_NATIVE_TERMINAL_END",instanceId:o}),!(!f||await q(f,29e3)))throw Error("NATIVE_OBSERVER_TEARDOWN_INCOMPLETE");return(u.exitCode??1)||(f?.exitCode??0)}finally{if(w=!0,await N?.close().catch(()=>{}),m.close(),await E?.close().catch(()=>{}),u&&!C(u))await s("RETAINED_FRONTEND",{pid:u.pid});else{f&&!C(f)&&(f.kill("SIGTERM"),await q(f,29e3)),l&&!C(l)&&(l.stdin?.end(),await q(l,2e3)||(l.kill("SIGTERM"),await q(l,5e3)));for(let p of P)p!==l&&p!==f&&!C(p)&&(p.kill("SIGTERM"),await q(p,2e3));if(M=P.every(C),J)try{await c.promises.lstat(J),M=!1}catch(p){if(p.code!=="ENOENT")throw p}}if(await s("CLEANUP",{allCreatedChildrenEnded:M,children:P.map(p=>({pid:p.pid,code:p.exitCode,signal:p.signalCode}))}),await a.close(),M){await Z();let p=0,b=async S=>{for(let X of await c.promises.readdir(S)){if(++p>4096)throw Error("NATIVE_ROOT_CLEANUP_INVENTORY_EXCEEDED");let W=y.join(S,X),I=await c.promises.lstat(W);if(I.isDirectory()&&!I.isSymbolicLink())await b(W);else if(!I.isFile()&&!I.isSocket()&&!I.isSymbolicLink())throw Error("NATIVE_ROOT_CLEANUP_TYPE_CHANGED")}};await b(n),await c.promises.rm(n,{recursive:!0})}else{console.error("CodeVibe: teardown incomplete;owned recovery files retained at "+n);for(let p of P)C(p)||(p.unref(),p.stdin?.destroy(),p.stdout?.destroy(),p.stderr?.destroy(),p.connected&&p.disconnect());throw Error("NATIVE_LAUNCH_CLEANUP_INCOMPLETE")}}}function qe(i){return i.isFile()&&!i.isSymbolicLink()&&i.nlink===1&&(i.mode&63)===0&&i.uid===process.getuid?.()}async function ze(i,e,t){if(!y.isAbsolute(i)||y.normalize(i)!==i||y.basename(i)!=="bootstrap.json")throw Error("NATIVE_TMUX_BOOTSTRAP_INVALID");let n=y.dirname(i),r=await c.promises.open(i,c.constants.O_RDONLY|c.constants.O_NOFOLLOW),o;try{let d=await r.stat();if(!qe(d)||d.size>2*1024*1024)throw Error("NATIVE_TMUX_BOOTSTRAP_INVALID");o=JSON.parse(await r.readFile("utf8"));let a=await r.stat();if(d.dev!==a.dev||d.ino!==a.ino||d.size!==a.size||d.mtimeMs!==a.mtimeMs||o.version!==1||o.nonce!==e||o.root?.path!==n||!Array.isArray(o.args)||!o.args.every(u=>typeof u=="string")||!o.environment||typeof o.environment!="object"||Array.isArray(o.environment)||!Object.values(o.environment).every(u=>typeof u=="string"))throw Error("NATIVE_TMUX_BOOTSTRAP_INVALID");let s=await c.promises.lstat(n);if(!s.isDirectory()||s.isSymbolicLink()||(s.mode&63)!==0||s.uid!==process.getuid?.()||s.dev!==o.root.dev||s.ino!==o.root.ino||s.uid!==o.root.uid)throw Error("NATIVE_TMUX_BOOTSTRAP_INVALID");let l=await c.promises.open(n+"/status",c.constants.O_WRONLY|c.constants.O_NOFOLLOW);try{let u=await l.stat(),f=(await c.promises.readdir(n)).sort();if(!qe(u)||u.size!==0||u.dev!==o.status?.dev||u.ino!==o.status?.ino||f.join(",")!=="bootstrap.json,status")throw Error("NATIVE_TMUX_BOOTSTRAP_INVALID");let N=await c.promises.lstat(n),E=await c.promises.lstat(i),h=await c.promises.lstat(n+"/status");if(N.dev!==s.dev||N.ino!==s.ino||E.dev!==d.dev||E.ino!==d.ino||h.dev!==u.dev||h.ino!==u.ino)throw Error("NATIVE_TMUX_BOOTSTRAP_INVALID");await c.promises.unlink(i),await c.promises.unlink(n+"/status"),await c.promises.rmdir(n);let m={...o.environment};return delete m.TMUX,delete m.TMUX_PANE,t.TMUX&&(m.TMUX=t.TMUX),t.TMUX_PANE&&(m.TMUX_PANE=t.TMUX_PANE),{args:o.args,environment:m,status:l}}catch(u){throw await l.close(),u}}finally{await r.close()}}var mt=i=>"'"+i.split("'").join("'\\''")+"'";function Ge(i){let e=Number(i.slice(0,-1));return Number.isInteger(e)&&e>=0&&e<=255&&i===String(e)+`
|
|
4
|
-
`?e:null}
|
|
5
|
-
`),
|
|
1
|
+
"use strict";var Lt=Object.create;var ve=Object.defineProperty;var Mt=Object.getOwnPropertyDescriptor;var Ut=Object.getOwnPropertyNames;var Ft=Object.getPrototypeOf,jt=Object.prototype.hasOwnProperty;var Bt=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),qt=(t,e)=>{for(var i in e)ve(t,i,{get:e[i],enumerable:!0})},Ke=(t,e,i,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Ut(e))!jt.call(t,n)&&n!==i&&ve(t,n,{get:()=>e[n],enumerable:!(r=Mt(e,n))||r.enumerable});return t};var z=(t,e,i)=>(i=t!=null?Lt(Ft(t)):{},Ke(e||!t||!t.__esModule?ve(i,"default",{value:t,enumerable:!0}):i,t)),Jt=t=>Ke(ve({},"__esModule",{value:!0}),t);var yt=Bt((li,Yt)=>{Yt.exports={name:"@quantiya/codevibe-codex-plugin",version:"2.0.106",description:"Control OpenAI Codex CLI from your iPhone and Android \u2014 real-time sync, approve file edits, send prompts by voice. Part of CodeVibe.",main:"dist/server.js",codevibe:{companionLauncher:"./libexec/companion-launcher"},files:["dist/**/*.js","libexec","hooks","README.md",".env.example"],scripts:{typecheck:"tsc --noEmit",build:"rm -rf dist && npm run typecheck && esbuild src/server.ts src/native-launch.ts --bundle --platform=node --target=node18 --minify --packages=external --outdir=dist",prepack:"node scripts/prepare-publish.js && npm run build",postpack:"node scripts/restore-dev.js",dev:"ts-node src/server.ts",start:"node dist/server.js",test:"jest --config jest.config.js"},keywords:["codex","codex-cli","openai","plugin","extension","mobile","ios","android","codevibe","companion","remote-control","ai","developer-tools"],author:"Quantiya <support@quantiya.ai>",license:"MIT",bugs:{email:"support@quantiya.ai"},homepage:"https://quantiya.ai/codevibe",engines:{node:">=22.0.0"},dependencies:{"@quantiya/codevibe-core":"^2.0.91","@quantiya/quorum-core":"^1.0.1",chokidar:"^4.0.0",dotenv:"^16.6.1",express:"^5.1.0",graphql:"^16.12.0","shell-quote":"1.9.0",uuid:"^13.0.0",ws:"^8.18.3"},bundledDependencies:["@quantiya/codevibe-core","@quantiya/quorum-core","chokidar","dotenv","express","graphql","shell-quote","uuid","ws"],devDependencies:{"@types/express":"^5.0.5","@types/jest":"^30.0.0","@types/node":"^24.10.1","@types/uuid":"^10.0.0","@types/ws":"^8.18.1",esbuild:"^0.28.0",jest:"^30.3.0","ts-jest":"^29.4.9","ts-node":"^10.9.2",typescript:"^5.9.3"},bundleDependencies:["@quantiya/codevibe-core","@quantiya/quorum-core","chokidar","dotenv","express","graphql","shell-quote","uuid","ws"]}});var Zt={};qt(Zt,{NATIVE_STARTUP_RESUME_TIMEOUT_MS:()=>_t,NativeLaunchCleanupError:()=>ue,consumeTmuxBootstrap:()=>Ot,findNativeCodex:()=>Le,launchNativeCompanion:()=>Dt,launchNativeInsideTmux:()=>Ue,missingTmuxSession:()=>Pt,nativeChildEnvironment:()=>Me,nativeExitReport:()=>St,nativeExitStatus:()=>xe,nativeStartupFailureMessage:()=>je,nativeStartupStep:()=>ke,nativeTmuxSocket:()=>Rt,stopNativeBackend:()=>bt,waitExit:()=>q});module.exports=Jt(Zt);var h=require("node:fs"),b=z(require("node:path")),Tt=z(require("node:os")),se=require("node:crypto"),X=require("node:child_process"),At=require("node:util");var Z=z(require("node:path")),we=class extends Error{constructor(i){super(`${i}: run plain codex for unsupported native launch forms.`);this.code=i;this.name="NativeLaunchError"}};function G(){throw new we("NATIVE_ARGUMENT_UNSUPPORTED")}function Oe(t){return typeof t=="string"&&t.length>0&&!t.includes("\0")}function zt(t){let e=t.split("-");return e.length===5&&e.every((i,r)=>i.length===[8,4,4,4,12][r]&&[...i].every(n=>"0123456789abcdef".includes(n)))}var Xt=new Set(["agents","exec","e","review","login","logout","mcp","plugin","app-server","remote-control","app","completion","update","doctor","sandbox","debug","apply","a","queue","archive","delete","migrate-rollouts","migrate-nfs-db","unarchive","fork","cloud","exec-server","features","help"]);function Qe(t,e,i){if(!Z.isAbsolute(e)||!Z.isAbsolute(i)||Z.normalize(i)!==i||i.includes(":")||i.includes("\0")||Buffer.byteLength(i)>100)throw new we("NATIVE_LAUNCH_INVALID");let r={workingDirectory:Z.resolve(e),cwdOverride:!1,resumeThreadId:null,model:null,policy:{},appServerArgs:[],tuiArgs:[]},n=null,o=!1,a=!1,d=new Set,s=c=>{d.has(c)&&G(),d.add(c)};for(let c=0;c<t.length;c++){let f=t[c];if(Oe(f)||G(),!o&&f==="--"){o=!0;continue}if(!o&&f.startsWith("-")){let m=f.indexOf("="),E=m<0?f:f.slice(0,m);if(E==="--no-alt-screen"&&m<0){s("renderer"),r.tuiArgs.push(E);continue}let p=["--model","-m"].includes(E)?"model":["--cd","-C"].includes(E)?"cwd":["--sandbox","-s"].includes(E)?"sandbox":["--ask-for-approval","-a"].includes(E)?"approval":null;p||G(),s(p);let N=m<0?t[++c]:f.slice(m+1);(!Oe(N)||N.startsWith("-"))&&G(),p==="model"&&(r.model=N),p==="cwd"&&(r.workingDirectory=Z.resolve(e,N),r.cwdOverride=!0),p==="sandbox"&&(["read-only","workspace-write","danger-full-access"].includes(N)||G(),r.policy.sandbox=N),p==="approval"&&(["on-request","never"].includes(N)||G(),r.policy.approvalPolicy=N);continue}if(!o&&f==="resume"&&n===null&&!a){a=!0;let m=t[++c];(!Oe(m)||!zt(m))&&G(),r.resumeThreadId=m;continue}!o&&!a&&Xt.has(f)&&G(),n!==null&&G(),n=f}let l=[];r.model!==null&&l.push("-c","model="+JSON.stringify(r.model)),r.policy.sandbox&&l.push("-c","sandbox_mode="+JSON.stringify(r.policy.sandbox)),r.policy.approvalPolicy&&l.push("-c","approval_policy="+JSON.stringify(r.policy.approvalPolicy)),r.appServerArgs=[...l,"app-server","--listen","unix://"+i];let u=r.tuiArgs;return r.tuiArgs=["--remote","unix://"+i,...u],r.model!==null&&r.tuiArgs.push("--model",r.model),a||(r.policy.sandbox&&r.tuiArgs.push("--sandbox",r.policy.sandbox),r.policy.approvalPolicy&&r.tuiArgs.push("--ask-for-approval",r.policy.approvalPolicy)),a&&r.tuiArgs.push("resume",r.resumeThreadId),n!==null&&r.tuiArgs.push("--",n),r}var Ne=z(require("ws")),O=require("node:fs"),B=z(require("node:path")),Ze=require("node:crypto");async function et(t,e){if(!B.isAbsolute(t)||B.normalize(t)!==t||t.includes(":")||t.includes("\0"))throw new w("NATIVE_SOCKET_UNSAFE");let i=await O.promises.lstat(B.dirname(t)),r=await O.promises.lstat(t),n=typeof process.getuid=="function"?process.getuid():void 0;if(!i.isDirectory()||i.isSymbolicLink()||(i.mode&63)!==0||i.dev!==e.dev||i.ino!==e.ino||n!==void 0&&(i.uid!==n||r.uid!==n))throw new w("NATIVE_SOCKET_UNSAFE");let o=t,a;if(r.isSymbolicLink()){let u=await O.promises.readlink(t);o=await O.promises.realpath(t),a={path:t,dev:r.dev,ino:r.ino,target:u,rootDev:i.dev,rootIno:i.ino}}let d=await O.promises.lstat(o),s=await O.promises.lstat(B.dirname(o));if(!d.isSocket()||d.isSymbolicLink()||!s.isDirectory()||s.isSymbolicLink()||(s.mode&63)!==0||n!==void 0&&(d.uid!==n||s.uid!==n))throw new w("NATIVE_SOCKET_UNSAFE");let l=await O.promises.lstat(t);if(l.dev!==r.dev||l.ino!==r.ino||a&&(await O.promises.readlink(t)!==a.target||await O.promises.realpath(t)!==o))throw new w("NATIVE_SOCKET_UNSAFE");return{socketPath:o,socketIdentity:{dev:d.dev,ino:d.ino},...a?{alias:a}:{}}}var w=class extends Error{constructor(i,r,n,o){super(i);this.code=i;this.rpcCode=r;this.diagnostic=n;this.handlerFailure=o;this.name="NativeClientError"}};function $e(t,e){let i=t.length<=128&&[...t].every(s=>"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/_.-".includes(s))?t:"UNKNOWN_NATIVE_METHOD",r=e instanceof Error?e:null,n=["Error","TypeError","RangeError","NativeClientError","NativeRuntimeError","NativeControlError","SyncEventClientError","SyncJournalError","ZodError"],o=e?.code??r?.message,a=typeof o=="string"&&o.length<=96&&(o.startsWith("NATIVE_")||o.startsWith("SYNC_")||["ENOENT","EACCES","EPERM","EIO"].includes(o))&&[...o].every(s=>"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_".includes(s))?o:null,d=null;for(let s of(r?.stack??"").split(`
|
|
2
|
+
`).slice(1)){for(let[l,u]of[["server.js","server"],["index.js","core"],["native-launch.js","native-launch"]]){let c="/dist/"+l+":",f=s.lastIndexOf(c);if(f<0)continue;let m=s.slice(f+c.length).split(")")[0].trim().split(":");if(m.length===2&&m.every(E=>E.length>0&&[...E].every(p=>"0123456789".includes(p)))){let[E,p]=m.map(Number);E>0&&E<1e5&&p>0&&p<1e7&&(d={module:u,line:E,column:p})}if(d)break}if(d)break}return new w("NATIVE_HANDLER_FAILED",void 0,void 0,{method:i,errorName:r&&n.includes(r.name)?r.name:"Error",causeCode:a,site:d})}var ce=class{constructor(e){this.options=e;this.socket=null;this.pending=new Map;this.handlers=new Set;this.accepting=!1;this.intentionalClose=!1;this.initialized=!1;this.requestPrefix="codevibe-"+(0,Ze.randomUUID)()+"-";this.sequence=0;this.instanceId=e.instanceId,this.endpoint={socketPath:e.socketPath,socketIdentity:{...e.socketIdentity},...e.alias?{alias:{...e.alias}}:{}}}async assertSocket(){this.options.assertOwner();let e=this.endpoint.socketPath;if(!B.isAbsolute(e)||B.normalize(e)!==e||e.includes(":")||e.includes("\0"))throw new w("NATIVE_SOCKET_UNSAFE");let i=await O.promises.lstat(B.dirname(e)),r=await O.promises.lstat(e),n=typeof process.getuid=="function"?process.getuid():void 0,o={rootDirectory:i.isDirectory(),rootNotSymlink:!i.isSymbolicLink(),rootPrivate:(i.mode&63)===0,ownerMatches:n===void 0||i.uid===n&&r.uid===n,socketType:r.isSocket(),socketNotSymlink:!r.isSymbolicLink(),socketIdentityMatches:r.dev===this.endpoint.socketIdentity.dev&&r.ino===this.endpoint.socketIdentity.ino};if(Object.values(o).some(d=>!d))throw new w("NATIVE_SOCKET_UNSAFE",void 0,o);let a=this.endpoint.alias;if(a){let d=await O.promises.lstat(B.dirname(a.path)),s=await O.promises.lstat(a.path);if(!d.isDirectory()||d.isSymbolicLink()||(d.mode&63)!==0||d.dev!==a.rootDev||d.ino!==a.rootIno||!s.isSymbolicLink()||s.dev!==a.dev||s.ino!==a.ino||n!==void 0&&(d.uid!==n||s.uid!==n)||await O.promises.readlink(a.path)!==a.target||await O.promises.realpath(a.path)!==e)throw new w("NATIVE_SOCKET_UNSAFE",void 0,{originalAliasMatches:!1})}this.options.assertOwner()}async connect(){try{await this.connectOnce()}catch(e){throw await this.close(),e}}async connectOnce(){if(this.socket||this.intentionalClose)throw new w("NATIVE_DISCONNECTED");await this.assertSocket();let e=new Ne.default("ws+unix://"+this.endpoint.socketPath+":/");this.socket=e,this.accepting=!0,e.on("message",i=>this.receive(i.toString())),e.on("error",()=>this.fail(new w("NATIVE_DISCONNECTED"))),e.on("close",()=>{this.initialized=!1,this.accepting=!1,this.rejectPending(),this.intentionalClose||this.report(new w("NATIVE_DISCONNECTED"))}),await new Promise((i,r)=>{let n=setTimeout(()=>{d(new w("NATIVE_RPC_TIMEOUT",void 0,{webSocketOpenTimedOut:!0})),e.terminate()},2e3),o=()=>d(),a=()=>d(new w("NATIVE_DISCONNECTED")),d=s=>{clearTimeout(n),e.off("open",o),e.off("error",a),e.off("close",a),s?r(s):i()};e.once("open",o),e.once("error",a),e.once("close",a)}),await this.assertSocket(),await this.request("initialize",{clientInfo:{name:"codevibe-codex",version:this.options.pluginVersion},capabilities:{experimentalApi:!0,requestAttestation:!1}},2e3),await this.notify("initialized"),this.initialized=!0}report(e){try{Promise.resolve(this.options.onFailure(e)).catch(()=>{})}catch{}}rejectPending(){for(let e of this.pending.values())clearTimeout(e.timer),e.reject(new w("NATIVE_DISCONNECTED"));this.pending.clear()}fail(e){this.accepting=!1,this.initialized=!1,this.rejectPending(),this.intentionalClose||this.report(e),this.socket?.terminate()}receive(e){if(!this.accepting)return;let i;try{let n=JSON.parse(e);if(!n||typeof n!="object"||Array.isArray(n))throw Error();i=n}catch{this.fail(new w("NATIVE_PROTOCOL_INVALID"));return}if(typeof i.method=="string"){if(i.id!==void 0&&typeof i.id!="string"&&typeof i.id!="number"){this.fail(new w("NATIVE_PROTOCOL_INVALID"));return}let n;try{this.options.assertOwner(),n=this.options.onMessage(i)}catch(a){this.report($e(i.method,a));return}let o=Promise.resolve(n).catch(a=>this.report($e(i.method,a)));this.handlers.add(o),o.then(()=>this.handlers.delete(o));return}if(typeof i.id!="string")return;let r=this.pending.get(i.id);if(r)if(this.pending.delete(i.id),clearTimeout(r.timer),i.error!==void 0){let n=i.error?.code;r.reject(new w("NATIVE_RPC_REJECTED",typeof n=="number"?n:void 0))}else Object.prototype.hasOwnProperty.call(i,"result")?r.resolve(i.result):r.reject(new w("NATIVE_PROTOCOL_INVALID"))}async write(e){this.options.assertOwner();let i=this.socket;if(!i||i.readyState!==Ne.default.OPEN||!this.accepting)throw new w("NATIVE_DISCONNECTED");await new Promise((r,n)=>i.send(JSON.stringify(e),o=>o?n(new w("NATIVE_DISCONNECTED")):r())),this.options.assertOwner()}async request(e,i,r=1e4,n){if(!this.initialized&&e!=="initialize")throw new w("NATIVE_DISCONNECTED");if(!Number.isFinite(r)||r<=0||r>3e5)throw new w("NATIVE_PROTOCOL_INVALID");if(n?.aborted)throw new w("NATIVE_REQUEST_CANCELLED");let o=this.requestPrefix+ ++this.sequence,d=new Promise((l,u)=>{let c=()=>{this.pending.delete(o),E.reject(new w("NATIVE_REQUEST_CANCELLED"))},f=()=>{n?.removeEventListener("abort",c),clearTimeout(m)},m=setTimeout(()=>{this.pending.delete(o),u(new w("NATIVE_RPC_TIMEOUT",void 0,{initializeTimedOut:e==="initialize",threadResumeTimedOut:e==="thread/resume",otherRpcTimedOut:e!=="initialize"&&e!=="thread/resume"})),n?.removeEventListener("abort",c)},r),E={resolve:p=>{f(),l(p)},reject:p=>{f(),u(p)},timer:m};this.pending.set(o,E),n?.addEventListener("abort",c,{once:!0}),n?.aborted&&c()}).then(l=>({value:l}),l=>({error:l}));try{n?.aborted||await this.write({id:o,method:e,params:i})}catch(l){let u=this.pending.get(o);throw u&&(clearTimeout(u.timer),this.pending.delete(o),u.reject(new w("NATIVE_DISCONNECTED"))),await d,l}let s=await d;if("error"in s)throw s.error;return s.value}async notify(e,i){await this.write({method:e,...i===void 0?{}:{params:i}})}async respond(e,i){if(!this.initialized)throw new w("NATIVE_DISCONNECTED");await this.write({id:e,result:i})}async close(){this.intentionalClose=!0,this.accepting=!1,this.initialized=!1,this.rejectPending();let e=this.socket;e&&e.readyState!==Ne.default.CLOSED&&await new Promise(i=>{let r=setTimeout(()=>{e.terminate(),i()},2e3);e.once("close",()=>{clearTimeout(r),i()}),e.close()}),await this.joinHandlers(),this.socket=null}async joinHandlers(){await Promise.allSettled([...this.handlers])}};var ee=require("node:fs"),M=z(require("node:path")),rt=z(require("node:os")),Pe=require("node:util");var C=class extends Error{constructor(i){super(i);this.code=i;this.name="NativeRuntimeError"}},re=()=>{throw new C("NATIVE_LAUNCH_AUTHORITY_INVALID")};function Ie(t){return!t||typeof t!="object"||Array.isArray(t)?re():t}function Ht(t,e){return Object.keys(t).sort().join(",")===e.sort().join(",")}function tt(t){return typeof t=="number"&&Number.isSafeInteger(t)&&t>0}function it(t){try{process.kill(t,0)}catch{re()}}async function nt(t,e){if(!M.isAbsolute(t)||M.normalize(t)!==t||M.basename(t)!=="launch.json")return re();let i=typeof process.getuid=="function"?process.getuid():void 0,r=await ee.promises.open(t,ee.constants.O_RDONLY|ee.constants.O_NOFOLLOW),n,o;try{let d=await r.stat();if(!d.isFile()||d.nlink!==1||(d.mode&63)!==0||d.size>2*1024*1024||i!==void 0&&d.uid!==i)return re();let s=Ie(JSON.parse(await r.readFile("utf8")));if(!Ht(s,["version","instanceId","root","launcher","server","endpoint","plan"])||s.version!==1||s.instanceId!==e||typeof e!="string"||!e.length||!tt(s.launcher?.pid)||s.launcher.host!==rt.hostname()||!tt(s.server?.pid)||s.root?.path!==M.dirname(t)||!Number.isSafeInteger(s.root.dev)||!Number.isSafeInteger(s.root.ino)||s.root.uid!==i||!M.isAbsolute(s.endpoint?.socketPath??"")||!Number.isSafeInteger(s.endpoint?.socketIdentity?.dev)||!Number.isSafeInteger(s.endpoint?.socketIdentity?.ino)||!M.isAbsolute(s.plan?.workingDirectory??"")||s.plan.resumeThreadId!==null&&typeof s.plan.resumeThreadId!="string")return re();let l=await r.stat();if(d.dev!==l.dev||d.ino!==l.ino||d.size!==l.size||d.mtimeMs!==l.mtimeMs)return re();n=s,o={dev:d.dev,ino:d.ino,size:d.size,mtimeMs:d.mtimeMs}}finally{await r.close()}let a=()=>{let d=(0,ee.lstatSync)(n.root.path),s=(0,ee.lstatSync)(t);if(!d.isDirectory()||d.isSymbolicLink()||(d.mode&63)!==0||d.dev!==n.root.dev||d.ino!==n.root.ino||d.uid!==n.root.uid||!s.isFile()||s.isSymbolicLink()||s.nlink!==1||(s.mode&63)!==0||s.dev!==o.dev||s.ino!==o.ino||s.size!==o.size||s.mtimeMs!==o.mtimeMs||s.uid!==n.root.uid)return re();it(n.launcher.pid),it(n.server.pid)};return a(),{record:JSON.parse(JSON.stringify(n)),assertCurrent:a}}function Se(t){let e=Ie(t);if(typeof e.id!="string"||!e.id.length)throw new C("NATIVE_ROOT_INVALID_ID");if(e.sessionId!==e.id||e.parentThreadId!=null)throw new C("NATIVE_ROOT_INVALID_SESSION");if(e.ephemeral!==!1)throw new C("NATIVE_ROOT_INVALID_PERSISTENCE");if(typeof e.cwd!="string"||!M.isAbsolute(e.cwd))throw new C("NATIVE_ROOT_INVALID_CWD");if(!Number.isFinite(e.createdAt)||e.createdAt<0)throw new C("NATIVE_ROOT_INVALID_TIMESTAMP");if(e.path!==null&&(typeof e.path!="string"||!M.isAbsolute(e.path)))throw new C("NATIVE_ROOT_INVALID_PATH");if(typeof e.cliVersion!="string")throw new C("NATIVE_ROOT_INVALID_VERSION");if(typeof e.modelProvider!="string")throw new C("NATIVE_ROOT_INVALID_PROVIDER");return{id:e.id,sessionId:e.sessionId,cwd:e.cwd,createdAt:e.createdAt,path:e.path,cliVersion:e.cliVersion,modelProvider:e.modelProvider}}var ye=class{constructor(e){this.options=e;this.root=null;this.ready=!1;this.generation=0;this.bindingDepth=0;this.binding=Promise.resolve();this.closed=!1;this.refreshPending=null;this.pendingControls=new Map;this.pendingFiles=new Map;this.client=new ce({...e.authority.record.endpoint,instanceId:e.authority.record.instanceId,pluginVersion:e.pluginVersion,assertOwner:e.authority.assertCurrent,onMessage:i=>this.observe(i),onFailure:i=>i.handlerFailure?e.onFailure(i.code,i.handlerFailure):e.onFailure(i.code)})}get thread(){return this.root?{...this.root}:null}controlFacts(){return JSON.parse(JSON.stringify([...this.pendingFiles.values(),...this.pendingControls.values()]))}isCurrentControl(e){let i=e.id===void 0?void 0:this.pendingControls.get(e.id);return!this.closed&&!!i&&i.method===e.method&&(0,Pe.isDeepStrictEqual)(i.params,e.params)}hasPendingControl(){return this.pendingControls.size>0}async start(){await this.client.connect();let e=this.options.authority.record.plan.resumeThreadId??this.options.recoveryThreadId;e&&await this.bind(await this.readMetadata(e))}bind(e){let i=this.options.authority.record.plan.resumeThreadId??this.options.recoveryThreadId;if(!this.root&&i&&e.id!==i)return Promise.reject(new C("NATIVE_ROOT_INVALID"));if(this.root&&e.id===this.root.id&&e.cwd!==this.root.cwd)return Promise.reject(new C("NATIVE_ROOT_INVALID"));if(this.root&&(0,Pe.isDeepStrictEqual)(this.root,e)&&(this.ready||this.bindingDepth>0))return this.binding;(!this.root||this.root.id!==e.id)&&(this.generation++,this.ready=!1,this.pendingControls.clear(),this.pendingFiles.clear());let r=this.generation;this.root={...e},this.bindingDepth++;let n=this.binding.then(async()=>{if(this.closed)throw new C("NATIVE_BINDING_FAILED");await this.options.onRoot({...e}),r===this.generation&&!this.closed&&(this.ready=!0)});return this.binding=n.catch(()=>{}),n.then(()=>{this.bindingDepth--},()=>{this.bindingDepth--}),n}observe(e){if(this.closed)return;let i=e.params;if(e.method==="thread/started"){let n=i?.thread;return n?.ephemeral===!0||n?.parentThreadId!=null||n?.sessionId!==n?.id?void 0:this.bind(Se(n))}if(!this.root||i?.threadId!==this.root.id)return;if(e.id!==void 0&&this.pendingControls.set(e.id,JSON.parse(JSON.stringify(e))),e.method==="serverRequest/resolved"&&this.pendingControls.delete(i.requestId),["item/started","item/completed"].includes(e.method)&&i.item?.type==="fileChange"&&this.pendingFiles.set(i.item.id,JSON.parse(JSON.stringify(e))),e.method==="item/completed"&&["commandExecution","fileChange"].includes(i.item?.type)){for(let[n,o]of this.pendingControls){let a=o.params;a.turnId===i.turnId&&a.itemId===i.item.id&&this.pendingControls.delete(n)}this.pendingFiles.delete(i.item.id)}if(!this.ready&&this.bindingDepth===0&&e.method==="turn/started"&&this.bind(this.root).catch(()=>{}),["item/agentMessage/delta","item/reasoning/textDelta","item/commandExecution/outputDelta"].includes(e.method))return;if(this.ready)return this.options.onMessage(e);let r=this.generation;return this.binding.then(()=>{if(!this.ready||this.closed||r!==this.generation)throw new C("NATIVE_BINDING_FAILED");return this.options.onMessage(e)})}async readMetadata(e){let i=await this.client.request("thread/resume",{threadId:e,excludeTurns:!0},2e3),r=Se(Ie(i).thread);if(r.id!==e)throw new C("NATIVE_ROOT_INVALID");return r}refreshMetadata(){if(this.refreshPending)return this.refreshPending;if(!this.root||this.closed)return Promise.resolve(null);let e=this.root.id,i=(async()=>{let r=Date.now()+2e3;for(let n=0;n<10&&Date.now()<r;n++)try{let o=await this.client.request("thread/resume",{threadId:e,excludeTurns:!0},Math.max(1,r-Date.now())),a=Se(Ie(o).thread);if(a.id!==e||this.root?.id!==e||this.closed)throw new C("NATIVE_ROOT_INVALID");return await this.bind(a),a}catch(o){if(!(o instanceof w)||o.code!=="NATIVE_RPC_REJECTED"||![-32600,-32601].includes(o.rpcCode??0))throw o;n<9&&Date.now()<r&&await new Promise(a=>setTimeout(a,Math.min(100,r-Date.now())))}return null})();return this.refreshPending=i,i.then(()=>{this.refreshPending=null},()=>{this.refreshPending=null}),i}async close(){this.closed=!0,await this.client.close(),await this.binding,await this.refreshPending?.catch(()=>{})}};var ot=require("node:crypto"),ge=require("node:util"),st=2*1024*1024,Te=t=>JSON.parse(JSON.stringify(t)),at=t=>(0,ot.createHash)("sha256").update(JSON.stringify(t)).digest("hex");function _(t){if(!t||typeof t!="object"||Array.isArray(t))throw Error("NATIVE_RECEIPT_INVALID");return t}function ne(t){return typeof t=="string"&&t.length>0&&t.length<=512}function dt(t){return ne(t)||typeof t=="number"&&Number.isSafeInteger(t)&&t>=0}function ct(t){return{nativeInstanceId:t.nativeInstanceId,request:t.request,resolved:t.resolved,completed:t.completed,turnCompleted:t.turnCompleted}}function Wt(t,e){let i=_(t);if(Buffer.byteLength(JSON.stringify(i))>st||Object.keys(i).sort().join(",")!=="completed,digest,nativeInstanceId,request,resolved,turnCompleted"||i.nativeInstanceId!==e||!ne(e))throw Error("NATIVE_RECEIPT_INVALID");let r=_(i.request),n=_(i.resolved),o=_(i.turnCompleted),a=_(r.params),d=_(n.params),s=_(o.params),l=_(s.turn),u=r.method==="item/commandExecution/requestApproval"?"commandExecution":r.method==="item/fileChange/requestApproval"?"fileChange":null;if(!u||!dt(r.id)||![a.threadId,a.turnId,a.itemId].every(ne)||n.method!=="serverRequest/resolved"||d.threadId!==a.threadId||d.requestId!==r.id||o.method!=="turn/completed"||s.threadId!==a.threadId||l.id!==a.turnId||!["completed","failed","interrupted"].includes(l.status))throw Error("NATIVE_RECEIPT_INVALID");if(i.completed===null){if(u!=="fileChange"||l.status!=="interrupted")throw Error("NATIVE_RECEIPT_INVALID")}else{let f=_(i.completed),m=_(f.params),E=_(m.item);if(f.method!=="item/completed"||m.threadId!==a.threadId||m.turnId!==a.turnId||E.id!==a.itemId||E.type!==u||!["completed","failed","declined"].includes(E.status))throw Error("NATIVE_RECEIPT_INVALID")}let c=ct(i);if(i.digest!==at(c))throw Error("NATIVE_RECEIPT_INVALID");return{...Te(c),digest:i.digest}}var Ae=class{constructor(e){this.instanceId=e;this.rows=new Map;this.unavailable=!1;if(!ne(e))throw Error("NATIVE_RECEIPT_INVALID")}invalidate(){this.unavailable=!0}get isUnavailable(){return this.unavailable}key(e,i){return JSON.stringify([e,i])}observe(e){if(!this.unavailable)try{let i=Te(e),r=_(i.params);if(!ne(r.threadId)||!["item/commandExecution/requestApproval","item/fileChange/requestApproval","serverRequest/resolved","turn/completed"].includes(i.method)&&!(i.method==="item/completed"&&["commandExecution","fileChange"].includes(r.item?.type)))return;let n=new Map(Te([...this.rows]));if(i.id!==void 0&&["item/commandExecution/requestApproval","item/fileChange/requestApproval"].includes(i.method)){if(!dt(i.id)||!ne(r.turnId)||!ne(r.itemId))throw Error("NATIVE_RECEIPT_INVALID");let o=this.key(r.threadId,i.id),a=n.get(o);if(a){if(a.request.method!==i.method||!(0,ge.isDeepStrictEqual)(a.request.params,i.params))throw Error("NATIVE_RECEIPT_COLLISION");return}n.set(o,{request:i,resolved:null,completed:null,turnCompleted:null})}else for(let o of n.values()){let a=_(o.request.params);if(a.threadId===r.threadId){if(i.method==="serverRequest/resolved"&&r.requestId===o.request.id&&!o.resolved&&(o.resolved=i),i.method==="item/completed"&&r.turnId===a.turnId&&r.item?.id===a.itemId&&r.item.type===(o.request.method==="item/commandExecution/requestApproval"?"commandExecution":"fileChange")){let d=Te(i);if(delete _(_(d.params).item).aggregatedOutput,o.completed&&!(0,ge.isDeepStrictEqual)(_(o.completed.params).item,_(d.params).item))throw Error("NATIVE_RECEIPT_COLLISION");o.completed??=d}if(i.method==="turn/completed"&&r.turn?.id===a.turnId){let d={method:i.method,params:{threadId:r.threadId,turn:{id:r.turn.id,status:r.turn.status}}};if(o.turnCompleted&&!(0,ge.isDeepStrictEqual)(o.turnCompleted,d))throw Error("NATIVE_RECEIPT_COLLISION");o.turnCompleted??=d}}}if(Buffer.byteLength(JSON.stringify([...n]))>st)throw Error("NATIVE_RECEIPT_WINDOW_FULL");this.rows=n}catch{this.invalidate()}}receipts(){if(this.unavailable)throw Error("NATIVE_RECEIPTS_UNAVAILABLE");return[...this.rows.values()].flatMap(e=>{if(!e.resolved||!e.turnCompleted)return[];if(!e.completed&&!(e.request.method==="item/fileChange/requestApproval"&&_(_(e.turnCompleted.params).turn).status==="interrupted"))return[];let i=ct({nativeInstanceId:this.instanceId,request:e.request,resolved:e.resolved,completed:e.completed,turnCompleted:e.turnCompleted});return[Wt({...i,digest:at(i)},this.instanceId)]})}acknowledge(e){let i=this.receipts().find(r=>r.digest===e);if(!i)throw Error("NATIVE_RECEIPT_ACK_INVALID");this.rows.delete(this.key(_(i.request.params).threadId,i.request.id))}},_e=class{constructor(e){this.window=e;this.current=null;this.sent=new Set;this.warned=!1;this.ready=!1}attach(e){this.current=e,this.sent.clear(),this.warned=!1,this.ready=!1}close(){this.current=null,this.sent.clear(),this.ready=!1}handle(e,i){let r=i;if(!r||!["CODEVIBE_NATIVE_RECEIPTS_POLL","CODEVIBE_NATIVE_RECEIPT_ACK"].includes(String(r.type)))return!1;if(e!==this.current||r.instanceId!==this.window.instanceId||e.connected!==!0)return!0;if(r.type==="CODEVIBE_NATIVE_RECEIPTS_POLL")this.ready=!0,this.flush();else if(typeof r.digest=="string"&&this.sent.has(r.digest)&&typeof r.consumed=="boolean"){if(r.consumed)try{this.window.acknowledge(r.digest)}catch{this.window.invalidate()}this.sent.delete(r.digest)}return!0}flush(){let e=this.current;if(!(!this.ready||!e||e.connected!==!0)){if(this.window.isUnavailable){this.warned||(this.warned=!0,this.send(e,{type:"CODEVIBE_NATIVE_RECEIPTS_UNAVAILABLE",instanceId:this.window.instanceId}));return}try{for(let i of this.window.receipts())this.sent.has(i.digest)||(this.sent.add(i.digest),this.send(e,{type:"CODEVIBE_NATIVE_RECEIPT",instanceId:this.window.instanceId,receipt:i}))}catch{this.window.invalidate(),this.flush()}}}send(e,i){try{e.send(i,r=>{r&&this.current===e&&this.window.invalidate()})}catch{this.current===e&&this.window.invalidate()}}};var le=require("node:fs"),he=z(require("node:path")),lt=require("node:child_process"),ut=require("node:util"),pt=require("node:crypto"),V=class extends Error{constructor(i,r=[]){super(i==="NATIVE_UPDATE_REQUIRED"?"This Codex installation lacks native capabilities required by CodeVibe. Update Codex, then retry codevibe --agent codex.":"CodeVibe could not inspect this Codex installation. Check that Codex runs normally, then retry.");this.code=i;this.missing=r;this.name="NativeCapabilityError"}};function Re(t){return new Set((t.oneOf??[]).flatMap(e=>e.properties?.method?.enum??[]))}function De(t,e,i,r=0){return!t||r>8?!1:t.$ref?.startsWith("#/definitions/")?De(i?.[t.$ref.slice(14)],e,i,r+1):t.type===e||Array.isArray(t.type)&&t.type.includes(e)?!0:[...t.anyOf??[],...t.oneOf??[]].some(n=>De(n,e,i,r+1))}function Gt(t){let e=[],i=Re(t.client),r=Re(t.requests),n=Re(t.notifications);for(let o of["initialize","thread/start","thread/resume","thread/read","thread/loaded/list","turn/start"])i.has(o)||e.push(o);for(let o of["item/commandExecution/requestApproval","item/fileChange/requestApproval"])r.has(o)||e.push(o);for(let o of["thread/started","thread/status/changed","turn/started","turn/completed","item/started","item/completed","serverRequest/resolved"])n.has(o)||e.push(o);for(let[o,a,d]of[[t.client,"ThreadResumeParams",[["threadId","string"],["excludeTurns","boolean"]]],[t.client,"TurnStartParams",[["threadId","string"],["clientUserMessageId","string"],["input","array"],["toolOutput","object"]]],[t.client,"TurnToolOutput",[["namespace","string"],["name","string"],["output","string"],["retain","boolean"]]],[t.requests,"CommandExecutionRequestApprovalParams",[["threadId","string"],["turnId","string"],["itemId","string"],["availableDecisions","array"]]]]){let s=o.definitions?.[a]?.properties;for(let[l,u]of d)De(s?.[l],u,o.definitions)||e.push(`${a}.${l}`)}return e}async function ht(t,e,i,r){let n=(0,ut.promisify)(lt.execFile);await le.promises.mkdir(e,{mode:448});try{let c=n(t,["--remote","unix://"+he.join(he.dirname(e),"native.sock"),"--help"],{env:i,timeout:1e4,maxBuffer:262144});r?.(c.child),await c}catch(c){throw c?.code===2&&!c.killed&&!c.signal?new V("NATIVE_UPDATE_REQUIRED",["remote terminal attachment"]):new V("NATIVE_CAPABILITY_PROBE_FAILED")}try{let c=n(t,["app-server","generate-json-schema","--experimental","--out",e],{env:i,timeout:15e3,maxBuffer:262144});r?.(c.child),await c}catch(c){throw c?.code===2&&!c.killed&&!c.signal?new V("NATIVE_UPDATE_REQUIRED",["native protocol introspection"]):new V("NATIVE_CAPABILITY_PROBE_FAILED")}let o=(0,pt.createHash)("sha256"),a=[];for(let c of["ClientRequest.json","ServerRequest.json","ServerNotification.json"]){let f=await le.promises.open(he.join(e,c),le.constants.O_RDONLY|le.constants.O_NOFOLLOW);try{let m=await f.stat();if(!m.isFile()||m.size>8*1024*1024)throw new V("NATIVE_CAPABILITY_PROBE_FAILED");let E=await f.readFile();o.update(c).update(E),a.push(JSON.parse(E.toString()))}finally{await f.close()}}let[d,s,l]=a,u=Gt({client:d,requests:s,notifications:l});if(u.length)throw new V("NATIVE_UPDATE_REQUIRED",u);return{schemaSha256:o.digest("hex")}}var U=require("node:fs"),oe=z(require("node:path")),T=t=>!t.pid||t.exitCode!==null||t.signalCode!==null;async function q(t,e){return T(t)?!0:new Promise(i=>{let r=setTimeout(()=>o(!1),e);r.unref();let n=()=>o(!0),o=a=>{clearTimeout(r),t.off("close",n),i(a)};t.once("close",n)})}var D=()=>{throw Error("NATIVE_STARTUP_SHUTDOWN_UNSAFE")},ft=(t,e)=>t.isFile()&&t.nlink===1&&t.uid===e&&(t.mode&63)===0;async function Ve(t,e){let i=await U.promises.open(t,U.constants.O_RDONLY|U.constants.O_NOFOLLOW);try{let r=await i.stat();if(!ft(r,e)||r.size>4096)return D();let n=await i.readFile("utf8"),o=await i.stat(),a=await U.promises.lstat(t);return!ft(a,e)||a.isSymbolicLink()||a.dev!==r.dev||a.ino!==r.ino||a.size!==r.size||a.mtimeMs!==r.mtimeMs||o.size!==r.size||o.mtimeMs!==r.mtimeMs?D():{bytes:n,pin:{dev:r.dev,ino:r.ino,size:r.size,mtimeMs:r.mtimeMs,uid:r.uid}}}finally{await i.close()}}async function mt(t){try{return await U.promises.lstat(t)}catch(e){if(e.code==="ENOENT")return null;throw e}}async function Et(t,e,i,r){let n={...t},o=JSON.parse(JSON.stringify(i)),a=e.pid;if(!a||a===process.pid||n.pid!==process.pid||n.uid!==process.getuid?.())return D();let d=await Ve(n.root+"/OWNER.json",n.uid),s=await Ve(n.root+"/backend-owner.json",n.uid),l={root:n.root,dev:n.dev,ino:n.ino,uid:n.uid,instanceId:n.instanceId,pid:n.pid};if(d.bytes!==JSON.stringify(l)||s.bytes!==JSON.stringify({instanceId:n.instanceId,launcherPid:n.pid,backendPid:a}))return D();let u=oe.dirname(o.socketPath),c=await U.promises.lstat(u);if(!oe.isAbsolute(o.socketPath)||oe.normalize(o.socketPath)!==o.socketPath||!c.isDirectory()||c.isSymbolicLink()||c.uid!==n.uid||(c.mode&63)!==0)return D();async function f(){let p=await U.promises.lstat(n.root);if(!p.isDirectory()||p.isSymbolicLink()||(p.mode&63)!==0||p.dev!==n.dev||p.ino!==n.ino||p.uid!==n.uid||e.pid!==a)return D();for(let[N,I]of[[n.root+"/OWNER.json",d],[n.root+"/backend-owner.json",s]]){let A=await Ve(N,n.uid);if(A.bytes!==I.bytes||Object.keys(I.pin).some(F=>A.pin[F]!==I.pin[F]))return D()}}async function m(){let p=await mt(o.socketPath),N=[];if(p){let A=await U.promises.lstat(u);if(!A.isDirectory()||A.isSymbolicLink()||A.uid!==n.uid||(A.mode&63)!==0||A.dev!==c.dev||A.ino!==c.ino||!p.isSocket()||p.isSymbolicLink()||p.uid!==n.uid||p.dev!==o.socketIdentity.dev||p.ino!==o.socketIdentity.ino)return D();N.push(o.socketPath)}let I=o.alias;if(I){if(oe.dirname(I.path)!==n.root||I.rootDev!==n.dev||I.rootIno!==n.ino)return D();let A=await mt(I.path);if(A){if(!A.isSymbolicLink()||A.uid!==n.uid||A.dev!==I.dev||A.ino!==I.ino||await U.promises.readlink(I.path)!==I.target)return D();N.push(I.path)}}return N}await f(),await m();async function E(){if(!T(e)||!r())return D();await f();let p=await m();for(let N of p)await f(),(await m()).includes(N)&&await U.promises.unlink(N);if(await f(),(await m()).length)return D()}return{cleanupExited:E,forceStop:async()=>{if(T(e))return r()&&await E(),{ended:!0,forced:!1};if(!r())return{ended:!1,forced:!1};if(await f(),await m(),T(e))return r()&&await E(),{ended:!0,forced:!1};if(!r())return{ended:!1,forced:!1};let p=e.kill("SIGKILL");return await q(e,1e4)?(await E(),{ended:!0,forced:p}):{ended:!1,forced:p}}}}var k=require("node:fs"),R=z(require("node:path")),Nt=require("node:module"),Y=class extends Error{};async function vt(t){try{await k.promises.access(t,k.constants.X_OK);let e=await k.promises.open(t,"r");try{if(!(await e.stat()).isFile())return!1;let i=Buffer.alloc(4);return(await e.read(i,0,4,0)).bytesRead===4&&["7f454c46","cffaedfe","cefaedfe","feedface","feedfacf","cafebabe","bebafeca","cafebabf","bfbafeca"].includes(i.toString("hex"))}finally{await e.close()}}catch{return!1}}var wt=(t,e)=>{let i=R.relative(t,e);return i!==""&&!i.startsWith(".."+R.sep)&&i!==".."&&!R.isAbsolute(i)};async function It(t){if(await vt(t))return{file:t,direct:!0};try{let e=R.resolve(R.dirname(t),"..","package.json"),i=await k.promises.realpath(R.dirname(e)),r=JSON.parse(await k.promises.readFile(e,"utf8")),n=typeof r.bin=="string"?r.bin:r.bin?.codex;if(r.name!=="@openai/codex"||typeof n!="string"||await k.promises.realpath(R.resolve(i,n))!==t)throw new Y;let o=process.platform==="android"?"linux":process.platform,a="@openai/codex-"+o+"-"+process.arch,d=i;try{let f=(0,Nt.createRequire)(e).resolve(a+"/package.json"),m=JSON.parse(await k.promises.readFile(f,"utf8"));if(Array.isArray(m.os)&&!m.os.includes(o)||Array.isArray(m.cpu)&&!m.cpu.includes(process.arch))throw new Y;d=await k.promises.realpath(R.dirname(f))}catch(f){if(f instanceof Y||f.code!=="MODULE_NOT_FOUND")throw f}let s=await k.promises.realpath(d+"/vendor");if(!wt(d,s))throw new Y;let l=(await k.promises.readdir(s,{withFileTypes:!0})).filter(f=>f.isDirectory());if(l.length>16)throw new Y;let u=[],c={"linux:x64":"x86_64-unknown-linux-musl","linux:arm64":"aarch64-unknown-linux-musl","darwin:x64":"x86_64-apple-darwin","darwin:arm64":"aarch64-apple-darwin"}[o+":"+process.arch];for(let f of l){if(d===i&&f.name!==c)continue;let m=R.join(s,f.name,"bin","codex");if(await vt(m)){let E=await k.promises.realpath(m);if(!wt(s,E))throw new Y;u.push(E)}}if(u.length!==1)throw new Y;return{file:u[0],direct:!0}}catch{return{file:t,direct:!1}}}var Kt=t=>new Promise(e=>setTimeout(e,t)),_t=12e4;async function ke(t,e,i=r=>console.error("CodeVibe: native startup failed",r)){let r=Date.now();try{return await e()}catch(n){try{i({stage:t,elapsedMs:Date.now()-r,code:n instanceof w?n.code:"NATIVE_STARTUP_FAILED",...n instanceof w&&n.diagnostic?{diagnostic:n.diagnostic}:{}})}catch{}throw n}}async function bt(t){return T(t)||(t.stdin?.end(),await q(t,2e3))?!0:(t.kill("SIGINT"),q(t,5e3))}async function Ct(t,e,i){for(let r of(e.PATH??"").split(b.delimiter).filter(Boolean)){let n=b.resolve(i,r,t);try{await h.promises.access(n,h.constants.X_OK);let o=await h.promises.realpath(n);if((await h.promises.stat(o)).isFile())return o}catch{}}throw Error(t==="codex"?"Codex executable not found;install Codex,then retry.":"tmux executable not found;install tmux,then retry.")}var Le=(t,e)=>Ct("codex",t,e);async function be(t){let e=(0,se.createHash)("sha256");for await(let i of(0,h.createReadStream)(t))e.update(i);return e.digest("hex")}function Me(t){let e={...t};return delete e.CODEVIBE_CODEX_TMUX_SESSION,delete e.CODEVIBE_CODEX_PRIMARY_COMPANION,delete e.QUORUM_REVIEWER_SUBPROCESS,e}async function Ue(t,e=process.env){let i=e.TMUX?.split(",")[0];if(!i||!b.isAbsolute(i)||!process.stdin.isTTY||!process.stdout.isTTY)throw Error("Native Companion requires its terminal launcher.");let r=await h.promises.mkdtemp(b.join(await h.promises.realpath("/tmp"),"cvcd-")),n=await h.promises.lstat(r),o=(0,se.randomUUID)(),a={root:r,dev:n.dev,ino:n.ino,uid:n.uid,instanceId:o,pid:process.pid};await h.promises.writeFile(r+"/OWNER.json",JSON.stringify(a),{flag:"wx",mode:384});let d=await h.promises.open(r+"/lifecycle.jsonl","wx",384),s=(v,j={})=>d.appendFile(JSON.stringify({utc:new Date().toISOString(),kind:v,...j})+`
|
|
3
|
+
`);await s("RESOURCE",a);let l,u,c,f,m,E=new Ae(o),p=new _e(E),N=null,I=!1,A=0,F=!1,te=null,ae=!1,pe=!1,K=!1,x,L=[],Be=async()=>{let v=await h.promises.lstat(r);if(!v.isDirectory()||v.isSymbolicLink()||v.dev!==n.dev||v.ino!==n.ino||v.uid!==n.uid||JSON.parse(await h.promises.readFile(r+"/OWNER.json","utf8")).instanceId!==o)throw Error("NATIVE_LAUNCH_ROOT_CHANGED")};try{let v=await Le(e,process.cwd()),j=Me(e),J=await It(v);K=J.direct;let H=(0,X.spawn)(v,["--version"],{env:j,stdio:["ignore","pipe","pipe"]});L.push(H),H.on("error",()=>{}),await s("VERSION_PROCESS",{pid:H.pid,executable:v});let ie="",W="";if(H.stdout.on("data",y=>{ie=(ie+y.toString()).slice(0,1025)}),H.stderr.on("data",y=>{W=(W+y.toString()).slice(0,65537)}),!await q(H,1e4)||H.exitCode!==0||ie.length>1024||W.length>64*1024)throw Error("NATIVE_VERSION_UNAVAILABLE");let Vt=await ht(J.file,r+"/protocol",j,y=>{L.push(y),s("CAPABILITY_PROCESS",{pid:y.pid}).catch(()=>{})});await s("CAPABILITIES",Vt);let g=Qe(t,process.cwd(),r+"/native.sock");g.workingDirectory=await h.promises.realpath(g.workingDirectory),N=g.resumeThreadId;let Ce=await be(v),qe=J.file===v?Ce:await be(J.file);await s("PLAN",{nativeVersion:ie.trim(),cli:v,cliSha256:Ce,backendExecutable:J.file,backendSha256:qe,directBackend:K,argvSha256:(0,se.createHash)("sha256").update(JSON.stringify(t)).digest("hex")}),await h.promises.mkdir(r+"/tmp",{mode:448});let Je={...j,TMPDIR:r+"/tmp"},ze=(0,h.openSync)(r+"/native.log","wx",384);l=(0,X.spawn)(J.file,g.appServerArgs,{cwd:g.workingDirectory,env:Je,detached:!0,stdio:["pipe","ignore",ze]}),l.on("error",()=>{}),(0,h.closeSync)(ze),L.push(l),await s("NATIVE_SERVER",{pid:l.pid}),l.pid&&await h.promises.writeFile(r+"/backend-owner.json",JSON.stringify({instanceId:o,launcherPid:process.pid,backendPid:l.pid}),{flag:"wx",mode:384});let kt=Date.now()+2e3,Xe=!1;for(;Date.now()<kt&&!T(l);){try{await h.promises.lstat(r+"/native.sock"),Xe=!0;break}catch(y){if(y.code!=="ENOENT")throw y}await Kt(20)}if(!Xe||!l.pid)throw Error("NATIVE_LISTENER_UNAVAILABLE");let fe=await et(r+"/native.sock",n);if(te=fe.socketPath,g.resumeThreadId&&K)try{x=await Et(a,l,fe,()=>ae&&!u)}catch(y){throw pe=!0,y}f=new ce({...fe,instanceId:o,pluginVersion:"launcher",assertOwner:()=>{if(!l||T(l))throw Error("NATIVE_OWNER_ENDED")},onMessage:()=>{},onFailure:()=>{}}),await ke("connect",()=>f.connect());try{let y=await f.request("thread/loaded/list",{},5e3);if(!Array.isArray(y?.data)||y.data.some(S=>typeof S!="string"||!S.length))throw new w("NATIVE_PROTOCOL_INVALID")}catch(y){throw y instanceof w&&y.code==="NATIVE_RPC_REJECTED"&&y.rpcCode===-32601?new V("NATIVE_UPDATE_REQUIRED",["thread/loaded/list"]):y}if(g.resumeThreadId){let y=new AbortController,S=Date.now(),P=()=>y.abort(),Ee=setInterval(()=>console.error(`CodeVibe: loading Codex session (${Math.floor((Date.now()-S)/1e3)}s); Ctrl+C cancels startup.`),5e3);process.on("SIGINT",P);let de;try{de=await ke("resume",()=>f.request("thread/resume",{threadId:g.resumeThreadId,excludeTurns:!0,...g.policy,...g.model!==null?{model:g.model}:{},...g.cwdOverride?{cwd:g.workingDirectory}:{}},_t,y.signal))}catch(Q){throw ae=Q instanceof w&&(Q.code==="NATIVE_REQUEST_CANCELLED"||Q.code==="NATIVE_RPC_TIMEOUT"),Q}finally{clearInterval(Ee),process.off("SIGINT",P)}if(de?.thread?.id!==g.resumeThreadId||g.policy.approvalPolicy&&de.approvalPolicy!==g.policy.approvalPolicy||g.policy.sandbox&&de.sandbox?.type!=={"read-only":"readOnly","workspace-write":"workspaceWrite","danger-full-access":"dangerFullAccess"}[g.policy.sandbox])throw Error("NATIVE_RESUME_POLICY_MISMATCH")}await f.close(),f=void 0;let xt={version:1,instanceId:o,root:{path:r,dev:n.dev,ino:n.ino,uid:n.uid},launcher:{pid:process.pid,host:Tt.hostname()},server:{pid:l.pid},endpoint:fe,plan:g};await h.promises.writeFile(r+"/launch.json",JSON.stringify(xt),{flag:"wx",mode:384});try{let y=await nt(r+"/launch.json",o);m=new ye({authority:y,pluginVersion:"launcher-receipts",onRoot:async S=>{N=S.id},onMessage:async S=>{E.observe(S),p.flush(),S.method==="thread/status/changed"&&await m.refreshMetadata()},onFailure:()=>{E.invalidate(),p.flush()}}),await m.start()}catch{E.invalidate(),await m?.close().catch(()=>{}),m=void 0,console.error("CodeVibe: native receipt recovery unavailable;desktop Codex remains independent.")}let He=y=>{let S=(0,h.openSync)(r+"/observer.log","a",384),P=(0,X.fork)(b.join(__dirname,"server.js"),[],{cwd:g.workingDirectory,detached:!0,stdio:["ignore",S,S,"ipc"],env:{...j,TMPDIR:r+"/tmp",CODEX_WORKING_DIRECTORY:g.workingDirectory,CODEVIBE_CODEX_TMUX_SESSION:"native-"+o,CODEVIBE_CODEX_NATIVE_DESCRIPTOR:r+"/launch.json",CODEVIBE_CODEX_NATIVE_INSTANCE:o,CODEVIBE_CODEX_DAEMON_RECOVERY:y?"1":"0",CODEVIBE_CODEX_NATIVE_THREAD:y?N??"":""}});(0,h.closeSync)(S),L.push(P),s("OBSERVER",{pid:P.pid,recovery:y}).catch(()=>{}),p.attach(P),P.on("error",()=>{});let Ee,de=new Promise(Q=>{Ee=Q});return P.on("message",Q=>{let $=Q;$?.instanceId===o&&(p.handle(P,$)||P!==c||I||($.type==="CODEVIBE_NATIVE_READY"&&(Ee(),p.handle(P,{type:"CODEVIBE_NATIVE_RECEIPTS_POLL",instanceId:o})),$.type==="CODEVIBE_NATIVE_BOUND"&&typeof $.threadId=="string"&&(N=$.threadId),$.type==="CODEVIBE_NATIVE_OBSERVER_DEGRADED"&&!T(P)&&P.kill("SIGTERM"),$.type==="CODEVIBE_NATIVE_MOBILE_END"&&u&&!T(u)&&u.kill("SIGTERM")))}),P.on("exit",()=>{if(!I&&u&&!T(u))if(N&&A++===0)try{c=He(!0).child}catch{console.error("CodeVibe: mobile observer restart failed;desktop remains available.")}else console.error("CodeVibe: mobile sync unavailable;desktop Codex remains available.")}),{child:P,initialized:de}},We=He(!1);if(c=We.child,await Promise.race([We.initialized,q(c,1e4)]),T(c)&&console.error("CodeVibe: mobile sync unavailable;desktop Codex remains available."),await Be(),await be(v)!==Ce||await be(J.file)!==qe)throw Error("NATIVE_EXECUTABLE_CHANGED");u=(0,X.spawn)(v,g.tuiArgs,{cwd:g.workingDirectory,env:Je,stdio:"inherit"}),L.push(u);let Ge=new Promise((y,S)=>{u.once("error",S),u.once("close",()=>y())});Ge.catch(()=>{}),await s("FRONTEND",{pid:u.pid});let Ye=()=>{},me=()=>{u&&!T(u)&&u.kill("SIGTERM")};if(process.on("SIGINT",Ye),process.on("SIGTERM",me),process.on("SIGHUP",me),await Ge,process.off("SIGINT",Ye),process.off("SIGTERM",me),process.off("SIGHUP",me),I=!0,await s("FRONTEND_ENDED",{code:u.exitCode,signal:u.signalCode}),c&&!T(c)&&c.connected&&c.send({type:"CODEVIBE_NATIVE_TERMINAL_END",instanceId:o}),!(!c||await q(c,29e3)))throw Error("NATIVE_OBSERVER_TEARDOWN_INCOMPLETE");return(u.exitCode??1)||(c?.exitCode??0)}finally{if(I=!0,await f?.close().catch(()=>{}),p.close(),await m?.close().catch(()=>{}),u&&!T(u))await s("RETAINED_FRONTEND",{pid:u.pid});else{if(c&&!T(c)&&(c.kill("SIGTERM"),await q(c,29e3)),l){let v=T(l)||await bt(l);if(ae&&!u&&x)try{if(v)await x.cleanupExited(),await s("STARTUP_BACKEND_ENDPOINT_CLEANED",{pid:l.pid});else{await s("STARTUP_BACKEND_FORCE_STOP_INTENT",{pid:l.pid});let j=await x.forceStop();await s("STARTUP_BACKEND_FORCE_STOP_RESULT",{pid:l.pid,...j})}}catch{pe=!0,await s("STARTUP_BACKEND_FORCE_STOP_REFUSED",{pid:l.pid})}}for(let v of L)v!==l&&v!==c&&!T(v)&&(v.kill("SIGTERM"),await q(v,2e3));if(F=L.every(T)&&!pe,te)try{await h.promises.lstat(te),F=!1}catch(v){if(v.code!=="ENOENT")throw v}}if(await s("CLEANUP",{allCreatedChildrenEnded:F,children:L.map(v=>({pid:v.pid,code:v.exitCode,signal:v.signalCode}))}),await d.close(),F){await Be();let v=0,j=async J=>{for(let H of await h.promises.readdir(J)){if(++v>4096)throw Error("NATIVE_ROOT_CLEANUP_INVENTORY_EXCEEDED");let ie=b.join(J,H),W=await h.promises.lstat(ie);if(W.isDirectory()&&!W.isSymbolicLink())await j(ie);else if(!W.isFile()&&!W.isSocket()&&!W.isSymbolicLink())throw Error("NATIVE_ROOT_CLEANUP_TYPE_CHANGED")}};await j(r),await h.promises.rm(r,{recursive:!0})}else{console.error("CodeVibe: teardown incomplete;owned recovery files retained at "+r);for(let v of L)T(v)||(v.unref(),v.stdin?.destroy(),v.stdout?.destroy(),v.stderr?.destroy(),v.connected&&v.disconnect());throw new ue(r,L.filter(v=>!T(v)).map(v=>v.pid).filter(Boolean),ae&&!K)}}}function gt(t){return t.isFile()&&!t.isSymbolicLink()&&t.nlink===1&&(t.mode&63)===0&&t.uid===process.getuid?.()}async function Ot(t,e,i){if(!b.isAbsolute(t)||b.normalize(t)!==t||b.basename(t)!=="bootstrap.json")throw Error("NATIVE_TMUX_BOOTSTRAP_INVALID");let r=b.dirname(t),n=await h.promises.open(t,h.constants.O_RDONLY|h.constants.O_NOFOLLOW),o;try{let a=await n.stat();if(!gt(a)||a.size>2*1024*1024)throw Error("NATIVE_TMUX_BOOTSTRAP_INVALID");o=JSON.parse(await n.readFile("utf8"));let d=await n.stat();if(a.dev!==d.dev||a.ino!==d.ino||a.size!==d.size||a.mtimeMs!==d.mtimeMs||o.version!==1||o.nonce!==e||o.root?.path!==r||!Array.isArray(o.args)||!o.args.every(u=>typeof u=="string")||!o.environment||typeof o.environment!="object"||Array.isArray(o.environment)||!Object.values(o.environment).every(u=>typeof u=="string"))throw Error("NATIVE_TMUX_BOOTSTRAP_INVALID");let s=await h.promises.lstat(r);if(!s.isDirectory()||s.isSymbolicLink()||(s.mode&63)!==0||s.uid!==process.getuid?.()||s.dev!==o.root.dev||s.ino!==o.root.ino||s.uid!==o.root.uid)throw Error("NATIVE_TMUX_BOOTSTRAP_INVALID");let l=await h.promises.open(r+"/status",h.constants.O_WRONLY|h.constants.O_NOFOLLOW);try{let u=await l.stat(),c=(await h.promises.readdir(r)).sort();if(!gt(u)||u.size!==0||u.dev!==o.status?.dev||u.ino!==o.status?.ino||c.join(",")!=="bootstrap.json,status")throw Error("NATIVE_TMUX_BOOTSTRAP_INVALID");let f=await h.promises.lstat(r),m=await h.promises.lstat(t),E=await h.promises.lstat(r+"/status");if(f.dev!==s.dev||f.ino!==s.ino||m.dev!==a.dev||m.ino!==a.ino||E.dev!==u.dev||E.ino!==u.ino)throw Error("NATIVE_TMUX_BOOTSTRAP_INVALID");await h.promises.unlink(t),await h.promises.unlink(r+"/status"),await h.promises.rmdir(r);let p={...o.environment};return delete p.TMUX,delete p.TMUX_PANE,i.TMUX&&(p.TMUX=i.TMUX),i.TMUX_PANE&&(p.TMUX_PANE=i.TMUX_PANE),{args:o.args,environment:p,status:l}}catch(u){throw await l.close(),u}}finally{await n.close()}}var Qt=t=>"'"+t.split("'").join("'\\''")+"'";function xe(t){let e=Number(t.slice(0,-1));return Number.isInteger(e)&&e>=0&&e<=255&&t===String(e)+`
|
|
4
|
+
`?e:null}var Fe={NATIVE_UPDATE_REQUIRED:new V("NATIVE_UPDATE_REQUIRED").message,NATIVE_CAPABILITY_PROBE_FAILED:new V("NATIVE_CAPABILITY_PROBE_FAILED").message,NATIVE_RPC_TIMEOUT:"Codex did not finish its native startup request in time. Try resuming the session directly with Codex.",NATIVE_REQUEST_CANCELLED:"Codex session loading was cancelled.",NATIVE_DISCONNECTED:"The native Codex connection ended during startup. Try the session directly with Codex.",NATIVE_STARTUP_FAILED:"CodeVibe could not start native Codex. Check that Codex runs directly, then retry.",NATIVE_LAUNCH_CLEANUP_INCOMPLETE:"Codex startup cleanup could not be completed safely."},ue=class extends Error{constructor(i,r,n=!1){super("NATIVE_LAUNCH_CLEANUP_INCOMPLETE");this.root=i;this.pids=r;this.needsNativeExecutable=n;this.code="NATIVE_LAUNCH_CLEANUP_INCOMPLETE"}};function St(t){if(t.length>2048)return null;let e=xe(t);if(e!==null)return{code:e,diagnostic:null};let i=t.split(`
|
|
5
|
+
`),r=xe(i[0]+`
|
|
6
|
+
`);if(![3,4].includes(i.length)||i[i.length-1]!==""||r===null||r===0||!Object.prototype.hasOwnProperty.call(Fe,i[1]))return null;if(i.length===4){if(i[1]!=="NATIVE_LAUNCH_CLEANUP_INCOMPLETE")return null;try{let n=JSON.parse(i[2]);return!n||typeof n!="object"||Array.isArray(n)||!["pids,root","needsNativeExecutable,pids,root"].includes(Object.keys(n).sort().join(","))||"needsNativeExecutable"in n&&n.needsNativeExecutable!==!0||typeof n.root!="string"||!/^\/(?:private\/)?tmp\/cvcd-[A-Za-z0-9]+$/.test(n.root)||!Array.isArray(n.pids)||n.pids.length>16||n.pids.some(o=>typeof o!="number"||!Number.isSafeInteger(o)||o<=0)||new Set(n.pids).size!==n.pids.length?null:{code:r,diagnostic:"NATIVE_LAUNCH_CLEANUP_INCOMPLETE",recovery:n}}catch{return null}}return{code:r,diagnostic:i[1]}}function je(t){if(!t.diagnostic)return null;let e=Fe[t.diagnostic],i=t.recovery;return i?`${e} ${i.pids.length?"Owned process IDs still requiring recovery: "+i.pids.join(", ")+".":"No owned child remains, but recovery files were retained."} Recovery files: ${i.root}. Inspect the retained state before retrying.${i.needsNativeExecutable?" This wrapper could not establish direct backend ownership; use the native Codex executable on PATH for supervised startup recovery.":""}`:e}function Pt(t){let e=t;return e?.code===1&&typeof e.stderr=="string"&&(e.stderr.startsWith("can't find session:")||e.stderr.startsWith("no server running on ")||e.stderr.startsWith("error connecting to ")&&(e.stderr.includes("No such file or directory")||e.stderr.includes("Connection refused")))}async function Rt(t,e){let i=t.TMUX_TMPDIR?await h.promises.realpath(t.TMUX_TMPDIR):e,r=b.join(i,"tmux-"+process.getuid?.());try{await h.promises.mkdir(r,{mode:448})}catch(o){if(o.code!=="EEXIST")throw o}let n=await h.promises.lstat(r);if(!n.isDirectory()||n.isSymbolicLink()||n.uid!==process.getuid?.()||(n.mode&63)!==0)throw Error("NATIVE_TMUX_NAMESPACE_UNSAFE");return b.join(r,"default")}async function Dt(t,e=process.env){if(["--version","-v","--help","-h"].includes(t[0])||e.CODEVIBE_COMPANION_DIAGNOSTIC==="version"){let E=await Le(e,process.cwd());e.CODEVIBE_COMPANION_DIAGNOSTIC==="version"&&console.log("codevibe companion codex "+yt().version);let p=(0,X.spawn)(E,e.CODEVIBE_COMPANION_DIAGNOSTIC==="version"?["--version"]:t,{env:Me(e),stdio:"inherit"});return new Promise(N=>{p.once("error",()=>N(127)),p.once("close",I=>N(I??1))})}if(e.TMUX)return Ue(t,e);if(!process.stdin.isTTY||!process.stdout.isTTY)throw Error("Codex Companion requires an interactive terminal;use plain codex for non-interactive commands.");let i=await Ct("tmux",e,process.cwd()),r=await h.promises.realpath("/tmp"),n=await Rt(e,r),o={...e};delete o.TMUX,delete o.TMUX_PANE;let a=(0,At.promisify)(X.execFile),d="codevibe-codex-"+process.pid+"-"+(0,se.randomUUID)().slice(0,8),s=await h.promises.mkdtemp(r+"/cvcd-tmux-"),l=await h.promises.lstat(s),u=(0,se.randomUUID)(),c,f=!1,m=[process.execPath,b.join(__dirname,"native-launch.js"),"--native-bootstrap",s+"/bootstrap.json",u].map(Qt).join(" ");try{c=await h.promises.open(s+"/status","wx+",384);let E=await c.stat(),p={version:1,nonce:u,root:{path:s,dev:l.dev,ino:l.ino,uid:l.uid},status:{dev:E.dev,ino:E.ino},args:t,environment:Object.fromEntries(Object.entries(e).filter(x=>typeof x[1]=="string"))};await h.promises.writeFile(s+"/bootstrap.json",JSON.stringify(p),{flag:"wx",mode:384});let N=["-x",String(process.stdout.columns||120),"-y",String(process.stdout.rows||40)];await a(i,["-S",n,"new-session","-d","-s",d,"-c",process.cwd(),...N,"exec "+m],{env:o,timeout:1e4}),f=!0,await a(i,["-S",n,"set-option","-t",d,"mouse","on"],{env:o,timeout:1e4}).catch(()=>{});let I=(0,X.spawn)(i,["-S",n,"attach-session","-t",d],{env:o,stdio:"inherit"}),A=()=>{};process.on("SIGINT",A);let F;try{F=await new Promise(x=>{I.once("error",()=>x(1)),I.once("close",L=>x(L??1))})}finally{process.off("SIGINT",A)}let te=Buffer.alloc(4096),ae=await c.read(te,0,te.length,0),pe=te.subarray(0,ae.bytesRead).toString(),K=St(pe);if(K!==null){let x=je(K);return x&&console.error(x),K.code}try{return await a(i,["-S",n,"has-session","-t",d],{env:o,timeout:1e4}),F}catch{return F||1}}finally{if(await c?.close(),!f){let E=!1;try{await a(i,["-S",n,"has-session","-t",d],{env:o,timeout:1e4})}catch(p){E=Pt(p)}if(E){let p=await h.promises.lstat(s);if(p.dev!==l.dev||p.ino!==l.ino)throw Error("NATIVE_TMUX_BOOTSTRAP_INVALID");let N=await h.promises.readdir(s);if(N.some(I=>!["bootstrap.json","status"].includes(I))||N.includes("bootstrap.json")&&JSON.parse(await h.promises.readFile(s+"/bootstrap.json","utf8")).nonce!==u)throw Error("NATIVE_TMUX_BOOTSTRAP_INVALID");for(let I of N)await h.promises.unlink(s+"/"+I);await h.promises.rmdir(s)}else console.error("CodeVibe: launcher setup incomplete;recovery files retained at "+s)}}}async function $t(){let t=process.argv.slice(2);if(t[0]!=="--native-bootstrap")return Dt(t);if(t.length!==3)throw Error("NATIVE_TMUX_BOOTSTRAP_INVALID");let e=await Ot(t[1],t[2],process.env),i=1,r=null,n;try{return i=await Ue(e.args,e.environment),i}catch(o){throw o instanceof ue?(r=o.code,n={root:o.root,pids:o.pids,...o.needsNativeExecutable?{needsNativeExecutable:!0}:{}}):r=(o instanceof V||o instanceof w)&&Object.prototype.hasOwnProperty.call(Fe,o.code)?o.code:"NATIVE_STARTUP_FAILED",o}finally{await e.status.writeFile(String(i)+`
|
|
7
|
+
`+(r?r+`
|
|
8
|
+
`:"")+(n?JSON.stringify(n)+`
|
|
9
|
+
`:"")),await e.status.close()}}require.main===module&&$t().then(t=>{process.exitCode=t},t=>{console.error(t instanceof ue?je({code:1,diagnostic:t.code,recovery:{root:t.root,pids:t.pids,...t.needsNativeExecutable?{needsNativeExecutable:!0}:{}}}):t instanceof Error?t.message:"Native launch failed"),process.exitCode=1});0&&(module.exports={NATIVE_STARTUP_RESUME_TIMEOUT_MS,NativeLaunchCleanupError,consumeTmuxBootstrap,findNativeCodex,launchNativeCompanion,launchNativeInsideTmux,missingTmuxSession,nativeChildEnvironment,nativeExitReport,nativeExitStatus,nativeStartupFailureMessage,nativeStartupStep,nativeTmuxSocket,stopNativeBackend,waitExit});
|