@jackwener/opencli 0.5.0 → 0.5.1

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
@@ -72,6 +72,12 @@ And, so that `opencli` commands can use it directly in the terminal, export it i
72
72
  export PLAYWRIGHT_MCP_EXTENSION_TOKEN="<your-token-here>"
73
73
  ```
74
74
 
75
+ After configuring, run `opencli doctor` to verify your token is correctly set up across all locations:
76
+
77
+ ```bash
78
+ opencli doctor
79
+ ```
80
+
75
81
  ## Quick Start
76
82
 
77
83
  ### Install via npm (recommended)
package/README.zh-CN.md CHANGED
@@ -72,6 +72,12 @@ OpenCLI 通过 Playwright MCP Bridge 扩展与你的浏览器通信。
72
72
  export PLAYWRIGHT_MCP_EXTENSION_TOKEN="<你的-token>"
73
73
  ```
74
74
 
75
+ 配置完成后,运行 `opencli doctor` 检测你的 Token 是否在所有位置都正确配置:
76
+
77
+ ```bash
78
+ opencli doctor
79
+ ```
80
+
75
81
  ## 快速开始
76
82
 
77
83
  ### npm 全局安装(推荐)
package/SKILL.md CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: opencli
3
3
  description: "OpenCLI — Make any website your CLI. Zero risk, AI-powered, reuse Chrome login."
4
- version: 0.4.6
4
+ version: 0.5.0
5
5
  author: jackwener
6
6
  tags: [cli, browser, web, mcp, playwright, bilibili, zhihu, twitter, github, v2ex, hackernews, reddit, xiaohongshu, xueqiu, AI, agent]
7
7
  ---
package/dist/browser.js CHANGED
@@ -572,13 +572,23 @@ function extractTabEntries(raw) {
572
572
  .map(line => line.trim())
573
573
  .filter(Boolean)
574
574
  .map(line => {
575
- const match = line.match(/Tab\s+(\d+)\s*(.*)$/);
576
- if (!match)
577
- return null;
578
- return {
579
- index: parseInt(match[1], 10),
580
- identity: match[2].trim() || `tab-${match[1]}`,
581
- };
575
+ // Match actual Playwright MCP format: "- 0: (current) [title](url)" or "- 1: [title](url)"
576
+ const mcpMatch = line.match(/^-\s+(\d+):\s*(.*)$/);
577
+ if (mcpMatch) {
578
+ return {
579
+ index: parseInt(mcpMatch[1], 10),
580
+ identity: mcpMatch[2].trim() || `tab-${mcpMatch[1]}`,
581
+ };
582
+ }
583
+ // Legacy format: "Tab 0 ..."
584
+ const legacyMatch = line.match(/Tab\s+(\d+)\s*(.*)$/);
585
+ if (legacyMatch) {
586
+ return {
587
+ index: parseInt(legacyMatch[1], 10),
588
+ identity: legacyMatch[2].trim() || `tab-${legacyMatch[1]}`,
589
+ };
590
+ }
591
+ return null;
582
592
  })
583
593
  .filter((entry) => entry !== null);
584
594
  }
@@ -15,6 +15,13 @@ describe('browser helpers', () => {
15
15
  { index: 1, identity: 'Chrome Extension' },
16
16
  ]);
17
17
  });
18
+ it('extracts tab entries from MCP markdown format', () => {
19
+ const entries = __test__.extractTabEntries('- 0: (current) [Playwright MCP extension](chrome-extension://abc/connect.html)\n- 1: [知乎 - 首页](https://www.zhihu.com/)');
20
+ expect(entries).toEqual([
21
+ { index: 0, identity: '(current) [Playwright MCP extension](chrome-extension://abc/connect.html)' },
22
+ { index: 1, identity: '[知乎 - 首页](https://www.zhihu.com/)' },
23
+ ]);
24
+ });
18
25
  it('closes only tabs that were opened during the session', () => {
19
26
  const tabsToClose = __test__.diffTabIndexes(['https://example.com', 'Chrome Extension'], [
20
27
  { index: 0, identity: 'https://example.com' },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jackwener/opencli",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -20,6 +20,17 @@ describe('browser helpers', () => {
20
20
  ]);
21
21
  });
22
22
 
23
+ it('extracts tab entries from MCP markdown format', () => {
24
+ const entries = __test__.extractTabEntries(
25
+ '- 0: (current) [Playwright MCP extension](chrome-extension://abc/connect.html)\n- 1: [知乎 - 首页](https://www.zhihu.com/)'
26
+ );
27
+
28
+ expect(entries).toEqual([
29
+ { index: 0, identity: '(current) [Playwright MCP extension](chrome-extension://abc/connect.html)' },
30
+ { index: 1, identity: '[知乎 - 首页](https://www.zhihu.com/)' },
31
+ ]);
32
+ });
33
+
23
34
  it('closes only tabs that were opened during the session', () => {
24
35
  const tabsToClose = __test__.diffTabIndexes(
25
36
  ['https://example.com', 'Chrome Extension'],
package/src/browser.ts CHANGED
@@ -610,12 +610,23 @@ function extractTabEntries(raw: any): Array<{ index: number; identity: string }>
610
610
  .map(line => line.trim())
611
611
  .filter(Boolean)
612
612
  .map(line => {
613
- const match = line.match(/Tab\s+(\d+)\s*(.*)$/);
614
- if (!match) return null;
615
- return {
616
- index: parseInt(match[1], 10),
617
- identity: match[2].trim() || `tab-${match[1]}`,
618
- };
613
+ // Match actual Playwright MCP format: "- 0: (current) [title](url)" or "- 1: [title](url)"
614
+ const mcpMatch = line.match(/^-\s+(\d+):\s*(.*)$/);
615
+ if (mcpMatch) {
616
+ return {
617
+ index: parseInt(mcpMatch[1], 10),
618
+ identity: mcpMatch[2].trim() || `tab-${mcpMatch[1]}`,
619
+ };
620
+ }
621
+ // Legacy format: "Tab 0 ..."
622
+ const legacyMatch = line.match(/Tab\s+(\d+)\s*(.*)$/);
623
+ if (legacyMatch) {
624
+ return {
625
+ index: parseInt(legacyMatch[1], 10),
626
+ identity: legacyMatch[2].trim() || `tab-${legacyMatch[1]}`,
627
+ };
628
+ }
629
+ return null;
619
630
  })
620
631
  .filter((entry): entry is { index: number; identity: string } => entry !== null);
621
632
  }