agent-device 0.13.1 → 0.13.2

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.
@@ -1372,6 +1372,12 @@ export declare type CommandSessionStore = {
1372
1372
  list?(): readonly CommandSessionRecord[] | Promise<readonly CommandSessionRecord[]>;
1373
1373
  };
1374
1374
 
1375
+ declare type CompanionTunnelScope = {
1376
+ tenantId: string;
1377
+ runId: string;
1378
+ leaseId: string;
1379
+ };
1380
+
1375
1381
  export declare function createAgentDevice(config: AgentDeviceRuntimeConfig): AgentDevice;
1376
1382
 
1377
1383
  export declare function createAgentDeviceClient(config?: AgentDeviceClientConfig, deps?: {
@@ -1914,12 +1920,6 @@ declare type MetroBridgeResult = {
1914
1920
  };
1915
1921
  };
1916
1922
 
1917
- declare type MetroBridgeScope = {
1918
- tenantId: string;
1919
- runId: string;
1920
- leaseId: string;
1921
- };
1922
-
1923
1923
  declare type MetroPrepareKind = 'auto' | 'react-native' | 'expo';
1924
1924
 
1925
1925
  export declare type MetroPrepareOptions = {
@@ -1928,7 +1928,7 @@ export declare type MetroPrepareOptions = {
1928
1928
  publicBaseUrl?: string;
1929
1929
  proxyBaseUrl?: string;
1930
1930
  bearerToken?: string;
1931
- bridgeScope?: MetroBridgeScope;
1931
+ bridgeScope?: CompanionTunnelScope;
1932
1932
  launchUrl?: string;
1933
1933
  companionProfileKey?: string;
1934
1934
  companionConsumerKey?: string;
@@ -1 +1 @@
1
- import e from"node:fs";import{setTimeout as r}from"node:timers/promises";import{normalizeBaseUrl as t,ENV_REGISTER_PATH as s,ENV_STATE_PATH as o,ENV_LOCAL_BASE_URL as a,ENV_SESSION as n,ENV_UNREGISTER_PATH as i,ENV_BEARER_TOKEN as c,METRO_COMPANION_RUN_ARG as f,ENV_SERVER_BASE_URL as l,ENV_LAUNCH_URL as d,ENV_SCOPE_TENANT_ID as u,ENV_SCOPE_RUN_ID as m,ENV_SCOPE_LEASE_ID as p,REACT_DEVTOOLS_COMPANION_RUN_ARG as g,ENV_DEVICE_PORT as y}from"./320.js";function w(e,r){return{authorization:`Bearer ${r}`,"content-type":"application/json",...e.includes("ngrok")?{"ngrok-skip-browser-warning":"1"}:{}}}function h(e){return{...e.bridgeScope,...e.session?{session:e.session}:{},local_base_url:t(e.localBaseUrl),...e.devicePort?{device_port:e.devicePort}:{},...e.launchUrl?{launch_url:e.launchUrl}:{}}}async function b(e){let r,s,o=e.registerPath??"/api/metro/companion/register";try{r=await fetch(`${t(e.serverBaseUrl)}${o}`,{method:"POST",headers:w(e.serverBaseUrl,e.bearerToken),body:JSON.stringify(h(e)),signal:AbortSignal.timeout(5e3)})}catch(r){if(r instanceof Error&&"TimeoutError"===r.name)throw Error(`${o} timed out after 5000ms calling ${t(e.serverBaseUrl)}${o}`);throw r}let a=await r.text();try{s=a?JSON.parse(a):{}}catch{let e;throw Error(`Failed to register companion (${r.status}): invalid JSON response: ${(e=a.replaceAll(/\s+/g," ").trim()).length>300?`${e.slice(0,300)}...`:e}`)}if(!r.ok||!0!==s.ok||"string"!=typeof s.data?.ws_url)throw Error(`Failed to register companion (${r.status}): ${JSON.stringify(s)}`);return{wsUrl:s.data.ws_url}}async function v(e){let r=e.unregisterPath??null;if(r)try{await fetch(`${t(e.serverBaseUrl)}${r}`,{method:"POST",headers:w(e.serverBaseUrl,e.bearerToken),body:JSON.stringify(h(e)),signal:AbortSignal.timeout(2e3)})}catch(e){console.error(e instanceof Error?e.message:String(e))}}async function S(e){return"string"==typeof e?Buffer.from(e,"utf8"):e instanceof ArrayBuffer?Buffer.from(e):ArrayBuffer.isView(e)?Buffer.from(e.buffer,e.byteOffset,e.byteLength):"u">typeof Blob&&e instanceof Blob?Buffer.from(await e.arrayBuffer()):Buffer.from(String(e),"utf8")}async function E(e){return JSON.parse((await S(e.data)).toString("utf8"))}function I(e,r){1===e.readyState&&e.send(JSON.stringify(r))}async function B(e,r){1!==e.readyState&&await new Promise((t,s)=>{let o=()=>{i(),t()},a=()=>{i(),s(Error(`${r} WebSocket failed before opening.`))},n=()=>{i(),s(Error(`${r} WebSocket closed before opening.`))},i=()=>{e.removeEventListener("open",o),e.removeEventListener("error",a),e.removeEventListener("close",n)};e.addEventListener("open",o,{once:!0}),e.addEventListener("error",a,{once:!0}),e.addEventListener("close",n,{once:!0})})}async function k(e){e.readyState>=WebSocket.CLOSING||await new Promise(r=>{let t=()=>{s(),r()},s=()=>{e.removeEventListener("close",t),e.removeEventListener("error",t)};e.addEventListener("close",t,{once:!0}),e.addEventListener("error",t,{once:!0}),e.readyState>=WebSocket.CLOSING&&t()})}function L(e,r,t){try{e.close(1e3===r||r>=3e3&&r<=4999?r:3001,t)}catch{}}function U(r){return!r.statePath||e.existsSync(r.statePath)}async function $(e,r,s,o){var a,n;switch(r.type){case"ping":return void I(e,{type:"pong",timestamp:r.timestamp});case"http-request":try{let o=await fetch(new URL(r.path,`${t(s.localBaseUrl)}/`),{method:r.method,headers:r.headers,...r.bodyBase64?{body:Buffer.from(r.bodyBase64,"base64")}:{}}),a=Buffer.from(await o.arrayBuffer());I(e,{type:"http-response",requestId:r.requestId,status:o.status,headers:Object.fromEntries(o.headers.entries()),...a.length>0?{bodyBase64:a.toString("base64")}:{}})}catch(t){I(e,{type:"http-error",requestId:r.requestId,message:t instanceof Error?t.message:String(t)})}return;case"ws-open":{let n,i=new WebSocket((a=s.localBaseUrl,(n=new URL(r.path,`${t(a)}/`)).protocol="https:"===n.protocol?"wss:":"ws:",n.toString()));i.binaryType="arraybuffer";let c=!1;i.addEventListener("message",t=>{(async()=>{if(!c)return;let s=await S(t.data);I(e,{type:"ws-frame",streamId:r.streamId,dataBase64:s.toString("base64"),binary:"string"!=typeof t.data})})().catch(e=>{console.error(e instanceof Error?e.message:String(e))})}),i.addEventListener("close",t=>{o.delete(r.streamId),c&&I(e,{type:"ws-close",streamId:r.streamId,code:t.code,reason:t.reason})}),i.addEventListener("error",()=>{c&&I(e,{type:"ws-close",streamId:r.streamId,code:1011,reason:"Upstream WebSocket error."})}),o.set(r.streamId,i);try{await B(i,"Upstream"),c=!0,I(e,{type:"ws-open-result",streamId:r.streamId,success:!0,headers:{}})}catch(t){o.delete(r.streamId),L(i,1011,"open failed"),I(e,{type:"ws-open-result",streamId:r.streamId,success:!1,error:t instanceof Error?t.message:String(t)})}return}case"ws-frame":{let e=o.get(r.streamId);if(!e||1!==e.readyState)return;let t=Buffer.from(r.dataBase64,"base64");e.send(r.binary?t:t.toString("utf8"));return}case"ws-close":{let e=o.get(r.streamId);if(!e)return;o.delete(r.streamId),L(e,"number"==typeof(n=r.code)&&Number.isInteger(n)&&(1e3===n||n>=3e3&&n<=4999||n>=1001&&n<=1015&&1004!==n&&1005!==n&&1006!==n)?n:1011,r.reason??"bridge requested close");return}}}async function P(e){let t=new Map,s=!1,o=null,a=!1,n=()=>{s||(s=!0,a&&v(e).finally(()=>process.exit(0)),o&&L(o,1e3,"companion stopping"),setTimeout(()=>process.exit(0),900).unref())};process.once("SIGTERM",n),process.once("SIGINT",n);let i=setInterval(()=>{U(e)||process.exit(0)},250);for(i.unref();!s&&U(e);){let n=!1;try{a=!1;let r=await b(e);if(n=!0,a=!0,s||!U(e)){await v(e),n=!1,a=!1;break}let i=new WebSocket(r.wsUrl);o=i,i.binaryType="arraybuffer";try{await B(i,"Bridge"),i.addEventListener("message",r=>{(async()=>{let s=await E(r);await $(i,s,e,t)})().catch(e=>{console.error(e instanceof Error?e.message:String(e))})}),await k(i)}finally{o=null,a=!1,t.forEach(e=>L(e,1012,"bridge disconnected")),t.clear(),n&&(await v(e),n=!1)}}catch(r){if(o=null,a=!1,n&&(await v(e),n=!1),s||!U(e))break;console.error(r instanceof Error?r.message:String(r))}if(s||!U(e))break;await r(1e3)}clearInterval(i)}(async function(e,r){let t=function(e,r){let t=e[0];if(t!==f&&t!==g)return null;let w=r[l]?.trim(),h=r[c]?.trim(),b=r[a]?.trim();if(!w||!h||!b)throw Error("Metro companion worker is missing required environment configuration.");let v=r[u]?.trim(),S=r[m]?.trim(),E=r[p]?.trim();if(!v||!S||!E)throw Error("Metro companion worker is missing required bridge scope configuration.");return{serverBaseUrl:w,bearerToken:h,localBaseUrl:b,bridgeScope:{tenantId:v,runId:S,leaseId:E},launchUrl:r[d]?.trim()||void 0,statePath:r[o]?.trim()||void 0,registerPath:r[s]?.trim()||void 0,unregisterPath:r[i]?.trim()||void 0,devicePort:function(e){if(!e?.trim())return;let r=Number.parseInt(e,10);if(!Number.isInteger(r)||r<1||r>65535)throw Error("Companion worker received invalid device port configuration.");return r}(r[y]),session:r[n]?.trim()||void 0}}(e,r);return!!t&&(await P(t),!0)})(process.argv.slice(2),process.env).catch(e=>{if(e instanceof Error&&e.message.includes("missing required environment")){console.error(e.message),process.exitCode=1;return}console.error(e instanceof Error?e.stack??e.message:String(e)),process.exitCode=1});
1
+ import e from"node:fs";import{setTimeout as r}from"node:timers/promises";import{normalizeBaseUrl as t,ENV_COMPANION_TUNNEL_BEARER_TOKEN as s,ENV_COMPANION_TUNNEL_SERVER_BASE_URL as n,ENV_COMPANION_TUNNEL_STATE_PATH as o,ENV_COMPANION_TUNNEL_LAUNCH_URL as a,ENV_COMPANION_TUNNEL_SCOPE_LEASE_ID as i,ENV_COMPANION_TUNNEL_SCOPE_TENANT_ID as c,ENV_COMPANION_TUNNEL_DEVICE_PORT as l,METRO_COMPANION_RUN_ARG as f,ENV_COMPANION_TUNNEL_SESSION as d,ENV_COMPANION_TUNNEL_SCOPE_RUN_ID as u,ENV_COMPANION_TUNNEL_REGISTER_PATH as m,ENV_COMPANION_TUNNEL_LOCAL_BASE_URL as p,REACT_DEVTOOLS_COMPANION_RUN_ARG as g,ENV_COMPANION_TUNNEL_UNREGISTER_PATH as y}from"./2301.js";function w(e,r){return{authorization:`Bearer ${r}`,"content-type":"application/json",...e.includes("ngrok")?{"ngrok-skip-browser-warning":"1"}:{}}}function h(e){return{...e.bridgeScope,...e.session?{session:e.session}:{},local_base_url:t(e.localBaseUrl),...e.devicePort?{device_port:e.devicePort}:{},...e.launchUrl?{launch_url:e.launchUrl}:{}}}async function b(e){let r,s,n=e.registerPath;try{r=await fetch(`${t(e.serverBaseUrl)}${n}`,{method:"POST",headers:w(e.serverBaseUrl,e.bearerToken),body:JSON.stringify(h(e)),signal:AbortSignal.timeout(5e3)})}catch(r){if(r instanceof Error&&"TimeoutError"===r.name)throw Error(`${n} timed out after 5000ms calling ${t(e.serverBaseUrl)}${n}`);throw r}let o=await r.text();try{s=o?JSON.parse(o):{}}catch{let e;throw Error(`Failed to register companion (${r.status}): invalid JSON response: ${(e=o.replaceAll(/\s+/g," ").trim()).length>300?`${e.slice(0,300)}...`:e}`)}if(!r.ok||!0!==s.ok||"string"!=typeof s.data?.ws_url)throw Error(`Failed to register companion (${r.status}): ${JSON.stringify(s)}`);return{wsUrl:s.data.ws_url}}async function S(e){let r=e.unregisterPath??null;if(r)try{await fetch(`${t(e.serverBaseUrl)}${r}`,{method:"POST",headers:w(e.serverBaseUrl,e.bearerToken),body:JSON.stringify(h(e)),signal:AbortSignal.timeout(2e3)})}catch(e){console.error(e instanceof Error?e.message:String(e))}}async function v(e){return"string"==typeof e?Buffer.from(e,"utf8"):e instanceof ArrayBuffer?Buffer.from(e):ArrayBuffer.isView(e)?Buffer.from(e.buffer,e.byteOffset,e.byteLength):"u">typeof Blob&&e instanceof Blob?Buffer.from(await e.arrayBuffer()):Buffer.from(String(e),"utf8")}async function E(e){return JSON.parse((await v(e.data)).toString("utf8"))}function I(e,r){1===e.readyState&&e.send(JSON.stringify(r))}async function B(e,r){1!==e.readyState&&await new Promise((t,s)=>{let n=()=>{i(),t()},o=()=>{i(),s(Error(`${r} WebSocket failed before opening.`))},a=()=>{i(),s(Error(`${r} WebSocket closed before opening.`))},i=()=>{e.removeEventListener("open",n),e.removeEventListener("error",o),e.removeEventListener("close",a)};e.addEventListener("open",n,{once:!0}),e.addEventListener("error",o,{once:!0}),e.addEventListener("close",a,{once:!0})})}async function k(e){e.readyState>=WebSocket.CLOSING||await new Promise(r=>{let t=()=>{s(),r()},s=()=>{e.removeEventListener("close",t),e.removeEventListener("error",t)};e.addEventListener("close",t,{once:!0}),e.addEventListener("error",t,{once:!0}),e.readyState>=WebSocket.CLOSING&&t()})}function L(e,r,t){try{e.close(1e3===r||r>=3e3&&r<=4999?r:3001,t)}catch{}}function U(r){return!r.statePath||e.existsSync(r.statePath)}async function $(e,r,s,n){var o,a;switch(r.type){case"ping":return void I(e,{type:"pong",timestamp:r.timestamp});case"http-request":try{let n=await fetch(new URL(r.path,`${t(s.localBaseUrl)}/`),{method:r.method,headers:r.headers,...r.bodyBase64?{body:Buffer.from(r.bodyBase64,"base64")}:{}}),o=Buffer.from(await n.arrayBuffer());I(e,{type:"http-response",requestId:r.requestId,status:n.status,headers:Object.fromEntries(n.headers.entries()),...o.length>0?{bodyBase64:o.toString("base64")}:{}})}catch(t){I(e,{type:"http-error",requestId:r.requestId,message:t instanceof Error?t.message:String(t)})}return;case"ws-open":{let a,i=new WebSocket((o=s.localBaseUrl,(a=new URL(r.path,`${t(o)}/`)).protocol="https:"===a.protocol?"wss:":"ws:",a.toString()));i.binaryType="arraybuffer";let c=!1;i.addEventListener("message",t=>{(async()=>{if(!c)return;let s=await v(t.data);I(e,{type:"ws-frame",streamId:r.streamId,dataBase64:s.toString("base64"),binary:"string"!=typeof t.data})})().catch(e=>{console.error(e instanceof Error?e.message:String(e))})}),i.addEventListener("close",t=>{n.delete(r.streamId),c&&I(e,{type:"ws-close",streamId:r.streamId,code:t.code,reason:t.reason})}),i.addEventListener("error",()=>{c&&I(e,{type:"ws-close",streamId:r.streamId,code:1011,reason:"Upstream WebSocket error."})}),n.set(r.streamId,i);try{await B(i,"Upstream"),c=!0,I(e,{type:"ws-open-result",streamId:r.streamId,success:!0,headers:{}})}catch(t){n.delete(r.streamId),L(i,1011,"open failed"),I(e,{type:"ws-open-result",streamId:r.streamId,success:!1,error:t instanceof Error?t.message:String(t)})}return}case"ws-frame":{let e=n.get(r.streamId);if(!e||1!==e.readyState)return;let t=Buffer.from(r.dataBase64,"base64");e.send(r.binary?t:t.toString("utf8"));return}case"ws-close":{let e=n.get(r.streamId);if(!e)return;n.delete(r.streamId),L(e,"number"==typeof(a=r.code)&&Number.isInteger(a)&&(1e3===a||a>=3e3&&a<=4999||a>=1001&&a<=1015&&1004!==a&&1005!==a&&1006!==a)?a:1011,r.reason??"bridge requested close");return}}}async function N(e){let t=new Map,s=!1,n=null,o=!1,a=()=>{s||(s=!0,o&&S(e).finally(()=>process.exit(0)),n&&L(n,1e3,"companion stopping"),setTimeout(()=>process.exit(0),900).unref())};process.once("SIGTERM",a),process.once("SIGINT",a);let i=setInterval(()=>{U(e)||process.exit(0)},250);for(i.unref();!s&&U(e);){let a=!1;try{o=!1;let r=await b(e);if(a=!0,o=!0,s||!U(e)){await S(e),a=!1,o=!1;break}let i=new WebSocket(r.wsUrl);n=i,i.binaryType="arraybuffer";try{await B(i,"Bridge"),i.addEventListener("message",r=>{(async()=>{let s=await E(r);await $(i,s,e,t)})().catch(e=>{console.error(e instanceof Error?e.message:String(e))})}),await k(i)}finally{n=null,o=!1,t.forEach(e=>L(e,1012,"bridge disconnected")),t.clear(),a&&(await S(e),a=!1)}}catch(r){if(n=null,o=!1,a&&(await S(e),a=!1),s||!U(e))break;console.error(r instanceof Error?r.message:String(r))}if(s||!U(e))break;await r(1e3)}clearInterval(i)}(async function(e,r){let t=function(e,r){let t=e[0];if(t!==f&&t!==g)return null;let w=r[n]?.trim(),h=r[s]?.trim(),b=r[p]?.trim();if(!w||!h||!b)throw Error("Companion tunnel worker is missing required environment configuration.");let S=r[c]?.trim(),v=r[u]?.trim(),E=r[i]?.trim();if(!S||!v||!E)throw Error("Companion tunnel worker is missing required bridge scope configuration.");let I=r[m]?.trim();if(!I)throw Error("Companion tunnel worker is missing required register path configuration.");return{serverBaseUrl:w,bearerToken:h,localBaseUrl:b,registerPath:I,bridgeScope:{tenantId:S,runId:v,leaseId:E},launchUrl:r[a]?.trim()||void 0,statePath:r[o]?.trim()||void 0,unregisterPath:r[y]?.trim()||void 0,devicePort:function(e){if(!e?.trim())return;let r=Number.parseInt(e,10);if(!Number.isInteger(r)||r<1||r>65535)throw Error("Companion worker received invalid device port configuration.");return r}(r[l]),session:r[d]?.trim()||void 0}}(e,r);return!!t&&(await N(t),!0)})(process.argv.slice(2),process.env).catch(e=>{if(e instanceof Error&&e.message.includes("missing required environment")){console.error(e.message),process.exitCode=1;return}console.error(e instanceof Error?e.stack??e.message:String(e)),process.exitCode=1});
@@ -4,6 +4,12 @@ export declare function buildBundleUrl(baseUrl: string, platform: 'ios' | 'andro
4
4
 
5
5
  export declare function buildIosRuntimeHints(baseUrl: string): MetroRuntimeHints;
6
6
 
7
+ declare type CompanionTunnelScope = {
8
+ tenantId: string;
9
+ runId: string;
10
+ leaseId: string;
11
+ };
12
+
7
13
  export declare function ensureMetroTunnel(options: EnsureMetroTunnelOptions): Promise<EnsureMetroTunnelResult>;
8
14
 
9
15
  export declare type EnsureMetroTunnelOptions = {
@@ -11,7 +17,7 @@ export declare type EnsureMetroTunnelOptions = {
11
17
  serverBaseUrl: string;
12
18
  bearerToken: string;
13
19
  localBaseUrl: string;
14
- bridgeScope: MetroBridgeScope;
20
+ bridgeScope: CompanionTunnelScope;
15
21
  launchUrl?: string;
16
22
  profileKey?: string;
17
23
  consumerKey?: string;
@@ -75,12 +81,6 @@ export declare type MetroBridgeRuntimePayload = {
75
81
  launch_url?: string;
76
82
  };
77
83
 
78
- declare type MetroBridgeScope = {
79
- tenantId: string;
80
- runId: string;
81
- leaseId: string;
82
- };
83
-
84
84
  /** Re-export of {@link SessionRuntimeHints} under the Metro-specific alias used by public API consumers. */
85
85
  export declare type MetroRuntimeHints = SessionRuntimeHints;
86
86
 
@@ -162,7 +162,7 @@ export declare type PrepareRemoteMetroOptions = {
162
162
  publicBaseUrl?: string;
163
163
  proxyBaseUrl?: string;
164
164
  proxyBearerToken?: string;
165
- bridgeScope?: MetroBridgeScope;
165
+ bridgeScope?: CompanionTunnelScope;
166
166
  launchUrl?: string;
167
167
  profileKey?: string;
168
168
  consumerKey?: string;
package/dist/src/metro.js CHANGED
@@ -1 +1 @@
1
- import{buildMetroRuntimeHints as e,ensureMetroCompanion as t,reloadMetro as r,stopMetroCompanion as o,prepareMetroRuntime as n}from"./1974.js";import{resolveRuntimeTransportHints as i}from"./8656.js";function s(e){return i(e)}async function a(e){let t=await n({projectRoot:e.projectRoot,kind:e.kind,publicBaseUrl:e.publicBaseUrl,proxyBaseUrl:e.proxyBaseUrl,proxyBearerToken:e.proxyBearerToken,bridgeScope:e.bridgeScope,launchUrl:e.launchUrl,companionProfileKey:e.profileKey,companionConsumerKey:e.consumerKey,metroPort:e.port,listenHost:e.listenHost,statusHost:e.statusHost,startupTimeoutMs:e.startupTimeoutMs,probeTimeoutMs:e.probeTimeoutMs,reuseExisting:e.reuseExisting,installDependenciesIfNeeded:e.installDependenciesIfNeeded,runtimeFilePath:e.runtimeFilePath,logPath:e.logPath,env:e.env});return{iosRuntime:t.iosRuntime,androidRuntime:t.androidRuntime,bridge:t.bridge,started:t.started,reused:t.reused,logPath:t.logPath}}async function u(e){let r=await t(e);return{pid:r.pid,started:r.spawned,logPath:r.logPath}}async function l(e){await o(e)}async function d(e={}){return await r(e)}function p(t){return e(t,"ios")}function m(t){return e(t,"android")}export{buildBundleUrl,normalizeBaseUrl}from"./320.js";export{m as buildAndroidRuntimeHints,p as buildIosRuntimeHints,u as ensureMetroTunnel,a as prepareRemoteMetro,d as reloadRemoteMetro,s as resolveRuntimeTransport,l as stopMetroTunnel};
1
+ import{buildMetroRuntimeHints as e,ensureMetroCompanion as t,reloadMetro as r,stopMetroCompanion as o,prepareMetroRuntime as n}from"./1974.js";import{resolveRuntimeTransportHints as i}from"./8656.js";function s(e){return i(e)}async function a(e){let t=await n({projectRoot:e.projectRoot,kind:e.kind,publicBaseUrl:e.publicBaseUrl,proxyBaseUrl:e.proxyBaseUrl,proxyBearerToken:e.proxyBearerToken,bridgeScope:e.bridgeScope,launchUrl:e.launchUrl,companionProfileKey:e.profileKey,companionConsumerKey:e.consumerKey,metroPort:e.port,listenHost:e.listenHost,statusHost:e.statusHost,startupTimeoutMs:e.startupTimeoutMs,probeTimeoutMs:e.probeTimeoutMs,reuseExisting:e.reuseExisting,installDependenciesIfNeeded:e.installDependenciesIfNeeded,runtimeFilePath:e.runtimeFilePath,logPath:e.logPath,env:e.env});return{iosRuntime:t.iosRuntime,androidRuntime:t.androidRuntime,bridge:t.bridge,started:t.started,reused:t.reused,logPath:t.logPath}}async function u(e){let r=await t(e);return{pid:r.pid,started:r.spawned,logPath:r.logPath}}async function l(e){await o(e)}async function d(e={}){return await r(e)}function p(t){return e(t,"ios")}function m(t){return e(t,"android")}export{buildBundleUrl,normalizeBaseUrl}from"./2301.js";export{m as buildAndroidRuntimeHints,p as buildIosRuntimeHints,u as ensureMetroTunnel,a as prepareRemoteMetro,d as reloadRemoteMetro,s as resolveRuntimeTransport,l as stopMetroTunnel};
@@ -0,0 +1,91 @@
1
+ declare type BackendDiagnosticsTimeWindow = {
2
+ since?: string;
3
+ until?: string;
4
+ };
5
+
6
+ declare type BackendDumpNetworkResult = {
7
+ entries: readonly BackendNetworkEntry[];
8
+ nextCursor?: string;
9
+ timeWindow?: BackendDiagnosticsTimeWindow;
10
+ backend?: string;
11
+ redacted?: boolean;
12
+ notes?: readonly string[];
13
+ };
14
+
15
+ declare type BackendNetworkEntry = {
16
+ timestamp?: string;
17
+ method?: string;
18
+ url?: string;
19
+ status?: number;
20
+ durationMs?: number;
21
+ requestHeaders?: Record<string, string>;
22
+ responseHeaders?: Record<string, string>;
23
+ requestBody?: string;
24
+ responseBody?: string;
25
+ metadata?: Record<string, unknown>;
26
+ };
27
+
28
+ export declare function mapNetworkDumpToBackendResult(dump: ParsedNetworkDump, options?: {
29
+ backend?: string;
30
+ redacted?: boolean;
31
+ notes?: readonly string[];
32
+ }): BackendDumpNetworkResult;
33
+
34
+ export declare function mergeNetworkDumps(primary: ParsedNetworkDump, secondary: ParsedNetworkDump, maxEntries?: number): ParsedNetworkDump;
35
+
36
+ export declare type NetworkIncludeMode = NetworkIncludeMode_2;
37
+
38
+ declare type NetworkIncludeMode_2 = 'summary' | 'headers' | 'body' | 'all';
39
+
40
+ export declare type NetworkLogBackend = NetworkLogBackend_2 | (string & {});
41
+
42
+ declare type NetworkLogBackend_2 = 'ios-simulator' | 'ios-device' | 'android' | 'macos';
43
+
44
+ export declare type ParsedNetworkDump = {
45
+ sourcePath?: string;
46
+ scannedLines: number;
47
+ matchedLines: number;
48
+ entries: ParsedNetworkEntry[];
49
+ include: NetworkIncludeMode;
50
+ limits: {
51
+ maxEntries: number;
52
+ maxPayloadChars: number;
53
+ maxScanLines: number;
54
+ };
55
+ };
56
+
57
+ export declare type ParsedNetworkEntry = {
58
+ url: string;
59
+ timestamp?: string;
60
+ method?: string;
61
+ status?: number;
62
+ durationMs?: number;
63
+ headers?: string;
64
+ requestBody?: string;
65
+ responseBody?: string;
66
+ raw?: string;
67
+ line?: number;
68
+ packetId?: string;
69
+ metadata?: {
70
+ packetId?: string;
71
+ [key: string]: unknown;
72
+ };
73
+ };
74
+
75
+ export declare function readRecentNetworkTrafficFromText(content: string, options?: {
76
+ sourcePath?: string;
77
+ backend?: NetworkLogBackend;
78
+ maxEntries?: number;
79
+ include?: NetworkIncludeMode;
80
+ maxPayloadChars?: number;
81
+ maxScanLines?: number;
82
+ }): ParsedNetworkDump;
83
+
84
+ export declare type RedactionResult = {
85
+ value: string;
86
+ redacted: boolean;
87
+ };
88
+
89
+ export declare function redactNetworkLogText(text: string): RedactionResult;
90
+
91
+ export { }
@@ -0,0 +1 @@
1
+ import{NETWORK_LOG_MEMORY_PATH as e,readRecentNetworkTrafficFromText as t}from"./5721.js";function a(a,s){var r;let d;return r=t(a,{path:s?.sourcePath,backend:function(e){switch(e){case"ios-simulator":return"ios-simulator";case"ios-device":return"ios-device";case"android":return"android";case"macos":return"macos";default:return}}(s?.backend),maxEntries:s?.maxEntries,include:s?.include,maxPayloadChars:s?.maxPayloadChars,maxScanLines:s?.maxScanLines}),{...(d=s?.sourcePath??(r.path===e?void 0:r.path))?{sourcePath:d}:{},scannedLines:r.scannedLines,matchedLines:r.matchedLines,entries:r.entries.map(e=>({url:e.url,...e.timestamp?{timestamp:e.timestamp}:{},...e.method?{method:e.method}:{},...void 0!==e.status?{status:e.status}:{},...void 0!==e.durationMs?{durationMs:e.durationMs}:{},...e.headers?{headers:e.headers}:{},...void 0!==e.requestBody?{requestBody:e.requestBody}:{},...void 0!==e.responseBody?{responseBody:e.responseBody}:{},...e.raw?{raw:e.raw}:{},...void 0!==e.line?{line:e.line}:{},...e.packetId?{packetId:e.packetId}:{}})),include:r.include,limits:r.limits}}function s(e,t,a=e.limits.maxEntries){let r=Math.max(0,a),o=e.entries.slice(0,r),n=new Set(o.map(e=>d(e)));for(let e of t.entries){if(o.length>=r)break;let t=d(e);n.has(t)||(n.add(t),o.push(e))}return{...e,matchedLines:o.length,entries:o}}function r(e,t){return{entries:e.entries.map(e=>{var t,a;let s,r;return r=(s={...(a=t=e).metadata??{}},a.packetId&&void 0===s.packetId&&(s.packetId=a.packetId),a.headers&&void 0===s.headers&&(s.headers=a.headers),Object.keys(s).length>0?s:void 0),{...t.timestamp?{timestamp:t.timestamp}:{},...t.method?{method:t.method}:{},url:t.url,...void 0!==t.status?{status:t.status}:{},...void 0!==t.durationMs?{durationMs:t.durationMs}:{},...void 0!==t.requestBody?{requestBody:t.requestBody}:{},...void 0!==t.responseBody?{responseBody:t.responseBody}:{},...r?{metadata:r}:{}}}),...t?.backend?{backend:t.backend}:{},...t?.redacted!==void 0?{redacted:t.redacted}:{},...t?.notes?{notes:t.notes}:{}}}function d(e){return`${e.timestamp??""}|${e.method??""}|${e.url}|${e.status??""}|${e.raw??""}`}export{redactNetworkLogText}from"./7166.js";export{r as mapNetworkDumpToBackendResult,s as mergeNetworkDumps,a as readRecentNetworkTrafficFromText};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-device",
3
- "version": "0.13.1",
3
+ "version": "0.13.2",
4
4
  "description": "Agent-driven CLI for mobile UI automation, network inspection, and performance diagnostics across iOS, Android, tvOS, and macOS.",
5
5
  "license": "MIT",
6
6
  "author": "Callstack",
@@ -40,6 +40,10 @@
40
40
  "import": "./dist/src/artifacts.js",
41
41
  "types": "./dist/src/artifacts.d.ts"
42
42
  },
43
+ "./observability": {
44
+ "import": "./dist/src/observability.js",
45
+ "types": "./dist/src/observability.d.ts"
46
+ },
43
47
  "./metro": {
44
48
  "import": "./dist/src/metro.js",
45
49
  "types": "./dist/src/metro.d.ts"
@@ -14,7 +14,8 @@ Open this file for remote daemon HTTP flows that let an agent running in a Linux
14
14
  - `agent-device snapshot --remote-config <path> -i`
15
15
  - `agent-device disconnect --remote-config <path>`
16
16
  - `agent-device connection status`
17
- - `AGENT_DEVICE_DAEMON_AUTH_TOKEN=...`
17
+ - `agent-device auth status`
18
+ - `AGENT_DEVICE_DAEMON_AUTH_TOKEN=...` for CI/service-token automation
18
19
 
19
20
  ## Most common mistake to avoid
20
21
 
@@ -30,9 +31,6 @@ Do not mix an arbitrary `--session` plus ad-hoc daemon, tenant, run, or lease fl
30
31
  Use this when the agent will run several commands in one session.
31
32
 
32
33
  ```bash
33
- export AGENT_DEVICE_DAEMON_AUTH_TOKEN="YOUR_TOKEN"
34
- export AGENT_DEVICE_PROXY_TOKEN="$AGENT_DEVICE_DAEMON_AUTH_TOKEN"
35
-
36
34
  agent-device connect --remote-config ./remote-config.json
37
35
 
38
36
  ARTIFACT_URL="<trusted-artifact-url>"
@@ -44,7 +42,7 @@ agent-device fill @e3 "test@example.com"
44
42
  agent-device disconnect
45
43
  ```
46
44
 
47
- After `connect`, normal commands use the active remote connection. End with `disconnect` to release the lease and stop the owned Metro companion.
45
+ After `connect`, normal commands use the active remote connection. If cloud credentials are missing, `connect` starts login automatically in an interactive shell and stores a revocable CLI session that silently mints short-lived `adc_agent_...` command tokens. The cloud side remains responsible for token expiry, tenant/run claim checks, revocation, one-time device approval, and polling rate limits. End with `disconnect` to release the lease and stop the owned Metro companion.
48
46
 
49
47
  ### Self-contained script flow
50
48
 
@@ -123,7 +121,7 @@ Optional overrides stay available for advanced cases:
123
121
  }
124
122
  ```
125
123
 
126
- - Keep secrets in env/config managed by the operator boundary. Do not persist auth tokens in connection state.
124
+ - Keep service tokens in env/config managed by the operator boundary. Do not persist auth tokens in connection state. Human login uses `agent-device auth login` or implicit `connect` login and stores only the CLI session credential.
127
125
  - Omit Metro fields for non-React Native flows.
128
126
  - Put `tenant`, `runId`, and `sessionIsolation` in the remote profile so agents can run `agent-device connect --remote-config ./remote-config.json` without extra scope flags. Add `platform`, `leaseBackend`, `session`, or Metro overrides only when the default inference is not enough for that flow.
129
127
  - Explicit command-line flags override connected defaults. Use them intentionally when switching session, platform, target, tenant, run, or lease scope.
@@ -137,7 +135,8 @@ Optional overrides stay available for advanced cases:
137
135
 
138
136
  - Start the daemon in HTTP mode with `AGENT_DEVICE_DAEMON_SERVER_MODE=http|dual` on the host.
139
137
  - Point the profile or env at the remote host with `daemonBaseUrl` or `AGENT_DEVICE_DAEMON_BASE_URL=http(s)://host:port[/base-path]`.
140
- - For non-loopback remote hosts, set `AGENT_DEVICE_DAEMON_AUTH_TOKEN` or `--daemon-auth-token`. The client rejects non-loopback remote daemon URLs without auth.
138
+ - For humans, run `connect --remote-config <path>` and let it refresh or create the CLI session. Use `agent-device auth status` to inspect it and `agent-device auth logout` to remove it.
139
+ - For CI/non-interactive shells, set `AGENT_DEVICE_DAEMON_AUTH_TOKEN=adc_live_...` or pass `--daemon-auth-token`. The client does not start device-code polling in CI by default.
141
140
  - Prefer an auth hook such as `AGENT_DEVICE_HTTP_AUTH_HOOK` when the host needs caller validation or tenant injection.
142
141
 
143
142
  ## Lease debug fallback
package/dist/src/320.js DELETED
@@ -1 +0,0 @@
1
- let E="--agent-device-run-metro-companion",_="--agent-device-run-react-devtools-companion",N="AGENT_DEVICE_METRO_COMPANION_SERVER_BASE_URL",O="AGENT_DEVICE_METRO_COMPANION_BEARER_TOKEN",A="AGENT_DEVICE_METRO_COMPANION_LOCAL_BASE_URL",T="AGENT_DEVICE_METRO_COMPANION_LAUNCH_URL",R="AGENT_DEVICE_METRO_COMPANION_STATE_PATH",C="AGENT_DEVICE_METRO_COMPANION_SCOPE_TENANT_ID",I="AGENT_DEVICE_METRO_COMPANION_SCOPE_RUN_ID",e="AGENT_DEVICE_METRO_COMPANION_SCOPE_LEASE_ID",P="AGENT_DEVICE_METRO_COMPANION_REGISTER_PATH",V="AGENT_DEVICE_METRO_COMPANION_UNREGISTER_PATH",S="AGENT_DEVICE_METRO_COMPANION_DEVICE_PORT",M="AGENT_DEVICE_METRO_COMPANION_SESSION";function n(E){let _=E.length;for(;_>0&&47===E.charCodeAt(_-1);)_-=1;return _===E.length?E:E.slice(0,_)}function r(E,_){let N=new URL(`${n(E)}/index.bundle`);return N.searchParams.set("platform",_),N.searchParams.set("dev","true"),N.searchParams.set("minify","false"),N.toString()}export{O as ENV_BEARER_TOKEN,S as ENV_DEVICE_PORT,T as ENV_LAUNCH_URL,A as ENV_LOCAL_BASE_URL,P as ENV_REGISTER_PATH,e as ENV_SCOPE_LEASE_ID,I as ENV_SCOPE_RUN_ID,C as ENV_SCOPE_TENANT_ID,N as ENV_SERVER_BASE_URL,M as ENV_SESSION,R as ENV_STATE_PATH,V as ENV_UNREGISTER_PATH,E as METRO_COMPANION_RUN_ARG,_ as REACT_DEVTOOLS_COMPANION_RUN_ARG,r as buildBundleUrl,n as normalizeBaseUrl};