@quantiya/codevibe-core 1.0.17 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/appsync/appsync-client.d.ts +16 -84
  2. package/dist/appsync/queries.d.ts +2 -8
  3. package/dist/audit-keys/__tests__/audit-keys-parity.test.d.ts +1 -0
  4. package/dist/audit-keys/index.d.ts +41 -0
  5. package/dist/auth/auth-service.d.ts +4 -2
  6. package/dist/auth/auth-telemetry.d.ts +0 -9
  7. package/dist/index.d.ts +4 -0
  8. package/dist/index.js +72 -45
  9. package/dist/orchestration/detect-agents.d.ts +56 -0
  10. package/dist/orchestration/index.d.ts +2 -0
  11. package/dist/orchestration/orchestration-cli.d.ts +9 -0
  12. package/dist/reviewer/__tests__/integration.test.d.ts +1 -0
  13. package/dist/reviewer/__tests__/mocks.test.d.ts +1 -0
  14. package/dist/reviewer/__tests__/output-parser.test.d.ts +1 -0
  15. package/dist/reviewer/__tests__/registry.test.d.ts +1 -0
  16. package/dist/reviewer/__tests__/subprocess.test.d.ts +1 -0
  17. package/dist/reviewer/index.d.ts +15 -0
  18. package/dist/reviewer/mocks.d.ts +80 -0
  19. package/dist/reviewer/output-parser.d.ts +95 -0
  20. package/dist/reviewer/provider.d.ts +153 -0
  21. package/dist/reviewer/providers/__tests__/claude-live-smoke.test.d.ts +1 -0
  22. package/dist/reviewer/providers/__tests__/claude.test.d.ts +1 -0
  23. package/dist/reviewer/providers/__tests__/codex-live-smoke.test.d.ts +1 -0
  24. package/dist/reviewer/providers/__tests__/codex.test.d.ts +1 -0
  25. package/dist/reviewer/providers/__tests__/gemini-live-smoke.test.d.ts +1 -0
  26. package/dist/reviewer/providers/__tests__/gemini.test.d.ts +1 -0
  27. package/dist/reviewer/providers/claude.d.ts +59 -0
  28. package/dist/reviewer/providers/codex.d.ts +67 -0
  29. package/dist/reviewer/providers/common.d.ts +25 -0
  30. package/dist/reviewer/providers/gemini.d.ts +108 -0
  31. package/dist/reviewer/registry.d.ts +87 -0
  32. package/dist/reviewer/subprocess.d.ts +117 -0
  33. package/dist/reviewer/types.d.ts +101 -0
  34. package/dist/types/index.d.ts +1 -0
  35. package/dist/types/reviewer.d.ts +67 -0
  36. package/dist/types/session.d.ts +16 -0
  37. package/package.json +6 -3
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
- "use strict";var mt=Object.create;var ie=Object.defineProperty;var ht=Object.getOwnPropertyDescriptor;var ft=Object.getOwnPropertyNames;var vt=Object.getPrototypeOf,St=Object.prototype.hasOwnProperty;var D=(n,e)=>()=>(n&&(e=n(n=0)),e);var Ne=(n,e)=>{for(var t in e)ie(n,t,{get:e[t],enumerable:!0})},$e=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of ft(e))!St.call(n,i)&&i!==t&&ie(n,i,{get:()=>e[i],enumerable:!(r=ht(e,i))||r.enumerable});return n};var m=(n,e,t)=>(t=n!=null?mt(vt(n)):{},$e(e||!n||!n.__esModule?ie(t,"default",{value:n,enumerable:!0}):t,n)),wt=n=>$e(ie({},"__esModule",{value:!0}),n);function kt(n,e){if(e instanceof Error){let t={name:e.name,message:e.message};e.stack&&(t.stack=e.stack);for(let r of Object.keys(e))r in t||(t[r]=e[r]);return t}return e}function ge(n){return new N(n)}var F,se,Ue,Le,N,c,Me=D(()=>{"use strict";F=m(require("fs")),se=m(require("path")),Ue=m(require("os")),Le={debug:0,info:1,warn:2,error:3};N=class{constructor(e){this.name=e.name,this.logFile=e.logFile,this.level=e.level||"info",this.enableConsole=e.console??!1,this.logFile&&this.ensureLogDir()}ensureLogDir(){if(this.logFile){let e=se.dirname(this.logFile);F.existsSync(e)||F.mkdirSync(e,{recursive:!0})}}shouldLog(e){return Le[e]>=Le[this.level]}formatMessage(e,t,r){let i=new Date().toISOString(),s=e.toUpperCase().padEnd(5),o=`[${i}] [${s}] [${this.name}] ${t}`;return r!==void 0&&(r instanceof Error?(o+=` ${r.name}: ${r.message}`,r.stack&&(o+=`
2
- ${r.stack}`)):typeof r=="object"?o+=` ${JSON.stringify(r,kt)}`:o+=` ${r}`),o}log(e,t,r){if(!this.shouldLog(e))return;let i=this.formatMessage(e,t,r);if(this.logFile)try{F.appendFileSync(this.logFile,i+`
3
- `)}catch{}if(this.enableConsole)switch(e){case"error":console.error(i);break;case"warn":console.warn(i);break;default:console.log(i)}}debug(e,t){this.log("debug",e,t)}info(e,t){this.log("info",e,t)}warn(e,t){this.log("warn",e,t)}error(e,t){this.log("error",e,t)}setLevel(e){this.level=e}};c=new N({name:"codevibe-core",logFile:se.join(Ue.tmpdir(),"codevibe-core.log"),level:"info"})});var $=D(()=>{"use strict";Me()});function bt(n){for(let e of n)try{process.stderr.write(e+`
4
- `)}catch{}}function It(){ye=he.join(Be.homedir(),".codevibe");try{_.mkdirSync(ye,{recursive:!0,mode:448})}catch{}L="file"}function Et(){if(L!==null||me!==null)return;let optedIn=process.env.CODEVIBE_ALLOW_FILE_KEYCHAIN==="1";if(optedIn){bt(["","\u26A0 CodeVibe: file-based credential storage selected (CODEVIBE_ALLOW_FILE_KEYCHAIN=1).","\u26A0 Location: ~/.codevibe/ (directory 0700, files 0600)","\u26A0 Trust level: equivalent to ~/.ssh/id_rsa \u2014 weaker than OS keyring.","\u26A0 To use the OS keyring instead, unset CODEVIBE_ALLOW_FILE_KEYCHAIN and","\u26A0 install libsecret-1-0 + a running keyring daemon (Linux) or use the","\u26A0 native Keychain (macOS) / Credential Manager (Windows).",""]),c.warn("[keychain-backend] Using file-based storage at ~/.codevibe (CODEVIBE_ALLOW_FILE_KEYCHAIN=1 explicit opt-in)"),It();return}let keytarLoadError=null;try{let nodeRequire=eval("require");C=nodeRequire("keytar")}catch(n){keytarLoadError=n instanceof Error?n.message:String(n),C=null}if(C){L="keytar",c.info("[keychain-backend] Using keytar (OS-native keyring)");return}me=new oe(["CodeVibe could not load the OS-native keyring (keytar).",`Reason: ${keytarLoadError??"unknown"}`,"","Options to fix this:"," 1. (Linux) Install libsecret and a keyring daemon:"," sudo apt install libsecret-1-0 gnome-keyring"," Then unlock the keyring for your user session.",""," 2. (Headless / CI / Docker) Opt in to file-based credential"," storage at ~/.codevibe/ (0600 files). This is equivalent"," in trust to ~/.ssh/id_rsa \u2014 not the OS keyring:"," export CODEVIBE_ALLOW_FILE_KEYCHAIN=1"].join(`
5
- `))}function At(n){return n.replace(/[^a-zA-Z0-9._-]/g,"_")}function We(n){return he.join(ye,`${At(n)}.json`)}function fe(n){try{let e=_.readFileSync(We(n),"utf-8"),t=JSON.parse(e);return t&&typeof t=="object"?t:{}}catch{return{}}}function Fe(n,e){let t=We(n);_.writeFileSync(t,JSON.stringify(e,null,2),{mode:384});try{_.chmodSync(t,384)}catch{}}function ve(){if(Et(),L===null)throw me??new oe("Keychain backend not initialized")}async function Se(n,e){return ve(),L==="keytar"&&C?C.getPassword(n,e):fe(n)[e]??null}async function we(n,e,t){if(ve(),L==="keytar"&&C){await C.setPassword(n,e,t);return}let r=fe(n);r[e]=t,Fe(n,r)}async function ke(n,e){if(ve(),L==="keytar"&&C)return C.deletePassword(n,e);let t=fe(n);return e in t?(delete t[e],Fe(n,t),!0):!1}var Be,he,_,oe,L,C,ye,me,He=D(()=>{"use strict";Be=m(require("os")),he=m(require("path")),_=m(require("fs"));$();oe=class extends Error{constructor(e){super(e),this.name="KeychainBackendUnavailableError"}},L=null,C=null,ye="",me=null});var E,U,be,xt,H,k,qe=D(()=>{"use strict";E=m(require("crypto")),U=class extends Error{constructor(e){super(e),this.name="CryptoError"}},be=1,xt="CodeVibe E2E v1",H=class n{constructor(){}static getInstance(){return n.instance||(n.instance=new n),n.instance}generateKeyPair(){let e=E.createECDH("prime256v1");e.generateKeys();let r=e.getPublicKey().subarray(1).toString("base64");return{privateKey:e.getPrivateKey().toString("base64"),publicKey:r}}generateSessionKey(){return E.randomBytes(32).toString("base64")}deriveSharedKey(e,t){try{let r=E.createECDH("prime256v1"),i=Buffer.from(e,"base64");r.setPrivateKey(i);let s=Buffer.concat([Buffer.from([4]),Buffer.from(t,"base64")]),o=r.computeSecret(s),a=E.hkdfSync("sha256",o,Buffer.alloc(0),Buffer.from(xt,"utf8"),32);return Buffer.from(a)}catch(r){throw new U(`Failed to derive shared key: ${r}`)}}encryptSessionKey(e,t){let r=this.generateKeyPair(),i=this.deriveSharedKey(r.privateKey,t),s=Buffer.from(e,"base64");return{encryptedKey:this.encrypt(s,i).toString("base64"),ephemeralPublicKey:r.publicKey}}decryptSessionKey(e,t){let r=this.deriveSharedKey(t,e.ephemeralPublicKey),i=Buffer.from(e.encryptedKey,"base64");return this.decrypt(i,r).toString("base64")}encryptContent(e,t){let r=Buffer.from(t,"base64"),i=Buffer.from(e,"utf8");return this.encrypt(i,r).toString("base64")}decryptContent(e,t){let r=Buffer.from(t,"base64"),i=Buffer.from(e,"base64");return this.decrypt(i,r).toString("utf8")}encryptMetadata(e,t){let r=JSON.stringify(e);return this.encryptContent(r,t)}decryptMetadata(e,t){let r=this.decryptContent(e,t);return JSON.parse(r)}encryptData(e,t){let r=Buffer.from(t,"base64");return this.encrypt(e,r)}decryptData(e,t){let r=Buffer.from(t,"base64");return this.decrypt(e,r)}encrypt(e,t){let r=E.randomBytes(12),i=E.createCipheriv("aes-256-gcm",t,r),s=Buffer.concat([i.update(e),i.final()]),o=i.getAuthTag();return Buffer.concat([r,s,o])}decrypt(e,t){let r=e.subarray(0,12),i=e.subarray(e.length-16),s=e.subarray(12,e.length-16),o=E.createDecipheriv("aes-256-gcm",t,r);o.setAuthTag(i);try{return Buffer.concat([o.update(s),o.final()])}catch{throw new U("Decryption failed: Invalid ciphertext or authentication tag")}}serializePrivateKey(e){return e}deserializePrivateKey(e){return e}},k=H.getInstance()});var G=D(()=>{"use strict";qe()});function b(){let n=process.env.ENVIRONMENT;return n==="development"||n==="production"?n:"production"}function ce(n){let e=n||b();return ae={...M[e],aws:{...M[e].aws,region:process.env.AWS_REGION||M[e].aws.region,appsyncUrl:process.env.APPSYNC_URL||M[e].aws.appsyncUrl,cognitoUserPoolId:process.env.COGNITO_USER_POOL_ID||M[e].aws.cognitoUserPoolId,cognitoClientId:process.env.COGNITO_CLIENT_ID||M[e].aws.cognitoClientId,cognitoDomain:process.env.COGNITO_DOMAIN||M[e].aws.cognitoDomain}},je=!0,ae}function f(){return(!je||!ae)&&ce(),ae}var Y,X,M,ae,je,Ve=D(()=>{"use strict";Y=m(require("os")),X=m(require("path")),M={development:{environment:"development",aws:{region:"us-east-1",appsyncUrl:"https://te6rjr37sbfpjc4fiunmb2tgy4.appsync-api.us-east-1.amazonaws.com/graphql",cognitoUserPoolId:"us-east-1_yVwWDPvvJ",cognitoClientId:"e9r5apv6v5uui3l928r2ris0r",cognitoDomain:"codevibe-development.auth.us-east-1.amazoncognito.com"},keychain:{serviceName:"ai.quantiya.app.codevibe"},server:{port:3456,host:"127.0.0.1",dynamicPort:!0},claude:{command:"claude",defaultTimeout:6e4},codex:{command:"codex",defaultTimeout:6e4,sessionsDir:X.default.join(Y.default.homedir(),".codex","sessions"),approvalTimeoutMs:5e3},gemini:{command:"gemini",defaultTimeout:6e4,transcriptDir:X.default.join(Y.default.homedir(),".gemini","tmp")}},production:{environment:"production",aws:{region:"us-east-1",appsyncUrl:"https://jwhyxq4sgrgcdosewp5k4ns5ca.appsync-api.us-east-1.amazonaws.com/graphql",cognitoUserPoolId:"us-east-1_mNRO0j5og",cognitoClientId:"5p04dbc9ojptc5r8n7605fg78f",cognitoDomain:"codevibe-production.auth.us-east-1.amazoncognito.com"},keychain:{serviceName:"ai.quantiya.app.codevibe"},server:{port:3456,host:"127.0.0.1",dynamicPort:!0},claude:{command:"claude",defaultTimeout:6e4},codex:{command:"codex",defaultTimeout:6e4,sessionsDir:X.default.join(Y.default.homedir(),".codex","sessions"),approvalTimeoutMs:5e3},gemini:{command:"gemini",defaultTimeout:6e4,transcriptDir:X.default.join(Y.default.homedir(),".gemini","tmp")}}},ae=null,je=!1});var q=D(()=>{"use strict";Ve()});var de,Je,K,Ie,Dt,B,g,ze=D(()=>{"use strict";de=m(require("os")),Je=require("uuid");He();G();q();$();K=class extends Error{constructor(e){super(e),this.name="KeychainError"}},Ie="device-identity",Dt="tokens-",B=class n{constructor(){this.deviceIdentity=null;this.sessionKeyCache=new Map;this.isRegistered=!1;this._serviceName=null}get serviceName(){return this._serviceName||(this._serviceName=f().keychain.serviceName),this._serviceName}static getInstance(){return n.instance||(n.instance=new n),n.instance}async getDeviceIdentity(){if(this.deviceIdentity)return this.deviceIdentity;let e=await Se(this.serviceName,Ie);return e?(this.deviceIdentity=JSON.parse(e),c.info(`[KeychainManager] Loaded device identity: ${this.deviceIdentity.deviceId}`),this.deviceIdentity):null}async setDeviceIdentity(e){try{await we(this.serviceName,Ie,JSON.stringify(e)),this.deviceIdentity=e,c.info(`[KeychainManager] Saved device identity: ${e.deviceId}`)}catch(t){throw c.error(`[KeychainManager] Failed to save device identity: ${t}`),new K(`Failed to save device identity: ${t}`)}}async getOrCreateDeviceIdentity(){let e=await this.getDeviceIdentity();if(e)return e;let t=k.generateKeyPair();return e={deviceId:(0,Je.v4)().toUpperCase(),privateKey:t.privateKey,publicKey:t.publicKey,createdAt:new Date().toISOString()},await this.setDeviceIdentity(e),c.info(`[KeychainManager] Generated new device identity: ${e.deviceId}`),e}async getDeviceId(){return(await this.getOrCreateDeviceIdentity()).deviceId}async getDevicePublicKey(){return(await this.getOrCreateDeviceIdentity()).publicKey}async getDevicePrivateKey(){return(await this.getOrCreateDeviceIdentity()).privateKey}async hasDeviceIdentity(){return await this.getDeviceIdentity()!==null}async deleteDeviceIdentity(){try{await ke(this.serviceName,Ie),this.deviceIdentity=null,this.sessionKeyCache.clear(),this.isRegistered=!1,c.info("[KeychainManager] Deleted device identity")}catch(e){throw c.error(`[KeychainManager] Failed to delete device identity: ${e}`),new K(`Failed to delete device identity: ${e}`)}}getTokenAccount(e){return`${Dt}${e}`}async getTokens(e="production"){let t=await Se(this.serviceName,this.getTokenAccount(e));if(!t)return null;let r=JSON.parse(t);return c.debug(`[KeychainManager] Loaded tokens for ${e}`),r}async setTokens(e,t="production"){try{await we(this.serviceName,this.getTokenAccount(t),JSON.stringify(e)),c.info(`[KeychainManager] Saved tokens for ${t}`,{userId:e.userId,email:e.email})}catch(r){throw c.error(`[KeychainManager] Failed to save tokens: ${r}`),new K(`Failed to save tokens: ${r}`)}}async deleteTokens(e="production"){try{let t=await ke(this.serviceName,this.getTokenAccount(e));return t&&c.info(`[KeychainManager] Deleted tokens for ${e}`),t}catch(t){return c.error(`[KeychainManager] Failed to delete tokens: ${t}`),!1}}isTokenExpired(e){return Date.now()>=e.expiresAt-3e5}async getSessionKey(e,t){let r=this.sessionKeyCache.get(e);if(r)return r;if(!t||t.length===0)return null;let i=await this.getDeviceId(),s=t.find(d=>d.deviceId===i);if(!s)return c.warn(`[KeychainManager] Device ${i} not found in encryptedKeys`),null;let o=await this.getDevicePrivateKey(),a=k.decryptSessionKey(s,o);return this.sessionKeyCache.set(e,a),c.info(`[KeychainManager] Decrypted and cached session key for ${e}`),a}createSessionKey(e){let t=k.generateSessionKey(),r=e.map(i=>{let s=k.encryptSessionKey(t,i.publicKey);return{deviceId:i.deviceId,encryptedKey:s.encryptedKey,ephemeralPublicKey:s.ephemeralPublicKey}});return c.info(`[KeychainManager] Created session key for ${e.length} devices`),{sessionKey:t,encryptedKeys:r}}cacheSessionKey(e,t){this.sessionKeyCache.set(e,t)}getCachedSessionKey(e){return this.sessionKeyCache.get(e)??null}getCachedSessionIds(){return Array.from(this.sessionKeyCache.keys())}clearSessionKey(e){this.sessionKeyCache.delete(e)}clearAllSessionKeys(){this.sessionKeyCache.clear()}getIsRegistered(){return this.isRegistered}setIsRegistered(e){this.isRegistered=e}getDeviceName(){return de.hostname()||"CLI Client"}getDevicePlatform(){let e=de.platform();return e==="darwin"?"MACOS":e==="linux"?"LINUX":e==="win32"?"WINDOWS":"CLI"}async clearAllData(){await this.deleteDeviceIdentity(),await this.deleteTokens("development"),await this.deleteTokens("production"),this.sessionKeyCache.clear(),this.isRegistered=!1,c.info("[KeychainManager] Cleared all data")}},g=B.getInstance()});var Ge={};Ne(Ge,{KeychainError:()=>K,KeychainManager:()=>B,keychainManager:()=>g});var P=D(()=>{"use strict";ze()});var Yt={};Ne(Yt,{AgentType:()=>et,AppSyncClient:()=>ee,AuthService:()=>J,CryptoError:()=>U,CryptoService:()=>H,DeliveryStatus:()=>Ze,ENCRYPTION_VERSION:()=>be,EventSource:()=>Ee,EventType:()=>Qe,KeychainError:()=>K,KeychainManager:()=>B,Logger:()=>N,SessionStatus:()=>le,authService:()=>R,createLogger:()=>ge,cryptoService:()=>k,errorWasBeaconed:()=>re,fireAuthCompletedBeacon:()=>te,fireAuthFailedBeacon:()=>v,getConfig:()=>f,getEnvironment:()=>b,getErrorReason:()=>Te,keychainManager:()=>g,loadConfig:()=>ce,logger:()=>c,markErrorBeaconed:()=>I,mutations:()=>T,normalizeSnapshot:()=>Re,parseInteractivePrompt:()=>pt,prepareSessionEncryption:()=>ue,queries:()=>O,registerDeviceEncryptionKey:()=>Oe,rekeySessionForNewDevices:()=>W,resumeOrCreateSession:()=>_e,runAuthCli:()=>pe,startDeviceKeyWatcher:()=>Pe,subscriptions:()=>V});module.exports=wt(Yt);P();G();var Q=m(require("ws")),Z=require("uuid");q();$();P();var Ye=m(require("dns")),Xe=m(require("fs"));if(Ct())try{Ye.setDefaultResultOrder("ipv4first")}catch{}function Ct(){if(process.platform!=="linux")return!1;try{let n=Xe.readFileSync("/proc/sys/kernel/osrelease","utf8");return/microsoft|wsl/i.test(n)}catch{return!1}}async function j(n,e,t){try{return await fetch(n,e)}catch(r){let i=r?.cause?.code,s=r?.cause?.message,o=i||s||r?.message||"unknown",a=Kt(i),d=t?`${t}: `:"",l=`Node ${process.version} on ${process.platform}`,y=[`${d}Cannot reach ${n}`,` Underlying error: ${o}`];a&&y.push(` Suggested fix: ${a}`),y.push(` Platform: ${l}`);let u=new Error(y.join(`
6
- `));throw u.cause=r,u}}function Kt(n){if(!n)return null;switch(n){case"ENOTFOUND":case"EAI_AGAIN":return'DNS resolution failed. On WSL Ubuntu, check /etc/resolv.conf, or try running with NODE_OPTIONS="--dns-result-order=ipv4first".';case"ETIMEDOUT":case"ECONNREFUSED":case"ECONNRESET":case"EHOSTUNREACH":case"ENETUNREACH":return`Network unreachable. On WSL Ubuntu, try NODE_OPTIONS="--dns-result-order=ipv4first" (WSL's IPv6 is often broken). If behind a corporate proxy, set HTTPS_PROXY.`;case"CERT_HAS_EXPIRED":case"CERT_NOT_YET_VALID":return"TLS certificate time error \u2014 likely system clock drift. On WSL, run `sudo hwclock -s`, or shut down WSL from PowerShell with `wsl --shutdown` and restart.";case"UNABLE_TO_GET_ISSUER_CERT_LOCALLY":case"SELF_SIGNED_CERT_IN_CHAIN":case"UNABLE_TO_VERIFY_LEAF_SIGNATURE":case"DEPTH_ZERO_SELF_SIGNED_CERT":return"Corporate HTTPS proxy detected \u2014 the TLS cert is not trusted by Node. Set NODE_EXTRA_CA_CERTS=/path/to/corporate-ca.pem, or configure HTTPS_PROXY if a proxy is required.";default:return null}}var O={getSession:`
1
+ "use strict";var Ar=Object.create;var we=Object.defineProperty;var Rr=Object.getOwnPropertyDescriptor;var Ir=Object.getOwnPropertyNames;var xr=Object.getPrototypeOf,Cr=Object.prototype.hasOwnProperty;var b=(r,e)=>()=>(r&&(e=r(r=0)),e);var ce=(r,e)=>{for(var t in e)we(r,t,{get:e[t],enumerable:!0})},ht=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Ir(e))!Cr.call(r,i)&&i!==t&&we(r,i,{get:()=>e[i],enumerable:!(n=Rr(e,i))||n.enumerable});return r};var S=(r,e,t)=>(t=r!=null?Ar(xr(r)):{},ht(e||!r||!r.__esModule?we(t,"default",{value:r,enumerable:!0}):t,r)),vt=r=>ht(we({},"__esModule",{value:!0}),r);function _r(r,e){if(e instanceof Error){let t={name:e.name,message:e.message};e.stack&&(t.stack=e.stack);for(let n of Object.keys(e))n in t||(t[n]=e[n]);return t}return e}function Ue(r){return new V(r)}var Y,Se,St,wt,V,c,bt=b(()=>{"use strict";Y=S(require("fs")),Se=S(require("path")),St=S(require("os")),wt={debug:0,info:1,warn:2,error:3};V=class{constructor(e){this.name=e.name,this.logFile=e.logFile,this.level=e.level||"info",this.enableConsole=e.console??!1,this.logFile&&this.ensureLogDir()}ensureLogDir(){if(this.logFile){let e=Se.dirname(this.logFile);Y.existsSync(e)||Y.mkdirSync(e,{recursive:!0})}}shouldLog(e){return wt[e]>=wt[this.level]}formatMessage(e,t,n){let i=new Date().toISOString(),o=e.toUpperCase().padEnd(5),s=`[${i}] [${o}] [${this.name}] ${t}`;return n!==void 0&&(n instanceof Error?(s+=` ${n.name}: ${n.message}`,n.stack&&(s+=`
2
+ ${n.stack}`)):typeof n=="object"?s+=` ${JSON.stringify(n,_r)}`:s+=` ${n}`),s}log(e,t,n){if(!this.shouldLog(e))return;let i=this.formatMessage(e,t,n);if(this.logFile)try{Y.appendFileSync(this.logFile,i+`
3
+ `)}catch{}if(this.enableConsole)switch(e){case"error":console.error(i);break;case"warn":console.warn(i);break;default:console.log(i)}}debug(e,t){this.log("debug",e,t)}info(e,t){this.log("info",e,t)}warn(e,t){this.log("warn",e,t)}error(e,t){this.log("error",e,t)}setLevel(e){this.level=e}};c=new V({name:"codevibe-core",logFile:Se.join(St.tmpdir(),"codevibe-core.log"),level:"info"})});var $=b(()=>{"use strict";bt()});function Tr(r){for(let e of r)try{process.stderr.write(e+`
4
+ `)}catch{}}function Pr(){Le=Be.join(Et.homedir(),".codevibe");try{N.mkdirSync(Le,{recursive:!0,mode:448})}catch{}F="file"}function Dr(){if(F!==null||Me!==null)return;let optedIn=process.env.CODEVIBE_ALLOW_FILE_KEYCHAIN==="1";if(optedIn){Tr(["","\u26A0 CodeVibe: file-based credential storage selected (CODEVIBE_ALLOW_FILE_KEYCHAIN=1).","\u26A0 Location: ~/.codevibe/ (directory 0700, files 0600)","\u26A0 Trust level: equivalent to ~/.ssh/id_rsa \u2014 weaker than OS keyring.","\u26A0 To use the OS keyring instead, unset CODEVIBE_ALLOW_FILE_KEYCHAIN and","\u26A0 install libsecret-1-0 + a running keyring daemon (Linux) or use the","\u26A0 native Keychain (macOS) / Credential Manager (Windows).",""]),c.warn("[keychain-backend] Using file-based storage at ~/.codevibe (CODEVIBE_ALLOW_FILE_KEYCHAIN=1 explicit opt-in)"),Pr();return}let keytarLoadError=null;try{let nodeRequire=eval("require");D=nodeRequire("keytar")}catch(r){keytarLoadError=r instanceof Error?r.message:String(r),D=null}if(D){F="keytar",c.info("[keychain-backend] Using keytar (OS-native keyring)");return}Me=new be(["CodeVibe could not load the OS-native keyring (keytar).",`Reason: ${keytarLoadError??"unknown"}`,"","Options to fix this:"," 1. (Linux) Install libsecret and a keyring daemon:"," sudo apt install libsecret-1-0 gnome-keyring"," Then unlock the keyring for your user session.",""," 2. (Headless / CI / Docker) Opt in to file-based credential"," storage at ~/.codevibe/ (0600 files). This is equivalent"," in trust to ~/.ssh/id_rsa \u2014 not the OS keyring:"," export CODEVIBE_ALLOW_FILE_KEYCHAIN=1"].join(`
5
+ `))}function Kr(r){return r.replace(/[^a-zA-Z0-9._-]/g,"_")}function kt(r){return Be.join(Le,`${Kr(r)}.json`)}function We(r){try{let e=N.readFileSync(kt(r),"utf-8"),t=JSON.parse(e);return t&&typeof t=="object"?t:{}}catch{return{}}}function At(r,e){let t=kt(r);N.writeFileSync(t,JSON.stringify(e,null,2),{mode:384});try{N.chmodSync(t,384)}catch{}}function Ve(){if(Dr(),F===null)throw Me??new be("Keychain backend not initialized")}async function Fe(r,e){return Ve(),F==="keytar"&&D?D.getPassword(r,e):We(r)[e]??null}async function je(r,e,t){if(Ve(),F==="keytar"&&D){await D.setPassword(r,e,t);return}let n=We(r);n[e]=t,At(r,n)}async function qe(r,e){if(Ve(),F==="keytar"&&D)return D.deletePassword(r,e);let t=We(r);return e in t?(delete t[e],At(r,t),!0):!1}var Et,Be,N,be,F,D,Le,Me,Rt=b(()=>{"use strict";Et=S(require("os")),Be=S(require("path")),N=S(require("fs"));$();be=class extends Error{constructor(e){super(e),this.name="KeychainBackendUnavailableError"}},F=null,D=null,Le="",Me=null});var T,j,Ge,$r,X,I,It=b(()=>{"use strict";T=S(require("crypto")),j=class extends Error{constructor(e){super(e),this.name="CryptoError"}},Ge=1,$r="CodeVibe E2E v1",X=class r{constructor(){}static getInstance(){return r.instance||(r.instance=new r),r.instance}generateKeyPair(){let e=T.createECDH("prime256v1");e.generateKeys();let n=e.getPublicKey().subarray(1).toString("base64");return{privateKey:e.getPrivateKey().toString("base64"),publicKey:n}}generateSessionKey(){return T.randomBytes(32).toString("base64")}deriveSharedKey(e,t){try{let n=T.createECDH("prime256v1"),i=Buffer.from(e,"base64");n.setPrivateKey(i);let o=Buffer.concat([Buffer.from([4]),Buffer.from(t,"base64")]),s=n.computeSecret(o),a=T.hkdfSync("sha256",s,Buffer.alloc(0),Buffer.from($r,"utf8"),32);return Buffer.from(a)}catch(n){throw new j(`Failed to derive shared key: ${n}`)}}encryptSessionKey(e,t){let n=this.generateKeyPair(),i=this.deriveSharedKey(n.privateKey,t),o=Buffer.from(e,"base64");return{encryptedKey:this.encrypt(o,i).toString("base64"),ephemeralPublicKey:n.publicKey}}decryptSessionKey(e,t){let n=this.deriveSharedKey(t,e.ephemeralPublicKey),i=Buffer.from(e.encryptedKey,"base64");return this.decrypt(i,n).toString("base64")}encryptContent(e,t){let n=Buffer.from(t,"base64"),i=Buffer.from(e,"utf8");return this.encrypt(i,n).toString("base64")}decryptContent(e,t){let n=Buffer.from(t,"base64"),i=Buffer.from(e,"base64");return this.decrypt(i,n).toString("utf8")}encryptMetadata(e,t){let n=JSON.stringify(e);return this.encryptContent(n,t)}decryptMetadata(e,t){let n=this.decryptContent(e,t);return JSON.parse(n)}encryptData(e,t){let n=Buffer.from(t,"base64");return this.encrypt(e,n)}decryptData(e,t){let n=Buffer.from(t,"base64");return this.decrypt(e,n)}encrypt(e,t){let n=T.randomBytes(12),i=T.createCipheriv("aes-256-gcm",t,n),o=Buffer.concat([i.update(e),i.final()]),s=i.getAuthTag();return Buffer.concat([n,o,s])}decrypt(e,t){let n=e.subarray(0,12),i=e.subarray(e.length-16),o=e.subarray(12,e.length-16),s=T.createDecipheriv("aes-256-gcm",t,n);s.setAuthTag(i);try{return Buffer.concat([s.update(o),s.final()])}catch{throw new j("Decryption failed: Invalid ciphertext or authentication tag")}}serializePrivateKey(e){return e}deserializePrivateKey(e){return e}},I=X.getInstance()});var de=b(()=>{"use strict";It()});function x(){let r=process.env.ENVIRONMENT;return r==="development"||r==="production"?r:"production"}function ke(r){let e=r||x();return Ee={...q[e],aws:{...q[e].aws,region:process.env.AWS_REGION||q[e].aws.region,appsyncUrl:process.env.APPSYNC_URL||q[e].aws.appsyncUrl,cognitoUserPoolId:process.env.COGNITO_USER_POOL_ID||q[e].aws.cognitoUserPoolId,cognitoClientId:process.env.COGNITO_CLIENT_ID||q[e].aws.cognitoClientId,cognitoDomain:process.env.COGNITO_DOMAIN||q[e].aws.cognitoDomain}},xt=!0,Ee}function k(){return(!xt||!Ee)&&ke(),Ee}var le,ue,q,Ee,xt,Ct=b(()=>{"use strict";le=S(require("os")),ue=S(require("path")),q={development:{environment:"development",aws:{region:"us-east-1",appsyncUrl:"https://te6rjr37sbfpjc4fiunmb2tgy4.appsync-api.us-east-1.amazonaws.com/graphql",cognitoUserPoolId:"us-east-1_yVwWDPvvJ",cognitoClientId:"e9r5apv6v5uui3l928r2ris0r",cognitoDomain:"codevibe-development.auth.us-east-1.amazoncognito.com"},keychain:{serviceName:"ai.quantiya.app.codevibe"},server:{port:3456,host:"127.0.0.1",dynamicPort:!0},claude:{command:"claude",defaultTimeout:6e4},codex:{command:"codex",defaultTimeout:6e4,sessionsDir:ue.default.join(le.default.homedir(),".codex","sessions"),approvalTimeoutMs:5e3},gemini:{command:"gemini",defaultTimeout:6e4,transcriptDir:ue.default.join(le.default.homedir(),".gemini","tmp")}},production:{environment:"production",aws:{region:"us-east-1",appsyncUrl:"https://jwhyxq4sgrgcdosewp5k4ns5ca.appsync-api.us-east-1.amazonaws.com/graphql",cognitoUserPoolId:"us-east-1_mNRO0j5og",cognitoClientId:"5p04dbc9ojptc5r8n7605fg78f",cognitoDomain:"codevibe-production.auth.us-east-1.amazoncognito.com"},keychain:{serviceName:"ai.quantiya.app.codevibe"},server:{port:3456,host:"127.0.0.1",dynamicPort:!0},claude:{command:"claude",defaultTimeout:6e4},codex:{command:"codex",defaultTimeout:6e4,sessionsDir:ue.default.join(le.default.homedir(),".codex","sessions"),approvalTimeoutMs:5e3},gemini:{command:"gemini",defaultTimeout:6e4,transcriptDir:ue.default.join(le.default.homedir(),".gemini","tmp")}}},Ee=null,xt=!1});var Q=b(()=>{"use strict";Ct()});var Ae,_t,K,He,Nr,G,y,Tt=b(()=>{"use strict";Ae=S(require("os")),_t=require("uuid");Rt();de();Q();$();K=class extends Error{constructor(e){super(e),this.name="KeychainError"}},He="device-identity",Nr="tokens-",G=class r{constructor(){this.deviceIdentity=null;this.sessionKeyCache=new Map;this.isRegistered=!1;this._serviceName=null}get serviceName(){return this._serviceName||(this._serviceName=k().keychain.serviceName),this._serviceName}static getInstance(){return r.instance||(r.instance=new r),r.instance}async getDeviceIdentity(){if(this.deviceIdentity)return this.deviceIdentity;let e=await Fe(this.serviceName,He);return e?(this.deviceIdentity=JSON.parse(e),c.info(`[KeychainManager] Loaded device identity: ${this.deviceIdentity.deviceId}`),this.deviceIdentity):null}async setDeviceIdentity(e){try{await je(this.serviceName,He,JSON.stringify(e)),this.deviceIdentity=e,c.info(`[KeychainManager] Saved device identity: ${e.deviceId}`)}catch(t){throw c.error(`[KeychainManager] Failed to save device identity: ${t}`),new K(`Failed to save device identity: ${t}`)}}async getOrCreateDeviceIdentity(){let e=await this.getDeviceIdentity();if(e)return e;let t=I.generateKeyPair();return e={deviceId:(0,_t.v4)().toUpperCase(),privateKey:t.privateKey,publicKey:t.publicKey,createdAt:new Date().toISOString()},await this.setDeviceIdentity(e),c.info(`[KeychainManager] Generated new device identity: ${e.deviceId}`),e}async getDeviceId(){return(await this.getOrCreateDeviceIdentity()).deviceId}async getDevicePublicKey(){return(await this.getOrCreateDeviceIdentity()).publicKey}async getDevicePrivateKey(){return(await this.getOrCreateDeviceIdentity()).privateKey}async hasDeviceIdentity(){return await this.getDeviceIdentity()!==null}async deleteDeviceIdentity(){try{await qe(this.serviceName,He),this.deviceIdentity=null,this.sessionKeyCache.clear(),this.isRegistered=!1,c.info("[KeychainManager] Deleted device identity")}catch(e){throw c.error(`[KeychainManager] Failed to delete device identity: ${e}`),new K(`Failed to delete device identity: ${e}`)}}getTokenAccount(e){return`${Nr}${e}`}async getTokens(e="production"){let t=await Fe(this.serviceName,this.getTokenAccount(e));if(!t)return null;let n=JSON.parse(t);return c.debug(`[KeychainManager] Loaded tokens for ${e}`),n}async setTokens(e,t="production"){try{await je(this.serviceName,this.getTokenAccount(t),JSON.stringify(e)),c.info(`[KeychainManager] Saved tokens for ${t}`,{userId:e.userId,email:e.email})}catch(n){throw c.error(`[KeychainManager] Failed to save tokens: ${n}`),new K(`Failed to save tokens: ${n}`)}}async deleteTokens(e="production"){try{let t=await qe(this.serviceName,this.getTokenAccount(e));return t&&c.info(`[KeychainManager] Deleted tokens for ${e}`),t}catch(t){return c.error(`[KeychainManager] Failed to delete tokens: ${t}`),!1}}isTokenExpired(e){return Date.now()>=e.expiresAt-3e5}async getSessionKey(e,t){let n=this.sessionKeyCache.get(e);if(n)return n;if(!t||t.length===0)return null;let i=await this.getDeviceId(),o=t.find(d=>d.deviceId===i);if(!o)return c.warn(`[KeychainManager] Device ${i} not found in encryptedKeys`),null;let s=await this.getDevicePrivateKey(),a=I.decryptSessionKey(o,s);return this.sessionKeyCache.set(e,a),c.info(`[KeychainManager] Decrypted and cached session key for ${e}`),a}createSessionKey(e){let t=I.generateSessionKey(),n=e.map(i=>{let o=I.encryptSessionKey(t,i.publicKey);return{deviceId:i.deviceId,encryptedKey:o.encryptedKey,ephemeralPublicKey:o.ephemeralPublicKey}});return c.info(`[KeychainManager] Created session key for ${e.length} devices`),{sessionKey:t,encryptedKeys:n}}cacheSessionKey(e,t){this.sessionKeyCache.set(e,t)}getCachedSessionKey(e){return this.sessionKeyCache.get(e)??null}getCachedSessionIds(){return Array.from(this.sessionKeyCache.keys())}clearSessionKey(e){this.sessionKeyCache.delete(e)}clearAllSessionKeys(){this.sessionKeyCache.clear()}getIsRegistered(){return this.isRegistered}setIsRegistered(e){this.isRegistered=e}getDeviceName(){return Ae.hostname()||"CLI Client"}getDevicePlatform(){let e=Ae.platform();return e==="darwin"?"MACOS":e==="linux"?"LINUX":e==="win32"?"WINDOWS":"CLI"}async clearAllData(){await this.deleteDeviceIdentity(),await this.deleteTokens("development"),await this.deleteTokens("production"),this.sessionKeyCache.clear(),this.isRegistered=!1,c.info("[KeychainManager] Cleared all data")}},y=G.getInstance()});var Pt={};ce(Pt,{KeychainError:()=>K,KeychainManager:()=>G,keychainManager:()=>y});var U=b(()=>{"use strict";Tt()});function Ur(){if(process.platform!=="linux")return!1;try{let r=Kt.readFileSync("/proc/sys/kernel/osrelease","utf8");return/microsoft|wsl/i.test(r)}catch{return!1}}async function Z(r,e,t){try{return await fetch(r,e)}catch(n){let i=n?.cause?.code,o=n?.cause?.message,s=i||o||n?.message||"unknown",a=Lr(i),d=t?`${t}: `:"",l=`Node ${process.version} on ${process.platform}`,m=[`${d}Cannot reach ${r}`,` Underlying error: ${s}`];a&&m.push(` Suggested fix: ${a}`),m.push(` Platform: ${l}`);let u=new Error(m.join(`
6
+ `));throw u.cause=n,u}}function Lr(r){if(!r)return null;switch(r){case"ENOTFOUND":case"EAI_AGAIN":return'DNS resolution failed. On WSL Ubuntu, check /etc/resolv.conf, or try running with NODE_OPTIONS="--dns-result-order=ipv4first".';case"ETIMEDOUT":case"ECONNREFUSED":case"ECONNRESET":case"EHOSTUNREACH":case"ENETUNREACH":return`Network unreachable. On WSL Ubuntu, try NODE_OPTIONS="--dns-result-order=ipv4first" (WSL's IPv6 is often broken). If behind a corporate proxy, set HTTPS_PROXY.`;case"CERT_HAS_EXPIRED":case"CERT_NOT_YET_VALID":return"TLS certificate time error \u2014 likely system clock drift. On WSL, run `sudo hwclock -s`, or shut down WSL from PowerShell with `wsl --shutdown` and restart.";case"UNABLE_TO_GET_ISSUER_CERT_LOCALLY":case"SELF_SIGNED_CERT_IN_CHAIN":case"UNABLE_TO_VERIFY_LEAF_SIGNATURE":case"DEPTH_ZERO_SELF_SIGNED_CERT":return"Corporate HTTPS proxy detected \u2014 the TLS cert is not trusted by Node. Set NODE_EXTRA_CA_CERTS=/path/to/corporate-ca.pem, or configure HTTPS_PROXY if a proxy is required.";default:return null}}var Dt,Kt,Je=b(()=>{"use strict";Dt=S(require("dns")),Kt=S(require("fs"));if(Ur())try{Dt.setDefaultResultOrder("ipv4first")}catch{}});var H,C,ee,ze=b(()=>{"use strict";H={getSession:`
7
7
  query GetSession($sessionId: ID!) {
8
8
  getSession(sessionId: $sessionId) {
9
9
  sessionId
@@ -66,19 +66,7 @@ ${r.stack}`)):typeof r=="object"?o+=` ${JSON.stringify(r,kt)}`:o+=` ${r}`),o}log
66
66
  lastUsedAt
67
67
  }
68
68
  }
69
- `,listSessions:`
70
- query ListSessions($userId: ID!, $limit: Int, $nextToken: String) {
71
- listSessions(userId: $userId, limit: $limit, nextToken: $nextToken) {
72
- items {
73
- sessionId
74
- agentType
75
- status
76
- lastHeartbeatAt
77
- }
78
- nextToken
79
- }
80
- }
81
- `},T={createSession:`
69
+ `},C={createSession:`
82
70
  mutation CreateSession($input: CreateSessionInput!) {
83
71
  createSession(input: $input) {
84
72
  sessionId
@@ -155,7 +143,37 @@ ${r.stack}`)):typeof r=="object"?o+=` ${JSON.stringify(r,kt)}`:o+=` ${r}`),o}log
155
143
  expiresAt
156
144
  }
157
145
  }
158
- `},V={onEventCreated:`
146
+ `,updateAvailableAgents:`
147
+ mutation UpdateAvailableAgents($agents: [AgentType!]!) {
148
+ updateAvailableAgents(agents: $agents) {
149
+ userId
150
+ availableAgents
151
+ orchestrationEnabledDefault
152
+ reviewerSeats {
153
+ seatId
154
+ role
155
+ agent
156
+ modelHint
157
+ }
158
+ updatedAt
159
+ }
160
+ }
161
+ `,updateReviewerPolicy:`
162
+ mutation UpdateReviewerPolicy($input: UpdateReviewerPolicyInput!) {
163
+ updateReviewerPolicy(input: $input) {
164
+ userId
165
+ availableAgents
166
+ orchestrationEnabledDefault
167
+ reviewerSeats {
168
+ seatId
169
+ role
170
+ agent
171
+ modelHint
172
+ }
173
+ updatedAt
174
+ }
175
+ }
176
+ `},ee={onEventCreated:`
159
177
  subscription OnEventCreated($sessionId: ID!) {
160
178
  onEventCreated(sessionId: $sessionId) {
161
179
  eventId
@@ -194,7 +212,11 @@ ${r.stack}`)):typeof r=="object"?o+=` ${JSON.stringify(r,kt)}`:o+=` ${r}`),o}log
194
212
  lastUsedAt
195
213
  }
196
214
  }
197
- `};var Qe=(a=>(a.USER_PROMPT="USER_PROMPT",a.ASSISTANT_RESPONSE="ASSISTANT_RESPONSE",a.TOOL_USE="TOOL_USE",a.NOTIFICATION="NOTIFICATION",a.INTERACTIVE_PROMPT="INTERACTIVE_PROMPT",a.PROMPT_RESPONSE="PROMPT_RESPONSE",a.REASONING="REASONING",a))(Qe||{}),Ee=(t=>(t.DESKTOP="DESKTOP",t.MOBILE="MOBILE",t))(Ee||{}),Ze=(r=>(r.SENT="SENT",r.DELIVERED="DELIVERED",r.EXECUTED="EXECUTED",r))(Ze||{});var le=(r=>(r.ACTIVE="ACTIVE",r.INACTIVE="INACTIVE",r.PAUSED="PAUSED",r))(le||{}),et=(r=>(r.CLAUDE="CLAUDE",r.GEMINI="GEMINI",r.CODEX="CODEX",r))(et||{});var x={urgentMaxAttempts:10,baseDelayMs:1e3,maxDelayMs:6e4,backoffMultiplier:2,persistentDelayMs:300*1e3},ee=class n{constructor(){this.authenticated=!1;this.currentUserId=null;this.currentEmail=null;this.tokens=null;this.activeSubscriptions=new Map;this.pendingRefresh=null;this.lastRefreshFailureAt=null;this.deviceKeyWatcher=null;this.heartbeatTimers=new Map;this.environment=b(),c.info("[AppSyncClient] Initialized",{environment:this.environment})}static{this.REFRESH_BACKOFF_MS=3e4}getCurrentUserId(){if(!this.currentUserId)throw new Error("Not authenticated. Call authenticateWithStoredTokens() first.");return this.currentUserId}getCurrentUserEmail(){return this.currentEmail}async authenticateWithStoredTokens(){try{let e=await g.getTokens(this.environment);if(!e)return c.debug("[AppSyncClient] No stored tokens found"),!1;if(c.info("[AppSyncClient] Found stored OAuth tokens",{userId:e.userId,email:e.email,expired:g.isTokenExpired(e)}),g.isTokenExpired(e)){if(c.info("[AppSyncClient] Tokens expired, attempting refresh..."),!await this.refreshTokens(e))return c.warn("[AppSyncClient] Token refresh failed"),!1}else this.tokens=e;return this.currentUserId=this.tokens.userId,this.currentEmail=this.tokens.email,this.authenticated=!0,c.info("[AppSyncClient] Authenticated successfully",{userId:this.currentUserId,email:this.currentEmail}),!0}catch(e){return c.error("[AppSyncClient] Authentication failed:",e),!1}}async refreshTokens(e){if(this.pendingRefresh)return this.pendingRefresh;if(this.lastRefreshFailureAt!==null&&Date.now()-this.lastRefreshFailureAt<n.REFRESH_BACKOFF_MS)return!1;this.pendingRefresh=this.performRefresh(e);try{return await this.pendingRefresh}finally{this.pendingRefresh=null}}async performRefresh(e){let t=await this.callCognitoRefresh(e.refreshToken);if(t!==null)return this.applyRefreshedTokens(e,t);let r=null;try{r=await g.getTokens(this.environment)}catch(i){c.warn("[AppSyncClient] Failed to re-read tokens from storage during refresh recovery",{error:i instanceof Error?i.message:String(i)})}if(r&&r.refreshToken&&r.refreshToken!==e.refreshToken){c.info("[AppSyncClient] In-memory refresh token rejected; retrying with storage-backed token (likely out-of-band re-auth)");let i=await this.callCognitoRefresh(r.refreshToken);if(i!==null)return this.applyRefreshedTokens(r,i)}return this.lastRefreshFailureAt=Date.now(),!1}async callCognitoRefresh(e){try{let t=f(),r=`https://${t.aws.cognitoDomain}/oauth2/token`,i=new URLSearchParams({grant_type:"refresh_token",client_id:t.aws.cognitoClientId,refresh_token:e}),s=await j(r,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:i.toString()},"Token refresh");return s.ok?await s.json():(c.error("[AppSyncClient] Token refresh failed",{status:s.status}),null)}catch(t){return c.error("[AppSyncClient] Token refresh error:",t),null}}async applyRefreshedTokens(e,t){let r={...e,accessToken:t.access_token,idToken:t.id_token,expiresAt:Date.now()+t.expires_in*1e3};this.tokens=r,this.lastRefreshFailureAt=null;try{await g.setTokens(r,this.environment),c.info("[AppSyncClient] Tokens refreshed",{expiresAt:new Date(r.expiresAt).toISOString()})}catch(i){c.warn("[AppSyncClient] Tokens refreshed but persistence failed; daemon keeps using fresh tokens in memory. A restart while persistence is still broken would lose them.",{error:i instanceof Error?i.message:String(i),expiresAt:new Date(r.expiresAt).toISOString()})}return!0}isAuthenticated(){return this.authenticated}signOut(){this.authenticated=!1,this.tokens=null,this.currentUserId=null,this.currentEmail=null,this.cleanupSubscriptions(),c.info("[AppSyncClient] Signed out")}async graphqlRequest(e,t,r=!1){let i=f();if(!this.tokens?.idToken)throw new Error('Not authenticated. Run "codevibe login" first.');let s={"Content-Type":"application/json",Authorization:this.tokens.idToken},o=await j(i.aws.appsyncUrl,{method:"POST",headers:s,body:JSON.stringify({query:e,variables:t})},"AppSync GraphQL request"),a=await o.json();if(o.status===401&&!r&&this.tokens){if(c.info("[AppSyncClient] 401 Unauthorized, refreshing token..."),await this.refreshTokens(this.tokens))return this.graphqlRequest(e,t,!0);throw new Error("Token expired and refresh failed")}if(!o.ok)throw new Error(`GraphQL request failed: ${o.status}`);if(a.errors?.length)throw new Error(`GraphQL error: ${a.errors[0].message}`);return a}async createSession(e){let t={...e,metadata:e.metadata?JSON.stringify(e.metadata):void 0},r=await this.graphqlRequest(T.createSession,{input:t});return c.info("[AppSyncClient] Session created",{sessionId:r.data.createSession.sessionId}),r.data.createSession}async updateSession(e){let t={...e,metadata:e.metadata?JSON.stringify(e.metadata):void 0},r=await this.graphqlRequest(T.updateSession,{input:t});return c.debug("[AppSyncClient] Session updated",{sessionId:r.data.updateSession.sessionId}),r.data.updateSession}async getSession(e){return(await this.graphqlRequest(O.getSession,{sessionId:e})).data.getSession}async createEvent(e){let t={...e,metadata:e.metadata?JSON.stringify(e.metadata):void 0},r=await this.graphqlRequest(T.createEvent,{input:t});return c.debug("[AppSyncClient] Event created",{eventId:r.data.createEvent.eventId,type:r.data.createEvent.type}),r.data.createEvent}async updateEventStatus(e){return(await this.graphqlRequest(T.updateEventStatus,{input:e})).data.updateEventStatus}async listEvents(e,t,r){return(await this.graphqlRequest(O.listEvents,{sessionId:e,source:t,limit:r})).data.listEvents.items}async listSessions(e=100){if(!this.currentUserId)throw new Error("Not authenticated");let t=[],r=null;do{let s=(await this.graphqlRequest(O.listSessions,{userId:this.currentUserId,limit:e,nextToken:r})).data?.listSessions;s?.items&&t.push(...s.items),r=s?.nextToken??null}while(r);return t}async sweepOrphanSessions(e){let t=e.staleThresholdMs??9e5,r=new Set(e.excludeSessionIds??[]),i=Date.now(),s;try{s=await this.listSessions()}catch(a){return c.warn("[AppSyncClient] OrphanSweep: listSessions failed, skipping sweep",{agentType:e.agentType,error:a instanceof Error?a.message:String(a)}),0}let o=0;for(let a of s){if(a.agentType!==e.agentType||a.status!=="ACTIVE"||r.has(a.sessionId)||!a.lastHeartbeatAt)continue;let d=i-new Date(a.lastHeartbeatAt).getTime();if(!(d<t)){c.warn("[AppSyncClient] OrphanSweep: marking stale session INACTIVE",{sessionId:a.sessionId,agentType:a.agentType,lastHeartbeatAt:a.lastHeartbeatAt,heartbeatAgeMinutes:Math.round(d/6e4)});try{await this.updateSession({sessionId:a.sessionId,status:"INACTIVE"}),o++}catch(l){c.warn("[AppSyncClient] OrphanSweep: updateSession failed, leaving row as-is",{sessionId:a.sessionId,error:l instanceof Error?l.message:String(l)})}}}return o>0&&c.info("[AppSyncClient] OrphanSweep complete",{agentType:e.agentType,swept:o}),o}async listUserDeviceKeys(){return(await this.graphqlRequest(O.listUserDeviceKeys,{})).data.listUserDeviceKeys||[]}async registerDeviceKey(e,t,r,i){let s={deviceId:e,publicKey:t,platform:r,deviceName:i};await this.graphqlRequest(T.registerDeviceKey,{input:s}),c.info("[AppSyncClient] Device key registered",{deviceId:e,platform:r})}async grantSessionKey(e){await this.graphqlRequest(T.grantSessionKey,{input:e}),c.info("[AppSyncClient] Session key granted",{sessionId:e.sessionId,deviceId:e.deviceId})}async getAttachmentDownloadUrl(e){return(await this.graphqlRequest(T.getAttachmentDownloadUrl,{s3Key:e})).data.getAttachmentDownloadUrl}subscribeToEvents(e,t,r){c.info("[AppSyncClient] Subscribing to events",{sessionId:e});let i=this.activeSubscriptions.get(e);i&&(this.cleanupSubscriptionState(i),this.activeSubscriptions.delete(e));let s={ws:null,subscriptionId:(0,Z.v4)(),sessionId:e,onEvent:t,onError:r,reconnectAttempts:0,isReconnecting:!1,destroyed:!1};return this.activeSubscriptions.set(e,s),this.createSubscription(s),()=>{this.cleanupSubscriptionState(s),this.activeSubscriptions.delete(e)}}buildRealtimeUrl(){let e=f(),t=e.aws.appsyncUrl.replace("https://","wss://").replace("appsync-api","appsync-realtime-api"),r={host:new URL(e.aws.appsyncUrl).host};this.tokens?.idToken&&(r.Authorization=this.tokens.idToken);let i=Buffer.from(JSON.stringify(r)).toString("base64"),s=Buffer.from(JSON.stringify({})).toString("base64");return`${t}?header=${i}&payload=${s}`}createSubscription(e){let{sessionId:t,subscriptionId:r,onEvent:i,onError:s}=e;try{let o=this.buildRealtimeUrl(),a=new Q.default(o,["graphql-ws"]);a.on("open",()=>{c.info("[AppSyncClient] WebSocket connected",{sessionId:t}),a.send(JSON.stringify({type:"connection_init"}))}),a.on("message",d=>{try{let l=JSON.parse(d.toString());switch(l.type){case"connection_ack":this.sendSubscriptionStart(a,e);break;case"start_ack":c.info("[AppSyncClient] Subscription started",{sessionId:t}),e.isReconnecting=!1,e.reconnectAttempts=0,this.startHeartbeat(t);break;case"data":this.resetKeepAliveTimer(e);let y=l.payload?.data?.onEventCreated;y&&y.source==="MOBILE"&&i(y);break;case"ka":this.resetKeepAliveTimer(e);break;case"error":let u=l.payload?.errors?.[0]?.message||"Unknown error";this.handleSubscriptionError(e,new Error(u));break}}catch(l){c.error("[AppSyncClient] Failed to parse message",{error:l})}}),a.on("error",d=>{c.error("[AppSyncClient] WebSocket error",{sessionId:t,error:d.message}),this.handleSubscriptionError(e,d)}),a.on("close",(d,l)=>{c.info("[AppSyncClient] WebSocket closed",{sessionId:t,code:d}),e.keepAliveTimer&&clearTimeout(e.keepAliveTimer),!e.destroyed&&this.activeSubscriptions.get(t)===e&&this.handleSubscriptionError(e,new Error(`WebSocket closed: ${d}`))}),e.ws=a,this.resetKeepAliveTimer(e)}catch(o){this.handleSubscriptionError(e,o)}}sendSubscriptionStart(e,t){let r=f(),{sessionId:i,subscriptionId:s}=t,o={host:new URL(r.aws.appsyncUrl).host};this.tokens?.idToken&&(o.Authorization=this.tokens.idToken),e.send(JSON.stringify({id:s,type:"start",payload:{data:JSON.stringify({query:V.onEventCreated,variables:{sessionId:i}}),extensions:{authorization:o}}}))}resetKeepAliveTimer(e){e.keepAliveTimer&&clearTimeout(e.keepAliveTimer),e.keepAliveTimer=setTimeout(()=>{this.handleSubscriptionError(e,new Error("Keep-alive timeout"))},300*1e3)}handleSubscriptionError(e,t){let{sessionId:r,onError:i}=e;if(e.isReconnecting||!this.activeSubscriptions.has(r))return;e.isReconnecting=!0,e.reconnectAttempts++,this.stopHeartbeat(r);let s=e.reconnectAttempts<=x.urgentMaxAttempts,o;if(s?o=Math.min(x.baseDelayMs*Math.pow(x.backoffMultiplier,e.reconnectAttempts-1),x.maxDelayMs):(o=x.persistentDelayMs,e.reconnectAttempts===x.urgentMaxAttempts+1&&c.info("[AppSyncClient] Switching to persistent reconnect (every 5min)",{sessionId:r})),c.info("[AppSyncClient] Scheduling reconnect",{sessionId:r,attempt:e.reconnectAttempts,phase:s?"urgent":"persistent",delayMs:o}),e.ws){try{e.ws.close(1e3)}catch{}e.ws=null}e.keepAliveTimer&&clearTimeout(e.keepAliveTimer),e.reconnectTimer=setTimeout(async()=>{if(e.isReconnecting=!1,e.destroyed||this.activeSubscriptions.get(r)!==e){c.info("[AppSyncClient] Reconnect skipped \u2014 state is no longer canonical",{sessionId:r});return}try{let a=await g.getTokens(this.environment);a&&(g.isTokenExpired(a)?await this.refreshTokens(a)&&c.info("[AppSyncClient] Tokens refreshed before reconnect",{sessionId:r}):this.tokens=a)}catch{c.warn("[AppSyncClient] Token refresh failed before reconnect, using existing tokens",{sessionId:r})}if(e.destroyed||this.activeSubscriptions.get(r)!==e){c.info("[AppSyncClient] Reconnect skipped after token refresh \u2014 state no longer canonical",{sessionId:r});return}e.subscriptionId=(0,Z.v4)(),this.createSubscription(e)},o)}cleanupSubscriptionState(e){if(e.destroyed=!0,e.reconnectTimer&&(clearTimeout(e.reconnectTimer),e.reconnectTimer=void 0),e.keepAliveTimer&&(clearTimeout(e.keepAliveTimer),e.keepAliveTimer=void 0),e.ws){try{e.ws.readyState===Q.default.OPEN&&e.ws.send(JSON.stringify({id:e.subscriptionId,type:"stop"}))}catch{}try{e.ws.close(1e3)}catch{}try{e.ws.removeAllListeners()}catch{}e.ws=null}}subscribeToDeviceKeyRegistered(e,t,r,i){c.info("[AppSyncClient] Subscribing to device key registrations",{userId:e}),this.deviceKeyWatcher&&this.stopDeviceKeyWatcherInternal();let s={userId:e,subscriptionId:(0,Z.v4)(),ws:null,onNewDevice:t,onReconnect:r,onError:i,reconnectAttempts:0,isReconnecting:!1,destroyed:!1};return this.deviceKeyWatcher=s,this.createDeviceKeyWatcherConnection(s),()=>{this.stopDeviceKeyWatcherInternal()}}stopDeviceKeyWatcher(){this.stopDeviceKeyWatcherInternal()}stopDeviceKeyWatcherInternal(){let e=this.deviceKeyWatcher;if(e){if(e.destroyed=!0,e.reconnectTimer&&(clearTimeout(e.reconnectTimer),e.reconnectTimer=void 0),e.keepAliveTimer&&(clearTimeout(e.keepAliveTimer),e.keepAliveTimer=void 0),e.ws){try{e.ws.readyState===Q.default.OPEN&&e.ws.send(JSON.stringify({id:e.subscriptionId,type:"stop"}))}catch{}try{e.ws.close(1e3)}catch{}try{e.ws.removeAllListeners()}catch{}e.ws=null}this.deviceKeyWatcher=null,c.info("[AppSyncClient] Device key watcher stopped")}}createDeviceKeyWatcherConnection(e){try{let t=this.buildRealtimeUrl(),r=new Q.default(t,["graphql-ws"]);r.on("open",()=>{c.info("[AppSyncClient] Device key watcher WebSocket connected",{userId:e.userId}),r.send(JSON.stringify({type:"connection_init"}))}),r.on("message",i=>{try{let s=JSON.parse(i.toString());switch(s.type){case"connection_ack":this.sendDeviceKeyWatcherStart(r,e);break;case"start_ack":c.info("[AppSyncClient] Device key watcher subscription started",{userId:e.userId});let o=e.isReconnecting;if(e.isReconnecting=!1,e.reconnectAttempts=0,o&&e.onReconnect)try{e.onReconnect()}catch(l){c.warn("[AppSyncClient] Device key watcher onReconnect handler threw",{error:l})}break;case"data":this.resetDeviceKeyWatcherKeepAlive(e);let a=s.payload?.data?.onDeviceKeyRegistered;if(a){c.info("[AppSyncClient] Device key registration observed",{userId:e.userId,newDeviceId:a.deviceId,platform:a.platform});try{e.onNewDevice(a)}catch(l){c.warn("[AppSyncClient] Device key watcher onNewDevice handler threw",{error:l})}}break;case"ka":this.resetDeviceKeyWatcherKeepAlive(e);break;case"error":let d=s.payload?.errors?.[0]?.message||"Unknown error";this.handleDeviceKeyWatcherError(e,new Error(d));break}}catch(s){c.error("[AppSyncClient] Failed to parse device key watcher message",{error:s})}}),r.on("error",i=>{c.error("[AppSyncClient] Device key watcher WebSocket error",{userId:e.userId,error:i.message}),this.handleDeviceKeyWatcherError(e,i)}),r.on("close",i=>{c.info("[AppSyncClient] Device key watcher WebSocket closed",{userId:e.userId,code:i}),e.keepAliveTimer&&clearTimeout(e.keepAliveTimer),!e.destroyed&&this.deviceKeyWatcher===e&&this.handleDeviceKeyWatcherError(e,new Error(`WebSocket closed: ${i}`))}),e.ws=r,this.resetDeviceKeyWatcherKeepAlive(e)}catch(t){this.handleDeviceKeyWatcherError(e,t)}}sendDeviceKeyWatcherStart(e,t){let r=f(),{userId:i,subscriptionId:s}=t,o={host:new URL(r.aws.appsyncUrl).host};this.tokens?.idToken&&(o.Authorization=this.tokens.idToken),e.send(JSON.stringify({id:s,type:"start",payload:{data:JSON.stringify({query:V.onDeviceKeyRegistered,variables:{userId:i}}),extensions:{authorization:o}}}))}resetDeviceKeyWatcherKeepAlive(e){e.keepAliveTimer&&clearTimeout(e.keepAliveTimer),e.keepAliveTimer=setTimeout(()=>{this.handleDeviceKeyWatcherError(e,new Error("Device key watcher keep-alive timeout"))},300*1e3)}handleDeviceKeyWatcherError(e,t){if(e.isReconnecting||e.destroyed||this.deviceKeyWatcher!==e)return;if(e.isReconnecting=!0,e.reconnectAttempts++,e.onError)try{e.onError(t)}catch{}if(e.ws){try{e.ws.removeAllListeners()}catch{}try{e.ws.close(1e3)}catch{}e.ws=null}e.keepAliveTimer&&(clearTimeout(e.keepAliveTimer),e.keepAliveTimer=void 0);let i=e.reconnectAttempts<=x.urgentMaxAttempts?Math.min(x.baseDelayMs*Math.pow(x.backoffMultiplier,e.reconnectAttempts-1),x.maxDelayMs):x.persistentDelayMs;c.warn("[AppSyncClient] Device key watcher reconnect scheduled",{userId:e.userId,attempts:e.reconnectAttempts,delayMs:i,error:t.message}),e.reconnectTimer=setTimeout(async()=>{if(e.isReconnecting=!1,e.destroyed||this.deviceKeyWatcher!==e){c.info("[AppSyncClient] Device key watcher reconnect skipped \u2014 state no longer canonical",{userId:e.userId});return}try{let s=await g.getTokens(this.environment);s&&(g.isTokenExpired(s)?await this.refreshTokens(s)&&c.info("[AppSyncClient] Tokens refreshed before device key watcher reconnect",{userId:e.userId}):this.tokens=s)}catch{c.warn("[AppSyncClient] Token refresh failed before device key watcher reconnect, using existing tokens",{userId:e.userId})}e.destroyed||this.deviceKeyWatcher!==e||(e.subscriptionId=(0,Z.v4)(),this.createDeviceKeyWatcherConnection(e))},i)}startHeartbeat(e,t=120*1e3){this.stopHeartbeat(e),this.sendHeartbeat(e);let r=setInterval(()=>{this.sendHeartbeat(e)},t);this.heartbeatTimers.set(e,r),c.info("[AppSyncClient] Heartbeat started",{sessionId:e,intervalMs:t})}stopHeartbeat(e){let t=this.heartbeatTimers.get(e);t&&(clearInterval(t),this.heartbeatTimers.delete(e),c.info("[AppSyncClient] Heartbeat stopped",{sessionId:e}))}async sendHeartbeat(e){try{await this.updateSession({sessionId:e,lastHeartbeatAt:new Date().toISOString()}),c.debug("[AppSyncClient] Heartbeat sent",{sessionId:e})}catch(t){c.warn("[AppSyncClient] Heartbeat failed",{sessionId:e,error:t})}}cleanupSubscriptions(){this.activeSubscriptions.forEach(e=>{this.cleanupSubscriptionState(e)}),this.activeSubscriptions.clear(),this.stopDeviceKeyWatcherInternal(),this.heartbeatTimers.forEach(e=>clearInterval(e)),this.heartbeatTimers.clear()}};var at=m(require("crypto")),ct=m(require("fs")),De=m(require("http")),dt=require("child_process");q();P();$();var tt=m(require("crypto")),rt=m(require("https")),nt=m(require("os")),Rt="G-GS74YEQTB8",_t="lAfOF6OxRzSQ-NsLBRjhAg",Pt="www.google-analytics.com",Ot=`/mp/collect?measurement_id=${Rt}&api_secret=${_t}`,Nt={port_in_use:"server_start",server_listen_failed:"server_start",browser_open_failed:"browser_open",login_timeout:"awaiting_callback",cognito_rejected:"awaiting_callback",state_mismatch:"awaiting_callback",no_authorization_code:"awaiting_callback",token_exchange_failed:"exchanging_code",token_exchange_network_error:"exchanging_code",keychain_write_failed:"storing_tokens",user_aborted:"unknown",unknown:"unknown"};function $t(){let n=typeof process.getuid=="function"?process.getuid():0;return tt.createHash("sha256").update(`${nt.hostname()}-${n}`).digest("hex").substring(0,36)}function it(){return{platform:process.platform,source:process.env.CODEVIBE_TELEMETRY_SOURCE||"production"}}async function st(n,e){try{let t=JSON.stringify({client_id:$t(),events:[{name:n,params:e}]});await new Promise(r=>{let i=rt.request({hostname:Pt,path:Ot,method:"POST",headers:{"Content-Type":"application/json"}},()=>r());i.on("error",()=>r()),i.write(t),i.end(),setTimeout(r,2e3)})}catch{}}async function te(n){await st("auth_completed",{...it(),user_id:n})}async function v(n,e){let t={...it(),reason:n,stage:e?.stage??Nt[n]};if(typeof e?.httpStatus=="number"&&(t.http_status=e.httpStatus),e?.errorFragment){let r=e.errorFragment.replace(/[\n\r\t"\\]/g," ").replace(/[^\x20-\x7E]/g,"").trim().substring(0,100);r&&(t.error_fragment=r)}await st("auth_failed",t)}var Ae=Symbol.for("codevibe.auth.beaconed"),ot=Symbol.for("codevibe.auth.failureReason");function I(n,e){try{Object.defineProperty(n,Ae,{value:!0,enumerable:!1,configurable:!0,writable:!1}),Object.defineProperty(n,ot,{value:e,enumerable:!1,configurable:!0,writable:!1})}catch{}return n}function re(n){return!!(n&&typeof n=="object"&&n[Ae])}function Te(n){if(n&&typeof n=="object"&&n[Ae]){let e=n[ot];if(typeof e=="string")return e}}var ne=8080,lt="/callback",xe=`http://localhost:${ne}${lt}`,J=class n{constructor(){}static getInstance(){return n.instance||(n.instance=new n),n.instance}openBrowser(e){console.log(""),console.log("Opening your browser for sign-in..."),this.isRunningInWSL()?console.log("If your browser does not open, paste this URL in your Windows browser:"):console.log("If your browser does not open automatically, visit this URL:"),console.log(` ${e}`),console.log("");let t=this.getBrowserCommands();this.tryBrowserCommand(t,e,0)}getBrowserCommands(){let e=process.platform;if(e==="darwin")return[{cmd:"open",fixedArgs:[]}];if(e==="win32")return[{cmd:"cmd",fixedArgs:["/c","start",""]}];let t=[];return this.isRunningInWSL()&&(t.push({cmd:"wslview",fixedArgs:[]}),t.push({cmd:"cmd.exe",fixedArgs:["/c","start",""]}),t.push({cmd:"powershell.exe",fixedArgs:["-NoProfile","-Command","Start-Process"]})),t.push({cmd:"xdg-open",fixedArgs:[]}),t}isRunningInWSL(){if(process.platform!=="linux")return!1;try{let e=ct.readFileSync("/proc/sys/kernel/osrelease","utf8");return/microsoft|wsl/i.test(e)}catch{return!1}}tryBrowserCommand(e,t,r){if(r>=e.length){c.debug("[AuthService] No browser-opening command succeeded. User must open the sign-in URL manually (printed to stdout above)."),console.log(""),console.log("\u26A0\uFE0F Could not open browser automatically."),this.isRunningInWSL()?console.log(" WSL detected \u2014 paste this URL in your Windows browser:"):console.log(" Please copy and paste this URL into your browser:"),console.log(` ${t}`),console.log("");return}let i=e[r],s=[...i.fixedArgs,t],o=!1,a=u=>{o||(o=!0,c.debug(`[AuthService] Browser command '${i.cmd}' ${u}; trying next fallback`),this.tryBrowserCommand(e,t,r+1))},d=u=>{o||(o=!0,c.debug(`[AuthService] Browser command '${i.cmd}' ${u}`))},l;try{l=(0,dt.spawn)(i.cmd,s,{detached:!0,stdio:"ignore"})}catch(u){a(`threw synchronously: ${u?.message||u}`);return}l.on("error",u=>{a(`failed to spawn: ${u?.message||u}`)}),l.on("exit",(u,S)=>{u===0?d("exited successfully"):a(S?`terminated by signal ${S}`:`exited with code ${u}`)}),setTimeout(()=>{d("still running after 3s, assuming success")},3e3).unref(),l.unref()}generateState(){return at.randomBytes(32).toString("hex")}buildAuthUrl(e){let t=f(),r=new URLSearchParams({client_id:t.aws.cognitoClientId,response_type:"code",scope:"email openid profile",redirect_uri:xe,state:e});return`https://${t.aws.cognitoDomain}/oauth2/authorize?${r.toString()}`}async exchangeCodeForTokens(e){let t=f(),r=`https://${t.aws.cognitoDomain}/oauth2/token`,i=new URLSearchParams({grant_type:"authorization_code",client_id:t.aws.cognitoClientId,code:e,redirect_uri:xe}),s;try{s=await j(r,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:i.toString()},"Token exchange")}catch(a){throw await v("token_exchange_network_error"),I(a,"token_exchange_network_error"),a}if(!s.ok){let a=await s.text(),d=new Error(`Token exchange failed: ${s.status} ${a}`);throw await v("token_exchange_failed",{httpStatus:s.status}),I(d,"token_exchange_failed"),d}let o=await s.json();return{accessToken:o.access_token,idToken:o.id_token,refreshToken:o.refresh_token,expiresIn:o.expires_in}}decodeJwt(e){let t=e.split(".");if(t.length!==3)throw new Error("Invalid JWT");return JSON.parse(Buffer.from(t[1],"base64").toString("utf-8"))}async refreshTokens(e){let t=f(),r=`https://${t.aws.cognitoDomain}/oauth2/token`,i=new URLSearchParams({grant_type:"refresh_token",client_id:t.aws.cognitoClientId,refresh_token:e}),s=await j(r,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:i.toString()},"Token refresh");if(!s.ok)throw new Error(`Token refresh failed: ${s.status}`);let o=await s.json();return{accessToken:o.access_token,idToken:o.id_token,expiresIn:o.expires_in}}async login(){let e=await g.getTokens(b());if(e&&!g.isTokenExpired(e))return e;let t=this.generateState(),r=this.buildAuthUrl(t);return new Promise((i,s)=>{let o=De.createServer(async(a,d)=>{if(!a.url?.startsWith(lt)){d.writeHead(404),d.end("Not found");return}try{let l=new URL(a.url,`http://localhost:${ne}`),y=l.searchParams.get("code"),u=l.searchParams.get("state"),S=l.searchParams.get("error");if(S){let A=new Error(`OAuth error: ${S}`);throw await v("cognito_rejected"),I(A,"cognito_rejected"),A}if(u!==t){let A=new Error("State mismatch");throw await v("state_mismatch"),I(A,"state_mismatch"),A}if(!y){let A=new Error("No authorization code");throw await v("no_authorization_code"),I(A,"no_authorization_code"),A}let w=await this.exchangeCodeForTokens(y),z=this.decodeJwt(w.idToken),h={accessToken:w.accessToken,idToken:w.idToken,refreshToken:w.refreshToken,expiresAt:Date.now()+w.expiresIn*1e3,userId:z.sub,email:z.email||"unknown"};try{await g.setTokens(h,b())}catch(A){throw await v("keychain_write_failed"),I(A,"keychain_write_failed"),A}d.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),d.end(`
215
+ `}});var Ot,Ye,$t,Nt=b(()=>{"use strict";Ot=(a=>(a.USER_PROMPT="USER_PROMPT",a.ASSISTANT_RESPONSE="ASSISTANT_RESPONSE",a.TOOL_USE="TOOL_USE",a.NOTIFICATION="NOTIFICATION",a.INTERACTIVE_PROMPT="INTERACTIVE_PROMPT",a.PROMPT_RESPONSE="PROMPT_RESPONSE",a.REASONING="REASONING",a))(Ot||{}),Ye=(t=>(t.DESKTOP="DESKTOP",t.MOBILE="MOBILE",t))(Ye||{}),$t=(n=>(n.SENT="SENT",n.DELIVERED="DELIVERED",n.EXECUTED="EXECUTED",n))($t||{})});var Xe,Ut,Lt=b(()=>{"use strict";Xe=(n=>(n.ACTIVE="ACTIVE",n.INACTIVE="INACTIVE",n.PAUSED="PAUSED",n))(Xe||{}),Ut=(n=>(n.CLAUDE="CLAUDE",n.GEMINI="GEMINI",n.CODEX="CODEX",n))(Ut||{})});var Mt=b(()=>{"use strict"});var Bt=b(()=>{"use strict"});var Qe,Wt=b(()=>{"use strict";Qe=(l=>(l.ARCHITECTURE="ARCHITECTURE",l.CORRECTNESS="CORRECTNESS",l.SECURITY="SECURITY",l.ACCURACY="ACCURACY",l.CLARITY="CLARITY",l.COMPLETENESS="COMPLETENESS",l.ARCHITECTURE_AND_ACCURACY="ARCHITECTURE_AND_ACCURACY",l.CORRECTNESS_AND_CLARITY="CORRECTNESS_AND_CLARITY",l.SECURITY_AND_COMPLETENESS="SECURITY_AND_COMPLETENESS",l))(Qe||{})});var pe=b(()=>{"use strict";Nt();Lt();Mt();Bt();Wt()});var ge,me,P,J,Vt=b(()=>{"use strict";ge=S(require("ws")),me=require("uuid");Q();$();U();Je();ze();pe();P={urgentMaxAttempts:10,baseDelayMs:1e3,maxDelayMs:6e4,backoffMultiplier:2,persistentDelayMs:300*1e3},J=class{constructor(){this.authenticated=!1;this.currentUserId=null;this.currentEmail=null;this.tokens=null;this.activeSubscriptions=new Map;this.deviceKeyWatcher=null;this.heartbeatTimers=new Map;this.environment=x(),c.info("[AppSyncClient] Initialized",{environment:this.environment})}getCurrentUserId(){if(!this.currentUserId)throw new Error("Not authenticated. Call authenticateWithStoredTokens() first.");return this.currentUserId}getCurrentUserEmail(){return this.currentEmail}async authenticateWithStoredTokens(){try{let e=await y.getTokens(this.environment);if(!e)return c.debug("[AppSyncClient] No stored tokens found"),!1;if(c.info("[AppSyncClient] Found stored OAuth tokens",{userId:e.userId,email:e.email,expired:y.isTokenExpired(e)}),y.isTokenExpired(e)){if(c.info("[AppSyncClient] Tokens expired, attempting refresh..."),!await this.refreshTokens(e))return c.warn("[AppSyncClient] Token refresh failed"),!1}else this.tokens=e;return this.currentUserId=this.tokens.userId,this.currentEmail=this.tokens.email,this.authenticated=!0,c.info("[AppSyncClient] Authenticated successfully",{userId:this.currentUserId,email:this.currentEmail}),!0}catch(e){return c.error("[AppSyncClient] Authentication failed:",e),!1}}async refreshTokens(e){try{let t=k(),n=`https://${t.aws.cognitoDomain}/oauth2/token`,i=new URLSearchParams({grant_type:"refresh_token",client_id:t.aws.cognitoClientId,refresh_token:e.refreshToken}),o=await Z(n,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:i.toString()},"Token refresh");if(!o.ok)return c.error("[AppSyncClient] Token refresh failed",{status:o.status}),!1;let s=await o.json(),a={...e,accessToken:s.access_token,idToken:s.id_token,expiresAt:Date.now()+s.expires_in*1e3};return await y.setTokens(a,this.environment),this.tokens=a,c.info("[AppSyncClient] Tokens refreshed",{expiresAt:new Date(a.expiresAt).toISOString()}),!0}catch(t){return c.error("[AppSyncClient] Token refresh error:",t),!1}}isAuthenticated(){return this.authenticated}signOut(){this.authenticated=!1,this.tokens=null,this.currentUserId=null,this.currentEmail=null,this.cleanupSubscriptions(),c.info("[AppSyncClient] Signed out")}async graphqlRequest(e,t,n=!1){let i=k();if(!this.tokens?.idToken)throw new Error('Not authenticated. Run "codevibe login" first.');let o={"Content-Type":"application/json",Authorization:this.tokens.idToken},s=await Z(i.aws.appsyncUrl,{method:"POST",headers:o,body:JSON.stringify({query:e,variables:t})},"AppSync GraphQL request"),a=await s.json();if(s.status===401&&!n&&this.tokens){if(c.info("[AppSyncClient] 401 Unauthorized, refreshing token..."),await this.refreshTokens(this.tokens))return this.graphqlRequest(e,t,!0);throw new Error("Token expired and refresh failed")}if(!s.ok)throw new Error(`GraphQL request failed: ${s.status}`);if(a.errors?.length)throw new Error(`GraphQL error: ${a.errors[0].message}`);return a}async createSession(e){let t={...e,metadata:e.metadata?JSON.stringify(e.metadata):void 0},n=await this.graphqlRequest(C.createSession,{input:t});return c.info("[AppSyncClient] Session created",{sessionId:n.data.createSession.sessionId}),n.data.createSession}async updateSession(e){let t={...e,metadata:e.metadata?JSON.stringify(e.metadata):void 0},n=await this.graphqlRequest(C.updateSession,{input:t});return c.debug("[AppSyncClient] Session updated",{sessionId:n.data.updateSession.sessionId}),n.data.updateSession}async getSession(e){return(await this.graphqlRequest(H.getSession,{sessionId:e})).data.getSession}async createEvent(e){let t={...e,metadata:e.metadata?JSON.stringify(e.metadata):void 0},n=await this.graphqlRequest(C.createEvent,{input:t});return c.debug("[AppSyncClient] Event created",{eventId:n.data.createEvent.eventId,type:n.data.createEvent.type}),n.data.createEvent}async updateEventStatus(e){return(await this.graphqlRequest(C.updateEventStatus,{input:e})).data.updateEventStatus}async listEvents(e,t,n){return(await this.graphqlRequest(H.listEvents,{sessionId:e,source:t,limit:n})).data.listEvents.items}async listUserDeviceKeys(){return(await this.graphqlRequest(H.listUserDeviceKeys,{})).data.listUserDeviceKeys||[]}async registerDeviceKey(e,t,n,i){let o={deviceId:e,publicKey:t,platform:n,deviceName:i};await this.graphqlRequest(C.registerDeviceKey,{input:o}),c.info("[AppSyncClient] Device key registered",{deviceId:e,platform:n})}async grantSessionKey(e){await this.graphqlRequest(C.grantSessionKey,{input:e}),c.info("[AppSyncClient] Session key granted",{sessionId:e.sessionId,deviceId:e.deviceId})}async getAttachmentDownloadUrl(e){return(await this.graphqlRequest(C.getAttachmentDownloadUrl,{s3Key:e})).data.getAttachmentDownloadUrl}async updateAvailableAgents(e){let t=await this.graphqlRequest(C.updateAvailableAgents,{agents:e});return c.info("[AppSyncClient] Updated available agents",{agents:e}),t.data.updateAvailableAgents}async updateReviewerPolicy(e){let t=await this.graphqlRequest(C.updateReviewerPolicy,{input:e});return c.info("[AppSyncClient] Updated reviewer policy",{orchestrationEnabledDefault:e.orchestrationEnabledDefault,reviewerSeatCount:e.reviewerSeats?.length}),t.data.updateReviewerPolicy}subscribeToEvents(e,t,n){c.info("[AppSyncClient] Subscribing to events",{sessionId:e});let i=this.activeSubscriptions.get(e);i&&(this.cleanupSubscriptionState(i),this.activeSubscriptions.delete(e));let o={ws:null,subscriptionId:(0,me.v4)(),sessionId:e,onEvent:t,onError:n,reconnectAttempts:0,isReconnecting:!1,destroyed:!1};return this.activeSubscriptions.set(e,o),this.createSubscription(o),()=>{this.cleanupSubscriptionState(o),this.activeSubscriptions.delete(e)}}buildRealtimeUrl(){let e=k(),t=e.aws.appsyncUrl.replace("https://","wss://").replace("appsync-api","appsync-realtime-api"),n={host:new URL(e.aws.appsyncUrl).host};this.tokens?.idToken&&(n.Authorization=this.tokens.idToken);let i=Buffer.from(JSON.stringify(n)).toString("base64"),o=Buffer.from(JSON.stringify({})).toString("base64");return`${t}?header=${i}&payload=${o}`}createSubscription(e){let{sessionId:t,subscriptionId:n,onEvent:i,onError:o}=e;try{let s=this.buildRealtimeUrl(),a=new ge.default(s,["graphql-ws"]);a.on("open",()=>{c.info("[AppSyncClient] WebSocket connected",{sessionId:t}),a.send(JSON.stringify({type:"connection_init"}))}),a.on("message",d=>{try{let l=JSON.parse(d.toString());switch(l.type){case"connection_ack":this.sendSubscriptionStart(a,e);break;case"start_ack":c.info("[AppSyncClient] Subscription started",{sessionId:t}),e.isReconnecting=!1,e.reconnectAttempts=0,this.startHeartbeat(t);break;case"data":this.resetKeepAliveTimer(e);let m=l.payload?.data?.onEventCreated;m&&m.source==="MOBILE"&&i(m);break;case"ka":this.resetKeepAliveTimer(e);break;case"error":let u=l.payload?.errors?.[0]?.message||"Unknown error";this.handleSubscriptionError(e,new Error(u));break}}catch(l){c.error("[AppSyncClient] Failed to parse message",{error:l})}}),a.on("error",d=>{c.error("[AppSyncClient] WebSocket error",{sessionId:t,error:d.message}),this.handleSubscriptionError(e,d)}),a.on("close",(d,l)=>{c.info("[AppSyncClient] WebSocket closed",{sessionId:t,code:d}),e.keepAliveTimer&&clearTimeout(e.keepAliveTimer),!e.destroyed&&this.activeSubscriptions.get(t)===e&&this.handleSubscriptionError(e,new Error(`WebSocket closed: ${d}`))}),e.ws=a,this.resetKeepAliveTimer(e)}catch(s){this.handleSubscriptionError(e,s)}}sendSubscriptionStart(e,t){let n=k(),{sessionId:i,subscriptionId:o}=t,s={host:new URL(n.aws.appsyncUrl).host};this.tokens?.idToken&&(s.Authorization=this.tokens.idToken),e.send(JSON.stringify({id:o,type:"start",payload:{data:JSON.stringify({query:ee.onEventCreated,variables:{sessionId:i}}),extensions:{authorization:s}}}))}resetKeepAliveTimer(e){e.keepAliveTimer&&clearTimeout(e.keepAliveTimer),e.keepAliveTimer=setTimeout(()=>{this.handleSubscriptionError(e,new Error("Keep-alive timeout"))},300*1e3)}handleSubscriptionError(e,t){let{sessionId:n,onError:i}=e;if(e.isReconnecting||!this.activeSubscriptions.has(n))return;e.isReconnecting=!0,e.reconnectAttempts++,this.stopHeartbeat(n);let o=e.reconnectAttempts<=P.urgentMaxAttempts,s;if(o?s=Math.min(P.baseDelayMs*Math.pow(P.backoffMultiplier,e.reconnectAttempts-1),P.maxDelayMs):(s=P.persistentDelayMs,e.reconnectAttempts===P.urgentMaxAttempts+1&&c.info("[AppSyncClient] Switching to persistent reconnect (every 5min)",{sessionId:n})),c.info("[AppSyncClient] Scheduling reconnect",{sessionId:n,attempt:e.reconnectAttempts,phase:o?"urgent":"persistent",delayMs:s}),e.ws){try{e.ws.close(1e3)}catch{}e.ws=null}e.keepAliveTimer&&clearTimeout(e.keepAliveTimer),e.reconnectTimer=setTimeout(async()=>{if(e.isReconnecting=!1,e.destroyed||this.activeSubscriptions.get(n)!==e){c.info("[AppSyncClient] Reconnect skipped \u2014 state is no longer canonical",{sessionId:n});return}try{let a=await y.getTokens(this.environment);a&&(y.isTokenExpired(a)?await this.refreshTokens(a)&&c.info("[AppSyncClient] Tokens refreshed before reconnect",{sessionId:n}):this.tokens=a)}catch{c.warn("[AppSyncClient] Token refresh failed before reconnect, using existing tokens",{sessionId:n})}if(e.destroyed||this.activeSubscriptions.get(n)!==e){c.info("[AppSyncClient] Reconnect skipped after token refresh \u2014 state no longer canonical",{sessionId:n});return}e.subscriptionId=(0,me.v4)(),this.createSubscription(e)},s)}cleanupSubscriptionState(e){if(e.destroyed=!0,e.reconnectTimer&&(clearTimeout(e.reconnectTimer),e.reconnectTimer=void 0),e.keepAliveTimer&&(clearTimeout(e.keepAliveTimer),e.keepAliveTimer=void 0),e.ws){try{e.ws.readyState===ge.default.OPEN&&e.ws.send(JSON.stringify({id:e.subscriptionId,type:"stop"}))}catch{}try{e.ws.close(1e3)}catch{}try{e.ws.removeAllListeners()}catch{}e.ws=null}}subscribeToDeviceKeyRegistered(e,t,n,i){c.info("[AppSyncClient] Subscribing to device key registrations",{userId:e}),this.deviceKeyWatcher&&this.stopDeviceKeyWatcherInternal();let o={userId:e,subscriptionId:(0,me.v4)(),ws:null,onNewDevice:t,onReconnect:n,onError:i,reconnectAttempts:0,isReconnecting:!1,destroyed:!1};return this.deviceKeyWatcher=o,this.createDeviceKeyWatcherConnection(o),()=>{this.stopDeviceKeyWatcherInternal()}}stopDeviceKeyWatcher(){this.stopDeviceKeyWatcherInternal()}stopDeviceKeyWatcherInternal(){let e=this.deviceKeyWatcher;if(e){if(e.destroyed=!0,e.reconnectTimer&&(clearTimeout(e.reconnectTimer),e.reconnectTimer=void 0),e.keepAliveTimer&&(clearTimeout(e.keepAliveTimer),e.keepAliveTimer=void 0),e.ws){try{e.ws.readyState===ge.default.OPEN&&e.ws.send(JSON.stringify({id:e.subscriptionId,type:"stop"}))}catch{}try{e.ws.close(1e3)}catch{}try{e.ws.removeAllListeners()}catch{}e.ws=null}this.deviceKeyWatcher=null,c.info("[AppSyncClient] Device key watcher stopped")}}createDeviceKeyWatcherConnection(e){try{let t=this.buildRealtimeUrl(),n=new ge.default(t,["graphql-ws"]);n.on("open",()=>{c.info("[AppSyncClient] Device key watcher WebSocket connected",{userId:e.userId}),n.send(JSON.stringify({type:"connection_init"}))}),n.on("message",i=>{try{let o=JSON.parse(i.toString());switch(o.type){case"connection_ack":this.sendDeviceKeyWatcherStart(n,e);break;case"start_ack":c.info("[AppSyncClient] Device key watcher subscription started",{userId:e.userId});let s=e.isReconnecting;if(e.isReconnecting=!1,e.reconnectAttempts=0,s&&e.onReconnect)try{e.onReconnect()}catch(l){c.warn("[AppSyncClient] Device key watcher onReconnect handler threw",{error:l})}break;case"data":this.resetDeviceKeyWatcherKeepAlive(e);let a=o.payload?.data?.onDeviceKeyRegistered;if(a){c.info("[AppSyncClient] Device key registration observed",{userId:e.userId,newDeviceId:a.deviceId,platform:a.platform});try{e.onNewDevice(a)}catch(l){c.warn("[AppSyncClient] Device key watcher onNewDevice handler threw",{error:l})}}break;case"ka":this.resetDeviceKeyWatcherKeepAlive(e);break;case"error":let d=o.payload?.errors?.[0]?.message||"Unknown error";this.handleDeviceKeyWatcherError(e,new Error(d));break}}catch(o){c.error("[AppSyncClient] Failed to parse device key watcher message",{error:o})}}),n.on("error",i=>{c.error("[AppSyncClient] Device key watcher WebSocket error",{userId:e.userId,error:i.message}),this.handleDeviceKeyWatcherError(e,i)}),n.on("close",i=>{c.info("[AppSyncClient] Device key watcher WebSocket closed",{userId:e.userId,code:i}),e.keepAliveTimer&&clearTimeout(e.keepAliveTimer),!e.destroyed&&this.deviceKeyWatcher===e&&this.handleDeviceKeyWatcherError(e,new Error(`WebSocket closed: ${i}`))}),e.ws=n,this.resetDeviceKeyWatcherKeepAlive(e)}catch(t){this.handleDeviceKeyWatcherError(e,t)}}sendDeviceKeyWatcherStart(e,t){let n=k(),{userId:i,subscriptionId:o}=t,s={host:new URL(n.aws.appsyncUrl).host};this.tokens?.idToken&&(s.Authorization=this.tokens.idToken),e.send(JSON.stringify({id:o,type:"start",payload:{data:JSON.stringify({query:ee.onDeviceKeyRegistered,variables:{userId:i}}),extensions:{authorization:s}}}))}resetDeviceKeyWatcherKeepAlive(e){e.keepAliveTimer&&clearTimeout(e.keepAliveTimer),e.keepAliveTimer=setTimeout(()=>{this.handleDeviceKeyWatcherError(e,new Error("Device key watcher keep-alive timeout"))},300*1e3)}handleDeviceKeyWatcherError(e,t){if(e.isReconnecting||e.destroyed||this.deviceKeyWatcher!==e)return;if(e.isReconnecting=!0,e.reconnectAttempts++,e.onError)try{e.onError(t)}catch{}if(e.ws){try{e.ws.removeAllListeners()}catch{}try{e.ws.close(1e3)}catch{}e.ws=null}e.keepAliveTimer&&(clearTimeout(e.keepAliveTimer),e.keepAliveTimer=void 0);let i=e.reconnectAttempts<=P.urgentMaxAttempts?Math.min(P.baseDelayMs*Math.pow(P.backoffMultiplier,e.reconnectAttempts-1),P.maxDelayMs):P.persistentDelayMs;c.warn("[AppSyncClient] Device key watcher reconnect scheduled",{userId:e.userId,attempts:e.reconnectAttempts,delayMs:i,error:t.message}),e.reconnectTimer=setTimeout(async()=>{if(e.isReconnecting=!1,e.destroyed||this.deviceKeyWatcher!==e){c.info("[AppSyncClient] Device key watcher reconnect skipped \u2014 state no longer canonical",{userId:e.userId});return}try{let o=await y.getTokens(this.environment);o&&(y.isTokenExpired(o)?await this.refreshTokens(o)&&c.info("[AppSyncClient] Tokens refreshed before device key watcher reconnect",{userId:e.userId}):this.tokens=o)}catch{c.warn("[AppSyncClient] Token refresh failed before device key watcher reconnect, using existing tokens",{userId:e.userId})}e.destroyed||this.deviceKeyWatcher!==e||(e.subscriptionId=(0,me.v4)(),this.createDeviceKeyWatcherConnection(e))},i)}startHeartbeat(e,t=120*1e3){this.stopHeartbeat(e),this.sendHeartbeat(e);let n=setInterval(()=>{this.sendHeartbeat(e)},t);this.heartbeatTimers.set(e,n),c.info("[AppSyncClient] Heartbeat started",{sessionId:e,intervalMs:t})}stopHeartbeat(e){let t=this.heartbeatTimers.get(e);t&&(clearInterval(t),this.heartbeatTimers.delete(e),c.info("[AppSyncClient] Heartbeat stopped",{sessionId:e}))}async sendHeartbeat(e){try{await this.updateSession({sessionId:e,lastHeartbeatAt:new Date().toISOString()}),c.debug("[AppSyncClient] Heartbeat sent",{sessionId:e})}catch(t){c.warn("[AppSyncClient] Heartbeat failed",{sessionId:e,error:t})}}cleanupSubscriptions(){this.activeSubscriptions.forEach(e=>{this.cleanupSubscriptionState(e)}),this.activeSubscriptions.clear(),this.stopDeviceKeyWatcherInternal(),this.heartbeatTimers.forEach(e=>clearInterval(e)),this.heartbeatTimers.clear()}}});var Re=b(()=>{"use strict";Vt();ze()});function L(){let r=[];for(let e of["CLAUDE","GEMINI","CODEX"])Gr(e)&&r.push(e);return c.debug("[detectInstalledAgents] Detected",{detected:r}),r}function Gr(r){try{return(0,Zt.execSync)(`command -v ${qr[r]}`,{stdio:"ignore",shell:"/bin/sh"}),!0}catch{return!1}}async function Ie(r,e){let t=L();if(t.length===0){e.warn("No AI coding agents detected on PATH \u2014 skipping updateAvailableAgents");return}await r.updateAvailableAgents(t),e.info("Pushed available agents to backend",{agents:t})}async function xe(r,e,t){let n=process.env.CODEVIBE_ORCHESTRATION_OVERRIDE;if(n!=="true"&&n!=="false")return;let i=n==="true";try{await r.updateSession({sessionId:e,orchestrationEnabled:i}),t.info("Applied per-session orchestration override",{sessionId:e,enabled:i})}catch(o){t.warn("Failed to apply per-session orchestration override",{sessionId:e,enabled:i,error:o?.message})}}var Zt,qr,nt=b(()=>{"use strict";Zt=require("child_process");$();qr={CLAUDE:"claude",GEMINI:"gemini",CODEX:"codex"}});async function Ce(r){let t=r.slice(3).filter(n=>!n.startsWith("--"))[0];switch(t){case"enable":await zr();break;case"disable":await Yr();break;case"status":await Xr();break;case"configure":await Qr();break;default:Jr(),process.exit(t?1:0)}}function Jr(){console.log(""),console.log(`${p.bold}codevibe orchestration${p.reset} \u2014 Quorum 2.0 reviewer policy`),console.log(""),console.log("Usage: codevibe orchestration <command>"),console.log(""),console.log("Commands:"),console.log(" enable Auto-enable orchestration for new sessions"),console.log(" disable Disable orchestration (sessions route to 1.0 flow)"),console.log(" status Show current reviewer policy + installed agents"),console.log(" configure Interactive wizard (toggle + customize panel)"),console.log("")}async function zr(){let e=await(await _e()).updateReviewerPolicy({orchestrationEnabledDefault:!0});ot(e),console.log(`
216
+ ${p.green}\u2713${p.reset} Orchestration enabled. New sessions will use your reviewer panel.`)}async function Yr(){let e=await(await _e()).updateReviewerPolicy({orchestrationEnabledDefault:!1});ot(e),console.log(`
217
+ ${p.yellow}\u2713${p.reset} Orchestration disabled. New sessions route to the 1.0 companion flow.`)}async function Xr(){let r=L();if(console.log(""),console.log(`${p.bold}Installed agents${p.reset}`),r.length===0)console.log(` ${p.dim}(none detected on PATH)${p.reset}`);else for(let n of r)console.log(` ${p.green}\u2713${p.reset} ${n.toLowerCase()}`);console.log("");let t=await(await _e()).updateAvailableAgents(r);ot(t)}async function Qr(){let r=L();r.length===0&&(console.log(""),console.log(`${p.yellow}No agents detected on PATH.${p.reset}`),console.log(`Install at least one of ${p.bold}claude${p.reset}, ${p.bold}gemini${p.reset}, or ${p.bold}codex${p.reset} before configuring orchestration.`),process.exit(1)),console.log(""),console.log(`${p.bold}Quorum 2.0 orchestration configuration${p.reset}`),console.log(`${p.dim}Detected agents: ${r.map(n=>n.toLowerCase()).join(", ")}${p.reset}`),console.log("");let e=await _e();await e.updateAvailableAgents(r);let t=rr.createInterface({input:process.stdin,output:process.stdout});try{if(!await er(t,"Enable orchestration for new sessions?",!1)){await e.updateReviewerPolicy({orchestrationEnabledDefault:!1}),console.log(`
218
+ ${p.yellow}\u2713${p.reset} Orchestration disabled.`);return}if(!await er(t,"Customize reviewer panel (otherwise use tier defaults)?",!1)){await e.updateReviewerPolicy({orchestrationEnabledDefault:!0,reviewerSeats:[]}),console.log(`
219
+ ${p.green}\u2713${p.reset} Orchestration enabled with tier-default reviewer panel.`);return}let o=await Zr(t),s=[],a=new Set;for(let d=0;d<o;d++){console.log(""),console.log(`${p.bold}Seat ${d}${p.reset}`);let l=Hr.filter(w=>!a.has(w)),m=await tr(t,"Role:",l),u=await tr(t,"Agent:",r);s.push({seatId:d,role:m,agent:u}),a.add(m)}await e.updateReviewerPolicy({orchestrationEnabledDefault:!0,reviewerSeats:s}),console.log(""),console.log(`${p.green}\u2713${p.reset} Orchestration enabled with custom panel:`);for(let d of s)console.log(` Seat ${d.seatId}: ${d.role.toLowerCase()} \u2192 ${d.agent.toLowerCase()}`)}finally{t.close()}}function it(r,e){return new Promise(t=>r.question(e,n=>t(n.trim())))}async function er(r,e,t){let i=(await it(r,e+(t?" [Y/n] ":" [y/N] "))).toLowerCase();return i?i.startsWith("y"):t}async function Zr(r){for(;;){let e=await it(r,"How many seats (2 for Pro, 3 for Max)? "),t=parseInt(e,10);if(t===2||t===3)return t;console.log(`${p.yellow}Enter 2 or 3.${p.reset}`)}}async function tr(r,e,t){for(;;){console.log(e),t.forEach((o,s)=>{console.log(` ${p.cyan}${s+1}${p.reset}. ${o.toLowerCase()}`)});let n=await it(r,"> "),i=parseInt(n,10)-1;if(i>=0&&i<t.length)return t[i];console.log(`${p.yellow}Enter a number between 1 and ${t.length}.${p.reset}`)}}async function _e(){let r=new J;return await r.authenticateWithStoredTokens()||(console.log(""),console.log(`${p.yellow}Not authenticated.${p.reset} Run ${p.bold}codevibe login${p.reset} first.`),process.exit(1)),r}function ot(r){console.log(""),console.log(`${p.bold}Current reviewer policy${p.reset}`),console.log(` Orchestration default: ${en(r.orchestrationEnabledDefault)}`),console.log(` Available agents: ${r.availableAgents?.length?r.availableAgents.map(e=>e.toLowerCase()).join(", "):`${p.dim}(not yet detected)${p.reset}`}`),console.log(` Reviewer panel: ${tn(r.reviewerSeats)}`)}function en(r){return r===!0?`${p.green}enabled${p.reset}`:r===!1?`${p.yellow}disabled${p.reset}`:`${p.dim}(unset \u2014 defaults to disabled)${p.reset}`}function tn(r){return!r||r.length===0?`${p.dim}tier defaults${p.reset}`:r.map(e=>`Seat ${e.seatId} ${e.role.toLowerCase()}\u2192${e.agent.toLowerCase()}`).join(", ")}var rr,p,Hr,nr=b(()=>{"use strict";rr=S(require("readline"));Re();pe();nt();p={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",green:"\x1B[32m",yellow:"\x1B[33m",purple:"\x1B[35m",cyan:"\x1B[36m"},Hr=["ARCHITECTURE","CORRECTNESS","SECURITY","ACCURACY","CLARITY","COMPLETENESS","ARCHITECTURE_AND_ACCURACY","CORRECTNESS_AND_CLARITY","SECURITY_AND_COMPLETENESS"]});var ir={};ce(ir,{applyPerSessionOrchestrationOverride:()=>xe,detectInstalledAgents:()=>L,pushDetectedAgents:()=>Ie,runOrchestrationCli:()=>Ce});var st=b(()=>{"use strict";nt();nr()});var Gn={};ce(Gn,{AgentType:()=>Ut,AppSyncClient:()=>J,AuditKeys:()=>yt,AuthService:()=>te,CryptoError:()=>j,CryptoService:()=>X,DeliveryStatus:()=>$t,ENCRYPTION_VERSION:()=>Ge,EventSource:()=>Ye,EventType:()=>Ot,KeychainError:()=>K,KeychainManager:()=>G,Logger:()=>V,Reviewer:()=>ft,ReviewerRole:()=>Qe,SessionStatus:()=>Xe,applyPerSessionOrchestrationOverride:()=>xe,authService:()=>O,createLogger:()=>Ue,cryptoService:()=>I,detectInstalledAgents:()=>L,errorWasBeaconed:()=>ye,fireAuthCompletedBeacon:()=>fe,fireAuthFailedBeacon:()=>R,getConfig:()=>k,getEnvironment:()=>x,getErrorReason:()=>et,keychainManager:()=>y,loadConfig:()=>ke,logger:()=>c,markErrorBeaconed:()=>_,mutations:()=>C,normalizeSnapshot:()=>dt,parseInteractivePrompt:()=>or,prepareSessionEncryption:()=>Pe,pushDetectedAgents:()=>Ie,queries:()=>H,registerDeviceEncryptionKey:()=>pt,rekeySessionForNewDevices:()=>z,resumeOrCreateSession:()=>lt,runAuthCli:()=>Te,runOrchestrationCli:()=>Ce,startDeviceKeyWatcher:()=>ut,subscriptions:()=>ee});module.exports=vt(Gn);U();de();Re();Re();var zt=S(require("crypto")),Yt=S(require("fs")),rt=S(require("http")),Xt=require("child_process");Q();U();$();Je();var Ft=S(require("crypto")),jt=S(require("https")),qt=S(require("os")),Mr="G-GS74YEQTB8",Br="lAfOF6OxRzSQ-NsLBRjhAg",Wr="www.google-analytics.com",Vr=`/mp/collect?measurement_id=${Mr}&api_secret=${Br}`,Fr={port_in_use:"server_start",server_listen_failed:"server_start",browser_open_failed:"browser_open",login_timeout:"awaiting_callback",cognito_rejected:"awaiting_callback",state_mismatch:"awaiting_callback",no_authorization_code:"awaiting_callback",token_exchange_failed:"exchanging_code",token_exchange_network_error:"exchanging_code",keychain_write_failed:"storing_tokens",user_aborted:"unknown",unknown:"unknown"};function jr(){let r=typeof process.getuid=="function"?process.getuid():0;return Ft.createHash("sha256").update(`${qt.hostname()}-${r}`).digest("hex").substring(0,36)}function Gt(){return{platform:process.platform,source:process.env.CODEVIBE_TELEMETRY_SOURCE||"production"}}async function Ht(r,e){try{let t=JSON.stringify({client_id:jr(),events:[{name:r,params:e}]});await new Promise(n=>{let i=jt.request({hostname:Wr,path:Vr,method:"POST",headers:{"Content-Type":"application/json"}},()=>n());i.on("error",()=>n()),i.write(t),i.end(),setTimeout(n,2e3)})}catch{}}async function fe(r){await Ht("auth_completed",{...Gt(),user_id:r})}async function R(r,e){let t={...Gt(),reason:r,stage:e?.stage??Fr[r]};typeof e?.httpStatus=="number"&&(t.http_status=e.httpStatus),await Ht("auth_failed",t)}var Ze=Symbol.for("codevibe.auth.beaconed"),Jt=Symbol.for("codevibe.auth.failureReason");function _(r,e){try{Object.defineProperty(r,Ze,{value:!0,enumerable:!1,configurable:!0,writable:!1}),Object.defineProperty(r,Jt,{value:e,enumerable:!1,configurable:!0,writable:!1})}catch{}return r}function ye(r){return!!(r&&typeof r=="object"&&r[Ze])}function et(r){if(r&&typeof r=="object"&&r[Ze]){let e=r[Jt];if(typeof e=="string")return e}}var he=8080,Qt="/callback",tt=`http://localhost:${he}${Qt}`,te=class r{constructor(){}static getInstance(){return r.instance||(r.instance=new r),r.instance}openBrowser(e){console.error(""),console.error("Opening your browser for sign-in..."),this.isRunningInWSL()?console.error("If your browser does not open, paste this URL in your Windows browser:"):console.error("If your browser does not open automatically, visit this URL:"),console.error(` ${e}`),console.error("");let t=this.getBrowserCommands();this.tryBrowserCommand(t,e,0)}getBrowserCommands(){let e=process.platform;if(e==="darwin")return[{cmd:"open",fixedArgs:[]}];if(e==="win32")return[{cmd:"cmd",fixedArgs:["/c","start",""]}];let t=[];return this.isRunningInWSL()&&(t.push({cmd:"wslview",fixedArgs:[]}),t.push({cmd:"cmd.exe",fixedArgs:["/c","start",""]}),t.push({cmd:"powershell.exe",fixedArgs:["-NoProfile","-Command","Start-Process"]})),t.push({cmd:"xdg-open",fixedArgs:[]}),t}isRunningInWSL(){if(process.platform!=="linux")return!1;try{let e=Yt.readFileSync("/proc/sys/kernel/osrelease","utf8");return/microsoft|wsl/i.test(e)}catch{return!1}}tryBrowserCommand(e,t,n){if(n>=e.length){c.debug("[AuthService] No browser-opening command succeeded. User must open the sign-in URL manually (printed to stderr above)."),console.error(""),console.error("\u26A0\uFE0F Could not open browser automatically."),this.isRunningInWSL()?console.error(" WSL detected \u2014 paste this URL in your Windows browser:"):console.error(" Please copy and paste this URL into your browser:"),console.error(` ${t}`),console.error("");return}let i=e[n],o=[...i.fixedArgs,t],s=!1,a=u=>{s||(s=!0,c.debug(`[AuthService] Browser command '${i.cmd}' ${u}; trying next fallback`),this.tryBrowserCommand(e,t,n+1))},d=u=>{s||(s=!0,c.debug(`[AuthService] Browser command '${i.cmd}' ${u}`))},l;try{l=(0,Xt.spawn)(i.cmd,o,{detached:!0,stdio:"ignore"})}catch(u){a(`threw synchronously: ${u?.message||u}`);return}l.on("error",u=>{a(`failed to spawn: ${u?.message||u}`)}),l.on("exit",(u,w)=>{u===0?d("exited successfully"):a(w?`terminated by signal ${w}`:`exited with code ${u}`)}),setTimeout(()=>{d("still running after 3s, assuming success")},3e3).unref(),l.unref()}generateState(){return zt.randomBytes(32).toString("hex")}buildAuthUrl(e){let t=k(),n=new URLSearchParams({client_id:t.aws.cognitoClientId,response_type:"code",scope:"email openid profile",redirect_uri:tt,state:e});return`https://${t.aws.cognitoDomain}/oauth2/authorize?${n.toString()}`}async exchangeCodeForTokens(e){let t=k(),n=`https://${t.aws.cognitoDomain}/oauth2/token`,i=new URLSearchParams({grant_type:"authorization_code",client_id:t.aws.cognitoClientId,code:e,redirect_uri:tt}),o;try{o=await Z(n,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:i.toString()},"Token exchange")}catch(a){throw await R("token_exchange_network_error"),_(a,"token_exchange_network_error"),a}if(!o.ok){let a=await o.text(),d=new Error(`Token exchange failed: ${o.status} ${a}`);throw await R("token_exchange_failed",{httpStatus:o.status}),_(d,"token_exchange_failed"),d}let s=await o.json();return{accessToken:s.access_token,idToken:s.id_token,refreshToken:s.refresh_token,expiresIn:s.expires_in}}decodeJwt(e){let t=e.split(".");if(t.length!==3)throw new Error("Invalid JWT");return JSON.parse(Buffer.from(t[1],"base64").toString("utf-8"))}async refreshTokens(e){let t=k(),n=`https://${t.aws.cognitoDomain}/oauth2/token`,i=new URLSearchParams({grant_type:"refresh_token",client_id:t.aws.cognitoClientId,refresh_token:e}),o=await Z(n,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:i.toString()},"Token refresh");if(!o.ok)throw new Error(`Token refresh failed: ${o.status}`);let s=await o.json();return{accessToken:s.access_token,idToken:s.id_token,expiresIn:s.expires_in}}async login(){let e=await y.getTokens(x());if(e&&!y.isTokenExpired(e))return e;let t=this.generateState(),n=this.buildAuthUrl(t);return new Promise((i,o)=>{let s=rt.createServer(async(a,d)=>{if(!a.url?.startsWith(Qt)){d.writeHead(404),d.end("Not found");return}try{let l=new URL(a.url,`http://localhost:${he}`),m=l.searchParams.get("code"),u=l.searchParams.get("state"),w=l.searchParams.get("error");if(w){let f=new Error(`OAuth error: ${w}`);throw await R("cognito_rejected"),_(f,"cognito_rejected"),f}if(u!==t){let f=new Error("State mismatch");throw await R("state_mismatch"),_(f,"state_mismatch"),f}if(!m){let f=new Error("No authorization code");throw await R("no_authorization_code"),_(f,"no_authorization_code"),f}let v=await this.exchangeCodeForTokens(m),W=this.decodeJwt(v.idToken),E={accessToken:v.accessToken,idToken:v.idToken,refreshToken:v.refreshToken,expiresAt:Date.now()+v.expiresIn*1e3,userId:W.sub,email:W.email||"unknown"};try{await y.setTokens(E,x())}catch(f){throw await R("keychain_write_failed"),_(f,"keychain_write_failed"),f}d.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),d.end(`
198
220
  <!DOCTYPE html>
199
221
  <html>
200
222
  <head><title>Success</title></head>
@@ -203,17 +225,17 @@ ${r.stack}`)):typeof r=="object"?o+=` ${JSON.stringify(r,kt)}`:o+=` ${r}`),o}log
203
225
  <p>You can close this window.</p>
204
226
  </body>
205
227
  </html>
206
- `),setTimeout(()=>{o.close(()=>i(h))},500)}catch(l){let y=String(l?.message||l).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");d.writeHead(400,{"Content-Type":"text/html; charset=utf-8"}),d.end(`
228
+ `),setTimeout(()=>{s.close(()=>i(E))},500)}catch(l){let m=String(l?.message||l).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");d.writeHead(400,{"Content-Type":"text/html; charset=utf-8"}),d.end(`
207
229
  <!DOCTYPE html>
208
230
  <html>
209
231
  <head><title>Error</title></head>
210
232
  <body style="font-family: system-ui; max-width: 720px; margin: 50px auto; padding: 0 16px;">
211
233
  <h1 style="color: #ef4444; text-align: center;">&#10007; Authentication Failed</h1>
212
- <pre style="background: #f4f4f5; padding: 16px; border-radius: 8px; white-space: pre-wrap; word-wrap: break-word; font-size: 13px; line-height: 1.5;">${y}</pre>
234
+ <pre style="background: #f4f4f5; padding: 16px; border-radius: 8px; white-space: pre-wrap; word-wrap: break-word; font-size: 13px; line-height: 1.5;">${m}</pre>
213
235
  <p style="text-align: center; color: #71717a; margin-top: 24px;">You can close this window and try again in your terminal.</p>
214
236
  </body>
215
237
  </html>
216
- `),setTimeout(()=>{o.close(()=>s(l))},500)}});o.on("error",async a=>{if(a.code==="EADDRINUSE"){let d=new Error(`Port ${ne} is in use`);await v("port_in_use"),I(d,"port_in_use"),s(d)}else await v("server_listen_failed"),I(a,"server_listen_failed"),s(a)}),o.listen(ne,"localhost",()=>{c.info("[AuthService] Callback server started"),this.openBrowser(r)}),setTimeout(async()=>{let a=new Error("Login timeout");await v("login_timeout"),I(a,"login_timeout"),o.close(()=>s(a))},120*1e3)})}async logout(){let e=f(),t=await g.deleteTokens(b());return t&&new Promise(r=>{let i=De.createServer((s,o)=>{s.url?.startsWith("/signout")?(o.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),o.end(`
238
+ `),setTimeout(()=>{s.close(()=>o(l))},500)}});s.on("error",async a=>{if(a.code==="EADDRINUSE"){let d=new Error(`Port ${he} is in use`);await R("port_in_use"),_(d,"port_in_use"),o(d)}else await R("server_listen_failed"),_(a,"server_listen_failed"),o(a)}),s.listen(he,"localhost",()=>{c.info("[AuthService] Callback server started"),this.openBrowser(n)}),setTimeout(async()=>{let a=new Error("Login timeout");await R("login_timeout"),_(a,"login_timeout"),s.close(()=>o(a))},120*1e3)})}async logout(){let e=k(),t=await y.deleteTokens(x());return t&&new Promise(n=>{let i=rt.createServer((o,s)=>{o.url?.startsWith("/signout")?(s.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),s.end(`
217
239
  <!DOCTYPE html>
218
240
  <html>
219
241
  <head><title>Signed Out</title></head>
@@ -222,27 +244,32 @@ ${r.stack}`)):typeof r=="object"?o+=` ${JSON.stringify(r,kt)}`:o+=` ${r}`),o}log
222
244
  <p>You can close this window.</p>
223
245
  </body>
224
246
  </html>
225
- `),setTimeout(()=>{i.close(()=>r(!0))},500)):(o.writeHead(404),o.end("Not found"))});i.on("error",()=>{r(!0)}),i.listen(ne,"localhost",()=>{let s=`https://${e.aws.cognitoDomain}/logout?client_id=${e.aws.cognitoClientId}&logout_uri=${encodeURIComponent(xe.replace("/callback","/signout"))}`;this.openBrowser(s)}),setTimeout(()=>{i.close(()=>r(!0))},30*1e3)})}async getStatus(){let e=await g.getTokens(b());return e?{authenticated:!g.isTokenExpired(e),tokens:e}:{authenticated:!1}}},R=J.getInstance();q();var p={reset:"\x1B[0m",green:"\x1B[32m",red:"\x1B[31m",yellow:"\x1B[33m",cyan:"\x1B[36m",dim:"\x1B[2m"};async function Lt(){console.log(`${p.cyan}CodeVibe Login${p.reset}
226
- `);try{let n=await R.getStatus();if(n.authenticated&&n.tokens){console.log(`${p.yellow}Already logged in as: ${n.tokens.email}${p.reset}`),console.log(`Token expires: ${new Date(n.tokens.expiresAt).toLocaleString()}`),console.log(`
227
- Run '${p.dim}codevibe logout${p.reset}' to sign out first.`),process.exit(0);return}console.log("Opening browser for authentication..."),console.log(`${p.dim}Waiting for callback...${p.reset}
228
- `);let e=await R.login();e&&(console.log(`
229
- ${p.green}\u2713 Authentication successful!${p.reset}`),console.log(` User: ${e.email}`),console.log(` User ID: ${e.userId}`),console.log(` Expires: ${new Date(e.expiresAt).toLocaleString()}`),await te(e.userId)),process.exit(0)}catch(n){if(console.log(`
230
- ${p.red}\u2717 Authentication failed${p.reset}`),console.log(` Error: ${n.message}`),!re(n)){let e=typeof n?.message=="string"?n.message:void 0;await v("unknown",{errorFragment:e})}process.exit(1)}}async function Ut(){console.log(`${p.cyan}CodeVibe Logout${p.reset}
231
- `);try{let n=await R.getStatus();if(!n.authenticated){console.log(`${p.yellow}Not logged in.${p.reset}`),process.exit(0);return}let e=n.tokens?.email;await R.logout()?(console.log(`${p.green}\u2713 Logged out successfully.${p.reset}`),console.log(` Previous user: ${e}`),console.log(`
232
- ${p.dim}Clearing browser session...${p.reset}`)):console.log(`${p.red}\u2717 Failed to log out.${p.reset}`),process.exit(0)}catch(n){console.log(`${p.red}\u2717 Logout failed: ${n.message}${p.reset}`),process.exit(1)}}async function Mt(){console.log(`${p.cyan}CodeVibe Auth Status${p.reset}
233
- `);try{let n=await R.getStatus();if(!n.tokens){console.log(`${p.yellow}Not authenticated.${p.reset}`),console.log(`
234
- Run '${p.dim}codevibe login${p.reset}' to sign in.`),process.exit(0);return}let e=!n.authenticated;console.log(e?`${p.yellow}\u26A0 Token expired${p.reset}`:`${p.green}\u2713 Authenticated${p.reset}`),console.log(` User: ${n.tokens.email}`),console.log(` User ID: ${n.tokens.userId}`),console.log(` Expires: ${new Date(n.tokens.expiresAt).toLocaleString()}`),e&&console.log(`
235
- ${p.dim}Token will be refreshed automatically.${p.reset}`),process.exit(0)}catch(n){console.log(`${p.red}\u2717 Status check failed: ${n.message}${p.reset}`),process.exit(1)}}async function Bt(){console.log(`${p.cyan}CodeVibe Reset Device${p.reset}
236
- `),console.log(`${p.red}\u26A0 WARNING: This will delete your device identity.${p.reset}`),console.log(`${p.red} Old encrypted sessions will become inaccessible.${p.reset}
237
- `);let{keychainManager:n}=await Promise.resolve().then(()=>(P(),Ge));try{await n.clearAllData(),console.log(`${p.green}\u2713 Device reset complete.${p.reset}`),console.log(` Run '${p.dim}codevibe login${p.reset}' to set up again.`),process.exit(0)}catch(e){console.log(`${p.red}\u2717 Reset failed: ${e.message}${p.reset}`),process.exit(1)}}function Wt(){console.log(`CodeVibe Authentication
247
+ `),setTimeout(()=>{i.close(()=>n(!0))},500)):(s.writeHead(404),s.end("Not found"))});i.on("error",()=>{n(!0)}),i.listen(he,"localhost",()=>{let o=`https://${e.aws.cognitoDomain}/logout?client_id=${e.aws.cognitoClientId}&logout_uri=${encodeURIComponent(tt.replace("/callback","/signout"))}`;this.openBrowser(o)}),setTimeout(()=>{i.close(()=>n(!0))},30*1e3)})}async getStatus(){let e=await y.getTokens(x());return e?{authenticated:!y.isTokenExpired(e),tokens:e}:{authenticated:!1}}},O=te.getInstance();Q();var g={reset:"\x1B[0m",green:"\x1B[32m",red:"\x1B[31m",yellow:"\x1B[33m",cyan:"\x1B[36m",dim:"\x1B[2m"};async function rn(){console.log(`${g.cyan}CodeVibe Login${g.reset}
248
+ `);try{let r=await O.getStatus();if(r.authenticated&&r.tokens){console.log(`${g.yellow}Already logged in as: ${r.tokens.email}${g.reset}`),console.log(`Token expires: ${new Date(r.tokens.expiresAt).toLocaleString()}`),console.log(`
249
+ Run '${g.dim}codevibe logout${g.reset}' to sign out first.`),process.exit(0);return}console.log("Opening browser for authentication..."),console.log(`${g.dim}Waiting for callback...${g.reset}
250
+ `);let e=await O.login();e&&(console.log(`
251
+ ${g.green}\u2713 Authentication successful!${g.reset}`),console.log(` User: ${e.email}`),console.log(` User ID: ${e.userId}`),console.log(` Expires: ${new Date(e.expiresAt).toLocaleString()}`),await fe(e.userId)),process.exit(0)}catch(r){console.error(`
252
+ ${g.red}\u2717 Authentication failed${g.reset}`),console.error(` Error: ${r.message}`),ye(r)||await R("unknown"),process.exit(1)}}async function nn(){console.log(`${g.cyan}CodeVibe Logout${g.reset}
253
+ `);try{let r=await O.getStatus();if(!r.authenticated){console.log(`${g.yellow}Not logged in.${g.reset}`),process.exit(0);return}let e=r.tokens?.email;await O.logout()?(console.log(`${g.green}\u2713 Logged out successfully.${g.reset}`),console.log(` Previous user: ${e}`),console.log(`
254
+ ${g.dim}Clearing browser session...${g.reset}`)):console.log(`${g.red}\u2717 Failed to log out.${g.reset}`),process.exit(0)}catch(r){console.error(`${g.red}\u2717 Logout failed: ${r.message}${g.reset}`),process.exit(1)}}async function on(){console.log(`${g.cyan}CodeVibe Auth Status${g.reset}
255
+ `);try{let r=await O.getStatus();if(!r.tokens){console.log(`${g.yellow}Not authenticated.${g.reset}`),console.log(`
256
+ Run '${g.dim}codevibe login${g.reset}' to sign in.`),process.exit(0);return}let e=!r.authenticated;console.log(e?`${g.yellow}\u26A0 Token expired${g.reset}`:`${g.green}\u2713 Authenticated${g.reset}`),console.log(` User: ${r.tokens.email}`),console.log(` User ID: ${r.tokens.userId}`),console.log(` Expires: ${new Date(r.tokens.expiresAt).toLocaleString()}`),e&&console.log(`
257
+ ${g.dim}Token will be refreshed automatically.${g.reset}`),process.exit(0)}catch(r){console.error(`${g.red}\u2717 Status check failed: ${r.message}${g.reset}`),process.exit(1)}}async function sn(){console.log(`${g.cyan}CodeVibe Reset Device${g.reset}
258
+ `),console.log(`${g.red}\u26A0 WARNING: This will delete your device identity.${g.reset}`),console.log(`${g.red} Old encrypted sessions will become inaccessible.${g.reset}
259
+ `);let{keychainManager:r}=await Promise.resolve().then(()=>(U(),Pt));try{await r.clearAllData(),console.log(`${g.green}\u2713 Device reset complete.${g.reset}`),console.log(` Run '${g.dim}codevibe login${g.reset}' to set up again.`),process.exit(0)}catch(e){console.error(`${g.red}\u2717 Reset failed: ${e.message}${g.reset}`),process.exit(1)}}function an(){console.log(`CodeVibe Authentication
238
260
  `),console.log("Usage:"),console.log(" codevibe login - Sign in via browser"),console.log(" codevibe logout - Sign out"),console.log(" codevibe status - Show auth status"),console.log(" codevibe reset-device - Reset device identity (destructive)"),console.log(`
239
- Environment:`),console.log(' Set ENVIRONMENT env var to "development" or "production" (default)'),console.log(" Example: ENVIRONMENT=development codevibe login")}async function pe(n){let e=b();console.log(`${p.dim}Environment: ${e}${p.reset}
240
- `);let r=n.slice(2).filter(i=>!i.startsWith("--"))[0];switch(r){case"login":await Lt();break;case"logout":await Ut();break;case"status":await Mt();break;case"reset-device":await Bt();break;default:Wt(),process.exit(r?1:0)}}require.main===module&&pe(process.argv).catch(n=>{console.error("Error:",n),process.exit(1)});q();$();var Ft=/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g;function pt(n){let e=Re(n);if(!e)return null;let t=Ht(e);if(t)return t;let r=qt(e);return r||null}function Re(n){return n.replace(/\r/g,`
241
- `).replace(Ft,"").replace(/[│┌┐└┘─├┤┬┴┼╌╎╭╮╯╰║═╔╗╚╝╠╣╦╩╬]/g," ").replace(/[ \t]+\n/g,`
261
+ Environment:`),console.log(' Set ENVIRONMENT env var to "development" or "production" (default)'),console.log(" Example: ENVIRONMENT=development codevibe login")}async function Te(r){let e=x();console.log(`${g.dim}Environment: ${e}${g.reset}
262
+ `);let n=r.slice(2).filter(i=>!i.startsWith("--"))[0];switch(n){case"login":await rn();break;case"logout":await nn();break;case"status":await on();break;case"reset-device":await sn();break;case"orchestration":{let{runOrchestrationCli:i}=(st(),vt(ir));await i(r);break}default:an(),process.exit(n?1:0)}}require.main===module&&Te(process.argv).catch(r=>{console.error("Error:",r),process.exit(1)});Q();$();var cn=/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g;function or(r){let e=dt(r);if(!e)return null;let t=dn(e);if(t)return t;let n=ln(e);return n||null}function dt(r){return r.replace(/\r/g,`
263
+ `).replace(cn,"").replace(/[│┌┐└┘─├┤┬┴┼╌╎╭╮╯╰║═╔╗╚╝╠╣╦╩╬]/g," ").replace(/[ \t]+\n/g,`
242
264
  `).replace(/\n{3,}/g,`
243
265
 
244
- `).trim()}function Ht(n){let e=n.split(`
245
- `).map(y=>y.trim()),t=jt(e,y=>/\[(?:y\/n|Y\/n|y\/N)\]/.test(y)),r=t>=0?e[t]:null;if(!r)return null;let i=gt(e,t),s=i.length>0?i.join(`
246
- `):r,o=s.toLowerCase(),a=o.includes("what to change")||o.includes("what should")||o.includes("provide")||o.includes("instructions");return{kind:"yes_no",promptText:s,options:a?[{number:"1",text:"Yes"},{number:"2",text:"No, provide instructions"}]:[{number:"1",text:"Yes"},{number:"2",text:"No"}],submitMap:{1:"y",2:"n"},requiresFollowUpText:a}}function qt(n){let e=n.split(`
247
- `).map(d=>d.trim()),t=Vt(e);if(t.length<2)return null;let r=t.map(({line:d})=>ut(d)).filter(d=>!!d),i={};for(let d of r)i[d.number]=d.number;let s=t[0]?.index??-1,o=gt(e,s-1);return{kind:"numbered",promptText:o.length>0?o.join(`
248
- `):"Select an option",options:r,submitMap:i}}function jt(n,e){for(let t=n.length-1;t>=0;t-=1)if(e(n[t]))return t;return-1}function ut(n){let e=n.match(/^(?:[>›❯▸▶➜➤*●]\s*)?(\d+)\.\s+(.*)$/);return e?{number:e[1],text:e[2]}:null}function Vt(n){let e=n.map((r,i)=>({index:i,line:r,parsed:ut(r)})).filter(r=>!!r.parsed);if(e.length===0)return[];let t=[e[e.length-1]];for(let r=e.length-2;r>=0;r-=1){let i=e[r],s=t[0];if(i.index!==s.index-1)break;t.unshift(i)}return t.map(({index:r,line:i})=>({index:r,line:i}))}function gt(n,e){if(e<0)return[];let t=Ce(n,e);if(t<0)return[];let{start:r,end:i}=Ke(n,t),s=n.slice(r,i+1).filter(Boolean);if(zt(s)){let u=Jt(n,r-1);return u.length>0?u:s}if(r<=1)return s;let o=r-1;if(o=Ce(n,o),o<0||o===r-1)return s;let{start:a,end:d}=Ke(n,o),l=n.slice(a,d+1).filter(Boolean);return l.some(yt)?[...l,...s]:s}function yt(n){return/^(?:would you like to|do you want to|the model would like to|action required|confirm)\b/i.test(n)}function Ce(n,e){let t=e;for(;t>=0&&!n[t];)t-=1;return t}function Ke(n,e){let t=e;for(;t>=0&&n[t];)t-=1;return{start:t+1,end:e}}function Jt(n,e){let t=[],r=e;for(;r>=0&&t.length<2&&(r=Ce(n,r),!(r<0));){let{start:s,end:o}=Ke(n,r),a=n.slice(s,o+1).filter(Boolean);a.length>0&&t.unshift(a),r=s-1}if(t.length===0)return[];let i=t.findIndex(s=>s.some(yt));return i>=0?t.slice(i).flat():t[t.length-1]}function zt(n){return n.length===0?!1:n.filter(Gt).length>=Math.max(2,Math.ceil(n.length/2))}function Gt(n){return/^\d+\s/.test(n)}G();P();G();$();async function W(n,e,t,r={}){let i;try{i=await t.getSession(n)}catch(u){return c.warn("[SessionRekey] Failed to fetch session state for re-key",{sessionId:n,error:u instanceof Error?u.message:String(u)}),0}if(!i)return c.warn("[SessionRekey] Session not found, skipping re-key",{sessionId:n}),0;if(!i.isEncrypted)return 0;let s=i.encryptedKeys||[],o=new Set(s.map(u=>u.deviceId)),a=r.forceDeviceIds??new Set,d;try{d=await t.listUserDeviceKeys()}catch(u){return c.warn("[SessionRekey] Failed to fetch user device keys",{sessionId:n,error:u instanceof Error?u.message:String(u)}),0}let l=d.filter(u=>!o.has(u.deviceId)||a.has(u.deviceId));if(l.length===0)return 0;c.info("[SessionRekey] Granting session key to devices",{sessionId:n,existingDeviceCount:s.length,grantCount:l.length,grantDeviceIds:l.map(u=>u.deviceId),forceCount:a.size});let y=0;for(let u of l)try{let S=k.encryptSessionKey(e,u.publicKey);await t.grantSessionKey({sessionId:n,deviceId:u.deviceId,encryptedKey:S.encryptedKey,ephemeralPublicKey:S.ephemeralPublicKey}),y++,c.info("[SessionRekey] Granted session key to device",{sessionId:n,deviceId:u.deviceId,platform:u.platform})}catch(S){c.warn("[SessionRekey] Failed to grant session key to device",{sessionId:n,deviceId:u.deviceId,error:S instanceof Error?S.message:String(S)})}return y>0&&c.info("[SessionRekey] Re-key complete",{sessionId:n,grantedCount:y,requestedCount:l.length}),y}async function ue(n,e,t){try{let r=await e.listUserDeviceKeys();if(r.length===0)return t.info("No device keys found, session will not be encrypted"),null;t.info("Preparing session encryption",{sessionId:n,deviceCount:r.length});let{sessionKey:i,encryptedKeys:s}=g.createSessionKey(r);return t.info("Session encryption prepared",{sessionId:n,deviceCount:s.length}),{sessionKey:i,encryptedKeys:s}}catch(r){return t.warn("Failed to prepare session encryption:",r),null}}async function _e(n,e,t){let{sessionId:r,userId:i,agentType:s,projectPath:o,metadata:a}=n,d=null;try{d=await e.getSession(r)}catch(w){t.warn("Failed to get session (will attempt to create new)",{sessionId:r,error:w})}if(d){t.info("Session exists in backend - reactivating",{sessionId:r,previousStatus:d.status});try{await e.updateSession({sessionId:r,status:"ACTIVE"})}catch(h){t.warn("Failed to reactivate existing session, will continue",{sessionId:r,error:h})}let w=null,z=d.encryptedKeys;if(d.isEncrypted&&z?.length)try{let h=await g.getSessionKey(r,z);h?(w=h,g.cacheSessionKey(r,h),t.info("Session key retrieved for resumed session",{sessionId:r})):t.warn("No encrypted key for this device; proceeding without decryption",{sessionId:r})}catch(h){t.warn("Failed to retrieve session key for resumed session",{sessionId:r,error:h})}if(w)try{let h=await W(r,w,e);h>0&&t.info("Session re-keyed for newly registered devices on resume",{sessionId:r,newDeviceCount:h})}catch(h){t.warn("Session re-key on resume failed (non-fatal)",{sessionId:r,error:h instanceof Error?h.message:String(h)})}return{resumed:!0,sessionKey:w}}let l=await ue(r,e,t),y=o,u=a;l&&(y=k.encryptContent(o,l.sessionKey),u&&Object.keys(u).length>0&&(u={encrypted:k.encryptMetadata(u,l.sessionKey)}),t.info("Session data encrypted",{sessionId:r})),t.info("Creating new session in backend",{sessionId:r,userId:i,agentType:s,isEncrypted:!!l}),await e.createSession({sessionId:r,userId:i,agentType:s,projectPath:y,status:"ACTIVE",metadata:u,isEncrypted:l?!0:void 0,creatorDeviceId:l?await g.getDeviceId():void 0,encryptionVersion:l?1:void 0,encryptedKeys:l?.encryptedKeys});let S=l?.sessionKey||null;return l&&g.cacheSessionKey(r,l.sessionKey),t.info("Session created",{sessionId:r,userId:i,isEncrypted:!!l}),{resumed:!1,sessionKey:S}}P();function Pe(n,e){let t=n.getCurrentUserId(),r=async(s,o)=>{let a=g.getCachedSessionIds();if(a.length===0){e.info("[DeviceKeyWatcher] No active sessions to re-key",{reason:s});return}e.info("[DeviceKeyWatcher] Running re-key pass",{reason:s,activeSessionCount:a.length,forceDeviceCount:o?.size??0});for(let d of a){let l=g.getCachedSessionKey(d);if(l)try{let y=await W(d,l,n,o?{forceDeviceIds:o}:void 0);y>0&&e.info("[DeviceKeyWatcher] Session re-keyed",{sessionId:d,newDeviceCount:y,reason:s})}catch(y){e.warn("[DeviceKeyWatcher] Re-key failed for session (non-fatal)",{sessionId:d,reason:s,error:y instanceof Error?y.message:String(y)})}}},i=n.subscribeToDeviceKeyRegistered(t,s=>{e.info("[DeviceKeyWatcher] New device observed, triggering re-key",{userId:t,newDeviceId:s.deviceId,platform:s.platform,deviceName:s.deviceName}),r(`new-device:${s.deviceId}`,new Set([s.deviceId]))},()=>{r("watcher-reconnect")},s=>{e.warn("[DeviceKeyWatcher] Subscription error (will retry)",{error:s instanceof Error?s.message:String(s)})});return e.info("[DeviceKeyWatcher] Started",{userId:t}),i}P();async function Oe(n,e){try{let t=await g.getDeviceId(),r=await g.getDevicePublicKey(),i=g.getDevicePlatform(),s=g.getDeviceName();e.info("Registering device encryption key",{deviceId:t,platform:i,deviceName:s}),await n.registerDeviceKey(t,r,i,s),g.setIsRegistered(!0),e.info("Device encryption key registered successfully",{deviceId:t})}catch(t){e.warn("Failed to register device encryption key (E2E encryption may not work):",t)}}0&&(module.exports={AgentType,AppSyncClient,AuthService,CryptoError,CryptoService,DeliveryStatus,ENCRYPTION_VERSION,EventSource,EventType,KeychainError,KeychainManager,Logger,SessionStatus,authService,createLogger,cryptoService,errorWasBeaconed,fireAuthCompletedBeacon,fireAuthFailedBeacon,getConfig,getEnvironment,getErrorReason,keychainManager,loadConfig,logger,markErrorBeaconed,mutations,normalizeSnapshot,parseInteractivePrompt,prepareSessionEncryption,queries,registerDeviceEncryptionKey,rekeySessionForNewDevices,resumeOrCreateSession,runAuthCli,startDeviceKeyWatcher,subscriptions});
266
+ `).trim()}function dn(r){let e=r.split(`
267
+ `).map(m=>m.trim()),t=un(e,m=>/\[(?:y\/n|Y\/n|y\/N)\]/.test(m)),n=t>=0?e[t]:null;if(!n)return null;let i=ar(e,t),o=i.length>0?i.join(`
268
+ `):n,s=o.toLowerCase(),a=s.includes("what to change")||s.includes("what should")||s.includes("provide")||s.includes("instructions");return{kind:"yes_no",promptText:o,options:a?[{number:"1",text:"Yes"},{number:"2",text:"No, provide instructions"}]:[{number:"1",text:"Yes"},{number:"2",text:"No"}],submitMap:{1:"y",2:"n"},requiresFollowUpText:a}}function ln(r){let e=r.split(`
269
+ `).map(d=>d.trim()),t=pn(e);if(t.length<2)return null;let n=t.map(({line:d})=>sr(d)).filter(d=>!!d),i={};for(let d of n)i[d.number]=d.number;let o=t[0]?.index??-1,s=ar(e,o-1);return{kind:"numbered",promptText:s.length>0?s.join(`
270
+ `):"Select an option",options:n,submitMap:i}}function un(r,e){for(let t=r.length-1;t>=0;t-=1)if(e(r[t]))return t;return-1}function sr(r){let e=r.match(/^(?:[>›❯▸▶➜➤*●]\s*)?(\d+)\.\s+(.*)$/);return e?{number:e[1],text:e[2]}:null}function pn(r){let e=r.map((n,i)=>({index:i,line:n,parsed:sr(n)})).filter(n=>!!n.parsed);if(e.length===0)return[];let t=[e[e.length-1]];for(let n=e.length-2;n>=0;n-=1){let i=e[n],o=t[0];if(i.index!==o.index-1)break;t.unshift(i)}return t.map(({index:n,line:i})=>({index:n,line:i}))}function ar(r,e){if(e<0)return[];let t=at(r,e);if(t<0)return[];let{start:n,end:i}=ct(r,t),o=r.slice(n,i+1).filter(Boolean);if(mn(o)){let u=gn(r,n-1);return u.length>0?u:o}if(n<=1)return o;let s=n-1;if(s=at(r,s),s<0||s===n-1)return o;let{start:a,end:d}=ct(r,s),l=r.slice(a,d+1).filter(Boolean);return l.some(cr)?[...l,...o]:o}function cr(r){return/^(?:would you like to|do you want to|the model would like to|action required|confirm)\b/i.test(r)}function at(r,e){let t=e;for(;t>=0&&!r[t];)t-=1;return t}function ct(r,e){let t=e;for(;t>=0&&r[t];)t-=1;return{start:t+1,end:e}}function gn(r,e){let t=[],n=e;for(;n>=0&&t.length<2&&(n=at(r,n),!(n<0));){let{start:o,end:s}=ct(r,n),a=r.slice(o,s+1).filter(Boolean);a.length>0&&t.unshift(a),n=o-1}if(t.length===0)return[];let i=t.findIndex(o=>o.some(cr));return i>=0?t.slice(i).flat():t[t.length-1]}function mn(r){return r.length===0?!1:r.filter(fn).length>=Math.max(2,Math.ceil(r.length/2))}function fn(r){return/^\d+\s/.test(r)}de();U();pe();de();$();async function z(r,e,t,n={}){let i;try{i=await t.getSession(r)}catch(u){return c.warn("[SessionRekey] Failed to fetch session state for re-key",{sessionId:r,error:u instanceof Error?u.message:String(u)}),0}if(!i)return c.warn("[SessionRekey] Session not found, skipping re-key",{sessionId:r}),0;if(!i.isEncrypted)return 0;let o=i.encryptedKeys||[],s=new Set(o.map(u=>u.deviceId)),a=n.forceDeviceIds??new Set,d;try{d=await t.listUserDeviceKeys()}catch(u){return c.warn("[SessionRekey] Failed to fetch user device keys",{sessionId:r,error:u instanceof Error?u.message:String(u)}),0}let l=d.filter(u=>!s.has(u.deviceId)||a.has(u.deviceId));if(l.length===0)return 0;c.info("[SessionRekey] Granting session key to devices",{sessionId:r,existingDeviceCount:o.length,grantCount:l.length,grantDeviceIds:l.map(u=>u.deviceId),forceCount:a.size});let m=0;for(let u of l)try{let w=I.encryptSessionKey(e,u.publicKey);await t.grantSessionKey({sessionId:r,deviceId:u.deviceId,encryptedKey:w.encryptedKey,ephemeralPublicKey:w.ephemeralPublicKey}),m++,c.info("[SessionRekey] Granted session key to device",{sessionId:r,deviceId:u.deviceId,platform:u.platform})}catch(w){c.warn("[SessionRekey] Failed to grant session key to device",{sessionId:r,deviceId:u.deviceId,error:w instanceof Error?w.message:String(w)})}return m>0&&c.info("[SessionRekey] Re-key complete",{sessionId:r,grantedCount:m,requestedCount:l.length}),m}async function Pe(r,e,t){try{let n=await e.listUserDeviceKeys();if(n.length===0)return t.info("No device keys found, session will not be encrypted"),null;t.info("Preparing session encryption",{sessionId:r,deviceCount:n.length});let{sessionKey:i,encryptedKeys:o}=y.createSessionKey(n);return t.info("Session encryption prepared",{sessionId:r,deviceCount:o.length}),{sessionKey:i,encryptedKeys:o}}catch(n){return t.warn("Failed to prepare session encryption:",n),null}}async function lt(r,e,t){let{sessionId:n,userId:i,agentType:o,projectPath:s,metadata:a}=r,d=null;try{d=await e.getSession(n)}catch(v){t.warn("Failed to get session (will attempt to create new)",{sessionId:n,error:v})}if(d){t.info("Session exists in backend - reactivating",{sessionId:n,previousStatus:d.status});try{await e.updateSession({sessionId:n,status:"ACTIVE"})}catch(E){t.warn("Failed to reactivate existing session, will continue",{sessionId:n,error:E})}let v=null,W=d.encryptedKeys;if(d.isEncrypted&&W?.length)try{let E=await y.getSessionKey(n,W);E?(v=E,y.cacheSessionKey(n,E),t.info("Session key retrieved for resumed session",{sessionId:n})):t.warn("No encrypted key for this device; proceeding without decryption",{sessionId:n})}catch(E){t.warn("Failed to retrieve session key for resumed session",{sessionId:n,error:E})}if(v)try{let E=await z(n,v,e);E>0&&t.info("Session re-keyed for newly registered devices on resume",{sessionId:n,newDeviceCount:E})}catch(E){t.warn("Session re-key on resume failed (non-fatal)",{sessionId:n,error:E instanceof Error?E.message:String(E)})}return{resumed:!0,sessionKey:v}}let l=await Pe(n,e,t),m=s,u=a;l&&(m=I.encryptContent(s,l.sessionKey),u&&Object.keys(u).length>0&&(u={encrypted:I.encryptMetadata(u,l.sessionKey)}),t.info("Session data encrypted",{sessionId:n})),t.info("Creating new session in backend",{sessionId:n,userId:i,agentType:o,isEncrypted:!!l}),await e.createSession({sessionId:n,userId:i,agentType:o,projectPath:m,status:"ACTIVE",metadata:u,isEncrypted:l?!0:void 0,creatorDeviceId:l?await y.getDeviceId():void 0,encryptionVersion:l?1:void 0,encryptedKeys:l?.encryptedKeys});let w=l?.sessionKey||null;return l&&y.cacheSessionKey(n,l.sessionKey),t.info("Session created",{sessionId:n,userId:i,isEncrypted:!!l}),{resumed:!1,sessionKey:w}}U();function ut(r,e){let t=r.getCurrentUserId(),n=async(o,s)=>{let a=y.getCachedSessionIds();if(a.length===0){e.info("[DeviceKeyWatcher] No active sessions to re-key",{reason:o});return}e.info("[DeviceKeyWatcher] Running re-key pass",{reason:o,activeSessionCount:a.length,forceDeviceCount:s?.size??0});for(let d of a){let l=y.getCachedSessionKey(d);if(l)try{let m=await z(d,l,r,s?{forceDeviceIds:s}:void 0);m>0&&e.info("[DeviceKeyWatcher] Session re-keyed",{sessionId:d,newDeviceCount:m,reason:o})}catch(m){e.warn("[DeviceKeyWatcher] Re-key failed for session (non-fatal)",{sessionId:d,reason:o,error:m instanceof Error?m.message:String(m)})}}},i=r.subscribeToDeviceKeyRegistered(t,o=>{e.info("[DeviceKeyWatcher] New device observed, triggering re-key",{userId:t,newDeviceId:o.deviceId,platform:o.platform,deviceName:o.deviceName}),n(`new-device:${o.deviceId}`,new Set([o.deviceId]))},()=>{n("watcher-reconnect")},o=>{e.warn("[DeviceKeyWatcher] Subscription error (will retry)",{error:o instanceof Error?o.message:String(o)})});return e.info("[DeviceKeyWatcher] Started",{userId:t}),i}U();async function pt(r,e){try{let t=await y.getDeviceId(),n=await y.getDevicePublicKey(),i=y.getDevicePlatform(),o=y.getDeviceName();e.info("Registering device encryption key",{deviceId:t,platform:i,deviceName:o}),await r.registerDeviceKey(t,n,i,o),y.setIsRegistered(!0),e.info("Device encryption key registered successfully",{deviceId:t})}catch(t){e.warn("Failed to register device encryption key (E2E encryption may not work):",t)}}st();var ft={};ce(ft,{ClaudeReviewerProvider:()=>ne,CodexReviewerProvider:()=>oe,GeminiReviewerProvider:()=>ie,MockReviewerSpawner:()=>$e,ReviewerErrorClass:()=>h,ReviewerRegistry:()=>ve,StaticReviewerMock:()=>Ne,SubprocessErrorClass:()=>A,VerdictParseErrorClass:()=>De,createSubprocessReviewerRegistry:()=>mr,parseVerdictOutput:()=>M,runReviewer:()=>B});var h=class r extends Error{constructor(e){super(yn(e)),this.name="ReviewerError",this.detail=e,typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,r)}};function yn(r){switch(r.kind){case"timeout":return`${r.agent} reviewer timed out after ${r.elapsed_ms}ms`;case"spawn_failed":return`${r.agent} reviewer spawn failed: ${r.reason}`;case"parse_failure":return`${r.agent} reviewer output was unparseable`;case"cancelled":return"reviewer cancelled before completion";case"internal_join_failure":return`reviewer task internal join failure: ${r.reason}`}}var De=class r extends Error{constructor(e){super(hn(e)),this.name="VerdictParseError",this.detail=e,typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,r)}};function hn(r){switch(r.kind){case"empty_output":return"reviewer returned an empty reply";case"invalid_verdict":return`first non-blank line ${JSON.stringify(r.found)} is not a valid verdict (expected APPROVE | REJECT | REVISE | ESCALATE)`;case"reasoning_missing":return"reviewer returned a bare verdict with no reasoning";case"revise_missing_changes":return"REVISE verdict requires at least one suggested change in a bulleted list";case"suggested_changes_require_revise":return`suggested changes are reserved for REVISE verdicts; ${JSON.stringify(r.found)} verdict must not carry a bulleted list`}}function M(r){let t=r.replace(/\r\n/g,`
271
+ `).split(`
272
+ `),n=0;for(;n<t.length&&t[n].trim()==="";)n+=1;if(n>=t.length)return{ok:!1,error:{kind:"empty_output"}};let i=t[n];n+=1;let o=vn(i.trim());if(!o.ok)return o;let s=o.kind,a=[],d=[],l=!1;for(;n<t.length;n+=1){let u=t[n];if(wn(u)){l=!0;let v=Sn(u).trimEnd();v.length>0&&d.push(v);continue}let w=bn(u);if(l){if(w==="")continue;let v=d[d.length-1];if(v!==void 0&&(u.startsWith(" ")||u.startsWith(" "))){d[d.length-1]=v+" "+w.trimStart();continue}return{ok:!1,error:{kind:"invalid_verdict",found:w}}}a.push(w)}for(;a.length>0&&a[0]==="";)a.shift();for(;a.length>0&&a[a.length-1]==="";)a.pop();let m=a.join(`
273
+ `);if(m.trim()==="")return{ok:!1,error:{kind:"reasoning_missing"}};if(s==="REVISE"){if(d.length===0)return{ok:!1,error:{kind:"revise_missing_changes"}}}else if(d.length>0)return{ok:!1,error:{kind:"suggested_changes_require_revise",found:s}};return{ok:!0,verdict:{kind:s,reasoning:m,suggested_changes:d}}}function vn(r){let e=r;switch((e.endsWith(":")||e.endsWith("."))&&(e=e.slice(0,-1)),e.toUpperCase()){case"APPROVE":return{ok:!0,kind:"APPROVE"};case"REJECT":return{ok:!0,kind:"REJECT"};case"REVISE":return{ok:!0,kind:"REVISE"};case"ESCALATE":return{ok:!0,kind:"ESCALATE"};default:return{ok:!1,error:{kind:"invalid_verdict",found:r}}}}function wn(r){return r.startsWith("- ")||r.startsWith("* ")}function Sn(r){return r.slice(2).trimStart()}function bn(r){return r.trimEnd()}var dr=require("child_process"),A=class r extends Error{constructor(e){super(En(e)),this.name="SubprocessError",this.detail=e,typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,r)}};function En(r){switch(r.kind){case"spawn_failed":return`failed to spawn subprocess: ${r.reason}`;case"timeout":return`subprocess timed out after ${r.elapsed_ms}ms`;case"io":return`subprocess IO error: ${r.reason}`;case"cancelled":return"subprocess cancelled before completion"}}function B(r){return new Promise((e,t)=>{let n=Date.now(),i;try{i=(0,dr.spawn)(r.command,[...r.args],{env:r.env,cwd:r.cwd,stdio:["pipe","pipe","pipe"],windowsHide:!0})}catch(f){t(new A({kind:"spawn_failed",reason:f instanceof Error?f.message:String(f)}));return}let o=!1,s=[],a=[],d=()=>{try{i.stdin&&!i.stdin.destroyed&&i.stdin.destroy()}catch{}try{i.stdout&&!i.stdout.destroyed&&i.stdout.destroy()}catch{}try{i.stderr&&!i.stderr.destroyed&&i.stderr.destroy()}catch{}},l=()=>{try{i.kill("SIGKILL")}catch{}},m=()=>{},u=()=>{},w=f=>{o||(o=!0,m(),u(),e(f))},v=f=>{o||(o=!0,m(),u(),d(),l(),t(f))};i.stdout.on("data",f=>{s.push(f)}),i.stderr.on("data",f=>{a.push(f)}),i.on("error",f=>{f.code==="ENOENT"||f.code==="EACCES"||f.code==="EPERM"?v(new A({kind:"spawn_failed",reason:f.message})):v(new A({kind:"io",reason:f.message}))}),i.on("close",(f,Sr)=>{if(o)return;let br=Date.now()-n,Er=Buffer.concat(s).toString("utf8"),kr=Buffer.concat(a).toString("utf8");w({stdout:Er,stderr:kr,elapsed_ms:br,exit_success:f===0&&Sr===null})}),i.stdin.on("error",f=>{});try{i.stdin.write(r.prompt,"utf8",()=>{try{i.stdin.end()}catch{}})}catch(f){v(new A({kind:"io",reason:f instanceof Error?f.message:String(f)}));return}let W=setTimeout(()=>{v(new A({kind:"timeout",elapsed_ms:r.timeout_ms}))},r.timeout_ms);u=()=>{clearTimeout(W)};let E=()=>{v(new A({kind:"cancelled"}))};if(r.signal){if(m=()=>{r.signal.removeEventListener("abort",E)},r.signal.aborted){E();return}r.signal.addEventListener("abort",E,{once:!0})}})}var lr=require("uuid");function re(r,e){switch(e.kind){case"spawn_failed":return{kind:"spawn_failed",agent:r,reason:e.reason};case"timeout":return{kind:"timeout",agent:r,elapsed_ms:e.elapsed_ms};case"io":return{kind:"spawn_failed",agent:r,reason:`io error: ${e.reason}`};case"cancelled":return{kind:"cancelled"}}}var ne=class{constructor(e={}){this.executable=e.executable??"claude"}async evaluate(e,t){if(e.agent!=="claude")throw new Error(`ClaudeReviewerProvider called with non-Claude spec (got ${e.agent}); the engine's registry wiring is responsible for dispatch`);let n=kn(this.executable,e),i;try{i=await B({command:n.command,args:n.args,env:n.env,prompt:e.prompt_template,timeout_ms:e.timeout_ms})}catch(o){throw o instanceof A?new h(re(e.agent,o.detail)):o}return An(e,t,i)}};function kn(r,e){let t=[];t.push("--print"),t.push("--allowed-tools",e.tool_allowlist.join(",")),e.model_hint!==null&&t.push("--model",e.model_hint);let n={...process.env,QUORUM_REVIEWER_SUBPROCESS:"1"};return{command:r,args:t,env:n}}function An(r,e,t){if(!t.exit_success)throw new h({kind:"spawn_failed",agent:r.agent,reason:`claude exited with non-zero status; stderr: ${t.stderr.trim()}`});let n=M(t.stdout);if(!n.ok)throw new h({kind:"parse_failure",agent:r.agent,raw_output:t.stdout});return{verdict_id:(0,lr.v4)(),gate_id:e,seat_id:r.seat_id,role:r.role,reviewer_agent:r.agent,verdict:n.verdict.kind,reasoning:n.verdict.reasoning,suggested_changes:n.verdict.suggested_changes,model_used:r.model_hint,tokens_used:null,latency_ms:t.elapsed_ms,submitted_at:new Date().toISOString()}}var ur=require("uuid");var ie=class{constructor(e={}){this.executable=e.executable??"gemini"}async evaluate(e,t){if(e.agent!=="gemini")throw new Error(`GeminiReviewerProvider called with non-Gemini spec (got ${e.agent}); the engine's registry wiring is responsible for dispatch`);let n=Rn(this.executable,e),i;try{i=await B({command:n.command,args:n.args,env:n.env,prompt:e.prompt_template,timeout_ms:e.timeout_ms})}catch(o){throw o instanceof A?new h(re(e.agent,o.detail)):o}return In(e,t,i)}};function Rn(r,e){let t=[];t.push("-p",""),t.push("--approval-mode","plan"),t.push("--output-format","json"),e.model_hint!==null&&t.push("--model",e.model_hint);let n={...process.env,QUORUM_REVIEWER_SUBPROCESS:"1"};return{command:r,args:t,env:n}}function In(r,e,t){if(!t.exit_success)throw new h({kind:"spawn_failed",agent:r.agent,reason:`gemini exited with non-zero status; stderr: ${t.stderr.trim()}`});let n=Cn(t.stdout);if(n===null)throw new h({kind:"parse_failure",agent:r.agent,raw_output:t.stdout});let i=M(n.response);if(!i.ok)throw new h({kind:"parse_failure",agent:r.agent,raw_output:n.response});let o=xn(n);return{verdict_id:(0,ur.v4)(),gate_id:e,seat_id:r.seat_id,role:r.role,reviewer_agent:r.agent,verdict:i.verdict.kind,reasoning:i.verdict.reasoning,suggested_changes:i.verdict.suggested_changes,model_used:r.model_hint,tokens_used:o,latency_ms:t.elapsed_ms,submitted_at:new Date().toISOString()}}function xn(r){let e=r.stats?.models;if(!e)return null;let t=[];for(let n of Object.values(e)){let i=n.tokens?.total;typeof i=="number"&&t.push(i)}return t.length===0?null:t.reduce((n,i)=>n+i,0)}function Cn(r){let e=r.indexOf("{");if(e<0)return null;let t=0,n=!1,i=!1;for(let o=e;o<r.length;o+=1){let s=r[o];if(i){i=!1;continue}if(n){s==="\\"?i=!0:s==='"'&&(n=!1);continue}if(s==='"'){n=!0;continue}if(s==="{")t+=1;else if(s==="}"&&(t-=1,t===0)){let a=r.slice(e,o+1),d;try{d=JSON.parse(a)}catch{return null}return _n(d)}}return null}function _n(r){if(typeof r!="object"||r===null||Array.isArray(r))return null;let e=r;return typeof e.response!="string"?null:e}var Oe=S(require("fs")),pr=S(require("os")),gr=S(require("path")),gt=require("uuid");var oe=class{constructor(e={}){this.executable=e.executable??"codex"}async evaluate(e,t){if(e.agent!=="codex")throw new Error(`CodexReviewerProvider called with non-Codex spec (got ${e.agent}); the engine's registry wiring is responsible for dispatch`);let n=Kn(),i=Tn(this.executable,e,n),o;try{o=await B({command:i.command,args:i.args,env:i.env,prompt:e.prompt_template,timeout_ms:e.timeout_ms})}catch(a){throw Ke(n),a instanceof A?new h(re(e.agent,a.detail)):a}if(!o.exit_success)throw Ke(n),new h({kind:"spawn_failed",agent:e.agent,reason:`codex exited with non-zero status; stderr: ${o.stderr.trim()}`});let s;try{s=Oe.readFileSync(n,"utf8")}catch(a){Ke(n);let d=a instanceof Error?a.message:String(a);throw new h({kind:"parse_failure",agent:e.agent,raw_output:`codex exited 0 but --output-last-message file unreadable (${d}): stdout follows
274
+ ${o.stdout}`})}return Ke(n),Pn(e,t,o,s)}};function Tn(r,e,t){let n=[];n.push("exec"),n.push("--sandbox","read-only"),n.push("--skip-git-repo-check"),n.push("--color","never"),n.push("--json"),n.push("--ephemeral"),n.push("--output-last-message",t),e.model_hint!==null&&n.push("--model",e.model_hint),n.push("-");let i={...process.env,QUORUM_REVIEWER_SUBPROCESS:"1"};return{command:r,args:n,env:i}}function Pn(r,e,t,n){if(!t.exit_success)throw new h({kind:"spawn_failed",agent:r.agent,reason:`codex exited with non-zero status; stderr: ${t.stderr.trim()}`});let i=M(n);if(!i.ok)throw new h({kind:"parse_failure",agent:r.agent,raw_output:n});let o=Dn(t.stdout);return{verdict_id:(0,gt.v4)(),gate_id:e,seat_id:r.seat_id,role:r.role,reviewer_agent:r.agent,verdict:i.verdict.kind,reasoning:i.verdict.reasoning,suggested_changes:i.verdict.suggested_changes,model_used:r.model_hint,tokens_used:o,latency_ms:t.elapsed_ms,submitted_at:new Date().toISOString()}}function Dn(r){let e=[];for(let t of r.split(`
275
+ `)){let n=t.trim();if(n==="")continue;let i;try{i=JSON.parse(n)}catch{continue}if(i.type==="turn.completed"&&i.usage){let o=i.usage.input_tokens??0,s=i.usage.output_tokens??0;e.push(o+s)}}return e.length===0?null:e.reduce((t,n)=>t+n,0)}function Kn(){return gr.join(pr.tmpdir(),`quorum-codex-last-${process.pid}-${(0,gt.v4)()}.txt`)}function Ke(r){try{Oe.unlinkSync(r)}catch{}}var ve=class{constructor(){this.providers=new Map}with(e,t){return this.providers.set(e,t),this}register(e,t){this.providers.set(e,t)}providerFor(e){return this.providers.get(e)}registeredAgents(){return Array.from(this.providers.keys())}async evaluate(e,t){let n=this.providers.get(e.agent);if(n===void 0)throw new h({kind:"spawn_failed",agent:e.agent,reason:`no provider registered for ${e.agent} \u2014 registry was built without a ${e.agent} entry but the policy snapshot includes a ${e.agent} reviewer`});return n.evaluate(e,t)}};function mr(){return new ve().with("claude",new ne).with("gemini",new ie).with("codex",new oe)}var mt=require("uuid");var $e=class r{constructor(){this.scripts=new Map}static key(e,t){return`${e}|${t}`}scriptVerdict(e,t,n,i){this.scriptVerdictWithChanges(e,t,n,i,[])}scriptVerdictWithChanges(e,t,n,i,o){let s=r.key(e,t),a=this.scripts.get(s)??[];a.push({type:"verdict",kind:n,reasoning:i,suggested_changes:o}),this.scripts.set(s,a)}scriptError(e,t,n){let i=r.key(e,t),o=this.scripts.get(i)??[];o.push({type:"error",error:n}),this.scripts.set(i,o)}remaining(e,t){let n=r.key(e,t);return this.scripts.get(n)?.length??0}async evaluate(e,t){let n=r.key(e.agent,t),i=this.scripts.get(n),o=i&&i.length>0?i.shift():null;if(o===null)throw new h({kind:"spawn_failed",agent:e.agent,reason:`no scripted response for (${e.agent}, gate=${t}); test forgot to wire a reviewer`});if(o.type==="error")throw new h(o.error);return{verdict_id:(0,mt.v4)(),gate_id:t,seat_id:e.seat_id,role:e.role,reviewer_agent:e.agent,verdict:o.kind,reasoning:o.reasoning,suggested_changes:o.suggested_changes,model_used:`mock-${e.agent}`,tokens_used:0,latency_ms:0,submitted_at:new Date().toISOString()}}};function fr(){return{type:"verdict",kind:"APPROVE",reasoning:"static mock: approve",suggested_changes:[]}}function yr(){return{type:"verdict",kind:"REJECT",reasoning:"static mock: reject",suggested_changes:[]}}function hr(r){return{type:"verdict",kind:"REVISE",reasoning:"static mock: revise",suggested_changes:r.length===0?["static mock: placeholder revision"]:r}}function vr(){return{type:"verdict",kind:"ESCALATE",reasoning:"static mock: escalate",suggested_changes:[]}}var Ne=class r{constructor(){this.defaultResponse=null;this.perAgent=new Map}static new(){return new r}static allApprove(){let e=new r;return e.defaultResponse=fr(),e}static allReject(){let e=new r;return e.defaultResponse=yr(),e}static allRevise(e){let t=new r;return t.defaultResponse=hr(e),t}static allEscalate(){let e=new r;return e.defaultResponse=vr(),e}static allError(e){let t=new r;return t.defaultResponse={type:"error",error:e},t}withAgentVerdict(e,t){let n;switch(t){case"APPROVE":n=fr();break;case"REJECT":n=yr();break;case"REVISE":n=hr([]);break;case"ESCALATE":n=vr();break}return this.perAgent.set(e,n),this}withAgentError(e,t){return this.perAgent.set(e,{type:"error",error:t}),this}async evaluate(e,t){let n=this.perAgent.get(e.agent)??this.defaultResponse;if(n===null)throw new h({kind:"spawn_failed",agent:e.agent,reason:`StaticReviewerMock has no response configured for ${e.agent} (set a default via allApprove() / allReject() / etc., or an override via withAgentVerdict() / withAgentError())`});if(n.type==="error")throw new h(n.error);return{verdict_id:(0,mt.v4)(),gate_id:t,seat_id:e.seat_id,role:e.role,reviewer_agent:e.agent,verdict:n.kind,reasoning:n.reasoning,suggested_changes:n.suggested_changes,model_used:`static-mock-${e.agent}`,tokens_used:0,latency_ms:0,submitted_at:new Date().toISOString()}}};var yt={};ce(yt,{dedupKeyForDestructiveActionEscalated:()=>jn,dedupKeyForFlagBadApproval:()=>qn,dedupKeyForProgressEvent:()=>Vn,dedupKeyForTaskCreated:()=>Bn,dedupKeyForTaskTerminated:()=>Wn,dedupKeyForToolUse:()=>Fn});var wr=require("node:crypto"),On="task_created",$n="task_terminated",Nn="progress",Un="tool_use",Ln="destructive_escalated",Mn="flag_bad_approval";function se(r){if(r.length!==36)throw new Error(`UUID must be 36 chars (got ${r.length}): ${r}`);if(r[8]!=="-"||r[13]!=="-"||r[18]!=="-"||r[23]!=="-")throw new Error(`UUID dashes misplaced: ${r}`);let e=r.replace(/-/g,"");if(!/^[0-9a-fA-F]{32}$/.test(e))throw new Error(`UUID contains non-hex characters: ${r}`);return Buffer.from(e,"hex")}function ae(r){let e=(0,wr.createHash)("sha256");for(let t of r)typeof t=="string"?e.update(t,"utf8"):e.update(t);return e.digest("hex")}function Bn(r){return ae([se(r),On])}function Wn(r){return ae([se(r),$n])}function Vn(r,e){return ae([se(r),Nn,e])}function Fn(r,e){return ae([se(r),Un,e])}function jn(r,e){return ae([se(r),Ln,e])}function qn(r){return ae([se(r),Mn])}pe();0&&(module.exports={AgentType,AppSyncClient,AuditKeys,AuthService,CryptoError,CryptoService,DeliveryStatus,ENCRYPTION_VERSION,EventSource,EventType,KeychainError,KeychainManager,Logger,Reviewer,ReviewerRole,SessionStatus,applyPerSessionOrchestrationOverride,authService,createLogger,cryptoService,detectInstalledAgents,errorWasBeaconed,fireAuthCompletedBeacon,fireAuthFailedBeacon,getConfig,getEnvironment,getErrorReason,keychainManager,loadConfig,logger,markErrorBeaconed,mutations,normalizeSnapshot,parseInteractivePrompt,prepareSessionEncryption,pushDetectedAgents,queries,registerDeviceEncryptionKey,rekeySessionForNewDevices,resumeOrCreateSession,runAuthCli,runOrchestrationCli,startDeviceKeyWatcher,subscriptions});
@@ -0,0 +1,56 @@
1
+ import { Logger } from '../logger';
2
+ import { AppSyncClient } from '../appsync';
3
+ export type DetectableAgent = 'CLAUDE' | 'GEMINI' | 'CODEX';
4
+ /**
5
+ * Returns the subset of agents present on PATH. Uses `command -v`
6
+ * (POSIX-standard) rather than `which` for portability across macOS
7
+ * and Linux. Runs synchronously — the whole probe is <10ms in practice
8
+ * even when agents are absent.
9
+ *
10
+ * Safe to call repeatedly; no caching here because the set of
11
+ * installed agents CAN change between plugin launches (user installs
12
+ * a new agent) and the caller decides how often to re-probe.
13
+ */
14
+ export declare function detectInstalledAgents(): DetectableAgent[];
15
+ /**
16
+ * Detect-and-push convenience for plugin daemon startup. All three
17
+ * plugins (Claude, Gemini, Codex) call this once at start(). Runs
18
+ * the local PATH probe, then pushes the set to the backend via
19
+ * updateAvailableAgents. Idempotent — the backend dedupes and stores.
20
+ * Non-fatal on the network failure path (caller should `.catch()`
21
+ * and log but not abort startup — Quorum 2.0 auto-enable degrades
22
+ * to "use last-pushed agent set" when the mutation fails).
23
+ *
24
+ * @param client AppSyncClient that's already been authenticated via
25
+ * authenticateWithStoredTokens()
26
+ * @param log Logger — warn-level when no agents detected, info
27
+ * on success
28
+ */
29
+ export declare function pushDetectedAgents(client: AppSyncClient, log: Pick<Logger, 'info' | 'warn'>): Promise<void>;
30
+ /**
31
+ * Quorum 2.0 (2f.0.a.6) per-session orchestration CLI override applier.
32
+ * All three plugin wrappers (`codevibe-claude`, `codevibe-gemini`,
33
+ * `codevibe-codex`) export `CODEVIBE_ORCHESTRATION_OVERRIDE=true|false`
34
+ * to the tmux env when the user passes `--orchestration` /
35
+ * `--no-orchestration`. The daemon inherits this via the hook env
36
+ * chain and calls THIS function after every session-creation site
37
+ * to pin the per-session decision — wins outright over the server's
38
+ * User.orchestrationEnabledDefault auto-populate.
39
+ *
40
+ * Called from each plugin's daemon at every session-creation call
41
+ * site. Claude has one (handleSessionStart covers new + /resume
42
+ * because Claude Code fires SessionStart on /resume). Gemini has
43
+ * two (handleSessionStart + switchToResumedSession — /resume doesn't
44
+ * fire SessionStart in Gemini). Codex has two (createLaunchSession
45
+ * + handleSessionStarted — launch session gets replaced by runtime
46
+ * session_meta).
47
+ *
48
+ * Non-fatal on error — a failed override doesn't block session setup;
49
+ * the server's auto-populate decision stands and the user can flip
50
+ * the session via mobile toggle after the fact.
51
+ *
52
+ * @param client AppSyncClient authenticated for the session's owner
53
+ * @param sessionId Backend session ID (post-resumeOrCreateSession)
54
+ * @param log Logger
55
+ */
56
+ export declare function applyPerSessionOrchestrationOverride(client: AppSyncClient, sessionId: string, log: Pick<Logger, 'info' | 'warn'>): Promise<void>;
@@ -0,0 +1,2 @@
1
+ export { detectInstalledAgents, pushDetectedAgents, applyPerSessionOrchestrationOverride, type DetectableAgent, } from './detect-agents';
2
+ export { runOrchestrationCli } from './orchestration-cli';
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Dispatch for the `orchestration` subcommand. Called by runAuthCli
3
+ * when it sees `argv[2] === 'orchestration'`. Supports four sub-actions:
4
+ * enable — set orchestrationEnabledDefault = true
5
+ * disable — set orchestrationEnabledDefault = false
6
+ * status — print current policy snapshot + installed agents
7
+ * configure — interactive wizard (toggle + panel customization)
8
+ */
9
+ export declare function runOrchestrationCli(argv: string[]): Promise<void>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};