@quantiya/codevibe-claude-plugin 1.0.12 → 1.0.14
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.
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codevibe-claude",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.14",
|
|
4
4
|
"description": "Sync Claude Code sessions with iOS mobile app via AWS backend. Control Claude Code from your phone with real-time bidirectional synchronization.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "CodeVibe Team"
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
"use strict";var _e=Object.create;var J=Object.defineProperty;var Me=Object.getOwnPropertyDescriptor;var Be=Object.getOwnPropertyNames;var Fe=Object.getPrototypeOf,qe=Object.prototype.hasOwnProperty;var x=(r,e)=>()=>(r&&(e=r(r=0)),e);var me=(r,e)=>{for(var t in e)J(r,t,{get:e[t],enumerable:!0})},ye=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Be(e))!qe.call(r,s)&&s!==t&&J(r,s,{get:()=>e[s],enumerable:!(n=Me(e,s))||n.enumerable});return r};var f=(r,e,t)=>(t=r!=null?_e(Fe(r)):{},ye(e||!r||!r.__esModule?J(t,"default",{value:r,enumerable:!0}):t,r)),He=r=>ye(J({},"__esModule",{value:!0}),r);var v,C,te,Ve,N,b,fe=x(()=>{"use strict";v=f(require("crypto")),C=class extends Error{constructor(e){super(e),this.name="CryptoError"}},te=1,Ve="CodeVibe E2E v1",N=class r{constructor(){}static getInstance(){return r.instance||(r.instance=new r),r.instance}generateKeyPair(){let e=v.createECDH("prime256v1");e.generateKeys();let n=e.getPublicKey().subarray(1).toString("base64");return{privateKey:e.getPrivateKey().toString("base64"),publicKey:n}}generateSessionKey(){return v.randomBytes(32).toString("base64")}deriveSharedKey(e,t){try{let n=v.createECDH("prime256v1"),s=Buffer.from(e,"base64");n.setPrivateKey(s);let i=Buffer.concat([Buffer.from([4]),Buffer.from(t,"base64")]),o=n.computeSecret(i),a=v.hkdfSync("sha256",o,Buffer.alloc(0),Buffer.from(Ve,"utf8"),32);return Buffer.from(a)}catch(n){throw new C(`Failed to derive shared key: ${n}`)}}encryptSessionKey(e,t){let n=this.generateKeyPair(),s=this.deriveSharedKey(n.privateKey,t),i=Buffer.from(e,"base64");return{encryptedKey:this.encrypt(i,s).toString("base64"),ephemeralPublicKey:n.publicKey}}decryptSessionKey(e,t){let n=this.deriveSharedKey(t,e.ephemeralPublicKey),s=Buffer.from(e.encryptedKey,"base64");return this.decrypt(s,n).toString("base64")}encryptContent(e,t){let n=Buffer.from(t,"base64"),s=Buffer.from(e,"utf8");return this.encrypt(s,n).toString("base64")}decryptContent(e,t){let n=Buffer.from(t,"base64"),s=Buffer.from(e,"base64");return this.decrypt(s,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=v.randomBytes(12),s=v.createCipheriv("aes-256-gcm",t,n),i=Buffer.concat([s.update(e),s.final()]),o=s.getAuthTag();return Buffer.concat([n,i,o])}decrypt(e,t){let n=e.subarray(0,12),s=e.subarray(e.length-16),i=e.subarray(12,e.length-16),o=v.createDecipheriv("aes-256-gcm",t,n);o.setAuthTag(s);try{return Buffer.concat([o.update(i),o.final()])}catch{throw new C("Decryption failed: Invalid ciphertext or authentication tag")}}serializePrivateKey(e){return e}deserializePrivateKey(e){return e}},b=N.getInstance()});var z=x(()=>{"use strict";fe()});function h(){let r=process.env.ENVIRONMENT;return r==="development"||r==="production"?r:"production"}function Y(r){let e=r||h();return G={...D[e],aws:{...D[e].aws,region:process.env.AWS_REGION||D[e].aws.region,appsyncUrl:process.env.APPSYNC_URL||D[e].aws.appsyncUrl,cognitoUserPoolId:process.env.COGNITO_USER_POOL_ID||D[e].aws.cognitoUserPoolId,cognitoClientId:process.env.COGNITO_CLIENT_ID||D[e].aws.cognitoClientId,cognitoDomain:process.env.COGNITO_DOMAIN||D[e].aws.cognitoDomain}},he=!0,G}function y(){return(!he||!G)&&Y(),G}var F,q,D,G,he,ve=x(()=>{"use strict";F=f(require("os")),q=f(require("path")),D={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:q.default.join(F.default.homedir(),".codex","sessions"),approvalTimeoutMs:5e3},gemini:{command:"gemini",defaultTimeout:6e4,transcriptDir:q.default.join(F.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:q.default.join(F.default.homedir(),".codex","sessions"),approvalTimeoutMs:5e3},gemini:{command:"gemini",defaultTimeout:6e4,transcriptDir:q.default.join(F.default.homedir(),".gemini","tmp")}}},G=null,he=!1});var O=x(()=>{"use strict";ve()});function ne(r){return new P(r)}var R,X,be,Se,P,c,we=x(()=>{"use strict";R=f(require("fs")),X=f(require("path")),be=f(require("os")),Se={debug:0,info:1,warn:2,error:3}
|
|
2
|
-
|
|
3
|
-
`));
|
|
1
|
+
"use strict";var _e=Object.create;var J=Object.defineProperty;var Me=Object.getOwnPropertyDescriptor;var Be=Object.getOwnPropertyNames;var Fe=Object.getPrototypeOf,qe=Object.prototype.hasOwnProperty;var x=(r,e)=>()=>(r&&(e=r(r=0)),e);var me=(r,e)=>{for(var t in e)J(r,t,{get:e[t],enumerable:!0})},ye=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Be(e))!qe.call(r,s)&&s!==t&&J(r,s,{get:()=>e[s],enumerable:!(n=Me(e,s))||n.enumerable});return r};var f=(r,e,t)=>(t=r!=null?_e(Fe(r)):{},ye(e||!r||!r.__esModule?J(t,"default",{value:r,enumerable:!0}):t,r)),He=r=>ye(J({},"__esModule",{value:!0}),r);var v,C,te,Ve,N,b,fe=x(()=>{"use strict";v=f(require("crypto")),C=class extends Error{constructor(e){super(e),this.name="CryptoError"}},te=1,Ve="CodeVibe E2E v1",N=class r{constructor(){}static getInstance(){return r.instance||(r.instance=new r),r.instance}generateKeyPair(){let e=v.createECDH("prime256v1");e.generateKeys();let n=e.getPublicKey().subarray(1).toString("base64");return{privateKey:e.getPrivateKey().toString("base64"),publicKey:n}}generateSessionKey(){return v.randomBytes(32).toString("base64")}deriveSharedKey(e,t){try{let n=v.createECDH("prime256v1"),s=Buffer.from(e,"base64");n.setPrivateKey(s);let i=Buffer.concat([Buffer.from([4]),Buffer.from(t,"base64")]),o=n.computeSecret(i),a=v.hkdfSync("sha256",o,Buffer.alloc(0),Buffer.from(Ve,"utf8"),32);return Buffer.from(a)}catch(n){throw new C(`Failed to derive shared key: ${n}`)}}encryptSessionKey(e,t){let n=this.generateKeyPair(),s=this.deriveSharedKey(n.privateKey,t),i=Buffer.from(e,"base64");return{encryptedKey:this.encrypt(i,s).toString("base64"),ephemeralPublicKey:n.publicKey}}decryptSessionKey(e,t){let n=this.deriveSharedKey(t,e.ephemeralPublicKey),s=Buffer.from(e.encryptedKey,"base64");return this.decrypt(s,n).toString("base64")}encryptContent(e,t){let n=Buffer.from(t,"base64"),s=Buffer.from(e,"utf8");return this.encrypt(s,n).toString("base64")}decryptContent(e,t){let n=Buffer.from(t,"base64"),s=Buffer.from(e,"base64");return this.decrypt(s,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=v.randomBytes(12),s=v.createCipheriv("aes-256-gcm",t,n),i=Buffer.concat([s.update(e),s.final()]),o=s.getAuthTag();return Buffer.concat([n,i,o])}decrypt(e,t){let n=e.subarray(0,12),s=e.subarray(e.length-16),i=e.subarray(12,e.length-16),o=v.createDecipheriv("aes-256-gcm",t,n);o.setAuthTag(s);try{return Buffer.concat([o.update(i),o.final()])}catch{throw new C("Decryption failed: Invalid ciphertext or authentication tag")}}serializePrivateKey(e){return e}deserializePrivateKey(e){return e}},b=N.getInstance()});var z=x(()=>{"use strict";fe()});function h(){let r=process.env.ENVIRONMENT;return r==="development"||r==="production"?r:"production"}function Y(r){let e=r||h();return G={...D[e],aws:{...D[e].aws,region:process.env.AWS_REGION||D[e].aws.region,appsyncUrl:process.env.APPSYNC_URL||D[e].aws.appsyncUrl,cognitoUserPoolId:process.env.COGNITO_USER_POOL_ID||D[e].aws.cognitoUserPoolId,cognitoClientId:process.env.COGNITO_CLIENT_ID||D[e].aws.cognitoClientId,cognitoDomain:process.env.COGNITO_DOMAIN||D[e].aws.cognitoDomain}},he=!0,G}function y(){return(!he||!G)&&Y(),G}var F,q,D,G,he,ve=x(()=>{"use strict";F=f(require("os")),q=f(require("path")),D={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:q.default.join(F.default.homedir(),".codex","sessions"),approvalTimeoutMs:5e3},gemini:{command:"gemini",defaultTimeout:6e4,transcriptDir:q.default.join(F.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:q.default.join(F.default.homedir(),".codex","sessions"),approvalTimeoutMs:5e3},gemini:{command:"gemini",defaultTimeout:6e4,transcriptDir:q.default.join(F.default.homedir(),".gemini","tmp")}}},G=null,he=!1});var O=x(()=>{"use strict";ve()});function We(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 ne(r){return new P(r)}var R,X,be,Se,P,c,we=x(()=>{"use strict";R=f(require("fs")),X=f(require("path")),be=f(require("os")),Se={debug:0,info:1,warn:2,error:3};P=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=X.dirname(this.logFile);R.existsSync(e)||R.mkdirSync(e,{recursive:!0})}}shouldLog(e){return Se[e]>=Se[this.level]}formatMessage(e,t,n){let s=new Date().toISOString(),i=e.toUpperCase().padEnd(5),o=`[${s}] [${i}] [${this.name}] ${t}`;return n!==void 0&&(n instanceof Error?(o+=` ${n.name}: ${n.message}`,n.stack&&(o+=`
|
|
2
|
+
${n.stack}`)):typeof n=="object"?o+=` ${JSON.stringify(n,We)}`:o+=` ${n}`),o}log(e,t,n){if(!this.shouldLog(e))return;let s=this.formatMessage(e,t,n);if(this.logFile)try{R.appendFileSync(this.logFile,s+`
|
|
3
|
+
`)}catch{}if(this.enableConsole)switch(e){case"error":console.error(s);break;case"warn":console.warn(s);break;default:console.log(s)}}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 P({name:"codevibe-core",logFile:X.join(be.tmpdir(),"codevibe-core.log"),level:"info"})});var H=x(()=>{"use strict";we()});var Q,Ee,I,k,re,je,K,g,ke=x(()=>{"use strict";Q=f(require("os")),Ee=require("uuid"),I=f(require("keytar"));z();O();H();k=class extends Error{constructor(e){super(e),this.name="KeychainError"}},re="device-identity",je="tokens-",K=class r{constructor(){this.deviceIdentity=null;this.sessionKeyCache=new Map;this.isRegistered=!1;this._serviceName=null}get serviceName(){return this._serviceName||(this._serviceName=y().keychain.serviceName),this._serviceName}static getInstance(){return r.instance||(r.instance=new r),r.instance}async getDeviceIdentity(){if(this.deviceIdentity)return this.deviceIdentity;try{let e=await I.getPassword(this.serviceName,re);return e?(this.deviceIdentity=JSON.parse(e),c.info(`[KeychainManager] Loaded device identity: ${this.deviceIdentity.deviceId}`),this.deviceIdentity):null}catch(e){return c.error(`[KeychainManager] Failed to load device identity: ${e}`),null}}async setDeviceIdentity(e){try{await I.setPassword(this.serviceName,re,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=b.generateKeyPair();return e={deviceId:(0,Ee.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 I.deletePassword(this.serviceName,re),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`${je}${e}`}async getTokens(e="production"){try{let t=await I.getPassword(this.serviceName,this.getTokenAccount(e));if(!t)return null;let n=JSON.parse(t);return c.debug(`[KeychainManager] Loaded tokens for ${e}`),n}catch(t){return c.error(`[KeychainManager] Failed to load tokens: ${t}`),null}}async setTokens(e,t="production"){try{await I.setPassword(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 I.deletePassword(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 s=await this.getDeviceId(),i=t.find(p=>p.deviceId===s);if(!i)return c.warn(`[KeychainManager] Device ${s} not found in encryptedKeys`),null;let o=await this.getDevicePrivateKey(),a=b.decryptSessionKey(i,o);return this.sessionKeyCache.set(e,a),c.info(`[KeychainManager] Decrypted and cached session key for ${e}`),a}createSessionKey(e){let t=b.generateSessionKey(),n=e.map(s=>{let i=b.encryptSessionKey(t,s.publicKey);return{deviceId:s.deviceId,encryptedKey:i.encryptedKey,ephemeralPublicKey:i.ephemeralPublicKey}});return c.info(`[KeychainManager] Created session key for ${e.length} devices`),{sessionKey:t,encryptedKeys:n}}cacheSessionKey(e,t){this.sessionKeyCache.set(e,t)}clearSessionKey(e){this.sessionKeyCache.delete(e)}clearAllSessionKeys(){this.sessionKeyCache.clear()}getIsRegistered(){return this.isRegistered}setIsRegistered(e){this.isRegistered=e}getDeviceName(){return Q.hostname()||"CLI Client"}getDevicePlatform(){let e=Q.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=K.getInstance()});var Ie={};me(Ie,{KeychainError:()=>k,KeychainManager:()=>K,keychainManager:()=>g});var U=x(()=>{"use strict";ke()});var ct={};me(ct,{AgentType:()=>De,AppSyncClient:()=>W,AuthService:()=>M,CryptoError:()=>C,CryptoService:()=>N,DeliveryStatus:()=>Ce,ENCRYPTION_VERSION:()=>te,EventSource:()=>se,EventType:()=>Ae,KeychainError:()=>k,KeychainManager:()=>K,Logger:()=>P,SessionStatus:()=>ie,authService:()=>T,createLogger:()=>ne,cryptoService:()=>b,getConfig:()=>y,getEnvironment:()=>h,keychainManager:()=>g,loadConfig:()=>Y,logger:()=>c,mutations:()=>E,normalizeSnapshot:()=>ue,parseInteractivePrompt:()=>Oe,prepareSessionEncryption:()=>ee,queries:()=>$,resumeOrCreateSession:()=>ge,runAuthCli:()=>Z,subscriptions:()=>V});module.exports=He(ct);U();z();var oe=f(require("ws")),ae=require("uuid");O();H();U();var Te=f(require("dns")),xe=f(require("fs"));if(Je())try{Te.setDefaultResultOrder("ipv4first")}catch{}function Je(){if(process.platform!=="linux")return!1;try{let r=xe.readFileSync("/proc/sys/kernel/osrelease","utf8");return/microsoft|wsl/i.test(r)}catch{return!1}}async function L(r,e,t){try{return await fetch(r,e)}catch(n){let s=n?.cause?.code,i=n?.cause?.message,o=s||i||n?.message||"unknown",a=ze(s),p=t?`${t}: `:"",l=`Node ${process.version} on ${process.platform}`,m=[`${p}Cannot reach ${r}`,` Underlying error: ${o}`];a&&m.push(` Suggested fix: ${a}`),m.push(` Platform: ${l}`);let u=new Error(m.join(`
|
|
4
|
+
`));throw u.cause=n,u}}function ze(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 $={getSession:`
|
|
4
5
|
query GetSession($sessionId: ID!) {
|
|
5
6
|
getSession(sessionId: $sessionId) {
|
|
6
7
|
sessionId
|
|
@@ -163,7 +164,7 @@
|
|
|
163
164
|
isEncrypted
|
|
164
165
|
}
|
|
165
166
|
}
|
|
166
|
-
`};var Ae=(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))(Ae||{}),se=(t=>(t.DESKTOP="DESKTOP",t.MOBILE="MOBILE",t))(se||{}),Ce=(n=>(n.SENT="SENT",n.DELIVERED="DELIVERED",n.EXECUTED="EXECUTED",n))(Ce||{});var ie=(n=>(n.ACTIVE="ACTIVE",n.INACTIVE="INACTIVE",n.PAUSED="PAUSED",n))(ie||{}),De=(n=>(n.CLAUDE="CLAUDE",n.GEMINI="GEMINI",n.CODEX="CODEX",n))(De||{});var _={urgentMaxAttempts:10,baseDelayMs:1e3,maxDelayMs:6e4,backoffMultiplier:2,persistentDelayMs:300*1e3},W=class{constructor(){this.authenticated=!1;this.currentUserId=null;this.currentEmail=null;this.tokens=null;this.activeSubscriptions=new Map;this.heartbeatTimers=new Map;this.environment=h(),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 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){try{let t=y(),n=`https://${t.aws.cognitoDomain}/oauth2/token`,s=new URLSearchParams({grant_type:"refresh_token",client_id:t.aws.cognitoClientId,refresh_token:e.refreshToken}),i=await L(n,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:s.toString()},"Token refresh");if(!i.ok)return c.error("[AppSyncClient] Token refresh failed",{status:i.status}),!1;let o=await i.json(),a={...e,accessToken:o.access_token,idToken:o.id_token,expiresAt:Date.now()+o.expires_in*1e3};return await g.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 s=y();if(!this.tokens?.idToken)throw new Error('Not authenticated. Run "codevibe login" first.');let i={"Content-Type":"application/json",Authorization:this.tokens.idToken},o=await L(s.aws.appsyncUrl,{method:"POST",headers:i,body:JSON.stringify({query:e,variables:t})},"AppSync GraphQL request"),a=await o.json();if(o.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(!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},n=await this.graphqlRequest(E.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(E.updateSession,{input:t});return c.debug("[AppSyncClient] Session updated",{sessionId:n.data.updateSession.sessionId}),n.data.updateSession}async getSession(e){return(await this.graphqlRequest($.getSession,{sessionId:e})).data.getSession}async createEvent(e){let t={...e,metadata:e.metadata?JSON.stringify(e.metadata):void 0},n=await this.graphqlRequest(E.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(E.updateEventStatus,{input:e})).data.updateEventStatus}async listEvents(e,t,n){return(await this.graphqlRequest($.listEvents,{sessionId:e,source:t,limit:n})).data.listEvents.items}async listUserDeviceKeys(){return(await this.graphqlRequest($.listUserDeviceKeys,{})).data.listUserDeviceKeys||[]}async registerDeviceKey(e,t,n,s){let i={deviceId:e,publicKey:t,platform:n,deviceName:s};await this.graphqlRequest(E.registerDeviceKey,{input:i}),c.info("[AppSyncClient] Device key registered",{deviceId:e,platform:n})}async getAttachmentDownloadUrl(e){return(await this.graphqlRequest(E.getAttachmentDownloadUrl,{s3Key:e})).data.getAttachmentDownloadUrl}subscribeToEvents(e,t,n){c.info("[AppSyncClient] Subscribing to events",{sessionId:e});let s=this.activeSubscriptions.get(e);s&&(this.cleanupSubscriptionState(s),this.activeSubscriptions.delete(e));let i={ws:null,subscriptionId:(0,ae.v4)(),sessionId:e,onEvent:t,onError:n,reconnectAttempts:0,isReconnecting:!1};return this.activeSubscriptions.set(e,i),this.createSubscription(i),()=>{this.cleanupSubscriptionState(i),this.activeSubscriptions.delete(e)}}buildRealtimeUrl(){let e=y(),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 s=Buffer.from(JSON.stringify(n)).toString("base64"),i=Buffer.from(JSON.stringify({})).toString("base64");return`${t}?header=${s}&payload=${i}`}createSubscription(e){let{sessionId:t,subscriptionId:n,onEvent:s,onError:i}=e;try{let o=this.buildRealtimeUrl(),a=new oe.default(o,["graphql-ws"]);a.on("open",()=>{c.info("[AppSyncClient] WebSocket connected",{sessionId:t}),a.send(JSON.stringify({type:"connection_init"}))}),a.on("message",l=>{try{let p=JSON.parse(l.toString());switch(p.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=p.payload?.data?.onEventCreated;m&&m.source==="MOBILE"&&s(m);break;case"ka":this.resetKeepAliveTimer(e);break;case"error":let u=p.payload?.errors?.[0]?.message||"Unknown error";this.handleSubscriptionError(e,new Error(u));break}}catch(p){c.error("[AppSyncClient] Failed to parse message",{error:p})}}),a.on("error",l=>{c.error("[AppSyncClient] WebSocket error",{sessionId:t,error:l.message}),this.handleSubscriptionError(e,l)}),a.on("close",(l,p)=>{c.info("[AppSyncClient] WebSocket closed",{sessionId:t,code:l}),e.keepAliveTimer&&clearTimeout(e.keepAliveTimer),this.activeSubscriptions.has(t)&&this.handleSubscriptionError(e,new Error(`WebSocket closed: ${l}`))}),e.ws=a,this.resetKeepAliveTimer(e)}catch(o){this.handleSubscriptionError(e,o)}}sendSubscriptionStart(e,t){let n=y(),{sessionId:s,subscriptionId:i}=t,o={host:new URL(n.aws.appsyncUrl).host};this.tokens?.idToken&&(o.Authorization=this.tokens.idToken),e.send(JSON.stringify({id:i,type:"start",payload:{data:JSON.stringify({query:V.onEventCreated,variables:{sessionId:s}}),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:n,onError:s}=e;if(e.isReconnecting||!this.activeSubscriptions.has(n))return;e.isReconnecting=!0,e.reconnectAttempts++,this.stopHeartbeat(n);let i=e.reconnectAttempts<=_.urgentMaxAttempts,o;if(i?o=Math.min(_.baseDelayMs*Math.pow(_.backoffMultiplier,e.reconnectAttempts-1),_.maxDelayMs):(o=_.persistentDelayMs,e.reconnectAttempts===_.urgentMaxAttempts+1&&c.info("[AppSyncClient] Switching to persistent reconnect (every 5min)",{sessionId:n})),c.info("[AppSyncClient] Scheduling reconnect",{sessionId:n,attempt:e.reconnectAttempts,phase:i?"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,!!this.activeSubscriptions.has(n)){try{let a=await g.getTokens(this.environment);a&&(g.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})}e.subscriptionId=(0,ae.v4)(),this.createSubscription(e)}},o)}cleanupSubscriptionState(e){if(e.reconnectTimer&&clearTimeout(e.reconnectTimer),e.keepAliveTimer&&clearTimeout(e.keepAliveTimer),e.ws){try{e.ws.readyState===oe.default.OPEN&&(e.ws.send(JSON.stringify({id:e.subscriptionId,type:"stop"})),e.ws.close(1e3))}catch{}e.ws=null}}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.heartbeatTimers.forEach(e=>clearInterval(e)),this.heartbeatTimers.clear()}};var Pe=f(require("crypto")),Ke=f(require("fs")),de=f(require("http")),$e=require("child_process");O();U();H();var j=8080,Ne="/callback",ce=`http://localhost:${j}${Ne}`,M=class r{constructor(){}static getInstance(){return r.instance||(r.instance=new r),r.instance}openBrowser(e){console.log(""),console.log("Opening your browser for sign-in..."),console.log("If your browser does not open automatically, visit this URL manually:"),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=Ke.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 stdout above).");return}let s=e[n],i=[...s.fixedArgs,t],o=!1,a=u=>{o||(o=!0,c.debug(`[AuthService] Browser command '${s.cmd}' ${u}; trying next fallback`),this.tryBrowserCommand(e,t,n+1))},l=u=>{o||(o=!0,c.debug(`[AuthService] Browser command '${s.cmd}' ${u}`))},p;try{p=(0,$e.spawn)(s.cmd,i,{detached:!0,stdio:"ignore"})}catch(u){a(`threw synchronously: ${u?.message||u}`);return}p.on("error",u=>{a(`failed to spawn: ${u?.message||u}`)}),p.on("exit",(u,A)=>{u===0?l("exited successfully"):a(A?`terminated by signal ${A}`:`exited with code ${u}`)}),setTimeout(()=>{l("still running after 3s, assuming success")},3e3).unref(),p.unref()}generateState(){return Pe.randomBytes(32).toString("hex")}buildAuthUrl(e){let t=y(),n=new URLSearchParams({client_id:t.aws.cognitoClientId,response_type:"code",scope:"email openid profile",redirect_uri:ce,state:e});return`https://${t.aws.cognitoDomain}/oauth2/authorize?${n.toString()}`}async exchangeCodeForTokens(e){let t=y(),n=`https://${t.aws.cognitoDomain}/oauth2/token`,s=new URLSearchParams({grant_type:"authorization_code",client_id:t.aws.cognitoClientId,code:e,redirect_uri:ce}),i=await L(n,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:s.toString()},"Token exchange");if(!i.ok){let a=await i.text();throw new Error(`Token exchange failed: ${i.status} ${a}`)}let o=await i.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=y(),n=`https://${t.aws.cognitoDomain}/oauth2/token`,s=new URLSearchParams({grant_type:"refresh_token",client_id:t.aws.cognitoClientId,refresh_token:e}),i=await L(n,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:s.toString()},"Token refresh");if(!i.ok)throw new Error(`Token refresh failed: ${i.status}`);let o=await i.json();return{accessToken:o.access_token,idToken:o.id_token,expiresIn:o.expires_in}}async login(){let e=await g.getTokens(h());if(e&&!g.isTokenExpired(e))return e;let t=this.generateState(),n=this.buildAuthUrl(t);return new Promise((s,i)=>{let o=de.createServer(async(a,l)=>{if(!a.url?.startsWith(Ne)){l.writeHead(404),l.end("Not found");return}try{let p=new URL(a.url,`http://localhost:${j}`),m=p.searchParams.get("code"),u=p.searchParams.get("state"),A=p.searchParams.get("error");if(A)throw new Error(`OAuth error: ${A}`);if(u!==t)throw new Error("State mismatch");if(!m)throw new Error("No authorization code");let S=await this.exchangeCodeForTokens(m),B=this.decodeJwt(S.idToken),w={accessToken:S.accessToken,idToken:S.idToken,refreshToken:S.refreshToken,expiresAt:Date.now()+S.expiresIn*1e3,userId:B.sub,email:B.email||"unknown"};await g.setTokens(w,h()),l.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),l.end(`
|
|
167
|
+
`};var Ae=(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))(Ae||{}),se=(t=>(t.DESKTOP="DESKTOP",t.MOBILE="MOBILE",t))(se||{}),Ce=(n=>(n.SENT="SENT",n.DELIVERED="DELIVERED",n.EXECUTED="EXECUTED",n))(Ce||{});var ie=(n=>(n.ACTIVE="ACTIVE",n.INACTIVE="INACTIVE",n.PAUSED="PAUSED",n))(ie||{}),De=(n=>(n.CLAUDE="CLAUDE",n.GEMINI="GEMINI",n.CODEX="CODEX",n))(De||{});var _={urgentMaxAttempts:10,baseDelayMs:1e3,maxDelayMs:6e4,backoffMultiplier:2,persistentDelayMs:300*1e3},W=class{constructor(){this.authenticated=!1;this.currentUserId=null;this.currentEmail=null;this.tokens=null;this.activeSubscriptions=new Map;this.heartbeatTimers=new Map;this.environment=h(),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 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){try{let t=y(),n=`https://${t.aws.cognitoDomain}/oauth2/token`,s=new URLSearchParams({grant_type:"refresh_token",client_id:t.aws.cognitoClientId,refresh_token:e.refreshToken}),i=await L(n,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:s.toString()},"Token refresh");if(!i.ok)return c.error("[AppSyncClient] Token refresh failed",{status:i.status}),!1;let o=await i.json(),a={...e,accessToken:o.access_token,idToken:o.id_token,expiresAt:Date.now()+o.expires_in*1e3};return await g.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 s=y();if(!this.tokens?.idToken)throw new Error('Not authenticated. Run "codevibe login" first.');let i={"Content-Type":"application/json",Authorization:this.tokens.idToken},o=await L(s.aws.appsyncUrl,{method:"POST",headers:i,body:JSON.stringify({query:e,variables:t})},"AppSync GraphQL request"),a=await o.json();if(o.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(!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},n=await this.graphqlRequest(E.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(E.updateSession,{input:t});return c.debug("[AppSyncClient] Session updated",{sessionId:n.data.updateSession.sessionId}),n.data.updateSession}async getSession(e){return(await this.graphqlRequest($.getSession,{sessionId:e})).data.getSession}async createEvent(e){let t={...e,metadata:e.metadata?JSON.stringify(e.metadata):void 0},n=await this.graphqlRequest(E.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(E.updateEventStatus,{input:e})).data.updateEventStatus}async listEvents(e,t,n){return(await this.graphqlRequest($.listEvents,{sessionId:e,source:t,limit:n})).data.listEvents.items}async listUserDeviceKeys(){return(await this.graphqlRequest($.listUserDeviceKeys,{})).data.listUserDeviceKeys||[]}async registerDeviceKey(e,t,n,s){let i={deviceId:e,publicKey:t,platform:n,deviceName:s};await this.graphqlRequest(E.registerDeviceKey,{input:i}),c.info("[AppSyncClient] Device key registered",{deviceId:e,platform:n})}async getAttachmentDownloadUrl(e){return(await this.graphqlRequest(E.getAttachmentDownloadUrl,{s3Key:e})).data.getAttachmentDownloadUrl}subscribeToEvents(e,t,n){c.info("[AppSyncClient] Subscribing to events",{sessionId:e});let s=this.activeSubscriptions.get(e);s&&(this.cleanupSubscriptionState(s),this.activeSubscriptions.delete(e));let i={ws:null,subscriptionId:(0,ae.v4)(),sessionId:e,onEvent:t,onError:n,reconnectAttempts:0,isReconnecting:!1};return this.activeSubscriptions.set(e,i),this.createSubscription(i),()=>{this.cleanupSubscriptionState(i),this.activeSubscriptions.delete(e)}}buildRealtimeUrl(){let e=y(),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 s=Buffer.from(JSON.stringify(n)).toString("base64"),i=Buffer.from(JSON.stringify({})).toString("base64");return`${t}?header=${s}&payload=${i}`}createSubscription(e){let{sessionId:t,subscriptionId:n,onEvent:s,onError:i}=e;try{let o=this.buildRealtimeUrl(),a=new oe.default(o,["graphql-ws"]);a.on("open",()=>{c.info("[AppSyncClient] WebSocket connected",{sessionId:t}),a.send(JSON.stringify({type:"connection_init"}))}),a.on("message",p=>{try{let l=JSON.parse(p.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"&&s(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",p=>{c.error("[AppSyncClient] WebSocket error",{sessionId:t,error:p.message}),this.handleSubscriptionError(e,p)}),a.on("close",(p,l)=>{c.info("[AppSyncClient] WebSocket closed",{sessionId:t,code:p}),e.keepAliveTimer&&clearTimeout(e.keepAliveTimer),this.activeSubscriptions.has(t)&&this.handleSubscriptionError(e,new Error(`WebSocket closed: ${p}`))}),e.ws=a,this.resetKeepAliveTimer(e)}catch(o){this.handleSubscriptionError(e,o)}}sendSubscriptionStart(e,t){let n=y(),{sessionId:s,subscriptionId:i}=t,o={host:new URL(n.aws.appsyncUrl).host};this.tokens?.idToken&&(o.Authorization=this.tokens.idToken),e.send(JSON.stringify({id:i,type:"start",payload:{data:JSON.stringify({query:V.onEventCreated,variables:{sessionId:s}}),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:n,onError:s}=e;if(e.isReconnecting||!this.activeSubscriptions.has(n))return;e.isReconnecting=!0,e.reconnectAttempts++,this.stopHeartbeat(n);let i=e.reconnectAttempts<=_.urgentMaxAttempts,o;if(i?o=Math.min(_.baseDelayMs*Math.pow(_.backoffMultiplier,e.reconnectAttempts-1),_.maxDelayMs):(o=_.persistentDelayMs,e.reconnectAttempts===_.urgentMaxAttempts+1&&c.info("[AppSyncClient] Switching to persistent reconnect (every 5min)",{sessionId:n})),c.info("[AppSyncClient] Scheduling reconnect",{sessionId:n,attempt:e.reconnectAttempts,phase:i?"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,!!this.activeSubscriptions.has(n)){try{let a=await g.getTokens(this.environment);a&&(g.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})}e.subscriptionId=(0,ae.v4)(),this.createSubscription(e)}},o)}cleanupSubscriptionState(e){if(e.reconnectTimer&&clearTimeout(e.reconnectTimer),e.keepAliveTimer&&clearTimeout(e.keepAliveTimer),e.ws){try{e.ws.readyState===oe.default.OPEN&&(e.ws.send(JSON.stringify({id:e.subscriptionId,type:"stop"})),e.ws.close(1e3))}catch{}e.ws=null}}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.heartbeatTimers.forEach(e=>clearInterval(e)),this.heartbeatTimers.clear()}};var Pe=f(require("crypto")),Ke=f(require("fs")),de=f(require("http")),$e=require("child_process");O();U();H();var j=8080,Ne="/callback",ce=`http://localhost:${j}${Ne}`,M=class r{constructor(){}static getInstance(){return r.instance||(r.instance=new r),r.instance}openBrowser(e){console.log(""),console.log("Opening your browser for sign-in..."),console.log("If your browser does not open automatically, visit this URL manually:"),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=Ke.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 stdout above).");return}let s=e[n],i=[...s.fixedArgs,t],o=!1,a=u=>{o||(o=!0,c.debug(`[AuthService] Browser command '${s.cmd}' ${u}; trying next fallback`),this.tryBrowserCommand(e,t,n+1))},p=u=>{o||(o=!0,c.debug(`[AuthService] Browser command '${s.cmd}' ${u}`))},l;try{l=(0,$e.spawn)(s.cmd,i,{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,A)=>{u===0?p("exited successfully"):a(A?`terminated by signal ${A}`:`exited with code ${u}`)}),setTimeout(()=>{p("still running after 3s, assuming success")},3e3).unref(),l.unref()}generateState(){return Pe.randomBytes(32).toString("hex")}buildAuthUrl(e){let t=y(),n=new URLSearchParams({client_id:t.aws.cognitoClientId,response_type:"code",scope:"email openid profile",redirect_uri:ce,state:e});return`https://${t.aws.cognitoDomain}/oauth2/authorize?${n.toString()}`}async exchangeCodeForTokens(e){let t=y(),n=`https://${t.aws.cognitoDomain}/oauth2/token`,s=new URLSearchParams({grant_type:"authorization_code",client_id:t.aws.cognitoClientId,code:e,redirect_uri:ce}),i=await L(n,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:s.toString()},"Token exchange");if(!i.ok){let a=await i.text();throw new Error(`Token exchange failed: ${i.status} ${a}`)}let o=await i.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=y(),n=`https://${t.aws.cognitoDomain}/oauth2/token`,s=new URLSearchParams({grant_type:"refresh_token",client_id:t.aws.cognitoClientId,refresh_token:e}),i=await L(n,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:s.toString()},"Token refresh");if(!i.ok)throw new Error(`Token refresh failed: ${i.status}`);let o=await i.json();return{accessToken:o.access_token,idToken:o.id_token,expiresIn:o.expires_in}}async login(){let e=await g.getTokens(h());if(e&&!g.isTokenExpired(e))return e;let t=this.generateState(),n=this.buildAuthUrl(t);return new Promise((s,i)=>{let o=de.createServer(async(a,p)=>{if(!a.url?.startsWith(Ne)){p.writeHead(404),p.end("Not found");return}try{let l=new URL(a.url,`http://localhost:${j}`),m=l.searchParams.get("code"),u=l.searchParams.get("state"),A=l.searchParams.get("error");if(A)throw new Error(`OAuth error: ${A}`);if(u!==t)throw new Error("State mismatch");if(!m)throw new Error("No authorization code");let S=await this.exchangeCodeForTokens(m),B=this.decodeJwt(S.idToken),w={accessToken:S.accessToken,idToken:S.idToken,refreshToken:S.refreshToken,expiresAt:Date.now()+S.expiresIn*1e3,userId:B.sub,email:B.email||"unknown"};await g.setTokens(w,h()),p.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),p.end(`
|
|
167
168
|
<!DOCTYPE html>
|
|
168
169
|
<html>
|
|
169
170
|
<head><title>Success</title></head>
|
|
@@ -172,7 +173,7 @@
|
|
|
172
173
|
<p>You can close this window.</p>
|
|
173
174
|
</body>
|
|
174
175
|
</html>
|
|
175
|
-
`),setTimeout(()=>{o.close(()=>s(w))},500)}catch(
|
|
176
|
+
`),setTimeout(()=>{o.close(()=>s(w))},500)}catch(l){let m=String(l?.message||l).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">");p.writeHead(400,{"Content-Type":"text/html; charset=utf-8"}),p.end(`
|
|
176
177
|
<!DOCTYPE html>
|
|
177
178
|
<html>
|
|
178
179
|
<head><title>Error</title></head>
|
|
@@ -182,7 +183,7 @@
|
|
|
182
183
|
<p style="text-align: center; color: #71717a; margin-top: 24px;">You can close this window and try again in your terminal.</p>
|
|
183
184
|
</body>
|
|
184
185
|
</html>
|
|
185
|
-
`),setTimeout(()=>{o.close(()=>i(
|
|
186
|
+
`),setTimeout(()=>{o.close(()=>i(l))},500)}});o.on("error",a=>{a.code==="EADDRINUSE"?i(new Error(`Port ${j} is in use`)):i(a)}),o.listen(j,"localhost",()=>{c.info("[AuthService] Callback server started"),this.openBrowser(n)}),setTimeout(()=>{o.close(()=>i(new Error("Login timeout")))},120*1e3)})}async logout(){let e=y(),t=await g.deleteTokens(h());return t&&new Promise(n=>{let s=de.createServer((i,o)=>{i.url?.startsWith("/signout")?(o.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),o.end(`
|
|
186
187
|
<!DOCTYPE html>
|
|
187
188
|
<html>
|
|
188
189
|
<head><title>Signed Out</title></head>
|
|
@@ -191,27 +192,27 @@
|
|
|
191
192
|
<p>You can close this window.</p>
|
|
192
193
|
</body>
|
|
193
194
|
</html>
|
|
194
|
-
`),setTimeout(()=>{s.close(()=>n(!0))},500)):(o.writeHead(404),o.end("Not found"))});s.on("error",()=>{n(!0)}),s.listen(j,"localhost",()=>{let i=`https://${e.aws.cognitoDomain}/logout?client_id=${e.aws.cognitoClientId}&logout_uri=${encodeURIComponent(ce.replace("/callback","/signout"))}`;this.openBrowser(i)}),setTimeout(()=>{s.close(()=>n(!0))},30*1e3)})}async getStatus(){let e=await g.getTokens(h());return e?{authenticated:!g.isTokenExpired(e),tokens:e}:{authenticated:!1}}},T=M.getInstance();O();var d={reset:"\x1B[0m",green:"\x1B[32m",red:"\x1B[31m",yellow:"\x1B[33m",cyan:"\x1B[36m",dim:"\x1B[2m"};async function
|
|
195
|
+
`),setTimeout(()=>{s.close(()=>n(!0))},500)):(o.writeHead(404),o.end("Not found"))});s.on("error",()=>{n(!0)}),s.listen(j,"localhost",()=>{let i=`https://${e.aws.cognitoDomain}/logout?client_id=${e.aws.cognitoClientId}&logout_uri=${encodeURIComponent(ce.replace("/callback","/signout"))}`;this.openBrowser(i)}),setTimeout(()=>{s.close(()=>n(!0))},30*1e3)})}async getStatus(){let e=await g.getTokens(h());return e?{authenticated:!g.isTokenExpired(e),tokens:e}:{authenticated:!1}}},T=M.getInstance();O();var d={reset:"\x1B[0m",green:"\x1B[32m",red:"\x1B[31m",yellow:"\x1B[33m",cyan:"\x1B[36m",dim:"\x1B[2m"};async function Ge(){console.log(`${d.cyan}CodeVibe Login${d.reset}
|
|
195
196
|
`);try{let r=await T.getStatus();if(r.authenticated&&r.tokens){console.log(`${d.yellow}Already logged in as: ${r.tokens.email}${d.reset}`),console.log(`Token expires: ${new Date(r.tokens.expiresAt).toLocaleString()}`),console.log(`
|
|
196
197
|
Run '${d.dim}codevibe logout${d.reset}' to sign out first.`),process.exit(0);return}console.log("Opening browser for authentication..."),console.log(`${d.dim}Waiting for callback...${d.reset}
|
|
197
198
|
`);let e=await T.login();e&&(console.log(`
|
|
198
199
|
${d.green}\u2713 Authentication successful!${d.reset}`),console.log(` User: ${e.email}`),console.log(` User ID: ${e.userId}`),console.log(` Expires: ${new Date(e.expiresAt).toLocaleString()}`)),process.exit(0)}catch(r){console.log(`
|
|
199
|
-
${d.red}\u2717 Authentication failed${d.reset}`),console.log(` Error: ${r.message}`),process.exit(1)}}async function
|
|
200
|
+
${d.red}\u2717 Authentication failed${d.reset}`),console.log(` Error: ${r.message}`),process.exit(1)}}async function Ye(){console.log(`${d.cyan}CodeVibe Logout${d.reset}
|
|
200
201
|
`);try{let r=await T.getStatus();if(!r.authenticated){console.log(`${d.yellow}Not logged in.${d.reset}`),process.exit(0);return}let e=r.tokens?.email;await T.logout()?(console.log(`${d.green}\u2713 Logged out successfully.${d.reset}`),console.log(` Previous user: ${e}`),console.log(`
|
|
201
|
-
${d.dim}Clearing browser session...${d.reset}`)):console.log(`${d.red}\u2717 Failed to log out.${d.reset}`),process.exit(0)}catch(r){console.log(`${d.red}\u2717 Logout failed: ${r.message}${d.reset}`),process.exit(1)}}async function
|
|
202
|
+
${d.dim}Clearing browser session...${d.reset}`)):console.log(`${d.red}\u2717 Failed to log out.${d.reset}`),process.exit(0)}catch(r){console.log(`${d.red}\u2717 Logout failed: ${r.message}${d.reset}`),process.exit(1)}}async function Xe(){console.log(`${d.cyan}CodeVibe Auth Status${d.reset}
|
|
202
203
|
`);try{let r=await T.getStatus();if(!r.tokens){console.log(`${d.yellow}Not authenticated.${d.reset}`),console.log(`
|
|
203
204
|
Run '${d.dim}codevibe login${d.reset}' to sign in.`),process.exit(0);return}let e=!r.authenticated;console.log(e?`${d.yellow}\u26A0 Token expired${d.reset}`:`${d.green}\u2713 Authenticated${d.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(`
|
|
204
|
-
${d.dim}Token will be refreshed automatically.${d.reset}`),process.exit(0)}catch(r){console.log(`${d.red}\u2717 Status check failed: ${r.message}${d.reset}`),process.exit(1)}}async function
|
|
205
|
+
${d.dim}Token will be refreshed automatically.${d.reset}`),process.exit(0)}catch(r){console.log(`${d.red}\u2717 Status check failed: ${r.message}${d.reset}`),process.exit(1)}}async function Qe(){console.log(`${d.cyan}CodeVibe Reset Device${d.reset}
|
|
205
206
|
`),console.log(`${d.red}\u26A0 WARNING: This will delete your device identity.${d.reset}`),console.log(`${d.red} Old encrypted sessions will become inaccessible.${d.reset}
|
|
206
|
-
`);let{keychainManager:r}=await Promise.resolve().then(()=>(U(),
|
|
207
|
+
`);let{keychainManager:r}=await Promise.resolve().then(()=>(U(),Ie));try{await r.clearAllData(),console.log(`${d.green}\u2713 Device reset complete.${d.reset}`),console.log(` Run '${d.dim}codevibe login${d.reset}' to set up again.`),process.exit(0)}catch(e){console.log(`${d.red}\u2717 Reset failed: ${e.message}${d.reset}`),process.exit(1)}}function Ze(){console.log(`CodeVibe Authentication
|
|
207
208
|
`),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(`
|
|
208
209
|
Environment:`),console.log(' Set ENVIRONMENT env var to "development" or "production" (default)'),console.log(" Example: ENVIRONMENT=development codevibe login")}async function Z(r){let e=h();console.log(`${d.dim}Environment: ${e}${d.reset}
|
|
209
|
-
`);let n=r.slice(2).filter(s=>!s.startsWith("--"))[0];switch(n){case"login":await
|
|
210
|
-
`).replace(
|
|
210
|
+
`);let n=r.slice(2).filter(s=>!s.startsWith("--"))[0];switch(n){case"login":await Ge();break;case"logout":await Ye();break;case"status":await Xe();break;case"reset-device":await Qe();break;default:Ze(),process.exit(n?1:0)}}require.main===module&&Z(process.argv).catch(r=>{console.error("Error:",r),process.exit(1)});O();H();var et=/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g;function Oe(r){let e=ue(r);if(!e)return null;let t=tt(e);if(t)return t;let n=nt(e);return n||null}function ue(r){return r.replace(/\r/g,`
|
|
211
|
+
`).replace(et,"").replace(/[│┌┐└┘─├┤┬┴┼╌╎╭╮╯╰║═╔╗╚╝╠╣╦╩╬]/g," ").replace(/[ \t]+\n/g,`
|
|
211
212
|
`).replace(/\n{3,}/g,`
|
|
212
213
|
|
|
213
|
-
`).trim()}function
|
|
214
|
-
`).map(m=>m.trim()),t=
|
|
215
|
-
`):n,o=i.toLowerCase(),a=o.includes("what to change")||o.includes("what should")||o.includes("provide")||o.includes("instructions");return{kind:"yes_no",promptText:i,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
|
|
216
|
-
`).map(
|
|
217
|
-
`):"Select an option",options:n,submitMap:s}}function
|
|
214
|
+
`).trim()}function tt(r){let e=r.split(`
|
|
215
|
+
`).map(m=>m.trim()),t=rt(e,m=>/\[(?:y\/n|Y\/n|y\/N)\]/.test(m)),n=t>=0?e[t]:null;if(!n)return null;let s=Ue(e,t),i=s.length>0?s.join(`
|
|
216
|
+
`):n,o=i.toLowerCase(),a=o.includes("what to change")||o.includes("what should")||o.includes("provide")||o.includes("instructions");return{kind:"yes_no",promptText:i,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 nt(r){let e=r.split(`
|
|
217
|
+
`).map(p=>p.trim()),t=st(e);if(t.length<2)return null;let n=t.map(({line:p})=>Re(p)).filter(p=>!!p),s={};for(let p of n)s[p.number]=p.number;let i=t[0]?.index??-1,o=Ue(e,i-1);return{kind:"numbered",promptText:o.length>0?o.join(`
|
|
218
|
+
`):"Select an option",options:n,submitMap:s}}function rt(r,e){for(let t=r.length-1;t>=0;t-=1)if(e(r[t]))return t;return-1}function Re(r){let e=r.match(/^(?:[>›❯▸▶➜➤*●]\s*)?(\d+)\.\s+(.*)$/);return e?{number:e[1],text:e[2]}:null}function st(r){let e=r.map((n,s)=>({index:s,line:n,parsed:Re(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 s=e[n],i=t[0];if(s.index!==i.index-1)break;t.unshift(s)}return t.map(({index:n,line:s})=>({index:n,line:s}))}function Ue(r,e){if(e<0)return[];let t=pe(r,e);if(t<0)return[];let{start:n,end:s}=le(r,t),i=r.slice(n,s+1).filter(Boolean);if(ot(i)){let u=it(r,n-1);return u.length>0?u:i}if(n<=1)return i;let o=n-1;if(o=pe(r,o),o<0||o===n-1)return i;let{start:a,end:p}=le(r,o),l=r.slice(a,p+1).filter(Boolean);return l.some(Le)?[...l,...i]:i}function Le(r){return/^(?:would you like to|do you want to|the model would like to|action required|confirm)\b/i.test(r)}function pe(r,e){let t=e;for(;t>=0&&!r[t];)t-=1;return t}function le(r,e){let t=e;for(;t>=0&&r[t];)t-=1;return{start:t+1,end:e}}function it(r,e){let t=[],n=e;for(;n>=0&&t.length<2&&(n=pe(r,n),!(n<0));){let{start:i,end:o}=le(r,n),a=r.slice(i,o+1).filter(Boolean);a.length>0&&t.unshift(a),n=i-1}if(t.length===0)return[];let s=t.findIndex(i=>i.some(Le));return s>=0?t.slice(s).flat():t[t.length-1]}function ot(r){return r.length===0?!1:r.filter(at).length>=Math.max(2,Math.ceil(r.length/2))}function at(r){return/^\d+\s/.test(r)}z();U();async function ee(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:s,encryptedKeys:i}=g.createSessionKey(n);return t.info("Session encryption prepared",{sessionId:r,deviceCount:i.length}),{sessionKey:s,encryptedKeys:i}}catch(n){return t.warn("Failed to prepare session encryption:",n),null}}async function ge(r,e,t){let{sessionId:n,userId:s,agentType:i,projectPath:o,metadata:a}=r,p=null;try{p=await e.getSession(n)}catch(S){t.warn("Failed to get session (will attempt to create new)",{sessionId:n,error:S})}if(p){t.info("Session exists in backend - reactivating",{sessionId:n,previousStatus:p.status});try{await e.updateSession({sessionId:n,status:"ACTIVE"})}catch(w){t.warn("Failed to reactivate existing session, will continue",{sessionId:n,error:w})}let S=null,B=p.encryptedKeys;if(p.isEncrypted&&B?.length)try{let w=await g.getSessionKey(n,B);w?(S=w,g.cacheSessionKey(n,w),t.info("Session key retrieved for resumed session",{sessionId:n})):t.warn("No encrypted key for this device; proceeding without decryption",{sessionId:n})}catch(w){t.warn("Failed to retrieve session key for resumed session",{sessionId:n,error:w})}return{resumed:!0,sessionKey:S}}let l=await ee(n,e,t),m=o,u=a;l&&(m=b.encryptContent(o,l.sessionKey),u&&Object.keys(u).length>0&&(u={encrypted:b.encryptMetadata(u,l.sessionKey)}),t.info("Session data encrypted",{sessionId:n})),t.info("Creating new session in backend",{sessionId:n,userId:s,agentType:i,isEncrypted:!!l}),await e.createSession({sessionId:n,userId:s,agentType:i,projectPath:m,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 A=l?.sessionKey||null;return l&&g.cacheSessionKey(n,l.sessionKey),t.info("Session created",{sessionId:n,userId:s,isEncrypted:!!l}),{resumed:!1,sessionKey:A}}0&&(module.exports={AgentType,AppSyncClient,AuthService,CryptoError,CryptoService,DeliveryStatus,ENCRYPTION_VERSION,EventSource,EventType,KeychainError,KeychainManager,Logger,SessionStatus,authService,createLogger,cryptoService,getConfig,getEnvironment,keychainManager,loadConfig,logger,mutations,normalizeSnapshot,parseInteractivePrompt,prepareSessionEncryption,queries,resumeOrCreateSession,runAuthCli,subscriptions});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quantiya/codevibe-claude-plugin",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.14",
|
|
4
4
|
"description": "Control Claude Code from your iPhone and Android — real-time sync, approve file edits, send prompts by voice. Part of CodeVibe.",
|
|
5
5
|
"main": "dist/server.js",
|
|
6
6
|
"bin": {
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"darwin"
|
|
51
51
|
],
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@quantiya/codevibe-core": "^1.0.
|
|
53
|
+
"@quantiya/codevibe-core": "^1.0.6",
|
|
54
54
|
"dotenv": "^16.6.1",
|
|
55
55
|
"express": "^5.1.0",
|
|
56
56
|
"graphql": "^16.12.0",
|