@guanzhu.me/pw-cli 0.0.7 → 0.0.9

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/bin/pw-cli.js CHANGED
@@ -716,42 +716,61 @@ async function main() {
716
716
  return;
717
717
  }
718
718
 
719
- // ── goto: navigate the currently active tab (not always the first one) ───
719
+ // ── From here on: delegate to playwright-cli (with enhancements) ─────────
720
+ const cliPath = findPlaywrightCli();
721
+ if (!cliPath) {
722
+ process.stderr.write('pw-cli: @playwright/cli not found.\nInstall: npm install -g @playwright/cli\n');
723
+ process.exit(1);
724
+ }
725
+
726
+ // Ensures a browser is reachable via CDP; if not, spawns playwright-cli open first.
727
+ async function ensureBrowserRunning() {
728
+ const { getPlaywrightCliCdpPort } = require('../src/browser-manager');
729
+ const { probeCDP } = require('../src/utils');
730
+ const { readState } = require('../src/state');
731
+ const cliPort = getPlaywrightCliCdpPort();
732
+ if (cliPort && await probeCDP(cliPort, 2000)) return;
733
+ const state = readState();
734
+ if (state && await probeCDP(state.port, 2000)) return;
735
+ // No browser reachable — start one via playwright-cli
736
+ const { spawnSync } = require('child_process');
737
+ const res = spawnSync(process.execPath, [cliPath, 'open', '--headed', '--persistent', '--profile', DEFAULT_PROFILE], {
738
+ stdio: 'inherit',
739
+ cwd: PW_CLI_DIR,
740
+ });
741
+ if (res.status !== 0) {
742
+ process.stderr.write('pw-cli: failed to open browser\n');
743
+ process.exit(res.status || 1);
744
+ }
745
+ }
746
+
747
+ // ── goto: navigate the tracked active tab ────────────────────────────────
720
748
  if (command === 'goto') {
721
749
  const gotoIdx = rawArgv.indexOf('goto');
722
750
  const afterGoto = rawArgv.slice(gotoIdx + 1);
723
751
  const rawUrl = afterGoto.find(a => !a.startsWith('-'));
724
752
  if (rawUrl) {
725
753
  const fullUrl = /^https?:\/\//.test(rawUrl) ? rawUrl : `https://${rawUrl}`;
754
+ const activeTabFile = JSON.stringify(path.join(PW_CLI_DIR, 'active-tab.json'));
726
755
  const navCode = `async (page, context) => {
727
756
  const pages = context.pages();
728
- const info = await Promise.all(pages.map(async p => {
729
- try {
730
- const [hidden, focused] = await Promise.all([
731
- p.evaluate(() => document.hidden),
732
- p.evaluate(() => document.hasFocus()),
733
- ]);
734
- return { p, hidden, focused };
735
- } catch { return { p, hidden: true, focused: false }; }
736
- }));
737
- const focused = info.find(v => v.focused);
738
- const visible = info.filter(v => !v.hidden);
739
- const target = (focused || visible[visible.length - 1] || info[info.length - 1]).p;
757
+ let target = pages[pages.length - 1] || page;
758
+ try {
759
+ const saved = JSON.parse(require('fs').readFileSync(${activeTabFile}, 'utf8'));
760
+ const match = pages.find(p => p.url() === saved.url);
761
+ if (match) target = match;
762
+ } catch {}
740
763
  await target.goto(${JSON.stringify(fullUrl)}, { waitUntil: 'domcontentloaded', timeout: 0 });
741
- return target.url();
764
+ const resultUrl = target.url();
765
+ try { require('fs').writeFileSync(${activeTabFile}, JSON.stringify({ url: resultUrl })); } catch {}
766
+ return resultUrl;
742
767
  }`;
768
+ await ensureBrowserRunning();
743
769
  await handleRunCode(['run-code', navCode]);
744
770
  return;
745
771
  }
746
772
  }
747
773
 
748
- // ── From here on: delegate to playwright-cli (with enhancements) ─────────
749
- const cliPath = findPlaywrightCli();
750
- if (!cliPath) {
751
- process.stderr.write('pw-cli: @playwright/cli not found.\nInstall: npm install -g @playwright/cli\n');
752
- process.exit(1);
753
- }
754
-
755
774
  let argv = [...rawArgv];
756
775
 
757
776
  // ── run-code: stdin support + auto-wrap plain code as function ───────────
@@ -789,13 +808,19 @@ async function main() {
789
808
  const openIdx = argv.indexOf('open');
790
809
  const afterOpen = argv.slice(openIdx + 1);
791
810
 
792
- // If a URL is provided with open, always use our CDP executor directly.
793
- // getConnection() handles all cases: reuse playwright-cli session, reuse own daemon,
794
- // or start a new daemon — so we never need to spawn playwright-cli open separately.
811
+ // If a URL is provided with open, ensure a browser is running then open a new tab.
795
812
  const rawUrlArg = afterOpen.find(a => !a.startsWith('-') && /^(https?:\/\/|[a-zA-Z0-9]([a-zA-Z0-9-]*\.)+[a-zA-Z]{2,})/.test(a));
796
813
  const urlArg = rawUrlArg && !/^https?:\/\//.test(rawUrlArg) ? `https://${rawUrlArg}` : rawUrlArg;
797
814
  if (urlArg) {
798
- const navCode = `async page => { const newPage = await page.context().newPage(); await newPage.goto(${JSON.stringify(urlArg)}, { waitUntil: 'domcontentloaded', timeout: 0 }); return newPage.url(); }`;
815
+ const activeTabFile = JSON.stringify(path.join(PW_CLI_DIR, 'active-tab.json'));
816
+ const navCode = `async page => {
817
+ const newPage = await page.context().newPage();
818
+ await newPage.goto(${JSON.stringify(urlArg)}, { waitUntil: 'domcontentloaded', timeout: 0 });
819
+ const resultUrl = newPage.url();
820
+ try { require('fs').writeFileSync(${activeTabFile}, JSON.stringify({ url: resultUrl })); } catch {}
821
+ return resultUrl;
822
+ }`;
823
+ await ensureBrowserRunning();
799
824
  await handleRunCode(['run-code', navCode]);
800
825
  return;
801
826
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@guanzhu.me/pw-cli",
3
- "version": "0.0.7",
3
+ "version": "0.0.9",
4
4
  "description": "Persistent Playwright browser CLI with headed defaults, profile support, queueing, and script execution",
5
5
  "bin": {
6
6
  "pw-cli": "./bin/pw-cli.js"
@@ -175,4 +175,4 @@ async function killBrowser() {
175
175
  return true;
176
176
  }
177
177
 
178
- module.exports = { getConnection, killBrowser };
178
+ module.exports = { getConnection, killBrowser, getPlaywrightCliCdpPort };