@myerscarpenter/quest-dev 1.0.7 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -57,7 +57,7 @@ Port forwarding is idempotent - safe to run multiple times without issues.
57
57
 
58
58
  ## How It Works
59
59
 
60
- - **screenshot**: Triggers `com.oculus.metacam/.capture.CaptureService` via ADB, waits for the screenshot to save, then pulls the most recent file from `/sdcard/Oculus/Screenshots/`
60
+ - **screenshot**: Triggers `com.oculus.metacam/.capture.CaptureService` via ADB, waits for the JPEG to be fully written (by checking for the EOI marker), pulls the file, then deletes it from the Quest
61
61
 
62
62
  - **open**: Uses ADB for port forwarding and browser launching. If `cdp-cli` is installed, it uses CDP to intelligently reuse existing tabs instead of opening new ones.
63
63
 
@@ -5,5 +5,5 @@
5
5
  /**
6
6
  * Main open command handler
7
7
  */
8
- export declare function openCommand(url: string): Promise<void>;
8
+ export declare function openCommand(url: string, closeOthers?: boolean): Promise<void>;
9
9
  //# sourceMappingURL=open.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"open.d.ts","sourceRoot":"","sources":["../../src/commands/open.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAyFH;;GAEG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA0D5D"}
1
+ {"version":3,"file":"open.d.ts","sourceRoot":"","sources":["../../src/commands/open.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA0IH;;GAEG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAkE1F"}
@@ -4,6 +4,51 @@
4
4
  */
5
5
  import { checkADBPath, checkADBDevices, ensurePortForwarding, ensureCDPForwarding, isBrowserRunning, launchBrowser, getCDPPort } from '../utils/adb.js';
6
6
  import { execCommandFull } from '../utils/exec.js';
7
+ /**
8
+ * Close all tabs except the one with the target URL
9
+ */
10
+ async function closeOtherTabs(targetUrl) {
11
+ const cdpPort = getCDPPort();
12
+ try {
13
+ // Get list of tabs
14
+ const result = await execCommandFull('cdp-cli', ['--cdp-url', `http://localhost:${cdpPort}`, 'tabs']);
15
+ if (result.code !== 0) {
16
+ console.log('Could not list tabs to close others');
17
+ return;
18
+ }
19
+ // Parse tabs
20
+ const lines = result.stdout.trim().split('\n').filter(line => line.trim());
21
+ const tabs = [];
22
+ for (const line of lines) {
23
+ try {
24
+ const tab = JSON.parse(line);
25
+ if (tab.id && tab.url !== undefined) {
26
+ tabs.push(tab);
27
+ }
28
+ }
29
+ catch {
30
+ // Skip non-JSON lines
31
+ }
32
+ }
33
+ // Normalize URLs for comparison (handle trailing slash differences)
34
+ const normalizeUrl = (url) => url.replace(/\/$/, '');
35
+ const normalizedTarget = normalizeUrl(targetUrl);
36
+ // Close all tabs that don't have the target URL, keeping the first match
37
+ let keptOne = false;
38
+ for (const tab of tabs) {
39
+ const isTargetTab = normalizeUrl(tab.url) === normalizedTarget;
40
+ if (isTargetTab && !keptOne) {
41
+ keptOne = true;
42
+ continue; // Keep this tab
43
+ }
44
+ console.log(`Closing tab: ${tab.url || '(blank)'}`);
45
+ await execCommandFull('cdp-cli', ['--cdp-url', `http://localhost:${cdpPort}`, 'close', tab.id]);
46
+ }
47
+ }
48
+ catch (error) {
49
+ console.log('Failed to close other tabs:', error.message);
50
+ }
51
+ }
7
52
  /**
8
53
  * Try to navigate or reload existing tab via cdp-cli
9
54
  */
@@ -70,7 +115,7 @@ async function tryNavigateExistingTab(targetUrl) {
70
115
  /**
71
116
  * Main open command handler
72
117
  */
73
- export async function openCommand(url) {
118
+ export async function openCommand(url, closeOthers = false) {
74
119
  // Parse URL to determine if we need reverse port forwarding
75
120
  let parsedUrl;
76
121
  try {
@@ -121,6 +166,13 @@ export async function openCommand(url) {
121
166
  await launchBrowser(url);
122
167
  }
123
168
  }
169
+ // Close other tabs if requested
170
+ if (closeOthers) {
171
+ // Wait for browser to stabilize after launch/navigation
172
+ console.log('Waiting for browser to stabilize...');
173
+ await new Promise(resolve => setTimeout(resolve, 2000));
174
+ await closeOtherTabs(url);
175
+ }
124
176
  console.log('\nDone!\n');
125
177
  }
126
178
  //# sourceMappingURL=open.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"open.js","sourceRoot":"","sources":["../../src/commands/open.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"open.js","sourceRoot":"","sources":["../../src/commands/open.ts"],"names":[],"mappings":"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"}
package/build/index.js CHANGED
@@ -46,13 +46,19 @@ cli.command('screenshot <output>', 'Take a screenshot from Quest and save to loc
46
46
  });
47
47
  // Open command
48
48
  cli.command('open <url>', 'Open URL in Quest browser (sets up CDP debugging port forwarding)', (yargs) => {
49
- return yargs.positional('url', {
49
+ return yargs
50
+ .positional('url', {
50
51
  describe: 'URL to open (localhost URLs get reverse forwarding for dev server access)',
51
52
  type: 'string',
52
53
  demandOption: true
54
+ })
55
+ .option('close-others', {
56
+ describe: 'Close all other tabs before opening',
57
+ type: 'boolean',
58
+ default: false
53
59
  });
54
60
  }, async (argv) => {
55
- await openCommand(argv.url);
61
+ await openCommand(argv.url, argv.closeOthers);
56
62
  });
57
63
  // Parse and execute
58
64
  cli.parse();
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;GAGG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,iCAAiC;AACjC,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAC5B,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,EAAE,OAAO,CAAC,CAC1D,CAAC;AACF,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC;AAEpC,aAAa;AACb,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;KACrC,UAAU,CAAC,WAAW,CAAC;KACvB,OAAO,CAAC,OAAO,CAAC;KAChB,KAAK,CAAC,+BAA+B,CAAC;KACtC,aAAa,CAAC,CAAC,EAAE,4BAA4B,CAAC;KAC9C,MAAM,EAAE;KACR,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE;IACxB,IAAI,GAAG,EAAE,CAAC;QACR,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACnC,CAAC;IACD,IAAI,GAAG,EAAE,CAAC;QACR,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,+CAA+C,CAAC,CAAC;IAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC;KACD,IAAI,EAAE;KACN,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC;KAClB,MAAM,CAAC,iFAAiF,CAAC,CAAC;AAE7F,qBAAqB;AACrB,GAAG,CAAC,OAAO,CACT,qBAAqB,EACrB,qDAAqD,EACrD,CAAC,KAAK,EAAE,EAAE;IACR,OAAO,KAAK,CAAC,UAAU,CAAC,QAAQ,EAAE;QAChC,QAAQ,EAAE,iDAAiD;QAC3D,IAAI,EAAE,QAAQ;QACd,YAAY,EAAE,IAAI;KACnB,CAAC,CAAC;AACL,CAAC,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;IACb,MAAM,iBAAiB,CAAC,IAAI,CAAC,MAAgB,CAAC,CAAC;AACjD,CAAC,CACF,CAAC;AAEF,eAAe;AACf,GAAG,CAAC,OAAO,CACT,YAAY,EACZ,mEAAmE,EACnE,CAAC,KAAK,EAAE,EAAE;IACR,OAAO,KAAK,CAAC,UAAU,CAAC,KAAK,EAAE;QAC7B,QAAQ,EAAE,2EAA2E;QACrF,IAAI,EAAE,QAAQ;QACd,YAAY,EAAE,IAAI;KACnB,CAAC,CAAC;AACL,CAAC,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;IACb,MAAM,WAAW,CAAC,IAAI,CAAC,GAAa,CAAC,CAAC;AACxC,CAAC,CACF,CAAC;AAEF,oBAAoB;AACpB,GAAG,CAAC,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;GAGG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,iCAAiC;AACjC,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAC5B,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,EAAE,OAAO,CAAC,CAC1D,CAAC;AACF,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC;AAEpC,aAAa;AACb,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;KACrC,UAAU,CAAC,WAAW,CAAC;KACvB,OAAO,CAAC,OAAO,CAAC;KAChB,KAAK,CAAC,+BAA+B,CAAC;KACtC,aAAa,CAAC,CAAC,EAAE,4BAA4B,CAAC;KAC9C,MAAM,EAAE;KACR,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE;IACxB,IAAI,GAAG,EAAE,CAAC;QACR,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACnC,CAAC;IACD,IAAI,GAAG,EAAE,CAAC;QACR,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,+CAA+C,CAAC,CAAC;IAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC;KACD,IAAI,EAAE;KACN,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC;KAClB,MAAM,CAAC,iFAAiF,CAAC,CAAC;AAE7F,qBAAqB;AACrB,GAAG,CAAC,OAAO,CACT,qBAAqB,EACrB,qDAAqD,EACrD,CAAC,KAAK,EAAE,EAAE;IACR,OAAO,KAAK,CAAC,UAAU,CAAC,QAAQ,EAAE;QAChC,QAAQ,EAAE,iDAAiD;QAC3D,IAAI,EAAE,QAAQ;QACd,YAAY,EAAE,IAAI;KACnB,CAAC,CAAC;AACL,CAAC,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;IACb,MAAM,iBAAiB,CAAC,IAAI,CAAC,MAAgB,CAAC,CAAC;AACjD,CAAC,CACF,CAAC;AAEF,eAAe;AACf,GAAG,CAAC,OAAO,CACT,YAAY,EACZ,mEAAmE,EACnE,CAAC,KAAK,EAAE,EAAE;IACR,OAAO,KAAK;SACT,UAAU,CAAC,KAAK,EAAE;QACjB,QAAQ,EAAE,2EAA2E;QACrF,IAAI,EAAE,QAAQ;QACd,YAAY,EAAE,IAAI;KACnB,CAAC;SACD,MAAM,CAAC,cAAc,EAAE;QACtB,QAAQ,EAAE,qCAAqC;QAC/C,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,KAAK;KACf,CAAC,CAAC;AACP,CAAC,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;IACb,MAAM,WAAW,CAAC,IAAI,CAAC,GAAa,EAAE,IAAI,CAAC,WAAsB,CAAC,CAAC;AACrE,CAAC,CACF,CAAC;AAEF,oBAAoB;AACpB,GAAG,CAAC,KAAK,EAAE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myerscarpenter/quest-dev",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "CLI for Meta Quest Browser development - screenshot and URL opening via ADB and cdp-cli",
5
5
  "type": "module",
6
6
  "bin": {
@@ -14,6 +14,55 @@ import {
14
14
  } from '../utils/adb.js';
15
15
  import { execCommand, execCommandFull } from '../utils/exec.js';
16
16
 
17
+ /**
18
+ * Close all tabs except the one with the target URL
19
+ */
20
+ async function closeOtherTabs(targetUrl: string): Promise<void> {
21
+ const cdpPort = getCDPPort();
22
+
23
+ try {
24
+ // Get list of tabs
25
+ const result = await execCommandFull('cdp-cli', ['--cdp-url', `http://localhost:${cdpPort}`, 'tabs']);
26
+ if (result.code !== 0) {
27
+ console.log('Could not list tabs to close others');
28
+ return;
29
+ }
30
+
31
+ // Parse tabs
32
+ const lines = result.stdout.trim().split('\n').filter(line => line.trim());
33
+ const tabs: Array<{ id: string; url: string }> = [];
34
+
35
+ for (const line of lines) {
36
+ try {
37
+ const tab = JSON.parse(line);
38
+ if (tab.id && tab.url !== undefined) {
39
+ tabs.push(tab);
40
+ }
41
+ } catch {
42
+ // Skip non-JSON lines
43
+ }
44
+ }
45
+
46
+ // Normalize URLs for comparison (handle trailing slash differences)
47
+ const normalizeUrl = (url: string) => url.replace(/\/$/, '');
48
+ const normalizedTarget = normalizeUrl(targetUrl);
49
+
50
+ // Close all tabs that don't have the target URL, keeping the first match
51
+ let keptOne = false;
52
+ for (const tab of tabs) {
53
+ const isTargetTab = normalizeUrl(tab.url) === normalizedTarget;
54
+ if (isTargetTab && !keptOne) {
55
+ keptOne = true;
56
+ continue; // Keep this tab
57
+ }
58
+ console.log(`Closing tab: ${tab.url || '(blank)'}`);
59
+ await execCommandFull('cdp-cli', ['--cdp-url', `http://localhost:${cdpPort}`, 'close', tab.id]);
60
+ }
61
+ } catch (error) {
62
+ console.log('Failed to close other tabs:', (error as Error).message);
63
+ }
64
+ }
65
+
17
66
  /**
18
67
  * Try to navigate or reload existing tab via cdp-cli
19
68
  */
@@ -93,7 +142,7 @@ async function tryNavigateExistingTab(targetUrl: string): Promise<boolean> {
93
142
  /**
94
143
  * Main open command handler
95
144
  */
96
- export async function openCommand(url: string): Promise<void> {
145
+ export async function openCommand(url: string, closeOthers: boolean = false): Promise<void> {
97
146
  // Parse URL to determine if we need reverse port forwarding
98
147
  let parsedUrl: URL;
99
148
  try {
@@ -150,5 +199,13 @@ export async function openCommand(url: string): Promise<void> {
150
199
  }
151
200
  }
152
201
 
202
+ // Close other tabs if requested
203
+ if (closeOthers) {
204
+ // Wait for browser to stabilize after launch/navigation
205
+ console.log('Waiting for browser to stabilize...');
206
+ await new Promise(resolve => setTimeout(resolve, 2000));
207
+ await closeOtherTabs(url);
208
+ }
209
+
153
210
  console.log('\nDone!\n');
154
211
  }
package/src/index.ts CHANGED
@@ -62,14 +62,20 @@ cli.command(
62
62
  'open <url>',
63
63
  'Open URL in Quest browser (sets up CDP debugging port forwarding)',
64
64
  (yargs) => {
65
- return yargs.positional('url', {
66
- describe: 'URL to open (localhost URLs get reverse forwarding for dev server access)',
67
- type: 'string',
68
- demandOption: true
69
- });
65
+ return yargs
66
+ .positional('url', {
67
+ describe: 'URL to open (localhost URLs get reverse forwarding for dev server access)',
68
+ type: 'string',
69
+ demandOption: true
70
+ })
71
+ .option('close-others', {
72
+ describe: 'Close all other tabs before opening',
73
+ type: 'boolean',
74
+ default: false
75
+ });
70
76
  },
71
77
  async (argv) => {
72
- await openCommand(argv.url as string);
78
+ await openCommand(argv.url as string, argv.closeOthers as boolean);
73
79
  }
74
80
  );
75
81